【Fortranコード】死ぬほどべた書きで書いた「バーンズリーのシダ」のプログラム
最近出たこちらの参考書をきっかけにFortranを勉強しています。
思いっきりべた書きで「バーンズリーのシダ」のコードをFortranで書いてみました。あまりきれいで汎用性があるコードではありませんが追々書き換えていくつもりです。
バーンズリーのシダって何?って感じかもしれませんが、下記wikipediaにあるようにフラクタル構造を持った植物です。
これをモデル化してFortranで数値計算させるということです。
理論解説は上記wikipediaに解説があるのでご参照ください。
Fortranコード
program main
implicit none
integer, parameter :: Nmax=500000, Nx=512, Ny=512
double precision, parameter :: Lx=6.d0, Ly=6.d0, dx=Lx/dble(Nx), dy=Ly/dble(Ny)
complex(kind(0d0)), parameter :: uso=(0.d0,1.d0)
integer :: i, j, n, m, ix, iy
real(kind=8)::random_value
double precision:: x, y
double precision, allocatable, dimension(:) :: x_, y_
double precision, allocatable, dimension(:,:) :: f
character(len=40) filename
call system("mkdir data")
! 配列の割付
allocate(x_(0:Nx-1), y_(0:Ny-1))
allocate(f(0:Nx-1,0:Ny-1))
m = 0
! x, y座標
x = 0
y = 0
do j=0,Ny-1
do i=0,Nx-1
x_(i) = -Lx/2.d0+dx*dble(i)
y_(j) = -Ly/2.d0+dy*dble(j)
end do
end do
do i=0, Nmax
call random_seed !乱数の初期値
call random_number(random_value)
if (0<= random_value .and. random_value<0.01) then
x = 0.d0
y = 0.16d0*y
ix = int(Nx/2 + x*Nx/10)
iy = int(y * Ny /12)
f(ix,iy) = 1.0d0
else if (0.01d0<= random_value .and. random_value<0.86d0) then
x = 0.85*x + 0.04d0*y
y = -0.04d0*x + 0.85d0*y +1.6d0
ix = int(Nx/2 + x*Nx/10)
iy = int(y * Ny /12)
f(ix,iy) = 1.0d0
else if(0.86d0<= random_value .and. random_value<0.93d0) then
x = 0.2d0*x - 0.26d0*y
y = 0.23d0*x + 0.22d0*y +1.6d0
ix = int(Nx/2 + x*Nx/10)
iy = int(y * Ny /12)
f(ix,iy) = 1.0d0
else
x =-0.15d0*x + 0.28d0*y
y = 0.26d0*x + 0.24d0*y +0.44d0
ix = int(Nx/2 + x*Nx/10)
iy = int(y * Ny /12)
f(ix,iy) = 1.0d0
end if
end do
!-----------------------------------------------------------------------------------
!output of movie file
write(filename,"(a,i5.5,a)") "data/barsley_",int(m),".vtk"
open(10,file=filename)
write(10,"('# vtk DataFile Version 3.0')")
write(10,"('test')")
write(10,"('ASCII ')")
write(10,"('DATASET STRUCTURED_GRID')")
write(10,"('DIMENSIONS ',3(1x,i3))") Nx, Ny, 1
write(10,"('POINTS ',i9,' float')") Nx*Ny*1
do j=0,Ny-1
do i=0,Nx-1
write(10,"(3(f9.4,1x))") x_(i), y_(j), 0.d0
end do
end do
write(10,"('POINT_DATA ',i9)") Nx*Ny*1
!date input
write(10,"('SCALARS julia float')")
write(10,"('LOOKUP_TABLE default')")
do j=0,Ny-1
do i=0,Nx-1
write(10,*) f(i,j)
end do
end do
close(10)
deallocate(x_, y_, f)
end program main
paraviewで可視化するとこのようになります。
可視化にはVTKFortranというライブラリがあるので今後検討してみようと思います。
追ってsubroutineやmodulleといった機能ごとにプログラムを分けて管理しやすいようにして置こうと思います。
そうすることで初期状態、境界条件の設定のみを変えることで他のプログラム部分は意識せずにプログラムを組むことができるということになります。
Twitter➡@t_kun_kamakiri
Instagram➡kamakiri1225
youtube➡https://www.youtube.com/channel/UCbG6_Q9ZRqqVT6YZOpcjDlQ
ブログ➡宇宙に入ったカマキリ(物理ブログ)
ココナラ➡物理の質問サポートサービス
コミュニティ➡製造業ブロガー