MOM6
mom_ocmip2_cfc Module Reference

Data Types

type  ocmip2_cfc_cs
 
type  p3d
 

Functions/Subroutines

logical function, public register_ocmip2_cfc (HI, GV, param_file, CS, tr_Reg, restart_CS)
 
subroutine, public initialize_ocmip2_cfc (restart, day, G, GV, h, diag, OBC, CS, sponge_CSp, diag_to_Z_CSp)
 This subroutine initializes the NTR tracer fields in tr(:,:,:,:) and it sets up the tracer output. More...
 
subroutine init_tracer_cfc (h, tr, name, land_val, IC_val, G, CS)
 This subroutine initializes a tracer array. More...
 
subroutine, public ocmip2_cfc_column_physics (h_old, h_new, ea, eb, fluxes, dt, G, GV, CS, evap_CFL_limit, minimum_forcing_depth)
 This subroutine applies diapycnal diffusion and any other column. More...
 
integer function, public ocmip2_cfc_stock (h, stocks, G, GV, CS, names, units, stock_index)
 This function calculates the mass-weighted integral of all tracer stocks, returning the number of stocks it has calculated. If the stock_index is present, only the stock corresponding to that coded index is returned. More...
 
subroutine, public ocmip2_cfc_surface_state (state, h, G, CS)
 
subroutine, public ocmip2_cfc_end (CS)
 

Variables

integer, parameter ntr = 2
 

Function/Subroutine Documentation

◆ init_tracer_cfc()

subroutine mom_ocmip2_cfc::init_tracer_cfc ( real, dimension(szi_(g),szj_(g),szk_(g)), intent(in)  h,
real, dimension(szi_(g),szj_(g),szk_(g)), intent(out)  tr,
character(len=*), intent(in)  name,
real, intent(in)  land_val,
real, intent(in)  IC_val,
type(ocean_grid_type), intent(in)  G,
type(ocmip2_cfc_cs), pointer  CS 
)
private

This subroutine initializes a tracer array.

Parameters
[in]gThe ocean's grid structure
[in]hLayer thicknesses, in H (usually m or kg m-2)

Definition at line 501 of file MOM_OCMIP2_CFC.F90.

References mom_error_handler::mom_error(), and mom_tracer_z_init::tracer_z_init().

Referenced by initialize_ocmip2_cfc().

