MOM6
mom_forcing_type Module Reference

Detailed Description

This module implements boundary forcing for MOM6.

Boundary fluxes

The ocean is a forced-dissipative system. Forcing occurs at the boundaries, and this module mediates the various forcing terms from momentum, heat, salt, and mass. Boundary fluxes from other tracers are treated by coupling to biogeochemical models. We here present elements of how MOM6 assumes boundary fluxes are passed into the ocean.

Note that all fluxes are positive into the ocean. For surface boundary fluxes, that means fluxes are positive downward. For example, a positive shortwave flux warms the ocean.

Surface boundary momentum fluxes

The ocean surface exchanges momentum with the overlying atmosphere, sea ice, and land ice. The momentum is exchanged as a horizontal stress (Newtons per squared meter: N/m2) imposed on the upper ocean grid cell.

Surface boundary mass fluxes

The ocean gains or loses mass through evaporation, precipitation, sea ice melt/form, and and river runoff. Positive mass fluxes add mass to the liquid ocean. The boundary mass flux units are (kilogram per square meter per sec: kg/(m2/sec)).

  • Evaporation field can in fact represent a mass loss (evaporation) or mass gain (condensation in foggy areas).
  • sea ice formation leads to mass moving from the liquid ocean to the ice model, and melt adds liquid to the ocean.
  • Precipitation can be liquid or frozen (snow). Furthermore, in some versions of the GFDL coupler, precipitation can be negative. The reason is that the ice model combines precipitation with ice melt and ice formation. This limitation of the ice model diagnostics should be overcome future versions.
  • River runoff can be liquid or frozen. Frozen runoff is often associated with calving land-ice and/or ice bergs.

Surface boundary salt fluxes

Over most of the ocean, there is no exchange of salt with the atmosphere. However, the liquid ocean exchanges salt with sea ice. When ice forms, it extracts salt from ice pockets and discharges the salt into the liquid ocean. The salt concentration of sea ice is therefore much lower (around 5ppt) than liquid seawater (around 30-35ppt in high latitudes).

For ocean-ice models run with a prescribed atmosphere, such as in the CORE/OMMIP simulations, it is necessary to employ a surface restoring term to the k=1 salinity equation, thus imposing a salt flux onto the ocean even outside of sea ice regimes. This salt flux is non-physical, and represents a limitation of the ocean-ice models run without an interactive atmosphere. Sometimes this salt flux is converted to an implied fresh water flux. However, doing so generally leads to changes in the sea level, unless a global normalization is provided to zero-out the net water flux. As a complement, for models with a restoring salt flux, one may choose to zero-out the net salt entering the ocean. There are pros/cons of each approach.

Surface boundary heat fluxes

There are many terms that contribute to boundary-related heating of the k=1 surface model grid cell. We here outline details of this heat, with each term having units W/m2.

The net flux of heat crossing ocean surface is stored in the diagnostic array "hfds". This array is computed as

\[ \mbox{hfds = shortwave + longwave + latent + sensible + mass transfer + frazil + restore + flux adjustments} \]

  • shortwave (SW) = shortwave radiation (always warms ocean)
  • longwave (LW) = longwave radiation (generally cools ocean)
  • latent (LAT) = turbulent latent heat loss due to evaporation (liquid to vapor) or melt (snow to liquid); generally cools the ocean
  • sensible (SENS) = turbulent heat transfer due to differences in air-sea or ice-sea temperature
  • mass transfer (MASS) = heat transfer due to heat content of mass (e.g., E-P+R) transferred across ocean surface; computed relative to 0 Celsius
  • frazil (FRAZ) = heat transferred to form frazil sea ice (positive heating of liquid ocean)
  • restore (RES) = heat from surface damping sometimes imposed in non-coupled model simulations .
  • restore (flux adjustments) = heat from surface flux adjustment.

Treatment of shortwave

The shortwave field itself is split into two pieces:

  • shortwave = penetrative SW + non-penetrative SW
  • non-penetrative = non-downwelling shortwave; portion of SW totally absorbed in the k=1 cell. The non-penetrative SW is combined with LW+LAT+SENS+seaice_melt_heat in net_heat inside routine extractFluxes1d. Notably, for many cases, non-penetrative SW = 0.
  • penetrative = that portion of shortwave penetrating below a tiny surface layer. This is the downwelling shortwave. Penetrative SW participates in the penetrative SW heating of k=1,nz cells, with the amount of penetration dependent on optical properties.

Convergence of heat into the k=1 cell

The convergence of boundary-related heat into surface grid cell is given by the difference in the net heat entering the top of the k=1 cell and the penetrative SW leaving the bottom of the cell.

\begin{eqnarray*} Q(k=1) &=& \mbox{hfds} - \mbox{pen}\_\mbox{SW(leaving bottom of k=1)} \\ &=& \mbox{nonpen}\_\mbox{SW} + (\mbox{pen}\_\mbox{SW(enter k=1)}-\mbox{pen}\_\mbox{SW(leave k=1)}) + \mbox{LW+LAT+SENS+MASS+FRAZ+RES} \\ &=& \mbox{nonpen}\_\mbox{SW}+ \mbox{LW+LAT+SENS+MASS+FRAZ+RES} + [\mbox{pen}\_\mbox{SW(enter k=1)} - \mbox{pen}\_\mbox{SW(leave k=1)}] \end{eqnarray*}

The convergence of the penetrative shortwave flux is given by \( \mbox{pen}\_\mbox{SW (enter k)}-\mbox{pen}\_\mbox{SW (leave k)}\). This term appears for all cells k=1,nz. It is diagnosed as "rsdoabsorb" inside module MOM6/src/parameterizations/vertical/MOM_diabatic_aux.F90

Data Types

interface  allocate_forcing_type
 Allocate the fields of a (flux) forcing type, based on either a set of input flags for each group of fields, or a pre-allocated reference forcing. More...
 
interface  allocate_mech_forcing
 Allocate the fields of a mechanical forcing type, based on either a set of input flags for each group of fields, or a pre-allocated reference forcing. More...
 
type  forcing
 Structure that contains pointers to the boundary forcing used to drive the liquid ocean simulated by MOM. More...
 
type  forcing_diags
 Structure that defines the id handles for the forcing type. More...
 
type  mech_forcing
 Structure that contains pointers to the mechanical forcing at the surface used to drive the liquid ocean simulated by MOM. Data in this type is allocated in the module MOM_surface_forcing.F90, of which there are three versions: solo, coupled, and ice-shelf. More...
 

Functions/Subroutines

subroutine, public extractfluxes1d (G, GV, US, fluxes, optics, nsw, j, dt, FluxRescaleDepth, useRiverHeatContent, useCalvingHeatContent, h, T, netMassInOut, netMassOut, net_heat, net_salt, pen_SW_bnd, tv, aggregate_FW, nonpenSW, netmassInOut_rate, net_Heat_Rate, net_salt_rate, pen_sw_bnd_Rate, skip_diags)
 This subroutine extracts fluxes from the surface fluxes type. It works on a j-row for optimization purposes. The 2d (i,j) wrapper is the next subroutine below. This routine multiplies fluxes by dt, so that the result is an accumulation of fluxes over a time step. More...
 
subroutine, public extractfluxes2d (G, GV, US, fluxes, optics, nsw, dt, FluxRescaleDepth, useRiverHeatContent, useCalvingHeatContent, h, T, netMassInOut, netMassOut, net_heat, Net_salt, Pen_SW_bnd, tv, aggregate_FW)
 2d wrapper for 1d extract fluxes from surface fluxes type. This subroutine extracts fluxes from the surface fluxes type. It multiplies the fluxes by dt, so that the result is an accumulation of the fluxes over a time step. More...
 
subroutine, public calculatebuoyancyflux1d (G, GV, US, fluxes, optics, nsw, h, Temp, Salt, tv, j, buoyancyFlux, netHeatMinusSW, netSalt, skip_diags)
 This routine calculates surface buoyancy flux by adding up the heat, FW & salt fluxes. These are actual fluxes, with units of stuff per time. Setting dt=1 in the call to extractFluxes routine allows us to get "stuf per time" rather than the time integrated fluxes needed in other routines that call extractFluxes. More...
 
subroutine, public calculatebuoyancyflux2d (G, GV, US, fluxes, optics, h, Temp, Salt, tv, buoyancyFlux, netHeatMinusSW, netSalt, skip_diags)
 Calculates surface buoyancy flux by adding up the heat, FW and salt fluxes, for 2d arrays. This is a wrapper for calculateBuoyancyFlux1d. More...
 
subroutine, public mom_forcing_chksum (mesg, fluxes, G, US, haloshift)
 Write out chksums for thermodynamic fluxes. More...
 
subroutine, public mom_mech_forcing_chksum (mesg, forces, G, US, haloshift)
 Write out chksums for the driving mechanical forces. More...
 
subroutine mech_forcing_singlepointprint (forces, G, i, j, mesg)
 Write out values of the mechanical forcing arrays at the i,j location. This is a debugging tool. More...
 
subroutine, public forcing_singlepointprint (fluxes, G, i, j, mesg)
 Write out values of the fluxes arrays at the i,j location. This is a debugging tool. More...
 
subroutine, public register_forcing_type_diags (Time, diag, US, use_temperature, handles, use_berg_fluxes)
 Register members of the forcing type for diagnostics. More...
 
subroutine, public forcing_accumulate (flux_tmp, forces, fluxes, G, wt2)
 Accumulate the forcing over time steps, taking input from a mechanical forcing type and a temporary forcing-flux type. More...
 
subroutine, public fluxes_accumulate (flux_tmp, fluxes, G, wt2, forces)
 Accumulate the thermodynamic fluxes over time steps. More...
 
subroutine, public copy_common_forcing_fields (forces, fluxes, G, skip_pres)
 This subroutine copies the computational domains of common forcing fields from a mech_forcing type to a (thermodynamic) forcing type. More...
 
subroutine, public set_derived_forcing_fields (forces, fluxes, G, US, Rho0)
 This subroutine calculates certain derived forcing fields based on information from a mech_forcing type and stores them in a (thermodynamic) forcing type. More...
 
subroutine, public set_net_mass_forcing (fluxes, forces, G, US)
 This subroutine determines the net mass source to the ocean from a (thermodynamic) forcing type and stores it in a mech_forcing type. More...
 
subroutine, public get_net_mass_forcing (fluxes, G, US, net_mass_src)
 This subroutine calculates determines the net mass source to the ocean from a (thermodynamic) forcing type and stores it in a provided array. More...
 
subroutine, public copy_back_forcing_fields (fluxes, forces, G)
 This subroutine copies the computational domains of common forcing fields from a mech_forcing type to a (thermodynamic) forcing type. More...
 
subroutine, public mech_forcing_diags (forces_in, dt, G, time_end, diag, handles)
 Offer mechanical forcing fields for diagnostics for those fields registered as part of register_forcing_type_diags. More...
 
subroutine, public forcing_diagnostics (fluxes_in, sfc_state, G_in, US, time_end, diag, handles)
 Offer buoyancy forcing fields for diagnostics for those fields registered as part of register_forcing_type_diags. More...
 
subroutine allocate_forcing_by_group (G, fluxes, water, heat, ustar, press, shelf, iceberg, salt, fix_accum_bug)
 Conditionally allocate fields within the forcing type. More...
 
subroutine allocate_forcing_by_ref (fluxes_ref, G, fluxes)
 
subroutine allocate_mech_forcing_by_group (G, forces, stress, ustar, shelf, press, iceberg)
 Conditionally allocate fields within the mechanical forcing type using control flags. More...
 
subroutine allocate_mech_forcing_from_ref (forces_ref, G, forces)
 Conditionally allocate fields within the mechanical forcing type based on a reference forcing. More...
 
subroutine get_forcing_groups (fluxes, water, heat, ustar, press, shelf, iceberg, salt, heat_added, buoy)
 Return flags indicating which groups of forcings are allocated. More...
 
subroutine get_mech_forcing_groups (forces, stress, ustar, shelf, press, iceberg)
 Return flags indicating which groups of mechanical forcings are allocated. More...
 
subroutine myalloc (array, is, ie, js, je, flag)
 Allocates and zeroes-out array. More...
 
subroutine, public deallocate_forcing_type (fluxes)
 Deallocate the forcing type. More...
 
subroutine, public deallocate_mech_forcing (forces)
 Deallocate the mechanical forcing type. More...
 
subroutine, public rotate_forcing (fluxes_in, fluxes, turns)
 
subroutine, public rotate_mech_forcing (forces_in, turns, forces)
 

Function/Subroutine Documentation

◆ allocate_forcing_by_group()

subroutine mom_forcing_type::allocate_forcing_by_group ( type(ocean_grid_type), intent(in)  G,
type(forcing), intent(inout)  fluxes,
logical, intent(in), optional  water,
logical, intent(in), optional  heat,
logical, intent(in), optional  ustar,
logical, intent(in), optional  press,
logical, intent(in), optional  shelf,
logical, intent(in), optional  iceberg,
logical, intent(in), optional  salt,
logical, intent(in), optional  fix_accum_bug 
)
private

Conditionally allocate fields within the forcing type.

Parameters
[in]gOcean grid structure
[in,out]fluxesA structure containing thermodynamic forcing fields
[in]waterIf present and true, allocate water fluxes
[in]heatIf present and true, allocate heat fluxes
[in]ustarIf present and true, allocate ustar and related fields
[in]pressIf present and true, allocate p_surf and related fields
[in]shelfIf present and true, allocate fluxes for ice-shelf
[in]icebergIf present and true, allocate fluxes for icebergs
[in]saltIf present and true, allocate salt fluxes
[in]fix_accum_bugIf present and true, avoid using a bug in accumulation of ustar_gustless

Definition at line 2865 of file MOM_forcing_type.F90.

2867  type(ocean_grid_type), intent(in) :: G !< Ocean grid structure
2868  type(forcing), intent(inout) :: fluxes !< A structure containing thermodynamic forcing fields
2869  logical, optional, intent(in) :: water !< If present and true, allocate water fluxes
2870  logical, optional, intent(in) :: heat !< If present and true, allocate heat fluxes
2871  logical, optional, intent(in) :: ustar !< If present and true, allocate ustar and related fields
2872  logical, optional, intent(in) :: press !< If present and true, allocate p_surf and related fields
2873  logical, optional, intent(in) :: shelf !< If present and true, allocate fluxes for ice-shelf
2874  logical, optional, intent(in) :: iceberg !< If present and true, allocate fluxes for icebergs
2875  logical, optional, intent(in) :: salt !< If present and true, allocate salt fluxes
2876  logical, optional, intent(in) :: fix_accum_bug !< If present and true, avoid using a bug in
2877  !! accumulation of ustar_gustless
2878 
2879  ! Local variables
2880  integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
2881  logical :: heat_water
2882 
2883  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
2884  isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
2885 
2886  call myalloc(fluxes%ustar,isd,ied,jsd,jed, ustar)
2887  call myalloc(fluxes%ustar_gustless,isd,ied,jsd,jed, ustar)
2888 
2889  call myalloc(fluxes%evap,isd,ied,jsd,jed, water)
2890  call myalloc(fluxes%lprec,isd,ied,jsd,jed, water)
2891  call myalloc(fluxes%fprec,isd,ied,jsd,jed, water)
2892  call myalloc(fluxes%vprec,isd,ied,jsd,jed, water)
2893  call myalloc(fluxes%lrunoff,isd,ied,jsd,jed, water)
2894  call myalloc(fluxes%frunoff,isd,ied,jsd,jed, water)
2895  call myalloc(fluxes%seaice_melt,isd,ied,jsd,jed, water)
2896  call myalloc(fluxes%netMassOut,isd,ied,jsd,jed, water)
2897  call myalloc(fluxes%netMassIn,isd,ied,jsd,jed, water)
2898  call myalloc(fluxes%netSalt,isd,ied,jsd,jed, water)
2899  call myalloc(fluxes%seaice_melt_heat,isd,ied,jsd,jed, heat)
2900  call myalloc(fluxes%sw,isd,ied,jsd,jed, heat)
2901  call myalloc(fluxes%lw,isd,ied,jsd,jed, heat)
2902  call myalloc(fluxes%latent,isd,ied,jsd,jed, heat)
2903  call myalloc(fluxes%sens,isd,ied,jsd,jed, heat)
2904  call myalloc(fluxes%latent_evap_diag,isd,ied,jsd,jed, heat)
2905  call myalloc(fluxes%latent_fprec_diag,isd,ied,jsd,jed, heat)
2906  call myalloc(fluxes%latent_frunoff_diag,isd,ied,jsd,jed, heat)
2907 
2908  call myalloc(fluxes%salt_flux,isd,ied,jsd,jed, salt)
2909 
2910  if (present(heat) .and. present(water)) then ; if (heat .and. water) then
2911  call myalloc(fluxes%heat_content_cond,isd,ied,jsd,jed, .true.)
2912  call myalloc(fluxes%heat_content_icemelt,isd,ied,jsd,jed, .true.)
2913  call myalloc(fluxes%heat_content_lprec,isd,ied,jsd,jed, .true.)
2914  call myalloc(fluxes%heat_content_fprec,isd,ied,jsd,jed, .true.)
2915  call myalloc(fluxes%heat_content_vprec,isd,ied,jsd,jed, .true.)
2916  call myalloc(fluxes%heat_content_lrunoff,isd,ied,jsd,jed, .true.)
2917  call myalloc(fluxes%heat_content_frunoff,isd,ied,jsd,jed, .true.)
2918  call myalloc(fluxes%heat_content_massout,isd,ied,jsd,jed, .true.)
2919  call myalloc(fluxes%heat_content_massin,isd,ied,jsd,jed, .true.)
2920  endif ; endif
2921 
2922  call myalloc(fluxes%p_surf,isd,ied,jsd,jed, press)
2923 
2924  call myalloc(fluxes%frac_shelf_h,isd,ied,jsd,jed, shelf)
2925  call myalloc(fluxes%ustar_shelf,isd,ied,jsd,jed, shelf)
2926  call myalloc(fluxes%iceshelf_melt,isd,ied,jsd,jed, shelf)
2927 
2928  !These fields should only on allocated when iceberg area is being passed through the coupler.
2929  call myalloc(fluxes%ustar_berg,isd,ied,jsd,jed, iceberg)
2930  call myalloc(fluxes%area_berg,isd,ied,jsd,jed, iceberg)
2931  call myalloc(fluxes%mass_berg,isd,ied,jsd,jed, iceberg)
2932 
2933  if (present(fix_accum_bug)) fluxes%gustless_accum_bug = .not.fix_accum_bug

◆ allocate_forcing_by_ref()

subroutine mom_forcing_type::allocate_forcing_by_ref ( type(forcing), intent(in)  fluxes_ref,
type(ocean_grid_type), intent(in)  G,
type(forcing), intent(out)  fluxes 
)
private
Parameters
[in]fluxes_refReference fluxes
[in]gGrid metric of target fluxes
[out]fluxesTarget fluxes

Definition at line 2937 of file MOM_forcing_type.F90.

2938  type(forcing), intent(in) :: fluxes_ref !< Reference fluxes
2939  type(ocean_grid_type), intent(in) :: G !< Grid metric of target fluxes
2940  type(forcing), intent(out) :: fluxes !< Target fluxes
2941 
2942  logical :: do_ustar, do_water, do_heat, do_salt, do_press, do_shelf, &
2943  do_iceberg, do_heat_added, do_buoy
2944 
2945  call get_forcing_groups(fluxes_ref, do_water, do_heat, do_ustar, do_press, &
2946  do_shelf, do_iceberg, do_salt, do_heat_added, do_buoy)
2947 
2948  call allocate_forcing_type(g, fluxes, do_water, do_heat, do_ustar, &
2949  do_press, do_shelf, do_iceberg, do_salt)
2950 
2951  ! The following fluxes would typically be allocated by the driver
2952  call myalloc(fluxes%sw_vis_dir, g%isd, g%ied, g%jsd, g%jed, &
2953  associated(fluxes_ref%sw_vis_dir))
2954  call myalloc(fluxes%sw_vis_dif, g%isd, g%ied, g%jsd, g%jed, &
2955  associated(fluxes_ref%sw_vis_dif))
2956  call myalloc(fluxes%sw_nir_dir, g%isd, g%ied, g%jsd, g%jed, &
2957  associated(fluxes_ref%sw_nir_dir))
2958  call myalloc(fluxes%sw_nir_dif, g%isd, g%ied, g%jsd, g%jed, &
2959  associated(fluxes_ref%sw_nir_dif))
2960 
2961  call myalloc(fluxes%salt_flux_in, g%isd, g%ied, g%jsd, g%jed, &
2962  associated(fluxes_ref%salt_flux_in))
2963  call myalloc(fluxes%salt_flux_added, g%isd, g%ied, g%jsd, g%jed, &
2964  associated(fluxes_ref%salt_flux_added))
2965 
2966  call myalloc(fluxes%p_surf_full, g%isd, g%ied, g%jsd, g%jed, &
2967  associated(fluxes_ref%p_surf_full))
2968 
2969  call myalloc(fluxes%heat_added, g%isd, g%ied, g%jsd, g%jed, &
2970  associated(fluxes_ref%heat_added))
2971  call myalloc(fluxes%buoy, g%isd, g%ied, g%jsd, g%jed, &
2972  associated(fluxes_ref%buoy))
2973 
2974  call myalloc(fluxes%TKE_tidal, g%isd, g%ied, g%jsd, g%jed, &
2975  associated(fluxes_ref%TKE_tidal))
2976  call myalloc(fluxes%ustar_tidal, g%isd, g%ied, g%jsd, g%jed, &
2977  associated(fluxes_ref%ustar_tidal))
2978 
2979  ! This flag would normally be set by a control flag in allocate_forcing_type.
2980  ! Here we copy the flag from the reference forcing.
2981  fluxes%gustless_accum_bug = fluxes_ref%gustless_accum_bug

◆ allocate_mech_forcing_by_group()

subroutine mom_forcing_type::allocate_mech_forcing_by_group ( type(ocean_grid_type), intent(in)  G,
type(mech_forcing), intent(inout)  forces,
logical, intent(in), optional  stress,
logical, intent(in), optional  ustar,
logical, intent(in), optional  shelf,
logical, intent(in), optional  press,
logical, intent(in), optional  iceberg 
)
private

Conditionally allocate fields within the mechanical forcing type using control flags.

Parameters
[in]gOcean grid structure
[in,out]forcesForcing fields structure
[in]stressIf present and true, allocate taux, tauy
[in]ustarIf present and true, allocate ustar and related fields
[in]shelfIf present and true, allocate forces for ice-shelf
[in]pressIf present and true, allocate p_surf and related fields
[in]icebergIf present and true, allocate forces for icebergs

Definition at line 2987 of file MOM_forcing_type.F90.

2989  type(ocean_grid_type), intent(in) :: G !< Ocean grid structure
2990  type(mech_forcing), intent(inout) :: forces !< Forcing fields structure
2991 
2992  logical, optional, intent(in) :: stress !< If present and true, allocate taux, tauy
2993  logical, optional, intent(in) :: ustar !< If present and true, allocate ustar and related fields
2994  logical, optional, intent(in) :: shelf !< If present and true, allocate forces for ice-shelf
2995  logical, optional, intent(in) :: press !< If present and true, allocate p_surf and related fields
2996  logical, optional, intent(in) :: iceberg !< If present and true, allocate forces for icebergs
2997 
2998  ! Local variables
2999  integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
3000  logical :: heat_water
3001 
3002  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
3003  isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
3004 
3005  call myalloc(forces%taux,isdb,iedb,jsd,jed, stress)
3006  call myalloc(forces%tauy,isd,ied,jsdb,jedb, stress)
3007 
3008  call myalloc(forces%ustar,isd,ied,jsd,jed, ustar)
3009 
3010  call myalloc(forces%p_surf,isd,ied,jsd,jed, press)
3011  call myalloc(forces%p_surf_full,isd,ied,jsd,jed, press)
3012  call myalloc(forces%net_mass_src,isd,ied,jsd,jed, press)
3013 
3014  call myalloc(forces%rigidity_ice_u,isdb,iedb,jsd,jed, shelf)
3015  call myalloc(forces%rigidity_ice_v,isd,ied,jsdb,jedb, shelf)
3016  call myalloc(forces%frac_shelf_u,isdb,iedb,jsd,jed, shelf)
3017  call myalloc(forces%frac_shelf_v,isd,ied,jsdb,jedb, shelf)
3018 
3019  !These fields should only on allocated when iceberg area is being passed through the coupler.
3020  call myalloc(forces%area_berg,isd,ied,jsd,jed, iceberg)
3021  call myalloc(forces%mass_berg,isd,ied,jsd,jed, iceberg)

◆ allocate_mech_forcing_from_ref()

subroutine mom_forcing_type::allocate_mech_forcing_from_ref ( type(mech_forcing), intent(in)  forces_ref,
type(ocean_grid_type), intent(in)  G,
type(mech_forcing), intent(out)  forces 
)
private

Conditionally allocate fields within the mechanical forcing type based on a reference forcing.

Parameters
[in]forces_refReference forcing fields
[in]gGrid metric of target forcing
[out]forcesMechanical forcing fields

Definition at line 3027 of file MOM_forcing_type.F90.

3028  type(mech_forcing), intent(in) :: forces_ref !< Reference forcing fields
3029  type(ocean_grid_type), intent(in) :: G !< Grid metric of target forcing
3030  type(mech_forcing), intent(out) :: forces !< Mechanical forcing fields
3031 
3032  logical :: do_stress, do_ustar, do_shelf, do_press, do_iceberg
3033 
3034  ! Identify the active fields in the reference forcing
3035  call get_mech_forcing_groups(forces_ref, do_stress, do_ustar, do_shelf, &
3036  do_press, do_iceberg)
3037 
3038  call allocate_mech_forcing(g, forces, do_stress, do_ustar, do_shelf, &
3039  do_press, do_iceberg)

◆ calculatebuoyancyflux1d()

subroutine, public mom_forcing_type::calculatebuoyancyflux1d ( type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
type(unit_scale_type), intent(in)  US,
type(forcing), intent(inout)  fluxes,
type(optics_type), pointer  optics,
integer, intent(in)  nsw,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke), intent(in)  h,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke), intent(in)  Temp,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke), intent(in)  Salt,
type(thermo_var_ptrs), intent(inout)  tv,
integer, intent(in)  j,
real, dimension( g %isd: g %ied, g %ke+1), intent(inout)  buoyancyFlux,
real, dimension( g %isd: g %ied), intent(inout)  netHeatMinusSW,
real, dimension( g %isd: g %ied), intent(inout)  netSalt,
logical, intent(in), optional  skip_diags 
)

This routine calculates surface buoyancy flux by adding up the heat, FW & salt fluxes. These are actual fluxes, with units of stuff per time. Setting dt=1 in the call to extractFluxes routine allows us to get "stuf per time" rather than the time integrated fluxes needed in other routines that call extractFluxes.

Parameters
[in]gocean grid
[in]gvocean vertical grid structure
[in]usA dimensional unit scaling type
[in,out]fluxessurface fluxes
opticspenetrating SW optics
[in]nswThe number of frequency bands of penetrating shortwave radiation
[in]hlayer thickness [H ~> m or kg m-2]
[in]tempprognostic temp [degC]
[in]saltsalinity [ppt]
[in,out]tvthermodynamics type
[in]jj-row to work on
[in,out]buoyancyfluxbuoyancy fluxes [L2 T-3 ~> m2 s-3]
[in,out]netheatminusswsurf Heat flux [degC H s-1 ~> degC m s-1 or degC kg m-2 s-1]
[in,out]netsaltsurf salt flux [ppt H s-1 ~> ppt m s-1 or ppt kg m-2 s-1]
[in]skip_diagsIf present and true, skip calculating diagnostics inside extractFluxes1d()

Definition at line 887 of file MOM_forcing_type.F90.

