Skip to content

Commit

Permalink
+Moved iceberg parameters to marine_ice_CS
Browse files Browse the repository at this point in the history
  Moved the parameters related to the icebergs into the control structure for
for the MOM_marine_ice module, and changed the arguments to
add_berg_flux_to_shelf to replace parameter arguments with a control structure
argument.  All answers are bitwise identical, although a public interface has
changed.
  • Loading branch information
Hallberg-NOAA committed May 3, 2018
1 parent 688aaef commit 7b17fe7
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 56 deletions.
62 changes: 21 additions & 41 deletions config_src/coupled_driver/ocean_model_MOM.F90
Original file line number Diff line number Diff line change
Expand Up @@ -142,27 +142,20 @@ module ocean_model_mod
type, public :: ocean_state_type ; private
! This type is private, and can therefore vary between different ocean models.
logical :: is_ocean_PE = .false. !< True if this is an ocean PE.
type(time_type) :: Time !< The ocean model's time and master clock.
integer :: Restart_control !< An integer that is bit-tested to determine whether
!! incremental restart files are saved and whether they
!! have a time stamped name. +1 (bit 0) for generic
!! files and +2 (bit 1) for time-stamped files. A
!! restart file is saved at the end of a run segment
!! unless Restart_control is negative.
type(time_type) :: Time !< The ocean model's time and master clock.
integer :: Restart_control !< An integer that is bit-tested to determine whether
!! incremental restart files are saved and whether they
!! have a time stamped name. +1 (bit 0) for generic
!! files and +2 (bit 1) for time-stamped files. A
!! restart file is saved at the end of a run segment
!! unless Restart_control is negative.

integer :: nstep = 0 !< The number of calls to update_ocean.
logical :: use_ice_shelf !< If true, the ice shelf model is enabled.
logical :: use_waves = .false.! If true use wave coupling.