501  type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure
502  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2)
503  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: tr
504  character(len=*), intent(in) :: name
505  real, intent(in) :: land_val, ic_val
506  type(ocmip2_cfc_cs), pointer :: cs
507 
508  ! This subroutine initializes a tracer array.
509 
510  logical :: ok
511  integer :: i, j, k, is, ie, js, je, nz
512  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
513 
514  if (len_trim(cs%IC_file) > 0) then
515  ! Read the tracer concentrations from a netcdf file.
516  if (.not.file_exists(cs%IC_file, g%Domain)) &
517  call mom_error(fatal, "initialize_OCMIP2_CFC: Unable to open "//cs%IC_file)
518  if (cs%Z_IC_file) then
519  ok = tracer_z_init(tr, h, cs%IC_file, name, g)
520  if (.not.ok) then
521  ok = tracer_z_init(tr, h, cs%IC_file, trim(name), g)
522  if (.not.ok) call mom_error(fatal,"initialize_OCMIP2_CFC: "//&
523  "Unable to read "//trim(name)//" from "//&
524  trim(cs%IC_file)//".")
525  endif
526  else
527  call read_data(cs%IC_file, trim(name), tr, domain=g%Domain%mpp_domain)
528  endif
529  else
530  do k=1,nz ; do j=js,je ; do i=is,ie
531  if (g%mask2dT(i,j) < 0.5) then
532  tr(i,j,k) = land_val
533  else
534  tr(i,j,k) = ic_val
535  endif
536  enddo ; enddo ; enddo
537  endif
538 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the call graph for this function:
Here is the caller graph for this function:

◆ initialize_ocmip2_cfc()

subroutine, public mom_ocmip2_cfc::initialize_ocmip2_cfc ( logical, intent(in)  restart,
type(time_type), intent(in), target  day,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension(szi_(g),szj_(g),szk_(g)), intent(in)  h,
type(diag_ctrl), intent(in), target  diag,
type(ocean_obc_type), pointer  OBC,
type(ocmip2_cfc_cs), pointer  CS,
type(sponge_cs), pointer  sponge_CSp,
type(diag_to_z_cs), pointer  diag_to_Z_CSp 
)

This subroutine initializes the NTR tracer fields in tr(:,:,:,:) and it sets up the tracer output.

Parameters
[in]restart.true. if the fields have already been read from a restart file.
[in]dayTime of the start of the run.
[in]gThe ocean's grid structure.
[in]gvThe ocean's vertical grid structure.
[in]hLayer thicknesses, in H
[in]diagA structure that is used to regulate diagnostic output.
obcThis open boundary condition type specifies whether, where, and what open boundary conditions are used.
csThe control structure returned by a previous call to register_OCMIP2_CFC.
sponge_cspA pointer to the control structure for the sponges, if they are in use. Otherwise this may be unassociated.
diag_to_z_cspA pointer to the control structure for diagnostics in depth space.

Definition at line 374 of file MOM_OCMIP2_CFC.F90.

References mom_tracer_registry::add_tracer_diagnostics(), init_tracer_cfc(), mom_error_handler::mom_error(), ntr, mom_io::query_vardesc(), and mom_diag_to_z::register_z_tracer().

374  logical, intent(in) :: restart !< .true. if the fields have already been
375  !! read from a restart file.
376  type(time_type), target, intent(in) :: day !< Time of the start of the run.
377  type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure.
378  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
379  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), &
380  intent(in) :: h !< Layer thicknesses, in H
381  !! (usually m or kg m-2).
382  type(diag_ctrl), target, intent(in) :: diag !< A structure that is used to regulate
383  !! diagnostic output.
384  type(ocean_obc_type), pointer :: obc !< This open boundary condition type
385  !! specifies whether, where, and what
386  !! open boundary conditions are used.
387  type(ocmip2_cfc_cs), pointer :: cs !< The control structure returned by a
388  !! previous call to register_OCMIP2_CFC.
389  type(sponge_cs), pointer :: sponge_csp !< A pointer to the control structure for
390  !! the sponges, if they are in use.
391  !! Otherwise this may be unassociated.
392  type(diag_to_z_cs), pointer :: diag_to_z_csp !< A pointer to the control structure
393  !! for diagnostics in depth space.
394 ! This subroutine initializes the NTR tracer fields in tr(:,:,:,:)
395 ! and it sets up the tracer output.
396 
397 ! Arguments: restart - .true. if the fields have already been read from
398 ! a restart file.
399 ! (in) day - Time of the start of the run.
400 ! (in) G - The ocean's grid structure.
401 ! (in) GV - The ocean's vertical grid structure.
402 ! (in) h - Layer thickness, in m or kg m-2.
403 ! (in) diag - A structure that is used to regulate diagnostic output.
404 ! (in) OBC - This open boundary condition type specifies whether, where,
405 ! and what open boundary conditions are used.
406 ! (in/out) CS - The control structure returned by a previous call to
407 ! register_OCMIP2_CFC.
408 ! (in/out) sponge_CSp - A pointer to the control structure for the sponges, if
409 ! they are in use. Otherwise this may be unassociated.
410 ! (in/out) diag_to_Z_Csp - A pointer to the control structure for diagnostics
411 ! in depth space.
412  logical :: from_file = .false.
413  character(len=16) :: name ! A variable's name in a NetCDF file.
414  character(len=72) :: longname ! The long name of that variable.
415  character(len=48) :: units ! The dimensions of the variable.
416  character(len=48) :: flux_units ! The units for tracer fluxes.
417  integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz, m
418  integer :: isdb, iedb, jsdb, jedb
419 
420  if (.not.associated(cs)) return
421  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = gv%ke
422  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
423  isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
424 
425  cs%Time => day
426  cs%diag => diag
427 
428  if (.not.restart .or. (cs%tracers_may_reinit .and. &
429  .not.query_initialized(cs%CFC11, cs%CFC11_name, cs%restart_CSp))) &
430  call init_tracer_cfc(h, cs%CFC11, cs%CFC11_name, cs%CFC11_land_val, &
431  cs%CFC11_IC_val, g, cs)
432 
433  if (.not.restart .or. (cs%tracers_may_reinit .and. &
434  .not.query_initialized(cs%CFC12, cs%CFC12_name, cs%restart_CSp))) &
435  call init_tracer_cfc(h, cs%CFC12, cs%CFC12_name, cs%CFC12_land_val, &
436  cs%CFC12_IC_val, g, cs)
437 
438  if (associated(obc)) then
439  ! By default, all tracers have 0 concentration in their inflows. This may
440  ! make the following calls are unnecessary.
441  ! call add_tracer_OBC_values(trim(CS%CFC11_desc%name), CS%tr_Reg, 0.0)
442  ! call add_tracer_OBC_values(trim(CS%CFC12_desc%name), CS%tr_Reg, 0.0)
443  endif
444 
445 
446  ! This needs to be changed if the units of tracer are changed above.
447  if (gv%Boussinesq) then ; flux_units = "mol s-1"
448  else ; flux_units = "mol m-3 kg s-1" ; endif
449 
450  do m=1,ntr
451  ! Register the tracer advective and diffusive fluxes for potential
452  ! diagnostic output.
453  if (m==1) then
454  ! Register CFC11 for potential diagnostic output.
455  call query_vardesc(cs%CFC11_desc, name, units=units, longname=longname, &
456  caller="initialize_OCMIP2_CFC")
457  cs%id_CFC11 = register_diag_field("ocean_model", trim(name), cs%diag%axesTL, &
458  day, trim(longname) , trim(units))
459  call register_z_tracer(cs%CFC11, trim(name), longname, units, &
460  day, g, diag_to_z_csp)
461  elseif (m==2) then
462  ! Register CFC12 for potential diagnostic output.
463  call query_vardesc(cs%CFC12_desc, name, units=units, longname=longname, &
464  caller="initialize_OCMIP2_CFC")
465  cs%id_CFC12 = register_diag_field("ocean_model", trim(name), cs%diag%axesTL, &
466  day, trim(longname) , trim(units))
467  call register_z_tracer(cs%CFC12, trim(name), longname, units, &
468  day, g, diag_to_z_csp)
469  else
470  call mom_error(fatal,"initialize_OCMIP2_CFC is only set up to work"//&
471  "with NTR <= 2.")
472  endif
473 
474  cs%id_tr_adx(m) = register_diag_field("ocean_model", trim(name)//"_adx", &
475  cs%diag%axesCuL, day, trim(longname)//" advective zonal flux" , &
476  trim(flux_units))
477  cs%id_tr_ady(m) = register_diag_field("ocean_model", trim(name)//"_ady", &
478  cs%diag%axesCvL, day, trim(longname)//" advective meridional flux" , &
479  trim(flux_units))
480  cs%id_tr_dfx(m) = register_diag_field("ocean_model", trim(name)//"_dfx", &
481  cs%diag%axesCuL, day, trim(longname)//" diffusive zonal flux" , &
482  trim(flux_units))
483  cs%id_tr_dfy(m) = register_diag_field("ocean_model", trim(name)//"_dfy", &
484  cs%diag%axesCvL, day, trim(longname)//" diffusive zonal flux" , &
485  trim(flux_units))
486  if (cs%id_tr_adx(m) > 0) call safe_alloc_ptr(cs%tr_adx(m)%p,isdb,iedb,jsd,jed,nz)
487  if (cs%id_tr_ady(m) > 0) call safe_alloc_ptr(cs%tr_ady(m)%p,isd,ied,jsdb,jedb,nz)
488  if (cs%id_tr_dfx(m) > 0) call safe_alloc_ptr(cs%tr_dfx(m)%p,isdb,iedb,jsd,jed,nz)
489  if (cs%id_tr_dfy(m) > 0) call safe_alloc_ptr(cs%tr_dfy(m)%p,isd,ied,jsdb,jedb,nz)
490 
491 ! Register the tracer for horizontal advection & diffusion.
492  if ((cs%id_tr_adx(m) > 0) .or. (cs%id_tr_ady(m) > 0) .or. &
493  (cs%id_tr_dfx(m) > 0) .or. (cs%id_tr_dfy(m) > 0)) &
494  call add_tracer_diagnostics(name, cs%tr_Reg, cs%tr_adx(m)%p, &
495  cs%tr_ady(m)%p,cs%tr_dfx(m)%p,cs%tr_dfy(m)%p)
496  enddo
497 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the call graph for this function:

◆ ocmip2_cfc_column_physics()

subroutine, public mom_ocmip2_cfc::ocmip2_cfc_column_physics ( real, dimension(szi_(g),szj_(g),szk_(g)), intent(in)  h_old,
real, dimension(szi_(g),szj_(g),szk_(g)), intent(in)  h_new,
real, dimension(szi_(g),szj_(g),szk_(g)), intent(in)  ea,
real, dimension(szi_(g),szj_(g),szk_(g)), intent(in)  eb,
type(forcing), intent(in)  fluxes,
real, intent(in)  dt,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
type(ocmip2_cfc_cs), pointer  CS,
real, intent(in), optional  evap_CFL_limit,
real, intent(in), optional  minimum_forcing_depth 
)

This subroutine applies diapycnal diffusion and any other column.

Parameters
[in]gThe ocean's grid structure.
[in]gvThe ocean's vertical grid structure.
[in]h_oldLayer thickness before entrainment,
[in]h_newLayer thickness after entrainment,
[in]eaan array to which the amount of fluid
[in]eban array to which the amount of fluid
[in]fluxesA structure containing pointers to any possible forcing fields. Unused fields have NULL ptrs.
[in]dtThe amount of time covered by this call, in s
csThe control structure returned by a previous call to register_OCMIP2_CFC.

Definition at line 547 of file MOM_OCMIP2_CFC.F90.

References mom_tracer_diabatic::applytracerboundaryfluxesinout(), ntr, and mom_tracer_diabatic::tracer_vertdiff().

547  type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure.
548  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
549  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), &
550  intent(in) :: h_old !< Layer thickness before entrainment,
551  !! in m or kg m-2.
552  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), &
553  intent(in) :: h_new !< Layer thickness after entrainment,
554  !! in m or kg m-2.
555  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), &
556  intent(in) :: ea !< an array to which the amount of fluid
557  !! entrained from the layer above during
558  !! this call will be added, in m or kg m-2.
559  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), &
560  intent(in) :: eb !< an array to which the amount of fluid
561  !! entrained from the layer below during
562  !! this call will be added, in m or kg m-2.
563  type(forcing), intent(in) :: fluxes !< A structure containing pointers to any
564  !! possible forcing fields. Unused fields
565  !! have NULL ptrs.
566  real, intent(in) :: dt !< The amount of time covered by this
567  !! call, in s
568  type(ocmip2_cfc_cs), pointer :: cs !< The control structure returned by a
569  !! previous call to register_OCMIP2_CFC.
570  real, optional,intent(in) :: evap_cfl_limit
571  real, optional,intent(in) :: minimum_forcing_depth
572 ! This subroutine applies diapycnal diffusion and any other column
573 ! tracer physics or chemistry to the tracers from this file.
574 ! CFCs are relatively simple, as they are passive tracers. with only a surface
575 ! flux as a source.
576 
577 ! Arguments: h_old - Layer thickness before entrainment, in m or kg m-2.
578 ! (in) h_new - Layer thickness after entrainment, in m or kg m-2.
579 ! (in) ea - an array to which the amount of fluid entrained
580 ! from the layer above during this call will be
581 ! added, in m or kg m-2.
582 ! (in) eb - an array to which the amount of fluid entrained
583 ! from the layer below during this call will be
584 ! added, in m or kg m-2.
585 ! (in) fluxes - A structure containing pointers to any possible
586 ! forcing fields. Unused fields have NULL ptrs.
587 ! (in) dt - The amount of time covered by this call, in s.
588 ! (in) G - The ocean's grid structure.
589 ! (in) GV - The ocean's vertical grid structure.
590 ! (in) CS - The control structure returned by a previous call to
591 ! register_OCMIP2_CFC.
592 !
593 ! The arguments to this subroutine are redundant in that
594 ! h_new[k] = h_old[k] + ea[k] - eb[k-1] + eb[k] - ea[k+1]
595 
596  real :: b1(szi_(g)) ! b1 and c1 are variables used by the
597  real :: c1(szi_(g),szk_(g)) ! tridiagonal solver.
598  real, dimension(SZI_(G),SZJ_(G)) :: &
599  cfc11_flux, & ! The fluxes of CFC11 and CFC12 into the ocean, in the
600  cfc12_flux ! units of CFC concentrations times meters per second.
601  real, pointer, dimension(:,:,:) :: cfc11, cfc12
602  real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_work ! Used so that h can be modified
603  integer :: i, j, k, is, ie, js, je, nz, m
604 
605  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = gv%ke
606 
607  if (.not.associated(cs)) return
608 
609  cfc11 => cs%CFC11 ; cfc12 => cs%CFC12
610 
611  ! These two calls unpack the fluxes from the input arrays.
612  ! The -GV%Rho0 changes the sign convention of the flux and changes the units
613  ! of the flux from [Conc. m s-1] to [Conc. kg m-2 s-1].
614  call extract_coupler_values(fluxes%tr_fluxes, cs%ind_cfc_11_flux, ind_flux, &
615  cfc11_flux, is, ie, js, je, -gv%Rho0)
616  call extract_coupler_values(fluxes%tr_fluxes, cs%ind_cfc_12_flux, ind_flux, &
617  cfc12_flux, is, ie, js, je, -gv%Rho0)
618 
619  ! Use a tridiagonal solver to determine the concentrations after the
620  ! surface source is applied and diapycnal advection and diffusion occurs.
621  if (present(evap_cfl_limit) .and. present(minimum_forcing_depth)) then
622  do k=1,nz ;do j=js,je ; do i=is,ie
623  h_work(i,j,k) = h_old(i,j,k)
624  enddo ; enddo ; enddo;
625  call applytracerboundaryfluxesinout(g, gv, cfc11, dt, fluxes, h_work, &
626  evap_cfl_limit, minimum_forcing_depth)
627  call tracer_vertdiff(h_work, ea, eb, dt, cfc11, g, gv, sfc_flux=cfc11_flux)
628 
629  do k=1,nz ;do j=js,je ; do i=is,ie
630  h_work(i,j,k) = h_old(i,j,k)
631  enddo ; enddo ; enddo;
632  call applytracerboundaryfluxesinout(g, gv, cfc12, dt, fluxes, h_work, &
633  evap_cfl_limit, minimum_forcing_depth)
634  call tracer_vertdiff(h_work, ea, eb, dt, cfc12, g, gv, sfc_flux=cfc12_flux)
635  else
636  call tracer_vertdiff(h_old, ea, eb, dt, cfc11, g, gv, sfc_flux=cfc11_flux)
637  call tracer_vertdiff(h_old, ea, eb, dt, cfc12, g, gv, sfc_flux=cfc12_flux)
638  endif
639 
640  ! Write out any desired diagnostics.
641  if (cs%mask_tracers) then
642  do k=1,nz ; do j=js,je ; do i=is,ie
643  if (h_new(i,j,k) < 1.1*gv%Angstrom) then
644  cs%CFC11_aux(i,j,k) = cs%CFC11_land_val
645  cs%CFC12_aux(i,j,k) = cs%CFC12_land_val
646  else
647  cs%CFC11_aux(i,j,k) = cfc11(i,j,k)
648  cs%CFC12_aux(i,j,k) = cfc12(i,j,k)
649  endif
650  enddo ; enddo ; enddo
651  if (cs%id_CFC11>0) call post_data(cs%id_CFC11, cs%CFC11_aux, cs%diag)
652  if (cs%id_CFC12>0) call post_data(cs%id_CFC12, cs%CFC12_aux, cs%diag)
653  else
654  if (cs%id_CFC11>0) call post_data(cs%id_CFC11, cfc11, cs%diag)
655  if (cs%id_CFC12>0) call post_data(cs%id_CFC12, cfc12, cs%diag)
656  endif
657  do m=1,ntr
658  if (cs%id_tr_adx(m)>0) &
659  call post_data(cs%id_tr_adx(m),cs%tr_adx(m)%p(:,:,:),cs%diag)
660  if (cs%id_tr_ady(m)>0) &
661  call post_data(cs%id_tr_ady(m),cs%tr_ady(m)%p(:,:,:),cs%diag)
662  if (cs%id_tr_dfx(m)>0) &
663  call post_data(cs%id_tr_dfx(m),cs%tr_dfx(m)%p(:,:,:),cs%diag)
664  if (cs%id_tr_dfy(m)>0) &
665  call post_data(cs%id_tr_dfy(m),cs%tr_dfy(m)%p(:,:,:),cs%diag)
666  enddo
667 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the call graph for this function:

◆ ocmip2_cfc_end()

subroutine, public mom_ocmip2_cfc::ocmip2_cfc_end ( type(ocmip2_cfc_cs), pointer  CS)

Definition at line 814 of file MOM_OCMIP2_CFC.F90.

References ntr.

Referenced by mom_tracer_flow_control::tracer_flow_control_end().

814  type(ocmip2_cfc_cs), pointer :: cs
815 ! This subroutine deallocates the memory owned by this module.
816 ! Argument: CS - The control structure returned by a previous call to
817 ! register_OCMIP2_CFC.
818  integer :: m
819 
820  if (associated(cs)) then
821  if (associated(cs%CFC11)) deallocate(cs%CFC11)
822  if (associated(cs%CFC12)) deallocate(cs%CFC12)
823  if (associated(cs%CFC11_aux)) deallocate(cs%CFC11_aux)
824  if (associated(cs%CFC12_aux)) deallocate(cs%CFC12_aux)
825  do m=1,ntr
826  if (associated(cs%tr_adx(m)%p)) deallocate(cs%tr_adx(m)%p)
827  if (associated(cs%tr_ady(m)%p)) deallocate(cs%tr_ady(m)%p)
828  if (associated(cs%tr_dfx(m)%p)) deallocate(cs%tr_dfx(m)%p)
829  if (associated(cs%tr_dfy(m)%p)) deallocate(cs%tr_dfy(m)%p)
830  enddo
831 
832  deallocate(cs)
833  endif
Here is the caller graph for this function:

◆ ocmip2_cfc_stock()

integer function, public mom_ocmip2_cfc::ocmip2_cfc_stock ( real, dimension(szi_(g),szj_(g),szk_(g)), intent(in)  h,
real, dimension(:), intent(out)  stocks,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
type(ocmip2_cfc_cs), pointer  CS,
character(len=*), dimension(:), intent(out)  names,
character(len=*), dimension(:), intent(out)  units,
integer, intent(in), optional  stock_index 
)

This function calculates the mass-weighted integral of all tracer stocks, returning the number of stocks it has calculated. If the stock_index is present, only the stock corresponding to that coded index is returned.

Parameters
[in]gThe ocean's grid structure.
[in]gvThe ocean's vertical grid structure.
[in]hLayer thicknesses, in H
[out]stocksthe mass-weighted integrated amount of each tracer, in kg times concentration units.
csThe control structure returned by a previous call to register_OCMIP2_CFC.
[out]namesThe names of the stocks calculated.
[out]unitsThe units of the stocks calculated.
[in]stock_indexThe coded index of a specific stock being sought.

Definition at line 674 of file MOM_OCMIP2_CFC.F90.

References mom_io::query_vardesc().

Referenced by mom_tracer_flow_control::call_tracer_stocks().

674  type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure.
675  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
676  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), &
677  intent(in) :: h !< Layer thicknesses, in H
678  !! (usually m or kg m-2).
679  real, dimension(:), intent(out) :: stocks !< the mass-weighted integrated amount
680  !! of each tracer, in kg times
681  !! concentration units.
682  type(ocmip2_cfc_cs), pointer :: cs !< The control structure returned by a
683  !! previous call to register_OCMIP2_CFC.
684  character(len=*), dimension(:), intent(out) :: names !< The names of the stocks calculated.
685  character(len=*), dimension(:), intent(out) :: units !< The units of the stocks calculated.
686  integer, optional, intent(in) :: stock_index !< The coded index of a specific
687  !! stock being sought.
688  integer :: ocmip2_cfc_stock
689 ! This function calculates the mass-weighted integral of all tracer stocks,
690 ! returning the number of stocks it has calculated. If the stock_index
691 ! is present, only the stock corresponding to that coded index is returned.
692 
693 ! Arguments: h - Layer thickness, in m or kg m-2.
694 ! (out) stocks - the mass-weighted integrated amount of each tracer,
695 ! in kg times concentration units.
696 ! (in) G - The ocean's grid structure.
697 ! (in) GV - The ocean's vertical grid structure.
698 ! (in) CS - The control structure returned by a previous call to
699 ! register_OCMIP2_CFC.
700 ! (out) names - the names of the stocks calculated.
701 ! (out) units - the units of the stocks calculated.
702 ! (in,opt) stock_index - the coded index of a specific stock being sought.
703 ! Return value: the number of stocks calculated here.
704 
705  real :: mass
706  integer :: i, j, k, is, ie, js, je, nz
707  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = gv%ke
708 
709  ocmip2_cfc_stock = 0
710  if (.not.associated(cs)) return
711 
712  if (present(stock_index)) then ; if (stock_index > 0) then
713  ! Check whether this stock is available from this routine.
714 
715  ! No stocks from this routine are being checked yet. Return 0.
716  return
717  endif ; endif
718 
719  call query_vardesc(cs%CFC11_desc, name=names(1), units=units(1), caller="OCMIP2_CFC_stock")
720  call query_vardesc(cs%CFC12_desc, name=names(2), units=units(2), caller="OCMIP2_CFC_stock")
721  units(1) = trim(units(1))//" kg" ; units(2) = trim(units(2))//" kg"
722 
723  stocks(1) = 0.0 ; stocks(2) = 0.0
724  do k=1,nz ; do j=js,je ; do i=is,ie
725  mass = g%mask2dT(i,j) * g%areaT(i,j) * h(i,j,k)
726  stocks(1) = stocks(1) + cs%CFC11(i,j,k) * mass
727  stocks(2) = stocks(2) + cs%CFC12(i,j,k) * mass
728  enddo ; enddo ; enddo
729  stocks(1) = gv%H_to_kg_m2 * stocks(1)
730  stocks(2) = gv%H_to_kg_m2 * stocks(2)
731 
732  ocmip2_cfc_stock = 2
733 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ocmip2_cfc_surface_state()

subroutine, public mom_ocmip2_cfc::ocmip2_cfc_surface_state ( type(surface), intent(inout)  state,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke), intent(in)  h,
type(ocean_grid_type), intent(in)  G,
type(ocmip2_cfc_cs), pointer  CS 
)
Parameters
[in]gThe ocean's grid structure.
[in]hLayer thicknesses, in H (usually m or kg m-2).
csThe control structure returned by a previous call to register_OCMIP2_CFC.

Definition at line 737 of file MOM_OCMIP2_CFC.F90.

737  type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure.
738  type(surface), intent(inout) :: state
739  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H
740  !! (usually m or kg m-2).
741  type(ocmip2_cfc_cs), pointer :: cs !< The control structure returned
742  !! by a previous call to
743  !! register_OCMIP2_CFC.
744 ! This subroutine sets up the fields that the coupler needs to calculate the
745 ! CFC fluxes between the ocean and atmosphere.
746 ! Arguments: state - A structure containing fields that describe the
747 ! surface state of the ocean.
748 ! (in) h - Layer thickness, in m or kg m-2.
749 ! (in) G - The ocean's grid structure.
750 ! (in) CS - The control structure returned by a previous call to
751 ! register_OCMIP2_CFC.
752 
753  real, dimension(SZI_(G),SZJ_(G)) :: &
754  cfc11_csurf, & ! The CFC-11 and CFC-12 surface concentrations times the
755  cfc12_csurf, & ! Schmidt number term, both in mol m-3.
756  cfc11_alpha, & ! The CFC-11 solubility in mol m-3 pptv-1.
757  cfc12_alpha ! The CFC-12 solubility in mol m-3 pptv-1.
758  real :: ta ! Absolute sea surface temperature in units of dekaKelvin!?!
759  real :: sal ! Surface salinity in PSU.
760  real :: sst ! Sea surface temperature in degrees Celsius.
761  real :: alpha_11 ! The solubility of CFC 11 in mol m-3 pptv-1.
762  real :: alpha_12 ! The solubility of CFC 12 in mol m-3 pptv-1.
763  real :: sc_11, sc_12 ! The Schmidt numbers of CFC 11 and CFC 12.
764  real :: sc_no_term ! A term related to the Schmidt number.
765  integer :: i, j, k, is, ie, js, je, m
766 
767  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
768 
769  if (.not.associated(cs)) return
770 
771  do j=js,je ; do i=is,ie
772  ta = max(0.01, (state%SST(i,j) + 273.15) * 0.01) ! Why is this in hectoKelvin?
773  sal = state%SSS(i,j) ; sst = state%SST(i,j)
774  ! Calculate solubilities using Warner and Weiss (1985) DSR, vol 32.
775  ! The final result is in mol/cm3/pptv (1 part per trillion 1e-12)
776  ! Use Bullister and Wisegavger for CCl4.
777  ! The factor 1.e-09 converts from mol/(l * atm) to mol/(m3 * pptv).
778  alpha_11 = exp(cs%d1_11 + cs%d2_11/ta + cs%d3_11*log(ta) + cs%d4_11*ta**2 +&
779  sal * ((cs%e3_11 * ta + cs%e2_11) * ta + cs%e1_11)) * &
780  1.0e-09 * g%mask2dT(i,j)
781  alpha_12 = exp(cs%d1_12 + cs%d2_12/ta + cs%d3_12*log(ta) + cs%d4_12*ta**2 +&
782  sal * ((cs%e3_12 * ta + cs%e2_12) * ta + cs%e1_12)) * &
783  1.0e-09 * g%mask2dT(i,j)
784  ! Calculate Schmidt numbers using coefficients given by
785  ! Zheng et al (1998), JGR vol 103, C1.
786  sc_11 = cs%a1_11 + sst * (cs%a2_11 + sst * (cs%a3_11 + sst * cs%a4_11)) * &
787  g%mask2dT(i,j)
788  sc_12 = cs%a1_12 + sst * (cs%a2_12 + sst * (cs%a3_12 + sst * cs%a4_12)) * &
789  g%mask2dT(i,j)
790  ! The abs here is to avoid NaNs. The model should be failing at this point.
791  sc_no_term = sqrt(660.0 / (abs(sc_11) + 1.0e-30))
792  cfc11_alpha(i,j) = alpha_11 * sc_no_term
793  cfc11_csurf(i,j) = cs%CFC11(i,j,1) * sc_no_term
794 
795  sc_no_term = sqrt(660.0 / (abs(sc_12) + 1.0e-30))
796  cfc12_alpha(i,j) = alpha_12 * sc_no_term
797  cfc12_csurf(i,j) = cs%CFC12(i,j,1) * sc_no_term
798  enddo ; enddo
799 
800  ! These calls load these values into the appropriate arrays in the
801  ! coupler-type structure.
802  call set_coupler_values(cfc11_alpha, state%tr_fields, cs%ind_cfc_11_flux, &
803  ind_alpha, is, ie, js, je)
804  call set_coupler_values(cfc11_csurf, state%tr_fields, cs%ind_cfc_11_flux, &
805  ind_csurf, is, ie, js, je)
806  call set_coupler_values(cfc12_alpha, state%tr_fields, cs%ind_cfc_12_flux, &
807  ind_alpha, is, ie, js, je)
808  call set_coupler_values(cfc12_csurf, state%tr_fields, cs%ind_cfc_12_flux, &
809  ind_csurf, is, ie, js, je)
810 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19

