/
compute_z_mod.f90
101 lines (81 loc) · 3.25 KB
/
compute_z_mod.f90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
!> \brief Compute the potential vorticity, z
!! \detail Given the current pressure and velocity fields,
!! computes the potential voriticity.
module compute_z_mod
use kind_params_mod
use kernel_mod
use argument_mod
use grid_mod
use field_mod
implicit none
private
public invoke_compute_z
public compute_z, compute_z_code
type, extends(kernel_type) :: compute_z
type(go_arg), dimension(6) :: meta_args = &
(/ go_arg(GO_WRITE, GO_CF, GO_POINTWISE), & ! z
go_arg(GO_READ, GO_CT, GO_POINTWISE), & ! p
go_arg(GO_READ, GO_CU, GO_POINTWISE), & ! u
go_arg(GO_READ, GO_CV, GO_POINTWISE), & ! v
go_arg(GO_READ, GO_GRID_DX_CONST), & ! dx
go_arg(GO_READ, GO_GRID_DY_CONST) & ! dy
/)
!> This kernel operates on fields that live on an
!! orthogonal, regular grid.
integer :: GRID_TYPE = GO_ORTHOGONAL_REGULAR
!> This kernel writes only to internal points of the
!! simulation domain.
integer :: ITERATES_OVER = GO_INTERNAL_PTS
!> Although the staggering of variables used in an Arakawa
!! C grid is well defined, the way in which they are indexed is
!! an implementation choice. This can be thought of as choosing
!! which grid-point types have the same (i,j) index as a T
!! point. This kernel assumes that the U,V and F points that
!! share the same index as a given T point are those immediately
!! to the South and West of it.
integer :: index_offset = GO_OFFSET_SW
contains
procedure, nopass :: code => compute_z_code
end type compute_z
contains
!===================================================
!> Manual implementation of the code needed to invoke
!! compute_z_code().
subroutine invoke_compute_z(zfld, pfld, ufld, vfld)
implicit none
type(r2d_field), intent(inout) :: zfld
type(r2d_field), intent(in) :: pfld, ufld, vfld
! Locals
integer :: I, J
real(go_wp) :: dx, dy
dx = zfld%grid%dx
dy = zfld%grid%dy
do J=zfld%internal%ystart, zfld%internal%ystop, 1
do I=zfld%internal%xstart, zfld%internal%xstop, 1
call compute_z_code(i, j, &
zfld%data, &
pfld%data, &
ufld%data, &
vfld%data, &
dx, dy)
end do
end do
end subroutine invoke_compute_z
!===================================================
!> Compute the potential vorticity on the grid point (i,j)
subroutine compute_z_code(i, j, z, p, u, v, dx, dy)
implicit none
integer, intent(in) :: I, J
real(go_wp), intent(in) :: dx, dy
real(go_wp), intent(inout), dimension(:,:) :: z
real(go_wp), intent(in), dimension(:,:) :: p, u, v
! Original code looked like:
! DO J=1,N
! DO I=1,M
! Z(I+1,J+1) =(FSDX*(V(I+1,J+1)-V(I,J+1))-FSDY*(U(I+1,J+1) &
! -U(I+1,J)))/(P(I,J)+P(I+1,J)+P(I+1,J+1)+P(I,J+1))
Z(I,J) =( (4.0d0/dx)*( V(I,J)-V(I-1,J))- &
(4.0d0/dy)*( U(I,J)-U(I,J-1)) ) / &
(P(I-1,J-1)+P(I,J-1)+ P(I,J)+P(I-1,J))
end subroutine compute_z_code
end module compute_z_mod