MOM6
ocean_model_mod Module Reference

Data Types

interface  ocean_model_data_get
 
type  ocean_public_type
 
type  ocean_state_type
 

Functions/Subroutines

subroutine, public ocean_model_init (Ocean_sfc, OS, Time_init, Time_in)
 
subroutine, public update_ocean_model (Ice_ocean_boundary, OS, Ocean_sfc, time_start_update, Ocean_coupling_time_step)
 
subroutine add_berg_flux_to_shelf (G, fluxes, use_ice_shelf, density_ice, kv_ice, latent_heat_fusion, state, time_step, berg_area_threshold)
 
subroutine, public ocean_model_restart (OS, timestamp)
 
subroutine, public ocean_model_end (Ocean_sfc, Ocean_state, Time)
 
subroutine, public ocean_model_save_restart (OS, Time, directory, filename_suffix)
 
subroutine initialize_ocean_public_type (input_domain, Ocean_sfc, diag, maskmap)
 
subroutine convert_state_to_ocean_type (state, Ocean_sfc, G, use_conT_absS, patm, press_to_z)
 
subroutine, public ocean_model_init_sfc (OS, Ocean_sfc)
 
subroutine, public ocean_model_flux_init (OS)
 
subroutine, public ocean_stock_pe (OS, index, value, time_index)
 
subroutine ocean_model_data2d_get (OS, Ocean, name, array2D, isc, jsc)
 
subroutine ocean_model_data1d_get (OS, Ocean, name, value)
 
subroutine, public ocean_public_type_chksum (id, timestep, ocn)
 

Function/Subroutine Documentation

◆ add_berg_flux_to_shelf()

subroutine ocean_model_mod::add_berg_flux_to_shelf ( type(ocean_grid_type), intent(inout)  G,
type(forcing), intent(inout)  fluxes,
logical, intent(in)  use_ice_shelf,
real, intent(in)  density_ice,
real, intent(in)  kv_ice,
real, intent(in)  latent_heat_fusion,
type(surface), intent(inout)  state,
real, intent(in)  time_step,
real, intent(in)  berg_area_threshold 
)
private
Parameters
[in,out]gThe ocean's grid structure

Definition at line 526 of file ocean_model_MOM.F90.

References mom_domains::to_all.

Referenced by update_ocean_model().

526  type(ocean_grid_type), intent(inout) :: g !< The ocean's grid structure
527  type(forcing), intent(inout) :: fluxes
528  type(surface), intent(inout) :: state
529  logical, intent(in) :: use_ice_shelf
530  real, intent(in) :: kv_ice ! The viscosity of ice, in m2 s-1.
531  real, intent(in) :: density_ice ! A typical density of ice, in kg m-3.
532  real, intent(in) :: latent_heat_fusion ! The latent heat of fusion, in J kg-1.
533  real, intent(in) :: time_step ! The latent heat of fusion, in J kg-1.
534  real, intent(in) :: berg_area_threshold !Area threshold for zero'ing fluxes bellow iceberg
535 ! Arguments:
536 ! (in) fluxes - A structure of surface fluxes that may be used.
537 ! (in) G - The ocean's grid structure.
538  real :: fraz ! refreezing rate in kg m-2 s-1
539  integer :: i, j, is, ie, js, je, isd, ied, jsd, jed
540  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
541  isd = g%isd ; jsd = g%jsd ; ied = g%ied ; jed = g%jed
542  !This routine adds iceberg data to the ice shelf data (if ice shelf is used)
543  !which can then be used to change the top of ocean boundary condition used in
544  !the ocean model. This routine is taken from the add_shelf_flux subroutine
545  !within the ice shelf model.
546 
547  if (.not. (((associated(fluxes%frac_shelf_h) .and. associated(fluxes%frac_shelf_u)) &
548  .and.(associated(fluxes%frac_shelf_v) .and. associated(fluxes%ustar_shelf)))&
549  .and.(associated(fluxes%rigidity_ice_u) .and. associated(fluxes%rigidity_ice_v)))) return
550 
551  if (.not. ((associated(fluxes%area_berg) .and. associated(fluxes%ustar_berg)) .and. associated(fluxes%mass_berg) ) ) return
552 
553  if (.not. use_ice_shelf) then
554  fluxes%frac_shelf_h(:,:)=0.
555  fluxes%frac_shelf_u(:,:)=0.
556  fluxes%frac_shelf_v(:,:)=0.
557  fluxes%ustar_shelf(:,:)=0.
558  fluxes%rigidity_ice_u(:,:)=0.
559  fluxes%rigidity_ice_v(:,:)=0.
560  endif
561 
562  do j=jsd,jed ; do i=isd,ied
563  if (g%areaT(i,j) > 0.0) &
564  fluxes%frac_shelf_h(i,j) = fluxes%frac_shelf_h(i,j) + fluxes%area_berg(i,j)
565  fluxes%ustar_shelf(i,j) = fluxes%ustar_shelf(i,j) + fluxes%ustar_berg(i,j)
566  enddo ; enddo
567  !do I=isd,ied-1 ; do j=isd,jed
568  do j=jsd,jed ; do i=isd,ied-1 ! ### changed stride order; i->ied-1?
569  fluxes%frac_shelf_u(i,j) = 0.0
570  if ((g%areaT(i,j) + g%areaT(i+1,j) > 0.0)) & ! .and. (G%dxdy_u(I,j) > 0.0)) &
571  fluxes%frac_shelf_u(i,j) = fluxes%frac_shelf_u(i,j) + (((fluxes%area_berg(i,j)*g%areaT(i,j)) + (fluxes%area_berg(i+1,j)*g%areaT(i+1,j))) / &
572  (g%areaT(i,j) + g%areaT(i+1,j)))
573  fluxes%rigidity_ice_u(i,j) = fluxes%rigidity_ice_u(i,j) +((kv_ice / density_ice) * &
574  min(fluxes%mass_berg(i,j), fluxes%mass_berg(i+1,j)))
575  enddo ; enddo
576  do j=jsd,jed-1 ; do i=isd,ied ! ### change stride order; j->jed-1?
577  !do i=isd,ied ; do J=isd,jed-1
578  fluxes%frac_shelf_v(i,j) = 0.0
579  if ((g%areaT(i,j) + g%areaT(i,j+1) > 0.0)) & ! .and. (G%dxdy_v(i,J) > 0.0)) &
580  fluxes%frac_shelf_v(i,j) = fluxes%frac_shelf_v(i,j) + (((fluxes%area_berg(i,j)*g%areaT(i,j)) + (fluxes%area_berg(i,j+1)*g%areaT(i,j+1))) / &
581  (g%areaT(i,j) + g%areaT(i,j+1) ))
582  fluxes%rigidity_ice_v(i,j) = fluxes%rigidity_ice_v(i,j) +((kv_ice / density_ice) * &
583  max(fluxes%mass_berg(i,j), fluxes%mass_berg(i,j+1)))
584  enddo ; enddo
585  call pass_vector(fluxes%frac_shelf_u, fluxes%frac_shelf_v, g%domain, to_all, cgrid_ne)
586 
587  !Zero'ing out other fluxes under the tabular icebergs
588  if (berg_area_threshold >= 0.) then
589  do j=jsd,jed ; do i=isd,ied
590  if (fluxes%frac_shelf_h(i,j) > berg_area_threshold) then !Only applying for ice shelf covering most of cell
591 
592  if (associated(fluxes%sw)) fluxes%sw(i,j) = 0.0
593  if (associated(fluxes%lw)) fluxes%lw(i,j) = 0.0
594  if (associated(fluxes%latent)) fluxes%latent(i,j) = 0.0
595  if (associated(fluxes%evap)) fluxes%evap(i,j) = 0.0
596 
597  ! Add frazil formation diagnosed by the ocean model (J m-2) in the
598  ! form of surface layer evaporation (kg m-2 s-1). Update lprec in the
599  ! control structure for diagnostic purposes.
600 
601  if (associated(state%frazil)) then
602  fraz = state%frazil(i,j) / time_step / latent_heat_fusion
603  if (associated(fluxes%evap)) fluxes%evap(i,j) = fluxes%evap(i,j) - fraz
604  !CS%lprec(i,j)=CS%lprec(i,j) - fraz
605  state%frazil(i,j) = 0.0
606  endif
607 
608  !Alon: Should these be set to zero too?
609  if (associated(fluxes%sens)) fluxes%sens(i,j) = 0.0
610  if (associated(fluxes%salt_flux)) fluxes%salt_flux(i,j) = 0.0
611  if (associated(fluxes%lprec)) fluxes%lprec(i,j) = 0.0
612  endif
613  enddo ; enddo
614  endif
615 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the caller graph for this function:

