MOM6
mom_ocean_model_nuopc Module Reference

Detailed Description

Top-level module for the MOM6 ocean model in coupled mode.

Data Types

type  ocean_public_type
 This type is used for communication with other components via the FMS coupler. The element names and types can be changed only with great deliberation, hence the persistnce of things like the cutsy element name "avg_kount". More...
 
type  ocean_state_type
 The ocean_state_type contains all information about the state of the ocean, with a format that is private so it can be readily changed without disrupting other coupled components. More...
 

Functions/Subroutines

subroutine, public ocean_model_init (Ocean_sfc, OS, Time_init, Time_in, gas_fields_ocn, input_restart_file)
 ocean_model_init initializes the ocean model, including registering fields for restarts and reading restart files if appropriate. More...
 
subroutine, public update_ocean_model (Ice_ocean_boundary, OS, Ocean_sfc, time_start_update, Ocean_coupling_time_step, update_dyn, update_thermo, Ocn_fluxes_used)
 update_ocean_model uses the forcing in Ice_ocean_boundary to advance the ocean model's state from the input value of Ocean_state (which must be for time time_start_update) for a time interval of Ocean_coupling_time_step, returning the publicly visible ocean surface properties in Ocean_sfc and storing the new ocean properties in Ocean_state. More...
 
subroutine, public ocean_model_restart (OS, timestamp, restartname)
 This subroutine writes out the ocean model restart file. More...
 
subroutine, public ocean_model_end (Ocean_sfc, Ocean_state, Time, write_restart)
 ocean_model_end terminates the model run, saving the ocean state in a restart and deallocating any data associated with the ocean. More...
 
subroutine, public ocean_model_save_restart (OS, Time, directory, filename_suffix)
 ocean_model_save_restart causes restart files associated with the ocean to be written out. More...
 
subroutine initialize_ocean_public_type (input_domain, Ocean_sfc, diag, maskmap, gas_fields_ocn)
 Initialize the public ocean type. More...
 
subroutine convert_state_to_ocean_type (sfc_state, Ocean_sfc, G, US, patm, press_to_z)
 This subroutine translates the coupler's ocean_data_type into MOM's surface state variable. This may eventually be folded into the MOM code that calculates the surface state in the first place. Note the offset in the arrays because the ocean_data_type has no halo points in its arrays and always uses absolute indicies. More...
 
subroutine, public ocean_model_init_sfc (OS, Ocean_sfc)
 This subroutine extracts the surface properties from the ocean's internal state and stores them in the ocean type returned to the calling ice model. It has to be separate from the ocean_initialization call because the coupler module allocates the space for some of these variables. More...
 
subroutine, public ocean_model_flux_init (OS, verbosity)
 ocean_model_flux_init is used to initialize properties of the air-sea fluxes as determined by various run-time parameters. It can be called from non-ocean PEs, or PEs that have not yet been initialzed, and it can safely be called multiple times. More...
 
subroutine, public ocean_stock_pe (OS, index, value, time_index)
 Ocean_stock_pe - returns the integrated stocks of heat, water, etc. for conservation checks. Because of the way FMS is coded, only the root PE has the integrated amount, while all other PEs get 0. More...
 
subroutine, public ocean_public_type_chksum (id, timestep, ocn)
 Write out FMS-format checsums on fields from the ocean surface state. More...
 
subroutine, public get_ocean_grid (OS, Gridp)
 
real function, public get_eps_omesh (OS)
 Returns eps_omesh read from param file. More...
 

Function/Subroutine Documentation

◆ convert_state_to_ocean_type()

subroutine mom_ocean_model_nuopc::convert_state_to_ocean_type ( type(surface), intent(inout)  sfc_state,
type(ocean_public_type), intent(inout), target  Ocean_sfc,
type(ocean_grid_type), intent(inout)  G,
type(unit_scale_type), intent(in)  US,
real, dimension(:,:), intent(in), optional  patm,
real, intent(in), optional  press_to_z 
)
private

This subroutine translates the coupler's ocean_data_type into MOM's surface state variable. This may eventually be folded into the MOM code that calculates the surface state in the first place. Note the offset in the arrays because the ocean_data_type has no halo points in its arrays and always uses absolute indicies.

Parameters
[in,out]sfc_stateA structure containing fields that describe the surface state of the ocean.
[in,out]ocean_sfcA structure containing various publicly
[in,out]gThe ocean's grid structure
[in]usA dimensional unit scaling type
[in]patmThe pressure at the ocean surface, in Pa.
[in]press_to_zA conversion factor between pressure and ocean depth in m, usually 1/(rho_0*g), in m Pa-1.

Definition at line 840 of file mom_ocean_model_nuopc.F90.

