Friday, April 20, 2007

Visual C++ & Chemistry

بسم الله الرحمن الرحیم

شیمی و C++

در این وبلاگ چند مثال در رابطه با کاربرد Visual C++ در شیمی آورده ام. امیدوارم که مورد استفاده شما باشد.

توجه کنید نام CChemistryDlg نام فرضی پروژه ما می باشد. و نکته دیگر اینکه پروژه های ساخته شده در برنامه های دیالوگی یا چند سندی قابل اجرا است.

1- تعیین موقعیت عناصر در جدول تناوبی

2- تعیین تعداد الکترونهای تراز آخر عنصرهای گروه اصلی (A)

3- تعیین بیشترین ظرفیت عنصرهای گروه اصلی

4- تعیین اولین جهش بزرگ انرژی یونش و تعداد جهش انرژی یونش

1-تعین موقعیت عناصر در جدول تناوبی

در این مثال برنامه ای می نویسیم تا گروه و دوره عنصر را با توجه به عدد اتمی تعیین کند. برای این کار تابعی به نام

PeriodicTable(int Anumber) و از نوع Cstring ایجاد و سپس کد زیر را در آن تایپ کنید:

Cstring CchemistryDlg::PeriodicTable(int Anumber)

{

int T1=0,T2=0;

int Xe[7]={2,10,18,18,36,54,86};

int FS[14]={1,3,11,19,37,55,87,4,12,20,38,56,88};

int Period=0;

BOOL bT=TRUE;

Cstring Group="";

if(Anumber>=5&&Anumber<=9)

{

T1=8-(10-Anumber);

}

else if(Anumber>=13&&Anumber<=17)

{

T1=8-(18-Anumber);

}

else if(Anumber>=31&&Anumber<=35)

{

T1=8-(36-Anumber);

}

else if(Anumber>=49&&Anumber<=53)

{

T1=8-(54-Anumber);

}

else if(Anumber>=81&&Anumber<=85)

{

T1=8-(86-Anumber);

}

if((Anumber>=21&&Anumber<=30)||(Anumber>=72&&Anumber<=80))

{

T2=(Anumber%10)+2;

bT=FALSE;

if(T2==8||T2==9||T2==10)

{

T2=8;

}

if(T2>10 &&T2<=12)

{

T2=(T2%10);

}

}

if((Anumber>=57&&Anumber<=71)||(Anumber>=89&&Anumber<=103))

{

T2=3;

bT=FALSE;

}

if(Anumber>=39&&Anumber<=48)

{

T2=Anumber%10+4;

bT=FALSE;

if(T2==8||T2==9||T2==10)

{

T2=8;

}

if(T2>10&&T2<=12)

{

T2=T2%10;

}

}

if(Anumber>=104&&Anumber<=106)

{

T2=Anumber%10;

bT=FALSE;

}

for(int y=0;y<14;y++)

{

if(Anumber==FS[y])

{

if(FS[y]%2==0)

{

T1=2;

}

else T1=1;

}

}

for(int u=0;u<7;u++)

{

if(Anumber==Xe[u])

{

T1=8;

}

}

if(Anumber==1 ||Anumber==2)

{

Period=1;

}

else if(Anumber>=3&&Anumber<=10)

{

Period=2;

}

else if(Anumber>=11&&Anumber<=18)

{

Period=3;

}

else if(Anumber>=19&&Anumber<=36)

{

Period=4;

}

else if(Anumber>=37&&Anumber<=54)

{

Period=5;

}

else if(Anumber>=55&&Anumber<=86)

{

Period=6;

}

else if(Anumber>=87&&Anumber<=106)

{

Period=7;

}

if(bT)

{

Group.Format("This Element is in %d A Group And %dth Period.",T1,Period);

}

else if(bT==FALSE)

{

Group.Format("This Element is in %d B Group And %dth Period.",T2,Period);

}

return (Cstring)Group;

}

در این کد Anumber عدد اتمی عنصر مورد نظر است. متغیر Xe آرایه ای است که عدد اتمی گازهای بی اثر را در خود نگه می دارد و متغیر FS آرایه ای است که عدد اتمی عنصرهای گروه اول و دوم اصلی جدول تناوبی را در خود نگه می دارد. در پایان دستورات تابع چنانچه هیچ یک از دستورات شرطی پیشین درست نباشد تابع چک می کند آیا عدد اتمی داده شده جزو گازهای بی اثر است یا خیر . سپس در پایان اگر متغیر bT برابر TRUE شد یعنی عدد اتمی متعلق به گروه اصلی جدول تناوبی است و در غیر اینصورت متعلق به گروه واسطه جدول تناوبی است. پس از پایان عملیات تابع دوره و گروه عنصر مورد نظر را بر می گرداند.