◆ convert_state_to_ocean_type()

subroutine ocean_model_mod::convert_state_to_ocean_type ( type(surface), intent(inout)  state,
type(ocean_public_type), intent(inout), target  Ocean_sfc,
type(ocean_grid_type), intent(inout)  G,
logical, intent(in)  use_conT_absS,
real, dimension(:,:), intent(in), optional  patm,
real, intent(in), optional  press_to_z 
)
private
Parameters
[in,out]gThe ocean's grid structure

Definition at line 758 of file ocean_model_MOM.F90.

References mom_constants::celsius_kelvin_offset.

Referenced by ocean_model_init_sfc(), and update_ocean_model().

758  type(surface), intent(inout) :: state
759  type(ocean_public_type), target, intent(inout) :: ocean_sfc
760  type(ocean_grid_type), intent(inout) :: g !< The ocean's grid structure
761  logical, intent(in) :: use_cont_abss
762  real, optional, intent(in) :: patm(:,:)
763  real, optional, intent(in) :: press_to_z
764 ! This subroutine translates the coupler's ocean_data_type into MOM's
765 ! surface state variable. This may eventually be folded into the MOM
766 ! code that calculates the surface state in the first place.
767 ! Note the offset in the arrays because the ocean_data_type has no
768 ! halo points in its arrays and always uses absolute indicies.
769  real :: igr0
770  character(len=48) :: val_str
771  integer :: isc_bnd, iec_bnd, jsc_bnd, jec_bnd
772  integer :: i, j, i0, j0, is, ie, js, je
773 
774  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
775  call pass_vector(state%u,state%v,g%Domain)
776 
777  call mpp_get_compute_domain(ocean_sfc%Domain, isc_bnd, iec_bnd, &
778  jsc_bnd, jec_bnd)
779  if (present(patm)) then
780  ! Check that the inidicies in patm are (isc_bnd:iec_bnd,jsc_bnd:jec_bnd).
781  if (.not.present(press_to_z)) call mom_error(fatal, &
782  'convert_state_to_ocean_type: press_to_z must be present if patm is.')
783  endif
784 
785  i0 = is - isc_bnd ; j0 = js - jsc_bnd
786  !If directed convert the surface T&S
787  !from conservative T to potential T and
788  !from absolute (reference) salinity to practical salinity
789  !
790  if(use_cont_abss) then
791  do j=jsc_bnd,jec_bnd ; do i=isc_bnd,iec_bnd
792  ocean_sfc%s_surf(i,j) = gsw_sp_from_sr(state%SSS(i+i0,j+j0))
793  ocean_sfc%t_surf(i,j) = gsw_pt_from_ct(state%SSS(i+i0,j+j0),state%SST(i+i0,j+j0)) + celsius_kelvin_offset
794  enddo ; enddo
795  else
796  do j=jsc_bnd,jec_bnd ; do i=isc_bnd,iec_bnd
797  ocean_sfc%t_surf(i,j) = state%SST(i+i0,j+j0) + celsius_kelvin_offset
798  ocean_sfc%s_surf(i,j) = state%SSS(i+i0,j+j0)
799  enddo ; enddo
800  endif
801 
802  do j=jsc_bnd,jec_bnd ; do i=isc_bnd,iec_bnd
803  ocean_sfc%sea_lev(i,j) = state%sea_lev(i+i0,j+j0)
804  if (present(patm)) &
805  ocean_sfc%sea_lev(i,j) = ocean_sfc%sea_lev(i,j) + patm(i,j) * press_to_z
806  if (associated(state%frazil)) &
807  ocean_sfc%frazil(i,j) = state%frazil(i+i0,j+j0)
808  ocean_sfc%area(i,j) = g%areaT(i+i0,j+j0)
809  enddo ; enddo
810 
811  if (ocean_sfc%stagger == agrid) then
812  do j=jsc_bnd,jec_bnd ; do i=isc_bnd,iec_bnd
813  ocean_sfc%u_surf(i,j) = g%mask2dT(i+i0,j+j0)*0.5*(state%u(i+i0,j+j0)+state%u(i-1+i0,j+j0))
814  ocean_sfc%v_surf(i,j) = g%mask2dT(i+i0,j+j0)*0.5*(state%v(i+i0,j+j0)+state%v(i+i0,j-1+j0))
815  enddo ; enddo
816  elseif (ocean_sfc%stagger == bgrid_ne) then
817  do j=jsc_bnd,jec_bnd ; do i=isc_bnd,iec_bnd
818  ocean_sfc%u_surf(i,j) = g%mask2dBu(i+i0,j+j0)*0.5*(state%u(i+i0,j+j0)+state%u(i+i0,j+j0+1))
819  ocean_sfc%v_surf(i,j) = g%mask2dBu(i+i0,j+j0)*0.5*(state%v(i+i0,j+j0)+state%v(i+i0+1,j+j0))
820  enddo ; enddo
821  elseif (ocean_sfc%stagger == cgrid_ne) then
822  do j=jsc_bnd,jec_bnd ; do i=isc_bnd,iec_bnd
823  ocean_sfc%u_surf(i,j) = g%mask2dCu(i+i0,j+j0)*state%u(i+i0,j+j0)
824  ocean_sfc%v_surf(i,j) = g%mask2dCv(i+i0,j+j0)*state%v(i+i0,j+j0)
825  enddo ; enddo
826  else
827  write(val_str, '(I8)') ocean_sfc%stagger
828  call mom_error(fatal, "convert_state_to_ocean_type: "//&
829  "Ocean_sfc%stagger has the unrecognized value of "//trim(val_str))
830  endif
831 
832  if (.not.associated(state%tr_fields,ocean_sfc%fields)) &
833  call mom_error(fatal,'state%tr_fields is not pointing to Ocean_sfc%fields')
834 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the caller graph for this function:

◆ initialize_ocean_public_type()

subroutine ocean_model_mod::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 
)
private