840  type(surface), intent(inout) :: sfc_state !< A structure containing fields that
841  !! describe the surface state of the ocean.
842  type(ocean_public_type), &
843  target, intent(inout) :: Ocean_sfc !< A structure containing various publicly
844  !! visible ocean surface fields, whose elements
845  !! have their data set here.
846  type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure
847  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
848  real, optional, intent(in) :: patm(:,:) !< The pressure at the ocean surface, in Pa.
849  real, optional, intent(in) :: press_to_z !< A conversion factor between pressure and
850  !! ocean depth in m, usually 1/(rho_0*g), in m Pa-1.
851  ! Local variables
852  real :: IgR0
853  character(len=48) :: val_str
854  integer :: isc_bnd, iec_bnd, jsc_bnd, jec_bnd
855  integer :: i, j, i0, j0, is, ie, js, je
856 
857  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
858  call pass_vector(sfc_state%u, sfc_state%v, g%Domain)
859 
860  call mpp_get_compute_domain(ocean_sfc%Domain, isc_bnd, iec_bnd, &
861  jsc_bnd, jec_bnd)
862  if (present(patm)) then
863  ! Check that the inidicies in patm are (isc_bnd:iec_bnd,jsc_bnd:jec_bnd).
864  if (.not.present(press_to_z)) call mom_error(fatal, &
865  'convert_state_to_ocean_type: press_to_z must be present if patm is.')
866  endif
867 
868  i0 = is - isc_bnd ; j0 = js - jsc_bnd
869  if (sfc_state%T_is_conT) then
870  ! Convert the surface T from conservative T to potential T.
871  do j=jsc_bnd,jec_bnd ; do i=isc_bnd,iec_bnd
872  ocean_sfc%t_surf(i,j) = gsw_pt_from_ct(sfc_state%SSS(i+i0,j+j0), &
873  sfc_state%SST(i+i0,j+j0)) + celsius_kelvin_offset
874  enddo ; enddo
875  else
876  do j=jsc_bnd,jec_bnd ; do i=isc_bnd,iec_bnd
877  ocean_sfc%t_surf(i,j) = sfc_state%SST(i+i0,j+j0) + celsius_kelvin_offset
878  enddo ; enddo
879  endif
880  if (sfc_state%S_is_absS) then
881  ! Convert the surface S from absolute salinity to practical salinity.
882  do j=jsc_bnd,jec_bnd ; do i=isc_bnd,iec_bnd
883  ocean_sfc%s_surf(i,j) = gsw_sp_from_sr(sfc_state%SSS(i+i0,j+j0))
884  enddo ; enddo
885  else
886  do j=jsc_bnd,jec_bnd ; do i=isc_bnd,iec_bnd
887  ocean_sfc%s_surf(i,j) = sfc_state%SSS(i+i0,j+j0)
888  enddo ; enddo
889  endif
890 
891  if (present(patm)) then
892  do j=jsc_bnd,jec_bnd ; do i=isc_bnd,iec_bnd
893  ocean_sfc%sea_lev(i,j) = sfc_state%sea_lev(i+i0,j+j0) + patm(i,j) * press_to_z
894  ocean_sfc%area(i,j) = us%L_to_m**2*g%areaT(i+i0,j+j0)
895  enddo ; enddo
896  else
897  do j=jsc_bnd,jec_bnd ; do i=isc_bnd,iec_bnd
898  ocean_sfc%sea_lev(i,j) = sfc_state%sea_lev(i+i0,j+j0)
899  ocean_sfc%area(i,j) = us%L_to_m**2*g%areaT(i+i0,j+j0)
900  enddo ; enddo
901  endif
902 
903  if (associated(sfc_state%frazil)) then
904  do j=jsc_bnd,jec_bnd ; do i=isc_bnd,iec_bnd
905  ocean_sfc%frazil(i,j) = sfc_state%frazil(i+i0,j+j0)
906  enddo ; enddo
907  endif
908 
909  if (allocated(sfc_state%melt_potential)) then
910  do j=jsc_bnd,jec_bnd ; do i=isc_bnd,iec_bnd
911  ocean_sfc%melt_potential(i,j) = sfc_state%melt_potential(i+i0,j+j0)
912  enddo ; enddo
913  endif
914 
915  if (allocated(sfc_state%Hml)) then
916  do j=jsc_bnd,jec_bnd ; do i=isc_bnd,iec_bnd
917  ocean_sfc%OBLD(i,j) = sfc_state%Hml(i+i0,j+j0)
918  enddo ; enddo
919  endif
920 
921  if (ocean_sfc%stagger == agrid) then
922  do j=jsc_bnd,jec_bnd ; do i=isc_bnd,iec_bnd
923  ocean_sfc%u_surf(i,j) = g%mask2dT(i+i0,j+j0) * &
924  0.5*(sfc_state%u(i+i0,j+j0)+sfc_state%u(i-1+i0,j+j0))
925  ocean_sfc%v_surf(i,j) = g%mask2dT(i+i0,j+j0) * &
926  0.5*(sfc_state%v(i+i0,j+j0)+sfc_state%v(i+i0,j-1+j0))
927  enddo ; enddo
928  elseif (ocean_sfc%stagger == bgrid_ne) then
929  do j=jsc_bnd,jec_bnd ; do i=isc_bnd,iec_bnd
930  ocean_sfc%u_surf(i,j) = g%mask2dBu(i+i0,j+j0) * &
931  0.5*(sfc_state%u(i+i0,j+j0)+sfc_state%u(i+i0,j+j0+1))
932  ocean_sfc%v_surf(i,j) = g%mask2dBu(i+i0,j+j0) * &
933  0.5*(sfc_state%v(i+i0,j+j0)+sfc_state%v(i+i0+1,j+j0))
934  enddo ; enddo
935  elseif (ocean_sfc%stagger == cgrid_ne) then
936  do j=jsc_bnd,jec_bnd ; do i=isc_bnd,iec_bnd
937  ocean_sfc%u_surf(i,j) = g%mask2dCu(i+i0,j+j0)*sfc_state%u(i+i0,j+j0)
938  ocean_sfc%v_surf(i,j) = g%mask2dCv(i+i0,j+j0)*sfc_state%v(i+i0,j+j0)
939  enddo ; enddo
940  else
941  write(val_str, '(I8)') ocean_sfc%stagger
942  call mom_error(fatal, "convert_state_to_ocean_type: "//&
943  "Ocean_sfc%stagger has the unrecognized value of "//trim(val_str))
944  endif
945 
946  if (coupler_type_initialized(sfc_state%tr_fields)) then
947  if (.not.coupler_type_initialized(ocean_sfc%fields)) then
948  call mom_error(fatal, "convert_state_to_ocean_type: "//&
949  "Ocean_sfc%fields has not been initialized.")
950  endif
951  call coupler_type_copy_data(sfc_state%tr_fields, ocean_sfc%fields)
952  endif
953 

References mom_constants::celsius_kelvin_offset.

Referenced by ocean_model_init(), ocean_model_init_sfc(), and update_ocean_model().

Here is the caller graph for this function:

◆ get_eps_omesh()

real function, public mom_ocean_model_nuopc::get_eps_omesh ( type(ocean_state_type OS)

Returns eps_omesh read from param file.

Definition at line 1078 of file mom_ocean_model_nuopc.F90.

1078  type(ocean_state_type) :: OS
1079  get_eps_omesh = os%eps_omesh; return

Referenced by mom_cap_mod::initializerealize().

Here is the caller graph for this function:

◆ get_ocean_grid()

subroutine, public mom_ocean_model_nuopc::get_ocean_grid ( type(ocean_state_type OS,
type(ocean_grid_type), pointer  Gridp 
)

Definition at line 1068 of file mom_ocean_model_nuopc.F90.

1068  ! Obtain the ocean grid.
1069  type(ocean_state_type) :: OS
1070  type(ocean_grid_type) , pointer :: Gridp
1071 
1072  gridp => os%grid
1073  return

Referenced by mom_cap_mod::datainitialize(), mom_cap_mod::initializerealize(), and mom_cap_mod::modeladvance().

Here is the caller graph for this function:

◆ initialize_ocean_public_type()

subroutine mom_ocean_model_nuopc::initialize_ocean_public_type ( type(domain2d), intent(in)  input_domain,
type(ocean_public_type), intent(inout)  Ocean_sfc,
type(diag_ctrl), intent(in)  diag,
logical, dimension(:,:), intent(in), optional  maskmap,
type(coupler_1d_bc_type), intent(in), optional  gas_fields_ocn 
)
private

Initialize the public ocean type.

Parameters
[in]input_domainThe ocean model domain description
[in,out]ocean_sfcA structure containing various publicly visible ocean surface properties after initialization, whose elements are allocated here.
[in]diagA structure that regulates diagnsotic output
[in]maskmapA mask indicating which virtual processors
[in]gas_fields_ocnIf present, this type describes the

Definition at line 778 of file mom_ocean_model_nuopc.F90.

778  type(domain2D), intent(in) :: input_domain !< The ocean model domain description
779  type(ocean_public_type), intent(inout) :: Ocean_sfc !< A structure containing various publicly
780  !! visible ocean surface properties after initialization, whose
781  !! elements are allocated here.
782  type(diag_ctrl), intent(in) :: diag !< A structure that regulates diagnsotic output
783  logical, dimension(:,:), &
784  optional, intent(in) :: maskmap !< A mask indicating which virtual processors
785  !! are actually in use. If missing, all are used.
786  type(coupler_1d_bc_type), &
787  optional, intent(in) :: gas_fields_ocn !< If present, this type describes the
788  !! ocean and surface-ice fields that will participate
789  !! in the calculation of additional gas or other
790  !! tracer fluxes.
791 
792  integer :: xsz, ysz, layout(2)
793  ! ice-ocean-boundary fields are always allocated using absolute indicies
794  ! and have no halos.
795  integer :: isc, iec, jsc, jec
796 
797  call mpp_get_layout(input_domain,layout)
798  call mpp_get_global_domain(input_domain, xsize=xsz, ysize=ysz)
799  if (PRESENT(maskmap)) then
800  call mpp_define_domains((/1,xsz,1,ysz/),layout,ocean_sfc%Domain, maskmap=maskmap)
801  else
802  call mpp_define_domains((/1,xsz,1,ysz/),layout,ocean_sfc%Domain)
803  endif
804  call mpp_get_compute_domain(ocean_sfc%Domain, isc, iec, jsc, jec)
805 
806  allocate ( ocean_sfc%t_surf (isc:iec,jsc:jec), &
807  ocean_sfc%s_surf (isc:iec,jsc:jec), &
808  ocean_sfc%u_surf (isc:iec,jsc:jec), &
809  ocean_sfc%v_surf (isc:iec,jsc:jec), &
810  ocean_sfc%sea_lev(isc:iec,jsc:jec), &
811  ocean_sfc%area (isc:iec,jsc:jec), &
812  ocean_sfc%OBLD (isc:iec,jsc:jec), &
813  ocean_sfc%melt_potential(isc:iec,jsc:jec), &
814  ocean_sfc%frazil (isc:iec,jsc:jec))
815 
816  ocean_sfc%t_surf = 0.0 ! time averaged sst (Kelvin) passed to atmosphere/ice model
817  ocean_sfc%s_surf = 0.0 ! time averaged sss (psu) passed to atmosphere/ice models
818  ocean_sfc%u_surf = 0.0 ! time averaged u-current (m/sec) passed to atmosphere/ice models
819  ocean_sfc%v_surf = 0.0 ! time averaged v-current (m/sec) passed to atmosphere/ice models
820  ocean_sfc%sea_lev = 0.0 ! time averaged thickness of top model grid cell (m) plus patm/rho0/grav
821  ocean_sfc%frazil = 0.0 ! time accumulated frazil (J/m^2) passed to ice model
822  ocean_sfc%melt_potential = 0.0 ! time accumulated melt potential (J/m^2) passed to ice model
823  ocean_sfc%OBLD = 0.0 ! ocean boundary layer depth, in m
824  ocean_sfc%area = 0.0
825  ocean_sfc%axes = diag%axesT1%handles !diag axes to be used by coupler tracer flux diagnostics
826 
827  if (present(gas_fields_ocn)) then
828  call coupler_type_spawn(gas_fields_ocn, ocean_sfc%fields, (/isc,isc,iec,iec/), &
829  (/jsc,jsc,jec,jec/), suffix = '_ocn', as_needed=.true.)
830  endif
831 

Referenced by ocean_model_init().

Here is the caller graph for this function:

◆ ocean_model_end()

subroutine, public mom_ocean_model_nuopc::ocean_model_end ( type(ocean_public_type), intent(inout)  Ocean_sfc,
type(ocean_state_type), pointer  Ocean_state,
type(time_type), intent(in)  Time,
logical, intent(in)  write_restart 
)

ocean_model_end terminates the model run, saving the ocean state in a restart and deallocating any data associated with the ocean.

Parameters
[in,out]ocean_sfcAn ocean_public_type structure that is to be deallocated upon termination.
ocean_stateA pointer to the structure containing the internal ocean state to be deallocated upon termination.
[in]timeThe model time, used for writing restarts.
[in]write_restarttrue => write restart file

Definition at line 725 of file mom_ocean_model_nuopc.F90.

725  type(ocean_public_type), intent(inout) :: Ocean_sfc !< An ocean_public_type structure that is
726  !! to be deallocated upon termination.
727  type(ocean_state_type), pointer :: Ocean_state !< A pointer to the structure containing
728  !! the internal ocean state to be deallocated
729  !! upon termination.
730  type(time_type), intent(in) :: Time !< The model time, used for writing restarts.
731  logical, intent(in) :: write_restart !< true => write restart file
732 
733  call ocean_model_save_restart(ocean_state, time)
734  call diag_mediator_end(time, ocean_state%diag, end_diag_manager=.true.)
735  call mom_end(ocean_state%MOM_CSp)
736  if (ocean_state%use_ice_shelf) call ice_shelf_end(ocean_state%Ice_shelf_CSp)

References mom_diag_mediator::diag_mediator_end(), mom_ice_shelf::ice_shelf_end(), and ocean_model_save_restart().

Here is the call graph for this function:

◆ ocean_model_flux_init()

subroutine, public mom_ocean_model_nuopc::ocean_model_flux_init ( type(ocean_state_type), optional, pointer  OS,
integer, intent(in), optional  verbosity 
)

ocean_model_flux_init is used to initialize properties of the air-sea fluxes as determined by various run-time parameters. It can be called from non-ocean PEs, or PEs that have not yet been initialzed, and it can safely be called multiple times.

Parameters
osAn optional pointer to the ocean state, used to figure out if this is an ocean PE that has already been initialized.
[in]verbosityA 0-9 integer indicating a level of verbosity.

Definition at line 982 of file mom_ocean_model_nuopc.F90.

982  type(ocean_state_type), optional, pointer :: OS !< An optional pointer to the ocean state,
983  !! used to figure out if this is an ocean PE that
984  !! has already been initialized.
985  integer, optional, intent(in) :: verbosity !< A 0-9 integer indicating a level of verbosity.
986 
987  logical :: OS_is_set
988  integer :: verbose
989 
990  os_is_set = .false. ; if (present(os)) os_is_set = associated(os)
991 
992  ! Use this to control the verbosity of output; consider rethinking this logic later.
993  verbose = 5 ; if (os_is_set) verbose = 3
994  if (present(verbosity)) verbose = verbosity
995 
996  call call_tracer_flux_init(verbosity=verbose)
997 

References mom_tracer_flow_control::call_tracer_flux_init().

Here is the call graph for this function:

◆ ocean_model_init()

subroutine, public mom_ocean_model_nuopc::ocean_model_init ( type(ocean_public_type), intent(inout), target  Ocean_sfc,
type(ocean_state_type), pointer  OS,
type(time_type), intent(in)  Time_init,
type(time_type), intent(in)  Time_in,
type(coupler_1d_bc_type), intent(in), optional  gas_fields_ocn,
character(len=*), intent(in), optional  input_restart_file 
)

ocean_model_init initializes the ocean model, including registering fields for restarts and reading restart files if appropriate.

This subroutine initializes both the ocean state and the ocean surface type. Because of the way that indicies and domains are handled, Ocean_sfc must have been used in a previous call to initialize_ocean_type.

Parameters
[in,out]ocean_sfcA structure containing various publicly
osA structure whose internal contents are private to ocean_model_mod that may be used to contain all information about the ocean's interior state.
[in]time_initThe start time for the coupled model's calendar
[in]time_inThe time at which to initialize the ocean model.
[in]gas_fields_ocnIf present, this type describes the
[in]input_restart_fileIf present, name of restart file to read

Definition at line 226 of file mom_ocean_model_nuopc.F90.

226  type(ocean_public_type), target, &
227  intent(inout) :: Ocean_sfc !< A structure containing various publicly
228  !! visible ocean surface properties after initialization,
229  !! the data in this type is intent out.
230  type(ocean_state_type), pointer :: OS !< A structure whose internal
231  !! contents are private to ocean_model_mod that may be used to
232  !! contain all information about the ocean's interior state.
233  type(time_type), intent(in) :: Time_init !< The start time for the coupled model's calendar
234  type(time_type), intent(in) :: Time_in !< The time at which to initialize the ocean model.
235  type(coupler_1d_bc_type), &
236  optional, intent(in) :: gas_fields_ocn !< If present, this type describes the
237  !! ocean and surface-ice fields that will participate
238  !! in the calculation of additional gas or other
239  !! tracer fluxes, and can be used to spawn related
240  !! internal variables in the ice model.
241  character(len=*), optional, intent(in) :: input_restart_file !< If present, name of restart file to read
242  ! Local variables
243  real :: Rho0 ! The Boussinesq ocean density, in kg m-3.
244  real :: G_Earth ! The gravitational acceleration in m s-2.
245  real :: HFrz !< If HFrz > 0 (m), melt potential will be computed.
246  !! The actual depth over which melt potential is computed will
247  !! min(HFrz, OBLD), where OBLD is the boundary layer depth.
248  !! If HFrz <= 0 (default), melt potential will not be computed.
249  logical :: use_melt_pot!< If true, allocate melt_potential array
250 
251 ! This include declares and sets the variable "version".
252 #include "version_variable.h"
253  character(len=40) :: mdl = "ocean_model_init" ! This module's name.
254  character(len=48) :: stagger
255  integer :: secs, days
256  type(param_file_type) :: param_file !< A structure to parse for run-time parameters
257  logical :: use_temperature
258 
259  call calltree_enter("ocean_model_init(), ocean_model_MOM.F90")
260  if (associated(os)) then
261  call mom_error(warning, "ocean_model_init called with an associated "// &
262  "ocean_state_type structure. Model is already initialized.")
263  return
264  endif
265  allocate(os)
266 
267  os%is_ocean_pe = ocean_sfc%is_ocean_pe
268  if (.not.os%is_ocean_pe) return
269 
270  os%Time = time_in
271  call initialize_mom(os%Time, time_init, param_file, os%dirs, os%MOM_CSp, &
272  os%restart_CSp, time_in, offline_tracer_mode=os%offline_tracer_mode, &
273  input_restart_file=input_restart_file, &
274  diag_ptr=os%diag, count_calls=.true.)
275  call get_mom_state_elements(os%MOM_CSp, g=os%grid, gv=os%GV, us=os%US, c_p=os%C_p, &
276  use_temp=use_temperature)
277  os%fluxes%C_p = os%C_p
278 
279  ! Read all relevant parameters and write them to the model log.
280  call log_version(param_file, mdl, version, "")
281 
282  call get_param(param_file, mdl, "SINGLE_STEPPING_CALL", os%single_step_call, &
283  "If true, advance the state of MOM with a single step "//&
284  "including both dynamics and thermodynamics. If false, "//&
285  "the two phases are advanced with separate calls.", default=.true.)
286  call get_param(param_file, mdl, "DT", os%dt, &
287  "The (baroclinic) dynamics time step. The time-step that "//&
288  "is actually used will be an integer fraction of the "//&
289  "forcing time-step.", units="s", fail_if_missing=.true.)
290  call get_param(param_file, mdl, "DT_THERM", os%dt_therm, &
291  "The thermodynamic and tracer advection time step. "//&
292  "Ideally DT_THERM should be an integer multiple of DT "//&
293  "and less than the forcing or coupling time-step, unless "//&
294  "THERMO_SPANS_COUPLING is true, in which case DT_THERM "//&
295  "can be an integer multiple of the coupling timestep. By "//&
296  "default DT_THERM is set to DT.", units="s", default=os%dt)
297  call get_param(param_file, "MOM", "THERMO_SPANS_COUPLING", os%thermo_spans_coupling, &
298  "If true, the MOM will take thermodynamic and tracer "//&
299  "timesteps that can be longer than the coupling timestep. "//&
300  "The actual thermodynamic timestep that is used in this "//&
301  "case is the largest integer multiple of the coupling "//&
302  "timestep that is less than or equal to DT_THERM.", default=.false.)
303  call get_param(param_file, mdl, "DIABATIC_FIRST", os%diabatic_first, &
304  "If true, apply diabatic and thermodynamic processes, "//&
305  "including buoyancy forcing and mass gain or loss, "//&
306  "before stepping the dynamics forward.", default=.false.)
307 
308  call get_param(param_file, mdl, "RESTART_CONTROL", os%Restart_control, &
309  "An integer whose bits encode which restart files are "//&
310  "written. Add 2 (bit 1) for a time-stamped file, and odd "//&
311  "(bit 0) for a non-time-stamped file. A restart file "//&
312  "will be saved at the end of the run segment for any "//&
313  "non-negative value.", default=1)
314  call get_param(param_file, mdl, "OCEAN_SURFACE_STAGGER", stagger, &
315  "A case-insensitive character string to indicate the "//&
316  "staggering of the surface velocity field that is "//&
317  "returned to the coupler. Valid values include "//&
318  "'A', 'B', or 'C'.", default="C")
319  if (uppercase(stagger(1:1)) == 'A') then ; ocean_sfc%stagger = agrid
320  elseif (uppercase(stagger(1:1)) == 'B') then ; ocean_sfc%stagger = bgrid_ne
321  elseif (uppercase(stagger(1:1)) == 'C') then ; ocean_sfc%stagger = cgrid_ne
322  else ; call mom_error(fatal,"ocean_model_init: OCEAN_SURFACE_STAGGER = "// &
323  trim(stagger)//" is invalid.") ; endif
324 
325  call get_param(param_file, mdl, "EPS_OMESH",os%eps_omesh, &
326  "Maximum allowable difference between ESMF mesh and "//&
327  "MOM6 domain coordinates in nuopc cap.", &
328  units="degrees", default=1.e-4)
329  call get_param(param_file, mdl, "RESTORE_SALINITY",os%restore_salinity, &
330  "If true, the coupled driver will add a globally-balanced "//&
331  "fresh-water flux that drives sea-surface salinity "//&
332  "toward specified values.", default=.false.)
333  call get_param(param_file, mdl, "RESTORE_TEMPERATURE",os%restore_temp, &
334  "If true, the coupled driver will add a "//&
335  "heat flux that drives sea-surface temperature "//&
336  "toward specified values.", default=.false.)
337  call get_param(param_file, mdl, "RHO_0", rho0, &
338  "The mean ocean density used with BOUSSINESQ true to "//&
339  "calculate accelerations and the mass for conservation "//&
340  "properties, or with BOUSSINSEQ false to convert some "//&
341  "parameters from vertical units of m to kg m-2.", &
342  units="kg m-3", default=1035.0)
343  call get_param(param_file, mdl, "G_EARTH", g_earth, &
344  "The gravitational acceleration of the Earth.", &
345  units="m s-2", default = 9.80)
346 
347  call get_param(param_file, mdl, "ICE_SHELF", os%use_ice_shelf, &
348  "If true, enables the ice shelf model.", default=.false.)
349 
350  call get_param(param_file, mdl, "ICEBERGS_APPLY_RIGID_BOUNDARY", os%icebergs_alter_ocean, &
351  "If true, allows icebergs to change boundary condition felt by ocean", default=.false.)
352 
353  os%press_to_z = 1.0/(rho0*g_earth)
354 
355  call get_param(param_file, mdl, "HFREEZE", hfrz, &
356  "If HFREEZE > 0, melt potential will be computed. The actual depth "//&
357  "over which melt potential is computed will be min(HFREEZE, OBLD), "//&
358  "where OBLD is the boundary layer depth. If HFREEZE <= 0 (default), "//&
359  "melt potential will not be computed.", units="m", default=-1.0, do_not_log=.true.)
360 
361  if (hfrz .gt. 0.0) then
362  use_melt_pot=.true.
363  else
364  use_melt_pot=.false.
365  endif
366 
367  ! Consider using a run-time flag to determine whether to do the diagnostic
368  ! vertical integrals, since the related 3-d sums are not negligible in cost.
369  call allocate_surface_state(os%sfc_state, os%grid, use_temperature, &
370  do_integrals=.true., gas_fields_ocn=gas_fields_ocn, use_meltpot=use_melt_pot)
371 
372  call surface_forcing_init(time_in, os%grid, os%US, param_file, os%diag, &
373  os%forcing_CSp, os%restore_salinity, os%restore_temp)
374 
375  if (os%use_ice_shelf) then
376  call initialize_ice_shelf(param_file, os%grid, os%Time, os%ice_shelf_CSp, &
377  os%diag, os%forces, os%fluxes)
378  endif
379  if (os%icebergs_alter_ocean) then
380  call marine_ice_init(os%Time, os%grid, param_file, os%diag, os%marine_ice_CSp)
381  if (.not. os%use_ice_shelf) &
382  call allocate_forcing_type(os%grid, os%fluxes, shelf=.true.)
383  endif
384 
385  call get_param(param_file, mdl, "USE_WAVES", os%Use_Waves, &
386  "If true, enables surface wave modules.", default=.false.)
387  if (os%use_waves) then
388  call mom_wave_interface_init(os%Time, os%grid, os%GV, os%US, param_file, os%Waves, os%diag)
389  else
390  call mom_wave_interface_init_lite(param_file)
391  endif
392 
393  if (associated(os%grid%Domain%maskmap)) then
394  call initialize_ocean_public_type(os%grid%Domain%mpp_domain, ocean_sfc, &
395  os%diag, maskmap=os%grid%Domain%maskmap, &
396  gas_fields_ocn=gas_fields_ocn)
397  else
398  call initialize_ocean_public_type(os%grid%Domain%mpp_domain, ocean_sfc, &
399  os%diag, gas_fields_ocn=gas_fields_ocn)
400  endif
401 
402  ! This call can only occur here if the coupler_bc_type variables have been
403  ! initialized already using the information from gas_fields_ocn.
404  if (present(gas_fields_ocn)) then
405  call coupler_type_set_diags(ocean_sfc%fields, "ocean_sfc", &
406  ocean_sfc%axes(1:2), time_in)
407 
408  call extract_surface_state(os%MOM_CSp, os%sfc_state)
409 
410  call convert_state_to_ocean_type(os%sfc_state, ocean_sfc, os%grid, os%US)
411 
412  endif
413 
414  call close_param_file(param_file)
415  call diag_mediator_close_registration(os%diag)
416 
417  if (is_root_pe()) &
418  write(*,'(/12x,a/)') '======== COMPLETED MOM INITIALIZATION ========'
419 
420  call calltree_leave("ocean_model_init(")

References mom_error_handler::calltree_enter(), mom_error_handler::calltree_leave(), mom_file_parser::close_param_file(), convert_state_to_ocean_type(), mom_diag_mediator::diag_mediator_close_registration(), initialize_ocean_public_type(), mom_marine_ice::marine_ice_init(), mom_wave_interface::mom_wave_interface_init_lite(), and mom_string_functions::uppercase().

Here is the call graph for this function:

◆ ocean_model_init_sfc()

subroutine, public mom_ocean_model_nuopc::ocean_model_init_sfc ( type(ocean_state_type), pointer  OS,
type(ocean_public_type), intent(inout)  Ocean_sfc 
)

This subroutine extracts the surface properties from the ocean's internal state and stores them in the ocean type returned to the calling ice model. It has to be separate from the ocean_initialization call because the coupler module allocates the space for some of these variables.

Parameters
osThe structure with the complete ocean state
[in,out]ocean_sfcA structure containing various publicly visible ocean surface properties after initialization, whose elements have their data set here.

Definition at line 961 of file mom_ocean_model_nuopc.F90.

961  type(ocean_state_type), pointer :: OS !< The structure with the complete ocean state
962  type(ocean_public_type), intent(inout) :: Ocean_sfc !< A structure containing various publicly
963  !! visible ocean surface properties after initialization, whose
964  !! elements have their data set here.
965  integer :: is, ie, js, je
966 
967  is = os%grid%isc ; ie = os%grid%iec ; js = os%grid%jsc ; je = os%grid%jec
968  call coupler_type_spawn(ocean_sfc%fields, os%sfc_state%tr_fields, &
969  (/is,is,ie,ie/), (/js,js,je,je/), as_needed=.true.)
970 
971  call extract_surface_state(os%MOM_CSp, os%sfc_state)
972 
973  call convert_state_to_ocean_type(os%sfc_state, ocean_sfc, os%grid, os%US)
974 

References convert_state_to_ocean_type().

Here is the call graph for this function:

◆ ocean_model_restart()

subroutine, public mom_ocean_model_nuopc::ocean_model_restart ( type(ocean_state_type), pointer  OS,
character(len=*), intent(in), optional  timestamp,
character(len=*), intent(in), optional  restartname 
)

This subroutine writes out the ocean model restart file.

Parameters
osA pointer to the structure containing the internal ocean state being saved to a restart file
[in]timestampAn optional timestamp string that should be prepended to the file name. (Currently this is unused.)
[in]restartnameName of restart file to use This option distinguishes the cesm interface from the non-cesm interface

Definition at line 673 of file mom_ocean_model_nuopc.F90.

673  type(ocean_state_type), pointer :: OS !< A pointer to the structure containing the
674  !! internal ocean state being saved to a restart file
675  character(len=*), optional, intent(in) :: timestamp !< An optional timestamp string that should be
676  !! prepended to the file name. (Currently this is unused.)
677  character(len=*), optional, intent(in) :: restartname !< Name of restart file to use
678  !! This option distinguishes the cesm interface from the
679  !! non-cesm interface
680 
681  if (.not.mom_state_is_synchronized(os%MOM_CSp)) &
682  call mom_error(warning, "End of MOM_main reached with inconsistent "//&
683  "dynamics and advective times. Additional restart fields "//&
684  "that have not been coded yet would be required for reproducibility.")
685  if (.not.os%fluxes%fluxes_used) call mom_error(fatal, "ocean_model_restart "//&
686  "was called with unused buoyancy fluxes. For conservation, the ocean "//&
687  "restart files can only be created after the buoyancy forcing is applied.")
688 
689  if (present(restartname)) then
690  call save_restart(os%dirs%restart_output_dir, os%Time, os%grid, &
691  os%restart_CSp, gv=os%GV, filename=restartname)
692  call forcing_save_restart(os%forcing_CSp, os%grid, os%Time, &
693  os%dirs%restart_output_dir) ! Is this needed?
694  if (os%use_ice_shelf) then
695  call ice_shelf_save_restart(os%Ice_shelf_CSp, os%Time, &
696  os%dirs%restart_output_dir)
697  endif
698  else
699  if (btest(os%Restart_control,1)) then
700  call save_restart(os%dirs%restart_output_dir, os%Time, os%grid, &
701  os%restart_CSp, .true., gv=os%GV)
702  call forcing_save_restart(os%forcing_CSp, os%grid, os%Time, &
703  os%dirs%restart_output_dir, .true.)
704  if (os%use_ice_shelf) then
705  call ice_shelf_save_restart(os%Ice_shelf_CSp, os%Time, os%dirs%restart_output_dir, .true.)
706  endif
707  endif
708  if (btest(os%Restart_control,0)) then
709  call save_restart(os%dirs%restart_output_dir, os%Time, os%grid, &
710  os%restart_CSp, gv=os%GV)
711  call forcing_save_restart(os%forcing_CSp, os%grid, os%Time, &
712  os%dirs%restart_output_dir)
713  if (os%use_ice_shelf) then
714  call ice_shelf_save_restart(os%Ice_shelf_CSp, os%Time, os%dirs%restart_output_dir)
715  endif
716  endif
717  endif
718 

References mom_surface_forcing_nuopc::forcing_save_restart(), mom_ice_shelf::ice_shelf_save_restart(), and mom_restart::save_restart().

Here is the call graph for this function:

◆ ocean_model_save_restart()

subroutine, public mom_ocean_model_nuopc::ocean_model_save_restart ( type(ocean_state_type), pointer  OS,
type(time_type), intent(in)  Time,
character(len=*), intent(in), optional  directory,
character(len=*), intent(in), optional  filename_suffix 
)

ocean_model_save_restart causes restart files associated with the ocean to be written out.

Parameters
osA pointer to the structure containing the internal ocean state (in).
[in]timeThe model time at this call, needed for mpp_write calls.
[in]directoryAn optional directory into which to write these restart files.
[in]filename_suffixAn optional suffix (e.g., a time-stamp) to append to the restart file names.

Definition at line 742 of file mom_ocean_model_nuopc.F90.

742  type(ocean_state_type), pointer :: OS !< A pointer to the structure containing the
743  !! internal ocean state (in).
744  type(time_type), intent(in) :: Time !< The model time at this call, needed for mpp_write calls.
745  character(len=*), optional, intent(in) :: directory !< An optional directory into which to
746  !! write these restart files.
747  character(len=*), optional, intent(in) :: filename_suffix !< An optional suffix (e.g., a time-stamp)
748  !! to append to the restart file names.
749 ! Note: This is a new routine - it will need to exist for the new incremental
750 ! checkpointing. It will also be called by ocean_model_end, giving the same
751 ! restart behavior as now in FMS.
752  character(len=200) :: restart_dir
753 
754  if (.not.mom_state_is_synchronized(os%MOM_CSp)) &
755  call mom_error(warning, "ocean_model_save_restart called with inconsistent "//&
756  "dynamics and advective times. Additional restart fields "//&
757  "that have not been coded yet would be required for reproducibility.")
758  if (.not.os%fluxes%fluxes_used) call mom_error(fatal, "ocean_model_save_restart "//&
759  "was called with unused buoyancy fluxes. For conservation, the ocean "//&
760  "restart files can only be created after the buoyancy forcing is applied.")
761 
762  if (present(directory)) then ; restart_dir = directory
763  else ; restart_dir = os%dirs%restart_output_dir ; endif
764 
765  call save_restart(restart_dir, time, os%grid, os%restart_CSp, gv=os%GV)
766 
767  call forcing_save_restart(os%forcing_CSp, os%grid, time, restart_dir)
768 
769  if (os%use_ice_shelf) then
770  call ice_shelf_save_restart(os%Ice_shelf_CSp, os%Time, os%dirs%restart_output_dir)
771  endif
772 

References mom_surface_forcing_nuopc::forcing_save_restart(), mom_ice_shelf::ice_shelf_save_restart(), and mom_restart::save_restart().

Referenced by ocean_model_end().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ocean_public_type_chksum()

subroutine, public mom_ocean_model_nuopc::ocean_public_type_chksum ( character(len=*), intent(in)  id,
integer, intent(in)  timestep,
type(ocean_public_type), intent(in)  ocn 
)

Write out FMS-format checsums on fields from the ocean surface state.

Parameters
[in]idAn identifying string for this call
[in]timestepThe number of elapsed timesteps
[in]ocnA structure containing various publicly visible ocean surface fields.

Definition at line 1044 of file mom_ocean_model_nuopc.F90.

1044 
1045  character(len=*), intent(in) :: id !< An identifying string for this call
1046  integer, intent(in) :: timestep !< The number of elapsed timesteps
1047  type(ocean_public_type), intent(in) :: ocn !< A structure containing various publicly
1048  !! visible ocean surface fields.
1049  integer :: n, m, outunit
1050 
1051  outunit = stdout()
1052 
1053  write(outunit,*) "BEGIN CHECKSUM(ocean_type):: ", id, timestep
1054  write(outunit,100) 'ocean%t_surf ',mpp_chksum(ocn%t_surf )
1055  write(outunit,100) 'ocean%s_surf ',mpp_chksum(ocn%s_surf )
1056  write(outunit,100) 'ocean%u_surf ',mpp_chksum(ocn%u_surf )
1057  write(outunit,100) 'ocean%v_surf ',mpp_chksum(ocn%v_surf )
1058  write(outunit,100) 'ocean%sea_lev ',mpp_chksum(ocn%sea_lev)
1059  write(outunit,100) 'ocean%frazil ',mpp_chksum(ocn%frazil )
1060  write(outunit,100) 'ocean%melt_potential ',mpp_chksum(ocn%melt_potential)
1061 
1062  call coupler_type_write_chksums(ocn%fields, outunit, 'ocean%')
1063 100 FORMAT(" CHECKSUM::",a20," = ",z20)
1064 

◆ ocean_stock_pe()

subroutine, public mom_ocean_model_nuopc::ocean_stock_pe ( type(ocean_state_type), pointer  OS,
integer, intent(in)  index,
real, intent(out)  value,
integer, intent(in), optional  time_index 
)

Ocean_stock_pe - returns the integrated stocks of heat, water, etc. for conservation checks. Because of the way FMS is coded, only the root PE has the integrated amount, while all other PEs get 0.

Parameters
osA structure containing the internal ocean state. The data in OS is intent in.
[in]indexThe stock index for the quantity of interest.
[out]valueSum returned for the conservation quantity of interest.
[in]time_indexAn unused optional argument, present only for interfacial compatibility with other models.

Definition at line 1004 of file mom_ocean_model_nuopc.F90.

1004  use stock_constants_mod, only : istock_water, istock_heat,istock_salt
1005  type(ocean_state_type), pointer :: OS !< A structure containing the internal ocean state.
1006  !! The data in OS is intent in.
1007  integer, intent(in) :: index !< The stock index for the quantity of interest.
1008  real, intent(out) :: value !< Sum returned for the conservation quantity of interest.
1009  integer, optional, intent(in) :: time_index !< An unused optional argument, present only for
1010  !! interfacial compatibility with other models.
1011 ! Arguments: OS - A structure containing the internal ocean state.
1012 ! (in) index - Index of conservation quantity of interest.
1013 ! (in) value - Sum returned for the conservation quantity of interest.
1014 ! (in,opt) time_index - Index for time level to use if this is necessary.
1015 
1016  real :: salt
1017 
1018  value = 0.0
1019  if (.not.associated(os)) return
1020  if (.not.os%is_ocean_pe) return
1021 
1022  select case (index)
1023  case (istock_water) ! Return the mass of fresh water in the ocean in kg.
1024  if (os%GV%Boussinesq) then
1025  call get_ocean_stocks(os%MOM_CSp, mass=value, on_pe_only=.true.)
1026  else ! In non-Boussinesq mode, the mass of salt needs to be subtracted.
1027  call get_ocean_stocks(os%MOM_CSp, mass=value, salt=salt, on_pe_only=.true.)
1028  value = value - salt
1029  endif
1030  case (istock_heat) ! Return the heat content of the ocean in J.
1031  call get_ocean_stocks(os%MOM_CSp, heat=value, on_pe_only=.true.)
1032  case (istock_salt) ! Return the mass of the salt in the ocean in kg.
1033  call get_ocean_stocks(os%MOM_CSp, salt=value, on_pe_only=.true.)
1034  case default ; value = 0.0
1035  end select
1036  ! If the FMS coupler is changed so that Ocean_stock_PE is only called on
1037  ! ocean PEs, uncomment the following and eliminate the on_PE_only flags above.
1038  ! if (.not.is_root_pe()) value = 0.0
1039 

References mom::get_ocean_stocks().

Here is the call graph for this function:

◆ update_ocean_model()

subroutine, public mom_ocean_model_nuopc::update_ocean_model ( type(ice_ocean_boundary_type), intent(in)  Ice_ocean_boundary,
type(ocean_state_type), pointer  OS,
type(ocean_public_type), intent(inout)  Ocean_sfc,
type(time_type), intent(in)  time_start_update,
type(time_type), intent(in)  Ocean_coupling_time_step,
logical, intent(in), optional  update_dyn,
logical, intent(in), optional  update_thermo,
logical, intent(in), optional  Ocn_fluxes_used 
)

update_ocean_model uses the forcing in Ice_ocean_boundary to advance the ocean model's state from the input value of Ocean_state (which must be for time time_start_update) for a time interval of Ocean_coupling_time_step, returning the publicly visible ocean surface properties in Ocean_sfc and storing the new ocean properties in Ocean_state.

Parameters
[in]ice_ocean_boundaryA structure containing the
osA pointer to a private structure containing
[in,out]ocean_sfcA structure containing all the
[in]time_start_updateThe time at the beginning of the update step.
[in]ocean_coupling_time_stepThe amount of time over which to advance the ocean.
[in]update_dynIf present and false, do not do updates due to the ocean dynamics.
[in]update_thermoIf present and false, do not do updates due to the ocean thermodynamics or remapping.
[in]ocn_fluxes_usedIf present, this indicates whether the cumulative thermodynamic fluxes from the ocean, like frazil, have been used and should be reset.

Definition at line 431 of file mom_ocean_model_nuopc.F90.

431  type(ice_ocean_boundary_type), &
432  intent(in) :: Ice_ocean_boundary !< A structure containing the
433  !! various forcing fields coming from the ice.
434  type(ocean_state_type), &
435  pointer :: OS !< A pointer to a private structure containing
436  !! the internal ocean state.
437  type(ocean_public_type), &
438  intent(inout) :: Ocean_sfc !< A structure containing all the
439  !! publicly visible ocean surface fields after
440  !! a coupling time step. The data in this type is
441  !! intent out.
442  type(time_type), intent(in) :: time_start_update !< The time at the beginning of the update step.
443  type(time_type), intent(in) :: Ocean_coupling_time_step !< The amount of time over
444  !! which to advance the ocean.
445  logical, optional, intent(in) :: update_dyn !< If present and false, do not do updates
446  !! due to the ocean dynamics.
447  logical, optional, intent(in) :: update_thermo !< If present and false, do not do updates
448  !! due to the ocean thermodynamics or remapping.
449  logical, optional, intent(in) :: Ocn_fluxes_used !< If present, this indicates whether the
450  !! cumulative thermodynamic fluxes from the ocean,
451  !! like frazil, have been used and should be reset.
452  ! Local variables
453  type(time_type) :: Master_time ! This allows step_MOM to temporarily change
454  ! the time that is seen by internal modules.
455  type(time_type) :: Time1 ! The value of the ocean model's time at the
456  ! start of a call to step_MOM.
457  integer :: index_bnds(4) ! The computational domain index bounds in the
458  ! ice-ocean boundary type.
459  real :: weight ! Flux accumulation weight
460  real :: dt_coupling ! The coupling time step in seconds.
461  integer :: nts ! The number of baroclinic dynamics time steps
462  ! within dt_coupling.
463  real :: dt_therm ! A limited and quantized version of OS%dt_therm (sec)
464  real :: dt_dyn ! The dynamics time step in sec.
465  real :: dtdia ! The diabatic time step in sec.
466  real :: t_elapsed_seg ! The elapsed time in this update segment, in s.
467  integer :: n, n_max, n_last_thermo
468  type(time_type) :: Time2 ! A temporary time.
469  logical :: thermo_does_span_coupling ! If true, thermodynamic forcing spans
470  ! multiple dynamic timesteps.
471  logical :: do_dyn ! If true, step the ocean dynamics and transport.
472  logical :: do_thermo ! If true, step the ocean thermodynamics.
473  logical :: step_thermo ! If true, take a thermodynamic step.
474  integer :: secs, days
475  integer :: is, ie, js, je
476 
477  call calltree_enter("update_ocean_model(), MOM_ocean_model_nuopc.F90")
478  call get_time(ocean_coupling_time_step, secs, days)
479  dt_coupling = 86400.0*real(days) + real(secs)
480 
481  if (time_start_update /= os%Time) then
482  call mom_error(warning, "update_ocean_model: internal clock does not "//&
483  "agree with time_start_update argument.")
484  endif
485  if (.not.associated(os)) then
486  call mom_error(fatal, "update_ocean_model called with an unassociated "// &
487  "ocean_state_type structure. ocean_model_init must be "// &
488  "called first to allocate this structure.")
489  return
490  endif
491 
492  do_dyn = .true. ; if (present(update_dyn)) do_dyn = update_dyn
493  do_thermo = .true. ; if (present(update_thermo)) do_thermo = update_thermo
494 
495  ! This is benign but not necessary if ocean_model_init_sfc was called or if
496  ! OS%sfc_state%tr_fields was spawned in ocean_model_init. Consider removing it.
497  is = os%grid%isc ; ie = os%grid%iec ; js = os%grid%jsc ; je = os%grid%jec
498  call coupler_type_spawn(ocean_sfc%fields, os%sfc_state%tr_fields, &
499  (/is,is,ie,ie/), (/js,js,je,je/), as_needed=.true.)
500 
501  ! Translate Ice_ocean_boundary into fluxes.
502  call mpp_get_compute_domain(ocean_sfc%Domain, index_bnds(1), index_bnds(2), &
503  index_bnds(3), index_bnds(4))
504 
505  weight = 1.0
506 
507  call convert_iob_to_forces(ice_ocean_boundary, os%forces, index_bnds, os%Time, &
508  os%grid, os%US, os%forcing_CSp)
509 
510  if (os%fluxes%fluxes_used) then
511  if (do_thermo) &
512  call convert_iob_to_fluxes(ice_ocean_boundary, os%fluxes, index_bnds, os%Time, dt_coupling, &
513  os%grid, os%US, os%forcing_CSp, os%sfc_state, &
514  os%restore_salinity, os%restore_temp)
515 
516  ! Add ice shelf fluxes
517  if (os%use_ice_shelf) then
518  if (do_thermo) &
519  call shelf_calc_flux(os%sfc_state, os%fluxes, os%Time, dt_coupling, os%Ice_shelf_CSp)
520  if (do_dyn) &
521  call add_shelf_forces(os%grid, os%US, os%Ice_shelf_CSp, os%forces)
522  endif
523  if (os%icebergs_alter_ocean) then
524  if (do_dyn) &
525  call iceberg_forces(os%grid, os%forces, os%use_ice_shelf, &
526  os%sfc_state, dt_coupling, os%marine_ice_CSp)
527  if (do_thermo) &
528  call iceberg_fluxes(os%grid, os%US, os%fluxes, os%use_ice_shelf, &
529  os%sfc_state, dt_coupling, os%marine_ice_CSp)
530  endif
531 
532  ! Fields that exist in both the forcing and mech_forcing types must be copied.
533  call copy_common_forcing_fields(os%forces, os%fluxes, os%grid, skip_pres=.true.)
534 
535 #ifdef _USE_GENERIC_TRACER
536  call enable_averaging(dt_coupling, os%Time + ocean_coupling_time_step, os%diag) !Is this needed?
537  call mom_generic_tracer_fluxes_accumulate(os%fluxes, weight) !here weight=1, just saving the current fluxes
538 #endif
539  else
540  os%flux_tmp%C_p = os%fluxes%C_p
541  if (do_thermo) &
542  call convert_iob_to_fluxes(ice_ocean_boundary, os%flux_tmp, index_bnds, os%Time, dt_coupling, &
543  os%grid, os%US, os%forcing_CSp, os%sfc_state, os%restore_salinity,os%restore_temp)
544 
545  if (os%use_ice_shelf) then
546  if (do_thermo) &
547  call shelf_calc_flux(os%sfc_state, os%flux_tmp, os%Time, dt_coupling, os%Ice_shelf_CSp)
548  if (do_dyn) &
549  call add_shelf_forces(os%grid, os%US, os%Ice_shelf_CSp, os%forces)
550  endif
551  if (os%icebergs_alter_ocean) then
552  if (do_dyn) &
553  call iceberg_forces(os%grid, os%forces, os%use_ice_shelf, &
554  os%sfc_state, dt_coupling, os%marine_ice_CSp)
555  if (do_thermo) &
556  call iceberg_fluxes(os%grid, os%US, os%flux_tmp, os%use_ice_shelf, &
557  os%sfc_state, dt_coupling, os%marine_ice_CSp)
558  endif
559 
560  call forcing_accumulate(os%flux_tmp, os%forces, os%fluxes, os%grid, weight)
561  ! Some of the fields that exist in both the forcing and mech_forcing types
562  ! (e.g., ustar) are time-averages must be copied back to the forces type.
563  call copy_back_forcing_fields(os%fluxes, os%forces, os%grid)
564 
565 #ifdef _USE_GENERIC_TRACER
566  call mom_generic_tracer_fluxes_accumulate(os%flux_tmp, weight) !weight of the current flux in the running average
567 #endif
568  endif
569  call set_derived_forcing_fields(os%forces, os%fluxes, os%grid, os%US, os%GV%Rho0)
570  call set_net_mass_forcing(os%fluxes, os%forces, os%grid, os%US)
571 
572  if (os%use_waves) then
573  call update_surface_waves(os%grid, os%GV, os%US, os%time, ocean_coupling_time_step, os%waves)
574  endif
575 
576  if (os%nstep==0) then
577  call finish_mom_initialization(os%Time, os%dirs, os%MOM_CSp, os%restart_CSp)
578  endif
579 
580  call disable_averaging(os%diag)
581  master_time = os%Time ; time1 = os%Time
582 
583  if (os%offline_tracer_mode) then
584  call step_offline(os%forces, os%fluxes, os%sfc_state, time1, dt_coupling, os%MOM_CSp)
585  elseif ((.not.do_thermo) .or. (.not.do_dyn)) then
586  ! The call sequence is being orchestrated from outside of update_ocean_model.
587  call step_mom(os%forces, os%fluxes, os%sfc_state, time1, dt_coupling, os%MOM_CSp, &
588  waves=os%Waves, do_dynamics=do_thermo, do_thermodynamics=do_dyn, &
589  reset_therm=ocn_fluxes_used)
590  !### What to do with these? , start_cycle=(n==1), end_cycle=.false., cycle_length=dt_coupling)
591 
592  elseif (os%single_step_call) then
593  call step_mom(os%forces, os%fluxes, os%sfc_state, time1, dt_coupling, os%MOM_CSp, waves=os%Waves)
594  else
595  n_max = 1 ; if (dt_coupling > os%dt) n_max = ceiling(dt_coupling/os%dt - 0.001)
596  dt_dyn = dt_coupling / real(n_max)
597  thermo_does_span_coupling = (os%thermo_spans_coupling .and. &
598  (os%dt_therm > 1.5*dt_coupling))
599 
600  if (thermo_does_span_coupling) then
601  dt_therm = dt_coupling * floor(os%dt_therm / dt_coupling + 0.001)
602  nts = floor(dt_therm/dt_dyn + 0.001)
603  else
604  nts = max(1,min(n_max,floor(os%dt_therm/dt_dyn + 0.001)))
605  n_last_thermo = 0
606  endif
607 
608  time2 = time1 ; t_elapsed_seg = 0.0
609  do n=1,n_max
610  if (os%diabatic_first) then
611  if (thermo_does_span_coupling) call mom_error(fatal, &
612  "MOM is not yet set up to have restarts that work with "//&
613  "THERMO_SPANS_COUPLING and DIABATIC_FIRST.")
614  if (modulo(n-1,nts)==0) then
615  dtdia = dt_dyn*min(nts,n_max-(n-1))
616  call step_mom(os%forces, os%fluxes, os%sfc_state, time2, dtdia, os%MOM_CSp, &
617  waves=os%Waves, do_dynamics=.false., do_thermodynamics=.true., &
618  start_cycle=(n==1), end_cycle=.false., cycle_length=dt_coupling)
619  endif
620 
621  call step_mom(os%forces, os%fluxes, os%sfc_state, time2, dt_dyn, os%MOM_CSp, &
622  waves=os%Waves, do_dynamics=.true., do_thermodynamics=.false., &
623  start_cycle=.false., end_cycle=(n==n_max), cycle_length=dt_coupling)
624  else
625  call step_mom(os%forces, os%fluxes, os%sfc_state, time2, dt_dyn, os%MOM_CSp, &
626  waves=os%Waves, do_dynamics=.true., do_thermodynamics=.false., &
627  start_cycle=(n==1), end_cycle=.false., cycle_length=dt_coupling)
628 
629  step_thermo = .false.
630  if (thermo_does_span_coupling) then
631  dtdia = dt_therm
632  step_thermo = mom_state_is_synchronized(os%MOM_CSp, adv_dyn=.true.)
633  elseif ((modulo(n,nts)==0) .or. (n==n_max)) then
634  dtdia = dt_dyn*(n - n_last_thermo)
635  n_last_thermo = n
636  step_thermo = .true.
637  endif
638 
639  if (step_thermo) then
640  ! Back up Time2 to the start of the thermodynamic segment.
641  time2 = time2 - set_time(int(floor((dtdia - dt_dyn) + 0.5)))
642  call step_mom(os%forces, os%fluxes, os%sfc_state, time2, dtdia, os%MOM_CSp, &
643  waves=os%Waves, do_dynamics=.false., do_thermodynamics=.true., &
644  start_cycle=.false., end_cycle=(n==n_max), cycle_length=dt_coupling)
645  endif
646  endif
647 
648  t_elapsed_seg = t_elapsed_seg + dt_dyn
649  time2 = time1 + set_time(int(floor(t_elapsed_seg + 0.5)))
650  enddo
651  endif
652 
653  os%Time = master_time + ocean_coupling_time_step
654  os%nstep = os%nstep + 1
655 
656  call mech_forcing_diags(os%forces, dt_coupling, os%grid, os%Time, os%diag, os%forcing_CSp%handles)
657 
658  if (os%fluxes%fluxes_used) then
659  call forcing_diagnostics(os%fluxes, os%sfc_state, os%grid, os%US, os%Time, os%diag, os%forcing_CSp%handles)
660  endif
661 
662 ! Translate state into Ocean.
663 ! call convert_state_to_ocean_type(OS%sfc_state, Ocean_sfc, OS%grid, &
664 ! Ice_ocean_boundary%p, OS%press_to_z)
665  call convert_state_to_ocean_type(os%sfc_state, ocean_sfc, os%grid, os%US)
666  call coupler_type_send_data(ocean_sfc%fields, os%Time)
667 
668  call calltree_leave("update_ocean_model()")

References mom_ice_shelf::add_shelf_forces(), mom_error_handler::calltree_enter(), mom_error_handler::calltree_leave(), convert_state_to_ocean_type(), mom_forcing_type::forcing_diagnostics(), mom_marine_ice::iceberg_fluxes(), mom_marine_ice::iceberg_forces(), mom_forcing_type::mech_forcing_diags(), mom::step_offline(), and mom_wave_interface::update_surface_waves().

Here is the call graph for this function: