module shallow_water integer, parameter:: double = kind(0.0d0) type shallow real(double), pointer:: u(:, :), ux(:, :), uy(:, :) real(double), pointer:: v(:, :), vx(:, :), vy(:, :) real(double), pointer:: h(:, :), hx(:, :), hy(:, :) ! 関数結果の場合だけ真, 変数にストアされると偽. logical:: temporary end type interface allocate module procedure allocate_basic module procedure allocate_constant end interface interface assignment(=) module procedure assign end interface interface operator(+) module procedure add end interface interface operator(*) module procedure mul end interface interface size module procedure size_shallow end interface contains ! 不定結合状態の変数を初期化 subroutine nullify(shall) type(SHALLOW):: shall nullify(shall%u, shall%u, shall%v) nullify(shall%ux, shall%uy, shall%vx) nullify(shall%vy, shall%hx, shall%hy) shall%temporary = .FALSE. end subroutine ! 不定結合状態の変数を初期化 subroutine allocate_basic(shall, nx, ny, temporary) type(SHALLOW):: shall integer, intent(in):: nx, ny logical, intent(in), optional:: temporary continue allocate(shall%u(nx, ny), shall%v(nx, ny), shall%h(nx, ny)) nullify(shall%ux, shall%uy, shall%vx, shall%vy, shall%hx, shall%hy) shall%temporary = .FALSE. if (present(temporary)) shall%temporary = temporary end subroutine subroutine deallocate(shall) type(SHALLOW):: shall if (associated(shall%u)) deallocate(shall%u, shall%v, shall%h) call nullify(shall) shall%temporary = .FALSE. end subroutine subroutine assign(lhs, rhs) type(SHALLOW), intent(out):: lhs type(SHALLOW), intent(in):: rhs lhs%temporary = .FALSE. lhs%u => rhs%u lhs%v => rhs%v lhs%h => rhs%h end subroutine integer function size_shallow(stat, dimord) result(result) type(SHALLOW):: stat integer:: dimord select case(dimord) case(1) result = size(stat%h, 1) case(2) result = size(stat%h, 2) case default result = 0 end select end function type(SHALLOW) function add(lhs, rhs) result(result) type(SHALLOW), intent(in):: lhs type(SHALLOW), intent(in):: rhs call allocate(result, size(lhs, 1), size(lhs, 2)) result%temporary = .TRUE. result%u = lhs%u + rhs%u result%v = lhs%v + rhs%v result%h = lhs%h + rhs%h if (lhs%temporary) call deallocate(lhs) if (rhs%temporary) call deallocate(rhs) end function type(SHALLOW) function mul(lhs, rhs) result(result) real(DOUBLE), intent(in):: lhs type(SHALLOW), intent(in):: rhs call Allocate(result, size(rhs, 1), size(rhs, 2)) result%temporary = .TRUE. result%u = lhs * rhs%u result%v = lhs * rhs%v result%h = lhs * rhs%h if (rhs%temporary) call deallocate(rhs) end function ! 不定結合状態の変数を初期化 subroutine allocate_constant(stat, nx, ny, H) type(SHALLOW):: stat integer, intent(in):: nx, ny real(double), intent(in):: H continue call Allocate(stat, nx, ny) stat%u(:, :) = 0.0_double stat%v(:, :) = 0.0_double stat%h(:, :) = H end subroutine end module shallow_water