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 #ifdef _USE_GENERIC_TRACER
55 use mom_generic_tracer,
only : register_mom_generic_tracer, initialize_mom_generic_tracer
56 use mom_generic_tracer,
only : mom_generic_tracer_column_physics, mom_generic_tracer_surface_state
57 use mom_generic_tracer,
only : end_mom_generic_tracer, mom_generic_tracer_get, mom_generic_flux_init
58 use mom_generic_tracer,
only : mom_generic_tracer_stock, mom_generic_tracer_min_max, mom_generic_tracer_cs
60 use pseudo_salt_tracer,
only : register_pseudo_salt_tracer, initialize_pseudo_salt_tracer
61 use pseudo_salt_tracer,
only : pseudo_salt_tracer_column_physics, pseudo_salt_tracer_surface_state
64 use boundary_impulse_tracer,
only : boundary_impulse_tracer_column_physics, boundary_impulse_tracer_surface_state
68 implicit none ;
private
70 public call_tracer_register, tracer_flow_control_init, call_tracer_set_forcing
71 public call_tracer_column_fns, call_tracer_surface_state, call_tracer_stocks
72 public call_tracer_flux_init, get_chl_from_model, tracer_flow_control_end
76 logical :: use_user_tracer_example = .false.
77 logical :: use_dome_tracer = .false.
78 logical :: use_isomip_tracer = .false.
79 logical :: use_rgc_tracer =.false.
80 logical :: use_ideal_age = .false.
81 logical :: use_regional_dyes = .false.
82 logical :: use_oil = .false.
83 logical :: use_advection_test_tracer = .false.
84 logical :: use_ocmip2_cfc = .false.
85 logical :: use_mom_generic_tracer = .false.
86 logical :: use_pseudo_salt_tracer = .false.
87 logical :: use_boundary_impulse_tracer = .false.
88 logical :: use_dyed_obc_tracer = .false.
99 #ifdef _USE_GENERIC_TRACER
100 type(mom_generic_tracer_cs),
pointer :: mom_generic_tracer_csp => null()
116 subroutine call_tracer_flux_init(verbosity)
117 integer,
optional,
intent(in) :: verbosity
120 character(len=40) :: mdl =
"call_tracer_flux_init"
121 logical :: use_ocmip_cfcs, use_mom_generic_tracer
125 call get_mom_input(param_file, check_params=.false.)
127 call get_param(param_file, mdl,
"USE_OCMIP2_CFC", use_ocmip_cfcs, &
128 default=.false., do_not_log=.true.)
129 call get_param(param_file, mdl,
"USE_generic_tracer", use_mom_generic_tracer,&
130 default=.false., do_not_log=.true.)
131 call close_param_file(param_file, quiet_close=.true.)
133 if (use_ocmip_cfcs)
call flux_init_ocmip2_cfc(verbosity=verbosity)
134 if (use_mom_generic_tracer)
then
135 #ifdef _USE_GENERIC_TRACER
136 call mom_generic_flux_init(verbosity=verbosity)
138 call mom_error(fatal, &
139 "call_tracer_flux_init: use_MOM_generic_tracer=.true. but MOM6 was "//&
140 "not compiled with _USE_GENERIC_TRACER")
144 end subroutine call_tracer_flux_init
149 subroutine call_tracer_register(HI, GV, US, param_file, CS, tr_Reg, restart_CS)
173 #include "version_variable.h"
174 character(len=40) :: mdl =
"MOM_tracer_flow_control"
176 if (
associated(cs))
then
177 call mom_error(warning,
"call_tracer_register called with an associated "// &
178 "control structure.")
180 else ;
allocate(cs) ;
endif
184 call get_param(param_file, mdl,
"USE_USER_TRACER_EXAMPLE", &
185 cs%use_USER_tracer_example, &
186 "If true, use the USER_tracer_example tracer package.", &
188 call get_param(param_file, mdl,
"USE_DOME_TRACER", cs%use_DOME_tracer, &
189 "If true, use the DOME_tracer tracer package.", &
191 call get_param(param_file, mdl,
"USE_ISOMIP_TRACER", cs%use_ISOMIP_tracer, &
192 "If true, use the ISOMIP_tracer tracer package.", &
194 call get_param(param_file, mdl,
"USE_RGC_TRACER", cs%use_RGC_tracer, &
195 "If true, use the RGC_tracer tracer package.", &
197 call get_param(param_file, mdl,
"USE_IDEAL_AGE_TRACER", cs%use_ideal_age, &
198 "If true, use the ideal_age_example tracer package.", &
200 call get_param(param_file, mdl,
"USE_REGIONAL_DYES", cs%use_regional_dyes, &
201 "If true, use the regional_dyes tracer package.", &
203 call get_param(param_file, mdl,
"USE_OIL_TRACER", cs%use_oil, &
204 "If true, use the oil_tracer tracer package.", &
206 call get_param(param_file, mdl,
"USE_ADVECTION_TEST_TRACER", cs%use_advection_test_tracer, &
207 "If true, use the advection_test_tracer tracer package.", &
209 call get_param(param_file, mdl,
"USE_OCMIP2_CFC", cs%use_OCMIP2_CFC, &
210 "If true, use the MOM_OCMIP2_CFC tracer package.", &
212 call get_param(param_file, mdl,
"USE_generic_tracer", cs%use_MOM_generic_tracer, &
213 "If true and _USE_GENERIC_TRACER is defined as a "//&
214 "preprocessor macro, use the MOM_generic_tracer packages.", &
216 call get_param(param_file, mdl,
"USE_PSEUDO_SALT_TRACER", cs%use_pseudo_salt_tracer, &
217 "If true, use the pseudo salt tracer, typically run as a diagnostic.", &
219 call get_param(param_file, mdl,
"USE_BOUNDARY_IMPULSE_TRACER", cs%use_boundary_impulse_tracer, &
220 "If true, use the boundary impulse tracer.", &
222 call get_param(param_file, mdl,
"USE_DYED_OBC_TRACER", cs%use_dyed_obc_tracer, &
223 "If true, use the dyed_obc_tracer tracer package.", &
226 #ifndef _USE_GENERIC_TRACER
227 if (cs%use_MOM_generic_tracer)
call mom_error(fatal, &
228 "call_tracer_register: use_MOM_generic_tracer=.true. but MOM6 was "//&
229 "not compiled with _USE_GENERIC_TRACER")
235 if (cs%use_USER_tracer_example) cs%use_USER_tracer_example = &
236 user_register_tracer_example(hi, gv, param_file, cs%USER_tracer_example_CSp, &
238 if (cs%use_DOME_tracer) cs%use_DOME_tracer = &
239 register_dome_tracer(hi, gv, param_file, cs%DOME_tracer_CSp, &
241 if (cs%use_ISOMIP_tracer) cs%use_ISOMIP_tracer = &
242 register_isomip_tracer(hi, gv, param_file, cs%ISOMIP_tracer_CSp, &
244 if (cs%use_RGC_tracer) cs%use_RGC_tracer = &
245 register_rgc_tracer(hi, gv, param_file, cs%RGC_tracer_CSp, &
247 if (cs%use_ideal_age) cs%use_ideal_age = &
248 register_ideal_age_tracer(hi, gv, param_file, cs%ideal_age_tracer_CSp, &
250 if (cs%use_regional_dyes) cs%use_regional_dyes = &
251 register_dye_tracer(hi, gv, us, param_file, cs%dye_tracer_CSp, &
253 if (cs%use_oil) cs%use_oil = &
254 register_oil_tracer(hi, gv, param_file, cs%oil_tracer_CSp, &
256 if (cs%use_advection_test_tracer) cs%use_advection_test_tracer = &
257 register_advection_test_tracer(hi, gv, param_file, cs%advection_test_tracer_CSp, &
259 if (cs%use_OCMIP2_CFC) cs%use_OCMIP2_CFC = &
260 register_ocmip2_cfc(hi, gv, param_file, cs%OCMIP2_CFC_CSp, &
262 #ifdef _USE_GENERIC_TRACER
263 if (cs%use_MOM_generic_tracer) cs%use_MOM_generic_tracer = &
264 register_mom_generic_tracer(hi, gv, param_file, cs%MOM_generic_tracer_CSp, &
267 if (cs%use_pseudo_salt_tracer) cs%use_pseudo_salt_tracer = &
268 register_pseudo_salt_tracer(hi, gv, param_file, cs%pseudo_salt_tracer_CSp, &
270 if (cs%use_boundary_impulse_tracer) cs%use_boundary_impulse_tracer = &
271 register_boundary_impulse_tracer(hi, gv, param_file, cs%boundary_impulse_tracer_CSp, &
273 if (cs%use_dyed_obc_tracer) cs%use_dyed_obc_tracer = &
274 register_dyed_obc_tracer(hi, gv, param_file, cs%dyed_obc_tracer_CSp, &
278 end subroutine call_tracer_register
282 subroutine tracer_flow_control_init(restart, day, G, GV, US, h, param_file, diag, OBC, &
283 CS, sponge_CSp, ALE_sponge_CSp, tv)
284 logical,
intent(in) :: restart
286 type(time_type),
target,
intent(in) :: day
291 real,
dimension(NIMEM_,NJMEM_,NKMEM_),
intent(in) :: h
294 type(
diag_ctrl),
target,
intent(in) :: diag
312 if (.not.
associated(cs))
call mom_error(fatal,
"tracer_flow_control_init: "// &
313 "Module must be initialized via call_tracer_register before it is used.")
316 if (cs%use_USER_tracer_example) &
317 call user_initialize_tracer(restart, day, g, gv, h, diag, obc, cs%USER_tracer_example_CSp, &
319 if (cs%use_DOME_tracer) &
320 call initialize_dome_tracer(restart, day, g, gv, us, h, diag, obc, cs%DOME_tracer_CSp, &
321 sponge_csp, param_file)
322 if (cs%use_ISOMIP_tracer) &
323 call initialize_isomip_tracer(restart, day, g, gv, h, diag, obc, cs%ISOMIP_tracer_CSp, &
325 if (cs%use_RGC_tracer) &
326 call initialize_rgc_tracer(restart, day, g, gv, h, diag, obc, &
327 cs%RGC_tracer_CSp, sponge_csp, ale_sponge_csp)
328 if (cs%use_ideal_age) &
329 call initialize_ideal_age_tracer(restart, day, g, gv, us, h, diag, obc, cs%ideal_age_tracer_CSp, &
331 if (cs%use_regional_dyes) &
332 call initialize_dye_tracer(restart, day, g, gv, h, diag, obc, cs%dye_tracer_CSp, &
335 call initialize_oil_tracer(restart, day, g, gv, us, h, diag, obc, cs%oil_tracer_CSp, &
337 if (cs%use_advection_test_tracer) &
338 call initialize_advection_test_tracer(restart, day, g, gv, h, diag, obc, cs%advection_test_tracer_CSp, &
340 if (cs%use_OCMIP2_CFC) &
341 call initialize_ocmip2_cfc(restart, day, g, gv, us, h, diag, obc, cs%OCMIP2_CFC_CSp, &
343 #ifdef _USE_GENERIC_TRACER
344 if (cs%use_MOM_generic_tracer) &
345 call initialize_mom_generic_tracer(restart, day, g, gv, us, h, param_file, diag, obc, &
346 cs%MOM_generic_tracer_CSp, sponge_csp, ale_sponge_csp)
348 if (cs%use_pseudo_salt_tracer) &
349 call initialize_pseudo_salt_tracer(restart, day, g, gv, h, diag, obc, cs%pseudo_salt_tracer_CSp, &
351 if (cs%use_boundary_impulse_tracer) &
352 call initialize_boundary_impulse_tracer(restart, day, g, gv, h, diag, obc, cs%boundary_impulse_tracer_CSp, &
354 if (cs%use_dyed_obc_tracer) &
355 call initialize_dyed_obc_tracer(restart, day, g, gv, h, diag, obc, cs%dyed_obc_tracer_CSp)
357 end subroutine tracer_flow_control_init
360 subroutine get_chl_from_model(Chl_array, G, CS)
361 real,
dimension(NIMEM_,NJMEM_,NKMEM_), &
362 intent(out) :: chl_array
368 #ifdef _USE_GENERIC_TRACER
369 if (cs%use_MOM_generic_tracer)
then
370 call mom_generic_tracer_get(
'chl',
'field',chl_array, cs%MOM_generic_tracer_CSp)
372 call mom_error(fatal,
"get_chl_from_model was called in a configuration "// &
373 "that is unable to provide a sensible model-based value.\n"// &
374 "CS%use_MOM_generic_tracer is false and no other viable options are on.")
377 call mom_error(fatal,
"get_chl_from_model was called in a configuration "// &
378 "that is unable to provide a sensible model-based value.\n"// &
379 "_USE_GENERIC_TRACER is undefined and no other options "//&
380 "are currently viable.")
383 end subroutine get_chl_from_model
387 subroutine call_tracer_set_forcing(state, fluxes, day_start, day_interval, G, CS)
389 type(
surface),
intent(inout) :: state
392 type(
forcing),
intent(inout) :: fluxes
395 type(time_type),
intent(in) :: day_start
396 type(time_type),
intent(in) :: day_interval
402 if (.not.
associated(cs))
call mom_error(fatal,
"call_tracer_set_forcing"// &
403 "Module must be initialized via call_tracer_register before it is used.")
408 end subroutine call_tracer_set_forcing
411 subroutine call_tracer_column_fns(h_old, h_new, ea, eb, fluxes, Hml, dt, G, GV, tv, optics, CS, &
412 debug, evap_CFL_limit, minimum_forcing_depth)
413 real,
dimension(NIMEM_,NJMEM_,NKMEM_),
intent(in) :: h_old
415 real,
dimension(NIMEM_,NJMEM_,NKMEM_),
intent(in) :: h_new
417 real,
dimension(NIMEM_,NJMEM_,NKMEM_),
intent(in) :: ea
420 real,
dimension(NIMEM_,NJMEM_,NKMEM_),
intent(in) :: eb
423 type(
forcing),
intent(in) :: fluxes
426 real,
dimension(NIMEM_,NJMEM_),
intent(in) :: hml
427 real,
intent(in) :: dt
434 type(optics_type),
pointer :: optics
439 logical,
intent(in) :: debug
440 real,
optional,
intent(in) :: evap_cfl_limit
443 real,
optional,
intent(in) :: minimum_forcing_depth
446 if (.not.
associated(cs))
call mom_error(fatal,
"call_tracer_column_fns: "// &
447 "Module must be initialized via call_tracer_register before it is used.")
450 if (
present(evap_cfl_limit) .and.
present(minimum_forcing_depth))
then
452 if (cs%use_USER_tracer_example) &
453 call tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
454 g, gv, cs%USER_tracer_example_CSp)
455 if (cs%use_DOME_tracer) &
456 call dome_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
457 g, gv, cs%DOME_tracer_CSp, &
458 evap_cfl_limit=evap_cfl_limit, &
459 minimum_forcing_depth=minimum_forcing_depth)
460 if (cs%use_ISOMIP_tracer) &
461 call isomip_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
462 g, gv, cs%ISOMIP_tracer_CSp, &
463 evap_cfl_limit=evap_cfl_limit, &
464 minimum_forcing_depth=minimum_forcing_depth)
465 if (cs%use_RGC_tracer) &
466 call rgc_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
467 g, gv, cs%RGC_tracer_CSp, &
468 evap_cfl_limit=evap_cfl_limit, &
469 minimum_forcing_depth=minimum_forcing_depth)
470 if (cs%use_ideal_age) &
471 call ideal_age_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
472 g, gv, cs%ideal_age_tracer_CSp, &
473 evap_cfl_limit=evap_cfl_limit, &
474 minimum_forcing_depth=minimum_forcing_depth)
475 if (cs%use_regional_dyes) &
476 call dye_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
477 g, gv, cs%dye_tracer_CSp, &
478 evap_cfl_limit=evap_cfl_limit, &
479 minimum_forcing_depth=minimum_forcing_depth)
481 call oil_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
482 g, gv, cs%oil_tracer_CSp, tv, &
483 evap_cfl_limit=evap_cfl_limit, &
484 minimum_forcing_depth=minimum_forcing_depth)
486 if (cs%use_advection_test_tracer) &
487 call advection_test_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
488 g, gv, cs%advection_test_tracer_CSp, &
489 evap_cfl_limit=evap_cfl_limit, &
490 minimum_forcing_depth=minimum_forcing_depth)
491 if (cs%use_OCMIP2_CFC) &
492 call ocmip2_cfc_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
493 g, gv, cs%OCMIP2_CFC_CSp, &
494 evap_cfl_limit=evap_cfl_limit, &
495 minimum_forcing_depth=minimum_forcing_depth)
496 #ifdef _USE_GENERIC_TRACER
497 if (cs%use_MOM_generic_tracer) &
498 call mom_generic_tracer_column_physics(h_old, h_new, ea, eb, fluxes, hml, dt, &
499 g, gv, cs%MOM_generic_tracer_CSp, tv, optics, &
500 evap_cfl_limit=evap_cfl_limit, &
501 minimum_forcing_depth=minimum_forcing_depth)
503 if (cs%use_pseudo_salt_tracer) &
504 call pseudo_salt_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
505 g, gv, cs%pseudo_salt_tracer_CSp, tv, debug,&
506 evap_cfl_limit=evap_cfl_limit, &
507 minimum_forcing_depth=minimum_forcing_depth)
508 if (cs%use_boundary_impulse_tracer) &
509 call boundary_impulse_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
510 g, gv, cs%boundary_impulse_tracer_CSp, tv, debug,&
511 evap_cfl_limit=evap_cfl_limit, &
512 minimum_forcing_depth=minimum_forcing_depth)
513 if (cs%use_dyed_obc_tracer) &
514 call dyed_obc_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
515 g, gv, cs%dyed_obc_tracer_CSp, &
516 evap_cfl_limit=evap_cfl_limit, &
517 minimum_forcing_depth=minimum_forcing_depth)
521 if (cs%use_USER_tracer_example) &
522 call tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
523 g, gv, cs%USER_tracer_example_CSp)
524 if (cs%use_DOME_tracer) &
525 call dome_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
526 g, gv, cs%DOME_tracer_CSp)
527 if (cs%use_ISOMIP_tracer) &
528 call isomip_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
529 g, gv, cs%ISOMIP_tracer_CSp)
530 if (cs%use_RGC_tracer) &
531 call rgc_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
532 g, gv, cs%RGC_tracer_CSp)
533 if (cs%use_ideal_age) &
534 call ideal_age_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
535 g, gv, cs%ideal_age_tracer_CSp)
536 if (cs%use_regional_dyes) &
537 call dye_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
538 g, gv, cs%dye_tracer_CSp)
540 call oil_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
541 g, gv, cs%oil_tracer_CSp, tv)
542 if (cs%use_advection_test_tracer) &
543 call advection_test_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
544 g, gv, cs%advection_test_tracer_CSp)
545 if (cs%use_OCMIP2_CFC) &
546 call ocmip2_cfc_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
547 g, gv, cs%OCMIP2_CFC_CSp)
548 #ifdef _USE_GENERIC_TRACER
549 if (cs%use_MOM_generic_tracer) &
550 call mom_generic_tracer_column_physics(h_old, h_new, ea, eb, fluxes, hml, dt, &
551 g, gv, cs%MOM_generic_tracer_CSp, tv, optics)
553 if (cs%use_pseudo_salt_tracer) &
554 call pseudo_salt_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
555 g, gv, cs%pseudo_salt_tracer_CSp, tv, debug)
556 if (cs%use_boundary_impulse_tracer) &
557 call boundary_impulse_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
558 g, gv, cs%boundary_impulse_tracer_CSp, tv, debug)
559 if (cs%use_dyed_obc_tracer) &
560 call dyed_obc_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, &
561 g, gv, cs%dyed_obc_tracer_CSp)
567 end subroutine call_tracer_column_fns
571 subroutine call_tracer_stocks(h, stock_values, G, GV, CS, stock_names, stock_units, &
572 num_stocks, stock_index, got_min_max, global_min, global_max, &
573 xgmin, ygmin, zgmin, xgmax, ygmax, zgmax)
574 real,
dimension(NIMEM_,NJMEM_,NKMEM_), &
576 real,
dimension(:),
intent(out) :: stock_values
583 character(len=*),
dimension(:), &
584 optional,
intent(out) :: stock_names
585 character(len=*),
dimension(:), &
586 optional,
intent(out) :: stock_units
587 integer,
optional,
intent(out) :: num_stocks
588 integer,
optional,
intent(in) :: stock_index
591 logical,
dimension(:), &
592 optional,
intent(inout) :: got_min_max
594 real,
dimension(:),
optional,
intent(out) :: global_min
595 real,
dimension(:),
optional,
intent(out) :: global_max
596 real,
dimension(:),
optional,
intent(out) :: xgmin
597 real,
dimension(:),
optional,
intent(out) :: ygmin
598 real,
dimension(:),
optional,
intent(out) :: zgmin
599 real,
dimension(:),
optional,
intent(out) :: xgmax
600 real,
dimension(:),
optional,
intent(out) :: ygmax
601 real,
dimension(:),
optional,
intent(out) :: zgmax
604 character(len=200),
dimension(MAX_FIELDS_) :: names, units
605 character(len=200) :: set_pkg_name
606 real,
dimension(MAX_FIELDS_) :: values
607 integer :: max_ns, ns_tot, ns, index, pkg, max_pkgs, nn
609 if (.not.
associated(cs))
call mom_error(fatal,
"call_tracer_stocks: "// &
610 "Module must be initialized via call_tracer_register before it is used.")
612 index = -1 ;
if (
present(stock_index)) index = stock_index
614 max_ns =
size(stock_values)
615 if (
present(stock_names)) max_ns = min(max_ns,
size(stock_names))
616 if (
present(stock_units)) max_ns = min(max_ns,
size(stock_units))
619 if (cs%use_USER_tracer_example)
then
620 ns = user_tracer_stock(h, values, g, gv, cs%USER_tracer_example_CSp, &
621 names, units, stock_index)
622 call store_stocks(
"tracer_example", ns, names, units, values, index, stock_values, &
623 set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
631 if (cs%use_ideal_age)
then
632 ns = ideal_age_stock(h, values, g, gv, cs%ideal_age_tracer_CSp, &
633 names, units, stock_index)
634 call store_stocks(
"ideal_age_example", ns, names, units, values, index, &
635 stock_values, set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
637 if (cs%use_regional_dyes)
then
638 ns = dye_stock(h, values, g, gv, cs%dye_tracer_CSp, &
639 names, units, stock_index)
640 call store_stocks(
"regional_dyes", ns, names, units, values, index, &
641 stock_values, set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
644 ns = oil_stock(h, values, g, gv, cs%oil_tracer_CSp, &
645 names, units, stock_index)
646 call store_stocks(
"oil_tracer", ns, names, units, values, index, &
647 stock_values, set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
649 if (cs%use_OCMIP2_CFC)
then
650 ns = ocmip2_cfc_stock(h, values, g, gv, cs%OCMIP2_CFC_CSp, names, units, stock_index)
651 call store_stocks(
"MOM_OCMIP2_CFC", ns, names, units, values, index, stock_values, &
652 set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
655 if (cs%use_advection_test_tracer)
then
656 ns = advection_test_stock( h, values, g, gv, cs%advection_test_tracer_CSp, &
657 names, units, stock_index )
658 call store_stocks(
"advection_test_tracer", ns, names, units, values, index, &
659 stock_values, set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
662 #ifdef _USE_GENERIC_TRACER
663 if (cs%use_MOM_generic_tracer)
then
664 ns = mom_generic_tracer_stock(h, values, g, gv, cs%MOM_generic_tracer_CSp, &
665 names, units, stock_index)
666 call store_stocks(
"MOM_generic_tracer", ns, names, units, values, index, stock_values, &
667 set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
669 nn=mom_generic_tracer_min_max(nn, got_min_max, global_min, global_max, &
670 xgmin, ygmin, zgmin, xgmax, ygmax, zgmax ,&
671 g, cs%MOM_generic_tracer_CSp,names, units)
675 if (cs%use_pseudo_salt_tracer)
then
676 ns = pseudo_salt_stock(h, values, g, gv, cs%pseudo_salt_tracer_CSp, &
677 names, units, stock_index)
678 call store_stocks(
"pseudo_salt_tracer", ns, names, units, values, index, &
679 stock_values, set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
682 if (cs%use_boundary_impulse_tracer)
then
683 ns = boundary_impulse_stock(h, values, g, gv, cs%boundary_impulse_tracer_CSp, &
684 names, units, stock_index)
685 call store_stocks(
"boundary_impulse_tracer", ns, names, units, values, index, &
686 stock_values, set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
689 if (ns_tot == 0) stock_values(1) = 0.0
691 if (
present(num_stocks)) num_stocks = ns_tot
693 end subroutine call_tracer_stocks
696 subroutine store_stocks(pkg_name, ns, names, units, values, index, stock_values, &
697 set_pkg_name, max_ns, ns_tot, stock_names, stock_units)
698 character(len=*),
intent(in) :: pkg_name
699 integer,
intent(in) :: ns
700 character(len=*),
dimension(:), &
702 character(len=*),
dimension(:), &
704 real,
dimension(:),
intent(in) :: values
705 integer,
intent(in) :: index
708 real,
dimension(:),
intent(inout) :: stock_values
709 character(len=*),
intent(inout) :: set_pkg_name
712 integer,
intent(in) :: max_ns
713 integer,
intent(inout) :: ns_tot
714 character(len=*),
dimension(:), &
715 optional,
intent(inout) :: stock_names
716 character(len=*),
dimension(:), &
717 optional,
intent(inout) :: stock_units
720 character(len=16) :: ind_text, ns_text, max_text
723 if ((index > 0) .and. (ns > 0))
then
724 write(ind_text,
'(i8)') index
726 call mom_error(fatal,
"Tracer package "//trim(pkg_name)//&
727 " is not permitted to return more than one value when queried"//&
728 " for specific stock index "//trim(adjustl(ind_text))//
".")
729 elseif (ns+ns_tot > 1)
then
730 call mom_error(fatal,
"Tracer packages "//trim(pkg_name)//
" and "//&
731 trim(set_pkg_name)//
" both attempted to set values for"//&
732 " specific stock index "//trim(adjustl(ind_text))//
".")
734 set_pkg_name = pkg_name
738 if (ns_tot+ns > max_ns)
then
739 write(ns_text,
'(i8)') ns_tot+ns ;
write(max_text,
'(i8)') max_ns
740 call mom_error(fatal,
"Attempted to return more tracer stock values (at least "//&
741 trim(adjustl(ns_text))//
") than the size "//trim(adjustl(max_text))//&
742 "of the smallest value, name, or units array.")
746 stock_values(ns_tot+n) = values(n)
747 if (
present(stock_names)) stock_names(ns_tot+n) = names(n)
748 if (
present(stock_units)) stock_units(ns_tot+n) = units(n)
752 end subroutine store_stocks
756 subroutine call_tracer_surface_state(state, h, G, CS)
759 real,
dimension(NIMEM_,NJMEM_,NKMEM_), &
765 if (.not.
associated(cs))
call mom_error(fatal,
"call_tracer_surface_state: "// &
766 "Module must be initialized via call_tracer_register before it is used.")
769 if (cs%use_USER_tracer_example) &
770 call user_tracer_surface_state(state, h, g, cs%USER_tracer_example_CSp)
771 if (cs%use_DOME_tracer) &
772 call dome_tracer_surface_state(state, h, g, cs%DOME_tracer_CSp)
773 if (cs%use_ISOMIP_tracer) &
774 call isomip_tracer_surface_state(state, h, g, cs%ISOMIP_tracer_CSp)
775 if (cs%use_ideal_age) &
776 call ideal_age_tracer_surface_state(state, h, g, cs%ideal_age_tracer_CSp)
777 if (cs%use_regional_dyes) &
778 call dye_tracer_surface_state(state, h, g, cs%dye_tracer_CSp)
780 call oil_tracer_surface_state(state, h, g, cs%oil_tracer_CSp)
781 if (cs%use_advection_test_tracer) &
782 call advection_test_tracer_surface_state(state, h, g, cs%advection_test_tracer_CSp)
783 if (cs%use_OCMIP2_CFC) &
784 call ocmip2_cfc_surface_state(state, h, g, cs%OCMIP2_CFC_CSp)
785 #ifdef _USE_GENERIC_TRACER
786 if (cs%use_MOM_generic_tracer) &
787 call mom_generic_tracer_surface_state(state, h, g, cs%MOM_generic_tracer_CSp)
790 end subroutine call_tracer_surface_state
792 subroutine tracer_flow_control_end(CS)
796 if (cs%use_USER_tracer_example) &
797 call user_tracer_example_end(cs%USER_tracer_example_CSp)
798 if (cs%use_DOME_tracer)
call dome_tracer_end(cs%DOME_tracer_CSp)
799 if (cs%use_ISOMIP_tracer)
call isomip_tracer_end(cs%ISOMIP_tracer_CSp)
800 if (cs%use_RGC_tracer)
call rgc_tracer_end(cs%RGC_tracer_CSp)
801 if (cs%use_ideal_age)
call ideal_age_example_end(cs%ideal_age_tracer_CSp)
802 if (cs%use_regional_dyes)
call regional_dyes_end(cs%dye_tracer_CSp)
803 if (cs%use_oil)
call oil_tracer_end(cs%oil_tracer_CSp)
804 if (cs%use_advection_test_tracer)
call advection_test_tracer_end(cs%advection_test_tracer_CSp)
805 if (cs%use_OCMIP2_CFC)
call ocmip2_cfc_end(cs%OCMIP2_CFC_CSp)
806 #ifdef _USE_GENERIC_TRACER
807 if (cs%use_MOM_generic_tracer)
call end_mom_generic_tracer(cs%MOM_generic_tracer_CSp)
809 if (cs%use_pseudo_salt_tracer)
call pseudo_salt_tracer_end(cs%pseudo_salt_tracer_CSp)
810 if (cs%use_boundary_impulse_tracer)
call boundary_impulse_tracer_end(cs%boundary_impulse_tracer_CSp)
811 if (cs%use_dyed_obc_tracer)
call dyed_obc_tracer_end(cs%dyed_obc_tracer_CSp)
813 if (
associated(cs))
deallocate(cs)
814 end subroutine tracer_flow_control_end