@@ -117,7 +117,7 @@ module MOM_state_initialization
117
117
! ! conditions or by reading them from a restart (or saves) file.
118
118
subroutine MOM_initialize_state (u , v , h , tv , Time , G , GV , US , PF , dirs , &
119
119
restart_CS , ALE_CSp , tracer_Reg , sponge_CSp , &
120
- ALE_sponge_CSp , oda_incupd_CSp , OBC , Time_in , frac_shelf_h )
120
+ ALE_sponge_CSp , oda_incupd_CSp , OBC , Time_in , frac_shelf_h , mass_shelf )
121
121
type (ocean_grid_type), intent (inout ) :: G ! < The ocean's grid structure.
122
122
type (verticalGrid_type), intent (in ) :: GV ! < The ocean's vertical grid structure.
123
123
type (unit_scale_type), intent (in ) :: US ! < A dimensional unit scaling type
@@ -147,6 +147,9 @@ subroutine MOM_initialize_state(u, v, h, tv, Time, G, GV, US, PF, dirs, &
147
147
real , dimension (SZI_(G),SZJ_(G)), &
148
148
optional , intent (in ) :: frac_shelf_h ! < The fraction of the grid cell covered
149
149
! ! by a floating ice shelf [nondim].
150
+ real , dimension (SZI_(G),SZJ_(G)), &
151
+ optional , intent (in ) :: mass_shelf ! < The mass per unit area of the overlying
152
+ ! ! ice shelf [ R Z ~> kg m-2 ]
150
153
! Local variables
151
154
real :: depth_tot(SZI_(G),SZJ_(G)) ! The nominal total depth of the ocean [Z ~> m]
152
155
character (len= 200 ) :: filename ! The name of an input file.
@@ -158,6 +161,7 @@ subroutine MOM_initialize_state(u, v, h, tv, Time, G, GV, US, PF, dirs, &
158
161
real :: vel_rescale ! A rescaling factor for velocities from the representation in
159
162
! a restart file to the internal representation in this run.
160
163
real :: dt ! The baroclinic dynamics timestep for this run [T ~> s].
164
+
161
165
logical :: from_Z_file, useALE
162
166
logical :: new_sim
163
167
integer :: write_geom
@@ -404,6 +408,23 @@ subroutine MOM_initialize_state(u, v, h, tv, Time, G, GV, US, PF, dirs, &
404
408
if (use_temperature .and. use_OBC) &
405
409
call fill_temp_salt_segments(G, GV, OBC, tv)
406
410
411
+ ! Calculate the initial surface displacement under ice shelf
412
+
413
+ call get_param(PF, mdl, " DEPRESS_INITIAL_SURFACE" , depress_sfc, &
414
+ " If true, depress the initial surface to avoid huge " // &
415
+ " tsunamis when a large surface pressure is applied." , &
416
+ default= .false. , do_not_log= just_read)
417
+ call get_param(PF, mdl, " TRIM_IC_FOR_P_SURF" , trim_ic_for_p_surf, &
418
+ " If true, cuts way the top of the column for initial conditions " // &
419
+ " at the depth where the hydrostatic pressure matches the imposed " // &
420
+ " surface pressure which is read from file." , default= .false. , &
421
+ do_not_log= just_read)
422
+
423
+ if (new_sim) then
424
+ if (use_ice_shelf .and. present (mass_shelf) .and. .not. (trim_ic_for_p_surf .or. depress_sfc)) &
425
+ call calc_sfc_displacement(PF, G, GV, US, mass_shelf, tv, h)
426
+ endif
427
+
407
428
! The thicknesses in halo points might be needed to initialize the velocities.
408
429
if (new_sim) call pass_var(h, G% Domain)
409
430
@@ -458,15 +479,6 @@ subroutine MOM_initialize_state(u, v, h, tv, Time, G, GV, US, PF, dirs, &
458
479
call convert_thickness(h, G, GV, US, tv)
459
480
460
481
! Remove the mass that would be displaced by an ice shelf or inverse barometer.
461
- call get_param(PF, mdl, " DEPRESS_INITIAL_SURFACE" , depress_sfc, &
462
- " If true, depress the initial surface to avoid huge " // &
463
- " tsunamis when a large surface pressure is applied." , &
464
- default= .false. , do_not_log= just_read)
465
- call get_param(PF, mdl, " TRIM_IC_FOR_P_SURF" , trim_ic_for_p_surf, &
466
- " If true, cuts way the top of the column for initial conditions " // &
467
- " at the depth where the hydrostatic pressure matches the imposed " // &
468
- " surface pressure which is read from file." , default= .false. , &
469
- do_not_log= just_read)
470
482
if (depress_sfc .and. trim_ic_for_p_surf) call MOM_error(FATAL, " MOM_initialize_state: " // &
471
483
" DEPRESS_INITIAL_SURFACE and TRIM_IC_FOR_P_SURF are exclusive and cannot both be True" )
472
484
if (new_sim .and. debug .and. (depress_sfc .or. trim_ic_for_p_surf)) &
@@ -1035,7 +1047,7 @@ subroutine convert_thickness(h, G, GV, US, tv)
1035
1047
end subroutine convert_thickness
1036
1048
1037
1049
! > Depress the sea-surface based on an initial condition file
1038
- subroutine depress_surface (h , G , GV , US , param_file , tv , just_read )
1050
+ subroutine depress_surface (h , G , GV , US , param_file , tv , just_read , z_top_shelf )
1039
1051
type (ocean_grid_type), intent (in ) :: G ! < The ocean's grid structure
1040
1052
type (verticalGrid_type), intent (in ) :: GV ! < The ocean's vertical grid structure
1041
1053
type (unit_scale_type), intent (in ) :: US ! < A dimensional unit scaling type
@@ -1045,6 +1057,8 @@ subroutine depress_surface(h, G, GV, US, param_file, tv, just_read)
1045
1057
type (thermo_var_ptrs), intent (in ) :: tv ! < A structure pointing to various thermodynamic variables
1046
1058
logical , intent (in ) :: just_read ! < If true, this call will only read
1047
1059
! ! parameters without changing h.
1060
+ real , dimension (SZI_(G),SZJ_(G)), &
1061
+ optional , intent (in ) :: z_top_shelf ! < Top interface position under ice shelf [Z ~> m]
1048
1062
! Local variables
1049
1063
real , dimension (SZI_(G),SZJ_(G)) :: &
1050
1064
eta_sfc ! The free surface height that the model should use [Z ~> m].
@@ -1057,30 +1071,40 @@ subroutine depress_surface(h, G, GV, US, param_file, tv, just_read)
1057
1071
character (len= 200 ) :: inputdir, eta_srf_file ! Strings for file/path
1058
1072
character (len= 200 ) :: filename, eta_srf_var ! Strings for file/path
1059
1073
integer :: i, j, k, is, ie, js, je, nz
1074
+ logical :: use_z_shelf
1060
1075
1061
1076
is = G% isc ; ie = G% iec ; js = G% jsc ; je = G% jec ; nz = GV% ke
1062
1077
1063
- ! Read the surface height (or pressure) from a file.
1078
+ use_z_shelf = present (z_top_shelf)
1064
1079
1065
- call get_param(param_file, mdl, " INPUTDIR" , inputdir, default= " ." )
1066
- inputdir = slasher(inputdir)
1067
- call get_param(param_file, mdl, " SURFACE_HEIGHT_IC_FILE" , eta_srf_file,&
1068
- " The initial condition file for the surface height." , &
1069
- fail_if_missing= .not. just_read, do_not_log= just_read)
1070
- call get_param(param_file, mdl, " SURFACE_HEIGHT_IC_VAR" , eta_srf_var, &
1071
- " The initial condition variable for the surface height." ,&
1072
- default= " SSH" , do_not_log= just_read)
1073
- filename = trim (inputdir)// trim (eta_srf_file)
1074
- if (.not. just_read) &
1075
- call log_param(param_file, mdl, " INPUTDIR/SURFACE_HEIGHT_IC_FILE" , filename)
1076
1080
1077
- call get_param(param_file, mdl, " SURFACE_HEIGHT_IC_SCALE" , scale_factor, &
1078
- " A scaling factor to convert SURFACE_HEIGHT_IC_VAR into units of m" , &
1079
- units= " variable" , default= 1.0 , scale= US% m_to_Z, do_not_log= just_read)
1081
+ if (.not. use_z_shelf) then
1082
+ ! Read the surface height (or pressure) from a file.
1080
1083
1081
- if (just_read) return ! All run-time parameters have been read, so return.
1084
+ call get_param(param_file, mdl, " INPUTDIR" , inputdir, default= " ." )
1085
+ inputdir = slasher(inputdir)
1086
+ call get_param(param_file, mdl, " SURFACE_HEIGHT_IC_FILE" , eta_srf_file,&
1087
+ " The initial condition file for the surface height." , &
1088
+ fail_if_missing= .not. just_read, do_not_log= just_read)
1089
+ call get_param(param_file, mdl, " SURFACE_HEIGHT_IC_VAR" , eta_srf_var, &
1090
+ " The initial condition variable for the surface height." ,&
1091
+ default= " SSH" , do_not_log= just_read)
1092
+ filename = trim (inputdir)// trim (eta_srf_file)
1093
+ if (.not. just_read) &
1094
+ call log_param(param_file, mdl, " INPUTDIR/SURFACE_HEIGHT_IC_FILE" , filename)
1095
+
1096
+ call get_param(param_file, mdl, " SURFACE_HEIGHT_IC_SCALE" , scale_factor, &
1097
+ " A scaling factor to convert SURFACE_HEIGHT_IC_VAR into units of m" , &
1098
+ units= " variable" , default= 1.0 , scale= US% m_to_Z, do_not_log= just_read)
1099
+
1100
+ if (just_read) return ! All run-time parameters have been read, so return.
1082
1101
1083
- call MOM_read_data(filename, eta_srf_var, eta_sfc, G% Domain, scale= scale_factor)
1102
+ call MOM_read_data(filename, eta_srf_var, eta_sfc, G% Domain, scale= scale_factor)
1103
+ else
1104
+ do j= js,je ; do i= is,ie
1105
+ eta_sfc(i,j) = z_top_shelf(i,j)
1106
+ enddo ; enddo
1107
+ endif
1084
1108
1085
1109
! Convert thicknesses to interface heights.
1086
1110
call find_eta(h, tv, G, GV, US, eta, dZref= G% Z_ref)
@@ -1201,6 +1225,88 @@ subroutine trim_for_ice(PF, G, GV, US, ALE_CSp, tv, h, just_read)
1201
1225
1202
1226
end subroutine trim_for_ice
1203
1227
1228
+ ! > Calculate the hydrostatic equilibrium position of the surface under an ice shelf
1229
+ subroutine calc_sfc_displacement (PF , G , GV , US , mass_shelf , tv , h )
1230
+ type (param_file_type), intent (in ) :: PF ! < Parameter file structure
1231
+ type (ocean_grid_type), intent (in ) :: G ! < Ocean grid structure
1232
+ type (verticalGrid_type), intent (in ) :: GV ! < Vertical grid structure
1233
+ type (unit_scale_type), intent (in ) :: US ! < A dimensional unit scaling type
1234
+ real , dimension (SZI_(G),SZJ_(G)), &
1235
+ intent (in ) :: mass_shelf ! < Ice shelf mass [R Z ~> kg m-2]
1236
+ type (thermo_var_ptrs), intent (inout ) :: tv ! < Thermodynamics structure
1237
+ real , dimension (SZI_(G),SZJ_(G),SZK_(GV)), &
1238
+ intent (inout ) :: h ! < Layer thickness [H ~> m or kg m-2]
1239
+
1240
+ real :: z_top_shelf(SZI_(G),SZJ_(G)) ! The depth of the top interface under ice shelves [Z ~> m]
1241
+ real , dimension (SZI_(G),SZJ_(G),SZK_(GV)+ 1 ) :: &
1242
+ eta ! The free surface height that the model should use [Z ~> m].
1243
+ ! temporary arrays
1244
+ real , dimension (SZK_(GV)) :: rho_col ! potential density in the column for use in ice
1245
+ real , dimension (SZK_(GV)) :: rho_h ! potential density multiplied by thickness [R Z ~> kg m-2 ]
1246
+ real , dimension (SZK_(GV)) :: h_tmp ! temporary storage for thicknesses [H ~> m]
1247
+ real , dimension (SZK_(GV)) :: p_ref ! pressure for density [R Z ~> kg m-2]
1248
+ real , dimension (SZK_(GV)+ 1 ) :: ei_tmp, ei_orig ! temporary storage for interface positions [Z ~> m]
1249
+ real :: z_top, z_col, mass_disp, residual, tol
1250
+ integer :: is, ie, js, je, k, nz, i, j, max_iter, iter
1251
+
1252
+ is = G% isc ; ie = G% iec ; js = G% jsc ; je = G% jec ; nz = GV% ke
1253
+
1254
+
1255
+ tol = 0.001 ! The initialization tolerance for ice shelf initialization (m)
1256
+ call get_param(PF, mdl, " ICE_SHELF_INITIALIZATION_Z_TOLERANCE" , tol, &
1257
+ " A initialization tolerance for the calculation of the static " // &
1258
+ " ice shelf displacement (m) using initial temperature and salinity profile." ,&
1259
+ default= tol, units= " m" , scale= US% m_to_Z)
1260
+ max_iter = 1e3
1261
+ call MOM_mesg(" Started calculating initial interface position under ice shelf " )
1262
+ ! Convert thicknesses to interface heights.
1263
+ call find_eta(h, tv, G, GV, US, eta, dZref= G% Z_ref)
1264
+ do j = js, je ; do i = is, ie
1265
+ iter = 1
1266
+ z_top_shelf(i,j) = 0.0
1267
+ p_ref(:) = tv% p_ref
1268
+ if (G% mask2dT(i,j) .gt. 0 . .and. mass_shelf(i,j) .gt. 0 .) then
1269
+ call calculate_density(tv% T(i,j,:), tv% S(i,j,:), P_Ref, rho_col, tv% eqn_of_state)
1270
+ z_top = min (max (- 1.0 * mass_shelf(i,j)/ rho_col(1 ),- G% bathyT(i,j)),0 .)
1271
+ h_tmp = 0.0
1272
+ z_col = 0.0
1273
+ ei_tmp(1 :nz+1 )= eta(i,j,1 :nz+1 )
1274
+ ei_orig(1 :nz+1 )= eta(i,j,1 :nz+1 )
1275
+ do k= 1 ,nz+1
1276
+ if (ei_tmp(k)<z_top) ei_tmp(k)= z_top
1277
+ enddo
1278
+ mass_disp = 0.0
1279
+ do k= 1 ,nz
1280
+ h_tmp(k) = max (ei_tmp(k)- ei_tmp(k+1 ),GV% Angstrom_H)
1281
+ rho_h(k) = h_tmp(k) * rho_col(k)
1282
+ mass_disp = mass_disp + rho_h(k)
1283
+ enddo
1284
+ residual = mass_shelf(i,j) - mass_disp
1285
+ do while (abs (residual) .gt. tol .and. z_top .gt. - G% bathyT(i,j) .and. iter .lt. max_iter)
1286
+ z_top= min (max (z_top- (residual* 0.5e-3 ),- G% bathyT(i,j)),0.0 )
1287
+ h_tmp = 0.0
1288
+ z_col = 0.0
1289
+ ei_tmp(1 :nz+1 ) = ei_orig(1 :nz+1 )
1290
+ do k= 1 ,nz+1
1291
+ if (ei_tmp(k)<z_top) ei_tmp(k)= z_top
1292
+ enddo
1293
+ mass_disp = 0.0
1294
+ do k= 1 ,nz
1295
+ h_tmp(k) = max (ei_tmp(k)- ei_tmp(k+1 ),GV% Angstrom_H)
1296
+ rho_h(k) = h_tmp(k) * rho_col(k)
1297
+ mass_disp = mass_disp + rho_h(k)
1298
+ enddo
1299
+ residual = mass_shelf(i,j) - mass_disp
1300
+ iter = iter+1
1301
+ end do
1302
+ if (iter .ge. max_iter) call MOM_mesg(" Warning: calc_sfc_displacement too many iterations." )
1303
+ z_top_shelf(i,j) = z_top
1304
+ endif
1305
+ enddo ; enddo
1306
+ call MOM_mesg(" Calling depress_surface " )
1307
+ call depress_surface(h, G, GV, US, PF, tv, just_read= .false. ,z_top_shelf= z_top_shelf)
1308
+ call MOM_mesg(" Finishing calling depress_surface " )
1309
+ end subroutine calc_sfc_displacement
1204
1310
1205
1311
! > Adjust the layer thicknesses by removing the top of the water column above the
1206
1312
! ! depth where the hydrostatic pressure matches p_surf
@@ -2597,6 +2703,7 @@ subroutine MOM_temp_salt_initialize_from_Z(h, tv, depth_tot, G, GV, US, PF, just
2597
2703
old_remap= remap_old_alg, answers_2018= answers_2018 )
2598
2704
call ALE_remap_scalar(remapCS, G, GV, nkd, h1, tmpS1dIn, h, tv% S, all_cells= remap_full_column, &
2599
2705
old_remap= remap_old_alg, answers_2018= answers_2018 )
2706
+
2600
2707
deallocate ( h1 )
2601
2708
deallocate ( tmpT1dIn )
2602
2709
deallocate ( tmpS1dIn )
0 commit comments