数値解析講座
|
科学技術者の技術の向上を支援することを目的として、基礎的な数値解析講座として Newton法、Runge-kutta 法、Euler法、Bisection法についての解法を解説するとともに、それらのソースプログラムを紹介した。また、流出解析手法として、広く活用されてきている貯留関数法についても、解説とソースプログラムを紹介した。 |
●数値解析法の説明(PDF) Newton法 Runge-kutta 法 Euler法 Bisection法 ●ソースプログラム(fortran言語) 方程式X : f(x)=a+X**P (P=3、a=3)
●計算結果(貯留関数法) 方程式X ソースプログラム c program open(10,file='out.csv') c 方程式 f(x)=a + x**p a=-3.0 p=3.0 eps=1.e-5 call newton(a,p,eps) call runge(a,p,eps) call euler(a,p,eps) call bisection(a,p,eps) pause 'end' stop end c----------------------------------------------------- subroutine newton(a,p,eps) funk(x) = a + x**p funk2(x)=p*x**(p-1) write(10,*) 'newton' write(10,*) 'f(x),x' x = 3.0 !初期値 do i=1,100 ax=funk(x)/funk2(x) x=x-ax if(abs(funk(x)).le.eps) go to 1000 write(10,9999) funk(x),x 9999 format(f10.4,',',f10.4) enddo 1000 continue write(*,*) 'newton ans= ',x write(10,'(a6,f10.3)') 'ans= ,',x return end c----------------------------------------------------- subroutine runge(a,p,eps) funk(x) = a + x**p write(10,*) 'runge' write(10,*) 'f(x),x' x = 0.1 !初期値 h = 0.1 !刻み幅 do i=1, 100 a1 = h * funk(x) a2 = h * funk(x + a1/2.) a3 = h * funk(x + a2/2.) a4 = h * funk(x + a3) x = x - (a1 + 2.*a2 + 2.*a3 + a4)/6. if(abs(funk(x)).le.eps) go to 1000 write(10,9999) funk(x),x 9999 format(f10.4,',',f10.4) end do 1000 continue write(*,*) 'runge ans= ',x write(10,'(a6,f10.3)') 'ans= ,',x return end c----------------------------------------------------- subroutine euler(a,p,eps) funk(x)=a+x**p write(10,*) 'euler' write(10,*) 'f(x),x' x=0.1 !初期値 h=0.1 !刻み幅 do i=1,50 x=x-funk(x)*h if(abs(funk(x)).le.eps) go to 1000 write(10,9999) funk(x),x 9999 format(f10.4,',',f10.4) enddo 1000 continue write(*,*) 'euler ans= ',x write(10,'(a6,f10.3)') 'ans= ,',x return end c----------------------------------------------------- subroutine bisection(a,p,eps) funk(x)=a+x**p write(10,*) 'bisection' write(10,*) 'f(x),x' dh=5.0 !上限値 dl=-1.0 !下限値 x=3.0 !初期値 3000 continue write(10,9999) funk(x),x 9999 format(f10.4,',',f10.4) if(abs(funk(x)).le.eps) go to 1000 if(funk(x).gt.0.0) go to 2000 dl=x x=(dh+dl)/2.0 go to 3000 2000 dh=x x=(dh+dl)/2.0 go to 3000 c 1000 continue write(*,*) 'bisection ans= ',x write(10,'(a6,f10.3)') 'ans= ,',x return end c program dimension r(10) data r/3.0, 8.0,16.0,26.0,14.2,3.0,0.0,0.0,0.0,0.0/ ! 時間雨量 open(10,file='out.csv') !出力ファイル write(10,*) '方程式(貯留関数法)' + ,'f(sq2)=r-(sq1+sq2)/2-k*sq2**p+k*sq1**p を解く (Q=sq*A/3.6)' eps=1.e-5 ak=8.0 p=0.6 a=10.8 write(10,*) '○定数' write(10,*) 'k=,',ak write(10,*) 'p=,',p write(10,*) 'A=,',a,',km2' write(10,*) 'TL=,',' 0.0',',hr' write(10,*) 'f1=,',' 0.0' write(10,*) 'Rsa=,',' 0.0',',mm' c write(10,*) '○計算結果' c write(*,*) 'Newton' write(10,*) 'Newton,r(mm/hr),sq(mm/hr),Q(m3/s)' sq1=0.001 do i=1,10 call newton(ak,p,a,r(i),sq1,eps,x) sq1=x enddo c write(*,*) 'Runge' write(10,*) 'Runge,r(mm/hr),sq(mm/hr),Q(m3/s)' sq1=0.001 do i=1,10 call runge(ak,p,a,r(i),sq1,eps,x) sq1=x enddo c write(*,*) 'Euler' write(10,*) 'Euler,r(mm/hr),sq(mm/hr),Q(m3/s)' sq1=0.001 do i=1,10 call euler(ak,p,a,r(i),sq1,eps,x) sq1=x enddo c write(*,*) 'Bisection' write(10,*) 'Bisection,r(mm/hr),sq(mm/hr),Q(m3/s)' sq1=0.001 do i=1,10 call bisection(ak,p,a,r(i),sq1,eps,x) sq1=x enddo pause 'end' stop end c---------------------------------------------------------- subroutine newton(ak,p,a,r,sq1,eps,x) funk(sq2)=r-(sq1+sq2)/2-ak*sq2**p+ak*sq1**p funk2(sq2)=-ak*p*sq2**(p-1)-0.5 ! = f’(sq2) x = 0.0001 !初期値 do i=1,100 xn=funk(x)/funk2(x) x=x-xn if(abs(funk(x)).le.eps) go to 1000 enddo 1000 continue write(10,9000) r,x,x*a/3.6 9000 format(3(',',f10.3)) write(*,*) r,x,x*a/3.6 end c---------------------------------------------------------- subroutine runge(ak,p,a,r,sq1,eps,x) funk(sq2) = r-(sq1+sq2)/2-ak*sq2**p+ak*sq1**p x = 100.0 !初期値 h = -0.1 !刻み幅 do i=1, 100 a1 = h * funk(x) a2 = h * funk(x + a1/2.) a3 = h * funk(x + a2/2.) a4 = h * funk(x + a3) x = x - (a1 + 2.*a2 + 2.*a3 + a4)/6. if(abs(funk(x)).le.eps) go to 1000 end do 1000 continue write(10,9000) r,x,x*a/3.6 9000 format(3(',',f10.3)) write(*,*) r,x,x*a/3.6 return end c---------------------------------------------------------- subroutine euler(ak,p,a,r,sq1,eps,x) funk(sq2) = r-(sq1+sq2)/2-ak*sq2**p+ak*sq1**p x=100.0 !初期値 h=-0.1 !刻み幅 do i=1,50 x=x-funk(x)*h if(abs(funk(x)).le.eps) go to 1000 enddo 1000 continue write(10,9000) r,x,x*a/3.6 9000 format(3(',',f10.3)) write(*,*) r,x,x*a/3.6 return end c---------------------------------------------------------- subroutine bisection(ak,p,a,r,sq1,eps,x) funk(sq2) = r-(sq1+sq2)/2-ak*sq2**p+ak*sq1**p dh=1000.0 !上限値 dl=0.0 !下限値 x=dh !初期値 3000 continue if(abs(funk(x)).le.eps) go to 1000 if(funk(x).gt.0.0) go to 2000 dh=x x=(dh+dl)/2.0 go to 3000 2000 dl=x x=(dh+dl)/2.0 go to 3000 c 1000 continue write(10,9000) r,x,x*a/3.6 9000 format(3(',',f10.3)) write(*,*) r,x,x*a/3.6 return end |
数値解析講座
|