搜档网
当前位置:搜档网 › 中南大学计算机实践C++程序设计

中南大学计算机实践C++程序设计

C++课程设计报告

------理论塔板数计算

化学与制药类班

组员

指导老师:****

2012年6月28日星期四

目录

1.C语言课程设计任务书

2.摘要

3.程序设计思路和流程框图

4.C++原始程序

5.程序运行结果

6.程序调试过程出现的一些问题的讨论

7.后记

1.C语言课程设计任务书

A.2012年6~7月

C++课程设计

主体

化工与制药类1101~1103班高级人才实验班全体同学

辅助

B.蒸馏

图1 多次部分气化的分离示意图

多次进行部分气化是使混合物得以完全分离地必要条件.

图2 无中间产品的多次部分

气化的分离示意图

C.精馏流程

预热到一定温度的原料液送入精馏塔的进料板,在每层塔板上,回流液体与上升蒸气互相接触,进行热和质的传递。

D.

设计内容

全塔物料衡算 理论塔板数求算

F.

G.

H.

I.

x D

a

b

x F

x W

d

c

1

1‘

2

3

4

5

6

方程1

J.C语言课程设计总要求

4人一组,独立编写程序;不得相互之间进行拷贝,如发现两份雷同的程序,将对两份同时进行严肃处理;

H.

2.摘要

本组使用了高斯消元法解了个二元方程组。同时应用了最小二乘法与类进行曲线拟合求得了 y =f(x)的相平衡方程。在进行循环的时候循环使用牛顿迭代法求得相平衡方程与精馏段操作线以及相平衡方程与提镏段操作线的交点,如此循环多次后可求得精馏塔理论塔板的数目n 。在设计课程中运用了c++语言的的数组与指针,类的定义与文件流输入与输出,循环语句,以及多种数学方法及其思想和作图等操作。

3.程序设计思路和流程框图

A.程序设计思路

1).首先运用高斯消元法求得了W,D 的值。原理如下首先设个数组a[3][2]={1,1,1,xf,xd,xw}和另外一个数组b[3].将a[0][i]乘以-xd 再加上a[1][i]用来消除D ,最后再利用个函数s=y/x*f 即可求得W 的值,再用F-W 即可求得D 的值。

2)利用最小二乘法进行曲线拟合求得相平衡方程;y=A+B*(x-z)+C*(x-z)^2+D*(x-z )^3. z 为x 的平均数。再化简即可得332210x a x a x a a y +++=;

的系数a0,a1,a2,a3.所以可得拟合后的方程1。 3)将xq 代入方程1可得yq ,在代入 可得R 的值继而可得L 的值。

5

.1966.0?--=q

q q x y y R

4)第一步循环解xm的值,首先令y1=xd,即可得方程xd=a0+a1*x+a2*x^2+a3*x^3用牛顿迭代法解方程组0=a0-xd+a1*x+a2*x^2+a3*x^3可得x1,再将x1代入直线方程y=R*x/(R+1)+xd/(R+1),得y2,再代入方程1解得x2如此一直循环。当xm少于xf时,结束循环。即一直解方程a0-R*x/(R+1)+xd/(R+1) +a1*x+a2*x^2+a3*x^3=0,并把值赋给xn+1,直到xm

5)第二部循环得到xj的值,类似于第一步只是把方程 2 y=R*x/(R+1)+xd/(R+1),换成方程 3 y=x*(L+F)/(L+F-W)-W*xw/(L+F-W).同时就是一直用牛顿迭代法解方程a0- x*(L+F)/(L+F-W)-W*xw/(L+F-W) +a1*x+a2*x^2+a3*x^3=0,并把值赋给xj+1,直到xj

B程序设计流程框图:

4.C语言原始程序

#include

#include

#include

#include

#include

#include

#include

double R,L,xd,xw,xq,xf,D,W,X[50];

double F=46.61;

double G(double x,double y)

{double s;

s=y/x*F;

return s;

}

class pirl //定义类用最小二乘法曲线拟合

{

private:

int n,m;

double *x,*y,*a;

public:

pirl (int nn,int mm)

{

n=nn;m=mm;

x=new double[n]; //动态分配内存

y=new double[n];

a=new double[m+1];

}

void input(); //由文件读入n个数据点(x,y)

void fit(); //执行最小二乘法曲线拟合

void output(); //输出m次拟合多项式的m+1个系数~pirl()

{ delete[] x,y,a; }

};

void pirl::input() //由文件读入n个数据点(x,y){

int k;

char strl[25];

cout<<"\n请输入文件名:";

cin>>strl;

ifstream fin (strl);

if (!fin)

{cout<<"\n不能打开这个文件 "<

{fin>>x[k]; fin>>y[k];}

fin.close();

}

void pirl::fit() //执行最小二乘法曲线拟合

{

int i,j,k;

double z,p,c,g,q,d1,d2,s[25],t[25],b[25];

for (i=0;i<=m;i++) a[i]=0.0;

z=0.0;

for (i=0;i<=n-1;i++) z=z+x[i]/(1.0*n);

b[0]=1.0;d1=1.0*n;p=0.0;c=0.0;

for(i=0;i<=n-1;i++)

{p=p+(x[i]-z);c=c+y[i];}

c=c/d1;p=p/d1;

a[0]=c*b[0];

if(m>0)

{

t[1]=1.0;t[0]=-p;

d2=0.0;c=0.0;g=0.0;

for (i=0;i<=n-1;i++)

{

q=x[i]-z-p;d2=d2+q*q;

c=c+y[i]*q;

g=g+(x[i]-z)*q*q;

}

c=c/d2;p=g/d2;q=d2/d1;

d1=d2;

a[1]=c*t[1];a[0]=c*t[0]+a[0];

}

for (j=2;j<=m;j++)

{

s[j]=t[j-1];

s[j-1]=-p*t[j-1]+t[j-2];

if(j>=3)

for (k=j-2;k>=1;k--)

s[k]=-p*t[k]+t[k-1]-q*b[k];

s[0]=-p*t[0]-q*b[0];

d2=0.0;c=0.0;g=0.0;

for (i=0;i<=n-1;i++)

{ q=s[j];

for(k=j-1;k>=0;k--)

q=q*(x[i]-z)+s[k];

d2=d2+q*q;c=c+y[i]*q;

g=g+(x[i]-z)*q*q;

}

c=c/d2;p=g/d2;q=d2/d1;

d1=d2;

a[j]=c*s[j];t[j]=s[j];

for (k=j-1;k>=0;k--)

{

a[k]=c*s[k]+a[k];

b[k]=t[k];t[k]=s[k];

}

}

}

void pirl::output() //输出m次拟合多项式的m+1个系数

{

int i;

char str2[25];

cout<<"\n输出文件名:";

cin>>str2;

ofstream fout (str2);

if (!fout)

{cout<<"\n不能打开这个文件"<

for (i=0;i<=m;i++)

{

fout<

cout<

}

fout.close();

}

double Diedai(double a,double b,double c,double d)//********迭代定义

{

double xn,xn1=0.45,f,f1;

do

{

xn=xn1;

f=a+xn*b+c*pow(xn,2)+d*pow(xn,3);

f1=b+2*c*xn+3*d*pow(xn,2);

xn1=xn-f/f1;

}while(fabs(xn1-xn)>=1e-6);

return xn1;

}

void main() //主函数

{

double xf=0.45;

double xd=0.966;

double xw=0.0118;

double p;

int Q,j;

xq=xf;

int i; //高斯法求W,D.

double a[2][3]={1,1,1,xd,xw,xf};

double b[3];

for(i=0;i<3;i++)

b[i]=a[1][i]-a[0][i]*xd;

W=G(b[1],b[2]);

D=F-G(b[1],b[2]);

cout<<"W="<

if (!ft)

{cout<<"\n不能打开这个文件 pirl.txt"<

for (k=0;k<25;k++)

ft<<0.1*k<<" "<<0.1*k-exp(-0.1*k)<

ft.close();

solution.input(); //由文件读入n个数据点(x,y)

solution.fit(); //执行最小二乘法的曲线拟合

solution.output(); //输出m次拟合多项式的m+1个系数

double a0=0.006561875; //根据系数A,B,C,D求出a0,a1,a2,a3. double a1=2.13811475;

double a2=-1.7405855;

double a3=0.598313;

double yq;

yq=a0+a1*xq+a2*pow(xq,2)+a3*pow(xq,3); //求yq。

cout<<"yq="<

R=1.5*(0.966-yq)/(yq-xq);

L=R*D;

cout<<"R="<

cout<

do //第二次循环解方程。

{ j++;

p=X[j-1]*(L+F)/(L+F-W)-W*xw/(L+F-W);

X[j]=Diedai(a0-p,a1,a2,a3);

}while(X[j]>=xw);

cout<<"理论塔板的数目是:"<

}

5.程序运行结果

6.程序调试过程出现的一些问题的讨论

(1).对于如何求方程组的程序,小组内曾存在争议。有组员认为用高斯法求解较好,因为有更强的数学性,可以多了解一种数学求解方法。有组员认为用一般的求一元二次方程组的方法即可,因为这样更易理解,减少了工作量。后来通过组内讨论,决定用高斯法,为的是挑战自己。

(2)对于这次课程实习,我们组觉得最具挑战性的是用最小二乘法求曲线拟合。我们没学过最小二乘法这种方法,不知道原理更别说自己编程了。于是我们在图书馆借了本算法程序集,把书上的程序理解后输入到电脑上,但是书上的算法和我们要解决的问题有很大出入。书上的算法用到了类和文件流输入与输出,而计算机老师对这两方面讲的不是很详细,所以我们再把书仔细的看了一遍。之后又把程序修改了很多,但是每次都过不了,于是我们和外组的同学又一起讨论了下,最后才明白问题出在文件的输入与输出上,所以我们又创了个文件输入了数据,最后才通过了!

(3)调试程序之中还粗心大意出了很多次低级错误,比如第一次调试过程中没有包含文件导致很多次都没通过,最后一仔细看才知道,是问题出在头文件上。记得还有一次,问题出在数据的定义上,运行时出现了“possible loss of data”的提示,之后把数据的

类型都改成了double才解决了这一问题。还记得我们很多次还掉了“;”之后讨论了好久才找出,出了错误实在不应该的。

(4)还有一次记得一个组员犯了一个太粗心的错误,他把第三步求R值时将xq带入了方程2导致求得R变成了负数,最后组内讨论好久才纠正。

7.后记

起初,面对这一程序设计感到十分茫然,化工原理和计算方法都是没学过的,无从下手。经过分析课件和查阅资料渐渐对原理和方法有了了解,对程序设计也有了头绪。然后通过分工合作和小组内交流商讨对课程内容有了更深的理解,使程序逐渐完整。最后通过不断地调试和修改完成了课程设计。

通过这次C语言程序设计,我了解了精馏原理和精馏的操作流程,对物料衡算,线性方程的拟合及计算,以及理论塔板数的求法有了初步掌握。了解了高斯主元消去法和最小二乘法在数据处理及曲线拟合中的应用。提高了自学能力和查找资料的能力,懂得了团队合作的重要性,感受到了不断学习虚心求教的必要性。

相关主题