۲-تعیین تعداد الکترونهای تراز آخر عنصرهای گروه اصلی (A)

همانطور که می دانید تعداد الکترونهای تراز آخر هر عنصر در گروههای اصلی برابر با شماره گروه آن عنصر می باشد. پس در این مثال باید باید از تابع مثال قبل اما با کمی تفاوت استفاده کنیم. پس تابعی با نام تابع قبلی ایجاد اما نوع آن را int انتخاب کنید. سپس کد زیر را در آن بنویسید:

int CchemistryDlg::PeriodicTable(int Anumber)

{

int T1=0;

int Xe[7]={2,10,18,18,36,54,86};

int FS[14]={1,3,11,19,37,55,87,4,12,20,38,56,88};

int Period=0;

if(Anumber>=5&&Anumber<=9)

{

T1=8-(10-Anumber);

}

else if(Anumber>=13&&Anumber<=17)

{

T1=8-(18-Anumber);

}

else if(Anumber>=31&&Anumber<=35)

{

T1=8-(36-Anumber);

}

else if(Anumber>=49&&Anumber<=53)

{

T1=8-(54-Anumber);

}

else if(Anumber>=81&&Anumber<=85)

{

T1=8-(86-Anumber);

}

for(int y=0;y<14;y++)

{

if(Anumber==FS[y])

{

if(FS[y]%2==0)

{

T1=2;

}

else T1=1;

}

}

for(int u=0;u<7;u++)

{

if(Anumber==Xe[u])

{

T1=8;

}

}

if(bT)

{

return T1;

}

}

حال باید کدی بنویسیم تا تعداد الکترونهای تراز آخر عنصر را به ما بر گرداند. پس تابعی به نام

ElectronCapacity(int Anumber1) واز نوع int ایجاد و سپس کد زیر را در آن تایپ کنید:

int CchemistryDlg:: ElectronCapacity(int Anumber1)

{

int Electron=0;

Electron=PeriodicTable(Anumber1);

return (int) Electron;

}

در این کد تابع PeriodicTable شماره گروه را بر می گردااند و سرانجام مقدار متغیر Electron توسط تابع بر گردانده می شود. *همانطور که گفتیم تعداد الکترونهای تراز آخر ظرفیت عنصرهای گروه اصلی برابر با شماره گروه عنصر می باشد.

۳-تعیین بیشترین ظرفیت عنصرهای گروه اصلی

همانطور که می دانید بیشترین ظرفیت عنصرهای گروه اصلی جدول تناوبی برابر با شماره گروه عنصر می باشد. پس تابعی با عنوان

ElementCapacity(int Anumber) واز نوع int ایجاد و کد زیر را در آن تایپ کنید:

int CchemistryDlg::ElementCapacity(int Anumber)

{

int m_Capacity=0;

if(Anumber==7)

m_Capacity=3;

else if(Anumber==8)

m_Capacity=2;

else if(Anumber==9)

m_Capacity=1;

else

m_Capacity=PeriodicTable(Anumber);

return (int)m_Capacity;

}

دراین کد نیز شماره گروه عنصر توسط تابع PeriodicTable به متغیر m_Capacity منتقل و در نهایت توسط تابع برگردانده می شود. همانطور که می دانید عناصر فلوئور، نیتروژن و آکسیژن از این قائده مستثنی هستند و بیشترین ظرفیت آنها به ترتیب برابر با 1، ۲ و3 است.

۵-تعیین اولین جهش بزرگ انرژی یونش و تعداد جهش انرژی یونش

در شیمی انرزی یونش عبارتست از مقدار انرژی لازم جهت جدا نمودن سست ترین الکترون از یک عنصر در حالت گازی شکل و تبدیل آن به یون مثبت گازی شکل.

در این بخش کدی می نویسیم تا اولین جهش انرژی یونش و تعداد آن را برای عنصر مورد نظر برگرداند.

برای این منظور تابعی به نام PeriodicTable (int ANumber,int*Group,int*Period) و از نوع void ایجاد و کد زیر را در آن تایپ کنید:

void CChemistryDlg:: PeriodicTable(int ANumber, int *Group, int *Period)

{

int T1=0,T2=0;

int Xe[7]={2,10,18,18,36,54,86};

int FS[14]={1,3,11,19,37,55,87,4,12,20,38,56,88};

int Period1=0;

BOOL bT=TRUE;

if(ANumber>=5&&ANumber<=9)

{

T1=8-(10-ANumber);

}

else if(ANumber>=13&&ANumber<=17)

{

T1=8-(18-ANumber);

}

else if(ANumber>=31&&ANumber<=35)

{

T1=8-(36-ANumber);

}

else if(ANumber>=49&&ANumber<=53)

{

T1=8-(54-ANumber);

}

else if(ANumber>=81&&ANumber<=85)

{

T1=8-(86-ANumber);

}

if((ANumber>=21&&ANumber<=30)||(ANumber>=72&&ANumber<=80))

{

T2=(ANumber%10)+2;

bT=FALSE;

if(T2==8||T2==9||T2==10)

{

T2=8;

}

if(T2>10 &&T2<=12)

{

T2=(T2%10);

}

}

if((ANumber>=57&&ANumber<=71)||(ANumber>=89&&ANumber<=103))

{

T2=3;

bT=FALSE;

}

if(ANumber>=39&&ANumber<=48)

{

T2=ANumber%10+4;

bT=FALSE;

if(T2==8||T2==9||T2==10)

{

T2=8;

}

if(T2>10&&T2<=12)

{

T2=T2%10;

}

}

if(ANumber>=104&&ANumber<=106)

{

T2=ANumber%10;

bT=FALSE;

}

for(int y=0;y<14;y++)

{

if(ANumber==FS[y])

{

if(FS[y]%2==0)

{

T1=2;

}

else T1=1;

}

}

for(int u=0;u<7;u++)

{

if(ANumber==Xe[u])

{

T1=8;

}

}

if(ANumber==1 ||ANumber==2)

{

Period1=1;

}

else if(ANumber>=3&&ANumber<=10)

{

Period1=2;

}

else if(ANumber>=11&&ANumber<=18)

{

Period1=3;

}

else if(ANumber>=19&&ANumber<=36)

{

Period1=4;

}

else if(ANumber>=37&&ANumber<=54)

{

Period1=5;

}

else if(ANumber>=55&&ANumber<=86)

{

Period1=6;

}

else if(ANumber>=87&&ANumber<=106)

{

Period1=7;

}

if(bT)

{

*Group=T1;

*Period=Period1;

}

else if(bT==FALSE)

{

*Group=T2;

*Period=Period1;

}

}

اکنون یک کنترل کادر ویرایش (Edit Box)ایجاد و متغیری به نام m_ed1 و از نوع CString به آن تخصیص دهید. سپس یک کنترل دکمه برروی فرم ایجاد و پس از دوبار کلیک برروی آن کد زیر را در آن تایپ کنید:

void CChemistryDlg::OnButtonIon()

{

int g=0,p=0;

PeriodicTable(17,&g,&p);

m_ed1.Format("The First Ionization is %d And Number Of Ionizations is %d",g+1,p-1);

UpdateData(0);

}

در تابع فوق از فرمولهای زیر استفاده کردیم:

شماره گروه عنصر=1- شماره اولین جهش بزرگ انرژی یونش

شماره دوره عنصر=1+تعداد جهش انرزی یونش

همانطور که دیدید ما دوباره از تابع PeriodicTable اما با کمی تفاوت استفاده کردیم. در این تابع از اشاره گر به عنوان پارامتر تابع استفاده کردیم تا پس از انجام عملیات شماره گروه و دوره تناوبی را به همان پارامتر منتقل کند. همانطور که می بینید نوع تابع void است و بنابراین تابع هیچ مقداری را بر نمی گرداند اما ما برای گرفتن شماره گروه و دوره از اشاره در پارامتر تابع استفاده کردیم. سپس همین تابع را در تابع OnButtonIon فراخوانی کردیم و به جای پارامتر ANumber عدد اتمی عنصر و به جای پارامترهای Group و Period آدرس متغیرهای g و p را قرار دادیم تا همانطور که گفتیم تابع پس از انجام عملیات شماره گروه و دوره تناوبی را به متغیرهای g و p منتقل کند و سرانجام نیز مقدار متغیرهای g و p را به متغیر مربوط به کنترل کادر ویرایش منتقل کردیم. عدد ۱۷ که در پارامتر تابع PeriodicTable قرار دادیم عدد اتمی عنصر کلر می باشد. شما می توانید به جای این پارامتر از متغیر کادر ویرایش استفاده کنید و هر عدد اتمی دلخواه را وارد و نتیجه را ببینید اما یادتان باشد تابع UpdateData() را حتما به ابتدای دستورات تابع اضافه کنید. اگر پس از اجرای برنامه برروی دکمه کلیک کنید نتیجه را خواهید دید.

منابع

آموزش شیمی. مهندس حسن سلطانی

مصطفی هاشمی 31/1/1386