21 #include <MOM_memory.h>
24 use user_tracer_example,
only : tracer_column_physics, user_initialize_tracer, user_tracer_stock
27 use dome_tracer,
only : register_dome_tracer, initialize_dome_tracer
28 use dome_tracer,
only : dome_tracer_column_physics, dome_tracer_surface_state
30 use isomip_tracer,
only : register_isomip_tracer, initialize_isomip_tracer
31 use isomip_tracer,
only : isomip_tracer_column_physics, isomip_tracer_surface_state
33 use rgc_tracer,
only : register_rgc_tracer, initialize_rgc_tracer
34 use rgc_tracer,
only : rgc_tracer_column_physics
36 use ideal_age_example,
only : register_ideal_age_tracer, initialize_ideal_age_tracer
37 use ideal_age_example,
only : ideal_age_tracer_column_physics, ideal_age_tracer_surface_state
39 use regional_dyes,
only : register_dye_tracer, initialize_dye_tracer
40 use regional_dyes,
only : dye_tracer_column_physics, dye_tracer_surface_state
42 use mom_ocmip2_cfc,
only : register_ocmip2_cfc, initialize_ocmip2_cfc, flux_init_ocmip2_cfc
43 use mom_ocmip2_cfc,
only : ocmip2_cfc_column_physics, ocmip2_cfc_surface_state
45 use oil_tracer,
only : register_oil_tracer, initialize_oil_tracer
46 use oil_tracer,
only : oil_tracer_column_physics, oil_tracer_surface_state
49 use advection_test_tracer,
only : advection_test_tracer_column_physics, advection_test_tracer_surface_state
51 use dyed_obc_tracer,
only : register_dyed_obc_tracer, initialize_dyed_obc_tracer
54 use mom_generic_tracer,
only : register_mom_generic_tracer, initialize_mom_generic_tracer
55 use mom_generic_tracer,
only : mom_generic_tracer_column_physics, mom_generic_tracer_surface_state
56 use mom_generic_tracer,
only : end_mom_generic_tracer, mom_generic_tracer_get, mom_generic_flux_init
58 use pseudo_salt_tracer,
only : register_pseudo_salt_tracer, initialize_pseudo_salt_tracer
59 use pseudo_salt_tracer,
only : pseudo_salt_tracer_column_physics, pseudo_salt_tracer_surface_state
62 use boundary_impulse_tracer,
only : boundary_impulse_tracer_column_physics, boundary_impulse_tracer_surface_state
66 implicit none ;
private
68 public call_tracer_register, tracer_flow_control_init, call_tracer_set_forcing
69 public call_tracer_column_fns, call_tracer_surface_state, call_tracer_stocks
70 public call_tracer_flux_init, get_chl_from_model, tracer_flow_control_end
74 logical :: use_user_tracer_example = .false.
75 logical :: use_dome_tracer = .false.
76 logical :: use_isomip_tracer = .false.
77 logical :: use_rgc_tracer =.false.
78 logical :: use_ideal_age = .false.
79 logical :: use_regional_dyes = .false.
80 logical :: use_oil = .false.
81 logical :: use_advection_test_tracer = .false.
82 logical :: use_ocmip2_cfc = .false.
83 logical :: use_mom_generic_tracer = .false.
84 logical :: use_pseudo_salt_tracer = .false.
85 logical :: use_boundary_impulse_tracer = .false.
86 logical :: use_dyed_obc_tracer = .false.
112 subroutine call_tracer_flux_init(verbosity)
113 integer,
optional,
intent(in) :: verbosity
116 character(len=40) :: mdl =
"call_tracer_flux_init"
117 logical :: use_ocmip_cfcs, use_mom_generic_tracer
121 call get_mom_input(param_file, check_params=.false.)
123 call get_param(param_file, mdl,
"USE_OCMIP2_CFC", use_ocmip_cfcs, &
124 default=.false., do_not_log=.true.)
125 call get_param(param_file, mdl,
"USE_generic_tracer", use_mom_generic_tracer,&
126 default=.false., do_not_log=.true.)
127 call close_param_file(param_file, quiet_close=.true.)
129 if (use_ocmip_cfcs)
call flux_init_ocmip2_cfc(verbosity=verbosity)
130 if (use_mom_generic_tracer)
then
131 call mom_generic_flux_init(verbosity=verbosity)
134 end subroutine call_tracer_flux_init
141 subroutine call_tracer_register(HI, GV, US, param_file, CS, tr_Reg, restart_CS)
157 # include "version_variable.h"
158 character(len=40) :: mdl =
"MOM_tracer_flow_control"
160 if (
associated(cs))
then
161 call mom_error(warning,
"call_tracer_register called with an associated "// &
162 "control structure.")
164 else ;
allocate(cs) ;
endif
168 call get_param(param_file, mdl,
"USE_USER_TRACER_EXAMPLE", &
169 cs%use_USER_tracer_example, &
170 "If true, use the USER_tracer_example tracer package.", &
172 call get_param(param_file, mdl,
"USE_DOME_TRACER", cs%use_DOME_tracer, &
173 "If true, use the DOME_tracer tracer package.", &
175 call get_param(param_file, mdl,
"USE_ISOMIP_TRACER", cs%use_ISOMIP_tracer, &
176 "If true, use the ISOMIP_tracer tracer package.", &
178 call get_param(param_file, mdl,
"USE_RGC_TRACER", cs%use_RGC_tracer, &
179 "If true, use the RGC_tracer tracer package.", &
181 call get_param(param_file, mdl,
"USE_IDEAL_AGE_TRACER", cs%use_ideal_age, &
182 "If true, use the ideal_age_example tracer package.", &
184 call get_param(param_file, mdl,
"USE_REGIONAL_DYES", cs%use_regional_dyes, &
185 "If true, use the regional_dyes tracer package.", &
187 call get_param(param_file, mdl,
"USE_OIL_TRACER", cs%use_oil, &
188 "If true, use the oil_tracer tracer package.", &
190 call get_param(param_file, mdl,
"USE_ADVECTION_TEST_TRACER", cs%use_advection_test_tracer, &
191 "If true, use the advection_test_tracer tracer package.", &
193 call get_param(param_file, mdl,
"USE_OCMIP2_CFC", cs%use_OCMIP2_CFC, &
194 "If true, use the MOM_OCMIP2_CFC tracer package.", &
196 call get_param(param_file, mdl,
"USE_generic_tracer", cs%use_MOM_generic_tracer, &
197 "If true and _USE_GENERIC_TRACER is defined as a "//&
198 "preprocessor macro, use the MOM_generic_tracer packages.", &
200 call get_param(param_file, mdl,
"USE_PSEUDO_SALT_TRACER", cs%use_pseudo_salt_tracer, &
201 "If true, use the pseudo salt tracer, typically run as a diagnostic.", &
203 call get_param(param_file, mdl,
"USE_BOUNDARY_IMPULSE_TRACER", cs%use_boundary_impulse_tracer, &
204 "If true, use the boundary impulse tracer.", &
206 call get_param(param_file, mdl,
"USE_DYED_OBC_TRACER", cs%use_dyed_obc_tracer, &
207 "If true, use the dyed_obc_tracer tracer package.", &
213 if (cs%use_USER_tracer_example) cs%use_USER_tracer_example = &
214 user_register_tracer_example(hi, gv, param_file, cs%USER_tracer_example_CSp, &
216 if (cs%use_DOME_tracer) cs%use_DOME_tracer = &
217 register_dome_tracer(hi, gv, param_file, cs%DOME_tracer_CSp, &
219 if (cs%use_ISOMIP_tracer) cs%use_ISOMIP_tracer = &
220 register_isomip_tracer(hi, gv, param_file, cs%ISOMIP_tracer_CSp, &
222 if (cs%use_RGC_tracer) cs%use_RGC_tracer = &
223 register_rgc_tracer(hi, gv, param_file, cs%RGC_tracer_CSp, &
225 if (cs%use_ideal_age) cs%use_ideal_age = &
226 register_ideal_age_tracer(hi, gv, param_file, cs%ideal_age_tracer_CSp, &
228 if (cs%use_regional_dyes) cs%use_regional_dyes = &
229 register_dye_tracer(hi, gv, us, param_file, cs%dye_tracer_CSp, &
231 if (cs%use_oil) cs%use_oil = &
232 register_oil_tracer(hi, gv, us, param_file, cs%oil_tracer_CSp, &
234 if (cs%use_advection_test_tracer) cs%use_advection_test_tracer = &
235 register_advection_test_tracer(hi, gv, param_file, cs%advection_test_tracer_CSp, &
237 if (cs%use_OCMIP2_CFC) cs%use_OCMIP2_CFC = &
238 register_ocmip2_cfc(hi, gv, param_file, cs%OCMIP2_CFC_CSp, &
240 if (cs%use_MOM_generic_tracer) cs%use_MOM_generic_tracer = &
241 register_mom_generic_tracer(hi, gv, param_file, cs%MOM_generic_tracer_CSp, &
243 if (cs%use_pseudo_salt_tracer) cs%use_pseudo_salt_tracer = &
244 register_pseudo_salt_tracer(hi, gv, param_file, cs%pseudo_salt_tracer_CSp, &
246 if (cs%use_boundary_impulse_tracer) cs%use_boundary_impulse_tracer = &
247 register_boundary_impulse_tracer(hi, gv, param_file, cs%boundary_impulse_tracer_CSp, &
249 if (cs%use_dyed_obc_tracer) cs%use_dyed_obc_tracer = &
250 register_dyed_obc_tracer(hi, gv, param_file, cs%dyed_obc_tracer_CSp, &
254 end subroutine call_tracer_register
258 subroutine tracer_flow_control_init(restart, day, G, GV, US, h, param_file, diag, OBC, &
259 CS, sponge_CSp, ALE_sponge_CSp, tv)
260 logical,
intent(in) :: restart
262 type(time_type),
target,
intent(in) :: day
267 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
271 type(
diag_ctrl),
target,
intent(in) :: diag
289 if (.not.
associated(cs))
call mom_error(fatal,
"tracer_flow_control_init: "// &
290 "Module must be initialized via call_tracer_register before it is used.")
293 if (cs%use_USER_tracer_example) &
294 call user_initialize_tracer(restart, day, g, gv, h, diag, obc, cs%USER_tracer_example_CSp, &
296 if (cs%use_DOME_tracer) &
297 call initialize_dome_tracer(restart, day, g, gv, us, h, diag, obc, cs%DOME_tracer_CSp, &
298 sponge_csp, param_file)
299 if (cs%use_ISOMIP_tracer) &
300 call initialize_isomip_tracer(restart, day, g, gv, h, diag, obc, cs%ISOMIP_tracer_CSp, &
302 if (cs%use_RGC_tracer) &
303 call initialize_rgc_tracer(restart, day, g, gv, h, diag, obc, &
304 cs%RGC_tracer_CSp, sponge_csp, ale_sponge_csp)
305 if (cs%use_ideal_age) &
306 call initialize_ideal_age_tracer(restart, day, g, gv, us, h, diag, obc, cs%ideal_age_tracer_CSp, &
308 if (cs%use_regional_dyes) &
309 call initialize_dye_tracer(restart, day, g, gv, h, diag, obc, cs%dye_tracer_CSp, &
312 call initialize_oil_tracer(restart, day, g, gv, us, h, diag, obc, cs%oil_tracer_CSp, &
314 if (cs%use_advection_test_tracer) &
315 call initialize_advection_test_tracer(restart, day, g, gv, h, diag, obc, cs%advection_test_tracer_CSp, &
317 if (cs%use_OCMIP2_CFC) &
318 call initialize_ocmip2_cfc(restart, day, g, gv, us, h, diag, obc, cs%OCMIP2_CFC_CSp, &
320 if (cs%use_MOM_generic_tracer) &
321 call initialize_mom_generic_tracer(restart, day, g, gv, us, h, param_file, diag, obc, &
322 cs%MOM_generic_tracer_CSp, sponge_csp, ale_sponge_csp)
323 if (cs%use_pseudo_salt_tracer) &
324 call initialize_pseudo_salt_tracer(restart, day, g, gv, h, diag, obc, cs%pseudo_salt_tracer_CSp, &
326 if (cs%use_boundary_impulse_tracer) &
327 call initialize_boundary_impulse_tracer(restart, day, g, gv, h, diag, obc, cs%boundary_impulse_tracer_CSp, &
329 if (cs%use_dyed_obc_tracer) &
330 call initialize_dyed_obc_tracer(restart, day, g, gv, h, diag, obc, cs%dyed_obc_tracer_CSp)
332 end subroutine tracer_flow_control_init
335 subroutine get_chl_from_model(Chl_array, G, CS)
337 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
338 intent(out) :: chl_array
343 if (cs%use_MOM_generic_tracer)
then
344 call mom_generic_tracer_get(
'chl',
'field', chl_array, cs%MOM_generic_tracer_CSp)
346 call mom_error(fatal,
"get_chl_from_model was called in a configuration "// &
347 "that is unable to provide a sensible model-based value.\n"// &
348 "CS%use_MOM_generic_tracer is false and no other viable options are on.")
351 end subroutine get_chl_from_model
355 subroutine call_tracer_set_forcing(sfc_state, fluxes, day_start, day_interval, G, CS)
357 type(
surface),
intent(inout) :: sfc_state
360 type(
forcing),
intent(inout) :: fluxes
363 type(time_type),
intent(in) :: day_start
364 type(time_type),
intent(in) :: day_interval
370 if (.not.
associated(cs))
call mom_error(fatal,
"call_tracer_set_forcing"// &
371 "Module must be initialized via call_tracer_register before it is used.")
376 end subroutine call_tracer_set_forcing
379 subroutine call_tracer_column_fns(h_old, h_new, ea, eb, fluxes, Hml, dt, G, GV, US, tv, optics, CS, &
380 debug, evap_CFL_limit, minimum_forcing_depth)
383 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(in) :: h_old
385 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(in) :: h_new
387 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(in) :: ea
390 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)),
intent(in) :: eb
393 type(
forcing),
intent(in) :: fluxes
396 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: hml
397 real,
intent(in) :: dt
402 type(optics_type),
pointer :: optics
407 logical,
intent(in) :: debug
408 real,
optional,
intent(in) :: evap_cfl_limit
411 real,
optional,
intent(in) :: minimum_forcing_depth
414 if (.not.
associated(cs))
call mom_error(fatal,
"call_tracer_column_fns: "// &
415 "Module must be initialized via call_tracer_register before it is used.")
418 if (
present(evap_cfl_limit) .and.
present(minimum_forcing_depth))
then
420 if (cs%use_USER_tracer_example) &
421 call tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
422 g, gv, us, cs%USER_tracer_example_CSp)
423 if (cs%use_DOME_tracer) &
424 call dome_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
425 g, gv, us, cs%DOME_tracer_CSp, &
426 evap_cfl_limit=evap_cfl_limit, &
427 minimum_forcing_depth=minimum_forcing_depth)
428 if (cs%use_ISOMIP_tracer) &
429 call isomip_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
430 g, gv, us, cs%ISOMIP_tracer_CSp, &
431 evap_cfl_limit=evap_cfl_limit, &
432 minimum_forcing_depth=minimum_forcing_depth)
433 if (cs%use_RGC_tracer) &
434 call rgc_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
435 g, gv, us, cs%RGC_tracer_CSp, &
436 evap_cfl_limit=evap_cfl_limit, &
437 minimum_forcing_depth=minimum_forcing_depth)
438 if (cs%use_ideal_age) &
439 call ideal_age_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
440 g, gv, us, cs%ideal_age_tracer_CSp, &
441 evap_cfl_limit=evap_cfl_limit, &
442 minimum_forcing_depth=minimum_forcing_depth)
443 if (cs%use_regional_dyes) &
444 call dye_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
445 g, gv, us, cs%dye_tracer_CSp, &
446 evap_cfl_limit=evap_cfl_limit, &
447 minimum_forcing_depth=minimum_forcing_depth)
449 call oil_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
450 g, gv, us, cs%oil_tracer_CSp, tv, &
451 evap_cfl_limit=evap_cfl_limit, &
452 minimum_forcing_depth=minimum_forcing_depth)
454 if (cs%use_advection_test_tracer) &
455 call advection_test_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
456 g, gv, us, cs%advection_test_tracer_CSp, &
457 evap_cfl_limit=evap_cfl_limit, &
458 minimum_forcing_depth=minimum_forcing_depth)
459 if (cs%use_OCMIP2_CFC) &
460 call ocmip2_cfc_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
461 g, gv, us, cs%OCMIP2_CFC_CSp, &
462 evap_cfl_limit=evap_cfl_limit, &
463 minimum_forcing_depth=minimum_forcing_depth)
464 if (cs%use_MOM_generic_tracer)
then
465 if (us%QRZ_T_to_W_m2 /= 1.0)
call mom_error(fatal,
"MOM_generic_tracer_column_physics "//&
466 "has not been written to permit dimensionsal rescaling. Set all 4 of the "//&
467 "[QRZT]_RESCALE_POWER parameters to 0.")
468 call mom_generic_tracer_column_physics(h_old, h_new, ea, eb, fluxes, hml, us%T_to_s*dt, &
469 g, gv, cs%MOM_generic_tracer_CSp, tv, optics, &
470 evap_cfl_limit=evap_cfl_limit, &
471 minimum_forcing_depth=minimum_forcing_depth)
473 if (cs%use_pseudo_salt_tracer) &
474 call pseudo_salt_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
475 g, gv, us, cs%pseudo_salt_tracer_CSp, tv, debug, &
476 evap_cfl_limit=evap_cfl_limit, &
477 minimum_forcing_depth=minimum_forcing_depth)
478 if (cs%use_boundary_impulse_tracer) &
479 call boundary_impulse_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
480 g, gv, us, cs%boundary_impulse_tracer_CSp, tv, debug, &
481 evap_cfl_limit=evap_cfl_limit, &
482 minimum_forcing_depth=minimum_forcing_depth)
483 if (cs%use_dyed_obc_tracer) &
484 call dyed_obc_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
485 g, gv, us, cs%dyed_obc_tracer_CSp, &
486 evap_cfl_limit=evap_cfl_limit, &
487 minimum_forcing_depth=minimum_forcing_depth)
491 if (cs%use_USER_tracer_example) &
492 call tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
493 g, gv, us, cs%USER_tracer_example_CSp)
494 if (cs%use_DOME_tracer) &
495 call dome_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
496 g, gv, us, cs%DOME_tracer_CSp)
497 if (cs%use_ISOMIP_tracer) &
498 call isomip_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
499 g, gv, us, cs%ISOMIP_tracer_CSp)
500 if (cs%use_RGC_tracer) &
501 call rgc_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
502 g, gv, us, cs%RGC_tracer_CSp)
503 if (cs%use_ideal_age) &
504 call ideal_age_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
505 g, gv, us, cs%ideal_age_tracer_CSp)
506 if (cs%use_regional_dyes) &
507 call dye_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
508 g, gv, us, cs%dye_tracer_CSp)
510 call oil_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
511 g, gv, us, cs%oil_tracer_CSp, tv)
512 if (cs%use_advection_test_tracer) &
513 call advection_test_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
514 g, gv, us, cs%advection_test_tracer_CSp)
515 if (cs%use_OCMIP2_CFC) &
516 call ocmip2_cfc_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
517 g, gv, us, cs%OCMIP2_CFC_CSp)
518 if (cs%use_MOM_generic_tracer)
then
519 if (us%QRZ_T_to_W_m2 /= 1.0)
call mom_error(fatal,
"MOM_generic_tracer_column_physics "//&
520 "has not been written to permit dimensionsal rescaling. Set all 4 of the "//&
521 "[QRZT]_RESCALE_POWER parameters to 0.")
522 call mom_generic_tracer_column_physics(h_old, h_new, ea, eb, fluxes, hml, us%T_to_s*dt, &
523 g, gv, cs%MOM_generic_tracer_CSp, tv, optics)
525 if (cs%use_pseudo_salt_tracer) &
526 call pseudo_salt_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
527 g, gv, us, cs%pseudo_salt_tracer_CSp, tv, debug)
528 if (cs%use_boundary_impulse_tracer) &
529 call boundary_impulse_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
530 g, gv, us, cs%boundary_impulse_tracer_CSp, tv, debug)
531 if (cs%use_dyed_obc_tracer) &
532 call dyed_obc_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
533 g, gv, us, cs%dyed_obc_tracer_CSp)
538 end subroutine call_tracer_column_fns
542 subroutine call_tracer_stocks(h, stock_values, G, GV, CS, stock_names, stock_units, &
543 num_stocks, stock_index, got_min_max, global_min, global_max, &
544 xgmin, ygmin, zgmin, xgmax, ygmax, zgmax)
547 real,
dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
549 real,
dimension(:),
intent(out) :: stock_values
554 character(len=*),
dimension(:), &
555 optional,
intent(out) :: stock_names
556 character(len=*),
dimension(:), &
557 optional,
intent(out) :: stock_units
558 integer,
optional,
intent(out) :: num_stocks
559 integer,
optional,
intent(in) :: stock_index
562 logical,
dimension(:), &
563 optional,
intent(inout) :: got_min_max
565 real,
dimension(:),
optional,
intent(out) :: global_min
566 real,
dimension(:),
optional,
intent(out) :: global_max
567 real,
dimension(:),
optional,
intent(out) :: xgmin
568 real,
dimension(:),
optional,
intent(out) :: ygmin
569 real,
dimension(:),
optional,
intent(out) :: zgmin
570 real,
dimension(:),
optional,
intent(out) :: xgmax
571 real,
dimension(:),
optional,
intent(out) :: ygmax
572 real,
dimension(:),
optional,
intent(out) :: zgmax
575 character(len=200),
dimension(MAX_FIELDS_) :: names, units
576 character(len=200) :: set_pkg_name
577 real,
dimension(MAX_FIELDS_) :: values
578 integer :: max_ns, ns_tot, ns, index, pkg, max_pkgs, nn
580 if (.not.
associated(cs))
call mom_error(fatal,
"call_tracer_stocks: "// &
581 "Module must be initialized via call_tracer_register before it is used.")
583 index = -1 ;
if (
present(stock_index)) index = stock_index
585 max_ns =
size(stock_values)
586 if (
present(stock_names)) max_ns = min(max_ns,
size(stock_names))
587 if (
present(stock_units)) max_ns = min(max_ns,
size(stock_units))
590 if (cs%use_USER_tracer_example)
then
591 ns = user_tracer_stock(h, values, g, gv, cs%USER_tracer_example_CSp, &
592 names, units, stock_index)
593 call store_stocks(
"tracer_example", ns, names, units, values, index, stock_values, &
594 set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
602 if (cs%use_ideal_age)
then
603 ns = ideal_age_stock(h, values, g, gv, cs%ideal_age_tracer_CSp, &
604 names, units, stock_index)
605 call store_stocks(
"ideal_age_example", ns, names, units, values, index, &
606 stock_values, set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
608 if (cs%use_regional_dyes)
then
609 ns = dye_stock(h, values, g, gv, cs%dye_tracer_CSp, &
610 names, units, stock_index)
611 call store_stocks(
"regional_dyes", ns, names, units, values, index, &
612 stock_values, set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
615 ns = oil_stock(h, values, g, gv, cs%oil_tracer_CSp, &
616 names, units, stock_index)
617 call store_stocks(
"oil_tracer", ns, names, units, values, index, &
618 stock_values, set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
620 if (cs%use_OCMIP2_CFC)
then
621 ns = ocmip2_cfc_stock(h, values, g, gv, cs%OCMIP2_CFC_CSp, names, units, stock_index)
622 call store_stocks(
"MOM_OCMIP2_CFC", ns, names, units, values, index, stock_values, &
623 set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
626 if (cs%use_advection_test_tracer)
then
627 ns = advection_test_stock( h, values, g, gv, cs%advection_test_tracer_CSp, &
628 names, units, stock_index )
629 call store_stocks(
"advection_test_tracer", ns, names, units, values, index, &
630 stock_values, set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
633 if (cs%use_MOM_generic_tracer)
then
634 ns = mom_generic_tracer_stock(h, values, g, gv, cs%MOM_generic_tracer_CSp, &
635 names, units, stock_index)
636 call store_stocks(
"MOM_generic_tracer", ns, names, units, values, index, stock_values, &
637 set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
639 nn=mom_generic_tracer_min_max(nn, got_min_max, global_min, global_max, &
640 xgmin, ygmin, zgmin, xgmax, ygmax, zgmax ,&
641 g, cs%MOM_generic_tracer_CSp,names, units)
644 if (cs%use_pseudo_salt_tracer)
then
645 ns = pseudo_salt_stock(h, values, g, gv, cs%pseudo_salt_tracer_CSp, &
646 names, units, stock_index)
647 call store_stocks(
"pseudo_salt_tracer", ns, names, units, values, index, &
648 stock_values, set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
651 if (cs%use_boundary_impulse_tracer)
then
652 ns = boundary_impulse_stock(h, values, g, gv, cs%boundary_impulse_tracer_CSp, &
653 names, units, stock_index)
654 call store_stocks(
"boundary_impulse_tracer", ns, names, units, values, index, &
655 stock_values, set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
658 if (ns_tot == 0) stock_values(1) = 0.0
660 if (
present(num_stocks)) num_stocks = ns_tot
662 end subroutine call_tracer_stocks
665 subroutine store_stocks(pkg_name, ns, names, units, values, index, stock_values, &
666 set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
667 character(len=*),
intent(in) :: pkg_name
668 integer,
intent(in) :: ns
669 character(len=*),
dimension(:), &
671 character(len=*),
dimension(:), &
673 real,
dimension(:),
intent(in) :: values
674 integer,
intent(in) :: index
677 real,
dimension(:),
intent(inout) :: stock_values
678 character(len=*),
intent(inout) :: set_pkg_name
681 integer,
intent(in) :: max_ns
682 integer,
intent(inout) :: ns_tot
683 character(len=*),
dimension(:), &
684 optional,
intent(inout) :: stock_names
685 character(len=*),
dimension(:), &
686 optional,
intent(inout) :: stock_units
689 character(len=16) :: ind_text, ns_text, max_text
692 if ((index > 0) .and. (ns > 0))
then
693 write(ind_text,
'(i8)') index
695 call mom_error(fatal,
"Tracer package "//trim(pkg_name)//&
696 " is not permitted to return more than one value when queried"//&
697 " for specific stock index "//trim(adjustl(ind_text))//
".")
698 elseif (ns+ns_tot > 1)
then
699 call mom_error(fatal,
"Tracer packages "//trim(pkg_name)//
" and "//&
700 trim(set_pkg_name)//
" both attempted to set values for"//&
701 " specific stock index "//trim(adjustl(ind_text))//
".")
703 set_pkg_name = pkg_name
707 if (ns_tot+ns > max_ns)
then
708 write(ns_text,
'(i8)') ns_tot+ns ;
write(max_text,
'(i8)') max_ns
709 call mom_error(fatal,
"Attempted to return more tracer stock values (at least "//&
710 trim(adjustl(ns_text))//
") than the size "//trim(adjustl(max_text))//&
711 "of the smallest value, name, or units array.")
715 stock_values(ns_tot+n) = values(n)
716 if (
present(stock_names)) stock_names(ns_tot+n) = names(n)
717 if (
present(stock_units)) stock_units(ns_tot+n) = units(n)
721 end subroutine store_stocks
725 subroutine call_tracer_surface_state(sfc_state, h, G, CS)
729 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)), &
734 if (.not.
associated(cs))
call mom_error(fatal,
"call_tracer_surface_state: "// &
735 "Module must be initialized via call_tracer_register before it is used.")
738 if (cs%use_USER_tracer_example) &
739 call user_tracer_surface_state(sfc_state, h, g, cs%USER_tracer_example_CSp)
740 if (cs%use_DOME_tracer) &
741 call dome_tracer_surface_state(sfc_state, h, g, cs%DOME_tracer_CSp)
742 if (cs%use_ISOMIP_tracer) &
743 call isomip_tracer_surface_state(sfc_state, h, g, cs%ISOMIP_tracer_CSp)
744 if (cs%use_ideal_age) &
745 call ideal_age_tracer_surface_state(sfc_state, h, g, cs%ideal_age_tracer_CSp)
746 if (cs%use_regional_dyes) &
747 call dye_tracer_surface_state(sfc_state, h, g, cs%dye_tracer_CSp)
749 call oil_tracer_surface_state(sfc_state, h, g, cs%oil_tracer_CSp)
750 if (cs%use_advection_test_tracer) &
751 call advection_test_tracer_surface_state(sfc_state, h, g, cs%advection_test_tracer_CSp)
752 if (cs%use_OCMIP2_CFC) &
753 call ocmip2_cfc_surface_state(sfc_state, h, g, cs%OCMIP2_CFC_CSp)
754 if (cs%use_MOM_generic_tracer) &
755 call mom_generic_tracer_surface_state(sfc_state, h, g, cs%MOM_generic_tracer_CSp)
757 end subroutine call_tracer_surface_state
759 subroutine tracer_flow_control_end(CS)
763 if (cs%use_USER_tracer_example) &
764 call user_tracer_example_end(cs%USER_tracer_example_CSp)
765 if (cs%use_DOME_tracer)
call dome_tracer_end(cs%DOME_tracer_CSp)
766 if (cs%use_ISOMIP_tracer)
call isomip_tracer_end(cs%ISOMIP_tracer_CSp)
767 if (cs%use_RGC_tracer)
call rgc_tracer_end(cs%RGC_tracer_CSp)
768 if (cs%use_ideal_age)
call ideal_age_example_end(cs%ideal_age_tracer_CSp)
769 if (cs%use_regional_dyes)
call regional_dyes_end(cs%dye_tracer_CSp)
770 if (cs%use_oil)
call oil_tracer_end(cs%oil_tracer_CSp)
771 if (cs%use_advection_test_tracer)
call advection_test_tracer_end(cs%advection_test_tracer_CSp)
772 if (cs%use_OCMIP2_CFC)
call ocmip2_cfc_end(cs%OCMIP2_CFC_CSp)
773 if (cs%use_MOM_generic_tracer)
call end_mom_generic_tracer(cs%MOM_generic_tracer_CSp)
774 if (cs%use_pseudo_salt_tracer)
call pseudo_salt_tracer_end(cs%pseudo_salt_tracer_CSp)
775 if (cs%use_boundary_impulse_tracer)
call boundary_impulse_tracer_end(cs%boundary_impulse_tracer_CSp)
776 if (cs%use_dyed_obc_tracer)
call dyed_obc_tracer_end(cs%dyed_obc_tracer_CSp)
778 if (
associated(cs))
deallocate(cs)
779 end subroutine tracer_flow_control_end