◆ register_ocmip2_cfc()

logical function, public mom_ocmip2_cfc::register_ocmip2_cfc ( type(hor_index_type), intent(in)  HI,
type(verticalgrid_type), intent(in)  GV,
type(param_file_type), intent(in)  param_file,
type(ocmip2_cfc_cs), pointer  CS,
type(tracer_registry_type), pointer  tr_Reg,
type(mom_restart_cs), pointer  restart_CS 
)
Parameters
[in]hiA horizontal index type structure.
[in]gvThe ocean's vertical grid structure.
[in]param_fileA structure to parse for run-time parameters.
csA pointer that is set to point to the control structure for this module.
tr_regA pointer to the tracer registry.
restart_csA pointer to the restart control structure.

Definition at line 161 of file MOM_OCMIP2_CFC.F90.

References atmos_ocean_fluxes_mod::aof_set_coupler_flux(), mom_error_handler::mom_error(), and mom_io::var_desc().

161  type(hor_index_type), intent(in) :: hi !< A horizontal index type structure.
162  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
163  type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters.
164  type(ocmip2_cfc_cs), pointer :: cs !< A pointer that is set to point to the control
165  !! structure for this module.
166  type(tracer_registry_type), &
167  pointer :: tr_reg !< A pointer to the tracer registry.
168  type(mom_restart_cs), pointer :: restart_cs !< A pointer to the restart control structure.
169 ! This subroutine is used to register tracer fields and subroutines
170 ! to be used with MOM.
171 ! Arguments: HI - A horizontal index type structure.
172 ! (in) param_file - A structure indicating the open file to parse for
173 ! model parameter values.
174 ! (in/out) CS - A pointer that is set to point to the control structure
175 ! for this module
176 ! (in/out) tr_Reg - A pointer to the tracer registry.
177 ! (in) restart_CS - A pointer to the restart control structure.
178 
179 ! This include declares and sets the variable "version".
180 #include "version_variable.h"
181  character(len=40) :: mdl = "MOM_OCMIP2_CFC" ! This module's name.
182  character(len=200) :: inputdir ! The directory where NetCDF input files are.
183  ! These can be overridden later in via the field manager?
184  character(len=128) :: default_ice_restart_file = 'ice_ocmip2_cfc.res.nc'
185  character(len=128) :: default_ocean_restart_file = 'ocmip2_cfc.res.nc'
186  real, dimension(:,:,:), pointer :: tr_ptr
187  real :: a11_dflt(4), a12_dflt(4) ! Default values of the various coefficients
188  real :: d11_dflt(4), d12_dflt(4) ! In the expressions for the solubility and
189  real :: e11_dflt(3), e12_dflt(3) ! Schmidt numbers.
190  logical :: register_ocmip2_cfc
191  integer :: isd, ied, jsd, jed, nz, m
192 
193  isd = hi%isd ; ied = hi%ied ; jsd = hi%jsd ; jed = hi%jed ; nz = gv%ke
194 
195  if (associated(cs)) then
196  call mom_error(warning, "register_OCMIP2_CFC called with an "// &
197  "associated control structure.")
198  return
199  endif
200  allocate(cs)
201 
202  ! These calls obtain the indices for the CFC11 and CFC12 flux coupling.
203  cs%ind_cfc_11_flux = aof_set_coupler_flux('cfc_11_flux', &
204  flux_type = 'air_sea_gas_flux', implementation = 'ocmip2', &
205  param = (/ 9.36e-07, 9.7561e-06 /), &
206  ice_restart_file = default_ice_restart_file, &
207  ocean_restart_file = default_ocean_restart_file, &
208  caller = "register_OCMIP2_CFC")
209  cs%ind_cfc_12_flux = aof_set_coupler_flux('cfc_12_flux', &
210  flux_type = 'air_sea_gas_flux', implementation = 'ocmip2', &
211  param = (/ 9.36e-07, 9.7561e-06 /), &
212  ice_restart_file = default_ice_restart_file, &
213  ocean_restart_file = default_ocean_restart_file, &
214  caller = "register_OCMIP2_CFC")
215  if ((cs%ind_cfc_11_flux < 0) .or. (cs%ind_cfc_11_flux < 0)) then
216  ! This is most likely to happen with the dummy version of aof_set_coupler_flux
217  ! used in ocean-only runs.
218  call mom_error(warning, "CFCs are currently only set up to be run in " // &
219  " coupled model configurations, and will be disabled.")
220  deallocate(cs)
221  register_ocmip2_cfc = .false.
222  return
223  endif
224 
225  ! Read all relevant parameters and write them to the model log.
226  call log_version(param_file, mdl, version, "")
227  call get_param(param_file, mdl, "CFC_IC_FILE", cs%IC_file, &
228  "The file in which the CFC initial values can be \n"//&
229  "found, or an empty string for internal initialization.", &
230  default=" ")
231  if ((len_trim(cs%IC_file) > 0) .and. (scan(cs%IC_file,'/') == 0)) then
232  ! Add the directory if CS%IC_file is not already a complete path.
233  call get_param(param_file, mdl, "INPUTDIR", inputdir, default=".")
234  cs%IC_file = trim(slasher(inputdir))//trim(cs%IC_file)
235  call log_param(param_file, mdl, "INPUTDIR/CFC_IC_FILE", cs%IC_file)
236  endif
237  call get_param(param_file, mdl, "CFC_IC_FILE_IS_Z", cs%Z_IC_file, &
238  "If true, CFC_IC_FILE is in depth space, not layer space", &
239  default=.false.)
240  call get_param(param_file, mdl, "MASK_MASSLESS_TRACERS", cs%mask_tracers, &
241  "If true, the tracers are masked out in massless layer. \n"//&
242  "This can be a problem with time-averages.", default=.false.)
243  call get_param(param_file, mdl, "TRACERS_MAY_REINIT", cs%tracers_may_reinit, &
244  "If true, tracers may go through the initialization code \n"//&
245  "if they are not found in the restart files. Otherwise \n"//&
246  "it is a fatal error if tracers are not found in the \n"//&
247  "restart files of a restarted run.", default=.false.)
248 
249  ! The following vardesc types contain a package of metadata about each tracer,
250  ! including, the name; units; longname; and grid information.
251  cs%CFC11_name = "CFC11" ; cs%CFC12_name = "CFC12"
252  cs%CFC11_desc = var_desc(cs%CFC11_name,"mol m-3","CFC-11 Concentration", caller=mdl)
253  cs%CFC12_desc = var_desc(cs%CFC12_name,"mol m-3","CFC-12 Concentration", caller=mdl)
254 
255  allocate(cs%CFC11(isd:ied,jsd:jed,nz)) ; cs%CFC11(:,:,:) = 0.0
256  allocate(cs%CFC12(isd:ied,jsd:jed,nz)) ; cs%CFC12(:,:,:) = 0.0
257  if (cs%mask_tracers) then
258  allocate(cs%CFC11_aux(isd:ied,jsd:jed,nz)) ; cs%CFC11_aux(:,:,:) = 0.0
259  allocate(cs%CFC12_aux(isd:ied,jsd:jed,nz)) ; cs%CFC12_aux(:,:,:) = 0.0
260  endif
261 
262  ! This pointer assignment is needed to force the compiler not to do a copy in
263  ! the registration calls. Curses on the designers and implementers of F90.
264  tr_ptr => cs%CFC11
265  ! Register CFC11 for the restart file.
266  call register_restart_field(tr_ptr, cs%CFC11_desc, &
267  .not.cs%tracers_may_reinit, restart_cs)
268  ! Register CFC11 for horizontal advection & diffusion.
269  call register_tracer(tr_ptr, cs%CFC11_desc, param_file, hi, gv, tr_reg, &
270  tr_desc_ptr=cs%CFC11_desc)
271  ! Do the same for CFC12
272  tr_ptr => cs%CFC12
273  call register_restart_field(tr_ptr, cs%CFC12_desc, &
274  .not.cs%tracers_may_reinit, restart_cs)
275  call register_tracer(tr_ptr, cs%CFC12_desc, param_file, hi, gv, tr_reg, &
276  tr_desc_ptr=cs%CFC12_desc)
277 
278  ! Set and read the various empirical coefficients.
279 
280 !-----------------------------------------------------------------------
281 ! Default Schmidt number coefficients for CFC11 (_11) and CFC12 (_12) are given
282 ! by Zheng et al (1998), JGR vol 103, C1.
283 !-----------------------------------------------------------------------
284  a11_dflt(:) = (/ 3501.8, -210.31, 6.1851, -0.07513 /)
285  a12_dflt(:) = (/ 3845.4, -228.95, 6.1908, -0.06743 /)
286  call get_param(param_file, mdl, "CFC11_A1", cs%a1_11, &
287  "A coefficient in the Schmidt number of CFC11.", &
288  units="nondim", default=a11_dflt(1))
289  call get_param(param_file, mdl, "CFC11_A2", cs%a2_11, &
290  "A coefficient in the Schmidt number of CFC11.", &
291  units="degC-1", default=a11_dflt(2))
292  call get_param(param_file, mdl, "CFC11_A3", cs%a3_11, &
293  "A coefficient in the Schmidt number of CFC11.", &
294  units="degC-2", default=a11_dflt(3))
295  call get_param(param_file, mdl, "CFC11_A4", cs%a4_11, &
296  "A coefficient in the Schmidt number of CFC11.", &
297  units="degC-3", default=a11_dflt(4))
298 
299  call get_param(param_file, mdl, "CFC12_A1", cs%a1_12, &
300  "A coefficient in the Schmidt number of CFC12.", &
301  units="nondim", default=a12_dflt(1))
302  call get_param(param_file, mdl, "CFC12_A2", cs%a2_12, &
303  "A coefficient in the Schmidt number of CFC12.", &
304  units="degC-1", default=a12_dflt(2))
305  call get_param(param_file, mdl, "CFC12_A3", cs%a3_12, &
306  "A coefficient in the Schmidt number of CFC12.", &
307  units="degC-2", default=a12_dflt(3))
308  call get_param(param_file, mdl, "CFC12_A4", cs%a4_12, &
309  "A coefficient in the Schmidt number of CFC12.", &
310  units="degC-3", default=a12_dflt(4))
311 
312 !-----------------------------------------------------------------------
313 ! Solubility coefficients for alpha in mol/l/atm for CFC11 (_11) and CFC12 (_12)
314 ! after Warner and Weiss (1985) DSR, vol 32.
315 !-----------------------------------------------------------------------
316  d11_dflt(:) = (/ -229.9261, 319.6552, 119.4471, -1.39165 /)
317  e11_dflt(:) = (/ -0.142382, 0.091459, -0.0157274 /)
318  d12_dflt(:) = (/ -218.0971, 298.9702, 113.8049, -1.39165 /)
319  e12_dflt(:) = (/ -0.143566, 0.091015, -0.0153924 /)
320 
321  call get_param(param_file, mdl, "CFC11_D1", cs%d1_11, &
322  "A coefficient in the solubility of CFC11.", &
323  units="none", default=d11_dflt(1))
324  call get_param(param_file, mdl, "CFC11_D2", cs%d2_11, &
325  "A coefficient in the solubility of CFC11.", &
326  units="hK", default=d11_dflt(2))
327  call get_param(param_file, mdl, "CFC11_D3", cs%d3_11, &
328  "A coefficient in the solubility of CFC11.", &
329  units="none", default=d11_dflt(3))
330  call get_param(param_file, mdl, "CFC11_D4", cs%d4_11, &
331  "A coefficient in the solubility of CFC11.", &
332  units="hK-2", default=d11_dflt(4))
333  call get_param(param_file, mdl, "CFC11_E1", cs%e1_11, &
334  "A coefficient in the solubility of CFC11.", &
335  units="PSU-1", default=e11_dflt(1))
336  call get_param(param_file, mdl, "CFC11_E2", cs%e2_11, &
337  "A coefficient in the solubility of CFC11.", &
338  units="PSU-1 hK-1", default=e11_dflt(2))
339  call get_param(param_file, mdl, "CFC11_E3", cs%e3_11, &
340  "A coefficient in the solubility of CFC11.", &
341  units="PSU-1 hK-2", default=e11_dflt(3))
342 
343  call get_param(param_file, mdl, "CFC12_D1", cs%d1_12, &
344  "A coefficient in the solubility of CFC12.", &
345  units="none", default=d12_dflt(1))
346  call get_param(param_file, mdl, "CFC12_D2", cs%d2_12, &
347  "A coefficient in the solubility of CFC12.", &
348  units="hK", default=d12_dflt(2))
349  call get_param(param_file, mdl, "CFC12_D3", cs%d3_12, &
350  "A coefficient in the solubility of CFC12.", &
351  units="none", default=d12_dflt(3))
352  call get_param(param_file, mdl, "CFC12_D4", cs%d4_12, &
353  "A coefficient in the solubility of CFC12.", &
354  units="hK-2", default=d12_dflt(4))
355  call get_param(param_file, mdl, "CFC12_E1", cs%e1_12, &
356  "A coefficient in the solubility of CFC12.", &
357  units="PSU-1", default=e12_dflt(1))
358  call get_param(param_file, mdl, "CFC12_E2", cs%e2_12, &
359  "A coefficient in the solubility of CFC12.", &
360  units="PSU-1 hK-1", default=e12_dflt(2))
361  call get_param(param_file, mdl, "CFC12_E3", cs%e3_12, &
362  "A coefficient in the solubility of CFC12.", &
363  units="PSU-1 hK-2", default=e12_dflt(3))
364 
365  cs%tr_Reg => tr_reg
366  cs%restart_CSp => restart_cs
367 
368  register_ocmip2_cfc = .true.
Here is the call graph for this function:

Variable Documentation

◆ ntr

integer, parameter mom_ocmip2_cfc::ntr = 2
private

Definition at line 101 of file MOM_OCMIP2_CFC.F90.

Referenced by initialize_ocmip2_cfc(), ocmip2_cfc_column_physics(), and ocmip2_cfc_end().

101 integer, parameter :: ntr = 2