! Many of the following variables do not appear to belong here. -RWH
logical :: icebergs_apply_rigid_boundary ! If true, the icebergs can change ocean bd condition.
real :: kv_iceberg ! The viscosity of the icebergs in m2/s (for ice rigidity)
real :: berg_area_threshold ! Fraction of grid cell which iceberg must occupy
!so that fluxes below are set to zero. (0.5 is a
!good value to use. Not applied for negative values.
real :: latent_heat_fusion ! Latent heat of fusion
real :: density_iceberg ! A typical density of icebergs in kg/m3 (for ice rigidity)
logical :: use_waves !< If true use wave coupling.

logical :: icebergs_alter_ocean !< If true, the icebergs can change ocean the
!! ocean dynamics and forcing fluxes.
logical :: restore_salinity !< If true, the coupled MOM driver adds a term to
!! restore salinity to a specified value.
logical :: restore_temp !< If true, the coupled MOM driver adds a term to
Expand Down Expand Up @@ -361,22 +354,9 @@ subroutine ocean_model_init(Ocean_sfc, OS, Time_init, Time_in, gas_fields_ocn)
call get_param(param_file, mdl, "ICE_SHELF", OS%use_ice_shelf, &
"If true, enables the ice shelf model.", default=.false.)

call get_param(param_file, mdl, "ICEBERGS_APPLY_RIGID_BOUNDARY", OS%icebergs_apply_rigid_boundary, &
call get_param(param_file, mdl, "ICEBERGS_APPLY_RIGID_BOUNDARY", OS%icebergs_alter_ocean, &
"If true, allows icebergs to change boundary condition felt by ocean", default=.false.)

if (OS%icebergs_apply_rigid_boundary) then
call get_param(param_file, mdl, "KV_ICEBERG", OS%kv_iceberg, &
"The viscosity of the icebergs", units="m2 s-1",default=1.0e10)
call get_param(param_file, mdl, "DENSITY_ICEBERGS", OS%density_iceberg, &
"A typical density of icebergs.", units="kg m-3", default=917.0)
call get_param(param_file, mdl, "LATENT_HEAT_FUSION", OS%latent_heat_fusion, &
"The latent heat of fusion.", units="J/kg", default=hlf)
call get_param(param_file, mdl, "BERG_AREA_THRESHOLD", OS%berg_area_threshold, &
"Fraction of grid cell which iceberg must occupy, so that fluxes \n"//&
"below berg are set to zero. Not applied for negative \n"//&
" values.", units="non-dim", default=-1.0)
endif

OS%press_to_z = 1.0/(Rho0*G_Earth)

! Consider using a run-time flag to determine whether to do the diagnostic
Expand All @@ -391,15 +371,16 @@ subroutine ocean_model_init(Ocean_sfc, OS, Time_init, Time_in, gas_fields_ocn)
call initialize_ice_shelf(param_file, OS%grid, OS%Time, OS%ice_shelf_CSp, &
OS%diag, OS%forces, OS%fluxes)
endif
if (OS%icebergs_apply_rigid_boundary) then
if (OS%icebergs_alter_ocean) then
call marine_ice_init(OS%Time, OS%grid, param_file, OS%diag, OS%marine_ice_CSp)
if (.not. OS%use_ice_shelf) &
call allocate_forcing_type(OS%grid, OS%fluxes, shelf=.true.)
endif

call get_param(param_file,mdl,"USE_WAVES",OS%Use_Waves,&
"If true, enables surface wave modules.",default=.false.)
call get_param(param_file, mdl, "USE_WAVES", OS%Use_Waves, &
"If true, enables surface wave modules.", default=.false.)
if (OS%use_waves) then
call MOM_wave_interface_init(OS%Time,OS%grid,OS%GV,param_file,OS%Waves,OS%diag)
call MOM_wave_interface_init(OS%Time, OS%grid, OS%GV, param_file, OS%Waves, OS%diag)
else
call MOM_wave_interface_init_lite(param_file)
endif
Expand Down Expand Up @@ -541,10 +522,9 @@ subroutine update_ocean_model(Ice_ocean_boundary, OS, Ocean_sfc, &
if (OS%use_ice_shelf) then
call shelf_calc_flux(OS%sfc_state, OS%forces, OS%fluxes, OS%Time, dt_coupling, OS%Ice_shelf_CSp)
endif
if (OS%icebergs_apply_rigid_boundary) then
if (OS%icebergs_alter_ocean) then
call add_berg_flux_to_shelf(OS%grid, OS%forces, OS%fluxes, OS%use_ice_shelf, &
OS%density_iceberg, OS%kv_iceberg, OS%latent_heat_fusion, OS%sfc_state, &
dt_coupling, OS%berg_area_threshold)
OS%sfc_state, dt_coupling, OS%marine_ice_CSp)
endif

! Fields that exist in both the forcing and mech_forcing types must be copied.
Expand All @@ -565,9 +545,9 @@ subroutine update_ocean_model(Ice_ocean_boundary, OS, Ocean_sfc, &
if (OS%use_ice_shelf) then
call shelf_calc_flux(OS%sfc_state, OS%forces, OS%flux_tmp, OS%Time, dt_coupling, OS%Ice_shelf_CSp)
endif
if (OS%icebergs_apply_rigid_boundary) then
call add_berg_flux_to_shelf(OS%grid, OS%forces, OS%flux_tmp, OS%use_ice_shelf, OS%density_iceberg, &
OS%kv_iceberg, OS%latent_heat_fusion, OS%sfc_state, dt_coupling, OS%berg_area_threshold)
if (OS%icebergs_alter_ocean) then
call add_berg_flux_to_shelf(OS%grid, OS%forces, OS%flux_tmp, OS%use_ice_shelf, &
OS%sfc_state, dt_coupling, OS%marine_ice_CSp)
endif

call forcing_accumulate(OS%flux_tmp, OS%forces, OS%fluxes, dt_coupling, OS%grid, weight)
Expand Down
46 changes: 31 additions & 15 deletions src/ice_shelf/MOM_marine_ice.F90
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module MOM_marine_ice

! This file is part of MOM6. See LICENSE.md for the license.

use MOM_constants, only : hlf
use MOM_diag_mediator, only : post_data, query_averaging_enabled, diag_ctrl
use MOM_domains, only : pass_var, pass_vector, AGRID, BGRID_NE, CGRID_NE
use MOM_domains, only : TO_ALL, Omit_Corners
Expand All @@ -24,6 +25,13 @@ module MOM_marine_ice

!> Control structure for MOM_marine_ice
type, public :: marine_ice_CS ; private
real :: kv_iceberg !< The viscosity of the icebergs in m2/s (for ice rigidity)
real :: berg_area_threshold !< Fraction of grid cell which iceberg must occupy
!! so that fluxes below are set to zero. (0.5 is a
!! good value to use.) Not applied for negative values.
real :: latent_heat_fusion !< Latent heat of fusion
real :: density_iceberg !< A typical density of icebergs in kg/m3 (for ice rigidity)

type(time_type), pointer :: Time !< A pointer to the ocean model's clock.
type(diag_ctrl), pointer :: diag !< A structure that is used to regulate the timing of diagnostic output.
end type marine_ice_CS
Expand All @@ -33,23 +41,18 @@ module MOM_marine_ice
!> add_berg_flux_to_shelf adds rigidity and ice-area coverage due to icebergs
!! to the forces type fields, and adds ice-areal coverage and modifies various
!! thermodynamic fluxes due to the presence of icebergs.
subroutine add_berg_flux_to_shelf(G, forces, fluxes, use_ice_shelf, density_ice, kv_ice, &
latent_heat_fusion, sfc_state, time_step, berg_area_threshold)
subroutine add_berg_flux_to_shelf(G, forces, fluxes, use_ice_shelf, sfc_state, &
time_step, CS)
type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure
type(mech_forcing), intent(inout) :: forces !< A structure with the driving mechanical forces
type(forcing), intent(inout) :: fluxes !< A structure with pointers to themodynamic,
!! tracer and mass exchange forcing fields
type(surface), intent(inout) :: sfc_state !< A structure containing fields that
!! describe the surface state of the ocean.
logical, intent(in) :: use_ice_shelf !< If true, this configuration uses ice shelves.
real, intent(in) :: kv_ice !< The viscosity of ice, in m2 s-1.
real, intent(in) :: density_ice !< A typical density of ice, in kg m-3.
real, intent(in) :: latent_heat_fusion !< The latent heat of fusion, in J kg-1.
real, intent(in) :: time_step !< The coupling time step, in s.
real, intent(in) :: berg_area_threshold !< Area threshold for zeroing fluxes below iceberg
! Arguments:
! (in) fluxes - A structure of surface fluxes that may be used.
! (in) G - The ocean's grid structure.
type(marine_ice_CS), pointer :: CS !< Pointer to the control structure for MOM_marine_ice

real :: fraz ! refreezing rate in kg m-2 s-1
real :: I_dt_LHF ! The inverse of the timestep times the latent heat of fusion, in kg J-1 s-1.
real :: kv_rho_ice ! The viscosity of ice divided by its density, in m5 kg-1 s-1.
Expand All @@ -61,6 +64,8 @@ subroutine add_berg_flux_to_shelf(G, forces, fluxes, use_ice_shelf, density_ice,
!the ocean model. This routine is taken from the add_shelf_flux subroutine
!within the ice shelf model.

if (.not.associated(CS)) return

if (.not.(associated(forces%area_berg) .and. associated(forces%mass_berg) ) ) return

if (.not.(associated(forces%frac_shelf_u) .and. associated(forces%frac_shelf_v) .and. &
Expand All @@ -73,12 +78,11 @@ subroutine add_berg_flux_to_shelf(G, forces, fluxes, use_ice_shelf, density_ice,
! This section sets or augments the values of fields in forces.
if (.not. use_ice_shelf) then
forces%frac_shelf_u(:,:) = 0.0 ; forces%frac_shelf_v(:,:) = 0.0
forces%rigidity_ice_u(:,:) = 0.0 ; forces%rigidity_ice_v(:,:) = 0.0
endif

call pass_var(forces%area_berg, G%domain, TO_ALL+Omit_corners, halo=1, complete=.false.)
call pass_var(forces%mass_berg, G%domain, TO_ALL+Omit_corners, halo=1, complete=.true.)
kv_rho_ice = kv_ice / density_ice
kv_rho_ice = CS%kv_iceberg / CS%density_iceberg
do j=js,je ; do I=is-1,ie
if ((G%areaT(i,j) + G%areaT(i+1,j) > 0.0)) & ! .and. (G%dxdy_u(I,j) > 0.0)) &
forces%frac_shelf_u(I,j) = forces%frac_shelf_u(I,j) + &
Expand Down Expand Up @@ -114,10 +118,11 @@ subroutine add_berg_flux_to_shelf(G, forces, fluxes, use_ice_shelf, density_ice,
endif ; enddo ; enddo

!Zero'ing out other fluxes under the tabular icebergs
if (berg_area_threshold >= 0.) then
I_dt_LHF = 1.0 / (time_step * latent_heat_fusion)
if (CS%berg_area_threshold >= 0.) then
I_dt_LHF = 1.0 / (time_step * CS%latent_heat_fusion)
do j=jsd,jed ; do i=isd,ied
if (fluxes%frac_shelf_h(i,j) > berg_area_threshold) then !Only applying for ice shelf covering most of cell
if (fluxes%frac_shelf_h(i,j) > CS%berg_area_threshold) then
! Only applying for ice shelf covering most of cell.

if (associated(fluxes%sw)) fluxes%sw(i,j) = 0.0
if (associated(fluxes%lw)) fluxes%lw(i,j) = 0.0
Expand Down Expand Up @@ -151,7 +156,7 @@ subroutine marine_ice_init(Time, G, param_file, diag, CS)
type(ocean_grid_type), intent(in) :: G !< Ocean grid structure
type(param_file_type), intent(in) :: param_file !< Runtime parameter handles
type(diag_ctrl), target, intent(inout) :: diag !< Diagnostics control structure
type(marine_ice_CS), pointer :: CS !< Control structure for MOM_marine_ice
type(marine_ice_CS), pointer :: CS !< Pointer to the control structure for MOM_marine_ice
! This include declares and sets the variable "version".
#include "version_variable.h"
character(len=40) :: mdl = "MOM_marine_ice" ! This module's name.
Expand All @@ -165,6 +170,17 @@ subroutine marine_ice_init(Time, G, param_file, diag, CS)
! Write all relevant parameters to the model log.
call log_version(mdl, version)

call get_param(param_file, mdl, "KV_ICEBERG", CS%kv_iceberg, &
"The viscosity of the icebergs", units="m2 s-1",default=1.0e10)
call get_param(param_file, mdl, "DENSITY_ICEBERGS", CS%density_iceberg, &
"A typical density of icebergs.", units="kg m-3", default=917.0)
call get_param(param_file, mdl, "LATENT_HEAT_FUSION", CS%latent_heat_fusion, &
"The latent heat of fusion.", units="J/kg", default=hlf)
call get_param(param_file, mdl, "BERG_AREA_THRESHOLD", CS%berg_area_threshold, &
"Fraction of grid cell which iceberg must occupy, so that fluxes \n"//&
"below berg are set to zero. Not applied for negative \n"//&
"values.", units="non-dim", default=-1.0)

end subroutine marine_ice_init

end module MOM_marine_ice

0 comments on commit 7b17fe7

Please sign in to comment.