Fortran90で自分で型を定義し、それを使用します。
本稿でいう”型”は、一般には構造体と呼ばれます。
Fortran使用者にとっては”型”という名称が分かりやすいでしょう。
整数型、倍精度型などと同列にあるもの、と考えて差し支えないです。
本稿では基本的なことしか書いていません。
二階偏微分の計算の時でも構造体の考えを使用していますので、もう少し例が欲しい方はこちらもどうぞ。
Hyper-dual numbersによる二階偏微分の計算 -シキノート
概要
簡単な実例
module CEOM_mod
implicit none
type Particle
double precision::m,x,v
end type Particle
end module CEOM_mod
program main
use CEOM_mod
implicit none
type(Particle)::p1
p1%m = 1d0
p1%x = 2d0
p1%v = 3d0
write(6,*)p1%m,p1%x,p1%v
stop
end program main
実行結果
$ ./a.out
1.0000000000000000 2.0000000000000000 3.0000000000000000
$
1.0000000000000000 2.0000000000000000 3.0000000000000000
$
説明
上は、粒子p1が質量m, 位置x, 速度vを持つ、ということを想定しています。
そこで、Particleという新しい”型”(複素数型みたいに、実部と虚部という2つの独立な変数を1つの複素数型変数が持つ、みたいな変数の型)を定義しました。
Particle型を持つ変数は、すべてm, x, vを内包するというイメージです。
mainプログラムではparticle型が定義されているモジュールを呼び出すために
use CEOM_mod
という文を入れ、実際にparticle型の変数p1を定義するために
type(Particle)::p1
と書いています。変数p1が定義されると自動的にp1が持つm,x,vの固有な値も定義されます。固有の値をいじる場合は
p1%m = 1d0
と書いて、変数に%をつけてm,x,vのいずれかを書いて代入します。
例
配列
module CEOM_mod
implicit none
type Particle
double precision::m,x,v
end type Particle
end module CEOM_mod
program main
use CEOM_mod
implicit none
integer::i,N
type(Particle),allocatable::p(:)
N=5
allocate(p(1:N))
do i=1,N
p(i)%m = 1d0
p(i)%x = dble(i)
p(i)%v = 0.1d0*i
enddo
do i=1,N
write(6,*)i,p(i)%m,p(i)%x,p(i)%v
enddo
stop
end program main
実行結果
$ ./a.out
1 1.0000000000000000 1.0000000000000000 0.10000000000000001<br />
2 1.0000000000000000 2.0000000000000000 0.20000000000000001<br />
3 1.0000000000000000 3.0000000000000000 0.30000000000000004<br />
4 1.0000000000000000 4.0000000000000000 0.40000000000000002<br />
5 1.0000000000000000 5.0000000000000000 0.50000000000000000
$
1 1.0000000000000000 1.0000000000000000 0.10000000000000001<br />
2 1.0000000000000000 2.0000000000000000 0.20000000000000001<br />
3 1.0000000000000000 3.0000000000000000 0.30000000000000004<br />
4 1.0000000000000000 4.0000000000000000 0.40000000000000002<br />
5 1.0000000000000000 5.0000000000000000 0.50000000000000000
$
サブルーチンの利用
module CEOM_mod
implicit none
type Particle
double precision::m,x,v
end type Particle
end module CEOM_mod
subroutine twicemass(N,p)
use CEOM_mod
implicit none
integer,intent(in)::N
type(Particle),intent(inout)::p(1:N)
integer::i
do i=1,N
p(i)%m = 2 * p(i)%m
enddo
return
end subroutine twicemass
program main
use CEOM_mod
implicit none
integer::i,N
type(Particle),allocatable::p(:)
N=3
allocate(p(1:N))
do i=1,N
p(i)%m = 1d0
p(i)%x = dble(i)
p(i)%v = 0.1d0*i
enddo
call twicemass(N,p)
do i=1,N
write(6,*)i,p(i)%m,p(i)%x,p(i)%v
enddo
stop
end program main
実行結果
$ ./a.out
1 2.0000000000000000 1.0000000000000000 0.10000000000000001<br />
2 2.0000000000000000 2.0000000000000000 0.20000000000000001<br />
3 2.0000000000000000 3.0000000000000000 0.30000000000000004<br />
$
1 2.0000000000000000 1.0000000000000000 0.10000000000000001<br />
2 2.0000000000000000 2.0000000000000000 0.20000000000000001<br />
3 2.0000000000000000 3.0000000000000000 0.30000000000000004<br />
$
補足
オブジェクト指向になれている方は、構造体の中身を外部から直接アクセスできる点で褒められた書き方ではないでしょう。
Fortran90にオブジェクト指向の考え方を持ってくるのは、計算速度というFortran90の長所を潰してしまうので、このくらいで良いでしょう。