Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion config_src/drivers/unit_drivers/MOM_sum_driver.F90
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ program MOM_main
use MOM_io, only : MOM_io_init, file_exists, open_file, close_file
use MOM_io, only : check_nml_error, io_infra_init, io_infra_end
use MOM_io, only : APPEND_FILE, ASCII_FILE, READONLY_FILE, SINGLE_FILE
use MOM_unit_scaling, only : unit_scale_type, unit_no_scaling_init, unit_scaling_end

implicit none

Expand All @@ -39,6 +40,8 @@ program MOM_main
type(hor_index_type) :: HI ! A hor_index_type for array extents
type(param_file_type) :: param_file ! The structure indicating the file(s)
! containing all run-time parameters.
type(unit_scale_type), pointer :: US => NULL() !< A structure containing various unit
! conversion factors, but in this case all are 1.
real :: max_depth ! The maximum ocean depth [m]
integer :: verbosity
integer :: num_sums
Expand Down Expand Up @@ -104,7 +107,8 @@ program MOM_main
allocate(depth_tot_fastR(num_sums)) ; depth_tot_fastR(:) = 0.0

! Set up the parameters of the physical grid
call set_grid_metrics(grid, param_file)
call unit_no_scaling_init(US)
call set_grid_metrics(grid, param_file, US)

! Set up the bottom depth, grid%bathyT either analytically or from file
call get_param(param_file, "MOM", "MAXIMUM_DEPTH", max_depth, &
Expand Down Expand Up @@ -162,6 +166,7 @@ program MOM_main
enddo

call destroy_dyn_horgrid(grid)
call unit_scaling_end(US)
call io_infra_end ; call MOM_infra_end

contains
Expand Down
8 changes: 3 additions & 5 deletions src/core/MOM_checksum_packages.F90
Original file line number Diff line number Diff line change
Expand Up @@ -92,23 +92,21 @@ subroutine MOM_state_chksum_3arg(mesg, u, v, h, G, GV, US, haloshift, symmetric)
intent(in) :: v !< Meridional velocity [L T-1 ~> m s-1] or [m s-1]..
real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2].
type(unit_scale_type), optional, intent(in) :: US !< A dimensional unit scaling type, which is
type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type, which is
!! used to rescale u and v if present.
integer, optional, intent(in) :: haloshift !< The width of halos to check (default 0).
logical, optional, intent(in) :: symmetric !< If true, do checksums on the fully
!! symmetric computational domain.
real :: L_T_to_m_s ! A rescaling factor for velocities [m T s-1 L-1 ~> 1] or [1]

integer :: hs
logical :: sym

L_T_to_m_s = 1.0 ; if (present(US)) L_T_to_m_s = US%L_T_to_m_s