889  type(ocean_grid_type), intent(in) :: G !< ocean grid
890  type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure
891  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
892  type(forcing), intent(inout) :: fluxes !< surface fluxes
893  type(optics_type), pointer :: optics !< penetrating SW optics
894  integer, intent(in) :: nsw !< The number of frequency bands of
895  !! penetrating shortwave radiation
896  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< layer thickness [H ~> m or kg m-2]
897  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: Temp !< prognostic temp [degC]
898  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: Salt !< salinity [ppt]
899  type(thermo_var_ptrs), intent(inout) :: tv !< thermodynamics type
900  integer, intent(in) :: j !< j-row to work on
901  real, dimension(SZI_(G),SZK_(G)+1), intent(inout) :: buoyancyFlux !< buoyancy fluxes [L2 T-3 ~> m2 s-3]
902  real, dimension(SZI_(G)), intent(inout) :: netHeatMinusSW !< surf Heat flux
903  !! [degC H s-1 ~> degC m s-1 or degC kg m-2 s-1]
904  real, dimension(SZI_(G)), intent(inout) :: netSalt !< surf salt flux
905  !! [ppt H s-1 ~> ppt m s-1 or ppt kg m-2 s-1]
906  logical, optional, intent(in) :: skip_diags !< If present and true, skip calculating
907  !! diagnostics inside extractFluxes1d()
908  ! local variables
909  integer :: k
910  real, parameter :: dt = 1. ! to return a rate from extractFluxes1d
911  real, dimension(SZI_(G)) :: netH ! net FW flux [H s-1 ~> m s-1 or kg m-2 s-1]
912  real, dimension(SZI_(G)) :: netEvap ! net FW flux leaving ocean via evaporation
913  ! [H s-1 ~> m s-1 or kg m-2 s-1]
914  real, dimension(SZI_(G)) :: netHeat ! net temp flux [degC H s-1 ~> degC m s-2 or degC kg m-2 s-1]
915  real, dimension(max(nsw,1), SZI_(G)) :: penSWbnd ! penetrating SW radiation by band
916  ! [degC H ~> degC m or degC kg m-2]
917  real, dimension(SZI_(G)) :: pressure ! pressure at the surface [R L2 T-2 ~> Pa]
918  real, dimension(SZI_(G)) :: dRhodT ! density partial derivative wrt temp [R degC-1 ~> kg m-3 degC-1]
919  real, dimension(SZI_(G)) :: dRhodS ! density partial derivative wrt saln [R ppt-1 ~> kg m-3 ppt-1]
920  real, dimension(SZI_(G),SZK_(G)+1) :: netPen ! The net penetrating shortwave radiation at each level
921  ! [degC H ~> degC m or degC kg m-2]
922 
923  logical :: useRiverHeatContent
924  logical :: useCalvingHeatContent
925  real :: depthBeforeScalingFluxes ! A depth scale [H ~> m or kg m-2]
926  real :: GoRho ! The gravitational acceleration divided by mean density times some
927  ! unit conversion factors [L2 H-1 s R-1 T-3 ~> m4 kg-1 s-2 or m7 kg-2 s-2]
928  real :: H_limit_fluxes ! Another depth scale [H ~> m or kg m-2]
929  integer :: i
930 
931  ! smg: what do we do when have heat fluxes from calving and river?
932  useriverheatcontent = .false.
933  usecalvingheatcontent = .false.
934 
935  depthbeforescalingfluxes = max( gv%Angstrom_H, 1.e-30*gv%m_to_H )
936  pressure(:) = 0.
937  if (associated(tv%p_surf)) then ; do i=g%isc,g%iec ; pressure(i) = tv%p_surf(i,j) ; enddo ; endif
938  gorho = (gv%g_Earth * gv%H_to_Z*us%T_to_s) / gv%Rho0
939 
940  h_limit_fluxes = depthbeforescalingfluxes
941 
942  ! The surface forcing is contained in the fluxes type.
943  ! We aggregate the thermodynamic forcing for a time step into the following:
944  ! netH = water added/removed via surface fluxes [H s-1 ~> m s-1 or kg m-2 s-1]
945  ! netHeat = heat via surface fluxes [degC H s-1 ~> degC m s-1 or degC kg m-2 s-1]
946  ! netSalt = salt via surface fluxes [ppt H s-1 ~> ppt m s-1 or gSalt m-2 s-1]
947  ! Note that unlike other calls to extractFLuxes1d() that return the time-integrated flux
948  ! this call returns the rate because dt=1
949  call extractfluxes1d(g, gv, us, fluxes, optics, nsw, j, dt*us%s_to_T, &
950  depthbeforescalingfluxes, useriverheatcontent, usecalvingheatcontent, &
951  h(:,j,:), temp(:,j,:), neth, netevap, netheatminussw, &
952  netsalt, penswbnd, tv, .false., skip_diags=skip_diags)
953 
954  ! Sum over bands and attenuate as a function of depth
955  ! netPen is the netSW as a function of depth
956  call sumswoverbands(g, gv, us, h(:,j,:), optics_nbands(optics), optics, j, dt*us%s_to_T, &
957  h_limit_fluxes, .true., penswbnd, netpen)
958 
959  ! Density derivatives
960  call calculate_density_derivs(temp(:,j,1), salt(:,j,1), pressure, drhodt, drhods, &
961  tv%eqn_of_state, eos_domain(g%HI))
962 
963  ! Adjust netSalt to reflect dilution effect of FW flux
964  netsalt(g%isc:g%iec) = netsalt(g%isc:g%iec) - salt(g%isc:g%iec,j,1) * neth(g%isc:g%iec) ! ppt H/s
965 
966  ! Add in the SW heating for purposes of calculating the net
967  ! surface buoyancy flux affecting the top layer.
968  !netHeat(:) = netHeatMinusSW(:) + sum( penSWbnd, dim=1 )
969  netheat(g%isc:g%iec) = netheatminussw(g%isc:g%iec) + netpen(g%isc:g%iec,1) ! K H/s
970 
971  ! Convert to a buoyancy flux, excluding penetrating SW heating
972  buoyancyflux(g%isc:g%iec,1) = - gorho * ( drhods(g%isc:g%iec) * netsalt(g%isc:g%iec) + &
973  drhodt(g%isc:g%iec) * netheat(g%isc:g%iec) ) ! [L2 T-3 ~> m2 s-3]
974  ! We also have a penetrative buoyancy flux associated with penetrative SW
975  do k=2, g%ke+1
976  buoyancyflux(g%isc:g%iec,k) = - gorho * ( drhodt(g%isc:g%iec) * netpen(g%isc:g%iec,k) ) ! [L2 T-3 ~> m2 s-3]
977  enddo
978 

◆ calculatebuoyancyflux2d()

subroutine, public mom_forcing_type::calculatebuoyancyflux2d ( type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
type(unit_scale_type), intent(in)  US,
type(forcing), intent(inout)  fluxes,
type(optics_type), pointer  optics,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke), intent(in)  h,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke), intent(in)  Temp,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke), intent(in)  Salt,
type(thermo_var_ptrs), intent(inout)  tv,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke+1), intent(inout)  buoyancyFlux,
real, dimension( g %isd: g %ied, g %jsd: g %jed), intent(inout), optional  netHeatMinusSW,
real, dimension( g %isd: g %ied, g %jsd: g %jed), intent(inout), optional  netSalt,
logical, intent(in), optional  skip_diags 
)

Calculates surface buoyancy flux by adding up the heat, FW and salt fluxes, for 2d arrays. This is a wrapper for calculateBuoyancyFlux1d.

Parameters
[in]gocean grid
[in]gvocean vertical grid structure
[in]usA dimensional unit scaling type
[in,out]fluxessurface fluxes
opticsSW ocean optics
[in]hlayer thickness [H ~> m or kg m-2]
[in]temptemperature [degC]
[in]saltsalinity [ppt]
[in,out]tvthermodynamics type
[in,out]buoyancyfluxbuoyancy fluxes [L2 T-3 ~> m2 s-3]
[in,out]netheatminusswsurf temp flux [degC H ~> degC m or degC kg m-2]
[in,out]netsaltsurf salt flux [ppt H ~> ppt m or ppt kg m-2]
[in]skip_diagsIf present and true, skip calculating diagnostics inside extractFluxes1d()

Definition at line 984 of file MOM_forcing_type.F90.

986  type(ocean_grid_type), intent(in) :: G !< ocean grid
987  type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure
988  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
989  type(forcing), intent(inout) :: fluxes !< surface fluxes
990  type(optics_type), pointer :: optics !< SW ocean optics
991  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< layer thickness [H ~> m or kg m-2]
992  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: Temp !< temperature [degC]
993  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: Salt !< salinity [ppt]
994  type(thermo_var_ptrs), intent(inout) :: tv !< thermodynamics type
995  real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: buoyancyFlux !< buoyancy fluxes [L2 T-3 ~> m2 s-3]
996  real, dimension(SZI_(G),SZJ_(G)), optional, intent(inout) :: netHeatMinusSW !< surf temp flux
997  !! [degC H ~> degC m or degC kg m-2]
998  real, dimension(SZI_(G),SZJ_(G)), optional, intent(inout) :: netSalt !< surf salt flux
999  !! [ppt H ~> ppt m or ppt kg m-2]
1000  logical, optional, intent(in) :: skip_diags !< If present and true, skip calculating
1001  !! diagnostics inside extractFluxes1d()
1002  ! local variables
1003  real, dimension( SZI_(G) ) :: netT ! net temperature flux [degC H s-1 ~> degC m s-2 or degC kg m-2 s-1]
1004  real, dimension( SZI_(G) ) :: netS ! net saln flux !! [ppt H s-1 ~> ppt m s-1 or ppt kg m-2 s-1]
1005  integer :: j
1006 
1007  nett(g%isc:g%iec) = 0. ; nets(g%isc:g%iec) = 0.
1008 
1009  !$OMP parallel do default(shared) firstprivate(netT,netS)
1010  do j=g%jsc,g%jec
1011  call calculatebuoyancyflux1d(g, gv, us, fluxes, optics, optics_nbands(optics), h, temp, salt, &
1012  tv, j, buoyancyflux(:,j,:), nett, nets, skip_diags=skip_diags)
1013  if (present(netheatminussw)) netheatminussw(g%isc:g%iec,j) = nett(g%isc:g%iec)
1014  if (present(netsalt)) netsalt(g%isc:g%iec,j) = nets(g%isc:g%iec)
1015  enddo
1016 

◆ copy_back_forcing_fields()

subroutine, public mom_forcing_type::copy_back_forcing_fields ( type(forcing), intent(in)  fluxes,
type(mech_forcing), intent(inout)  forces,
type(ocean_grid_type), intent(in)  G 
)

This subroutine copies the computational domains of common forcing fields from a mech_forcing type to a (thermodynamic) forcing type.

Parameters
[in]fluxesA structure containing thermodynamic forcing fields
[in,out]forcesA structure with the driving mechanical forces
[in]ggrid type

Definition at line 2198 of file MOM_forcing_type.F90.

2199  type(forcing), intent(in) :: fluxes !< A structure containing thermodynamic forcing fields
2200  type(mech_forcing), intent(inout) :: forces !< A structure with the driving mechanical forces
2201  type(ocean_grid_type), intent(in) :: G !< grid type
2202 
2203  integer :: i, j, is, ie, js, je
2204  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
2205 
2206  if (associated(forces%ustar) .and. associated(fluxes%ustar)) then
2207  do j=js,je ; do i=is,ie
2208  forces%ustar(i,j) = fluxes%ustar(i,j)
2209  enddo ; enddo
2210  endif
2211 

◆ copy_common_forcing_fields()

subroutine, public mom_forcing_type::copy_common_forcing_fields ( type(mech_forcing), intent(in)  forces,
type(forcing), intent(inout)  fluxes,
type(ocean_grid_type), intent(in)  G,
logical, intent(in), optional  skip_pres 
)

This subroutine copies the computational domains of common forcing fields from a mech_forcing type to a (thermodynamic) forcing type.

Parameters
[in]forcesA structure with the driving mechanical forces
[in,out]fluxesA structure containing thermodynamic forcing fields
[in]ggrid type
[in]skip_presIf present and true, do not copy pressure fields.

Definition at line 2060 of file MOM_forcing_type.F90.

2061  type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces
2062  type(forcing), intent(inout) :: fluxes !< A structure containing thermodynamic forcing fields
2063  type(ocean_grid_type), intent(in) :: G !< grid type
2064  logical, optional, intent(in) :: skip_pres !< If present and true, do not copy pressure fields.
2065 
2066  logical :: do_pres
2067  integer :: i, j, is, ie, js, je
2068  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
2069 
2070  do_pres = .true. ; if (present(skip_pres)) do_pres = .not.skip_pres
2071 
2072  if (associated(forces%ustar) .and. associated(fluxes%ustar)) then
2073  do j=js,je ; do i=is,ie
2074  fluxes%ustar(i,j) = forces%ustar(i,j)
2075  enddo ; enddo
2076  endif
2077 
2078  if (do_pres) then
2079  if (associated(forces%p_surf) .and. associated(fluxes%p_surf)) then
2080  do j=js,je ; do i=is,ie
2081  fluxes%p_surf(i,j) = forces%p_surf(i,j)
2082  enddo ; enddo
2083  endif
2084 
2085  if (associated(forces%p_surf_full) .and. associated(fluxes%p_surf_full)) then
2086  do j=js,je ; do i=is,ie
2087  fluxes%p_surf_full(i,j) = forces%p_surf_full(i,j)
2088  enddo ; enddo
2089  endif
2090 
2091  if (associated(forces%p_surf_SSH, forces%p_surf_full)) then
2092  fluxes%p_surf_SSH => fluxes%p_surf_full
2093  elseif (associated(forces%p_surf_SSH, forces%p_surf)) then
2094  fluxes%p_surf_SSH => fluxes%p_surf
2095  endif
2096  endif
2097 

◆ deallocate_forcing_type()

subroutine, public mom_forcing_type::deallocate_forcing_type ( type(forcing), intent(inout)  fluxes)

Deallocate the forcing type.

Parameters
[in,out]fluxesForcing fields structure

Definition at line 3114 of file MOM_forcing_type.F90.

3115  type(forcing), intent(inout) :: fluxes !< Forcing fields structure
3116 
3117  if (associated(fluxes%ustar)) deallocate(fluxes%ustar)
3118  if (associated(fluxes%ustar_gustless)) deallocate(fluxes%ustar_gustless)
3119  if (associated(fluxes%buoy)) deallocate(fluxes%buoy)
3120  if (associated(fluxes%sw)) deallocate(fluxes%sw)
3121  if (associated(fluxes%seaice_melt_heat)) deallocate(fluxes%seaice_melt_heat)
3122  if (associated(fluxes%sw_vis_dir)) deallocate(fluxes%sw_vis_dir)
3123  if (associated(fluxes%sw_vis_dif)) deallocate(fluxes%sw_vis_dif)
3124  if (associated(fluxes%sw_nir_dir)) deallocate(fluxes%sw_nir_dir)
3125  if (associated(fluxes%sw_nir_dif)) deallocate(fluxes%sw_nir_dif)
3126  if (associated(fluxes%lw)) deallocate(fluxes%lw)
3127  if (associated(fluxes%latent)) deallocate(fluxes%latent)
3128  if (associated(fluxes%latent_evap_diag)) deallocate(fluxes%latent_evap_diag)
3129  if (associated(fluxes%latent_fprec_diag)) deallocate(fluxes%latent_fprec_diag)
3130  if (associated(fluxes%latent_frunoff_diag)) deallocate(fluxes%latent_frunoff_diag)
3131  if (associated(fluxes%sens)) deallocate(fluxes%sens)
3132  if (associated(fluxes%heat_added)) deallocate(fluxes%heat_added)
3133  if (associated(fluxes%heat_content_lrunoff)) deallocate(fluxes%heat_content_lrunoff)
3134  if (associated(fluxes%heat_content_frunoff)) deallocate(fluxes%heat_content_frunoff)
3135  if (associated(fluxes%heat_content_icemelt)) deallocate(fluxes%heat_content_icemelt)
3136  if (associated(fluxes%heat_content_lprec)) deallocate(fluxes%heat_content_lprec)
3137  if (associated(fluxes%heat_content_fprec)) deallocate(fluxes%heat_content_fprec)
3138  if (associated(fluxes%heat_content_cond)) deallocate(fluxes%heat_content_cond)
3139  if (associated(fluxes%heat_content_massout)) deallocate(fluxes%heat_content_massout)
3140  if (associated(fluxes%heat_content_massin)) deallocate(fluxes%heat_content_massin)
3141  if (associated(fluxes%evap)) deallocate(fluxes%evap)
3142  if (associated(fluxes%lprec)) deallocate(fluxes%lprec)
3143  if (associated(fluxes%fprec)) deallocate(fluxes%fprec)
3144  if (associated(fluxes%vprec)) deallocate(fluxes%vprec)
3145  if (associated(fluxes%lrunoff)) deallocate(fluxes%lrunoff)
3146  if (associated(fluxes%frunoff)) deallocate(fluxes%frunoff)
3147  if (associated(fluxes%seaice_melt)) deallocate(fluxes%seaice_melt)
3148  if (associated(fluxes%salt_flux)) deallocate(fluxes%salt_flux)
3149  if (associated(fluxes%p_surf_full)) deallocate(fluxes%p_surf_full)
3150  if (associated(fluxes%p_surf)) deallocate(fluxes%p_surf)
3151  if (associated(fluxes%TKE_tidal)) deallocate(fluxes%TKE_tidal)
3152  if (associated(fluxes%ustar_tidal)) deallocate(fluxes%ustar_tidal)
3153  if (associated(fluxes%ustar_shelf)) deallocate(fluxes%ustar_shelf)
3154  if (associated(fluxes%iceshelf_melt)) deallocate(fluxes%iceshelf_melt)
3155  if (associated(fluxes%frac_shelf_h)) deallocate(fluxes%frac_shelf_h)
3156  if (associated(fluxes%ustar_berg)) deallocate(fluxes%ustar_berg)
3157  if (associated(fluxes%area_berg)) deallocate(fluxes%area_berg)
3158  if (associated(fluxes%mass_berg)) deallocate(fluxes%mass_berg)
3159 
3160  call coupler_type_destructor(fluxes%tr_fluxes)
3161 

◆ deallocate_mech_forcing()

subroutine, public mom_forcing_type::deallocate_mech_forcing ( type(mech_forcing), intent(inout)  forces)

Deallocate the mechanical forcing type.

Parameters
[in,out]forcesForcing fields structure

Definition at line 3166 of file MOM_forcing_type.F90.

3167  type(mech_forcing), intent(inout) :: forces !< Forcing fields structure
3168 
3169  if (associated(forces%taux)) deallocate(forces%taux)
3170  if (associated(forces%tauy)) deallocate(forces%tauy)
3171  if (associated(forces%ustar)) deallocate(forces%ustar)
3172  if (associated(forces%p_surf)) deallocate(forces%p_surf)
3173  if (associated(forces%p_surf_full)) deallocate(forces%p_surf_full)
3174  if (associated(forces%net_mass_src)) deallocate(forces%net_mass_src)
3175  if (associated(forces%rigidity_ice_u)) deallocate(forces%rigidity_ice_u)
3176  if (associated(forces%rigidity_ice_v)) deallocate(forces%rigidity_ice_v)
3177  if (associated(forces%frac_shelf_u)) deallocate(forces%frac_shelf_u)
3178  if (associated(forces%frac_shelf_v)) deallocate(forces%frac_shelf_v)
3179  if (associated(forces%area_berg)) deallocate(forces%area_berg)
3180  if (associated(forces%mass_berg)) deallocate(forces%mass_berg)
3181 

◆ extractfluxes1d()

subroutine, public mom_forcing_type::extractfluxes1d ( type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
type(unit_scale_type), intent(in)  US,
type(forcing), intent(inout)  fluxes,
type(optics_type), pointer  optics,
integer, intent(in)  nsw,
integer, intent(in)  j,
real, intent(in)  dt,
real, intent(in)  FluxRescaleDepth,
logical, intent(in)  useRiverHeatContent,
logical, intent(in)  useCalvingHeatContent,
real, dimension( g %isd: g %ied, g %ke), intent(in)  h,
real, dimension( g %isd: g %ied, g %ke), intent(in)  T,
real, dimension( g %isd: g %ied), intent(out)  netMassInOut,
real, dimension( g %isd: g %ied), intent(out)  netMassOut,
real, dimension( g %isd: g %ied), intent(out)  net_heat,
real, dimension( g %isd: g %ied), intent(out)  net_salt,
real, dimension(max(1,nsw),g%isd:g%ied), intent(out)  pen_SW_bnd,
type(thermo_var_ptrs), intent(inout)  tv,
logical, intent(in)  aggregate_FW,
real, dimension( g %isd: g %ied), intent(out), optional  nonpenSW,
real, dimension( g %isd: g %ied), intent(out), optional  netmassInOut_rate,
real, dimension( g %isd: g %ied), intent(out), optional  net_Heat_Rate,
real, dimension( g %isd: g %ied), intent(out), optional  net_salt_rate,
real, dimension(max(1,nsw),g%isd:g%ied), intent(out), optional  pen_sw_bnd_Rate,
logical, intent(in), optional  skip_diags 
)

This subroutine extracts fluxes from the surface fluxes type. It works on a j-row for optimization purposes. The 2d (i,j) wrapper is the next subroutine below. This routine multiplies fluxes by dt, so that the result is an accumulation of fluxes over a time step.

Parameters
[in]gocean grid structure
[in]gvocean vertical grid structure
[in]usA dimensional unit scaling type
[in,out]fluxesstructure containing pointers to possible forcing fields. NULL unused fields.
opticspointer to optics
[in]nswnumber of bands of penetrating SW
[in]jj-index to work on
[in]dtThe time step for these fluxes [T ~> s]
[in]fluxrescaledepthmin ocean depth before fluxes are scaled away [H ~> m or kg m-2]
[in]useriverheatcontentlogical for river heat content
[in]usecalvingheatcontentlogical for calving heat content
[in]hlayer thickness [H ~> m or kg m-2]
[in]tlayer temperatures [degC]
[out]netmassinoutnet mass flux (non-Bouss) or volume flux (if Bouss) of water in/out of ocean over a time step [H ~> m or kg m-2]
[out]netmassoutnet mass flux (non-Bouss) or volume flux (if Bouss) of water leaving ocean surface over a time step [H ~> m or kg m-2]. netMassOut < 0 means mass leaves ocean.
[out]net_heatnet heat at the surface accumulated over a time step for coupler + restoring. Exclude two terms from net_heat: (1) downwelling (penetrative) SW, (2) evaporation heat content, (since do not yet know evap temperature). [degC H ~> degC m or degC kg m-2].
[out]net_saltsurface salt flux into the ocean accumulated over a time step [ppt H ~> ppt m or ppt kg m-2].
[out]pen_sw_bndpenetrating SW flux, split into bands. [degC H ~> degC m or degC kg m-2] and array size nsw x G isd: G ied, where nsw=number of SW bands in pen_SW_bnd. This heat flux is not part of net_heat.
[in,out]tvstructure containing pointers to available thermodynamic fields. Used to keep track of the heat flux associated with net mass fluxes into the ocean.
[in]aggregate_fwFor determining how to aggregate forcing.
[out]nonpenswNon-penetrating SW used in net_heat
[out]net_heat_rateRate of net surface heating
[out]net_salt_rateSurface salt flux into the ocean
[out]netmassinout_rateRate of net mass flux into the ocean
[out]pen_sw_bnd_rateRate of penetrative shortwave heating
[in]skip_diagsIf present and true, skip calculating diagnostics

Definition at line 360 of file MOM_forcing_type.F90.

365 
366  type(ocean_grid_type), intent(in) :: G !< ocean grid structure
367  type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure
368  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
369  type(forcing), intent(inout) :: fluxes !< structure containing pointers to possible
370  !! forcing fields. NULL unused fields.
371  type(optics_type), pointer :: optics !< pointer to optics
372  integer, intent(in) :: nsw !< number of bands of penetrating SW
373  integer, intent(in) :: j !< j-index to work on
374  real, intent(in) :: dt !< The time step for these fluxes [T ~> s]
375  real, intent(in) :: FluxRescaleDepth !< min ocean depth before fluxes
376  !! are scaled away [H ~> m or kg m-2]
377  logical, intent(in) :: useRiverHeatContent !< logical for river heat content
378  logical, intent(in) :: useCalvingHeatContent !< logical for calving heat content
379  real, dimension(SZI_(G),SZK_(G)), &
380  intent(in) :: h !< layer thickness [H ~> m or kg m-2]
381  real, dimension(SZI_(G),SZK_(G)), &
382  intent(in) :: T !< layer temperatures [degC]
383  real, dimension(SZI_(G)), intent(out) :: netMassInOut !< net mass flux (non-Bouss) or volume flux
384  !! (if Bouss) of water in/out of ocean over
385  !! a time step [H ~> m or kg m-2]
386  real, dimension(SZI_(G)), intent(out) :: netMassOut !< net mass flux (non-Bouss) or volume flux
387  !! (if Bouss) of water leaving ocean surface
388  !! over a time step [H ~> m or kg m-2].
389  !! netMassOut < 0 means mass leaves ocean.
390  real, dimension(SZI_(G)), intent(out) :: net_heat !< net heat at the surface accumulated over a
391  !! time step for coupler + restoring.
392  !! Exclude two terms from net_heat:
393  !! (1) downwelling (penetrative) SW,
394  !! (2) evaporation heat content,
395  !! (since do not yet know evap temperature).
396  !! [degC H ~> degC m or degC kg m-2].
397  real, dimension(SZI_(G)), intent(out) :: net_salt !< surface salt flux into the ocean
398  !! accumulated over a time step
399  !! [ppt H ~> ppt m or ppt kg m-2].
400  real, dimension(max(1,nsw),G%isd:G%ied), intent(out) :: pen_SW_bnd !< penetrating SW flux, split into bands.
401  !! [degC H ~> degC m or degC kg m-2]
402  !! and array size nsw x SZI_(G), where
403  !! nsw=number of SW bands in pen_SW_bnd.
404  !! This heat flux is not part of net_heat.
405  type(thermo_var_ptrs), intent(inout) :: tv !< structure containing pointers to available
406  !! thermodynamic fields. Used to keep
407  !! track of the heat flux associated with net
408  !! mass fluxes into the ocean.
409  logical, intent(in) :: aggregate_FW !< For determining how to aggregate forcing.
410  real, dimension(SZI_(G)), &
411  optional, intent(out) :: nonpenSW !< Non-penetrating SW used in net_heat
412  !! [degC H ~> degC m or degC kg m-2].
413  !! Summed over SW bands when diagnosing nonpenSW.
414  real, dimension(SZI_(G)), &
415  optional, intent(out) :: net_Heat_rate !< Rate of net surface heating
416  !! [degC H T-1 ~> degC m s-1 or degC kg m-2 s-1].
417  real, dimension(SZI_(G)), &
418  optional, intent(out) :: net_salt_rate !< Surface salt flux into the ocean
419  !! [ppt H T-1 ~> ppt m s-1 or ppt kg m-2 s-1].
420  real, dimension(SZI_(G)), &
421  optional, intent(out) :: netmassInOut_rate !< Rate of net mass flux into the ocean
422  !! [H T-1 ~> m s-1 or kg m-2 s-1].
423  real, dimension(max(1,nsw),G%isd:G%ied), &
424  optional, intent(out) :: pen_sw_bnd_rate !< Rate of penetrative shortwave heating
425  !! [degC H T-1 ~> degC m s-1 or degC kg m-2 s-1].
426  logical, optional, intent(in) :: skip_diags !< If present and true, skip calculating diagnostics
427 
428  ! local
429  real :: htot(SZI_(G)) ! total ocean depth [H ~> m or kg m-2]
430  real :: Pen_sw_tot(SZI_(G)) ! sum across all bands of Pen_SW [degC H ~> degC m or degC kg m-2].
431  real :: pen_sw_tot_rate(SZI_(G)) ! Summed rate of shortwave heating across bands
432  ! [degC H T-1 ~> degC m s-1 or degC kg m-2 s-1]
433  real :: Ih_limit ! inverse depth at which surface fluxes start to be limited
434  ! or 0 for no limiting [H-1 ~> m-1 or m2 kg-1]
435  real :: scale ! scale scales away fluxes if depth < FluxRescaleDepth
436  real :: I_Cp ! 1.0 / C_p [degC Q-1 ~> kg degC J-1]
437  real :: I_Cp_Hconvert ! Unit conversion factors divided by the heat capacity
438  ! [degC H R-1 Z-1 Q-1 ~> degC m3 J-1 or kg degC J-1]
439  logical :: calculate_diags ! Indicate to calculate/update diagnostic arrays
440  character(len=200) :: mesg
441  integer :: is, ie, nz, i, k, n
442 
443  logical :: do_NHR, do_NSR, do_NMIOR, do_PSWBR
444 
445  !BGR-Jul 5,2017{
446  ! Initializes/sets logicals if 'rates' are requested
447  ! These factors are required for legacy reasons
448  ! and therefore computed only when optional outputs are requested
449  do_nhr = .false.
450  do_nsr = .false.
451  do_nmior = .false.
452  do_pswbr = .false.
453  if (present(net_heat_rate)) do_nhr = .true.
454  if (present(net_salt_rate)) do_nsr = .true.
455  if (present(netmassinout_rate)) do_nmior = .true.
456  if (present(pen_sw_bnd_rate)) do_pswbr = .true.
457  !}BGR
458 
459  ih_limit = 0.0 ; if (fluxrescaledepth > 0.0) ih_limit = 1.0 / fluxrescaledepth
460  i_cp = 1.0 / fluxes%C_p
461  i_cp_hconvert = 1.0 / (gv%H_to_RZ * fluxes%C_p)
462 
463  is = g%isc ; ie = g%iec ; nz = g%ke
464 
465  calculate_diags = .true.
466  if (present(skip_diags)) calculate_diags = .not. skip_diags
467 
468  ! error checking
469 
470  if (nsw > 0) then ; if (nsw /= optics_nbands(optics)) call mom_error(warning, &
471  "mismatch in the number of bands of shortwave radiation in MOM_forcing_type extract_fluxes.")
472  endif
473 
474  if (.not.associated(fluxes%sw)) call mom_error(fatal, &
475  "MOM_forcing_type extractFluxes1d: fluxes%sw is not associated.")
476 
477  if (.not.associated(fluxes%lw)) call mom_error(fatal, &
478  "MOM_forcing_type extractFluxes1d: fluxes%lw is not associated.")
479 
480  if (.not.associated(fluxes%latent)) call mom_error(fatal, &
481  "MOM_forcing_type extractFluxes1d: fluxes%latent is not associated.")
482 
483  if (.not.associated(fluxes%sens)) call mom_error(fatal, &
484  "MOM_forcing_type extractFluxes1d: fluxes%sens is not associated.")
485 
486  if (.not.associated(fluxes%evap)) call mom_error(fatal, &
487  "MOM_forcing_type extractFluxes1d: No evaporation defined.")
488 
489  if (.not.associated(fluxes%vprec)) call mom_error(fatal, &
490  "MOM_forcing_type extractFluxes1d: fluxes%vprec not defined.")
491 
492  if ((.not.associated(fluxes%lprec)) .or. &
493  (.not.associated(fluxes%fprec))) call mom_error(fatal, &
494  "MOM_forcing_type extractFluxes1d: No precipitation defined.")
495 
496  do i=is,ie ; htot(i) = h(i,1) ; enddo
497  do k=2,nz ; do i=is,ie ; htot(i) = htot(i) + h(i,k) ; enddo ; enddo
498 
499  if (nsw >= 1) then
500  call extract_optics_slice(optics, j, g, gv, pensw_top=pen_sw_bnd)
501  if (do_pswbr) call extract_optics_slice(optics, j, g, gv, pensw_top=pen_sw_bnd_rate)
502  endif
503 
504  do i=is,ie
505 
506  scale = 1.0 ; if ((ih_limit > 0.0) .and. (htot(i)*ih_limit < 1.0)) scale = htot(i)*ih_limit
507 
508  ! Convert the penetrating shortwave forcing to (K * H) and reduce fluxes for shallow depths.
509  ! (H=m for Bouss, H=kg/m2 for non-Bouss)
510  pen_sw_tot(i) = 0.0
511  if (nsw >= 1) then
512  do n=1,nsw
513  pen_sw_bnd(n,i) = i_cp_hconvert*scale*dt * max(0.0, pen_sw_bnd(n,i))
514  pen_sw_tot(i) = pen_sw_tot(i) + pen_sw_bnd(n,i)
515  enddo
516  else
517  pen_sw_bnd(1,i) = 0.0
518  endif
519 
520  if (do_pswbr) then ! Repeat the above code w/ dt=1s for legacy reasons
521  pen_sw_tot_rate(i) = 0.0
522  if (nsw >= 1) then
523  do n=1,nsw
524  pen_sw_bnd_rate(n,i) = i_cp_hconvert*scale * max(0.0, pen_sw_bnd_rate(n,i))
525  pen_sw_tot_rate(i) = pen_sw_tot_rate(i) + pen_sw_bnd_rate(n,i)
526  enddo
527  else
528  pen_sw_bnd_rate(1,i) = 0.0
529  endif
530  endif
531 
532  ! net volume/mass of liquid and solid passing through surface boundary fluxes
533  netmassinout(i) = dt * (scale * &
534  (((((( fluxes%lprec(i,j) &
535  + fluxes%fprec(i,j) ) &
536  + fluxes%evap(i,j) ) &
537  + fluxes%lrunoff(i,j) ) &
538  + fluxes%vprec(i,j) ) &
539  + fluxes%seaice_melt(i,j)) &
540  + fluxes%frunoff(i,j) ))
541 
542  if (do_nmior) then ! Repeat the above code without multiplying by a timestep for legacy reasons
543  netmassinout_rate(i) = (scale * &
544  (((((( fluxes%lprec(i,j) &
545  + fluxes%fprec(i,j) ) &
546  + fluxes%evap(i,j) ) &
547  + fluxes%lrunoff(i,j) ) &
548  + fluxes%vprec(i,j) ) &
549  + fluxes%seaice_melt(i,j)) &
550  + fluxes%frunoff(i,j) ))
551  endif
552 
553  ! smg:
554  ! for non-Bouss, we add/remove salt mass to total ocean mass. to conserve
555  ! total salt mass ocean+ice, the sea ice model must lose mass when salt mass
556  ! is added to the ocean, which may still need to be coded. Not that the units
557  ! of netMassInOut are still kg_m2, so no conversion to H should occur yet.
558  if (.not.gv%Boussinesq .and. associated(fluxes%salt_flux)) then
559  netmassinout(i) = netmassinout(i) + dt * (scale * fluxes%salt_flux(i,j))
560  if (do_nmior) netmassinout_rate(i) = netmassinout_rate(i) + &
561  (scale * fluxes%salt_flux(i,j))
562  endif
563 
564  ! net volume/mass of water leaving the ocean.
565  ! check that fluxes are < 0, which means mass is indeed leaving.
566  netmassout(i) = 0.0
567 
568  ! evap > 0 means condensating water is added into ocean.
569  ! evap < 0 means evaporation of water from the ocean, in
570  ! which case heat_content_evap is computed in MOM_diabatic_driver.F90
571  if (fluxes%evap(i,j) < 0.0) netmassout(i) = netmassout(i) + fluxes%evap(i,j)
572  ! if (associated(fluxes%heat_content_cond)) fluxes%heat_content_cond(i,j) = 0.0 !??? --AJA
573 
574  ! lprec < 0 means sea ice formation taking water from the ocean.
575  ! smg: we should split the ice melt/formation from the lprec
576  if (fluxes%lprec(i,j) < 0.0) netmassout(i) = netmassout(i) + fluxes%lprec(i,j)
577 
578  ! seaice_melt < 0 means sea ice formation taking water from the ocean.
579  if (fluxes%seaice_melt(i,j) < 0.0) netmassout(i) = netmassout(i) + fluxes%seaice_melt(i,j)
580 
581  ! vprec < 0 means virtual evaporation arising from surface salinity restoring,
582  ! in which case heat_content_vprec is computed in MOM_diabatic_driver.F90.
583  if (fluxes%vprec(i,j) < 0.0) netmassout(i) = netmassout(i) + fluxes%vprec(i,j)
584 
585  netmassout(i) = dt * scale * netmassout(i)
586 
587  ! convert to H units (Bouss=meter or non-Bouss=kg/m^2)
588  netmassinout(i) = gv%RZ_to_H * netmassinout(i)
589  if (do_nmior) netmassinout_rate(i) = gv%RZ_to_H * netmassinout_rate(i)
590  netmassout(i) = gv%RZ_to_H * netmassout(i)
591 
592  ! surface heat fluxes from radiation and turbulent fluxes (K * H)
593  ! (H=m for Bouss, H=kg/m2 for non-Bouss)
594 
595  ! CIME provides heat flux from snow&ice melt (seaice_melt_heat), so this is added below
596  if (associated(fluxes%seaice_melt_heat)) then
597  net_heat(i) = scale * dt * i_cp_hconvert * &
598  ( fluxes%sw(i,j) + (((fluxes%lw(i,j) + fluxes%latent(i,j)) + fluxes%sens(i,j)) + &
599  fluxes%seaice_melt_heat(i,j)) )
600  !Repeats above code w/ dt=1. for legacy reason
601  if (do_nhr) net_heat_rate(i) = scale * i_cp_hconvert * &
602  ( fluxes%sw(i,j) + (((fluxes%lw(i,j) + fluxes%latent(i,j)) + fluxes%sens(i,j)) + &
603  fluxes%seaice_melt_heat(i,j)))
604  else
605  net_heat(i) = scale * dt * i_cp_hconvert * &
606  ( fluxes%sw(i,j) + ((fluxes%lw(i,j) + fluxes%latent(i,j)) + fluxes%sens(i,j)) )
607  !Repeats above code w/ dt=1. for legacy reason
608  if (do_nhr) net_heat_rate(i) = scale * i_cp_hconvert * &
609  ( fluxes%sw(i,j) + ((fluxes%lw(i,j) + fluxes%latent(i,j)) + fluxes%sens(i,j)) )
610  endif
611 
612  ! Add heat flux from surface damping (restoring) (K * H) or flux adjustments.
613  if (associated(fluxes%heat_added)) then
614  net_heat(i) = net_heat(i) + (scale * (dt * i_cp_hconvert)) * fluxes%heat_added(i,j)
615  if (do_nhr) net_heat_rate(i) = net_heat_rate(i) + (scale * i_cp_hconvert) * fluxes%heat_added(i,j)
616  endif
617 
618  ! Add explicit heat flux for runoff (which is part of the ice-ocean boundary
619  ! flux type). Runoff is otherwise added with a temperature of SST.
620  if (useriverheatcontent) then
621  ! remove lrunoff*SST here, to counteract its addition elsewhere
622  net_heat(i) = (net_heat(i) + (scale*(dt * i_cp_hconvert)) * fluxes%heat_content_lrunoff(i,j)) - &
623  (gv%RZ_to_H * (scale * dt)) * fluxes%lrunoff(i,j) * t(i,1)
624  !BGR-Jul 5, 2017{
625  !Intentionally neglect the following contribution to rate for legacy reasons.
626  !if (do_NHR) net_heat_rate(i) = (net_heat_rate(i) + (scale*I_Cp_Hconvert) * fluxes%heat_content_lrunoff(i,j)) - &
627  ! (GV%RZ_to_H * (scale)) * fluxes%lrunoff(i,j) * T(i,1)
628  !}BGR
629  if (calculate_diags .and. associated(tv%TempxPmE)) then
630  tv%TempxPmE(i,j) = tv%TempxPmE(i,j) + (scale * dt) * &
631  (i_cp*fluxes%heat_content_lrunoff(i,j) - fluxes%lrunoff(i,j)*t(i,1))
632  endif
633  endif
634 
635  ! Add explicit heat flux for calving (which is part of the ice-ocean boundary
636  ! flux type). Calving is otherwise added with a temperature of SST.
637  if (usecalvingheatcontent) then
638  ! remove frunoff*SST here, to counteract its addition elsewhere
639  net_heat(i) = net_heat(i) + (scale*(dt * i_cp_hconvert)) * fluxes%heat_content_frunoff(i,j) - &
640  (gv%RZ_to_H * (scale * dt)) * fluxes%frunoff(i,j) * t(i,1)
641  !BGR-Jul 5, 2017{
642  !Intentionally neglect the following contribution to rate for legacy reasons.
643 ! if (do_NHR) net_heat_rate(i) = net_heat_rate(i) + (scale*I_Cp_Hconvert) * fluxes%heat_content_frunoff(i,j) - &
644 ! (GV%RZ_to_H * scale) * fluxes%frunoff(i,j) * T(i,1)
645  !}BGR
646  if (calculate_diags .and. associated(tv%TempxPmE)) then
647  tv%TempxPmE(i,j) = tv%TempxPmE(i,j) + (scale * dt) * &
648  (i_cp*fluxes%heat_content_frunoff(i,j) - fluxes%frunoff(i,j)*t(i,1))
649  endif
650  endif
651 
652 ! smg: new code
653  ! add heat from all terms that may add mass to the ocean (K * H).
654  ! if evap, lprec, or vprec < 0, then compute their heat content
655  ! inside MOM_diabatic_driver.F90 and fill in fluxes%heat_content_massout.
656  ! we do so since we do not here know the temperature
657  ! of water leaving the ocean, as it could be leaving from more than
658  ! one layer of the upper ocean in the case of very thin layers.
659  ! When evap, lprec, or vprec > 0, then we know their heat content here
660  ! via settings from inside of the appropriate config_src driver files.
661 ! if (associated(fluxes%heat_content_lprec)) then
662 ! net_heat(i) = net_heat(i) + scale * dt * I_Cp_Hconvert * &
663 ! (fluxes%heat_content_lprec(i,j) + (fluxes%heat_content_fprec(i,j) + &
664 ! (fluxes%heat_content_lrunoff(i,j) + (fluxes%heat_content_frunoff(i,j) + &
665 ! (fluxes%heat_content_cond(i,j) + fluxes%heat_content_vprec(i,j))))))
666 ! endif
667 
668  if (fluxes%num_msg < fluxes%max_msg) then
669  if (pen_sw_tot(i) > 1.000001 * i_cp_hconvert*scale*dt*fluxes%sw(i,j)) then
670  fluxes%num_msg = fluxes%num_msg + 1
671  write(mesg,'("Penetrating shortwave of ",1pe17.10, &
672  &" exceeds total shortwave of ",1pe17.10,&
673  &" at ",1pg11.4,"E, "1pg11.4,"N.")') &
674  pen_sw_tot(i), i_cp_hconvert*scale*dt * fluxes%sw(i,j), &
675  g%geoLonT(i,j), g%geoLatT(i,j)
676  call mom_error(warning,mesg)
677  endif
678  endif
679 
680  ! remove penetrative portion of the SW that is NOT absorbed within a
681  ! tiny layer at the top of the ocean.
682  net_heat(i) = net_heat(i) - pen_sw_tot(i)
683  !Repeat above code for 'rate' term
684  if (do_nhr) net_heat_rate(i) = net_heat_rate(i) - pen_sw_tot_rate(i)
685 
686  ! diagnose non-downwelling SW
687  if (present(nonpensw)) then
688  nonpensw(i) = scale * dt * i_cp_hconvert * fluxes%sw(i,j) - pen_sw_tot(i)
689  endif
690 
691  ! Salt fluxes
692  net_salt(i) = 0.0
693  if (do_nsr) net_salt_rate(i) = 0.0
694  ! Convert salt_flux from kg (salt)/(m^2 * s) to
695  ! Boussinesq: (ppt * m)
696  ! non-Bouss: (g/m^2)
697  if (associated(fluxes%salt_flux)) then
698  net_salt(i) = (scale * dt * (1000.0 * fluxes%salt_flux(i,j))) * gv%RZ_to_H
699  !Repeat above code for 'rate' term
700  if (do_nsr) net_salt_rate(i) = (scale * 1. * (1000.0 * fluxes%salt_flux(i,j))) * gv%RZ_to_H
701  endif
702 
703  ! Diagnostics follow...
704  if (calculate_diags) then
705 
706  ! Store Net_salt for unknown reason?
707  if (associated(fluxes%salt_flux)) then
708  ! This seems like a bad idea to me. -RWH
709  if (calculate_diags) fluxes%netSalt(i,j) = us%kg_m2s_to_RZ_T*net_salt(i)
710  endif
711 
712  ! Initialize heat_content_massin that is diagnosed in mixedlayer_convection or
713  ! applyBoundaryFluxes such that the meaning is as the sum of all incoming components.
714  if (associated(fluxes%heat_content_massin)) then
715  if (aggregate_fw) then
716  if (netmassinout(i) > 0.0) then ! net is "in"
717  fluxes%heat_content_massin(i,j) = -fluxes%C_p * netmassout(i) * t(i,1) * gv%H_to_RZ / dt
718  else ! net is "out"
719  fluxes%heat_content_massin(i,j) = fluxes%C_p * ( netmassinout(i) - netmassout(i) ) * &
720  t(i,1) * gv%H_to_RZ / dt
721  endif
722  else
723  fluxes%heat_content_massin(i,j) = 0.
724  endif
725  endif
726 
727  ! Initialize heat_content_massout that is diagnosed in mixedlayer_convection or
728  ! applyBoundaryFluxes such that the meaning is as the sum of all outgoing components.
729  if (associated(fluxes%heat_content_massout)) then
730  if (aggregate_fw) then
731  if (netmassinout(i) > 0.0) then ! net is "in"
732  fluxes%heat_content_massout(i,j) = fluxes%C_p * netmassout(i) * t(i,1) * gv%H_to_RZ / dt
733  else ! net is "out"
734  fluxes%heat_content_massout(i,j) = -fluxes%C_p * ( netmassinout(i) - netmassout(i) ) * &
735  t(i,1) * gv%H_to_RZ / dt
736  endif
737  else
738  fluxes%heat_content_massout(i,j) = 0.0
739  endif
740  endif
741 
742  ! smg: we should remove sea ice melt from lprec!!!
743  ! fluxes%lprec > 0 means ocean gains mass via liquid precipitation and/or sea ice melt.
744  ! When atmosphere does not provide heat of this precipitation, the ocean assumes
745  ! it enters the ocean at the SST.
746  ! fluxes%lprec < 0 means ocean loses mass via sea ice formation. As we do not yet know
747  ! the layer at which this mass is removed, we cannot compute it heat content. We must
748  ! wait until MOM_diabatic_driver.F90.
749  if (associated(fluxes%heat_content_lprec)) then
750  if (fluxes%lprec(i,j) > 0.0) then
751  fluxes%heat_content_lprec(i,j) = fluxes%C_p*fluxes%lprec(i,j)*t(i,1)
752  else
753  fluxes%heat_content_lprec(i,j) = 0.0
754  endif
755  endif
756 
757  ! fprec SHOULD enter ocean at 0degC if atmos model does not provide fprec heat content.
758  ! However, we need to adjust netHeat above to reflect the difference between 0decC and SST
759  ! and until we do so fprec is treated like lprec and enters at SST. -AJA
760  if (associated(fluxes%heat_content_fprec)) then
761  if (fluxes%fprec(i,j) > 0.0) then
762  fluxes%heat_content_fprec(i,j) = fluxes%C_p*fluxes%fprec(i,j)*t(i,1)
763  else
764  fluxes%heat_content_fprec(i,j) = 0.0
765  endif
766  endif
767 
768  ! Following lprec and fprec, water flux due to sea ice melt (seaice_melt) enters at SST - GMM
769  if (associated(fluxes%heat_content_icemelt)) then
770  if (fluxes%seaice_melt(i,j) > 0.0) then
771  fluxes%heat_content_icemelt(i,j) = fluxes%C_p*fluxes%seaice_melt(i,j)*t(i,1)
772  else
773  fluxes%heat_content_icemelt(i,j) = 0.0
774  endif
775  endif
776 
777  ! virtual precip associated with salinity restoring
778  ! vprec > 0 means add water to ocean, assumed to be at SST
779  ! vprec < 0 means remove water from ocean; set heat_content_vprec in MOM_diabatic_driver.F90
780  if (associated(fluxes%heat_content_vprec)) then
781  if (fluxes%vprec(i,j) > 0.0) then
782  fluxes%heat_content_vprec(i,j) = fluxes%C_p*fluxes%vprec(i,j)*t(i,1)
783  else
784  fluxes%heat_content_vprec(i,j) = 0.0
785  endif
786  endif
787 
788  ! fluxes%evap < 0 means ocean loses mass due to evaporation.
789  ! Evaporation leaves ocean surface at a temperature that has yet to be determined,
790  ! since we do not know the precise layer that the water evaporates. We therefore
791  ! compute fluxes%heat_content_massout at the relevant point inside MOM_diabatic_driver.F90.
792  ! fluxes%evap > 0 means ocean gains moisture via condensation.
793  ! Condensation is assumed to drop into the ocean at the SST, just like lprec.
794  if (associated(fluxes%heat_content_cond)) then
795  if (fluxes%evap(i,j) > 0.0) then
796  fluxes%heat_content_cond(i,j) = fluxes%C_p*fluxes%evap(i,j)*t(i,1)
797  else
798  fluxes%heat_content_cond(i,j) = 0.0
799  endif
800  endif
801 
802  ! Liquid runoff enters ocean at SST if land model does not provide runoff heat content.
803  if (.not. useriverheatcontent) then
804  if (associated(fluxes%lrunoff) .and. associated(fluxes%heat_content_lrunoff)) then
805  fluxes%heat_content_lrunoff(i,j) = fluxes%C_p*fluxes%lrunoff(i,j)*t(i,1)
806  endif
807  endif
808 
809  ! Icebergs enter ocean at SST if land model does not provide calving heat content.
810  if (.not. usecalvingheatcontent) then
811  if (associated(fluxes%frunoff) .and. associated(fluxes%heat_content_frunoff)) then
812  fluxes%heat_content_frunoff(i,j) = fluxes%C_p*fluxes%frunoff(i,j)*t(i,1)
813  endif
814  endif
815 
816  endif ! calculate_diags
817 
818  enddo ! i-loop
819 

◆ extractfluxes2d()

subroutine, public mom_forcing_type::extractfluxes2d ( type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
type(unit_scale_type), intent(in)  US,
type(forcing), intent(inout)  fluxes,
type(optics_type), pointer  optics,
integer, intent(in)  nsw,
real, intent(in)  dt,
real, intent(in)  FluxRescaleDepth,
logical, intent(in)  useRiverHeatContent,
logical, intent(in)  useCalvingHeatContent,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke), intent(in)  h,
real, dimension( g %isd: g %ied, g %jsd: g %jed, g %ke), intent(in)  T,
real, dimension( g %isd: g %ied, g %jsd: g %jed), intent(out)  netMassInOut,
real, dimension( g %isd: g %ied, g %jsd: g %jed), intent(out)  netMassOut,
real, dimension( g %isd: g %ied, g %jsd: g %jed), intent(out)  net_heat,
real, dimension( g %isd: g %ied, g %jsd: g %jed), intent(out)  Net_salt,
real, dimension(max(1,nsw),g%isd:g%ied,g%jsd:g%jed), intent(out)  Pen_SW_bnd,
type(thermo_var_ptrs), intent(inout)  tv,
logical, intent(in)  aggregate_FW 
)

2d wrapper for 1d extract fluxes from surface fluxes type. This subroutine extracts fluxes from the surface fluxes type. It multiplies the fluxes by dt, so that the result is an accumulation of the fluxes over a time step.

Parameters
[in]gocean grid structure
[in]gvocean vertical grid structure
[in]usA dimensional unit scaling type
[in,out]fluxesstructure containing pointers to forcing.
opticspointer to optics
[in]nswnumber of bands of penetrating SW
[in]dtThe time step for these fluxes [T ~> s]
[in]fluxrescaledepthmin ocean depth before fluxes are scaled away [H ~> m or kg m-2]
[in]useriverheatcontentlogical for river heat content
[in]usecalvingheatcontentlogical for calving heat content
[in]hlayer thickness [H ~> m or kg m-2]
[in]tlayer temperatures [degC]
[out]netmassinoutnet mass flux (non-Bouss) or volume flux (if Bouss) of water in/out of ocean over a time step [H ~> m or kg m-2]
[out]netmassoutnet mass flux (non-Bouss) or volume flux (if Bouss) of water leaving ocean surface over a time step [H ~> m or kg m-2].
[out]net_heatnet heat at the surface accumulated over a time step associated with coupler + restore. Exclude two terms from net_heat: (1) downwelling (penetrative) SW, (2) evaporation heat content, (since do not yet know temperature of evap). [degC H ~> degC m or degC kg m-2]
[out]net_saltsurface salt flux into the ocean accumulated over a time step [ppt H ~> ppt m or ppt kg m-2]
[out]pen_sw_bndpenetrating SW flux, by frequency band [degC H ~> degC m or degC kg m-2] with array size nsw x G isd: G ied, where nsw=number of SW bands in pen_SW_bnd. This heat flux is not in net_heat.
[in,out]tvstructure containing pointers to available thermodynamic fields. Here it is used to keep track of the heat flux associated with net mass fluxes into the ocean.
[in]aggregate_fwFor determining how to aggregate the forcing.

Definition at line 826 of file MOM_forcing_type.F90.

830 
831  type(ocean_grid_type), intent(in) :: G !< ocean grid structure
832  type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure
833  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
834  type(forcing), intent(inout) :: fluxes !< structure containing pointers to forcing.
835  type(optics_type), pointer :: optics !< pointer to optics
836  integer, intent(in) :: nsw !< number of bands of penetrating SW
837  real, intent(in) :: dt !< The time step for these fluxes [T ~> s]
838  real, intent(in) :: FluxRescaleDepth !< min ocean depth before fluxes
839  !! are scaled away [H ~> m or kg m-2]
840  logical, intent(in) :: useRiverHeatContent !< logical for river heat content
841  logical, intent(in) :: useCalvingHeatContent !< logical for calving heat content
842  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), &
843  intent(in) :: h !< layer thickness [H ~> m or kg m-2]
844  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), &
845  intent(in) :: T !< layer temperatures [degC]
846  real, dimension(SZI_(G),SZJ_(G)), intent(out) :: netMassInOut !< net mass flux (non-Bouss) or volume flux
847  !! (if Bouss) of water in/out of ocean over
848  !! a time step [H ~> m or kg m-2]
849  real, dimension(SZI_(G),SZJ_(G)), intent(out) :: netMassOut !< net mass flux (non-Bouss) or volume flux
850  !! (if Bouss) of water leaving ocean surface
851  !! over a time step [H ~> m or kg m-2].
852  real, dimension(SZI_(G),SZJ_(G)), intent(out) :: net_heat !< net heat at the surface accumulated over a
853  !! time step associated with coupler + restore.
854  !! Exclude two terms from net_heat:
855  !! (1) downwelling (penetrative) SW,
856  !! (2) evaporation heat content,
857  !! (since do not yet know temperature of evap).
858  !! [degC H ~> degC m or degC kg m-2]
859  real, dimension(SZI_(G),SZJ_(G)), intent(out) :: net_salt !< surface salt flux into the ocean accumulated
860  !! over a time step [ppt H ~> ppt m or ppt kg m-2]
861  real, dimension(max(1,nsw),G%isd:G%ied,G%jsd:G%jed), intent(out) :: pen_SW_bnd !< penetrating SW flux, by frequency
862  !! band [degC H ~> degC m or degC kg m-2] with array
863  !! size nsw x SZI_(G), where nsw=number of SW bands
864  !! in pen_SW_bnd. This heat flux is not in net_heat.
865  type(thermo_var_ptrs), intent(inout) :: tv !< structure containing pointers to available
866  !! thermodynamic fields. Here it is used to keep
867  !! track of the heat flux associated with net
868  !! mass fluxes into the ocean.
869  logical, intent(in) :: aggregate_FW !< For determining how to aggregate the forcing.
870 
871  integer :: j
872  !$OMP parallel do default(shared)
873  do j=g%jsc, g%jec
874  call extractfluxes1d(g, gv, us, fluxes, optics, nsw, j, dt, &
875  fluxrescaledepth, useriverheatcontent, usecalvingheatcontent,&
876  h(:,j,:), t(:,j,:), netmassinout(:,j), netmassout(:,j), &
877  net_heat(:,j), net_salt(:,j), pen_sw_bnd(:,:,j), tv, aggregate_fw)
878  enddo
879 

