forked from mom-ocean/MOM6
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgeneric_tracer_utils.F90
More file actions
323 lines (288 loc) · 15.9 KB
/
generic_tracer_utils.F90
File metadata and controls
323 lines (288 loc) · 15.9 KB
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
!> g_tracer_utils module consists of core utility subroutines to be used by
!! all generic tracer modules. These include the lowest level functions
!! for adding, allocating memory, and record keeping of individual generic
!! tracers irrespective of their physical/chemical nature.
module g_tracer_utils
use coupler_types_mod, only: coupler_2d_bc_type
use time_manager_mod, only : time_type
use field_manager_mod, only: fm_string_len
use MOM_diag_mediator, only : g_diag_ctrl=>diag_ctrl
implicit none ; private
!> Each generic tracer node is an instant of a FORTRAN type with the following member variables.
!! These member fields are supposed to uniquely define an individual tracer.
!! One such type shall be instantiated for EACH individual tracer.
type g_tracer_type
!> Tracer concentration field in space (and time)
!! MOM keeps the prognostic tracer fields at 3 time levels, hence 4D.
real, pointer, dimension(:,:,:,:) :: field => NULL()
!> Tracer concentration in river runoff
real, allocatable, dimension(:,:) :: trunoff
logical :: requires_restart = .true. !< Unknown
character(len=fm_string_len) :: src_file !< Tracer source filename
character(len=fm_string_len) :: src_var_name !< Tracer source variable name
character(len=fm_string_len) :: src_var_unit !< Tracer source variable units
character(len=fm_string_len) :: src_var_gridspec !< Tracer source grid file name
character(len=fm_string_len) :: obc_src_file_name !< Boundary condition tracer source filename
character(len=fm_string_len) :: obc_src_field_name !< Boundary condition tracer source fieldname
integer :: src_var_record !< Unknown
logical :: requires_src_info = .false. !< Unknown
real :: src_var_unit_conversion = 1.0 !< This factor depends on the tracer. Ask Jasmin
real :: src_var_valid_min = 0.0 !< Unknown
end type g_tracer_type
!> Unknown
type g_diag_type
integer :: dummy !< A dummy member, not part of the API
end type g_diag_type
!> The following type fields are common to ALL generic tracers and hence has to be instantiated only once
type g_tracer_common
! type(g_diag_ctrl) :: diag_CS !< Unknown
!> Domain extents
integer :: isd !< Start index of the data domain in the i-direction
integer :: jsd !< Start index of the data domain in the j-direction
end type g_tracer_common
!> Unknown dangerous module data!
type(g_tracer_common), target, save :: g_tracer_com
public :: g_tracer_type
public :: g_tracer_flux_init
public :: g_tracer_set_values
public :: g_tracer_get_values
public :: g_tracer_get_pointer
public :: g_tracer_get_common
public :: g_tracer_set_common
public :: g_tracer_set_csdiag
public :: g_tracer_send_diag
public :: g_tracer_get_name
public :: g_tracer_get_alias
public :: g_tracer_get_next
public :: g_tracer_is_prog
public :: g_diag_type
public :: g_tracer_get_obc_segment_props
!> Set the values of various (array) members of the tracer node g_tracer_type
!!
!! This function is overloaded to set the values of the following member variables
interface g_tracer_set_values
module procedure g_tracer_set_real
module procedure g_tracer_set_2D
module procedure g_tracer_set_3D
module procedure g_tracer_set_4D
end interface
!> Reverse of interface g_tracer_set_values for getting the tracer member arrays in the argument value
!!
!! This means "get the values of array %field_name for tracer tracer_name and put them in argument array_out"
interface g_tracer_get_values
module procedure g_tracer_get_4D_val
module procedure g_tracer_get_3D_val
module procedure g_tracer_get_2D_val
module procedure g_tracer_get_real
module procedure g_tracer_get_string
end interface
!> Return the pointer to the requested field of a particular tracer
!!
!! This means "get the pointer of array %field_name for tracer tracer_name in argument array_ptr"
interface g_tracer_get_pointer
module procedure g_tracer_get_4D
module procedure g_tracer_get_3D
module procedure g_tracer_get_2D
end interface
contains
!> Unknown
subroutine g_tracer_flux_init(g_tracer)
type(g_tracer_type), pointer :: g_tracer !< Pointer to this tracer node
end subroutine g_tracer_flux_init
!> Unknown
subroutine g_tracer_set_csdiag(diag_CS)
type(g_diag_ctrl), target,intent(in) :: diag_CS !< Unknown
end subroutine g_tracer_set_csdiag
subroutine g_tracer_set_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,axes,grid_tmask,grid_kmt,init_time)
integer, intent(in) :: isc !< Computation start index in i direction
integer, intent(in) :: iec !< Computation end index in i direction
integer, intent(in) :: jsc !< Computation start index in j direction
integer, intent(in) :: jec !< Computation end index in j direction
integer, intent(in) :: isd !< Data start index in i direction
integer, intent(in) :: ied !< Data end index in i direction
integer, intent(in) :: jsd !< Data start index in j direction
integer, intent(in) :: jed !< Data end index in j direction
integer, intent(in) :: nk !< Number of levels in k direction
integer, intent(in) :: ntau !< Unknown
integer, intent(in) :: axes(3) !< Domain axes?
real, dimension(isd:,jsd:,:),intent(in) :: grid_tmask !< Unknown
integer,dimension(isd:,jsd:),intent(in) :: grid_kmt !< Unknown
type(time_type), intent(in) :: init_time !< Unknown
end subroutine g_tracer_set_common
subroutine g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,&
axes,grid_tmask,grid_mask_coast,grid_kmt,init_time,diag_CS)
integer, intent(out) :: isc !< Computation start index in i direction
integer, intent(out) :: iec !< Computation end index in i direction
integer, intent(out) :: jsc !< Computation start index in j direction
integer, intent(out) :: jec !< Computation end index in j direction
integer, intent(out) :: isd !< Data start index in i direction
integer, intent(out) :: ied !< Data end index in i direction
integer, intent(out) :: jsd !< Data start index in j direction
integer, intent(out) :: jed !< Data end index in j direction
integer, intent(out) :: nk !< Number of levels in k direction
integer, intent(out) :: ntau !< Unknown
integer, optional, intent(out) :: axes(3) !< Unknown
type(time_type), optional, intent(out) :: init_time !< Unknown
real, optional, dimension(:,:,:), pointer :: grid_tmask !< Unknown
integer, optional, dimension(:,:), pointer :: grid_mask_coast !< Unknown
integer, optional, dimension(:,:), pointer :: grid_kmt !< Unknown
type(g_diag_ctrl), optional, pointer :: diag_CS !< Unknown
end subroutine g_tracer_get_common
!> Unknown
subroutine g_tracer_get_4D(g_tracer_list,name,member,array_ptr)
character(len=*), intent(in) :: name !< Unknown
character(len=*), intent(in) :: member !< Unknown
type(g_tracer_type), pointer :: g_tracer_list !< Unknown
real, dimension(:,:,:,:), pointer :: array_ptr !< Unknown
end subroutine g_tracer_get_4D
!> Unknown
subroutine g_tracer_get_3D(g_tracer_list,name,member,array_ptr)
character(len=*), intent(in) :: name !< Unknown
character(len=*), intent(in) :: member !< Unknown
type(g_tracer_type), pointer :: g_tracer_list !< Unknown
real, dimension(:,:,:), pointer :: array_ptr !< Unknown
end subroutine g_tracer_get_3D
!> Unknown
subroutine g_tracer_get_2D(g_tracer_list,name,member,array_ptr)
character(len=*), intent(in) :: name !< Unknown
character(len=*), intent(in) :: member !< Unknown
type(g_tracer_type), pointer :: g_tracer_list !< Unknown
real, dimension(:,:), pointer :: array_ptr !< Unknown
end subroutine g_tracer_get_2D
!> Unknown
subroutine g_tracer_get_4D_val(g_tracer_list,name,member,array,isd,jsd)
character(len=*), intent(in) :: name !< Unknown
character(len=*), intent(in) :: member !< Unknown
type(g_tracer_type), pointer :: g_tracer_list !< Unknown
integer, intent(in) :: isd !< Unknown
integer, intent(in) :: jsd !< Unknown
real, dimension(isd:,jsd:,:,:), intent(out):: array !< Unknown
end subroutine g_tracer_get_4D_val
!> Unknown
subroutine g_tracer_get_3D_val(g_tracer_list,name,member,array,isd,jsd,ntau,positive)
character(len=*), intent(in) :: name !< Unknown
character(len=*), intent(in) :: member !< Unknown
type(g_tracer_type), pointer :: g_tracer_list !< Unknown
integer, intent(in) :: isd !< Unknown
integer, intent(in) :: jsd !< Unknown
integer, optional, intent(in) :: ntau !< Unknown
logical, optional, intent(in) :: positive !< Unknown
real, dimension(isd:,jsd:,:), intent(out):: array !< Unknown
integer :: tau
character(len=fm_string_len), parameter :: sub_name = 'g_tracer_get_3D_val'
end subroutine g_tracer_get_3D_val
!> Unknown
subroutine g_tracer_get_2D_val(g_tracer_list,name,member,array,isd,jsd)
character(len=*), intent(in) :: name !< Unknown
character(len=*), intent(in) :: member !< Unknown
type(g_tracer_type), pointer :: g_tracer_list !< Unknown
integer, intent(in) :: isd !< Unknown
integer, intent(in) :: jsd !< Unknown
real, dimension(isd:,jsd:), intent(out):: array !< Unknown
end subroutine g_tracer_get_2D_val
!> Unknown
subroutine g_tracer_get_real(g_tracer_list,name,member,value)
character(len=*), intent(in) :: name !< Unknown
character(len=*), intent(in) :: member !< Unknown
type(g_tracer_type), pointer :: g_tracer_list !< Unknown
real, intent(out):: value !< Unknown
end subroutine g_tracer_get_real
!> Unknown
subroutine g_tracer_get_string(g_tracer_list,name,member,string)
character(len=*), intent(in) :: name !< Unknown
character(len=*), intent(in) :: member !< Unknown
type(g_tracer_type), pointer :: g_tracer_list !< Unknown
character(len=fm_string_len), intent(out) :: string !< Unknown
end subroutine g_tracer_get_string
!> Unknown
subroutine g_tracer_set_2D(g_tracer_list,name,member,array,isd,jsd,weight)
character(len=*), intent(in) :: name !< Unknown
character(len=*), intent(in) :: member !< Unknown
type(g_tracer_type), pointer :: g_tracer_list !< Unknown
integer, intent(in) :: isd !< Unknown
integer, intent(in) :: jsd !< Unknown
real, dimension(isd:,jsd:),intent(in) :: array !< Unknown
real, optional ,intent(in) :: weight !< Unknown
end subroutine g_tracer_set_2D
!> Unknown
subroutine g_tracer_set_3D(g_tracer_list,name,member,array,isd,jsd,ntau)
character(len=*), intent(in) :: name !< Unknown
character(len=*), intent(in) :: member !< Unknown
type(g_tracer_type), pointer :: g_tracer_list !< Unknown
integer, intent(in) :: isd !< Unknown
integer, intent(in) :: jsd !< Unknown
integer, optional, intent(in) :: ntau !< Unknown
real, dimension(isd:,jsd:,:), intent(in) :: array !< Unknown
end subroutine g_tracer_set_3D
!> Unknown
subroutine g_tracer_set_4D(g_tracer_list,name,member,array,isd,jsd)
character(len=*), intent(in) :: name !< Unknown
character(len=*), intent(in) :: member !< Unknown
type(g_tracer_type), pointer :: g_tracer_list !< Unknown
integer, intent(in) :: isd !< Unknown
integer, intent(in) :: jsd !< Unknown
real, dimension(isd:,jsd:,:,:), intent(in) :: array !< Unknown
end subroutine g_tracer_set_4D
!> Unknown
subroutine g_tracer_set_real(g_tracer_list,name,member,value)
character(len=*), intent(in) :: name !< Unknown
character(len=*), intent(in) :: member !< Unknown
type(g_tracer_type), pointer :: g_tracer_list !< Unknown
real, intent(in) :: value !< Unknown
end subroutine g_tracer_set_real
subroutine g_tracer_send_diag(g_tracer_list,model_time,tau)
type(g_tracer_type), pointer :: g_tracer_list !< pointer to the head of the generic tracer list
type(g_tracer_type), pointer :: g_tracer !< Pointer to tracer node
type(time_type), intent(in) :: model_time !< Time
integer, intent(in) :: tau !< The time step for the %field 4D field to be reported
end subroutine g_tracer_send_diag
!> Unknown
subroutine g_tracer_get_name(g_tracer,string)
type(g_tracer_type), pointer :: g_tracer !< Unknown
character(len=*), intent(out) :: string !< Unknown
end subroutine g_tracer_get_name
!> Unknown
subroutine g_tracer_get_alias(g_tracer,string)
type(g_tracer_type), pointer :: g_tracer !< Unknown
character(len=*), intent(out) :: string !< Unknown
end subroutine g_tracer_get_alias
!> Is the tracer prognostic?
function g_tracer_is_prog(g_tracer)
logical :: g_tracer_is_prog
type(g_tracer_type), pointer :: g_tracer !< Pointer to tracer node
end function g_tracer_is_prog
!> get the next tracer in the list
subroutine g_tracer_get_next(g_tracer,g_tracer_next)
type(g_tracer_type), pointer :: g_tracer !< Pointer to tracer node
type(g_tracer_type), pointer :: g_tracer_next !< Pointer to the next tracer node in the list
end subroutine g_tracer_get_next
subroutine g_tracer_get_obc_segment_props(g_tracer_list, name, obc_has, src_file, src_var_name)
type(g_tracer_type), pointer :: g_tracer_list !< pointer to the head of the generic tracer list
type(g_tracer_type), pointer :: g_tracer !< Pointer to tracer node
character(len=*), intent(in) :: name
logical, intent(out):: obc_has !<.true. if This tracer has OBC
character(len=*),optional,intent(out):: src_file, src_var_name !<OBC source file and variable in file
end subroutine g_tracer_get_obc_segment_props
!>Vertical Diffusion of a tracer node
!!
!! This subroutine solves a tridiagonal equation to find and set values of vertically diffused field
!! for a tracer node.This is ported from GOLD (vertdiff) and simplified
!! Since the surface flux from the atmosphere (%stf) has the units of mol/m^2/sec the resulting
!! tracer concentration has units of mol/Kg
subroutine g_tracer_vertdiff_G(g_tracer, h_old, ea, eb, dt, kg_m2_to_H, m_to_H, tau, mom)
type(g_tracer_type), pointer :: g_tracer !< Unknown
!> Layer thickness before entrainment, in m or kg m-2.
real, dimension(g_tracer_com%isd:,g_tracer_com%jsd:,:), intent(in) :: h_old
!> The amount of fluid entrained from the layer above, in H.
real, dimension(g_tracer_com%isd:,g_tracer_com%jsd:,:), intent(in) :: ea
!> The amount of fluid entrained from the layer below, in H.
real, dimension(g_tracer_com%isd:,g_tracer_com%jsd:,:), intent(in) :: eb
real, intent(in) :: dt !< The amount of time covered by this call, in s.
real, intent(in) :: kg_m2_to_H !< A conversion factor that translates kg m-2 into
!! the units of h_old (H)
real, intent(in) :: m_to_H !< A conversion factor that translates m into the units
!! of h_old (H).
integer, intent(in) :: tau !< Unknown
logical, intent(in), optional :: mom !< Unknown
end subroutine g_tracer_vertdiff_G
end module g_tracer_utils