MOM6
MOM_geothermal.F90
Go to the documentation of this file.
2 !***********************************************************************
3 !* GNU General Public License *
4 !* This file is a part of MOM. *
5 !* *
6 !* MOM is free software; you can redistribute it and/or modify it and *
7 !* are expected to follow the terms of the GNU General Public License *
8 !* as published by the Free Software Foundation; either version 2 of *
9 !* the License, or (at your option) any later version. *
10 !* *
11 !* MOM is distributed in the hope that it will be useful, but WITHOUT *
12 !* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
13 !* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public *
14 !* License for more details. *
15 !* *
16 !* For the full text of the GNU General Public License, *
17 !* write to: Free Software Foundation, Inc., *
18 !* 675 Mass Ave, Cambridge, MA 02139, USA. *
19 !* or see: http://www.gnu.org/licenses/gpl.html *
20 !***********************************************************************
21 
22 !********+*********+*********+*********+*********+*********+*********+**
23 !* *
24 !* By Robert Hallberg, 2010. *
25 !* *
26 !* This file contains the subroutine (geothemal) that implements *
27 !* a geothermal heating at the bottom. This can be done either in a *
28 !* layered isopycnal mode, in which the heating raises the density of *
29 !* the layer to the target density of the layer above, and then moves *
30 !* the water into that layer, or in a simple Eulerian mode, in which *
31 !* the bottommost GEOTHERMAL_THICKNESS are heated. Geothermal heating*
32 !* will also provide a buoyant source of bottom TKE that can be used *
33 !* to further mix the near-bottom water. In cold fresh water lakes *
34 !* where heating increases density, water should be moved into deeper *
35 !* layers, but this is not implemented yet. *
36 !* *
37 !* Macros written all in capital letters are defined in MOM_memory.h. *
38 !* *
39 !* A small fragment of the grid is shown below: *
40 !* *
41 !* j+1 x ^ x ^ x At x: q *
42 !* j+1 > o > o > At ^: v *
43 !* j x ^ x ^ x At >: u *
44 !* j > o > o > At o: h, buoy, Rml, eaml, ebml, etc. *
45 !* j-1 x ^ x ^ x *
46 !* i-1 i i+1 At x & ^: *
47 !* i i+1 At > & o: *
48 !* *
49 !* The boundaries always run through q grid points (x). *
50 !* *
51 !********+*********+*********+*********+*********+*********+*********+**
52 
53 use mom_diag_mediator, only : post_data, register_diag_field, safe_alloc_ptr
55 use mom_error_handler, only : mom_error, fatal, warning
57 use mom_io, only : read_data, slasher
58 use mom_grid, only : ocean_grid_type
62 
63 implicit none ; private
64 
65 #include <MOM_memory.h>
66 
68 
69 type, public :: geothermal_cs ; private
70  real :: drcv_dt_inplace ! The value of dRcv_dT above which (dRcv_dT is
71  ! negative) the water is heated in place instead
72  ! of moving upward between layers, in kg m-3 K-1.
73  real, pointer :: geo_heat(:,:) => null() ! The geothermal heat flux, in
74  ! W m-2.
75  real :: geothermal_thick ! The thickness over which geothermal heating is
76  ! applied, in m.
77  logical :: apply_geothermal ! If true, geothermal heating will be applied;
78  ! otherwise GEOTHERMAL_SCALE has been set to 0 and
79  ! there is no heat to apply.
80 
81  type(time_type), pointer :: time ! A pointer to the ocean model's clock.
82  type(diag_ctrl), pointer :: diag ! A structure that is used to regulate the
83  ! timing of diagnostic output.
84 end type geothermal_cs
85 
86 contains
87 
88 !> This subroutine applies geothermal heating, including the movement of water
89 !! between isopycnal layers to match the target densities. The heating is
90 !! applied to the bottommost layers that occur within ### of the bottom. If
91 !! the partial derivative of the coordinate density with temperature is positive
92 !! or very small, the layers are simply heated in place. Any heat that can not
93 !! be applied to the ocean is returned (WHERE)?
94 subroutine geothermal(h, tv, dt, ea, eb, G, GV, CS)
95  type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure.
96  type(verticalgrid_type), intent(in) :: GV !< The ocean's vertical grid
97  !! structure.
98  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thicknesses, in H
99  !! (usually m or kg m-2).
100  type(thermo_var_ptrs), intent(inout) :: tv !< A structure containing pointers
101  !! to any available thermodynamic
102  !! fields. Absent fields have NULL
103  !! ptrs.
104  real, intent(in) :: dt !< Time increment, in s.
105  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: ea !< The amount of fluid moved
106  !! downward into a layer; this
107  !! should be increased due to mixed
108  !! layer detrainment, in the same
109  !! units as h - usually m or kg m-2
110  !! (i.e., H).
111  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: eb !< The amount of fluid moved upward
112  !! into a layer; this should be
113  !! increased due to mixed layer
114  !! entrainment, in the same units as
115  !! h - usually m or kg m-2 (i.e., H)
116  type(geothermal_cs), pointer :: CS !< The control structure returned by
117  !! a previous call to
118  !! geothermal_init.
119 
120 ! This subroutine applies geothermal heating, including the movement of water
121 ! between isopycnal layers to match the target densities. The heating is
122 ! applied to the bottommost layers that occur within ### of the bottom. If
123 ! the partial derivative of the coordinate density with temperature is positive
124 ! or very small, the layers are simply heated in place. Any heat that can not
125 ! be applied to the ocean is returned (WHERE)?
126 
127 ! Arguments: h - Layer thickness, in m or kg m-2. (Intent in/out)
128 ! The units of h are referred to as H below.
129 ! (in/out) tv - A structure containing pointers to any available
130 ! thermodynamic fields. Absent fields have NULL ptrs.
131 ! (in) dt - Time increment, in s.
132 ! (in/out) ea - The amount of fluid moved downward into a layer; this should
133 ! be increased due to mixed layer detrainment, in the same units
134 ! as h - usually m or kg m-2 (i.e., H).
135 ! (in/out) eb - The amount of fluid moved upward into a layer; this should
136 ! be increased due to mixed layer entrainment, in the same units
137 ! as h - usually m or kg m-2 (i.e., H).
138 ! (in) G - The ocean's grid structure.
139 ! (in) GV - The ocean's vertical grid structure.
140 ! (in) CS - The control structure returned by a previous call to
141 ! geothermal_init.
142 
143 ! real :: resid(SZI_(G),SZJ_(G)) !z1l: never been used.
144 
145  real, dimension(SZI_(G)) :: &
146  heat_rem, & ! remaining heat (H * degC)
147  h_geo_rem, & ! remaining thickness to apply geothermal heating (units of H)
148  Rcv_BL, & ! coordinate density in the deepest variable density layer (kg/m3)
149  p_ref ! coordiante densities reference pressure (Pa)
150 
151  real, dimension(2) :: &
152  T2, S2, & ! temp and saln in the present and target layers (degC and ppt)
153  dRcv_dT_, & ! partial derivative of coordinate density wrt temp (kg m-3 K-1)
154  dRcv_dS_ ! partial derivative of coordinate density wrt saln (kg m-3 ppt-1)
155 
156  real :: Angstrom, H_neglect ! small thicknesses in H
157  real :: Rcv ! coordinate density of present layer (kg m-3)
158  real :: Rcv_tgt ! coordinate density of target layer (kg m-3)
159  real :: dRcv ! difference between Rcv and Rcv_tgt (kg m-3)
160  real :: dRcv_dT ! partial derivative of coordinate density wrt temp
161  ! in the present layer (kg m-3 K-1); usually negative
162  real :: h_heated ! thickness that is being heated (units of H)
163  real :: heat_avail ! heating available for the present layer (units of Kelvin * H)
164  real :: heat_in_place ! heating to warm present layer w/o movement between layers (K * H)
165  real :: heat_trans ! heating available to move water from present layer to target layer (K * H)
166  real :: heating ! heating used to move water from present layer to target layer (K * H)
167  ! 0 <= heating <= heat_trans
168  real :: h_transfer ! thickness moved between layers (units of H)
169  real :: wt_in_place ! relative weighting that goes from 0 to 1 (non-dim)
170  real :: I_h ! inverse thickness (units of 1/H)
171  real :: dTemp ! temperature increase in a layer (Kelvin)
172  real :: Irho_cp ! inverse of heat capacity per unit layer volume (units K H m2 J-1)
173 
174  logical :: do_i(szi_(g))
175  integer :: i, j, k, is, ie, js, je, nz, k2, i2
176  integer :: isj, iej, num_start, num_left, nkmb, k_tgt
177 
178 
179  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
180 
181  if (.not. associated(cs)) call mom_error(fatal, "MOM_geothermal: "//&
182  "Module must be initialized before it is used.")
183  if (.not.cs%apply_geothermal) return
184 
185  nkmb = gv%nk_rho_varies
186  irho_cp = 1.0 / (gv%H_to_kg_m2 * tv%C_p)
187  angstrom = gv%Angstrom
188  h_neglect = gv%H_subroundoff
189  p_ref(:) = tv%P_Ref
190 
191  if (.not.ASSOCIATED(tv%T)) call mom_error(fatal, "MOM geothermal: "//&
192  "Geothermal heating can only be applied if T & S are state variables.")
193 
194 ! do i=is,ie ; do j=js,je
195 ! resid(i,j) = tv%internal_heat(i,j)
196 ! enddo ; enddo
197 
198 !$OMP parallel do default(none) shared(is,ie,js,je,G,GV,CS,dt,Irho_cp,nkmb,tv, &
199 !$OMP p_Ref,h,Angstrom,nz,H_neglect,eb) &
200 !$OMP private(num_start,heat_rem,do_i,h_geo_rem,num_left,&
201 !$OMP isj,iej,Rcv_BL,h_heated,heat_avail,k_tgt, &
202 !$OMP Rcv_tgt,Rcv,dRcv_dT,T2,S2,dRcv_dT_, &
203 !$OMP dRcv_dS_,heat_in_place,heat_trans, &
204 !$OMP wt_in_place,dTemp,dRcv,h_transfer,heating, &
205 !$OMP I_h)
206 
207  do j=js,je
208  ! 1. Only work on columns that are being heated.
209  ! 2. Find the deepest layer with any mass.
210  ! 3. Find the partial derivative of locally referenced potential density
211  ! and coordinate density with temperature, and the density of the layer
212  ! and the layer above.
213  ! 4. Heat a portion of the bottommost layer until it matches the target
214  ! density of the layer above, and move it.
215  ! 4a. In the case of variable density layers, heat but do not move.
216  ! 5. If there is still heat left over, repeat for the next layer up.
217  ! This subroutine updates thickness, T & S, and increments eb accordingly.
218 
219  ! 6. If there is not enough mass in the ocean, pass some of the heat up
220  ! from the ocean via the frazil field?
221 
222  num_start = 0
223  do i=is,ie
224  heat_rem(i) = g%mask2dT(i,j) * (cs%geo_heat(i,j) * (dt*irho_cp))
225  do_i(i) = .true. ; if (heat_rem(i) <= 0.0) do_i(i) = .false.
226  if (do_i(i)) num_start = num_start + 1
227  h_geo_rem(i) = cs%Geothermal_thick * gv%m_to_H
228  enddo
229  if (num_start == 0) cycle
230  num_left = num_start
231 
232  ! Find the first and last columns that need to be worked on.
233  isj = ie+1 ; do i=is,ie ; if (do_i(i)) then ; isj = i ; exit ; endif ; enddo
234  iej = is-1 ; do i=ie,is,-1 ; if (do_i(i)) then ; iej = i ; exit ; endif ; enddo
235 
236  if (nkmb > 0) then
237  call calculate_density(tv%T(:,j,nkmb), tv%S(:,j,nkmb), p_ref(:), &
238  rcv_bl(:), isj, iej-isj+1, tv%eqn_of_state)
239  else
240  rcv_bl(:) = -1.0
241  endif
242 
243  do k=nz,1,-1
244  do i=isj,iej ; if (do_i(i)) then
245 
246  if (h(i,j,k) > angstrom) then
247  if ((h(i,j,k)-angstrom) >= h_geo_rem(i)) then
248  h_heated = h_geo_rem(i)
249  heat_avail = heat_rem(i)
250  h_geo_rem(i) = 0.0
251  else
252  h_heated = (h(i,j,k)-angstrom)
253  heat_avail = heat_rem(i) * (h_heated / &
254  (h_geo_rem(i) + h_neglect))
255  h_geo_rem(i) = h_geo_rem(i) - h_heated
256  endif
257 
258  if (k<=nkmb .or. nkmb<=0) then
259  ! Simply heat the layer; convective adjustment occurs later
260  ! if necessary.
261  k_tgt = k
262  elseif ((k==nkmb+1) .or. (gv%Rlay(k-1) < rcv_bl(i))) then
263  ! Add enough heat to match the lowest buffer layer density.
264  k_tgt = nkmb
265  rcv_tgt = rcv_bl(i)
266  else
267  ! Add enough heat to match the target density of layer k-1.
268  k_tgt = k-1
269  rcv_tgt = gv%Rlay(k-1)
270  endif
271 
272  if (k<=nkmb .or. nkmb<=0) then
273  rcv = 0.0 ; drcv_dt = 0.0 ! Is this OK?
274  else
275  call calculate_density(tv%T(i,j,k), tv%S(i,j,k), tv%P_Ref, &
276  rcv, tv%eqn_of_state)
277  t2(1) = tv%T(i,j,k) ; s2(1) = tv%S(i,j,k)
278  t2(2) = tv%T(i,j,k_tgt) ; s2(2) = tv%S(i,j,k_tgt)
279  call calculate_density_derivs(t2(:), s2(:), p_ref(:), &
280  drcv_dt_, drcv_ds_, 1, 2, tv%eqn_of_state)
281  drcv_dt = 0.5*(drcv_dt_(1) + drcv_dt_(2))
282  endif
283 
284  if ((drcv_dt >= 0.0) .or. (k<=nkmb .or. nkmb<=0)) then
285  ! This applies to variable density layers.
286  heat_in_place = heat_avail
287  heat_trans = 0.0
288  elseif (drcv_dt <= cs%dRcv_dT_inplace) then
289  ! This is the option that usually applies in isopycnal coordinates.
290  heat_in_place = min(heat_avail, max(0.0, h(i,j,k) * &
291  ((gv%Rlay(k)-rcv) / drcv_dt)))
292  heat_trans = heat_avail - heat_in_place
293  else
294  ! wt_in_place should go from 0 to 1.
295  wt_in_place = (cs%dRcv_dT_inplace - drcv_dt) / cs%dRcv_dT_inplace
296  heat_in_place = max(wt_in_place*heat_avail, &
297  h(i,j,k) * ((gv%Rlay(k)-rcv) / drcv_dt) )
298  heat_trans = heat_avail - heat_in_place
299  endif
300 
301  if (heat_in_place > 0.0) then
302  ! This applies to variable density layers. In isopycnal coordinates
303  ! this only arises for relatively fresh water near the freezing
304  ! point, in which case heating in place will eventually cause things
305  ! to sort themselves out, if only because the water will warm to
306  ! the temperature of maximum density.
307  dtemp = heat_in_place / (h(i,j,k) + h_neglect)
308  tv%T(i,j,k) = tv%T(i,j,k) + dtemp
309  heat_rem(i) = heat_rem(i) - heat_in_place
310  rcv = rcv + drcv_dt * dtemp
311  endif
312 
313  if (heat_trans > 0.0) then
314  ! The second expression might never be used, but will avoid
315  ! division by 0.
316  drcv = max(rcv - rcv_tgt, 0.0)
317 
318  ! dTemp = -dRcv / dRcv_dT
319  ! h_transfer = min(heat_rem(i) / dTemp, h(i,j,k)-Angstrom)
320  if ((-drcv_dt * heat_trans) >= drcv * (h(i,j,k)-angstrom)) then
321  h_transfer = h(i,j,k) - angstrom
322  heating = (h_transfer * drcv) / (-drcv_dt)
323  ! Since not all the heat has been applied, return the fraction
324  ! of the layer thickness that has not yet been fully heated to
325  ! the h_geo_rem.
326  h_geo_rem(i) = h_geo_rem(i) + h_heated * &
327  ((heat_avail - (heating + heat_in_place)) / heat_avail)
328  else
329  h_transfer = (-drcv_dt * heat_trans) / drcv
330  heating = heat_trans
331  endif
332  heat_rem(i) = heat_rem(i) - heating
333 
334  i_h = 1.0 / (h(i,j,k_tgt) + h_transfer + h_neglect)
335  tv%T(i,j,k_tgt) = (h(i,j,k_tgt) * tv%T(i,j,k_tgt) + &
336  (h_transfer * tv%T(i,j,k) + heating)) * i_h
337  tv%S(i,j,k_tgt) = (h(i,j,k_tgt) * tv%S(i,j,k_tgt) + &
338  h_transfer * tv%S(i,j,k)) * i_h
339 
340  h(i,j,k) = h(i,j,k) - h_transfer
341  h(i,j,k_tgt) = h(i,j,k_tgt) + h_transfer
342  eb(i,j,k_tgt) = eb(i,j,k_tgt) + h_transfer
343  if (k_tgt < k-1) then
344  do k2 = k_tgt+1,k-1
345  eb(i,j,k2) = eb(i,j,k2) + h_transfer
346  enddo
347  endif
348  endif
349 
350  if (heat_rem(i) <= 0.0) then
351  do_i(i) = .false. ; num_left = num_left-1
352  ! For efficiency, uncomment these?
353  ! if ((i==isj) .and. (num_left > 0)) then
354  ! do i2=isj+1,iej ; if (do_i(i2)) then
355  ! isj = i2 ; exit ! Set the new starting value.
356  ! endif ; enddo
357  ! endif
358  ! if ((i==iej) .and. (num_left > 0)) then
359  ! do i2=iej-1,isj,-1 ; if (do_i(i2)) then
360  ! iej = i2 ; exit ! Set the new ending value.
361  ! endif ; enddo
362  ! endif
363  endif
364  endif
365  endif ; enddo
366  if (num_left <= 0) exit
367  enddo ! k-loop
368 
369  if (associated(tv%internal_heat)) then ; do i=is,ie
370  tv%internal_heat(i,j) = tv%internal_heat(i,j) + gv%H_to_kg_m2 * &
371  (g%mask2dT(i,j) * (cs%geo_heat(i,j) * (dt*irho_cp)) - heat_rem(i))
372  enddo ; endif
373  enddo ! j-loop
374 
375 ! do i=is,ie ; do j=js,je
376 ! resid(i,j) = tv%internal_heat(i,j) - resid(i,j) - GV%H_to_kg_m2 * &
377 ! (G%mask2dT(i,j) * (CS%geo_heat(i,j) * (dt*Irho_cp)))
378 ! enddo ; enddo
379 
380 end subroutine geothermal
381 
382 subroutine geothermal_init(Time, G, param_file, diag, CS)
383  type(time_type), target, intent(in) :: Time !< Current model time.
384  type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure.
385  type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time
386  !! parameters.
387  type(diag_ctrl), target, intent(inout) :: diag !< Structure used to regulate diagnostic output.
388  type(geothermal_cs), pointer :: CS !< Pointer pointing to the module control
389  !! structure.
390 
391 ! Arguments:
392 ! (in) Time - current model time
393 ! (in) G - ocean grid structure
394 ! (in) param_file - structure indicating the open file to parse for
395 ! model parameter values
396 ! (in) diag - structure used to regulate diagnostic output
397 ! (in/out) CS - pointer pointing to the module control structure
398 
399 ! This include declares and sets the variable "version".
400 #include "version_variable.h"
401 
402  character(len=40) :: mdl = "MOM_geothermal" ! module name
403  character(len=200) :: inputdir, geo_file, filename, geotherm_var
404  real :: scale
405  integer :: i, j, isd, ied, jsd, jed, id
406  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
407 
408  if (associated(cs)) then
409  call mom_error(warning, "geothermal_init called with an associated"// &
410  "associated control structure.")
411  return
412  else ; allocate(cs) ; endif
413 
414  cs%diag => diag
415  cs%Time => time
416 
417  ! write parameters to the model log.
418  call log_version(param_file, mdl, version, "")
419  call get_param(param_file, mdl, "GEOTHERMAL_SCALE", scale, &
420  "The constant geothermal heat flux, a rescaling \n"//&
421  "factor for the heat flux read from GEOTHERMAL_FILE, or \n"//&
422  "0 to disable the geothermal heating.", &
423  units="W m-2 or various", default=0.0)
424  cs%apply_geothermal = .not.(scale == 0.0)
425  if (.not.cs%apply_geothermal) return
426 
427  call safe_alloc_ptr(cs%geo_heat, isd, ied, jsd, jed) ; cs%geo_heat(:,:) = 0.0
428 
429  call get_param(param_file, mdl, "GEOTHERMAL_FILE", geo_file, &
430  "The file from which the geothermal heating is to be \n"//&
431  "read, or blank to use a constant heating rate.", default=" ")
432  call get_param(param_file, mdl, "GEOTHERMAL_THICKNESS", cs%geothermal_thick, &
433  "The thickness over which to apply geothermal heating.", &
434  units="m", default=0.1)
435  call get_param(param_file, mdl, "GEOTHERMAL_DRHO_DT_INPLACE", cs%dRcv_dT_inplace, &
436  "The value of drho_dT above which geothermal heating \n"//&
437  "simply heats water in place instead of moving it between \n"//&
438  "isopycnal layers. This must be negative.", &
439  units="kg m-3 K-1", default=-0.01)
440  if (cs%dRcv_dT_inplace >= 0.0) call mom_error(fatal, "geothermal_init: "//&
441  "GEOTHERMAL_DRHO_DT_INPLACE must be negative.")
442 
443  if (len_trim(geo_file) >= 1) then
444  call get_param(param_file, mdl, "INPUTDIR", inputdir, default=".")
445  inputdir = slasher(inputdir)
446  filename = trim(inputdir)//trim(geo_file)
447  call log_param(param_file, mdl, "INPUTDIR/GEOTHERMAL_FILE", filename)
448  call get_param(param_file, mdl, "GEOTHERMAL_VARNAME", geotherm_var, &
449  "The name of the geothermal heating variable in \n"//&
450  "GEOTHERMAL_FILE.", default="geo_heat")
451  call read_data(filename, trim(geotherm_var), cs%geo_heat, &
452  domain=g%Domain%mpp_domain)
453  do j=jsd,jed ; do i=isd,ied
454  cs%geo_heat(i,j) = (g%mask2dT(i,j) * scale) * cs%geo_heat(i,j)
455  enddo ; enddo
456  else
457  do j=jsd,jed ; do i=isd,ied
458  cs%geo_heat(i,j) = g%mask2dT(i,j) * scale
459  enddo ; enddo
460  endif
461 
462  ! post the static geothermal heating field
463  id = register_static_field('ocean_model', 'geo_heat', diag%axesT1, &
464  'Geothermal heat flux into ocean', 'W m-2', &
465  cmor_field_name='hfgeou', cmor_units='W m-2', &
466  cmor_standard_name='upward_geothermal_heat_flux_at_sea_floor', &
467  cmor_long_name='Upward geothermal heat flux at sea floor')
468  if (id > 0) call post_data(id, cs%geo_heat, diag, .true.)
469 
470 end subroutine geothermal_init
471 
472 subroutine geothermal_end(CS)
473  type(geothermal_cs), pointer :: CS
474 
475  if (associated(cs%geo_heat)) deallocate(cs%geo_heat)
476  if (associated(cs)) deallocate(cs)
477 end subroutine geothermal_end
478 
479 end module mom_geothermal
subroutine, public geothermal(h, tv, dt, ea, eb, G, GV, CS)
This subroutine applies geothermal heating, including the movement of water between isopycnal layers ...
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
The following data type a list of diagnostic fields an their variants, as well as variables that cont...
Calculates density of sea water from T, S and P.
Definition: MOM_EOS.F90:45
Provides the ocean grid type.
Definition: MOM_grid.F90:2
This module contains I/O framework code.
Definition: MOM_io.F90:2
subroutine, public geothermal_end(CS)
subroutine, public calculate_density_derivs(T, S, pressure, drho_dT, drho_dS, start, npts, EOS)
Calls the appropriate subroutine to calculate density derivatives for 1-D array inputs.
Definition: MOM_EOS.F90:214
subroutine, public geothermal_init(Time, G, param_file, diag, CS)
Provides subroutines for quantities specific to the equation of state.
Definition: MOM_EOS.F90:2
integer function, public register_static_field(module_name, field_name, axes, long_name, units, missing_value, range, mask_variant, standard_name, do_not_log, interp_method, tile_count, cmor_field_name, cmor_long_name, cmor_units, cmor_standard_name, area)
Registers a static diagnostic, returning an integer handle.
The thermo_var_ptrs structure contains pointers to an assortment of thermodynamic fields that may be ...
integer function, public register_diag_field(module_name, field_name, axes, init_time, long_name, units, missing_value, range, mask_variant, standard_name, verbose, do_not_log, err_msg, interp_method, tile_count, cmor_field_name, cmor_long_name, cmor_units, cmor_standard_name, cell_methods, x_cell_method, y_cell_method, v_cell_method, conversion, v_extensive)
Returns the "diag_mediator" handle for a group (native, CMOR, z-coord, ...) of diagnostics derived fr...
subroutine, public mom_error(level, message, all_print)