◆ fluxes_accumulate()

subroutine, public mom_forcing_type::fluxes_accumulate ( type(forcing), intent(in)  flux_tmp,
type(forcing), intent(inout)  fluxes,
type(ocean_grid_type), intent(inout)  G,
real, intent(out)  wt2,
type(mech_forcing), intent(in), optional  forces 
)

Accumulate the thermodynamic fluxes over time steps.

Parameters
[in]flux_tmpA temporary structure with current thermodynamic forcing fields
[in,out]fluxesA structure containing time-averaged thermodynamic forcing fields
[in,out]gThe ocean's grid structure
[out]wt2The relative weight of the new fluxes
[in]forcesA structure with the driving mechanical forces

Definition at line 1913 of file MOM_forcing_type.F90.

1914  type(forcing), intent(in) :: flux_tmp !< A temporary structure with current
1915  !! thermodynamic forcing fields
1916  type(forcing), intent(inout) :: fluxes !< A structure containing time-averaged
1917  !! thermodynamic forcing fields
1918  type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure
1919  real, intent(out) :: wt2 !< The relative weight of the new fluxes
1920  type(mech_forcing), optional, intent(in) :: forces !< A structure with the driving mechanical forces
1921 
1922  ! This subroutine copies mechancal forcing from flux_tmp to fluxes and
1923  ! stores the time-weighted averages of the various buoyancy fluxes in fluxes,
1924  ! and increments the amount of time over which the buoyancy forcing in fluxes should be
1925  ! applied based on the time interval stored in flux_tmp.
1926 
1927  real :: wt1
1928  integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq, i0, j0
1929  integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB, isr, ier, jsr, jer
1930  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
1931  isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
1932  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
1933  isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
1934 
1935 
1936  if (fluxes%dt_buoy_accum < 0) call mom_error(fatal, "fluxes_accumulate: "//&
1937  "fluxes must be initialzed before it can be augmented.")
1938 
1939  ! wt1 is the relative weight of the previous fluxes.
1940  wt1 = fluxes%dt_buoy_accum / (fluxes%dt_buoy_accum + flux_tmp%dt_buoy_accum)
1941  wt2 = 1.0 - wt1 ! = flux_tmp%dt_buoy_accum / (fluxes%dt_buoy_accum + flux_tmp%dt_buoy_accum)
1942  fluxes%dt_buoy_accum = fluxes%dt_buoy_accum + flux_tmp%dt_buoy_accum
1943 
1944  ! Copy over the pressure fields and accumulate averages of ustar, either from the forcing
1945  ! type or from the temporary fluxes type.
1946  if (present(forces)) then
1947  do j=js,je ; do i=is,ie
1948  fluxes%p_surf(i,j) = forces%p_surf(i,j)
1949  fluxes%p_surf_full(i,j) = forces%p_surf_full(i,j)
1950 
1951  fluxes%ustar(i,j) = wt1*fluxes%ustar(i,j) + wt2*forces%ustar(i,j)
1952  enddo ; enddo
1953  else
1954  do j=js,je ; do i=is,ie
1955  fluxes%p_surf(i,j) = flux_tmp%p_surf(i,j)
1956  fluxes%p_surf_full(i,j) = flux_tmp%p_surf_full(i,j)
1957 
1958  fluxes%ustar(i,j) = wt1*fluxes%ustar(i,j) + wt2*flux_tmp%ustar(i,j)
1959  enddo ; enddo
1960  endif
1961 
1962  ! Average the water, heat, and salt fluxes, and ustar.
1963  do j=js,je ; do i=is,ie
1964  if (fluxes%gustless_accum_bug) then
1965  fluxes%ustar_gustless(i,j) = flux_tmp%ustar_gustless(i,j)
1966  else
1967  fluxes%ustar_gustless(i,j) = wt1*fluxes%ustar_gustless(i,j) + wt2*flux_tmp%ustar_gustless(i,j)
1968  endif
1969 
1970  fluxes%evap(i,j) = wt1*fluxes%evap(i,j) + wt2*flux_tmp%evap(i,j)
1971  fluxes%lprec(i,j) = wt1*fluxes%lprec(i,j) + wt2*flux_tmp%lprec(i,j)
1972  fluxes%fprec(i,j) = wt1*fluxes%fprec(i,j) + wt2*flux_tmp%fprec(i,j)
1973  fluxes%vprec(i,j) = wt1*fluxes%vprec(i,j) + wt2*flux_tmp%vprec(i,j)
1974  fluxes%lrunoff(i,j) = wt1*fluxes%lrunoff(i,j) + wt2*flux_tmp%lrunoff(i,j)
1975  fluxes%frunoff(i,j) = wt1*fluxes%frunoff(i,j) + wt2*flux_tmp%frunoff(i,j)
1976  fluxes%seaice_melt(i,j) = wt1*fluxes%seaice_melt(i,j) + wt2*flux_tmp%seaice_melt(i,j)
1977  fluxes%sw(i,j) = wt1*fluxes%sw(i,j) + wt2*flux_tmp%sw(i,j)
1978  fluxes%sw_vis_dir(i,j) = wt1*fluxes%sw_vis_dir(i,j) + wt2*flux_tmp%sw_vis_dir(i,j)
1979  fluxes%sw_vis_dif(i,j) = wt1*fluxes%sw_vis_dif(i,j) + wt2*flux_tmp%sw_vis_dif(i,j)
1980  fluxes%sw_nir_dir(i,j) = wt1*fluxes%sw_nir_dir(i,j) + wt2*flux_tmp%sw_nir_dir(i,j)
1981  fluxes%sw_nir_dif(i,j) = wt1*fluxes%sw_nir_dif(i,j) + wt2*flux_tmp%sw_nir_dif(i,j)
1982  fluxes%lw(i,j) = wt1*fluxes%lw(i,j) + wt2*flux_tmp%lw(i,j)
1983  fluxes%latent(i,j) = wt1*fluxes%latent(i,j) + wt2*flux_tmp%latent(i,j)
1984  fluxes%sens(i,j) = wt1*fluxes%sens(i,j) + wt2*flux_tmp%sens(i,j)
1985 
1986  fluxes%salt_flux(i,j) = wt1*fluxes%salt_flux(i,j) + wt2*flux_tmp%salt_flux(i,j)
1987  enddo ; enddo
1988  if (associated(fluxes%heat_added) .and. associated(flux_tmp%heat_added)) then
1989  do j=js,je ; do i=is,ie
1990  fluxes%heat_added(i,j) = wt1*fluxes%heat_added(i,j) + wt2*flux_tmp%heat_added(i,j)
1991  enddo ; enddo
1992  endif
1993  ! These might always be associated, in which case they can be combined?
1994  if (associated(fluxes%heat_content_cond) .and. associated(flux_tmp%heat_content_cond)) then
1995  do j=js,je ; do i=is,ie
1996  fluxes%heat_content_cond(i,j) = wt1*fluxes%heat_content_cond(i,j) + wt2*flux_tmp%heat_content_cond(i,j)
1997  enddo ; enddo
1998  endif
1999  if (associated(fluxes%heat_content_lprec) .and. associated(flux_tmp%heat_content_lprec)) then
2000  do j=js,je ; do i=is,ie
2001  fluxes%heat_content_lprec(i,j) = wt1*fluxes%heat_content_lprec(i,j) + wt2*flux_tmp%heat_content_lprec(i,j)
2002  enddo ; enddo
2003  endif
2004  if (associated(fluxes%heat_content_fprec) .and. associated(flux_tmp%heat_content_fprec)) then
2005  do j=js,je ; do i=is,ie
2006  fluxes%heat_content_fprec(i,j) = wt1*fluxes%heat_content_fprec(i,j) + wt2*flux_tmp%heat_content_fprec(i,j)
2007  enddo ; enddo
2008  endif
2009  if (associated(fluxes%heat_content_icemelt) .and. associated(flux_tmp%heat_content_icemelt)) then
2010  do j=js,je ; do i=is,ie
2011  fluxes%heat_content_icemelt(i,j) = wt1*fluxes%heat_content_icemelt(i,j) + wt2*flux_tmp%heat_content_icemelt(i,j)
2012  enddo ; enddo
2013  endif
2014  if (associated(fluxes%heat_content_vprec) .and. associated(flux_tmp%heat_content_vprec)) then
2015  do j=js,je ; do i=is,ie
2016  fluxes%heat_content_vprec(i,j) = wt1*fluxes%heat_content_vprec(i,j) + wt2*flux_tmp%heat_content_vprec(i,j)
2017  enddo ; enddo
2018  endif
2019  if (associated(fluxes%heat_content_lrunoff) .and. associated(flux_tmp%heat_content_lrunoff)) then
2020  do j=js,je ; do i=is,ie
2021  fluxes%heat_content_lrunoff(i,j) = wt1*fluxes%heat_content_lrunoff(i,j) + wt2*flux_tmp%heat_content_lrunoff(i,j)
2022  enddo ; enddo
2023  endif
2024  if (associated(fluxes%heat_content_frunoff) .and. associated(flux_tmp%heat_content_frunoff)) then
2025  do j=js,je ; do i=is,ie
2026  fluxes%heat_content_frunoff(i,j) = wt1*fluxes%heat_content_frunoff(i,j) + wt2*flux_tmp%heat_content_frunoff(i,j)
2027  enddo ; enddo
2028  endif
2029  if (associated(fluxes%heat_content_icemelt) .and. associated(flux_tmp%heat_content_icemelt)) then
2030  do j=js,je ; do i=is,ie
2031  fluxes%heat_content_icemelt(i,j) = wt1*fluxes%heat_content_icemelt(i,j) + wt2*flux_tmp%heat_content_icemelt(i,j)
2032  enddo ; enddo
2033  endif
2034 
2035  if (associated(fluxes%ustar_shelf) .and. associated(flux_tmp%ustar_shelf)) then
2036  do i=isd,ied ; do j=jsd,jed
2037  fluxes%ustar_shelf(i,j) = flux_tmp%ustar_shelf(i,j)
2038  enddo ; enddo
2039  endif
2040  if (associated(fluxes%iceshelf_melt) .and. associated(flux_tmp%iceshelf_melt)) then
2041  do i=isd,ied ; do j=jsd,jed
2042  fluxes%iceshelf_melt(i,j) = flux_tmp%iceshelf_melt(i,j)
2043  enddo ; enddo
2044  endif
2045  if (associated(fluxes%frac_shelf_h) .and. associated(flux_tmp%frac_shelf_h)) then
2046  do i=isd,ied ; do j=jsd,jed
2047  fluxes%frac_shelf_h(i,j) = flux_tmp%frac_shelf_h(i,j)
2048  enddo ; enddo
2049  endif
2050 
2051  if (coupler_type_initialized(fluxes%tr_fluxes) .and. &
2052  coupler_type_initialized(flux_tmp%tr_fluxes)) &
2053  call coupler_type_increment_data(flux_tmp%tr_fluxes, fluxes%tr_fluxes, &
2054  scale_factor=wt2, scale_prev=wt1)
2055 

◆ forcing_accumulate()

subroutine, public mom_forcing_type::forcing_accumulate ( type(forcing), intent(in)  flux_tmp,
type(mech_forcing), intent(in)  forces,
type(forcing), intent(inout)  fluxes,
type(ocean_grid_type), intent(inout)  G,
real, intent(out)  wt2 
)

Accumulate the forcing over time steps, taking input from a mechanical forcing type and a temporary forcing-flux type.

Parameters
[in]flux_tmpA temporary structure with current thermodynamic forcing fields
[in]forcesA structure with the driving mechanical forces
[in,out]fluxesA structure containing time-averaged thermodynamic forcing fields
[in,out]gThe ocean's grid structure
[out]wt2The relative weight of the new fluxes

Definition at line 1894 of file MOM_forcing_type.F90.

1895  type(forcing), intent(in) :: flux_tmp !< A temporary structure with current
1896  !!thermodynamic forcing fields
1897  type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces
1898  type(forcing), intent(inout) :: fluxes !< A structure containing time-averaged
1899  !! thermodynamic forcing fields
1900  type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure
1901  real, intent(out) :: wt2 !< The relative weight of the new fluxes
1902 
1903  ! This subroutine copies mechancal forcing from flux_tmp to fluxes and
1904  ! stores the time-weighted averages of the various buoyancy fluxes in fluxes,
1905  ! and increments the amount of time over which the buoyancy forcing should be
1906  ! applied, all via a call to fluxes accumulate.
1907 
1908  call fluxes_accumulate(flux_tmp, fluxes, g, wt2, forces)
1909 

◆ forcing_diagnostics()

subroutine, public mom_forcing_type::forcing_diagnostics ( type(forcing), intent(in), target  fluxes_in,
type(surface), intent(in)  sfc_state,
type(ocean_grid_type), intent(in), target  G_in,
type(unit_scale_type), intent(in)  US,
type(time_type), intent(in)  time_end,
type(diag_ctrl), intent(inout)  diag,
type(forcing_diags), intent(inout)  handles 
)

Offer buoyancy forcing fields for diagnostics for those fields registered as part of register_forcing_type_diags.

Parameters
[in]fluxes_inA structure containing thermodynamic forcing fields
[in]sfc_stateA structure containing fields that describe the surface state of the ocean.
[in]g_inInput grid type
[in]usA dimensional unit scaling type
[in]time_endThe end time of the diagnostic interval.
[in,out]diagdiagnostic regulator
[in,out]handlesdiagnostic ids

Definition at line 2273 of file MOM_forcing_type.F90.

2274  type(forcing), target, intent(in) :: fluxes_in !< A structure containing thermodynamic forcing fields
2275  type(surface), intent(in) :: sfc_state !< A structure containing fields that
2276  !! describe the surface state of the ocean.
2277  type(ocean_grid_type), target, intent(in) :: G_in !< Input grid type
2278  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
2279  type(time_type), intent(in) :: time_end !< The end time of the diagnostic interval.
2280  type(diag_ctrl), intent(inout) :: diag !< diagnostic regulator
2281  type(forcing_diags), intent(inout) :: handles !< diagnostic ids
2282 
2283  ! local
2284  type(ocean_grid_type), pointer :: G ! Grid metric on model index map
2285  type(forcing), pointer :: fluxes ! Fluxes on the model index map
2286  real, dimension(SZI_(diag%G),SZJ_(diag%G)) :: res
2287  real :: total_transport ! for diagnosing integrated boundary transport
2288  real :: ave_flux ! for diagnosing averaged boundary flux
2289  real :: RZ_T_conversion ! A combination of scaling factors for mass fluxes [kg T m-2 s-1 R-1 Z-1 ~> 1]
2290  real :: I_dt ! inverse time step [T-1 ~> s-1]
2291  real :: ppt2mks ! conversion between ppt and mks
2292  integer :: turns ! Number of index quarter turns
2293  integer :: i,j,is,ie,js,je
2294 
2295  call cpu_clock_begin(handles%id_clock_forcing)
2296 
2297  ! NOTE: post_data expects data to be on the rotated index map, so any
2298  ! rotations must be applied before saving the output.
2299  turns = diag%G%HI%turns
2300  if (turns /= 0) then
2301  g => diag%G
2302  allocate(fluxes)
2303  call allocate_forcing_type(fluxes_in, g, fluxes)
2304  call rotate_forcing(fluxes_in, fluxes, turns)
2305  else
2306  g => g_in
2307  fluxes => fluxes_in
2308  endif
2309 
2310  rz_t_conversion = us%RZ_T_to_kg_m2s
2311  i_dt = 1.0 / fluxes%dt_buoy_accum
2312  ppt2mks = 1e-3
2313  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
2314 
2315  call enable_averages(fluxes%dt_buoy_accum, time_end, diag)
2316  ! if (query_averaging_enabled(diag)) then
2317 
2318  ! post the diagnostics for surface mass fluxes ==================================
2319 
2320  if (handles%id_prcme > 0 .or. handles%id_total_prcme > 0 .or. handles%id_prcme_ga > 0) then
2321  do j=js,je ; do i=is,ie
2322  res(i,j) = 0.0
2323  if (associated(fluxes%lprec)) res(i,j) = res(i,j) + rz_t_conversion*fluxes%lprec(i,j)
2324  if (associated(fluxes%fprec)) res(i,j) = res(i,j) + rz_t_conversion*fluxes%fprec(i,j)
2325  ! fluxes%cond is not needed because it is derived from %evap > 0
2326  if (associated(fluxes%evap)) res(i,j) = res(i,j) + rz_t_conversion*fluxes%evap(i,j)
2327  if (associated(fluxes%lrunoff)) res(i,j) = res(i,j) + rz_t_conversion*fluxes%lrunoff(i,j)
2328  if (associated(fluxes%frunoff)) res(i,j) = res(i,j) + rz_t_conversion*fluxes%frunoff(i,j)
2329  if (associated(fluxes%vprec)) res(i,j) = res(i,j) + rz_t_conversion*fluxes%vprec(i,j)
2330  if (associated(fluxes%seaice_melt)) res(i,j) = res(i,j) + rz_t_conversion*fluxes%seaice_melt(i,j)
2331  enddo ; enddo
2332  if (handles%id_prcme > 0) call post_data(handles%id_prcme, res, diag)
2333  if (handles%id_total_prcme > 0) then
2334  total_transport = global_area_integral(res, g)
2335  call post_data(handles%id_total_prcme, total_transport, diag)
2336  endif
2337  if (handles%id_prcme_ga > 0) then
2338  ave_flux = global_area_mean(res, g)
2339  call post_data(handles%id_prcme_ga, ave_flux, diag)
2340  endif
2341  endif
2342 
2343  if (handles%id_net_massout > 0 .or. handles%id_total_net_massout > 0) then
2344  do j=js,je ; do i=is,ie
2345  res(i,j) = 0.0
2346  if (associated(fluxes%lprec)) then
2347  if (fluxes%lprec(i,j) < 0.0) res(i,j) = res(i,j) + rz_t_conversion*fluxes%lprec(i,j)
2348  endif
2349  if (associated(fluxes%vprec)) then
2350  if (fluxes%vprec(i,j) < 0.0) res(i,j) = res(i,j) + rz_t_conversion*fluxes%vprec(i,j)
2351  endif
2352  if (associated(fluxes%evap)) then
2353  if (fluxes%evap(i,j) < 0.0) res(i,j) = res(i,j) + rz_t_conversion*fluxes%evap(i,j)
2354  endif
2355  if (associated(fluxes%seaice_melt)) then
2356  if (fluxes%seaice_melt(i,j) < 0.0) &
2357  res(i,j) = res(i,j) + rz_t_conversion*fluxes%seaice_melt(i,j)
2358  endif
2359  enddo ; enddo
2360  if (handles%id_net_massout > 0) call post_data(handles%id_net_massout, res, diag)
2361  if (handles%id_total_net_massout > 0) then
2362  total_transport = global_area_integral(res, g)
2363  call post_data(handles%id_total_net_massout, total_transport, diag)
2364  endif
2365  endif
2366 
2367  if (handles%id_massout_flux > 0 .and. associated(fluxes%netMassOut)) &
2368  call post_data(handles%id_massout_flux,fluxes%netMassOut,diag)
2369 
2370  if (handles%id_net_massin > 0 .or. handles%id_total_net_massin > 0) then
2371  do j=js,je ; do i=is,ie
2372  res(i,j) = 0.0
2373 
2374  if (associated(fluxes%fprec)) &
2375  res(i,j) = res(i,j) + rz_t_conversion*fluxes%fprec(i,j)
2376  if (associated(fluxes%lrunoff)) &
2377  res(i,j) = res(i,j) + rz_t_conversion*fluxes%lrunoff(i,j)
2378  if (associated(fluxes%frunoff)) &
2379  res(i,j) = res(i,j) + rz_t_conversion*fluxes%frunoff(i,j)
2380 
2381  if (associated(fluxes%lprec)) then
2382  if (fluxes%lprec(i,j) > 0.0) res(i,j) = res(i,j) + rz_t_conversion*fluxes%lprec(i,j)
2383  endif
2384  if (associated(fluxes%vprec)) then
2385  if (fluxes%vprec(i,j) > 0.0) res(i,j) = res(i,j) + rz_t_conversion*fluxes%vprec(i,j)
2386  endif
2387  ! fluxes%cond is not needed because it is derived from %evap > 0
2388  if (associated(fluxes%evap)) then
2389  if (fluxes%evap(i,j) > 0.0) res(i,j) = res(i,j) + rz_t_conversion*fluxes%evap(i,j)
2390  endif
2391  if (associated(fluxes%seaice_melt)) then
2392  if (fluxes%seaice_melt(i,j) > 0.0) &
2393  res(i,j) = res(i,j) + rz_t_conversion*fluxes%seaice_melt(i,j)
2394  endif
2395  enddo ; enddo
2396  if (handles%id_net_massin > 0) call post_data(handles%id_net_massin, res, diag)
2397  if (handles%id_total_net_massin > 0) then
2398  total_transport = global_area_integral(res, g)
2399  call post_data(handles%id_total_net_massin, total_transport, diag)
2400  endif
2401  endif
2402 
2403  if (handles%id_massin_flux > 0 .and. associated(fluxes%netMassIn)) &
2404  call post_data(handles%id_massin_flux,fluxes%netMassIn,diag)
2405 
2406  if ((handles%id_evap > 0) .and. associated(fluxes%evap)) &
2407  call post_data(handles%id_evap, fluxes%evap, diag)
2408  if ((handles%id_total_evap > 0) .and. associated(fluxes%evap)) then
2409  total_transport = global_area_integral(fluxes%evap, g, scale=us%RZ_T_to_kg_m2s)
2410  call post_data(handles%id_total_evap, total_transport, diag)
2411  endif
2412  if ((handles%id_evap_ga > 0) .and. associated(fluxes%evap)) then
2413  ave_flux = global_area_mean(fluxes%evap, g, scale=us%RZ_T_to_kg_m2s)
2414  call post_data(handles%id_evap_ga, ave_flux, diag)
2415  endif
2416 
2417  if (associated(fluxes%lprec) .and. associated(fluxes%fprec)) then
2418  do j=js,je ; do i=is,ie
2419  res(i,j) = rz_t_conversion* (fluxes%lprec(i,j) + fluxes%fprec(i,j))
2420  enddo ; enddo
2421  if (handles%id_precip > 0) call post_data(handles%id_precip, res, diag)
2422  if (handles%id_total_precip > 0) then
2423  total_transport = global_area_integral(res, g)
2424  call post_data(handles%id_total_precip, total_transport, diag)
2425  endif
2426  if (handles%id_precip_ga > 0) then
2427  ave_flux = global_area_mean(res, g)
2428  call post_data(handles%id_precip_ga, ave_flux, diag)
2429  endif
2430  endif
2431 
2432  if (associated(fluxes%lprec)) then
2433  if (handles%id_lprec > 0) call post_data(handles%id_lprec, fluxes%lprec, diag)
2434  if (handles%id_total_lprec > 0) then
2435  total_transport = global_area_integral(fluxes%lprec, g, scale=us%RZ_T_to_kg_m2s)
2436  call post_data(handles%id_total_lprec, total_transport, diag)
2437  endif
2438  if (handles%id_lprec_ga > 0) then
2439  ave_flux = global_area_mean(fluxes%lprec, g, scale=us%RZ_T_to_kg_m2s)
2440  call post_data(handles%id_lprec_ga, ave_flux, diag)
2441  endif
2442  endif
2443 
2444  if (associated(fluxes%fprec)) then
2445  if (handles%id_fprec > 0) call post_data(handles%id_fprec, fluxes%fprec, diag)
2446  if (handles%id_total_fprec > 0) then
2447  total_transport = global_area_integral(fluxes%fprec, g, scale=us%RZ_T_to_kg_m2s)
2448  call post_data(handles%id_total_fprec, total_transport, diag)
2449  endif
2450  if (handles%id_fprec_ga > 0) then
2451  ave_flux = global_area_mean(fluxes%fprec, g, scale=us%RZ_T_to_kg_m2s)
2452  call post_data(handles%id_fprec_ga, ave_flux, diag)
2453  endif
2454  endif
2455 
2456  if (associated(fluxes%vprec)) then
2457  if (handles%id_vprec > 0) call post_data(handles%id_vprec, fluxes%vprec, diag)
2458  if (handles%id_total_vprec > 0) then
2459  total_transport = global_area_integral(fluxes%vprec, g, scale=us%RZ_T_to_kg_m2s)
2460  call post_data(handles%id_total_vprec, total_transport, diag)
2461  endif
2462  if (handles%id_vprec_ga > 0) then
2463  ave_flux = global_area_mean(fluxes%vprec, g, scale=us%RZ_T_to_kg_m2s)
2464  call post_data(handles%id_vprec_ga, ave_flux, diag)
2465  endif
2466  endif
2467 
2468  if (associated(fluxes%lrunoff)) then
2469  if (handles%id_lrunoff > 0) call post_data(handles%id_lrunoff, fluxes%lrunoff, diag)
2470  if (handles%id_total_lrunoff > 0) then
2471  total_transport = global_area_integral(fluxes%lrunoff, g, scale=us%RZ_T_to_kg_m2s)
2472  call post_data(handles%id_total_lrunoff, total_transport, diag)
2473  endif
2474  endif
2475 
2476  if (associated(fluxes%frunoff)) then
2477  if (handles%id_frunoff > 0) call post_data(handles%id_frunoff, fluxes%frunoff, diag)
2478  if (handles%id_total_frunoff > 0) then
2479  total_transport = global_area_integral(fluxes%frunoff, g, scale=us%RZ_T_to_kg_m2s)
2480  call post_data(handles%id_total_frunoff, total_transport, diag)
2481  endif
2482  endif
2483 
2484  if (associated(fluxes%seaice_melt)) then
2485  if (handles%id_seaice_melt > 0) call post_data(handles%id_seaice_melt, fluxes%seaice_melt, diag)
2486  if (handles%id_total_seaice_melt > 0) then
2487  total_transport = global_area_integral(fluxes%seaice_melt, g, scale=us%RZ_T_to_kg_m2s)
2488  call post_data(handles%id_total_seaice_melt, total_transport, diag)
2489  endif
2490  endif
2491 
2492  ! post diagnostics for boundary heat fluxes ====================================
2493 
2494  if ((handles%id_heat_content_lrunoff > 0) .and. associated(fluxes%heat_content_lrunoff)) &
2495  call post_data(handles%id_heat_content_lrunoff, fluxes%heat_content_lrunoff, diag)
2496  if ((handles%id_total_heat_content_lrunoff > 0) .and. associated(fluxes%heat_content_lrunoff)) then
2497  total_transport = global_area_integral(fluxes%heat_content_lrunoff, g, scale=us%QRZ_T_to_W_m2)
2498  call post_data(handles%id_total_heat_content_lrunoff, total_transport, diag)
2499  endif
2500 
2501  if ((handles%id_heat_content_frunoff > 0) .and. associated(fluxes%heat_content_frunoff)) &
2502  call post_data(handles%id_heat_content_frunoff, fluxes%heat_content_frunoff, diag)
2503  if ((handles%id_total_heat_content_frunoff > 0) .and. associated(fluxes%heat_content_frunoff)) then
2504  total_transport = global_area_integral(fluxes%heat_content_frunoff, g, scale=us%QRZ_T_to_W_m2)
2505  call post_data(handles%id_total_heat_content_frunoff, total_transport, diag)
2506  endif
2507 
2508  if ((handles%id_heat_content_lprec > 0) .and. associated(fluxes%heat_content_lprec)) &
2509  call post_data(handles%id_heat_content_lprec, fluxes%heat_content_lprec, diag)
2510  if ((handles%id_total_heat_content_lprec > 0) .and. associated(fluxes%heat_content_lprec)) then
2511  total_transport = global_area_integral(fluxes%heat_content_lprec, g, scale=us%QRZ_T_to_W_m2)
2512  call post_data(handles%id_total_heat_content_lprec, total_transport, diag)
2513  endif
2514 
2515  if ((handles%id_heat_content_fprec > 0) .and. associated(fluxes%heat_content_fprec)) &
2516  call post_data(handles%id_heat_content_fprec, fluxes%heat_content_fprec, diag)
2517  if ((handles%id_total_heat_content_fprec > 0) .and. associated(fluxes%heat_content_fprec)) then
2518  total_transport = global_area_integral(fluxes%heat_content_fprec, g, scale=us%QRZ_T_to_W_m2)
2519  call post_data(handles%id_total_heat_content_fprec, total_transport, diag)
2520  endif
2521 
2522  if ((handles%id_heat_content_icemelt > 0) .and. associated(fluxes%heat_content_icemelt)) &
2523  call post_data(handles%id_heat_content_icemelt, fluxes%heat_content_icemelt, diag)
2524  if ((handles%id_total_heat_content_icemelt > 0) .and. associated(fluxes%heat_content_icemelt)) then
2525  total_transport = global_area_integral(fluxes%heat_content_icemelt, g, scale=us%QRZ_T_to_W_m2)
2526  call post_data(handles%id_total_heat_content_icemelt, total_transport, diag)
2527  endif
2528 
2529  if ((handles%id_heat_content_vprec > 0) .and. associated(fluxes%heat_content_vprec)) &
2530  call post_data(handles%id_heat_content_vprec, fluxes%heat_content_vprec, diag)
2531  if ((handles%id_total_heat_content_vprec > 0) .and. associated(fluxes%heat_content_vprec)) then
2532  total_transport = global_area_integral(fluxes%heat_content_vprec, g, scale=us%QRZ_T_to_W_m2)
2533  call post_data(handles%id_total_heat_content_vprec, total_transport, diag)
2534  endif
2535 
2536  if ((handles%id_heat_content_cond > 0) .and. associated(fluxes%heat_content_cond)) &
2537  call post_data(handles%id_heat_content_cond, fluxes%heat_content_cond, diag)
2538  if ((handles%id_total_heat_content_cond > 0) .and. associated(fluxes%heat_content_cond)) then
2539  total_transport = global_area_integral(fluxes%heat_content_cond, g, scale=us%QRZ_T_to_W_m2)
2540  call post_data(handles%id_total_heat_content_cond, total_transport, diag)
2541  endif
2542 
2543  if ((handles%id_heat_content_massout > 0) .and. associated(fluxes%heat_content_massout)) &
2544  call post_data(handles%id_heat_content_massout, fluxes%heat_content_massout, diag)
2545  if ((handles%id_total_heat_content_massout > 0) .and. associated(fluxes%heat_content_massout)) then
2546  total_transport = global_area_integral(fluxes%heat_content_massout, g, scale=us%QRZ_T_to_W_m2)
2547  call post_data(handles%id_total_heat_content_massout, total_transport, diag)
2548  endif
2549 
2550  if ((handles%id_heat_content_massin > 0) .and. associated(fluxes%heat_content_massin)) &
2551  call post_data(handles%id_heat_content_massin, fluxes%heat_content_massin, diag)
2552  if ((handles%id_total_heat_content_massin > 0) .and. associated(fluxes%heat_content_massin)) then
2553  total_transport = global_area_integral(fluxes%heat_content_massin, g, scale=us%QRZ_T_to_W_m2)
2554  call post_data(handles%id_total_heat_content_massin, total_transport, diag)
2555  endif
2556 
2557  if (handles%id_net_heat_coupler > 0 .or. handles%id_total_net_heat_coupler > 0 .or. &
2558  handles%id_net_heat_coupler_ga > 0. ) then
2559  do j=js,je ; do i=is,ie
2560  res(i,j) = 0.0
2561  if (associated(fluxes%LW)) res(i,j) = res(i,j) + fluxes%lw(i,j)
2562  if (associated(fluxes%latent)) res(i,j) = res(i,j) + fluxes%latent(i,j)
2563  if (associated(fluxes%sens)) res(i,j) = res(i,j) + fluxes%sens(i,j)
2564  if (associated(fluxes%SW)) res(i,j) = res(i,j) + fluxes%sw(i,j)
2565  if (associated(fluxes%seaice_melt_heat)) res(i,j) = res(i,j) + fluxes%seaice_melt_heat(i,j)
2566  enddo ; enddo
2567  if (handles%id_net_heat_coupler > 0) call post_data(handles%id_net_heat_coupler, res, diag)
2568  if (handles%id_total_net_heat_coupler > 0) then
2569  total_transport = global_area_integral(res, g, scale=us%QRZ_T_to_W_m2)
2570  call post_data(handles%id_total_net_heat_coupler, total_transport, diag)
2571  endif
2572  if (handles%id_net_heat_coupler_ga > 0) then
2573  ave_flux = global_area_mean(res, g, scale=us%QRZ_T_to_W_m2)
2574  call post_data(handles%id_net_heat_coupler_ga, ave_flux, diag)
2575  endif
2576  endif
2577 
2578  if (handles%id_net_heat_surface > 0 .or. handles%id_total_net_heat_surface > 0 .or. &
2579  handles%id_net_heat_surface_ga > 0. ) then
2580  do j=js,je ; do i=is,ie
2581  res(i,j) = 0.0
2582  if (associated(fluxes%LW)) res(i,j) = res(i,j) + fluxes%lw(i,j)
2583  if (associated(fluxes%latent)) res(i,j) = res(i,j) + fluxes%latent(i,j)
2584  if (associated(fluxes%sens)) res(i,j) = res(i,j) + fluxes%sens(i,j)
2585  if (associated(fluxes%SW)) res(i,j) = res(i,j) + fluxes%sw(i,j)
2586  if (associated(fluxes%seaice_melt_heat)) res(i,j) = res(i,j) + fluxes%seaice_melt_heat(i,j)
2587  if (allocated(sfc_state%frazil)) res(i,j) = res(i,j) + sfc_state%frazil(i,j) * i_dt
2588  !if (associated(sfc_state%TempXpme)) then
2589  ! res(i,j) = res(i,j) + sfc_state%TempXpme(i,j) * fluxes%C_p * I_dt
2590  !else
2591  if (associated(fluxes%heat_content_lrunoff)) &
2592  res(i,j) = res(i,j) + fluxes%heat_content_lrunoff(i,j)
2593  if (associated(fluxes%heat_content_frunoff)) &
2594  res(i,j) = res(i,j) + fluxes%heat_content_frunoff(i,j)
2595  if (associated(fluxes%heat_content_lprec)) &
2596  res(i,j) = res(i,j) + fluxes%heat_content_lprec(i,j)
2597  if (associated(fluxes%heat_content_fprec)) &
2598  res(i,j) = res(i,j) + fluxes%heat_content_fprec(i,j)
2599  if (associated(fluxes%heat_content_icemelt)) &
2600  res(i,j) = res(i,j) + fluxes%heat_content_icemelt(i,j)
2601  if (associated(fluxes%heat_content_vprec)) &
2602  res(i,j) = res(i,j) + fluxes%heat_content_vprec(i,j)
2603  if (associated(fluxes%heat_content_cond)) &
2604  res(i,j) = res(i,j) + fluxes%heat_content_cond(i,j)
2605  if (associated(fluxes%heat_content_massout)) &
2606  res(i,j) = res(i,j) + fluxes%heat_content_massout(i,j)
2607  !endif
2608  if (associated(fluxes%heat_added)) res(i,j) = res(i,j) + fluxes%heat_added(i,j)
2609  enddo ; enddo
2610  if (handles%id_net_heat_surface > 0) call post_data(handles%id_net_heat_surface, res, diag)
2611 
2612  if (handles%id_total_net_heat_surface > 0) then
2613  total_transport = global_area_integral(res, g, scale=us%QRZ_T_to_W_m2)
2614  call post_data(handles%id_total_net_heat_surface, total_transport, diag)
2615  endif
2616  if (handles%id_net_heat_surface_ga > 0) then
2617  ave_flux = global_area_mean(res, g, scale=us%QRZ_T_to_W_m2)
2618  call post_data(handles%id_net_heat_surface_ga, ave_flux, diag)
2619  endif
2620  endif
2621 
2622  if (handles%id_heat_content_surfwater > 0 .or. handles%id_total_heat_content_surfwater > 0) then
2623  do j=js,je ; do i=is,ie
2624  res(i,j) = 0.0
2625  ! if (associated(sfc_state%TempXpme)) then
2626  ! res(i,j) = res(i,j) + sfc_state%TempXpme(i,j) * fluxes%C_p * I_dt
2627  ! else
2628  if (associated(fluxes%heat_content_lrunoff)) res(i,j) = res(i,j) + fluxes%heat_content_lrunoff(i,j)
2629  if (associated(fluxes%heat_content_frunoff)) res(i,j) = res(i,j) + fluxes%heat_content_frunoff(i,j)
2630  if (associated(fluxes%heat_content_lprec)) res(i,j) = res(i,j) + fluxes%heat_content_lprec(i,j)
2631  if (associated(fluxes%heat_content_icemelt)) res(i,j) = res(i,j) + fluxes%heat_content_icemelt(i,j)
2632  if (associated(fluxes%heat_content_fprec)) res(i,j) = res(i,j) + fluxes%heat_content_fprec(i,j)
2633  if (associated(fluxes%heat_content_vprec)) res(i,j) = res(i,j) + fluxes%heat_content_vprec(i,j)
2634  if (associated(fluxes%heat_content_cond)) res(i,j) = res(i,j) + fluxes%heat_content_cond(i,j)
2635  if (associated(fluxes%heat_content_massout)) res(i,j) = res(i,j) + fluxes%heat_content_massout(i,j)
2636  ! endif
2637  enddo ; enddo
2638  if (handles%id_heat_content_surfwater > 0) call post_data(handles%id_heat_content_surfwater, res, diag)
2639  if (handles%id_total_heat_content_surfwater > 0) then
2640  total_transport = global_area_integral(res, g, scale=us%QRZ_T_to_W_m2)
2641  call post_data(handles%id_total_heat_content_surfwater, total_transport, diag)
2642  endif
2643  endif
2644 
2645  ! for OMIP, hfrunoffds = heat content of liquid plus frozen runoff
2646  if (handles%id_hfrunoffds > 0) then
2647  do j=js,je ; do i=is,ie
2648  res(i,j) = 0.0
2649  if (associated(fluxes%heat_content_lrunoff)) res(i,j) = res(i,j) + fluxes%heat_content_lrunoff(i,j)
2650  if (associated(fluxes%heat_content_frunoff)) res(i,j) = res(i,j) + fluxes%heat_content_frunoff(i,j)
2651  enddo ; enddo
2652  call post_data(handles%id_hfrunoffds, res, diag)
2653  endif
2654 
2655  ! for OMIP, hfrainds = heat content of lprec + fprec + cond
2656  if (handles%id_hfrainds > 0) then
2657  do j=js,je ; do i=is,ie
2658  res(i,j) = 0.0
2659  if (associated(fluxes%heat_content_lprec)) res(i,j) = res(i,j) + fluxes%heat_content_lprec(i,j)
2660  if (associated(fluxes%heat_content_fprec)) res(i,j) = res(i,j) + fluxes%heat_content_fprec(i,j)
2661  if (associated(fluxes%heat_content_cond)) res(i,j) = res(i,j) + fluxes%heat_content_cond(i,j)
2662  enddo ; enddo
2663  call post_data(handles%id_hfrainds, res, diag)
2664  endif
2665 
2666  if ((handles%id_LwLatSens > 0) .and. associated(fluxes%lw) .and. &
2667  associated(fluxes%latent) .and. associated(fluxes%sens)) then
2668  do j=js,je ; do i=is,ie
2669  res(i,j) = (fluxes%lw(i,j) + fluxes%latent(i,j)) + fluxes%sens(i,j)
2670  enddo ; enddo
2671  call post_data(handles%id_LwLatSens, res, diag)
2672  endif
2673 
2674  if ((handles%id_total_LwLatSens > 0) .and. associated(fluxes%lw) .and. &
2675  associated(fluxes%latent) .and. associated(fluxes%sens)) then
2676  do j=js,je ; do i=is,ie
2677  res(i,j) = (fluxes%lw(i,j) + fluxes%latent(i,j)) + fluxes%sens(i,j)
2678  enddo ; enddo
2679  total_transport = global_area_integral(res, g, scale=us%QRZ_T_to_W_m2)
2680  call post_data(handles%id_total_LwLatSens, total_transport, diag)
2681  endif
2682 
2683  if ((handles%id_LwLatSens_ga > 0) .and. associated(fluxes%lw) .and. &
2684  associated(fluxes%latent) .and. associated(fluxes%sens)) then
2685  do j=js,je ; do i=is,ie
2686  res(i,j) = ((fluxes%lw(i,j) + fluxes%latent(i,j)) + fluxes%sens(i,j))
2687  enddo ; enddo
2688  ave_flux = global_area_mean(res, g, scale=us%QRZ_T_to_W_m2)
2689  call post_data(handles%id_LwLatSens_ga, ave_flux, diag)
2690  endif
2691 
2692  if ((handles%id_sw > 0) .and. associated(fluxes%sw)) then
2693  call post_data(handles%id_sw, fluxes%sw, diag)
2694  endif
2695  if ((handles%id_sw_vis > 0) .and. associated(fluxes%sw_vis_dir) .and. &
2696  associated(fluxes%sw_vis_dif)) then
2697  call post_data(handles%id_sw_vis, fluxes%sw_vis_dir+fluxes%sw_vis_dif, diag)
2698  endif
2699  if ((handles%id_sw_nir > 0) .and. associated(fluxes%sw_nir_dir) .and. &
2700  associated(fluxes%sw_nir_dif)) then
2701  call post_data(handles%id_sw_nir, fluxes%sw_nir_dir+fluxes%sw_nir_dif, diag)
2702  endif
2703  if ((handles%id_total_sw > 0) .and. associated(fluxes%sw)) then
2704  total_transport = global_area_integral(fluxes%sw, g, scale=us%QRZ_T_to_W_m2)
2705  call post_data(handles%id_total_sw, total_transport, diag)
2706  endif
2707  if ((handles%id_sw_ga > 0) .and. associated(fluxes%sw)) then
2708  ave_flux = global_area_mean(fluxes%sw, g, scale=us%QRZ_T_to_W_m2)
2709  call post_data(handles%id_sw_ga, ave_flux, diag)
2710  endif
2711 
2712  if ((handles%id_lw > 0) .and. associated(fluxes%lw)) then
2713  call post_data(handles%id_lw, fluxes%lw, diag)
2714  endif
2715  if ((handles%id_total_lw > 0) .and. associated(fluxes%lw)) then
2716  total_transport = global_area_integral(fluxes%lw, g, scale=us%QRZ_T_to_W_m2)
2717  call post_data(handles%id_total_lw, total_transport, diag)
2718  endif
2719  if ((handles%id_lw_ga > 0) .and. associated(fluxes%lw)) then
2720  ave_flux = global_area_mean(fluxes%lw, g, scale=us%QRZ_T_to_W_m2)
2721  call post_data(handles%id_lw_ga, ave_flux, diag)
2722  endif
2723 
2724  if ((handles%id_lat > 0) .and. associated(fluxes%latent)) then
2725  call post_data(handles%id_lat, fluxes%latent, diag)
2726  endif
2727  if ((handles%id_total_lat > 0) .and. associated(fluxes%latent)) then
2728  total_transport = global_area_integral(fluxes%latent, g, scale=us%QRZ_T_to_W_m2)
2729  call post_data(handles%id_total_lat, total_transport, diag)
2730  endif
2731  if ((handles%id_lat_ga > 0) .and. associated(fluxes%latent)) then
2732  ave_flux = global_area_mean(fluxes%latent, g, scale=us%QRZ_T_to_W_m2)
2733  call post_data(handles%id_lat_ga, ave_flux, diag)
2734  endif
2735 
2736  if ((handles%id_lat_evap > 0) .and. associated(fluxes%latent_evap_diag)) then
2737  call post_data(handles%id_lat_evap, fluxes%latent_evap_diag, diag)
2738  endif
2739  if ((handles%id_total_lat_evap > 0) .and. associated(fluxes%latent_evap_diag)) then
2740  total_transport = global_area_integral(fluxes%latent_evap_diag, g, scale=us%QRZ_T_to_W_m2)
2741  call post_data(handles%id_total_lat_evap, total_transport, diag)
2742  endif
2743 
2744  if ((handles%id_lat_fprec > 0) .and. associated(fluxes%latent_fprec_diag)) then
2745  call post_data(handles%id_lat_fprec, fluxes%latent_fprec_diag, diag)
2746  endif
2747  if ((handles%id_total_lat_fprec > 0) .and. associated(fluxes%latent_fprec_diag)) then
2748  total_transport = global_area_integral(fluxes%latent_fprec_diag, g, scale=us%QRZ_T_to_W_m2)
2749  call post_data(handles%id_total_lat_fprec, total_transport, diag)
2750  endif
2751 
2752  if ((handles%id_lat_frunoff > 0) .and. associated(fluxes%latent_frunoff_diag)) then
2753  call post_data(handles%id_lat_frunoff, fluxes%latent_frunoff_diag, diag)
2754  endif
2755  if (handles%id_total_lat_frunoff > 0 .and. associated(fluxes%latent_frunoff_diag)) then
2756  total_transport = global_area_integral(fluxes%latent_frunoff_diag, g, scale=us%QRZ_T_to_W_m2)
2757  call post_data(handles%id_total_lat_frunoff, total_transport, diag)
2758  endif
2759 
2760  if ((handles%id_sens > 0) .and. associated(fluxes%sens)) then
2761  call post_data(handles%id_sens, fluxes%sens, diag)
2762  endif
2763 
2764  if ((handles%id_seaice_melt_heat > 0) .and. associated(fluxes%seaice_melt_heat)) then
2765  call post_data(handles%id_seaice_melt_heat, fluxes%seaice_melt_heat, diag)
2766  endif
2767 
2768  if ((handles%id_total_seaice_melt_heat > 0) .and. associated(fluxes%seaice_melt_heat)) then
2769  total_transport = global_area_integral(fluxes%seaice_melt_heat, g, scale=us%QRZ_T_to_W_m2)
2770  call post_data(handles%id_total_seaice_melt_heat, total_transport, diag)
2771  endif
2772 
2773  if ((handles%id_total_sens > 0) .and. associated(fluxes%sens)) then
2774  total_transport = global_area_integral(fluxes%sens, g, scale=us%QRZ_T_to_W_m2)
2775  call post_data(handles%id_total_sens, total_transport, diag)
2776  endif
2777  if ((handles%id_sens_ga > 0) .and. associated(fluxes%sens)) then
2778  ave_flux = global_area_mean(fluxes%sens, g, scale=us%QRZ_T_to_W_m2)
2779  call post_data(handles%id_sens_ga, ave_flux, diag)
2780  endif
2781 
2782  if ((handles%id_heat_added > 0) .and. associated(fluxes%heat_added)) then
2783  call post_data(handles%id_heat_added, fluxes%heat_added, diag)
2784  endif
2785 
2786  if ((handles%id_total_heat_added > 0) .and. associated(fluxes%heat_added)) then
2787  total_transport = global_area_integral(fluxes%heat_added, g, scale=us%QRZ_T_to_W_m2)
2788  call post_data(handles%id_total_heat_added, total_transport, diag)
2789  endif
2790 
2791 
2792  ! post the diagnostics for boundary salt fluxes ==========================
2793 
2794  if ((handles%id_saltflux > 0) .and. associated(fluxes%salt_flux)) &
2795  call post_data(handles%id_saltflux, fluxes%salt_flux, diag)
2796  if ((handles%id_total_saltflux > 0) .and. associated(fluxes%salt_flux)) then
2797  total_transport = ppt2mks*global_area_integral(fluxes%salt_flux, g, scale=us%RZ_T_to_kg_m2s)
2798  call post_data(handles%id_total_saltflux, total_transport, diag)
2799  endif
2800 
2801  if ((handles%id_saltFluxAdded > 0) .and. associated(fluxes%salt_flux_added)) &
2802  call post_data(handles%id_saltFluxAdded, fluxes%salt_flux_added, diag)
2803  if ((handles%id_total_saltFluxAdded > 0) .and. associated(fluxes%salt_flux_added)) then
2804  total_transport = ppt2mks*global_area_integral(fluxes%salt_flux_added, g, scale=us%RZ_T_to_kg_m2s)
2805  call post_data(handles%id_total_saltFluxAdded, total_transport, diag)
2806  endif
2807 
2808  if (handles%id_saltFluxIn > 0 .and. associated(fluxes%salt_flux_in)) &
2809  call post_data(handles%id_saltFluxIn, fluxes%salt_flux_in, diag)
2810  if ((handles%id_total_saltFluxIn > 0) .and. associated(fluxes%salt_flux_in)) then
2811  total_transport = ppt2mks*global_area_integral(fluxes%salt_flux_in, g, scale=us%RZ_T_to_kg_m2s)
2812  call post_data(handles%id_total_saltFluxIn, total_transport, diag)
2813  endif
2814 
2815  if (handles%id_saltFluxGlobalAdj > 0) &
2816  call post_data(handles%id_saltFluxGlobalAdj, fluxes%saltFluxGlobalAdj, diag)
2817  if (handles%id_vPrecGlobalAdj > 0) &
2818  call post_data(handles%id_vPrecGlobalAdj, fluxes%vPrecGlobalAdj, diag)
2819  if (handles%id_netFWGlobalAdj > 0) &
2820  call post_data(handles%id_netFWGlobalAdj, fluxes%netFWGlobalAdj, diag)
2821  if (handles%id_saltFluxGlobalScl > 0) &
2822  call post_data(handles%id_saltFluxGlobalScl, fluxes%saltFluxGlobalScl, diag)
2823  if (handles%id_vPrecGlobalScl > 0) &
2824  call post_data(handles%id_vPrecGlobalScl, fluxes%vPrecGlobalScl, diag)
2825  if (handles%id_netFWGlobalScl > 0) &
2826  call post_data(handles%id_netFWGlobalScl, fluxes%netFWGlobalScl, diag)
2827 
2828 
2829  ! remaining boundary terms ==================================================
2830 
2831  if ((handles%id_psurf > 0) .and. associated(fluxes%p_surf)) &
2832  call post_data(handles%id_psurf, fluxes%p_surf, diag)
2833 
2834  if ((handles%id_TKE_tidal > 0) .and. associated(fluxes%TKE_tidal)) &
2835  call post_data(handles%id_TKE_tidal, fluxes%TKE_tidal, diag)
2836 
2837  if ((handles%id_buoy > 0) .and. associated(fluxes%buoy)) &
2838  call post_data(handles%id_buoy, fluxes%buoy, diag)
2839 
2840  if ((handles%id_ustar > 0) .and. associated(fluxes%ustar)) &
2841  call post_data(handles%id_ustar, fluxes%ustar, diag)
2842 
2843  if ((handles%id_ustar_berg > 0) .and. associated(fluxes%ustar_berg)) &
2844  call post_data(handles%id_ustar_berg, fluxes%ustar_berg, diag)
2845 
2846  if ((handles%id_frac_ice_cover > 0) .and. associated(fluxes%frac_shelf_h)) &
2847  call post_data(handles%id_frac_ice_cover, fluxes%frac_shelf_h, diag)
2848 
2849  if ((handles%id_ustar_ice_cover > 0) .and. associated(fluxes%ustar_shelf)) &
2850  call post_data(handles%id_ustar_ice_cover, fluxes%ustar_shelf, diag)
2851 
2852  ! endif ! query_averaging_enabled
2853  call disable_averaging(diag)
2854 
2855  if (turns /= 0) then
2856  call deallocate_forcing_type(fluxes)
2857  deallocate(fluxes)
2858  endif
2859 
2860  call cpu_clock_end(handles%id_clock_forcing)

◆ forcing_singlepointprint()

subroutine, public mom_forcing_type::forcing_singlepointprint ( type(forcing), intent(in)  fluxes,
type(ocean_grid_type), intent(in)  G,
integer, intent(in)  i,
integer, intent(in)  j,
character(len=*), intent(in)  mesg 
)

Write out values of the fluxes arrays at the i,j location. This is a debugging tool.

Parameters
[in]fluxesA structure containing thermodynamic forcing fields
[in]gGrid type
[in]mesgMessage
[in]ii-index
[in]jj-index

Definition at line 1172 of file MOM_forcing_type.F90.

1173  type(forcing), intent(in) :: fluxes !< A structure containing thermodynamic forcing fields
1174  type(ocean_grid_type), intent(in) :: G !< Grid type
1175  character(len=*), intent(in) :: mesg !< Message
1176  integer, intent(in) :: i !< i-index
1177  integer, intent(in) :: j !< j-index
1178 
1179  write(0,'(2a)') 'MOM_forcing_type, forcing_SinglePointPrint: Called from ',mesg
1180  write(0,'(a,2es15.3)') 'MOM_forcing_type, forcing_SinglePointPrint: lon,lat = ',g%geoLonT(i,j),g%geoLatT(i,j)
1181  call locmsg(fluxes%ustar,'ustar')
1182  call locmsg(fluxes%buoy,'buoy')
1183  call locmsg(fluxes%sw,'sw')
1184  call locmsg(fluxes%sw_vis_dir,'sw_vis_dir')
1185  call locmsg(fluxes%sw_vis_dif,'sw_vis_dif')
1186  call locmsg(fluxes%sw_nir_dir,'sw_nir_dir')
1187  call locmsg(fluxes%sw_nir_dif,'sw_nir_dif')
1188  call locmsg(fluxes%lw,'lw')
1189  call locmsg(fluxes%latent,'latent')
1190  call locmsg(fluxes%latent_evap_diag,'latent_evap_diag')
1191  call locmsg(fluxes%latent_fprec_diag,'latent_fprec_diag')
1192  call locmsg(fluxes%latent_frunoff_diag,'latent_frunoff_diag')
1193  call locmsg(fluxes%sens,'sens')
1194  call locmsg(fluxes%evap,'evap')
1195  call locmsg(fluxes%lprec,'lprec')
1196  call locmsg(fluxes%fprec,'fprec')
1197  call locmsg(fluxes%vprec,'vprec')
1198  call locmsg(fluxes%seaice_melt,'seaice_melt')
1199  call locmsg(fluxes%seaice_melt_heat,'seaice_melt_heat')
1200  call locmsg(fluxes%p_surf,'p_surf')
1201  call locmsg(fluxes%salt_flux,'salt_flux')
1202  call locmsg(fluxes%TKE_tidal,'TKE_tidal')
1203  call locmsg(fluxes%ustar_tidal,'ustar_tidal')
1204  call locmsg(fluxes%lrunoff,'lrunoff')
1205  call locmsg(fluxes%frunoff,'frunoff')
1206  call locmsg(fluxes%heat_content_lrunoff,'heat_content_lrunoff')
1207  call locmsg(fluxes%heat_content_frunoff,'heat_content_frunoff')
1208  call locmsg(fluxes%heat_content_lprec,'heat_content_lprec')
1209  call locmsg(fluxes%heat_content_fprec,'heat_content_fprec')
1210  call locmsg(fluxes%heat_content_icemelt,'heat_content_icemelt')
1211  call locmsg(fluxes%heat_content_vprec,'heat_content_vprec')
1212  call locmsg(fluxes%heat_content_cond,'heat_content_cond')
1213  call locmsg(fluxes%heat_content_cond,'heat_content_massout')
1214 
1215  contains
1216  !> Format and write a message depending on associated state of array
1217  subroutine locmsg(array,aname)
1218  real, dimension(:,:), pointer :: array !< Array to write element from
1219  character(len=*) :: aname !< Name of array
1220 
1221  if (associated(array)) then
1222  write(0,'(3a,es15.3)') 'MOM_forcing_type, forcing_SinglePointPrint: ',trim(aname),' = ',array(i,j)
1223  else
1224  write(0,'(4a)') 'MOM_forcing_type, forcing_SinglePointPrint: ',trim(aname),' is not associated.'
1225  endif
1226  end subroutine locmsg
1227 

