58. 2017/06/0758
⋮
type :: Vector2d
real(8),public :: x
real(8),public :: y
contains
procedure,public,pass :: magnitude !大きさを計算する手続
end type Vector2d
contains
!magnitudeの実装
real(8) function magnitude(this)
implicit none
class(Vector2d),intent(in) :: this
magnitude = sqrt(this%x**2+this%y**2)
end function magnitude
⋮
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
82. 2017/06/0782
type :: Vector2d
⋮
procedure,public,pass :: isOrthogonal
!拡張演算と手続の対応付け
generic :: operator(.orth.) => isOrthogonal
end type Vector2d
⋮
logical function isOrthogonal(this,term2)
implicit none
class(Vector2d),intent(in) :: this
class(Vector2d),intent(in) :: term2
!ゼロベクトルは対象外
if(abs(this%dot(term2))<1d‐14)then !内積が10‐14未満なら
isOrthogonal = .true. !0とみなして直交
else
isOrthogonal = .false. !10‐14以上なら非直交
end if
end function isOrthogonal
class_Vector2d.f90
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
83. 2017/06/0783
program main
use class_Vector2d
implicit none
type(Vector2d) :: u,v
u%x = 2d0; u%y = 1d0
v%x = ‐1d0; v%y = 2d0
if(u .orth. v)then
print *,'u and v are orthogonal to each other'
else
print *,'u and v are not orthogonal to each other'
end if
end program main
main.f90
u and v are orthogonal to each other
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
88. 2017/06/0788
program main
use class_Vector3d
implicit none
type(Vector3d) :: u,v
u%x = 3d0; u%y = 2d0; u%z = 1d0
v%x = 1d0; v%y = 0d0; v%z = ‐3d0
if(u .orth. v)then
print *,'u and v are orthogonal to each other'
else
print *,'u and v are not orthogonal to each other'
end if
end program main
main.f90
u and v are orthogonal to each other
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
98. 2017/06/0798
program convection
use parameters,only:Nx,Nt,dt,c
use kernel,only:initialize,computeDifference
implicit none
real(8),allocatable :: f (:)
real(8),allocatable :: d_f_dx(:)
integer :: n
allocate( f (Nx))
allocate(d_f_dx(Nx))
call initialize(f)
do n=1,Nt
call computeDifference(d_f_dx,f)
f(:) = f(:) ‐ dt*c*d_f_dx(:)
end do
deallocate( f )
deallocate(d_f_dx)
end program convection
main.f90
x
f
tcΔff
n
n1n
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
106. 2017/06/07106
real(8) :: f(N), d_f_dx(N)
do n=1, n_end
call computeDifference(f, d_f_dx, N)
f(:) = f(:) ‐ dt*c*d_f_dx(:)
end do
物理量とその微分
値が分離
微分値と微分
の計算が分離
type(Field) :: f
do n=1, n_end
f = f ‐ dt*c*f%x()
end do
物理量と微分値,
微分の計算を包括
書籍等に書かれて
いる式と類似
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
手続き型
OOP
112. 2017/06/07112
program convection_oop
use parameters,only:Nt,c,dt
use class_Field
implicit none
type(Field) :: f !場を表す派生型の変数
integer :: n
call f%construct() !前処理
call f%initialize() !値の初期化
do n=1,Nt
f = f + f%x()*‐c*dt !時間積分
end do
call f%destruct() !後処理
end program convection_oop
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
119. 2017/06/07119
program convection_oop
use parameters,only:Nt,c,dt
use class_Field
implicit none
type(Field) :: f !場を表す派生型の変数
integer :: n
call f%construct() !前処理
call f%initialize() !値の初期化
do n=1,Nt
f = f + f%x()*‐c*dt !時間積分
end do
call f%destruct() !後処理
end program convection_oop
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
120. 2017/06/07120
program convection_oop
use parameters,only:Nt,c,dt
use class_Field
implicit none
type(Field) :: f, f05 !場を表す派生型の変数
integer :: n
call f%construct() !前処理
call f05%construct() !
call f%initialize() !値の初期化
do n=1,Nt
f05 = f + f%x()*‐c*dt !時間積分
f = f + (f%x()+f05%x())/2d0*‐c*dt !
end do
call f%destruct() !後処理
call f05%destruct() !
end program convection_oop
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
136. 2017/06/07136 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
program main
⋮
implicit none
type(Parameter1d) :: x,y,t
type(FieldParameter2d) :: cavity
type(FractionalStep) :: fs_cavity
call cavity%construct( x, y, t ,fluid=Water,Re=Re,...)
!計算条件とPoissonソルバをアルゴリズムに渡して初期化
call fs_cavity%construct(Field = cavity,&
Solver = SOR(&
error_tolerance = 1d‐9,&
accelaration = 1.925d0))
!時間積分開始
call fs_cavity%integrate(from=1, to=Nt)
end program main
main.f90
137. 2017/06/07137 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
subroutine integrate(this,from,to)
⋮
TimeIntegrate:block
integer :: n
do n=ts,te
call this%computeAuxiliaryVelocity()
call this%computePressure()
call this%computeVelocity()
end do
end block TimeIntegrate
end subroutine integrate
FractionalStep.f90
138. 2017/06/07138 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
subroutine computePressure(this)
implicit none
class(FractionalStep),intent(inout) :: this
call this%solver%solve(this%pres,this%dive)
end subroutine computePressure
FractionalStep.f90