吊橋的程式
這次的吊橋,自己有嘗試去寫過,可是卻漏洞百出,慘不忍睹阿,只好參考同學所作出來的程式,經過一番了解,與跟人探討後,無形中亦學到了很多東西!雖然這個版本的程式,每個後面都有註解,但還是有些東西是字面上所得不到的,一定要自己思考過,重新寫過一次,這樣東西才會變成自己的!
===================================================================
module bridge();
real fL,fR,w,dx,ans,t1,t2,t3,a;
real change,app,dff,max;
integer i; //正整數I
parameter nodes=11; //節點我看就不要改好ㄌ
reg[0:100]x[0:nodes]; //有N個點每一點都有100個位元
reg[0:100]a1,a2,a3,temp;
initial //initial區塊
begin
dff=1.0; //為分兩次的值
fL=10.0; //吊橋最左邊低高度
fR=20.0; //吊橋最右邊低高度
w=10.0; //吊橋低寬度
a=(fR-fL-0.5*dff*w*w)/w; //為解析法中X項的的係數0.5*dff*i*dx*i*dx+"a"*i*dx+fL
dx=w/(nodes-1); //節點之間低距離
max=1.0; //最大誤差起始值
x[0]=$realtobits(fL); //將FL轉成2進制存到X[0]裡面
x[nodes-1]=$realtobits(fR); //將FR轉成2進制存到x[nodes-1]裡面
for(i=1;i<=nodes-2;i=i+1) //起始化但是保留最左邊根最右邊的值 x[i]=0.0; //將X[1]到X[9]起始值都設為0 while (max>0.001)//最大誤差要是比0.001大或是-0.001大就進入回圈
begin
max=0.0;
for(i=1;i<=nodes-2;i=i+1)//此FOR迴圈開始就是疊代 begin //此三數為連續如456那a1=4 a2=5 a3=6 a1=x[i-1];//左邊的點 a2=x[i];//中間的點 a3=x[i+1];//右邊的點 t1=$bitstoreal(a1);//必須轉回10進制才能運算 t2=$bitstoreal(a2);//必須轉回10進制才能運算 t3=$bitstoreal(a3);//必須轉回10進制才能運算 ans=0.5*(t1+t3-dff*dx*dx);//此行老師為必考推導過程下面附注 change=ans-t2;//把後面算出來的減掉前一次所算出的答案 x[i]=$realtobits(ans);//把ANS轉成2進制存到X[i] if(change<0) change="change*-1.0;//">max)//change要是比MAX大MAX換成change
max=change;//
end
end
for(i=0;i
temp=x[i];//將上一個迴圈的X[i]抓下來存到temp
app=$bitstoreal(temp);//再把temp轉成10進制存到app
$display(" nodes %d\n 差分 %f 解析 %f\n"
,i,app,0.5*dff*i*dx*i*dx+a*i*dx+fL);
//0.5*dff*i*dx*i*dx+a*i*dx+fL此行為解析法就是對dff做兩次積分所得到的]
end
end
endmodule
//ANS推導
//d^2w/dx^2={a1-2(a2)+a3}/dx^2=dff
//{a1-2(a2)+a3}/dx^2=dff把此式做移項
//a1-2a2+a3=(dff)(dx^2)
//2a2=(dff)(dx^2)-a1-a3
//a2={(dff)(dx^2)-a1-a3}/2
//參考老師C語言P195頁
//a=(fR-fL-0.5*dff*w*w)/w;推導
//對d^2w/dx^2=dff做兩次積分
//dw/dx=dff*x+a第一次積分
//w(x)=1/2(dff*x^2)+a*x+b
//將邊界條件帶入
//當x=0(即是吊橋最左邊=fl)w(0)=fl
//1/2(dff*0^2)+a*0+b=fl所以a跟dff項為0所以fl=b
//所以原式改寫成
//w(x)=1/2(dff*x^2)+a*x+fl
//當x=10(即是吊橋最左邊=fr)w(10)=fr
//1/2(dff*w^2)+a*w+fl=fr
//求出a
//a*w=fr-fl-1/2(dff*w^2)
//a={fr-fl-1/2(dff*w^2)}/w
//搞定
0 Comments:
Post a Comment
<< Home