◆ get_forcing_groups()

subroutine mom_forcing_type::get_forcing_groups ( type(forcing), intent(in)  fluxes,
logical, intent(out)  water,
logical, intent(out)  heat,
logical, intent(out)  ustar,
logical, intent(out)  press,
logical, intent(out)  shelf,
logical, intent(out)  iceberg,
logical, intent(out)  salt,
logical, intent(out)  heat_added,
logical, intent(out)  buoy 
)
private

Return flags indicating which groups of forcings are allocated.

Parameters
[in]fluxesReference flux fields
[out]waterTrue if fluxes contains water-based fluxes
[out]heatTrue if fluxes contains heat-based fluxes
[out]ustarTrue if fluxes contains ustar fluxes
[out]pressTrue if fluxes contains surface pressure
[out]shelfTrue if fluxes contains ice shelf fields
[out]icebergTrue if fluxes contains iceberg fluxes
[out]saltTrue if fluxes contains salt flux
[out]heat_addedTrue if fluxes contains explicit heat
[out]buoyTrue if fluxes contains buoyancy fluxes

Definition at line 3044 of file MOM_forcing_type.F90.

3046  type(forcing), intent(in) :: fluxes !< Reference flux fields
3047  logical, intent(out) :: water !< True if fluxes contains water-based fluxes
3048  logical, intent(out) :: heat !< True if fluxes contains heat-based fluxes
3049  logical, intent(out) :: ustar !< True if fluxes contains ustar fluxes
3050  logical, intent(out) :: press !< True if fluxes contains surface pressure
3051  logical, intent(out) :: shelf !< True if fluxes contains ice shelf fields
3052  logical, intent(out) :: iceberg !< True if fluxes contains iceberg fluxes
3053  logical, intent(out) :: salt !< True if fluxes contains salt flux
3054  logical, intent(out) :: heat_added !< True if fluxes contains explicit heat
3055  logical, intent(out) :: buoy !< True if fluxes contains buoyancy fluxes
3056 
3057  ! NOTE: heat, salt, heat_added, and buoy would typically depend on each other
3058  ! to some degree. But since this would be enforced at the driver level,
3059  ! we handle them here as independent flags.
3060 
3061  ustar = associated(fluxes%ustar) &
3062  .and. associated(fluxes%ustar_gustless)
3063  ! TODO: Check for all associated fields, but for now just check one as a marker
3064  water = associated(fluxes%evap)
3065  heat = associated(fluxes%seaice_melt_heat)
3066  salt = associated(fluxes%salt_flux)
3067  press = associated(fluxes%p_surf)
3068  shelf = associated(fluxes%frac_shelf_h)
3069  iceberg = associated(fluxes%ustar_berg)
3070  heat_added = associated(fluxes%heat_added)
3071  buoy = associated(fluxes%buoy)

◆ get_mech_forcing_groups()

subroutine mom_forcing_type::get_mech_forcing_groups ( type(mech_forcing), intent(in)  forces,
logical, intent(out)  stress,
logical, intent(out)  ustar,
logical, intent(out)  shelf,
logical, intent(out)  press,
logical, intent(out)  iceberg 
)
private

Return flags indicating which groups of mechanical forcings are allocated.

Parameters
[in]forcesReference forcing fields
[out]stressTrue if forces contains wind stress fields
[out]ustarTrue if forces contains ustar field
[out]shelfTrue if forces contains ice shelf fields
[out]pressTrue if forces contains pressure fields
[out]icebergTrue if forces contains iceberg fields

Definition at line 3076 of file MOM_forcing_type.F90.

3077  type(mech_forcing), intent(in) :: forces !< Reference forcing fields
3078  logical, intent(out) :: stress !< True if forces contains wind stress fields
3079  logical, intent(out) :: ustar !< True if forces contains ustar field
3080  logical, intent(out) :: shelf !< True if forces contains ice shelf fields
3081  logical, intent(out) :: press !< True if forces contains pressure fields
3082  logical, intent(out) :: iceberg !< True if forces contains iceberg fields
3083 
3084  stress = associated(forces%taux) &
3085  .and. associated(forces%tauy)
3086  ustar = associated(forces%ustar)
3087  shelf = associated(forces%rigidity_ice_u) &
3088  .and. associated(forces%rigidity_ice_v) &
3089  .and. associated(forces%frac_shelf_u) &
3090  .and. associated(forces%frac_shelf_v)
3091  press = associated(forces%p_surf) &
3092  .and. associated(forces%p_surf_full) &
3093  .and. associated(forces%net_mass_src)
3094  iceberg = associated(forces%area_berg) &
3095  .and. associated(forces%mass_berg)

◆ get_net_mass_forcing()

subroutine, public mom_forcing_type::get_net_mass_forcing ( type(forcing), intent(in)  fluxes,
type(ocean_grid_type), intent(in)  G,
type(unit_scale_type), intent(in)  US,
real, dimension( g %isd: g %ied, g %jsd: g %jed), intent(out)  net_mass_src 
)

This subroutine calculates determines the net mass source to the ocean from a (thermodynamic) forcing type and stores it in a provided array.

Parameters
[in]fluxesA structure containing thermodynamic forcing fields
[in]gThe ocean grid type
[in]usA dimensional unit scaling type
[out]net_mass_srcThe net mass flux of water into the ocean [kg m-2 s-1].

Definition at line 2158 of file MOM_forcing_type.F90.

2159  type(forcing), intent(in) :: fluxes !< A structure containing thermodynamic forcing fields
2160  type(ocean_grid_type), intent(in) :: G !< The ocean grid type
2161  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
2162  real, dimension(SZI_(G),SZJ_(G)), intent(out) :: net_mass_src !< The net mass flux of water into the ocean
2163  !! [kg m-2 s-1].
2164 
2165  real :: RZ_T_conversion ! A combination of scaling factors for mass fluxes [kg T m-2 s-1 R-1 Z-1 ~> 1]
2166  integer :: i, j, is, ie, js, je
2167  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
2168 
2169  rz_t_conversion = us%RZ_T_to_kg_m2s
2170 
2171  net_mass_src(:,:) = 0.0
2172  if (associated(fluxes%lprec)) then ; do j=js,je ; do i=is,ie
2173  net_mass_src(i,j) = net_mass_src(i,j) + rz_t_conversion*fluxes%lprec(i,j)
2174  enddo ; enddo ; endif
2175  if (associated(fluxes%fprec)) then ; do j=js,je ; do i=is,ie
2176  net_mass_src(i,j) = net_mass_src(i,j) + rz_t_conversion*fluxes%fprec(i,j)
2177  enddo ; enddo ; endif
2178  if (associated(fluxes%vprec)) then ; do j=js,je ; do i=is,ie
2179  net_mass_src(i,j) = net_mass_src(i,j) + rz_t_conversion*fluxes%vprec(i,j)
2180  enddo ; enddo ; endif
2181  if (associated(fluxes%lrunoff)) then ; do j=js,je ; do i=is,ie
2182  net_mass_src(i,j) = net_mass_src(i,j) + rz_t_conversion*fluxes%lrunoff(i,j)
2183  enddo ; enddo ; endif
2184  if (associated(fluxes%frunoff)) then ; do j=js,je ; do i=is,ie
2185  net_mass_src(i,j) = net_mass_src(i,j) + rz_t_conversion*fluxes%frunoff(i,j)
2186  enddo ; enddo ; endif
2187  if (associated(fluxes%evap)) then ; do j=js,je ; do i=is,ie
2188  net_mass_src(i,j) = net_mass_src(i,j) + rz_t_conversion*fluxes%evap(i,j)
2189  enddo ; enddo ; endif
2190  if (associated(fluxes%seaice_melt)) then ; do j=js,je ; do i=is,ie
2191  net_mass_src(i,j) = net_mass_src(i,j) + rz_t_conversion*fluxes%seaice_melt(i,j)
2192  enddo ; enddo ; endif
2193 

◆ mech_forcing_diags()

subroutine, public mom_forcing_type::mech_forcing_diags ( type(mech_forcing), intent(in), target  forces_in,
real, intent(in)  dt,
type(ocean_grid_type), intent(in)  G,
type(time_type), intent(in)  time_end,
type(diag_ctrl), intent(inout)  diag,
type(forcing_diags), intent(inout)  handles 
)

Offer mechanical forcing fields for diagnostics for those fields registered as part of register_forcing_type_diags.

Parameters
[in]forces_inmechanical forcing input fields
[in]dttime step for the forcing [s]
[in]ggrid type
[in]time_endThe end time of the diagnostic interval.
[in,out]diagdiagnostic type
[in,out]handlesdiagnostic id for diag_manager

Definition at line 2216 of file MOM_forcing_type.F90.

2217  type(mech_forcing), target, intent(in) :: forces_in !< mechanical forcing input fields
2218  real, intent(in) :: dt !< time step for the forcing [s]
2219  type(ocean_grid_type), intent(in) :: G !< grid type
2220  type(time_type), intent(in) :: time_end !< The end time of the diagnostic interval.
2221  type(diag_ctrl), intent(inout) :: diag !< diagnostic type
2222  type(forcing_diags), intent(inout) :: handles !< diagnostic id for diag_manager
2223 
2224  integer :: i,j,is,ie,js,je
2225 
2226  type(mech_forcing), pointer :: forces
2227  integer :: turns
2228 
2229  call cpu_clock_begin(handles%id_clock_forcing)
2230 
2231  ! NOTE: post_data expects data to be on the rotated index map, so any
2232  ! rotations must be applied before saving the output.
2233  turns = diag%G%HI%turns
2234  if (turns /= 0) then
2235  allocate(forces)
2236  call allocate_mech_forcing(forces_in, diag%G, forces)
2237  call rotate_mech_forcing(forces_in, turns, forces)
2238  else
2239  forces => forces_in
2240  endif
2241 
2242  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
2243  call enable_averaging(dt, time_end, diag)
2244  ! if (query_averaging_enabled(diag)) then
2245 
2246  if ((handles%id_taux > 0) .and. associated(forces%taux)) &
2247  call post_data(handles%id_taux, forces%taux, diag)
2248 
2249  if ((handles%id_tauy > 0) .and. associated(forces%tauy)) &
2250  call post_data(handles%id_tauy, forces%tauy, diag)
2251 
2252  if ((handles%id_mass_berg > 0) .and. associated(forces%mass_berg)) &
2253  call post_data(handles%id_mass_berg, forces%mass_berg, diag)
2254 
2255  if ((handles%id_area_berg > 0) .and. associated(forces%area_berg)) &
2256  call post_data(handles%id_area_berg, forces%area_berg, diag)
2257 
2258  ! endif
2259 
2260  call disable_averaging(diag)
2261 
2262  if (turns /= 0) then
2263  call deallocate_mech_forcing(forces)
2264  deallocate(forces)
2265  endif
2266 
2267  call cpu_clock_end(handles%id_clock_forcing)

◆ mech_forcing_singlepointprint()

subroutine mom_forcing_type::mech_forcing_singlepointprint ( type(mech_forcing), intent(in)  forces,
type(ocean_grid_type), intent(in)  G,
integer, intent(in)  i,
integer, intent(in)  j,
character(len=*), intent(in)  mesg 
)
private

Write out values of the mechanical forcing arrays at the i,j location. This is a debugging tool.

Parameters
[in]forcesA structure with the driving mechanical forces
[in]gGrid type
[in]mesgMessage
[in]ii-index
[in]jj-index

Definition at line 1144 of file MOM_forcing_type.F90.

1145  type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces
1146  type(ocean_grid_type), intent(in) :: G !< Grid type
1147  character(len=*), intent(in) :: mesg !< Message
1148  integer, intent(in) :: i !< i-index
1149  integer, intent(in) :: j !< j-index
1150 
1151  write(0,'(2a)') 'MOM_forcing_type, forcing_SinglePointPrint: Called from ',mesg
1152  write(0,'(a,2es15.3)') 'MOM_forcing_type, forcing_SinglePointPrint: lon,lat = ',g%geoLonT(i,j),g%geoLatT(i,j)
1153  call locmsg(forces%taux,'taux')
1154  call locmsg(forces%tauy,'tauy')
1155 
1156  contains
1157  !> Format and write a message depending on associated state of array
1158  subroutine locmsg(array,aname)
1159  real, dimension(:,:), pointer :: array !< Array to write element from
1160  character(len=*) :: aname !< Name of array
1161 
1162  if (associated(array)) then
1163  write(0,'(3a,es15.3)') 'MOM_forcing_type, mech_forcing_SinglePointPrint: ',trim(aname),' = ',array(i,j)
1164  else
1165  write(0,'(4a)') 'MOM_forcing_type, mech_forcing_SinglePointPrint: ',trim(aname),' is not associated.'
1166  endif
1167  end subroutine locmsg
1168 

◆ mom_forcing_chksum()

subroutine, public mom_forcing_type::mom_forcing_chksum ( character(len=*), intent(in)  mesg,
type(forcing), intent(in)  fluxes,
type(ocean_grid_type), intent(in)  G,
type(unit_scale_type), intent(in)  US,
integer, intent(in), optional  haloshift 
)

Write out chksums for thermodynamic fluxes.

Parameters
[in]mesgmessage
[in]fluxesA structure containing thermodynamic forcing fields
[in]ggrid type
[in]usA dimensional unit scaling type
[in]haloshiftshift in halo

Definition at line 1021 of file MOM_forcing_type.F90.

1022  character(len=*), intent(in) :: mesg !< message
1023  type(forcing), intent(in) :: fluxes !< A structure containing thermodynamic forcing fields
1024  type(ocean_grid_type), intent(in) :: G !< grid type
1025  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
1026  integer, optional, intent(in) :: haloshift !< shift in halo
1027 
1028  integer :: is, ie, js, je, nz, hshift
1029  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
1030 
1031  hshift = 1 ; if (present(haloshift)) hshift = haloshift
1032 
1033  ! Note that for the chksum calls to be useful for reproducing across PE
1034  ! counts, there must be no redundant points, so all variables use is..ie
1035  ! and js...je as their extent.
1036  if (associated(fluxes%ustar)) &
1037  call hchksum(fluxes%ustar, mesg//" fluxes%ustar", g%HI, haloshift=hshift, scale=us%Z_to_m*us%s_to_T)
1038  if (associated(fluxes%buoy)) &
1039  call hchksum(fluxes%buoy, mesg//" fluxes%buoy ", g%HI, haloshift=hshift, scale=us%L_to_m**2*us%s_to_T**3)
1040  if (associated(fluxes%sw)) &
1041  call hchksum(fluxes%sw, mesg//" fluxes%sw", g%HI, haloshift=hshift, scale=us%QRZ_T_to_W_m2)
1042  if (associated(fluxes%sw_vis_dir)) &
1043  call hchksum(fluxes%sw_vis_dir, mesg//" fluxes%sw_vis_dir", g%HI, haloshift=hshift, scale=us%QRZ_T_to_W_m2)
1044  if (associated(fluxes%sw_vis_dif)) &
1045  call hchksum(fluxes%sw_vis_dif, mesg//" fluxes%sw_vis_dif", g%HI, haloshift=hshift, scale=us%QRZ_T_to_W_m2)
1046  if (associated(fluxes%sw_nir_dir)) &
1047  call hchksum(fluxes%sw_nir_dir, mesg//" fluxes%sw_nir_dir", g%HI, haloshift=hshift, scale=us%QRZ_T_to_W_m2)
1048  if (associated(fluxes%sw_nir_dif)) &
1049  call hchksum(fluxes%sw_nir_dif, mesg//" fluxes%sw_nir_dif", g%HI, haloshift=hshift, scale=us%QRZ_T_to_W_m2)
1050  if (associated(fluxes%lw)) &
1051  call hchksum(fluxes%lw, mesg//" fluxes%lw", g%HI, haloshift=hshift, scale=us%QRZ_T_to_W_m2)
1052  if (associated(fluxes%latent)) &
1053  call hchksum(fluxes%latent, mesg//" fluxes%latent", g%HI, haloshift=hshift, scale=us%QRZ_T_to_W_m2)
1054  if (associated(fluxes%latent_evap_diag)) &
1055  call hchksum(fluxes%latent_evap_diag, mesg//" fluxes%latent_evap_diag", g%HI, &
1056  haloshift=hshift, scale=us%QRZ_T_to_W_m2)
1057  if (associated(fluxes%latent_fprec_diag)) &
1058  call hchksum(fluxes%latent_fprec_diag, mesg//" fluxes%latent_fprec_diag", g%HI, &
1059  haloshift=hshift, scale=us%QRZ_T_to_W_m2)
1060  if (associated(fluxes%latent_frunoff_diag)) &
1061  call hchksum(fluxes%latent_frunoff_diag, mesg//" fluxes%latent_frunoff_diag", g%HI, &
1062  haloshift=hshift, scale=us%QRZ_T_to_W_m2)
1063  if (associated(fluxes%sens)) &
1064  call hchksum(fluxes%sens, mesg//" fluxes%sens", g%HI, haloshift=hshift, scale=us%QRZ_T_to_W_m2)
1065  if (associated(fluxes%evap)) &
1066  call hchksum(fluxes%evap, mesg//" fluxes%evap", g%HI, haloshift=hshift, scale=us%RZ_T_to_kg_m2s)
1067  if (associated(fluxes%lprec)) &
1068  call hchksum(fluxes%lprec, mesg//" fluxes%lprec", g%HI, haloshift=hshift, scale=us%RZ_T_to_kg_m2s)
1069  if (associated(fluxes%fprec)) &
1070  call hchksum(fluxes%fprec, mesg//" fluxes%fprec", g%HI, haloshift=hshift, scale=us%RZ_T_to_kg_m2s)
1071  if (associated(fluxes%vprec)) &
1072  call hchksum(fluxes%vprec, mesg//" fluxes%vprec", g%HI, haloshift=hshift, scale=us%RZ_T_to_kg_m2s)
1073  if (associated(fluxes%seaice_melt)) &
1074  call hchksum(fluxes%seaice_melt, mesg//" fluxes%seaice_melt", g%HI, haloshift=hshift, scale=us%RZ_T_to_kg_m2s)
1075  if (associated(fluxes%seaice_melt_heat)) &
1076  call hchksum(fluxes%seaice_melt_heat, mesg//" fluxes%seaice_melt_heat", g%HI, &
1077  haloshift=hshift, scale=us%QRZ_T_to_W_m2)
1078  if (associated(fluxes%p_surf)) &
1079  call hchksum(fluxes%p_surf, mesg//" fluxes%p_surf", g%HI, haloshift=hshift , scale=us%RL2_T2_to_Pa)
1080  if (associated(fluxes%salt_flux)) &
1081  call hchksum(fluxes%salt_flux, mesg//" fluxes%salt_flux", g%HI, haloshift=hshift, scale=us%RZ_T_to_kg_m2s)
1082  if (associated(fluxes%TKE_tidal)) &
1083  call hchksum(fluxes%TKE_tidal, mesg//" fluxes%TKE_tidal", g%HI, haloshift=hshift, &
1084  scale=us%RZ3_T3_to_W_m2)
1085  if (associated(fluxes%ustar_tidal)) &
1086  call hchksum(fluxes%ustar_tidal, mesg//" fluxes%ustar_tidal", g%HI, haloshift=hshift, scale=us%Z_to_m*us%s_to_T)
1087  if (associated(fluxes%lrunoff)) &
1088  call hchksum(fluxes%lrunoff, mesg//" fluxes%lrunoff", g%HI, haloshift=hshift, scale=us%RZ_T_to_kg_m2s)
1089  if (associated(fluxes%frunoff)) &
1090  call hchksum(fluxes%frunoff, mesg//" fluxes%frunoff", g%HI, haloshift=hshift, scale=us%RZ_T_to_kg_m2s)
1091  if (associated(fluxes%heat_content_lrunoff)) &
1092  call hchksum(fluxes%heat_content_lrunoff, mesg//" fluxes%heat_content_lrunoff", g%HI, &
1093  haloshift=hshift, scale=us%RZ_T_to_kg_m2s)
1094  if (associated(fluxes%heat_content_frunoff)) &
1095  call hchksum(fluxes%heat_content_frunoff, mesg//" fluxes%heat_content_frunoff", g%HI, &
1096  haloshift=hshift, scale=us%QRZ_T_to_W_m2)
1097  if (associated(fluxes%heat_content_lprec)) &
1098  call hchksum(fluxes%heat_content_lprec, mesg//" fluxes%heat_content_lprec", g%HI, &
1099  haloshift=hshift, scale=us%QRZ_T_to_W_m2)
1100  if (associated(fluxes%heat_content_fprec)) &
1101  call hchksum(fluxes%heat_content_fprec, mesg//" fluxes%heat_content_fprec", g%HI, &
1102  haloshift=hshift, scale=us%QRZ_T_to_W_m2)
1103  if (associated(fluxes%heat_content_icemelt)) &
1104  call hchksum(fluxes%heat_content_icemelt, mesg//" fluxes%heat_content_icemelt", g%HI, &
1105  haloshift=hshift, scale=us%QRZ_T_to_W_m2)
1106  if (associated(fluxes%heat_content_cond)) &
1107  call hchksum(fluxes%heat_content_cond, mesg//" fluxes%heat_content_cond", g%HI, &
1108  haloshift=hshift, scale=us%QRZ_T_to_W_m2)
1109  if (associated(fluxes%heat_content_massout)) &
1110  call hchksum(fluxes%heat_content_massout, mesg//" fluxes%heat_content_massout", g%HI, &
1111  haloshift=hshift, scale=us%QRZ_T_to_W_m2)

◆ mom_mech_forcing_chksum()

subroutine, public mom_forcing_type::mom_mech_forcing_chksum ( character(len=*), intent(in)  mesg,
type(mech_forcing), intent(in)  forces,
type(ocean_grid_type), intent(in)  G,
type(unit_scale_type), intent(in)  US,
integer, intent(in), optional  haloshift 
)

Write out chksums for the driving mechanical forces.

Parameters
[in]mesgmessage
[in]forcesA structure with the driving mechanical forces
[in]ggrid type
[in]usA dimensional unit scaling type
[in]haloshiftshift in halo

Definition at line 1115 of file MOM_forcing_type.F90.

1116  character(len=*), intent(in) :: mesg !< message
1117  type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces
1118  type(ocean_grid_type), intent(in) :: G !< grid type
1119  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
1120  integer, optional, intent(in) :: haloshift !< shift in halo
1121 
1122  integer :: is, ie, js, je, nz, hshift
1123  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
1124 
1125  hshift=1; if (present(haloshift)) hshift=haloshift
1126 
1127  ! Note that for the chksum calls to be useful for reproducing across PE
1128  ! counts, there must be no redundant points, so all variables use is..ie
1129  ! and js...je as their extent.
1130  if (associated(forces%taux) .and. associated(forces%tauy)) &
1131  call uvchksum(mesg//" forces%tau[xy]", forces%taux, forces%tauy, g%HI, &
1132  haloshift=hshift, symmetric=.true., scale=us%RZ_T_to_kg_m2s*us%L_T_to_m_s)
1133  if (associated(forces%p_surf)) &
1134  call hchksum(forces%p_surf, mesg//" forces%p_surf", g%HI, haloshift=hshift, scale=us%RL2_T2_to_Pa)
1135  if (associated(forces%ustar)) &
1136  call hchksum(forces%ustar, mesg//" forces%ustar", g%HI, haloshift=hshift, scale=us%Z_to_m*us%s_to_T)
1137  if (associated(forces%rigidity_ice_u) .and. associated(forces%rigidity_ice_v)) &
1138  call uvchksum(mesg//" forces%rigidity_ice_[uv]", forces%rigidity_ice_u, forces%rigidity_ice_v, &
1139  g%HI, haloshift=hshift, symmetric=.true., scale=us%L_to_m**3*us%L_to_Z*us%s_to_T)
1140 

◆ myalloc()

subroutine mom_forcing_type::myalloc ( real, dimension(:,:), pointer  array,
integer, intent(in)  is,
integer, intent(in)  ie,
integer, intent(in)  js,
integer, intent(in)  je,
logical, intent(in), optional  flag 
)
private

Allocates and zeroes-out array.

Parameters
arrayArray to be allocated
[in]isStart i-index
[in]ieEnd i-index
[in]jsStart j-index
[in]jeEnd j-index
[in]flagFlag to indicate to allocate

Definition at line 3100 of file MOM_forcing_type.F90.

3101  real, dimension(:,:), pointer :: array !< Array to be allocated
3102  integer, intent(in) :: is !< Start i-index
3103  integer, intent(in) :: ie !< End i-index
3104  integer, intent(in) :: js !< Start j-index
3105  integer, intent(in) :: je !< End j-index
3106  logical, optional, intent(in) :: flag !< Flag to indicate to allocate
3107 
3108  if (present(flag)) then ; if (flag) then ; if (.not.associated(array)) then
3109  allocate(array(is:ie,js:je)) ; array(is:ie,js:je) = 0.0
3110  endif ; endif ; endif

◆ register_forcing_type_diags()

subroutine, public mom_forcing_type::register_forcing_type_diags ( type(time_type), intent(in)  Time,
type(diag_ctrl), intent(inout)  diag,
type(unit_scale_type), intent(in)  US,
logical, intent(in)  use_temperature,
type(forcing_diags), intent(inout)  handles,
logical, intent(in), optional  use_berg_fluxes 
)

Register members of the forcing type for diagnostics.

Parameters
[in]timetime type
[in,out]diagdiagnostic control type
[in]usA dimensional unit scaling type
[in]use_temperatureTrue if T/S are in use
[in,out]handleshandles for diagnostics
[in]use_berg_fluxesIf true, allow iceberg flux diagnostics

Definition at line 1232 of file MOM_forcing_type.F90.

1233  type(time_type), intent(in) :: Time !< time type
1234  type(diag_ctrl), intent(inout) :: diag !< diagnostic control type
1235  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
1236  logical, intent(in) :: use_temperature !< True if T/S are in use
1237  type(forcing_diags), intent(inout) :: handles !< handles for diagnostics
1238  logical, optional, intent(in) :: use_berg_fluxes !< If true, allow iceberg flux diagnostics
1239 
1240  ! Clock for forcing diagnostics
1241  handles%id_clock_forcing=cpu_clock_id('(Ocean forcing diagnostics)', grain=clock_routine)
1242 
1243 
1244  handles%id_taux = register_diag_field('ocean_model', 'taux', diag%axesCu1, time, &
1245  'Zonal surface stress from ocean interactions with atmos and ice', &
1246  'Pa', conversion=us%RZ_T_to_kg_m2s*us%L_T_to_m_s, &
1247  standard_name='surface_downward_x_stress', cmor_field_name='tauuo', &
1248  cmor_units='N m-2', cmor_long_name='Surface Downward X Stress', &
1249  cmor_standard_name='surface_downward_x_stress')
1250 
1251  handles%id_tauy = register_diag_field('ocean_model', 'tauy', diag%axesCv1, time, &
1252  'Meridional surface stress ocean interactions with atmos and ice', &
1253  'Pa', conversion=us%RZ_T_to_kg_m2s*us%L_T_to_m_s, &
1254  standard_name='surface_downward_y_stress', cmor_field_name='tauvo', &
1255  cmor_units='N m-2', cmor_long_name='Surface Downward Y Stress', &
1256  cmor_standard_name='surface_downward_y_stress')
1257 
1258  handles%id_ustar = register_diag_field('ocean_model', 'ustar', diag%axesT1, time, &
1259  'Surface friction velocity = [(gustiness + tau_magnitude)/rho0]^(1/2)', &
1260  'm s-1', conversion=us%Z_to_m*us%s_to_T)
1261 
1262  if (present(use_berg_fluxes)) then
1263  if (use_berg_fluxes) then
1264  handles%id_ustar_berg = register_diag_field('ocean_model', 'ustar_berg', diag%axesT1, time, &
1265  'Friction velocity below iceberg ', 'm s-1', conversion=us%Z_to_m*us%s_to_T)
1266 
1267  handles%id_area_berg = register_diag_field('ocean_model', 'area_berg', diag%axesT1, time, &
1268  'Area of grid cell covered by iceberg ', 'm2 m-2')
1269 
1270  handles%id_mass_berg = register_diag_field('ocean_model', 'mass_berg', diag%axesT1, time, &
1271  'Mass of icebergs ', 'kg m-2', conversion=us%RZ_to_kg_m2)
1272 
1273  handles%id_ustar_ice_cover = register_diag_field('ocean_model', 'ustar_ice_cover', diag%axesT1, time, &
1274  'Friction velocity below iceberg and ice shelf together', 'm s-1', conversion=us%Z_to_m*us%s_to_T)
1275 
1276  handles%id_frac_ice_cover = register_diag_field('ocean_model', 'frac_ice_cover', diag%axesT1, time, &
1277  'Area of grid cell below iceberg and ice shelf together ', 'm2 m-2')
1278  endif
1279  endif
1280 
1281  handles%id_psurf = register_diag_field('ocean_model', 'p_surf', diag%axesT1, time, &
1282  'Pressure at ice-ocean or atmosphere-ocean interface', &
1283  'Pa', conversion=us%RL2_T2_to_Pa, cmor_field_name='pso', &
1284  cmor_long_name='Sea Water Pressure at Sea Water Surface', &
1285  cmor_standard_name='sea_water_pressure_at_sea_water_surface')
1286 
1287  handles%id_TKE_tidal = register_diag_field('ocean_model', 'TKE_tidal', diag%axesT1, time, &
1288  'Tidal source of BBL mixing', 'W m-2', conversion=us%RZ3_T3_to_W_m2)
1289 
1290  if (.not. use_temperature) then
1291  handles%id_buoy = register_diag_field('ocean_model', 'buoy', diag%axesT1, time, &
1292  'Buoyancy forcing', 'm2 s-3', conversion=us%L_to_m**2*us%s_to_T**3)
1293  return
1294  endif
1295 
1296 
1297  !===============================================================
1298  ! surface mass flux maps
1299 
1300  handles%id_prcme = register_diag_field('ocean_model', 'PRCmE', diag%axesT1, time, &
1301  'Net surface water flux (precip+melt+lrunoff+ice calving-evap)', 'kg m-2 s-1', &
1302  standard_name='water_flux_into_sea_water', cmor_field_name='wfo', &
1303  cmor_standard_name='water_flux_into_sea_water',cmor_long_name='Water Flux Into Sea Water')
1304  ! This diagnostic is rescaled to MKS units when combined.
1305 
1306  handles%id_evap = register_diag_field('ocean_model', 'evap', diag%axesT1, time, &
1307  'Evaporation/condensation at ocean surface (evaporation is negative)', &
1308  'kg m-2 s-1', conversion=us%RZ_T_to_kg_m2s, &
1309  standard_name='water_evaporation_flux', cmor_field_name='evs', &
1310  cmor_standard_name='water_evaporation_flux', &
1311  cmor_long_name='Water Evaporation Flux Where Ice Free Ocean over Sea')
1312 
1313  ! smg: seaice_melt field requires updates to the sea ice model
1314  handles%id_seaice_melt = register_diag_field('ocean_model', 'seaice_melt', &
1315  diag%axesT1, time, 'water flux to ocean from snow/sea ice melting(> 0) or formation(< 0)', &
1316  'kg m-2 s-1', conversion=us%RZ_T_to_kg_m2s, &
1317  standard_name='water_flux_into_sea_water_due_to_sea_ice_thermodynamics', &
1318  cmor_field_name='fsitherm', &
1319  cmor_standard_name='water_flux_into_sea_water_due_to_sea_ice_thermodynamics',&
1320  cmor_long_name='water flux to ocean from sea ice melt(> 0) or form(< 0)')
1321 
1322  handles%id_precip = register_diag_field('ocean_model', 'precip', diag%axesT1, time, &
1323  'Liquid + frozen precipitation into ocean', 'kg m-2 s-1')
1324  ! This diagnostic is rescaled to MKS units when combined.
1325 
1326  handles%id_fprec = register_diag_field('ocean_model', 'fprec', diag%axesT1, time, &
1327  'Frozen precipitation into ocean', &
1328  units='kg m-2 s-1', conversion=us%RZ_T_to_kg_m2s, &
1329  standard_name='snowfall_flux', cmor_field_name='prsn', &
1330  cmor_standard_name='snowfall_flux', cmor_long_name='Snowfall Flux where Ice Free Ocean over Sea')
1331 
1332  handles%id_lprec = register_diag_field('ocean_model', 'lprec', diag%axesT1, time, &
1333  'Liquid precipitation into ocean', &
1334  units='kg m-2 s-1', conversion=us%RZ_T_to_kg_m2s, &
1335  standard_name='rainfall_flux', &
1336  cmor_field_name='prlq', cmor_standard_name='rainfall_flux', &
1337  cmor_long_name='Rainfall Flux where Ice Free Ocean over Sea')
1338 
1339  handles%id_vprec = register_diag_field('ocean_model', 'vprec', diag%axesT1, time, &
1340  'Virtual liquid precip into ocean due to SSS restoring', &
1341  units='kg m-2 s-1', conversion=us%RZ_T_to_kg_m2s)
1342 
1343  handles%id_frunoff = register_diag_field('ocean_model', 'frunoff', diag%axesT1, time, &
1344  'Frozen runoff (calving) and iceberg melt into ocean', &
1345  units='kg m-2 s-1', conversion=us%RZ_T_to_kg_m2s, &
1346  standard_name='water_flux_into_sea_water_from_icebergs', &
1347  cmor_field_name='ficeberg', &
1348  cmor_standard_name='water_flux_into_sea_water_from_icebergs', &
1349  cmor_long_name='Water Flux into Seawater from Icebergs')
1350 
1351  handles%id_lrunoff = register_diag_field('ocean_model', 'lrunoff', diag%axesT1, time, &
1352  'Liquid runoff (rivers) into ocean', &
1353  units='kg m-2 s-1', conversion=us%RZ_T_to_kg_m2s, &
1354  standard_name='water_flux_into_sea_water_from_rivers', cmor_field_name='friver', &
1355  cmor_standard_name='water_flux_into_sea_water_from_rivers', &
1356  cmor_long_name='Water Flux into Sea Water From Rivers')
1357 
1358  handles%id_net_massout = register_diag_field('ocean_model', 'net_massout', diag%axesT1, time, &
1359  'Net mass leaving the ocean due to evaporation, seaice formation', 'kg m-2 s-1')
1360  ! This diagnostic is rescaled to MKS units when combined.
1361 
1362  handles%id_net_massin = register_diag_field('ocean_model', 'net_massin', diag%axesT1, time, &
1363  'Net mass entering ocean due to precip, runoff, ice melt', 'kg m-2 s-1')
1364  ! This diagnostic is rescaled to MKS units when combined.
1365 
1366  handles%id_massout_flux = register_diag_field('ocean_model', 'massout_flux', diag%axesT1, time, &
1367  'Net mass flux of freshwater out of the ocean (used in the boundary flux calculation)', &
1368  'kg m-2', conversion=diag%GV%H_to_kg_m2)
1369  ! This diagnostic is calculated in MKS units.
1370 
1371  handles%id_massin_flux = register_diag_field('ocean_model', 'massin_flux', diag%axesT1, time, &
1372  'Net mass flux of freshwater into the ocean (used in boundary flux calculation)', 'kg m-2')
1373  ! This diagnostic is calculated in MKS units.
1374 
1375  !=========================================================================
1376  ! area integrated surface mass transport, all are rescaled to MKS units before area integration.
1377 
1378  handles%id_total_prcme = register_scalar_field('ocean_model', 'total_PRCmE', time, diag, &
1379  long_name='Area integrated net surface water flux (precip+melt+liq runoff+ice calving-evap)',&
1380  units='kg s-1', standard_name='water_flux_into_sea_water_area_integrated', &
1381  cmor_field_name='total_wfo', &
1382  cmor_standard_name='water_flux_into_sea_water_area_integrated', &
1383  cmor_long_name='Water Transport Into Sea Water Area Integrated')
1384 
1385  handles%id_total_evap = register_scalar_field('ocean_model', 'total_evap', time, diag,&
1386  long_name='Area integrated evap/condense at ocean surface', &
1387  units='kg s-1', standard_name='water_evaporation_flux_area_integrated', &
1388  cmor_field_name='total_evs', &
1389  cmor_standard_name='water_evaporation_flux_area_integrated', &
1390  cmor_long_name='Evaporation Where Ice Free Ocean over Sea Area Integrated')
1391 
1392  ! seaice_melt field requires updates to the sea ice model
1393  handles%id_total_seaice_melt = register_scalar_field('ocean_model', 'total_icemelt', time, diag, &
1394  long_name='Area integrated sea ice melt (>0) or form (<0)', units='kg s-1', &
1395  standard_name='water_flux_into_sea_water_due_to_sea_ice_thermodynamics_area_integrated', &
1396  cmor_field_name='total_fsitherm', &
1397  cmor_standard_name='water_flux_into_sea_water_due_to_sea_ice_thermodynamics_area_integrated', &
1398  cmor_long_name='Water Melt/Form from Sea Ice Area Integrated')
1399 
1400  handles%id_total_precip = register_scalar_field('ocean_model', 'total_precip', time, diag, &
1401  long_name='Area integrated liquid+frozen precip into ocean', units='kg s-1')
1402 
1403  handles%id_total_fprec = register_scalar_field('ocean_model', 'total_fprec', time, diag,&
1404  long_name='Area integrated frozen precip into ocean', units='kg s-1', &
1405  standard_name='snowfall_flux_area_integrated', &
1406  cmor_field_name='total_prsn', &
1407  cmor_standard_name='snowfall_flux_area_integrated', &
1408  cmor_long_name='Snowfall Flux where Ice Free Ocean over Sea Area Integrated')
1409 
1410  handles%id_total_lprec = register_scalar_field('ocean_model', 'total_lprec', time, diag,&
1411  long_name='Area integrated liquid precip into ocean', units='kg s-1', &
1412  standard_name='rainfall_flux_area_integrated', &
1413  cmor_field_name='total_pr', &
1414  cmor_standard_name='rainfall_flux_area_integrated', &
1415  cmor_long_name='Rainfall Flux where Ice Free Ocean over Sea Area Integrated')
1416 
1417  handles%id_total_vprec = register_scalar_field('ocean_model', 'total_vprec', time, diag, &
1418  long_name='Area integrated virtual liquid precip due to SSS restoring', units='kg s-1')
1419 
1420  handles%id_total_frunoff = register_scalar_field('ocean_model', 'total_frunoff', time, diag, &
1421  long_name='Area integrated frozen runoff (calving) & iceberg melt into ocean', units='kg s-1',&
1422  cmor_field_name='total_ficeberg', &
1423  cmor_standard_name='water_flux_into_sea_water_from_icebergs_area_integrated', &
1424  cmor_long_name='Water Flux into Seawater from Icebergs Area Integrated')
1425 
1426  handles%id_total_lrunoff = register_scalar_field('ocean_model', 'total_lrunoff', time, diag,&
1427  long_name='Area integrated liquid runoff into ocean', units='kg s-1', &
1428  cmor_field_name='total_friver', &
1429  cmor_standard_name='water_flux_into_sea_water_from_rivers_area_integrated', &
1430  cmor_long_name='Water Flux into Sea Water From Rivers Area Integrated')
1431 
1432  handles%id_total_net_massout = register_scalar_field('ocean_model', 'total_net_massout', time, diag, &
1433  long_name='Area integrated mass leaving ocean due to evap and seaice form', units='kg s-1')
1434 
1435  handles%id_total_net_massin = register_scalar_field('ocean_model', 'total_net_massin', time, diag, &
1436  long_name='Area integrated mass entering ocean due to predip, runoff, ice melt', units='kg s-1')
1437 
1438  !=========================================================================
1439  ! area averaged surface mass transport
1440 
1441  handles%id_prcme_ga = register_scalar_field('ocean_model', 'PRCmE_ga', time, diag, &
1442  long_name='Area averaged net surface water flux (precip+melt+liq runoff+ice calving-evap)',&
1443  units='kg m-2 s-1', standard_name='water_flux_into_sea_water_area_averaged', &
1444  cmor_field_name='ave_wfo', &
1445  cmor_standard_name='rainfall_flux_area_averaged', &
1446  cmor_long_name='Water Transport Into Sea Water Area Averaged')
1447 
1448  handles%id_evap_ga = register_scalar_field('ocean_model', 'evap_ga', time, diag,&
1449  long_name='Area averaged evap/condense at ocean surface', &
1450  units='kg m-2 s-1', standard_name='water_evaporation_flux_area_averaged', &
1451  cmor_field_name='ave_evs', &
1452  cmor_standard_name='water_evaporation_flux_area_averaged', &
1453  cmor_long_name='Evaporation Where Ice Free Ocean over Sea Area Averaged')
1454 
1455  handles%id_lprec_ga = register_scalar_field('ocean_model', 'lprec_ga', time, diag,&
1456  long_name='Area integrated liquid precip into ocean', units='kg m-2 s-1', &
1457  standard_name='rainfall_flux_area_averaged', &
1458  cmor_field_name='ave_pr', &
1459  cmor_standard_name='rainfall_flux_area_averaged', &
1460  cmor_long_name='Rainfall Flux where Ice Free Ocean over Sea Area Averaged')
1461 
1462  handles%id_fprec_ga = register_scalar_field('ocean_model', 'fprec_ga', time, diag,&
1463  long_name='Area integrated frozen precip into ocean', units='kg m-2 s-1', &
1464  standard_name='snowfall_flux_area_averaged', &
1465  cmor_field_name='ave_prsn', &
1466  cmor_standard_name='snowfall_flux_area_averaged', &
1467  cmor_long_name='Snowfall Flux where Ice Free Ocean over Sea Area Averaged')
1468 
1469  handles%id_precip_ga = register_scalar_field('ocean_model', 'precip_ga', time, diag, &
1470  long_name='Area averaged liquid+frozen precip into ocean', units='kg m-2 s-1')
1471 
1472  handles%id_vprec_ga = register_scalar_field('ocean_model', 'vrec_ga', time, diag, &
1473  long_name='Area averaged virtual liquid precip due to SSS restoring', units='kg m-2 s-1')
1474 
1475  !===============================================================
1476  ! surface heat flux maps
1477 
1478  handles%id_heat_content_frunoff = register_diag_field('ocean_model', 'heat_content_frunoff', &
1479  diag%axesT1, time, 'Heat content (relative to 0C) of solid runoff into ocean', &
1480  'W m-2', conversion=us%QRZ_T_to_W_m2, &
1481  standard_name='temperature_flux_due_to_solid_runoff_expressed_as_heat_flux_into_sea_water')
1482 
1483  handles%id_heat_content_lrunoff = register_diag_field('ocean_model', 'heat_content_lrunoff', &
1484  diag%axesT1, time, 'Heat content (relative to 0C) of liquid runoff into ocean', &
1485  'W m-2', conversion=us%QRZ_T_to_W_m2, &
1486  standard_name='temperature_flux_due_to_runoff_expressed_as_heat_flux_into_sea_water')
1487 
1488  handles%id_hfrunoffds = register_diag_field('ocean_model', 'hfrunoffds', &
1489  diag%axesT1, time, 'Heat content (relative to 0C) of liquid+solid runoff into ocean', &
1490  'W m-2', conversion=us%QRZ_T_to_W_m2, &
1491  standard_name='temperature_flux_due_to_runoff_expressed_as_heat_flux_into_sea_water')
1492 
1493  handles%id_heat_content_lprec = register_diag_field('ocean_model', 'heat_content_lprec', &
1494  diag%axesT1,time,'Heat content (relative to 0degC) of liquid precip entering ocean', &
1495  'W m-2', conversion=us%QRZ_T_to_W_m2)
1496 
1497  handles%id_heat_content_fprec = register_diag_field('ocean_model', 'heat_content_fprec',&
1498  diag%axesT1,time,'Heat content (relative to 0degC) of frozen prec entering ocean',&
1499  'W m-2', conversion=us%QRZ_T_to_W_m2)
1500 
1501  handles%id_heat_content_icemelt = register_diag_field('ocean_model', 'heat_content_icemelt',&
1502  diag%axesT1,time,'Heat content (relative to 0degC) of water flux due to sea ice melting/freezing',&
1503  'W m-2', conversion=us%QRZ_T_to_W_m2)
1504 
1505  handles%id_heat_content_vprec = register_diag_field('ocean_model', 'heat_content_vprec', &
1506  diag%axesT1,time,'Heat content (relative to 0degC) of virtual precip entering ocean',&
1507  'W m-2', conversion=us%QRZ_T_to_W_m2)
1508 
1509  handles%id_heat_content_cond = register_diag_field('ocean_model', 'heat_content_cond', &
1510  diag%axesT1,time,'Heat content (relative to 0degC) of water condensing into ocean',&
1511  'W m-2', conversion=us%QRZ_T_to_W_m2)
1512 
1513  handles%id_hfrainds = register_diag_field('ocean_model', 'hfrainds', &
1514  diag%axesT1,time,'Heat content (relative to 0degC) of liquid+frozen precip entering ocean', &
1515  'W m-2', conversion=us%QRZ_T_to_W_m2, &
1516  standard_name='temperature_flux_due_to_rainfall_expressed_as_heat_flux_into_sea_water',&
1517  cmor_long_name='Heat Content (relative to 0degC) of Liquid + Frozen Precipitation')
1518 
1519  handles%id_heat_content_surfwater = register_diag_field('ocean_model', 'heat_content_surfwater',&
1520  diag%axesT1, time, &
1521  'Heat content (relative to 0degC) of net water crossing ocean surface (frozen+liquid)', &
1522  'W m-2', conversion=us%QRZ_T_to_W_m2)
1523 
1524  handles%id_heat_content_massout = register_diag_field('ocean_model', 'heat_content_massout', &
1525  diag%axesT1, time,'Heat content (relative to 0degC) of net mass leaving ocean ocean via evap and ice form',&
1526  'W m-2', conversion=us%QRZ_T_to_W_m2, &
1527  cmor_field_name='hfevapds', &
1528  cmor_standard_name='temperature_flux_due_to_evaporation_expressed_as_heat_flux_out_of_sea_water', &
1529  cmor_long_name='Heat Content (relative to 0degC) of Water Leaving Ocean via Evaporation and Ice Formation')
1530 
1531  handles%id_heat_content_massin = register_diag_field('ocean_model', 'heat_content_massin', &
1532  diag%axesT1, time,'Heat content (relative to 0degC) of net mass entering ocean ocean',&
1533  'W m-2', conversion=us%QRZ_T_to_W_m2)
1534 
1535  handles%id_net_heat_coupler = register_diag_field('ocean_model', 'net_heat_coupler', &
1536  diag%axesT1,time,'Surface ocean heat flux from SW+LW+latent+sensible+seaice_melt_heat (via the coupler)',&
1537  'W m-2', conversion=us%QRZ_T_to_W_m2)
1538 
1539  handles%id_net_heat_surface = register_diag_field('ocean_model', 'net_heat_surface',diag%axesT1, time, &
1540  'Surface ocean heat flux from SW+LW+lat+sens+mass transfer+frazil+restore+seaice_melt_heat or '// &
1541  'flux adjustments', &
1542  'W m-2', conversion=us%QRZ_T_to_W_m2, &
1543  standard_name='surface_downward_heat_flux_in_sea_water', cmor_field_name='hfds', &
1544  cmor_standard_name='surface_downward_heat_flux_in_sea_water', &
1545  cmor_long_name='Surface ocean heat flux from SW+LW+latent+sensible+masstransfer+frazil+seaice_melt_heat')
1546 
1547  handles%id_sw = register_diag_field('ocean_model', 'SW', diag%axesT1, time, &
1548  'Shortwave radiation flux into ocean', 'W m-2', conversion=us%QRZ_T_to_W_m2, &
1549  standard_name='net_downward_shortwave_flux_at_sea_water_surface', &
1550  cmor_field_name='rsntds', &
1551  cmor_standard_name='net_downward_shortwave_flux_at_sea_water_surface', &
1552  cmor_long_name='Net Downward Shortwave Radiation at Sea Water Surface')
1553  handles%id_sw_vis = register_diag_field('ocean_model', 'sw_vis', diag%axesT1, time, &
1554  'Shortwave radiation direct and diffuse flux into the ocean in the visible band', &
1555  'W m-2', conversion=us%QRZ_T_to_W_m2)
1556  handles%id_sw_nir = register_diag_field('ocean_model', 'sw_nir', diag%axesT1, time, &
1557  'Shortwave radiation direct and diffuse flux into the ocean in the near-infrared band', &
1558  'W m-2', conversion=us%QRZ_T_to_W_m2)
1559 
1560  handles%id_LwLatSens = register_diag_field('ocean_model', 'LwLatSens', diag%axesT1, time, &
1561  'Combined longwave, latent, and sensible heating at ocean surface', 'W m-2', conversion=us%QRZ_T_to_W_m2)
1562 
1563  handles%id_lw = register_diag_field('ocean_model', 'LW', diag%axesT1, time, &
1564  'Longwave radiation flux into ocean', 'W m-2', conversion=us%QRZ_T_to_W_m2, &
1565  standard_name='surface_net_downward_longwave_flux', &
1566  cmor_field_name='rlntds', &
1567  cmor_standard_name='surface_net_downward_longwave_flux', &
1568  cmor_long_name='Surface Net Downward Longwave Radiation')
1569 
1570  handles%id_lat = register_diag_field('ocean_model', 'latent', diag%axesT1, time, &
1571  'Latent heat flux into ocean due to fusion and evaporation (negative means ocean heat loss)', &
1572  'W m-2', conversion=us%QRZ_T_to_W_m2, cmor_field_name='hflso', &
1573  cmor_standard_name='surface_downward_latent_heat_flux', &
1574  cmor_long_name='Surface Downward Latent Heat Flux due to Evap + Melt Snow/Ice')
1575 
1576  handles%id_lat_evap = register_diag_field('ocean_model', 'latent_evap', diag%axesT1, time, &
1577  'Latent heat flux into ocean due to evaporation/condensation', 'W m-2', conversion=us%QRZ_T_to_W_m2)
1578 
1579  handles%id_lat_fprec = register_diag_field('ocean_model', 'latent_fprec_diag', diag%axesT1, time,&
1580  'Latent heat flux into ocean due to melting of frozen precipitation', 'W m-2', conversion=us%QRZ_T_to_W_m2, &
1581  cmor_field_name='hfsnthermds', &
1582  cmor_standard_name='heat_flux_into_sea_water_due_to_snow_thermodynamics', &
1583  cmor_long_name='Latent Heat to Melt Frozen Precipitation')
1584 
1585  handles%id_lat_frunoff = register_diag_field('ocean_model', 'latent_frunoff', diag%axesT1, time, &
1586  'Latent heat flux into ocean due to melting of icebergs', 'W m-2', conversion=us%QRZ_T_to_W_m2, &
1587  cmor_field_name='hfibthermds', &
1588  cmor_standard_name='heat_flux_into_sea_water_due_to_iceberg_thermodynamics', &
1589  cmor_long_name='Latent Heat to Melt Frozen Runoff/Iceberg')
1590 
1591  handles%id_sens = register_diag_field('ocean_model', 'sensible', diag%axesT1, time, &
1592  'Sensible heat flux into ocean', 'W m-2', conversion=us%QRZ_T_to_W_m2, &
1593  standard_name='surface_downward_sensible_heat_flux', &
1594  cmor_field_name='hfsso', &
1595  cmor_standard_name='surface_downward_sensible_heat_flux', &
1596  cmor_long_name='Surface Downward Sensible Heat Flux')
1597 
1598  handles%id_seaice_melt_heat = register_diag_field('ocean_model', 'seaice_melt_heat', diag%axesT1, time,&
1599  'Heat flux into ocean due to snow and sea ice melt/freeze', 'W m-2', conversion=us%QRZ_T_to_W_m2, &
1600  standard_name='snow_ice_melt_heat_flux', &
1601  !GMM TODO cmor_field_name='hfsso', &
1602  cmor_standard_name='snow_ice_melt_heat_flux', &
1603  cmor_long_name='Heat flux into ocean from snow and sea ice melt')
1604 
1605  handles%id_heat_added = register_diag_field('ocean_model', 'heat_added', diag%axesT1, time, &
1606  'Flux Adjustment or restoring surface heat flux into ocean', 'W m-2', conversion=us%QRZ_T_to_W_m2)
1607 
1608 
1609  !===============================================================
1610  ! area integrated surface heat fluxes
1611 
1612  handles%id_total_heat_content_frunoff = register_scalar_field('ocean_model', &
1613  'total_heat_content_frunoff', time, diag, &
1614  long_name='Area integrated heat content (relative to 0C) of solid runoff', &
1615  units='W', cmor_field_name='total_hfsolidrunoffds', &
1616  cmor_standard_name= &
1617  'temperature_flux_due_to_solid_runoff_expressed_as_heat_flux_into_sea_water_area_integrated',&
1618  cmor_long_name= &
1619  'Temperature Flux due to Solid Runoff Expressed as Heat Flux into Sea Water Area Integrated')
1620 
1621  handles%id_total_heat_content_lrunoff = register_scalar_field('ocean_model', &
1622  'total_heat_content_lrunoff', time, diag, &
1623  long_name='Area integrated heat content (relative to 0C) of liquid runoff', &
1624  units='W', cmor_field_name='total_hfrunoffds', &
1625  cmor_standard_name= &
1626  'temperature_flux_due_to_runoff_expressed_as_heat_flux_into_sea_water_area_integrated',&
1627  cmor_long_name= &
1628  'Temperature Flux due to Runoff Expressed as Heat Flux into Sea Water Area Integrated')
1629 
1630  handles%id_total_heat_content_lprec = register_scalar_field('ocean_model', &
1631  'total_heat_content_lprec', time, diag, &
1632  long_name='Area integrated heat content (relative to 0C) of liquid precip', &
1633  units='W', cmor_field_name='total_hfrainds', &
1634  cmor_standard_name= &
1635  'temperature_flux_due_to_rainfall_expressed_as_heat_flux_into_sea_water_area_integrated',&
1636  cmor_long_name= &
1637  'Temperature Flux due to Rainfall Expressed as Heat Flux into Sea Water Area Integrated')
1638 
1639  handles%id_total_heat_content_fprec = register_scalar_field('ocean_model', &
1640  'total_heat_content_fprec', time, diag, &
1641  long_name='Area integrated heat content (relative to 0C) of frozen precip',&
1642  units='W')
1643 
1644  handles%id_total_heat_content_icemelt = register_scalar_field('ocean_model', &
1645  'total_heat_content_icemelt', time, diag,long_name= &
1646  'Area integrated heat content (relative to 0C) of water flux due sea ice melting/freezing', &
1647  units='W')
1648 
1649  handles%id_total_heat_content_vprec = register_scalar_field('ocean_model', &
1650  'total_heat_content_vprec', time, diag, &
1651  long_name='Area integrated heat content (relative to 0C) of virtual precip',&
1652  units='W')
1653 
1654  handles%id_total_heat_content_cond = register_scalar_field('ocean_model', &
1655  'total_heat_content_cond', time, diag, &
1656  long_name='Area integrated heat content (relative to 0C) of condensate',&
1657  units='W')
1658 
1659  handles%id_total_heat_content_surfwater = register_scalar_field('ocean_model', &
1660  'total_heat_content_surfwater', time, diag, &
1661  long_name='Area integrated heat content (relative to 0C) of water crossing surface',&
1662  units='W')
1663 
1664  handles%id_total_heat_content_massout = register_scalar_field('ocean_model', &
1665  'total_heat_content_massout', time, diag, &
1666  long_name='Area integrated heat content (relative to 0C) of water leaving ocean', &
1667  units='W', &
1668  cmor_field_name='total_hfevapds', &
1669  cmor_standard_name= &
1670  'temperature_flux_due_to_evaporation_expressed_as_heat_flux_out_of_sea_water_area_integrated',&
1671  cmor_long_name='Heat Flux Out of Sea Water due to Evaporating Water Area Integrated')
1672 
1673  handles%id_total_heat_content_massin = register_scalar_field('ocean_model', &
1674  'total_heat_content_massin', time, diag, &
1675  long_name='Area integrated heat content (relative to 0C) of water entering ocean',&
1676  units='W')
1677 
1678  handles%id_total_net_heat_coupler = register_scalar_field('ocean_model', &
1679  'total_net_heat_coupler', time, diag, &
1680  long_name='Area integrated surface heat flux from SW+LW+latent+sensible+seaice_melt_heat (via the coupler)',&
1681  units='W')
1682 
1683  handles%id_total_net_heat_surface = register_scalar_field('ocean_model', &
1684  'total_net_heat_surface', time, diag, &
1685  long_name='Area integrated surface heat flux from SW+LW+lat+sens+mass+frazil+restore or flux adjustments', &
1686  units='W', &
1687  cmor_field_name='total_hfds', &
1688  cmor_standard_name='surface_downward_heat_flux_in_sea_water_area_integrated', &
1689  cmor_long_name= &
1690  'Surface Ocean Heat Flux from SW+LW+latent+sensible+mass transfer+frazil Area Integrated')
1691 
1692  handles%id_total_sw = register_scalar_field('ocean_model', &
1693  'total_sw', time, diag, &
1694  long_name='Area integrated net downward shortwave at sea water surface', &
1695  units='W', &
1696  cmor_field_name='total_rsntds', &
1697  cmor_standard_name='net_downward_shortwave_flux_at_sea_water_surface_area_integrated',&
1698  cmor_long_name= &
1699  'Net Downward Shortwave Radiation at Sea Water Surface Area Integrated')
1700 
1701  handles%id_total_LwLatSens = register_scalar_field('ocean_model',&
1702  'total_LwLatSens', time, diag, &
1703  long_name='Area integrated longwave+latent+sensible heating',&
1704  units='W')
1705 
1706  handles%id_total_lw = register_scalar_field('ocean_model', &
1707  'total_lw', time, diag, &
1708  long_name='Area integrated net downward longwave at sea water surface', &
1709  units='W', &
1710  cmor_field_name='total_rlntds', &
1711  cmor_standard_name='surface_net_downward_longwave_flux_area_integrated',&
1712  cmor_long_name= &
1713  'Surface Net Downward Longwave Radiation Area Integrated')
1714 
1715  handles%id_total_lat = register_scalar_field('ocean_model', &
1716  'total_lat', time, diag, &
1717  long_name='Area integrated surface downward latent heat flux', &
1718  units='W', &
1719  cmor_field_name='total_hflso', &
1720  cmor_standard_name='surface_downward_latent_heat_flux_area_integrated',&
1721  cmor_long_name= &
1722  'Surface Downward Latent Heat Flux Area Integrated')
1723 
1724  handles%id_total_lat_evap = register_scalar_field('ocean_model', &
1725  'total_lat_evap', time, diag, &
1726  long_name='Area integrated latent heat flux due to evap/condense',&
1727  units='W')
1728 
1729  handles%id_total_lat_fprec = register_scalar_field('ocean_model', &
1730  'total_lat_fprec', time, diag, &
1731  long_name='Area integrated latent heat flux due to melting frozen precip', &
1732  units='W', &
1733  cmor_field_name='total_hfsnthermds', &
1734  cmor_standard_name='heat_flux_into_sea_water_due_to_snow_thermodynamics_area_integrated',&
1735  cmor_long_name= &
1736  'Latent Heat to Melt Frozen Precipitation Area Integrated')
1737 
1738  handles%id_total_lat_frunoff = register_scalar_field('ocean_model', &
1739  'total_lat_frunoff', time, diag, &
1740  long_name='Area integrated latent heat flux due to melting icebergs', &
1741  units='W', &
1742  cmor_field_name='total_hfibthermds', &
1743  cmor_standard_name='heat_flux_into_sea_water_due_to_iceberg_thermodynamics_area_integrated',&
1744  cmor_long_name= &
1745  'Heat Flux into Sea Water due to Iceberg Thermodynamics Area Integrated')
1746 
1747  handles%id_total_sens = register_scalar_field('ocean_model', &
1748  'total_sens', time, diag, &
1749  long_name='Area integrated downward sensible heat flux', &
1750  units='W', &
1751  cmor_field_name='total_hfsso', &
1752  cmor_standard_name='surface_downward_sensible_heat_flux_area_integrated',&
1753  cmor_long_name= &
1754  'Surface Downward Sensible Heat Flux Area Integrated')
1755 
1756  handles%id_total_heat_added = register_scalar_field('ocean_model',&
1757  'total_heat_adjustment', time, diag, &
1758  long_name='Area integrated surface heat flux from restoring and/or flux adjustment', &
1759  units='W')
1760 
1761  handles%id_total_seaice_melt_heat = register_scalar_field('ocean_model',&
1762  'total_seaice_melt_heat', time, diag, &
1763  long_name='Area integrated surface heat flux from snow and sea ice melt', &
1764  units='W')
1765 
1766  !===============================================================
1767  ! area averaged surface heat fluxes
1768 
1769  handles%id_net_heat_coupler_ga = register_scalar_field('ocean_model', &
1770  'net_heat_coupler_ga', time, diag, &
1771  long_name='Area averaged surface heat flux from SW+LW+latent+sensible+seaice_melt_heat (via the coupler)',&
1772  units='W m-2')
1773 
1774  handles%id_net_heat_surface_ga = register_scalar_field('ocean_model', &
1775  'net_heat_surface_ga', time, diag, long_name= &
1776  'Area averaged surface heat flux from SW+LW+lat+sens+mass+frazil+restore+seaice_melt_heat or flux adjustments', &
1777  units='W m-2', &
1778  cmor_field_name='ave_hfds', &
1779  cmor_standard_name='surface_downward_heat_flux_in_sea_water_area_averaged', &
1780  cmor_long_name= &
1781  'Surface Ocean Heat Flux from SW+LW+latent+sensible+mass transfer+frazil Area Averaged')
1782 
1783  handles%id_sw_ga = register_scalar_field('ocean_model', &
1784  'sw_ga', time, diag, &
1785  long_name='Area averaged net downward shortwave at sea water surface', &
1786  units='W m-2', &
1787  cmor_field_name='ave_rsntds', &
1788  cmor_standard_name='net_downward_shortwave_flux_at_sea_water_surface_area_averaged',&
1789  cmor_long_name= &
1790  'Net Downward Shortwave Radiation at Sea Water Surface Area Averaged')
1791 
1792  handles%id_LwLatSens_ga = register_scalar_field('ocean_model',&
1793  'LwLatSens_ga', time, diag, &
1794  long_name='Area averaged longwave+latent+sensible heating',&
1795  units='W m-2')
1796 
1797  handles%id_lw_ga = register_scalar_field('ocean_model', &
1798  'lw_ga', time, diag, &
1799  long_name='Area averaged net downward longwave at sea water surface', &
1800  units='W m-2', &
1801  cmor_field_name='ave_rlntds', &
1802  cmor_standard_name='surface_net_downward_longwave_flux_area_averaged',&
1803  cmor_long_name= &
1804  'Surface Net Downward Longwave Radiation Area Averaged')
1805 
1806  handles%id_lat_ga = register_scalar_field('ocean_model', &
1807  'lat_ga', time, diag, &
1808  long_name='Area averaged surface downward latent heat flux', &
1809  units='W m-2', &
1810  cmor_field_name='ave_hflso', &
1811  cmor_standard_name='surface_downward_latent_heat_flux_area_averaged',&
1812  cmor_long_name= &
1813  'Surface Downward Latent Heat Flux Area Averaged')
1814 
1815  handles%id_sens_ga = register_scalar_field('ocean_model', &
1816  'sens_ga', time, diag, &
1817  long_name='Area averaged downward sensible heat flux', &
1818  units='W m-2', &
1819  cmor_field_name='ave_hfsso', &
1820  cmor_standard_name='surface_downward_sensible_heat_flux_area_averaged',&
1821  cmor_long_name= &
1822  'Surface Downward Sensible Heat Flux Area Averaged')
1823 
1824 
1825  !===============================================================
1826  ! maps of surface salt fluxes, virtual precip fluxes, and adjustments
1827 
1828  handles%id_saltflux = register_diag_field('ocean_model', 'salt_flux', diag%axesT1, time,&
1829  'Net salt flux into ocean at surface (restoring + sea-ice)', &
1830  units='kg m-2 s-1', conversion=us%RZ_T_to_kg_m2s, &
1831  cmor_field_name='sfdsi', cmor_standard_name='downward_sea_ice_basal_salt_flux', &
1832  cmor_long_name='Downward Sea Ice Basal Salt Flux')
1833 
1834  handles%id_saltFluxIn = register_diag_field('ocean_model', 'salt_flux_in', diag%axesT1, time, &
1835  'Salt flux into ocean at surface from coupler', &
1836  units='kg m-2 s-1', conversion=us%RZ_T_to_kg_m2s)
1837 
1838  handles%id_saltFluxAdded = register_diag_field('ocean_model', 'salt_flux_added', &
1839  diag%axesT1,time,'Salt flux into ocean at surface due to restoring or flux adjustment', &
1840  units='kg m-2 s-1', conversion=us%RZ_T_to_kg_m2s)
1841 
1842  handles%id_saltFluxGlobalAdj = register_scalar_field('ocean_model', &
1843  'salt_flux_global_restoring_adjustment', time, diag, &
1844  'Adjustment needed to balance net global salt flux into ocean at surface', &
1845  units='kg m-2 s-1') !, conversion=US%RZ_T_to_kg_m2s)
1846 
1847  handles%id_vPrecGlobalAdj = register_scalar_field('ocean_model', &
1848  'vprec_global_adjustment', time, diag, &
1849  'Adjustment needed to adjust net vprec into ocean to zero', &
1850  'kg m-2 s-1')
1851 
1852  handles%id_netFWGlobalAdj = register_scalar_field('ocean_model', &
1853  'net_fresh_water_global_adjustment', time, diag, &
1854  'Adjustment needed to adjust net fresh water into ocean to zero',&
1855  'kg m-2 s-1')
1856 
1857  handles%id_saltFluxGlobalScl = register_scalar_field('ocean_model', &
1858  'salt_flux_global_restoring_scaling', time, diag, &
1859  'Scaling applied to balance net global salt flux into ocean at surface', &
1860  'nondim')
1861 
1862  handles%id_vPrecGlobalScl = register_scalar_field('ocean_model',&
1863  'vprec_global_scaling', time, diag, &
1864  'Scaling applied to adjust net vprec into ocean to zero', &
1865  'nondim')
1866 
1867  handles%id_netFWGlobalScl = register_scalar_field('ocean_model', &
1868  'net_fresh_water_global_scaling', time, diag, &
1869  'Scaling applied to adjust net fresh water into ocean to zero', &
1870  'nondim')
1871 
1872  !===============================================================
1873  ! area integrals of surface salt fluxes
1874 
1875  handles%id_total_saltflux = register_scalar_field('ocean_model', &
1876  'total_salt_flux', time, diag, &
1877  long_name='Area integrated surface salt flux', units='kg', &
1878  cmor_field_name='total_sfdsi', &
1879  cmor_units='kg s-1', &
1880  cmor_standard_name='downward_sea_ice_basal_salt_flux_area_integrated',&
1881  cmor_long_name='Downward Sea Ice Basal Salt Flux Area Integrated')
1882 
1883  handles%id_total_saltFluxIn = register_scalar_field('ocean_model', 'total_salt_Flux_In', &
1884  time, diag, long_name='Area integrated surface salt flux at surface from coupler', units='kg')
1885 
1886  handles%id_total_saltFluxAdded = register_scalar_field('ocean_model', 'total_salt_Flux_Added', &
1887  time, diag, long_name='Area integrated surface salt flux due to restoring or flux adjustment', units='kg')
1888 
1889 

◆ rotate_forcing()

subroutine, public mom_forcing_type::rotate_forcing ( type(forcing), intent(in)  fluxes_in,
type(forcing), intent(inout)  fluxes,
integer, intent(in)  turns 
)
Parameters
[in]fluxes_inInput forcing struct
[in,out]fluxesRotated forcing struct
[in]turnsNumber of quarter turns

Definition at line 3186 of file MOM_forcing_type.F90.

3187  type(forcing), intent(in) :: fluxes_in !< Input forcing struct
3188  type(forcing), intent(inout) :: fluxes !< Rotated forcing struct
3189  integer, intent(in) :: turns !< Number of quarter turns
3190 
3191  logical :: do_ustar, do_water, do_heat, do_salt, do_press, do_shelf, &
3192  do_iceberg, do_heat_added, do_buoy
3193 
3194  call get_forcing_groups(fluxes_in, do_water, do_heat, do_ustar, do_press, &
3195  do_shelf, do_iceberg, do_salt, do_heat_added, do_buoy)
3196 
3197  if (do_ustar) then
3198  call rotate_array(fluxes_in%ustar, turns, fluxes%ustar)
3199  call rotate_array(fluxes_in%ustar_gustless, turns, fluxes%ustar_gustless)
3200  endif
3201 
3202  if (do_water) then
3203  call rotate_array(fluxes_in%evap, turns, fluxes%evap)
3204  call rotate_array(fluxes_in%lprec, turns, fluxes%lprec)
3205  call rotate_array(fluxes_in%fprec, turns, fluxes%fprec)
3206  call rotate_array(fluxes_in%vprec, turns, fluxes%vprec)
3207  call rotate_array(fluxes_in%lrunoff, turns, fluxes%lrunoff)
3208  call rotate_array(fluxes_in%frunoff, turns, fluxes%frunoff)
3209  call rotate_array(fluxes_in%seaice_melt, turns, fluxes%seaice_melt)
3210  call rotate_array(fluxes_in%netMassOut, turns, fluxes%netMassOut)
3211  call rotate_array(fluxes_in%netMassIn, turns, fluxes%netMassIn)
3212  call rotate_array(fluxes_in%netSalt, turns, fluxes%netSalt)
3213  endif
3214 
3215  if (do_heat) then
3216  call rotate_array(fluxes_in%seaice_melt_heat, turns, fluxes%seaice_melt_heat)
3217  call rotate_array(fluxes_in%sw, turns, fluxes%sw)
3218  call rotate_array(fluxes_in%lw, turns, fluxes%lw)
3219  call rotate_array(fluxes_in%latent, turns, fluxes%latent)
3220  call rotate_array(fluxes_in%sens, turns, fluxes%sens)
3221  call rotate_array(fluxes_in%latent_evap_diag, turns, fluxes%latent_evap_diag)
3222  call rotate_array(fluxes_in%latent_fprec_diag, turns, fluxes%latent_fprec_diag)
3223  call rotate_array(fluxes_in%latent_frunoff_diag, turns, fluxes%latent_frunoff_diag)
3224  endif
3225 
3226  if (do_salt) then
3227  call rotate_array(fluxes_in%salt_flux, turns, fluxes%salt_flux)
3228  endif
3229 
3230  if (do_heat .and. do_water) then
3231  call rotate_array(fluxes_in%heat_content_cond, turns, fluxes%heat_content_cond)
3232  call rotate_array(fluxes_in%heat_content_icemelt, turns, fluxes%heat_content_icemelt)
3233  call rotate_array(fluxes_in%heat_content_lprec, turns, fluxes%heat_content_lprec)
3234  call rotate_array(fluxes_in%heat_content_fprec, turns, fluxes%heat_content_fprec)
3235  call rotate_array(fluxes_in%heat_content_vprec, turns, fluxes%heat_content_vprec)
3236  call rotate_array(fluxes_in%heat_content_lrunoff, turns, fluxes%heat_content_lrunoff)
3237  call rotate_array(fluxes_in%heat_content_frunoff, turns, fluxes%heat_content_frunoff)
3238  call rotate_array(fluxes_in%heat_content_massout, turns, fluxes%heat_content_massout)
3239  call rotate_array(fluxes_in%heat_content_massin, turns, fluxes%heat_content_massin)
3240  endif
3241 
3242  if (do_press) then
3243  call rotate_array(fluxes_in%p_surf, turns, fluxes%p_surf)
3244  endif
3245 
3246  if (do_shelf) then
3247  call rotate_array(fluxes_in%frac_shelf_h, turns, fluxes%frac_shelf_h)
3248  call rotate_array(fluxes_in%ustar_shelf, turns, fluxes%ustar_shelf)
3249  call rotate_array(fluxes_in%iceshelf_melt, turns, fluxes%iceshelf_melt)
3250  endif
3251 
3252  if (do_iceberg) then
3253  call rotate_array(fluxes_in%ustar_berg, turns, fluxes%ustar_berg)
3254  call rotate_array(fluxes_in%area_berg, turns, fluxes%area_berg)
3255  call rotate_array(fluxes_in%iceshelf_melt, turns, fluxes%iceshelf_melt)
3256  endif
3257 
3258  if (do_heat_added) then
3259  call rotate_array(fluxes_in%heat_added, turns, fluxes%heat_added)
3260  endif
3261 
3262  ! The following fields are handled by drivers rather than control flags.
3263  if (associated(fluxes_in%sw_vis_dir)) &
3264  call rotate_array(fluxes_in%sw_vis_dir, turns, fluxes%sw_vis_dir)
3265  if (associated(fluxes_in%sw_vis_dif)) &
3266  call rotate_array(fluxes_in%sw_vis_dif, turns, fluxes%sw_vis_dif)
3267  if (associated(fluxes_in%sw_nir_dir)) &
3268  call rotate_array(fluxes_in%sw_nir_dir, turns, fluxes%sw_nir_dir)
3269  if (associated(fluxes_in%sw_nir_dif)) &
3270  call rotate_array(fluxes_in%sw_nir_dif, turns, fluxes%sw_nir_dif)
3271 
3272  if (associated(fluxes_in%salt_flux_in)) &
3273  call rotate_array(fluxes_in%salt_flux_in, turns, fluxes%salt_flux_in)
3274  if (associated(fluxes_in%salt_flux_added)) &
3275  call rotate_array(fluxes_in%salt_flux_added, turns, fluxes%salt_flux_added)
3276 
3277  if (associated(fluxes_in%p_surf_full)) &
3278  call rotate_array(fluxes_in%p_surf_full, turns, fluxes%p_surf_full)
3279 
3280  if (associated(fluxes_in%buoy)) &
3281  call rotate_array(fluxes_in%buoy, turns, fluxes%buoy)
3282 
3283  if (associated(fluxes_in%TKE_tidal)) &
3284  call rotate_array(fluxes_in%TKE_tidal, turns, fluxes%TKE_tidal)
3285  if (associated(fluxes_in%ustar_tidal)) &
3286  call rotate_array(fluxes_in%ustar_tidal, turns, fluxes%ustar_tidal)
3287 
3288  ! TODO: tracer flux rotation
3289  if (coupler_type_initialized(fluxes%tr_fluxes)) &
3290  call mom_error(fatal, "Rotation of tracer BC fluxes not yet implemented.")
3291 
3292  ! Scalars and flags
3293  fluxes%accumulate_p_surf = fluxes_in%accumulate_p_surf
3294 
3295  fluxes%vPrecGlobalAdj = fluxes_in%vPrecGlobalAdj
3296  fluxes%saltFluxGlobalAdj = fluxes_in%saltFluxGlobalAdj
3297  fluxes%netFWGlobalAdj = fluxes_in%netFWGlobalAdj
3298  fluxes%vPrecGlobalScl = fluxes_in%vPrecGlobalScl
3299  fluxes%saltFluxGlobalScl = fluxes_in%saltFluxGlobalScl
3300  fluxes%netFWGlobalScl = fluxes_in%netFWGlobalScl
3301 
3302  fluxes%fluxes_used = fluxes_in%fluxes_used
3303  fluxes%dt_buoy_accum = fluxes_in%dt_buoy_accum
3304  fluxes%C_p = fluxes_in%C_p
3305  ! NOTE: gustless_accum_bug is set during allocation
3306 
3307  fluxes%num_msg = fluxes_in%num_msg
3308  fluxes%max_msg = fluxes_in%max_msg

◆ rotate_mech_forcing()

subroutine, public mom_forcing_type::rotate_mech_forcing ( type(mech_forcing), intent(in)  forces_in,
integer, intent(in)  turns,
type(mech_forcing), intent(inout)  forces 
)
Parameters
[in]forces_inForcing on the input domain
[in]turnsNumber of quarter-turns
[in,out]forcesForcing on the rotated domain

Definition at line 3312 of file MOM_forcing_type.F90.

3313  type(mech_forcing), intent(in) :: forces_in !< Forcing on the input domain
3314  integer, intent(in) :: turns !< Number of quarter-turns
3315  type(mech_forcing), intent(inout) :: forces !< Forcing on the rotated domain
3316 
3317  logical :: do_stress, do_ustar, do_shelf, do_press, do_iceberg
3318 
3319  call get_mech_forcing_groups(forces_in, do_stress, do_ustar, do_shelf, &
3320  do_press, do_iceberg)
3321 
3322  if (do_stress) &
3323  call rotate_vector(forces_in%taux, forces_in%tauy, turns, &
3324  forces%taux, forces%tauy)
3325 
3326  if (do_ustar) &
3327  call rotate_array(forces_in%ustar, turns, forces%ustar)
3328 
3329  if (do_shelf) then
3330  call rotate_array_pair( &
3331  forces_in%rigidity_ice_u, forces_in%rigidity_ice_v, turns, &
3332  forces%rigidity_ice_u, forces%rigidity_ice_v &
3333  )
3334  call rotate_array_pair( &
3335  forces_in%frac_shelf_u, forces_in%frac_shelf_v, turns, &
3336  forces%frac_shelf_u, forces%frac_shelf_v &
3337  )
3338  endif
3339 
3340  if (do_press) then
3341  ! NOTE: p_surf_SSH either points to p_surf or p_surf_full
3342  call rotate_array(forces_in%p_surf, turns, forces%p_surf)
3343  call rotate_array(forces_in%p_surf_full, turns, forces%p_surf_full)
3344  call rotate_array(forces_in%net_mass_src, turns, forces%net_mass_src)
3345  endif
3346 
3347  if (do_iceberg) then
3348  call rotate_array(forces_in%area_berg, turns, forces%area_berg)
3349  call rotate_array(forces_in%mass_berg, turns, forces%mass_berg)
3350  endif
3351 
3352  ! Copy fields
3353  forces%dt_force_accum = forces_in%dt_force_accum
3354  forces%net_mass_src_set = forces_in%net_mass_src_set
3355  forces%accumulate_p_surf = forces_in%accumulate_p_surf
3356  forces%accumulate_rigidity = forces_in%accumulate_rigidity
3357  forces%initialized = forces_in%initialized

◆ set_derived_forcing_fields()

subroutine, public mom_forcing_type::set_derived_forcing_fields ( type(mech_forcing), intent(in)  forces,
type(forcing), intent(inout)  fluxes,
type(ocean_grid_type), intent(in)  G,
type(unit_scale_type), intent(in)  US,
real, intent(in)  Rho0 
)

This subroutine calculates certain derived forcing fields based on information from a mech_forcing type and stores them in a (thermodynamic) forcing type.

Parameters
[in]forcesA structure with the driving mechanical forces
[in,out]fluxesA structure containing thermodynamic forcing fields
[in]ggrid type
[in]usA dimensional unit scaling type
[in]rho0A reference density of seawater [R ~> kg m-3], as used to calculate ustar.

Definition at line 2102 of file MOM_forcing_type.F90.

2103  type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces
2104  type(forcing), intent(inout) :: fluxes !< A structure containing thermodynamic forcing fields
2105  type(ocean_grid_type), intent(in) :: G !< grid type
2106  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
2107  real, intent(in) :: Rho0 !< A reference density of seawater [R ~> kg m-3],
2108  !! as used to calculate ustar.
2109 
2110  real :: taux2, tauy2 ! Squared wind stress components [R2 L2 Z2 T-4 ~> Pa2].
2111  real :: Irho0 ! Inverse of the mean density rescaled to [Z L-1 R-1 ~> m3 kg-1]
2112  integer :: i, j, is, ie, js, je
2113  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
2114 
2115  irho0 = us%L_to_Z / rho0
2116 
2117  if (associated(forces%taux) .and. associated(forces%tauy) .and. &
2118  associated(fluxes%ustar_gustless)) then
2119  do j=js,je ; do i=is,ie
2120  taux2 = 0.0
2121  if ((g%mask2dCu(i-1,j) + g%mask2dCu(i,j)) > 0) &
2122  taux2 = (g%mask2dCu(i-1,j) * forces%taux(i-1,j)**2 + &
2123  g%mask2dCu(i,j) * forces%taux(i,j)**2) / &
2124  (g%mask2dCu(i-1,j) + g%mask2dCu(i,j))
2125  tauy2 = 0.0
2126  if ((g%mask2dCv(i,j-1) + g%mask2dCv(i,j)) > 0) &
2127  tauy2 = (g%mask2dCv(i,j-1) * forces%tauy(i,j-1)**2 + &
2128  g%mask2dCv(i,j) * forces%tauy(i,j)**2) / &
2129  (g%mask2dCv(i,j-1) + g%mask2dCv(i,j))
2130 
2131  if (fluxes%gustless_accum_bug) then
2132  ! This change is just for computational efficiency, but it is wrapped with another change.
2133  fluxes%ustar_gustless(i,j) = sqrt(us%L_to_Z * sqrt(taux2 + tauy2) / rho0)
2134  else
2135  fluxes%ustar_gustless(i,j) = sqrt(sqrt(taux2 + tauy2) * irho0)
2136  endif
2137  enddo ; enddo
2138  endif
2139 

◆ set_net_mass_forcing()

subroutine, public mom_forcing_type::set_net_mass_forcing ( type(forcing), intent(in)  fluxes,
type(mech_forcing), intent(inout)  forces,
type(ocean_grid_type), intent(in)  G,
type(unit_scale_type), intent(in)  US 
)

This subroutine determines the net mass source to the ocean from a (thermodynamic) forcing type and stores it in a mech_forcing type.

Parameters
[in]fluxesA structure containing thermodynamic forcing fields
[in,out]forcesA structure with the driving mechanical forces
[in]usA dimensional unit scaling type
[in]gThe ocean grid type

Definition at line 2145 of file MOM_forcing_type.F90.

2146  type(forcing), intent(in) :: fluxes !< A structure containing thermodynamic forcing fields
2147  type(mech_forcing), intent(inout) :: forces !< A structure with the driving mechanical forces
2148  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
2149  type(ocean_grid_type), intent(in) :: G !< The ocean grid type
2150 
2151  if (associated(forces%net_mass_src)) &
2152  call get_net_mass_forcing(fluxes, g, us, forces%net_mass_src)
2153