! Note that for the chksum calls to be useful for reproducing across PE
! counts, there must be no redundant points, so all variables use is..ie
! and js...je as their extent.
hs = 1 ; if (present(haloshift)) hs = haloshift
sym = .false. ; if (present(symmetric)) sym = symmetric
call uvchksum(mesg//" u", u, v, G%HI, haloshift=hs, symmetric=sym, scale=L_T_to_m_s)
call uvchksum(mesg//" u", u, v, G%HI, haloshift=hs, symmetric=sym, scale=US%L_T_to_m_s)
call hchksum(h, mesg//" h",G%HI, haloshift=hs, scale=GV%H_to_m)
end subroutine MOM_state_chksum_3arg

Expand Down
93 changes: 63 additions & 30 deletions src/framework/MOM_unit_scaling.F90
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,47 @@ module MOM_unit_scaling

implicit none ; private

public unit_scaling_init, unit_scaling_end, fix_restart_unit_scaling
! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional
! consistency testing. These are noted in comments with units like Z, H, L, T, R and Q, along with
! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the rescaled
! combination is a nondimensional variable, the notation would be "a slope [Z L-1 ~> nondim]",
! but if (as the case for the variables here), the rescaled combination is exactly 1, the right
! notation would be something like "a dimensional scaling factor [Z m-1 ~> 1]". If the units
! vary with the Boussinesq approximation, the Boussinesq variant is given first.

public unit_scaling_init, unit_no_scaling_init, unit_scaling_end, fix_restart_unit_scaling

!> Describes various unit conversion factors
type, public :: unit_scale_type
real :: m_to_Z !< A constant that translates distances in meters to the units of depth.
real :: Z_to_m !< A constant that translates distances in the units of depth to meters.
real :: m_to_L !< A constant that translates lengths in meters to the units of horizontal lengths.
real :: L_to_m !< A constant that translates lengths in the units of horizontal lengths to meters.
real :: s_to_T !< A constant that translates time intervals in seconds to the units of time.
real :: T_to_s !< A constant that translates the units of time to seconds.
real :: R_to_kg_m3 !< A constant that translates the units of density to kilograms per meter cubed.
real :: kg_m3_to_R !< A constant that translates kilograms per meter cubed to the units of density.
real :: Q_to_J_kg !< A constant that translates the units of enthalpy to Joules per kilogram.
real :: J_kg_to_Q !< A constant that translates Joules per kilogram to the units of enthalpy.
real :: m_to_Z !< A constant that translates distances in meters to the units of depth [Z m-1 ~> 1]
real :: Z_to_m !< A constant that translates distances in the units of depth to meters [m Z-1 ~> 1]
real :: m_to_L !< A constant that translates lengths in meters to the units of horizontal lengths [L m-1 ~> 1]
real :: L_to_m !< A constant that translates lengths in the units of horizontal lengths to meters [m L-1 ~> 1]
real :: s_to_T !< A constant that translates time intervals in seconds to the units of time [T s-1 ~> 1]
real :: T_to_s !< A constant that translates the units of time to seconds [s T-1 ~> 1]
real :: R_to_kg_m3 !< A constant that translates the units of density to kilograms per meter cubed [kg m-3 R-1 ~> 1]
real :: kg_m3_to_R !< A constant that translates kilograms per meter cubed to the units of density [R m3 kg-1 ~> 1]
real :: Q_to_J_kg !< A constant that translates the units of enthalpy to Joules per kilogram [J kg-1 Q-1 ~> 1]
real :: J_kg_to_Q !< A constant that translates Joules per kilogram to the units of enthalpy [Q kg J-1 ~> 1]

! These are useful combinations of the fundamental scale conversion factors above.
real :: Z_to_L !< Convert vertical distances to lateral lengths
real :: L_to_Z !< Convert lateral lengths to vertical distances
real :: L_T_to_m_s !< Convert lateral velocities from L T-1 to m s-1.
real :: m_s_to_L_T !< Convert lateral velocities from m s-1 to L T-1.
real :: L_T2_to_m_s2 !< Convert lateral accelerations from L T-2 to m s-2.
real :: Z2_T_to_m2_s !< Convert vertical diffusivities from Z2 T-1 to m2 s-1.
real :: m2_s_to_Z2_T !< Convert vertical diffusivities from m2 s-1 to Z2 T-1.
real :: W_m2_to_QRZ_T !< Convert heat fluxes from W m-2 to Q R Z T-1.
real :: QRZ_T_to_W_m2 !< Convert heat fluxes from Q R Z T-1 to W m-2.
! Not used enough: real :: kg_m2_to_RZ !< Convert mass loads from kg m-2 to R Z.
real :: RZ_to_kg_m2 !< Convert mass loads from R Z to kg m-2.
real :: kg_m2s_to_RZ_T !< Convert mass fluxes from kg m-2 s-1 to R Z T-1.
real :: RZ_T_to_kg_m2s !< Convert mass fluxes from R Z T-1 to kg m-2 s-1.
real :: RZ3_T3_to_W_m2 !< Convert turbulent kinetic energy fluxes from R Z3 T-3 to W m-2.
real :: W_m2_to_RZ3_T3 !< Convert turbulent kinetic energy fluxes from W m-2 to R Z3 T-3.
real :: RL2_T2_to_Pa !< Convert pressures from R L2 T-2 to Pa.
! Not used enough: real :: Pa_to_RL2_T2 !< Convert pressures from Pa to R L2 T-2.
real :: Z_to_L !< Convert vertical distances to lateral lengths [L Z-1 ~> 1]
real :: L_to_Z !< Convert lateral lengths to vertical distances [Z L-1 ~> 1]
real :: L_T_to_m_s !< Convert lateral velocities from L T-1 to m s-1 [T m L-1 s-1 ~> 1]
real :: m_s_to_L_T !< Convert lateral velocities from m s-1 to L T-1 [L s T-1 m-1 ~> 1]
real :: L_T2_to_m_s2 !< Convert lateral accelerations from L T-2 to m s-2 [L s2 T-2 m-1 ~> 1]
real :: Z2_T_to_m2_s !< Convert vertical diffusivities from Z2 T-1 to m2 s-1 [T1 m2 Z-2 s-1 ~> 1]
real :: m2_s_to_Z2_T !< Convert vertical diffusivities from m2 s-1 to Z2 T-1 [Z2 s T-1 m-2 ~> 1]
real :: W_m2_to_QRZ_T !< Convert heat fluxes from W m-2 to Q R Z T-1 [Q R Z m2 T-1 W-1 ~> 1]
real :: QRZ_T_to_W_m2 !< Convert heat fluxes from Q R Z T-1 to W m-2 [W T Q-1 R-1 Z-1 m-2 ~> 1]
! Not used enough: real :: kg_m2_to_RZ !< Convert mass loads from kg m-2 to R Z [R Z m2 kg-1 ~> 1]
real :: RZ_to_kg_m2 !< Convert mass loads from R Z to kg m-2 [kg R-1 Z-1 m-2 ~> 1]
real :: kg_m2s_to_RZ_T !< Convert mass fluxes from kg m-2 s-1 to R Z T-1 [R Z m2 s T-1 kg-1 ~> 1]
real :: RZ_T_to_kg_m2s !< Convert mass fluxes from R Z T-1 to kg m-2 s-1 [T kg R-1 Z-1 m-2 s-1 ~> 1]
real :: RZ3_T3_to_W_m2 !< Convert turbulent kinetic energy fluxes from R Z3 T-3 to W m-2 [W T3 R-1 Z-3 m-2 ~> 1]
real :: W_m2_to_RZ3_T3 !< Convert turbulent kinetic energy fluxes from W m-2 to R Z3 T-3 [R Z3 m2 T-3 W-1 ~> 1]
real :: RL2_T2_to_Pa !< Convert pressures from R L2 T-2 to Pa [Pa T2 R-1 L-2 ~> 1]
! Not used enough: real :: Pa_to_RL2_T2 !< Convert pressures from Pa to R L2 T-2 [R L2 T-2 Pa-1 ~> 1]

! These are used for changing scaling across restarts.
real :: m_to_Z_restart = 0.0 !< A copy of the m_to_Z that is used in restart files.
Expand Down Expand Up @@ -130,7 +138,32 @@ subroutine unit_scaling_init( param_file, US )
US%Q_to_J_kg = 1.0 * Q_Rescale_factor
US%J_kg_to_Q = 1.0 / Q_Rescale_factor

! These are useful combinations of the fundamental scale conversion factors set above.
call set_unit_scaling_combos(US)
end subroutine unit_scaling_init

!> Allocates and initializes the ocean model unit scaling type to unscaled values.
subroutine unit_no_scaling_init(US)
type(unit_scale_type), pointer :: US !< A dimensional unit scaling type

if (associated(US)) call MOM_error(FATAL, &
'unit_scaling_init: called with an associated US pointer.')
allocate(US)

US%Z_to_m = 1.0 ; US%m_to_Z = 1.0
US%L_to_m = 1.0 ; US%m_to_L = 1.0
US%T_to_s = 1.0 ; US%s_to_T = 1.0
US%R_to_kg_m3 = 1.0 ; US%kg_m3_to_R = 1.0
US%Q_to_J_kg = 1.0 ; US%J_kg_to_Q = 1.0

call set_unit_scaling_combos(US)
end subroutine unit_no_scaling_init

!> This subroutine sets useful combinations of the fundamental scale conversion factors
!! in the unit scaling type.
subroutine set_unit_scaling_combos(US)
type(unit_scale_type), intent(inout) :: US !< A dimensional unit scaling type

! Convert vertical to horizontal length scales and the reverse:
US%Z_to_L = US%Z_to_m * US%m_to_L
US%L_to_Z = US%L_to_m * US%m_to_Z
! Horizontal velocities:
Expand Down Expand Up @@ -159,7 +192,7 @@ subroutine unit_scaling_init( param_file, US )
! It does not seem like US%Pa_to_RL2_T2 would be used enough in MOM6 to justify its existence.
! US%Pa_to_RL2_T2 = US%kg_m3_to_R * US%m_s_to_L_T**2

end subroutine unit_scaling_init
end subroutine set_unit_scaling_combos

!> Set the unit scaling factors for output to restart files to the unit scaling
!! factors for this run.
Expand Down
6 changes: 2 additions & 4 deletions src/ice_shelf/MOM_ice_shelf.F90
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ module MOM_ice_shelf
use MOM_domains, only : MOM_domains_init, pass_var, pass_vector, clone_MOM_domain
use MOM_domains, only : TO_ALL, CGRID_NE, BGRID_NE, CORNER
use MOM_dyn_horgrid, only : dyn_horgrid_type, create_dyn_horgrid, destroy_dyn_horgrid
use MOM_dyn_horgrid, only : rescale_dyn_horgrid_bathymetry
use MOM_error_handler, only : MOM_error, MOM_mesg, FATAL, WARNING, is_root_pe
use MOM_file_parser, only : read_param, get_param, log_param, log_version, param_file_type
use MOM_grid, only : MOM_grid_init, ocean_grid_type
Expand Down Expand Up @@ -1306,9 +1305,8 @@ subroutine initialize_ice_shelf(param_file, ocn_grid, Time, CS, diag, forces_in,
call create_dyn_horgrid(dG, CS%Grid%HI)
call clone_MOM_domain(CS%Grid%Domain,dG%Domain)
call set_grid_metrics(dG,param_file,CS%US)
! Set up the bottom depth, G%D either analytically or from file
call MOM_initialize_topography(dG%bathyT, CS%Grid%max_depth, dG, param_file)
call rescale_dyn_horgrid_bathymetry(dG, CS%US%Z_to_m)
! Set up the bottom depth, dG%bathyT, either analytically or from file
call MOM_initialize_topography(dG%bathyT, CS%Grid%max_depth, dG, param_file, CS%US)
call copy_dyngrid_to_MOM_grid(dG, CS%Grid, CS%US)
call destroy_dyn_horgrid(dG)
! endif
Expand Down
15 changes: 5 additions & 10 deletions src/initialization/MOM_fixed_initialization.F90
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module MOM_fixed_initialization

use MOM_debugging, only : hchksum, qchksum, uvchksum
use MOM_domains, only : pass_var
use MOM_dyn_horgrid, only : dyn_horgrid_type, rescale_dyn_horgrid_bathymetry
use MOM_dyn_horgrid, only : dyn_horgrid_type
use MOM_error_handler, only : MOM_mesg, MOM_error, FATAL, WARNING, is_root_pe
use MOM_error_handler, only : callTree_enter, callTree_leave, callTree_waypoint
use MOM_file_parser, only : get_param, read_param, log_param, param_file_type
Expand Down Expand Up @@ -82,7 +82,6 @@ subroutine MOM_initialize_fixed(G, US, OBC, PF, write_geom, output_dir)
! This also sets G%max_depth based on the input parameter MAXIMUM_DEPTH,
! or, if absent, is diagnosed as G%max_depth = max( G%D(:,:) )
call MOM_initialize_topography(G%bathyT, G%max_depth, G, PF, US)
! call rescale_dyn_horgrid_bathymetry(G, US%Z_to_m)

! To initialize masks, the bathymetry in halo regions must be filled in
call pass_var(G%bathyT, G%Domain)
Expand Down Expand Up @@ -174,20 +173,16 @@ subroutine MOM_initialize_topography(D, max_depth, G, PF, US)
intent(out) :: D !< Ocean bottom depth [Z ~> m] or [m]
type(param_file_type), intent(in) :: PF !< Parameter file structure
real, intent(out) :: max_depth !< Maximum depth of model [Z ~> m] or [m]
type(unit_scale_type), optional, intent(in) :: US !< A dimensional unit scaling type
type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type

! This subroutine makes the appropriate call to set up the bottom depth.
! This is a separate subroutine so that it can be made public and shared with
! the ice-sheet code or other components.

! Local variables
real :: m_to_Z, Z_to_m ! Dimensional rescaling factors
character(len=40) :: mdl = "MOM_initialize_topography" ! This subroutine's name.
character(len=200) :: config

m_to_Z = 1.0 ; if (present(US)) m_to_Z = US%m_to_Z
Z_to_m = 1.0 ; if (present(US)) Z_to_m = US%Z_to_m

call get_param(PF, mdl, "TOPO_CONFIG", config, &
"This specifies how bathymetry is specified: \n"//&
" \t file - read bathymetric information from the file \n"//&
Expand Down Expand Up @@ -216,7 +211,7 @@ subroutine MOM_initialize_topography(D, max_depth, G, PF, US)
" \t dense - Denmark Strait-like dense water formation and overflow.\n"//&
" \t USER - call a user modified routine.", &
fail_if_missing=.true.)
max_depth = -1.e9*m_to_Z ; call read_param(PF, "MAXIMUM_DEPTH", max_depth, scale=m_to_Z)
max_depth = -1.e9*US%m_to_Z ; call read_param(PF, "MAXIMUM_DEPTH", max_depth, scale=US%m_to_Z)
select case ( trim(config) )
case ("file"); call initialize_topography_from_file(D, G, PF, US)
case ("flat"); call initialize_topography_named(D, G, PF, config, max_depth, US)
Expand All @@ -241,11 +236,11 @@ subroutine MOM_initialize_topography(D, max_depth, G, PF, US)
"Unrecognized topography setup '"//trim(config)//"'")
end select
if (max_depth>0.) then
call log_param(PF, mdl, "MAXIMUM_DEPTH", max_depth*Z_to_m, &
call log_param(PF, mdl, "MAXIMUM_DEPTH", max_depth*US%Z_to_m, &
"The maximum depth of the ocean.", units="m")
else
max_depth = diagnoseMaximumDepth(D,G)
call log_param(PF, mdl, "!MAXIMUM_DEPTH", max_depth*Z_to_m, &
call log_param(PF, mdl, "!MAXIMUM_DEPTH", max_depth*US%Z_to_m, &
"The (diagnosed) maximum depth of the ocean.", units="m", like_default=.true.)
endif
if (trim(config) /= "DOME") then
Expand Down
Loading