Definition at line 719 of file ocean_model_MOM.F90.

Referenced by ocean_model_init().

719  type(domain2d), intent(in) :: input_domain
720  type(ocean_public_type), intent(inout) :: ocean_sfc
721  type(diag_ctrl), intent(in) :: diag
722  logical, intent(in), optional :: maskmap(:,:)
723  integer :: xsz, ysz, layout(2)
724  ! ice-ocean-boundary fields are always allocated using absolute indicies
725  ! and have no halos.
726  integer :: isc_bnd, iec_bnd, jsc_bnd, jec_bnd
727 
728  call mpp_get_layout(input_domain,layout)
729  call mpp_get_global_domain(input_domain, xsize=xsz, ysize=ysz)
730  if(PRESENT(maskmap)) then
731  call mpp_define_domains((/1,xsz,1,ysz/),layout,ocean_sfc%Domain, maskmap=maskmap)
732  else
733  call mpp_define_domains((/1,xsz,1,ysz/),layout,ocean_sfc%Domain)
734  endif
735  call mpp_get_compute_domain(ocean_sfc%Domain, isc_bnd, iec_bnd, &
736  jsc_bnd, jec_bnd)
737 
738  allocate ( ocean_sfc%t_surf (isc_bnd:iec_bnd,jsc_bnd:jec_bnd), &
739  ocean_sfc%s_surf (isc_bnd:iec_bnd,jsc_bnd:jec_bnd), &
740  ocean_sfc%u_surf (isc_bnd:iec_bnd,jsc_bnd:jec_bnd), &
741  ocean_sfc%v_surf (isc_bnd:iec_bnd,jsc_bnd:jec_bnd), &
742  ocean_sfc%sea_lev(isc_bnd:iec_bnd,jsc_bnd:jec_bnd), &
743  ocean_sfc%area (isc_bnd:iec_bnd,jsc_bnd:jec_bnd), &
744  ocean_sfc%frazil (isc_bnd:iec_bnd,jsc_bnd:jec_bnd))
745 
746  ocean_sfc%t_surf = 0.0 ! time averaged sst (Kelvin) passed to atmosphere/ice model
747  ocean_sfc%s_surf = 0.0 ! time averaged sss (psu) passed to atmosphere/ice models
748  ocean_sfc%u_surf = 0.0 ! time averaged u-current (m/sec) passed to atmosphere/ice models
749  ocean_sfc%v_surf = 0.0 ! time averaged v-current (m/sec) passed to atmosphere/ice models
750  ocean_sfc%sea_lev = 0.0 ! time averaged thickness of top model grid cell (m) plus patm/rho0/grav
751  ocean_sfc%frazil = 0.0 ! time accumulated frazil (J/m^2) passed to ice model
752  ocean_sfc%area = 0.0
753  ocean_sfc%axes = diag%axesT1%handles !diag axes to be used by coupler tracer flux diagnostics
754 
Here is the caller graph for this function:

◆ ocean_model_data1d_get()

subroutine ocean_model_mod::ocean_model_data1d_get ( type(ocean_state_type), pointer  OS,
type(ocean_public_type), intent(in)  Ocean,
character(len=*), intent(in)  name,
real, intent(out)  value 
)

Definition at line 1041 of file ocean_model_MOM.F90.

1041  type(ocean_state_type), pointer :: os
1042  type(ocean_public_type), intent(in) :: ocean
1043  character(len=*) , intent(in) :: name
1044  real , intent(out):: value
1045 
1046  if (.not.associated(os)) return
1047  if (.not.os%is_ocean_pe) return
1048 
1049  select case(name)
1050  case('c_p')
1051  value = os%C_p
1052  case default
1053  call mom_error(fatal,'get_ocean_grid_data1D: unknown argument name='//name)
1054  end select
1055 
1056 

◆ ocean_model_data2d_get()

subroutine ocean_model_mod::ocean_model_data2d_get ( type(ocean_state_type), pointer  OS,
type(ocean_public_type), intent(in)  Ocean,
character(len=*), intent(in)  name,
real, dimension(isc:,jsc:), intent(out)  array2D,
integer, intent(in)  isc,
integer, intent(in)  jsc 
)

Definition at line 993 of file ocean_model_MOM.F90.

References mom_constants::celsius_kelvin_offset.

994  type(ocean_state_type), pointer :: os
995  type(ocean_public_type), intent(in) :: ocean
996  character(len=*) , intent(in) :: name
997  real, dimension(isc:,jsc:), intent(out):: array2d
998  integer , intent(in) :: isc,jsc
999 
1000  integer :: g_isc, g_iec, g_jsc, g_jec,g_isd, g_ied, g_jsd, g_jed, i, j
1001 
1002  if (.not.associated(os)) return
1003  if (.not.os%is_ocean_pe) return
1004 
1005 ! The problem is %areaT is on MOM domain but Ice_Ocean_Boundary%... is on mpp domain.
1006 ! We want to return the MOM data on the mpp (compute) domain
1007 ! Get MOM domain extents
1008  call mpp_get_compute_domain(os%grid%Domain%mpp_domain, g_isc, g_iec, g_jsc, g_jec)
1009  call mpp_get_data_domain (os%grid%Domain%mpp_domain, g_isd, g_ied, g_jsd, g_jed)
1010 
1011  g_isc = g_isc-g_isd+1 ; g_iec = g_iec-g_isd+1 ; g_jsc = g_jsc-g_jsd+1 ; g_jec = g_jec-g_jsd+1
1012 
1013 
1014  select case(name)
1015  case('area')
1016  array2d(isc:,jsc:) = os%grid%areaT(g_isc:g_iec,g_jsc:g_jec)
1017  case('mask')
1018  array2d(isc:,jsc:) = os%grid%mask2dT(g_isc:g_iec,g_jsc:g_jec)
1019 !OR same result
1020 ! do j=g_jsc,g_jec; do i=g_isc,g_iec
1021 ! array2D(isc+i-g_isc,jsc+j-g_jsc) = OS%grid%mask2dT(i,j)
1022 ! enddo; enddo
1023  case('t_surf')
1024  array2d(isc:,jsc:) = ocean%t_surf(isc:,jsc:)-celsius_kelvin_offset
1025  case('t_pme')
1026  array2d(isc:,jsc:) = ocean%t_surf(isc:,jsc:)-celsius_kelvin_offset
1027  case('t_runoff')
1028  array2d(isc:,jsc:) = ocean%t_surf(isc:,jsc:)-celsius_kelvin_offset
1029  case('t_calving')
1030  array2d(isc:,jsc:) = ocean%t_surf(isc:,jsc:)-celsius_kelvin_offset
1031  case('btfHeat')
1032  array2d(isc:,jsc:) = 0
1033  case default
1034  call mom_error(fatal,'get_ocean_grid_data2D: unknown argument name='//name)
1035  end select
1036 
1037 
real, parameter, public celsius_kelvin_offset

◆ ocean_model_end()

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

Definition at line 659 of file ocean_model_MOM.F90.

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

659  type(ocean_public_type), intent(inout) :: ocean_sfc
660  type(ocean_state_type), pointer :: ocean_state
661  type(time_type), intent(in) :: time
662 
663 ! This subroutine terminates the model run, saving the ocean state in a
664 ! restart file and deallocating any data associated with the ocean.
665 
666 ! Arguments: Ocean_sfc - An ocean_public_type structure that is to be
667 ! deallocated upon termination.
668 ! (inout) Ocean_state - A pointer to the structure containing the internal
669 ! ocean state to be deallocated upon termination.
670 ! (in) Time - The model time, used for writing restarts.
671 
672  call ocean_model_save_restart(ocean_state, time)
673  call diag_mediator_end(time, ocean_state%MOM_CSp%diag)
674  call mom_end(ocean_state%MOM_CSp)
675  if (ocean_state%use_ice_shelf) call ice_shelf_end(ocean_state%Ice_shelf_CSp)
Here is the call graph for this function:

◆ ocean_model_flux_init()

subroutine, public ocean_model_mod::ocean_model_flux_init ( type(ocean_state_type), optional, pointer  OS)

Definition at line 880 of file ocean_model_MOM.F90.

References atmos_ocean_fluxes_mod::aof_set_coupler_flux(), mom_file_parser::close_param_file(), and mom_get_input::get_mom_input().

880  type(ocean_state_type), optional, pointer :: os
881 
882  integer :: dummy
883  character(len=128) :: default_ice_restart_file, default_ocean_restart_file
884  character(len=40) :: mdl = "ocean_model_flux_init" ! This module's name.
885  type(param_file_type) :: param_file !< A structure to parse for run-time parameters
886  type(directories) :: dirs_tmp ! A structure containing several relevant directory paths.
887  logical :: use_ocmip_cfcs, use_mom_generic_tracer
888  logical :: os_is_set
889 
890  os_is_set = .false. ; if (present(os)) os_is_set = associated(os)
891 
892  call get_mom_input(param_file, dirs_tmp, check_params=.false.)
893 
894  call get_param(param_file, mdl, "USE_OCMIP2_CFC", use_ocmip_cfcs, &
895  default=.false., do_not_log=.true.)
896  call get_param(param_file, mdl, "USE_generic_tracer", use_mom_generic_tracer,&
897  default=.false., do_not_log=.true.)
898 
899  call close_param_file(param_file, quiet_close=.true.)
900 
901  if(.not.os_is_set) then
902  if (use_ocmip_cfcs)then
903  default_ice_restart_file = 'ice_ocmip2_cfc.res.nc'
904  default_ocean_restart_file = 'ocmip2_cfc.res.nc'
905 
906  dummy = aof_set_coupler_flux('cfc_11_flux', &
907  flux_type = 'air_sea_gas_flux', implementation = 'ocmip2', &
908  param = (/ 9.36e-07, 9.7561e-06 /), &
909  ice_restart_file = default_ice_restart_file, &
910  ocean_restart_file = default_ocean_restart_file, &
911  caller = "register_OCMIP2_CFC")
912  dummy = aof_set_coupler_flux('cfc_12_flux', &
913  flux_type = 'air_sea_gas_flux', implementation = 'ocmip2', &
914  param = (/ 9.36e-07, 9.7561e-06 /), &
915  ice_restart_file = default_ice_restart_file, &
916  ocean_restart_file = default_ocean_restart_file, &
917  caller = "register_OCMIP2_CFC")
918  endif
919  endif
920 
921  if (use_mom_generic_tracer) then
922 #ifdef _USE_GENERIC_TRACER
923  call mom_generic_flux_init()
924 #else
925  call mom_error(fatal, &
926  "call_tracer_register: use_MOM_generic_tracer=.true. BUT not compiled with _USE_GENERIC_TRACER")
927 #endif
928  endif
929 
Here is the call graph for this function:

◆ ocean_model_init()

subroutine, public ocean_model_mod::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 
)

Definition at line 203 of file ocean_model_MOM.F90.

References mom_forcing_type::allocate_forcing_type(), mom_error_handler::calltree_enter(), mom_error_handler::calltree_leave(), mom_file_parser::close_param_file(), mom_diag_mediator::diag_mediator_close_registration(), initialize_ocean_public_type(), mom_sum_output::mom_sum_output_init(), and mom_string_functions::uppercase().

203  type(ocean_public_type), target, intent(inout) :: ocean_sfc
204  type(ocean_state_type), pointer :: os
205  type(time_type), intent(in) :: time_init
206  type(time_type), intent(in) :: time_in
207 ! This subroutine initializes both the ocean state and the ocean surface type.
208 ! Because of the way that indicies and domains are handled, Ocean_sfc must have
209 ! been used in a previous call to initialize_ocean_type.
210 
211 ! Arguments: Ocean_sfc - A structure containing various publicly visible ocean
212 ! surface properties after initialization, this is intent(out).
213 ! (out,private) OS - A structure whose internal contents are private
214 ! to ocean_model_mod that may be used to contain all
215 ! information about the ocean's interior state.
216 ! (in) Time_init - The start time for the coupled model's calendar.
217 ! (in) Time_in - The time at which to initialize the ocean model.
218  real :: time_unit ! The time unit in seconds for ENERGYSAVEDAYS.
219  real :: rho0 ! The Boussinesq ocean density, in kg m-3.
220  real :: g_earth ! The gravitational acceleration in m s-2.
221 ! This include declares and sets the variable "version".
222 #include "version_variable.h"
223  character(len=40) :: mdl = "ocean_model_init" ! This module's name.
224  character(len=48) :: stagger
225  integer :: secs, days
226  type(param_file_type) :: param_file !< A structure to parse for run-time parameters
227  logical :: offline_tracer_mode
228 
229  call calltree_enter("ocean_model_init(), ocean_model_MOM.F90")
230  if (associated(os)) then
231  call mom_error(warning, "ocean_model_init called with an associated "// &
232  "ocean_state_type structure. Model is already initialized.")
233  return
234  endif
235  allocate(os)
236 
237  os%is_ocean_pe = ocean_sfc%is_ocean_pe
238  if (.not.os%is_ocean_pe) return
239 
240  os%state%tr_fields => ocean_sfc%fields
241  os%Time = time_in
242  call initialize_mom(os%Time, param_file, os%dirs, os%MOM_CSp, time_in, &
243  offline_tracer_mode=offline_tracer_mode)
244  os%grid => os%MOM_CSp%G ; os%GV => os%MOM_CSp%GV
245  os%C_p = os%MOM_CSp%tv%C_p
246  os%fluxes%C_p = os%MOM_CSp%tv%C_p
247 
248  ! Read all relevant parameters and write them to the model log.
249  call log_version(param_file, mdl, version, "")
250  call get_param(param_file, mdl, "RESTART_CONTROL", os%Restart_control, &
251  "An integer whose bits encode which restart files are \n"//&
252  "written. Add 2 (bit 1) for a time-stamped file, and odd \n"//&
253  "(bit 0) for a non-time-stamped file. A restart file \n"//&
254  "will be saved at the end of the run segment for any \n"//&
255  "non-negative value.", default=1)
256  call get_param(param_file, mdl, "TIMEUNIT", time_unit, &
257  "The time unit for ENERGYSAVEDAYS.", &
258  units="s", default=86400.0)
259  call get_param(param_file, mdl, "ENERGYSAVEDAYS",os%energysavedays, &
260  "The interval in units of TIMEUNIT between saves of the \n"//&
261  "energies of the run and other globally summed diagnostics.", &
262  default=set_time(0,days=1), timeunit=time_unit)
263 
264  call get_param(param_file, mdl, "OCEAN_SURFACE_STAGGER", stagger, &
265  "A case-insensitive character string to indicate the \n"//&
266  "staggering of the surface velocity field that is \n"//&
267  "returned to the coupler. Valid values include \n"//&
268  "'A', 'B', or 'C'.", default="C")
269  if (uppercase(stagger(1:1)) == 'A') then ; ocean_sfc%stagger = agrid
270  elseif (uppercase(stagger(1:1)) == 'B') then ; ocean_sfc%stagger = bgrid_ne
271  elseif (uppercase(stagger(1:1)) == 'C') then ; ocean_sfc%stagger = cgrid_ne
272  else ; call mom_error(fatal,"ocean_model_init: OCEAN_SURFACE_STAGGER = "// &
273  trim(stagger)//" is invalid.") ; endif
274 
275  call get_param(param_file, mdl, "RESTORE_SALINITY",os%restore_salinity, &
276  "If true, the coupled driver will add a globally-balanced \n"//&
277  "fresh-water flux that drives sea-surface salinity \n"//&
278  "toward specified values.", default=.false.)
279  call get_param(param_file, mdl, "RESTORE_TEMPERATURE",os%restore_temp, &
280  "If true, the coupled driver will add a \n"//&
281  "heat flux that drives sea-surface temperauture \n"//&
282  "toward specified values.", default=.false.)
283  call get_param(param_file, mdl, "RHO_0", rho0, &
284  "The mean ocean density used with BOUSSINESQ true to \n"//&
285  "calculate accelerations and the mass for conservation \n"//&
286  "properties, or with BOUSSINSEQ false to convert some \n"//&
287  "parameters from vertical units of m to kg m-2.", &
288  units="kg m-3", default=1035.0)
289  call get_param(param_file, mdl, "G_EARTH", g_earth, &
290  "The gravitational acceleration of the Earth.", &
291  units="m s-2", default = 9.80)
292 
293  call get_param(param_file, mdl, "ICE_SHELF", os%use_ice_shelf, &
294  "If true, enables the ice shelf model.", default=.false.)
295 
296  call get_param(param_file, mdl, "ICEBERGS_APPLY_RIGID_BOUNDARY", os%icebergs_apply_rigid_boundary, &
297  "If true, allows icebergs to change boundary condition felt by ocean", default=.false.)
298 
299  if (os%icebergs_apply_rigid_boundary) then
300  call get_param(param_file, mdl, "KV_ICEBERG", os%kv_iceberg, &
301  "The viscosity of the icebergs", units="m2 s-1",default=1.0e10)
302  call get_param(param_file, mdl, "DENSITY_ICEBERGS", os%density_iceberg, &
303  "A typical density of icebergs.", units="kg m-3", default=917.0)
304  call get_param(param_file, mdl, "LATENT_HEAT_FUSION", os%latent_heat_fusion, &
305  "The latent heat of fusion.", units="J/kg", default=hlf)
306  call get_param(param_file, mdl, "BERG_AREA_THRESHOLD", os%berg_area_threshold, &
307  "Fraction of grid cell which iceberg must occupy, so that fluxes \n"//&
308  "below berg are set to zero. Not applied for negative \n"//&
309  " values.", units="non-dim", default=-1.0)
310  endif
311 
312  os%press_to_z = 1.0/(rho0*g_earth)
313 
314  call surface_forcing_init(time_in, os%grid, param_file, os%MOM_CSp%diag, &
315  os%forcing_CSp, os%restore_salinity, os%restore_temp)
316 
317  if (os%use_ice_shelf) then
318  call initialize_ice_shelf(param_file, os%grid, os%Time, os%ice_shelf_CSp, &
319  os%MOM_CSp%diag, os%fluxes)
320  endif
321  if (os%icebergs_apply_rigid_boundary) then
322  !call allocate_forcing_type(OS%grid, OS%fluxes, iceberg=.true.)
323  !This assumes that the iceshelf and ocean are on the same grid. I hope this is true
324  if (.not. os%use_ice_shelf) call allocate_forcing_type(os%grid, os%fluxes, ustar=.true., shelf=.true.)
325  endif
326 
327  call mom_sum_output_init(os%grid, param_file, os%dirs%output_directory, &
328  os%MOM_CSp%ntrunc, time_init, os%sum_output_CSp)
329 
330  ! This call has been moved into the first call to update_ocean_model.
331 ! call write_energy(OS%MOM_CSp%u, OS%MOM_CSp%v, OS%MOM_CSp%h, OS%MOM_CSp%tv, &
332 ! OS%Time, 0, OS%grid, OS%GV, OS%sum_output_CSp, OS%MOM_CSp%tracer_flow_CSp)
333 
334  ! write_energy_time is the next integral multiple of energysavedays.
335  os%write_energy_time = time_init + os%energysavedays * &
336  (1 + (os%Time - time_init) / os%energysavedays)
337 
338  if(ASSOCIATED(os%grid%Domain%maskmap)) then
339  call initialize_ocean_public_type(os%grid%Domain%mpp_domain, ocean_sfc, &
340  os%MOM_CSp%diag, maskmap=os%grid%Domain%maskmap)
341  else
342  call initialize_ocean_public_type(os%grid%Domain%mpp_domain, ocean_sfc, &
343  os%MOM_CSp%diag)
344  endif
345 ! call convert_state_to_ocean_type(state, Ocean_sfc, OS%grid)
346 
347  call close_param_file(param_file)
348  call diag_mediator_close_registration(os%MOM_CSp%diag)
349 
350  if (is_root_pe()) &
351  write(*,'(/12x,a/)') '======== COMPLETED MOM INITIALIZATION ========'
352 
353  call calltree_leave("ocean_model_init(")
Here is the call graph for this function:

◆ ocean_model_init_sfc()

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

Definition at line 849 of file ocean_model_MOM.F90.

References convert_state_to_ocean_type().

849  type(ocean_state_type), pointer :: os
850  type(ocean_public_type), intent(inout) :: ocean_sfc
851 
852  call calculate_surface_state(os%state, os%MOM_CSp%u, &
853  os%MOM_CSp%v, os%MOM_CSp%h, os%MOM_CSp%ave_ssh,&
854  os%grid, os%GV, os%MOM_CSp)
855 
856  call convert_state_to_ocean_type(os%state, ocean_sfc, os%grid, os%MOM_CSp%use_conT_absS)
857 
Here is the call graph for this function:

◆ ocean_model_restart()

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

Definition at line 619 of file ocean_model_MOM.F90.

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

619  type(ocean_state_type), pointer :: os
620  character(len=*), intent(in), optional :: timestamp
621 
622  if (os%MOM_CSp%t_dyn_rel_adv > 0.0) call mom_error(warning, "End of MOM_main reached "//&
623  "with inconsistent dynamics and advective times. Additional restart fields "//&
624  "that have not been coded yet would be required for reproducibility.")
625  if (.not.os%fluxes%fluxes_used) call mom_error(fatal, "ocean_model_restart "//&
626  "was called with unused buoyancy fluxes. For conservation, the ocean "//&
627  "restart files can only be created after the buoyancy forcing is applied.")
628 
629  if (btest(os%Restart_control,1)) then
630  call save_restart(os%dirs%restart_output_dir, os%Time, os%grid, &
631  os%MOM_CSp%restart_CSp, .true., gv=os%GV)
632  call forcing_save_restart(os%forcing_CSp, os%grid, os%Time, &
633  os%dirs%restart_output_dir, .true.)
634  if (os%use_ice_shelf) then
635  call ice_shelf_save_restart(os%Ice_shelf_CSp, os%Time, os%dirs%restart_output_dir, .true.)
636  endif
637  endif
638  if (btest(os%Restart_control,0)) then
639  call save_restart(os%dirs%restart_output_dir, os%Time, os%grid, &
640  os%MOM_CSp%restart_CSp, gv=os%GV)
641  call forcing_save_restart(os%forcing_CSp, os%grid, os%Time, &
642  os%dirs%restart_output_dir)
643  if (os%use_ice_shelf) then
644  call ice_shelf_save_restart(os%Ice_shelf_CSp, os%Time, os%dirs%restart_output_dir)
645  endif
646  endif
647 
Here is the call graph for this function:

◆ ocean_model_save_restart()

subroutine, public ocean_model_mod::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 
)

Definition at line 681 of file ocean_model_MOM.F90.

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

Referenced by ocean_model_end().

681  type(ocean_state_type), pointer :: os
682  type(time_type), intent(in) :: time
683  character(len=*), optional, intent(in) :: directory
684  character(len=*), optional, intent(in) :: filename_suffix
685 ! Arguments: Ocean_state - A structure containing the internal ocean state (in).
686 ! (in) Time - The model time at this call. This is needed for mpp_write calls.
687 ! (in, opt) directory - An optional directory into which to write these restart files.
688 ! (in, opt) filename_suffix - An optional suffix (e.g., a time-stamp) to append
689 ! to the restart file names.
690 
691 ! Note: This is a new routine - it will need to exist for the new incremental
692 ! checkpointing. It will also be called by ocean_model_end, giving the same
693 ! restart behavior as now in FMS.
694  character(len=200) :: restart_dir
695 
696  if (os%MOM_CSp%t_dyn_rel_adv > 0.0) call mom_error(warning, "End of MOM_main reached "//&
697  "with inconsistent dynamics and advective times. Additional restart fields "//&
698  "that have not been coded yet would be required for reproducibility.")
699  if (.not.os%fluxes%fluxes_used) call mom_error(fatal, "ocean_model_save_restart "//&
700  "was called with unused buoyancy fluxes. For conservation, the ocean "//&
701  "restart files can only be created after the buoyancy forcing is applied.")
702 
703  if (present(directory)) then ; restart_dir = directory
704  else ; restart_dir = os%dirs%restart_output_dir ; endif
705 
706  call save_restart(restart_dir, time, os%grid, os%MOM_CSp%restart_CSp, gv=os%GV)
707 
708  call forcing_save_restart(os%forcing_CSp, os%grid, time, restart_dir)
709 
710  if (os%use_ice_shelf) then
711  call ice_shelf_save_restart(os%Ice_shelf_CSp, os%Time, os%dirs%restart_output_dir)
712  endif
713 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ocean_public_type_chksum()

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

Definition at line 1060 of file ocean_model_MOM.F90.

1060 
1061  character(len=*), intent(in) :: id
1062  integer , intent(in) :: timestep
1063  type(ocean_public_type), intent(in) :: ocn
1064  integer :: n,m, outunit
1065 
1066  outunit = stdout()
1067 
1068  write(outunit,*) "BEGIN CHECKSUM(ocean_type):: ", id, timestep
1069  write(outunit,100) 'ocean%t_surf ',mpp_chksum(ocn%t_surf )
1070  write(outunit,100) 'ocean%s_surf ',mpp_chksum(ocn%s_surf )
1071  write(outunit,100) 'ocean%u_surf ',mpp_chksum(ocn%u_surf )
1072  write(outunit,100) 'ocean%v_surf ',mpp_chksum(ocn%v_surf )
1073  write(outunit,100) 'ocean%sea_lev ',mpp_chksum(ocn%sea_lev)
1074  write(outunit,100) 'ocean%frazil ',mpp_chksum(ocn%frazil )
1075 
1076  do n = 1, ocn%fields%num_bcs !{
1077  do m = 1, ocn%fields%bc(n)%num_fields !{
1078  write(outunit,101) 'ocean%',trim(ocn%fields%bc(n)%name), &
1079  trim(ocn%fields%bc(n)%field(m)%name), &
1080  mpp_chksum(ocn%fields%bc(n)%field(m)%values)
1081  enddo !} m
1082  enddo !} n
1083 101 FORMAT(" CHECKSUM::",a6,a,'%',a," = ",z20)
1084 
1085 
1086 100 FORMAT(" CHECKSUM::",a20," = ",z20)

◆ ocean_stock_pe()

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

Definition at line 936 of file ocean_model_MOM.F90.

936  use stock_constants_mod, only : istock_water, istock_heat,istock_salt
937  type(ocean_state_type), pointer :: os
938  integer, intent(in) :: index
939  real, intent(out) :: value
940  integer, optional, intent(in) :: time_index
941 ! Arguments: OS - A structure containing the internal ocean state.
942 ! (in) index - Index of conservation quantity of interest.
943 ! (in) value - Sum returned for the conservation quantity of interest.
944 ! (in,opt) time_index - Index for time level to use if this is necessary.
945 
946  real :: to_heat, to_mass, to_salt, psu_to_kg ! Conversion constants.
947  integer :: i, j, k, is, ie, js, je, nz, ind
948 
949  value = 0.0
950  if (.not.associated(os)) return
951  if (.not.os%is_ocean_pe) return
952 
953  is = os%grid%isc ; ie = os%grid%iec
954  js = os%grid%jsc ; je = os%grid%jec ; nz = os%grid%ke
955 
956  select case (index)
957  case (istock_water)
958  ! Return the mass of fresh water in the ocean on this PE in kg.
959  to_mass = os%GV%H_to_kg_m2
960  if (os%GV%Boussinesq) then
961  do k=1,nz ; do j=js,je ; do i=is,ie ; if (os%grid%mask2dT(i,j) > 0.5) then
962  value = value + to_mass*(os%MOM_CSp%h(i,j,k) * os%grid%areaT(i,j))
963  endif ; enddo ; enddo ; enddo
964  else
965  ! In non-Boussinesq mode, the mass of salt needs to be subtracted.
966  psu_to_kg = 1.0e-3
967  do k=1,nz ; do j=js,je ; do i=is,ie ; if (os%grid%mask2dT(i,j) > 0.5) then
968  value = value + to_mass * ((1.0 - psu_to_kg*os%MOM_CSp%tv%S(i,j,k))*&
969  (os%MOM_CSp%h(i,j,k) * os%grid%areaT(i,j)))
970  endif ; enddo ; enddo ; enddo
971  endif
972  case (istock_heat)
973  ! Return the heat content of the ocean on this PE in J.
974  to_heat = os%GV%H_to_kg_m2 * os%C_p
975  do k=1,nz ; do j=js,je ; do i=is,ie ; if (os%grid%mask2dT(i,j) > 0.5) then
976  value = value + (to_heat * os%MOM_CSp%tv%T(i,j,k)) * &
977  (os%MOM_CSp%h(i,j,k)*os%grid%areaT(i,j))
978  endif ; enddo ; enddo ; enddo
979  case (istock_salt)
980  ! Return the mass of the salt in the ocean on this PE in kg.
981  ! The 1000 converts salinity in PSU to salt in kg kg-1.
982  to_salt = os%GV%H_to_kg_m2 / 1000.0
983  do k=1,nz ; do j=js,je ; do i=is,ie ; if (os%grid%mask2dT(i,j) > 0.5) then
984  value = value + (to_salt * os%MOM_CSp%tv%S(i,j,k)) * &
985  (os%MOM_CSp%h(i,j,k)*os%grid%areaT(i,j))
986  endif ; enddo ; enddo ; enddo
987  case default ; value = 0.0
988  end select
989 

◆ update_ocean_model()

subroutine, public ocean_model_mod::update_ocean_model ( type(ice_ocean_boundary_type), intent(inout)  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 
)

Definition at line 369 of file ocean_model_MOM.F90.

References add_berg_flux_to_shelf(), mom_error_handler::calltree_enter(), mom_error_handler::calltree_leave(), convert_state_to_ocean_type(), and mom::step_offline().

369  type(ice_ocean_boundary_type), intent(inout) :: ice_ocean_boundary
370  type(ocean_state_type), pointer :: os
371  type(ocean_public_type), intent(inout) :: ocean_sfc
372  type(time_type), intent(in) :: time_start_update
373  type(time_type), intent(in) :: ocean_coupling_time_step
374 ! This subroutine uses the forcing in Ice_ocean_boundary to advance the
375 ! ocean model's state from the input value of Ocean_state (which must be for
376 ! time time_start_update) for a time interval of Ocean_coupling_time_step,
377 ! returning the publicly visible ocean surface properties in Ocean_sfc and
378 ! storing the new ocean properties in Ocean_state.
379 
380 ! Arguments: Ice_ocean_boundary - A structure containing the various forcing
381 ! fields coming from the ice. It is intent in.
382 ! (inout) Ocean_state - A structure containing the internal ocean state.
383 ! (out) Ocean_sfc - A structure containing all the publicly visible ocean
384 ! surface fields after a coupling time step.
385 ! (in) time_start_update - The time at the beginning of the update step.
386 ! (in) Ocean_coupling_time_step - The amount of time over which to advance
387 ! the ocean.
388 
389 ! Note: although several types are declared intent(inout), this is to allow for
390 ! the possibility of halo updates and to keep previously allocated memory.
391 ! In practice, Ice_ocean_boundary is intent in, Ocean_state is private to
392 ! this module and intent inout, and Ocean_sfc is intent out.
393  type(time_type) :: master_time ! This allows step_MOM to temporarily change
394  ! the time that is seen by internal modules.
395  type(time_type) :: time1 ! The value of the ocean model's time at the
396  ! start of a call to step_MOM.
397  integer :: index_bnds(4) ! The computational domain index bounds in the
398  ! ice-ocean boundary type.
399  real :: weight ! Flux accumulation weight
400  real :: time_step ! The time step of a call to step_MOM in seconds.
401  integer :: secs, days
402 
403  call calltree_enter("update_ocean_model(), ocean_model_MOM.F90")
404  call get_time(ocean_coupling_time_step, secs, days)
405  time_step = 86400.0*real(days) + real(secs)
406 
407  if (time_start_update /= os%Time) then
408  call mom_error(warning, "update_ocean_model: internal clock does not "//&
409  "agree with time_start_update argument.")
410  endif
411  if (.not.associated(os)) then
412  call mom_error(fatal, "update_ocean_model called with an unassociated "// &
413  "ocean_state_type structure. ocean_model_init must be "// &
414  "called first to allocate this structure.")
415  return
416  endif
417 
418 ! Translate Ice_ocean_boundary into fluxes.
419  call mpp_get_compute_domain(ocean_sfc%Domain, index_bnds(1), index_bnds(2), &
420  index_bnds(3), index_bnds(4))
421 
422  weight = 1.0
423 
424  if (os%fluxes%fluxes_used) then
425  call enable_averaging(time_step, os%Time + ocean_coupling_time_step, os%MOM_CSp%diag) ! Needed to allow diagnostics in convert_IOB
426  call convert_iob_to_fluxes(ice_ocean_boundary, os%fluxes, index_bnds, os%Time, &
427  os%grid, os%forcing_CSp, os%state, os%restore_salinity,os%restore_temp)
428 #ifdef _USE_GENERIC_TRACER
429  call mom_generic_tracer_fluxes_accumulate(os%fluxes, weight) !here weight=1, just saving the current fluxes
430 #endif
431 
432  ! Add ice shelf fluxes
433  if (os%use_ice_shelf) then
434  call shelf_calc_flux(os%State, os%fluxes, os%Time, time_step, os%Ice_shelf_CSp)
435  endif
436  if (os%icebergs_apply_rigid_boundary) then
437  !This assumes that the iceshelf and ocean are on the same grid. I hope this is true
438  call add_berg_flux_to_shelf(os%grid, os%fluxes,os%use_ice_shelf,os%density_iceberg,os%kv_iceberg, os%latent_heat_fusion, os%State, time_step, os%berg_area_threshold)
439  endif
440  ! Indicate that there are new unused fluxes.
441  os%fluxes%fluxes_used = .false.
442  os%fluxes%dt_buoy_accum = time_step
443  else
444  os%flux_tmp%C_p = os%fluxes%C_p
445  call convert_iob_to_fluxes(ice_ocean_boundary, os%flux_tmp, index_bnds, os%Time, &
446  os%grid, os%forcing_CSp, os%state, os%restore_salinity,os%restore_temp)
447  if (os%use_ice_shelf) then
448  call shelf_calc_flux(os%State, os%flux_tmp, os%Time, time_step, os%Ice_shelf_CSp)
449  endif
450  if (os%icebergs_apply_rigid_boundary) then
451  !This assumes that the iceshelf and ocean are on the same grid. I hope this is true
452  call add_berg_flux_to_shelf(os%grid, os%flux_tmp, os%use_ice_shelf,os%density_iceberg,os%kv_iceberg, os%latent_heat_fusion, os%State, time_step, os%berg_area_threshold)
453  endif
454 
455  call forcing_accumulate(os%flux_tmp, os%fluxes, time_step, os%grid, weight)
456 #ifdef _USE_GENERIC_TRACER
457  call mom_generic_tracer_fluxes_accumulate(os%flux_tmp, weight) !weight of the current flux in the running average
458 #endif
459  endif
460 
461  if (os%nstep==0) then
462  call finish_mom_initialization(os%Time, os%dirs, os%MOM_CSp, os%fluxes)
463 
464  call write_energy(os%MOM_CSp%u, os%MOM_CSp%v, os%MOM_CSp%h, os%MOM_CSp%tv, &
465  os%Time, 0, os%grid, os%GV, os%sum_output_CSp, &
466  os%MOM_CSp%tracer_flow_CSp)
467  endif
468 
469  call disable_averaging(os%MOM_CSp%diag)
470  master_time = os%Time ; time1 = os%Time
471 
472  if(os%MOM_Csp%offline_tracer_mode) then
473  call step_offline(os%fluxes, os%state, time1, time_step, os%MOM_CSp)
474  else
475  call step_mom(os%fluxes, os%state, time1, time_step, os%MOM_CSp)
476  endif
477 
478  os%Time = master_time + ocean_coupling_time_step
479  os%nstep = os%nstep + 1
480 
481  call enable_averaging(time_step, os%Time, os%MOM_CSp%diag)
482  call mech_forcing_diags(os%fluxes, time_step, os%grid, &
483  os%MOM_CSp%diag, os%forcing_CSp%handles)
484  call disable_averaging(os%MOM_CSp%diag)
485 
486  if (os%fluxes%fluxes_used) then
487  call enable_averaging(os%fluxes%dt_buoy_accum, os%Time, os%MOM_CSp%diag)
488  call forcing_diagnostics(os%fluxes, os%state, os%fluxes%dt_buoy_accum, &
489  os%grid, os%MOM_CSp%diag, os%forcing_CSp%handles)
490  call accumulate_net_input(os%fluxes, os%state, os%fluxes%dt_buoy_accum, &
491  os%grid, os%sum_output_CSp)
492  call disable_averaging(os%MOM_CSp%diag)
493  endif
494 
495 ! See if it is time to write out the energy.
496  if ((os%Time + ((ocean_coupling_time_step)/2) > os%write_energy_time) .and. &
497  (os%MOM_CSp%t_dyn_rel_adv==0.0)) then
498  call write_energy(os%MOM_CSp%u, os%MOM_CSp%v, os%MOM_CSp%h, os%MOM_CSp%tv, &
499  os%Time, os%nstep, os%grid, os%GV, os%sum_output_CSp, &
500  os%MOM_CSp%tracer_flow_CSp)
501  os%write_energy_time = os%write_energy_time + os%energysavedays
502  endif
503 
504 ! Translate state into Ocean.
505 ! call convert_state_to_ocean_type(OS%state, Ocean_sfc, OS%grid, &
506 ! Ice_ocean_boundary%p, OS%press_to_z)
507  call convert_state_to_ocean_type(os%state, ocean_sfc, os%grid, os%MOM_CSp%use_conT_absS)
508 
509  call calltree_leave("update_ocean_model()")
Here is the call graph for this function: