7 use mom_cpu_clock,
only : cpu_clock_id, cpu_clock_begin, cpu_clock_end
27 implicit none ;
private 29 #include <MOM_memory.h> 31 public register_ice_shelf_dyn_restarts, initialize_ice_shelf_dyn, update_ice_shelf
32 public ice_time_step_cfl, ice_shelf_dyn_end
33 public shelf_advance_front, ice_shelf_min_thickness_calve, calve_to_mask
42 real,
pointer,
dimension(:,:) :: u_shelf => null()
44 real,
pointer,
dimension(:,:) :: v_shelf => null()
47 real,
pointer,
dimension(:,:) :: u_face_mask => null()
55 real,
pointer,
dimension(:,:) :: v_face_mask => null()
57 real,
pointer,
dimension(:,:) :: u_face_mask_bdry => null()
58 real,
pointer,
dimension(:,:) :: v_face_mask_bdry => null()
59 real,
pointer,
dimension(:,:) :: u_flux_bdry_val => null()
61 real,
pointer,
dimension(:,:) :: v_flux_bdry_val => null()
64 real,
pointer,
dimension(:,:) :: umask => null()
67 real,
pointer,
dimension(:,:) :: vmask => null()
70 real,
pointer,
dimension(:,:) :: calve_mask => null()
72 real,
pointer,
dimension(:,:) :: t_shelf => null()
74 real,
pointer,
dimension(:,:) :: tmask => null()
75 real,
pointer,
dimension(:,:) :: ice_visc => null()
76 real,
pointer,
dimension(:,:) :: thickness_bdry_val => null()
77 real,
pointer,
dimension(:,:) :: u_bdry_val => null()
79 real,
pointer,
dimension(:,:) :: v_bdry_val => null()
81 real,
pointer,
dimension(:,:) :: h_bdry_val => null()
82 real,
pointer,
dimension(:,:) :: t_bdry_val => null()
84 real,
pointer,
dimension(:,:) :: basal_traction => null()
88 real,
pointer,
dimension(:,:) :: od_rt => null()
89 real,
pointer,
dimension(:,:) :: ground_frac_rt => null()
90 real,
pointer,
dimension(:,:) :: od_av => null()
91 real,
pointer,
dimension(:,:) :: ground_frac => null()
94 integer :: od_rt_counter = 0
96 real :: velocity_update_time_step
102 real :: elapsed_velocity_time
107 logical :: gl_regularize
109 integer :: n_sub_regularize
122 real :: a_glen_isothermal
125 real :: c_basal_friction
128 real :: density_ocean_avg
132 real :: thresh_float_col_depth
133 logical :: moving_shelf_front
134 logical :: calve_to_mask
135 real :: min_thickness_simple_calve
139 real :: nonlinear_tolerance
141 integer :: cg_max_iterations
142 integer :: nonlin_solve_err_mode
150 logical :: module_is_initialized = .false.
153 integer :: id_u_shelf = -1, id_v_shelf = -1, id_t_shelf = -1, &
154 id_ground_frac = -1, id_col_thick = -1, id_od_av = -1, &
155 id_u_mask = -1, id_v_mask = -1, id_t_mask = -1
167 integer :: ish, ieh, jsh, jeh
175 function slope_limiter(num, denom)
176 real,
intent(in) :: num
177 real,
intent(in) :: denom
178 real :: slope_limiter
183 elseif (num*denom <= 0)
then 187 slope_limiter = (r+abs(r))/(1+abs(r))
190 end function slope_limiter
193 function quad_area (X, Y)
194 real,
dimension(4),
intent(in) :: x
195 real,
dimension(4),
intent(in) :: y
197 real :: p2, q2, a2, c2, b2, d2
204 p2 = (x(4)-x(1))**2 + (y(4)-y(1))**2 ; q2 = (x(3)-x(2))**2 + (y(3)-y(2))**2
205 a2 = (x(3)-x(4))**2 + (y(3)-y(4))**2 ; c2 = (x(1)-x(2))**2 + (y(1)-y(2))**2
206 b2 = (x(2)-x(4))**2 + (y(2)-y(4))**2 ; d2 = (x(3)-x(1))**2 + (y(3)-y(1))**2
207 quad_area = .25 * sqrt(4*p2*q2-(b2+d2-a2-c2)**2)
209 end function quad_area
213 subroutine register_ice_shelf_dyn_restarts(G, param_file, CS, restart_CS)
219 logical :: shelf_mass_is_dynamic, override_shelf_movement, active_shelf_dynamics
220 character(len=40) :: mdl =
"MOM_ice_shelf_dyn" 221 integer :: isd, ied, jsd, jed, isdb, iedb, jsdb, jedb
223 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
224 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
226 if (
associated(cs))
then 227 call mom_error(fatal,
"MOM_ice_shelf_dyn.F90, register_ice_shelf_dyn_restarts: "// &
228 "called with an associated control structure.")
233 override_shelf_movement = .false. ; active_shelf_dynamics = .false.
234 call get_param(param_file, mdl,
"DYNAMIC_SHELF_MASS", shelf_mass_is_dynamic, &
235 "If true, the ice sheet mass can evolve with time.", &
236 default=.false., do_not_log=.true.)
237 if (shelf_mass_is_dynamic)
then 238 call get_param(param_file, mdl,
"OVERRIDE_SHELF_MOVEMENT", override_shelf_movement, &
239 "If true, user provided code specifies the ice-shelf "//&
240 "movement instead of the dynamic ice model.", default=.false., do_not_log=.true.)
241 active_shelf_dynamics = .not.override_shelf_movement
244 if (active_shelf_dynamics)
then 245 allocate( cs%u_shelf(isdb:iedb,jsdb:jedb) ) ; cs%u_shelf(:,:) = 0.0
246 allocate( cs%v_shelf(isdb:iedb,jsdb:jedb) ) ; cs%v_shelf(:,:) = 0.0
247 allocate( cs%t_shelf(isd:ied,jsd:jed) ) ; cs%t_shelf(:,:) = -10.0
248 allocate( cs%ice_visc(isd:ied,jsd:jed) ) ; cs%ice_visc(:,:) = 0.0
249 allocate( cs%basal_traction(isd:ied,jsd:jed) ) ; cs%basal_traction(:,:) = 0.0
250 allocate( cs%OD_av(isd:ied,jsd:jed) ) ; cs%OD_av(:,:) = 0.0
251 allocate( cs%ground_frac(isd:ied,jsd:jed) ) ; cs%ground_frac(:,:) = 0.0
255 "ice sheet/shelf u-velocity",
"m s-1", hor_grid=
'Bu')
257 "ice sheet/shelf v-velocity",
"m s-1", hor_grid=
'Bu')
259 "ice sheet/shelf vertically averaged temperature",
"deg C")
261 "Average open ocean depth in a cell",
"m")
263 "fractional degree of grounding",
"nondim")
265 "Volume integrated Glens law ice viscosity",
"kg m2 s-1")
267 "The area integrated basal traction coefficient",
"kg s-1")
270 end subroutine register_ice_shelf_dyn_restarts
273 subroutine initialize_ice_shelf_dyn(param_file, Time, ISS, CS, G, US, diag, new_sim, solo_ice_sheet_in)
276 type(time_type),
intent(inout) :: time
282 type(
diag_ctrl),
target,
intent(in) :: diag
283 logical,
intent(in) :: new_sim
285 logical,
optional,
intent(in) :: solo_ice_sheet_in
294 # include "version_variable.h" 295 character(len=200) :: config
296 character(len=200) :: ic_file,filename,inputdir
297 character(len=40) :: var_name
298 character(len=40) :: mdl =
"MOM_ice_shelf_dyn" 299 logical :: shelf_mass_is_dynamic, override_shelf_movement, active_shelf_dynamics
301 integer :: i, j, is, ie, js, je, isd, ied, jsd, jed, isdq, iedq, jsdq, jedq, iters
303 isdq = g%isdB ; iedq = g%iedB ; jsdq = g%jsdB ; jedq = g%jedB
304 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
306 if (.not.
associated(cs))
then 307 call mom_error(fatal,
"MOM_ice_shelf_dyn.F90, initialize_ice_shelf_dyn: "// &
308 "called with an associated control structure.")
311 if (cs%module_is_initialized)
then 312 call mom_error(warning,
"MOM_ice_shelf_dyn.F90, initialize_ice_shelf_dyn was "//&
313 "called with a control structure that has already been initialized.")
315 cs%module_is_initialized = .true.
321 call get_param(param_file, mdl,
"DEBUG", debug, default=.false.)
322 call get_param(param_file, mdl,
"DEBUG_IS", cs%debug, &
323 "If true, write verbose debugging messages for the ice shelf.", &
325 call get_param(param_file, mdl,
"DYNAMIC_SHELF_MASS", shelf_mass_is_dynamic, &
326 "If true, the ice sheet mass can evolve with time.", &
328 override_shelf_movement = .false. ; active_shelf_dynamics = .false.
329 if (shelf_mass_is_dynamic)
then 330 call get_param(param_file, mdl,
"OVERRIDE_SHELF_MOVEMENT", override_shelf_movement, &
331 "If true, user provided code specifies the ice-shelf "//&
332 "movement instead of the dynamic ice model.", default=.false., do_not_log=.true.)
333 active_shelf_dynamics = .not.override_shelf_movement
335 call get_param(param_file, mdl,
"GROUNDING_LINE_INTERPOLATE", cs%GL_regularize, &
336 "If true, regularize the floatation condition at the "//&
337 "grounding line as in Goldberg Holland Schoof 2009.", default=.false.)
338 call get_param(param_file, mdl,
"GROUNDING_LINE_INTERP_SUBGRID_N", cs%n_sub_regularize, &
339 "The number of sub-partitions of each cell over which to "//&
340 "integrate for the interpolated grounding line. Each cell "//&
341 "is divided into NxN equally-sized rectangles, over which the "//&
342 "basal contribution is integrated by iterative quadrature.", &
344 call get_param(param_file, mdl,
"GROUNDING_LINE_COUPLE", cs%GL_couple, &
345 "If true, let the floatation condition be determined by "//&
346 "ocean column thickness. This means that update_OD_ffrac "//&
347 "will be called. GL_REGULARIZE and GL_COUPLE are exclusive.", &
348 default=.false., do_not_log=cs%GL_regularize)
349 if (cs%GL_regularize) cs%GL_couple = .false.
350 if (cs%GL_regularize .and. (cs%n_sub_regularize == 0))
call mom_error (fatal, &
351 "GROUNDING_LINE_INTERP_SUBGRID_N must be a positive integer if GL regularization is used")
352 call get_param(param_file, mdl,
"ICE_SHELF_CFL_FACTOR", cs%CFL_factor, &
353 "A factor used to limit timestep as CFL_FACTOR * min (\Delta x / u). "//&
354 "This is only used with an ice-only model.", default=0.25)
356 call get_param(param_file, mdl,
"RHO_0", cs%density_ocean_avg, &
357 "avg ocean density used in floatation cond", &
358 units=
"kg m-3", default=1035., scale=us%kg_m3_to_R)
359 if (active_shelf_dynamics)
then 360 call get_param(param_file, mdl,
"ICE_VELOCITY_TIMESTEP", cs%velocity_update_time_step, &
361 "seconds between ice velocity calcs", units=
"s", scale=us%s_to_T, &
362 fail_if_missing=.true.)
363 call get_param(param_file, mdl,
"G_EARTH", cs%g_Earth, &
364 "The gravitational acceleration of the Earth.", &
365 units=
"m s-2", default = 9.80, scale=us%m_s_to_L_T**2*us%Z_to_m)
367 call get_param(param_file, mdl,
"A_GLEN_ISOTHERM", cs%A_glen_isothermal, &
368 "Ice viscosity parameter in Glen's Law", &
369 units=
"Pa-3 yr-1", default=9.461e-18, scale=1.0/(365.0*86400.0))
371 call get_param(param_file, mdl,
"GLEN_EXPONENT", cs%n_glen, &
372 "nonlinearity exponent in Glen's Law", &
373 units=
"none", default=3.)
374 call get_param(param_file, mdl,
"MIN_STRAIN_RATE_GLEN", cs%eps_glen_min, &
375 "min. strain rate to avoid infinite Glen's law viscosity", &
376 units=
"a-1", default=1.e-12, scale=us%T_to_s/(365.0*86400.0))
377 call get_param(param_file, mdl,
"BASAL_FRICTION_EXP", cs%n_basal_fric, &
378 "Exponent in sliding law \tau_b = C u^(n_basal_fric)", &
379 units=
"none", fail_if_missing=.true.)
380 call get_param(param_file, mdl,
"BASAL_FRICTION_COEFF", cs%C_basal_friction, &
381 "Coefficient in sliding law \tau_b = C u^(n_basal_fric)", &
382 units=
"Pa (m yr-1)-(n_basal_fric)", scale=us%kg_m2s_to_RZ_T*((365.0*86400.0)**cs%n_basal_fric), &
383 fail_if_missing=.true.)
384 call get_param(param_file, mdl,
"DENSITY_ICE", cs%density_ice, &
385 "A typical density of ice.", units=
"kg m-3", default=917.0, scale=us%kg_m3_to_R)
386 call get_param(param_file, mdl,
"CONJUGATE_GRADIENT_TOLERANCE", cs%cg_tolerance, &
387 "tolerance in CG solver, relative to initial residual", default=1.e-6)
388 call get_param(param_file, mdl,
"ICE_NONLINEAR_TOLERANCE", cs%nonlinear_tolerance, &
389 "nonlin tolerance in iterative velocity solve",default=1.e-6)
390 call get_param(param_file, mdl,
"CONJUGATE_GRADIENT_MAXIT", cs%cg_max_iterations, &
391 "max iteratiions in CG solver", default=2000)
392 call get_param(param_file, mdl,
"THRESH_FLOAT_COL_DEPTH", cs%thresh_float_col_depth, &
393 "min ocean thickness to consider ice *floating*; "//&
394 "will only be important with use of tides", &
395 units=
"m", default=1.e-3, scale=us%m_to_Z)
396 call get_param(param_file, mdl,
"NONLIN_SOLVE_ERR_MODE", cs%nonlin_solve_err_mode, &
397 "Choose whether nonlin error in vel solve is based on nonlinear "//&
398 "residual (1) or relative change since last iteration (2)", default=1)
400 call get_param(param_file, mdl,
"SHELF_MOVING_FRONT", cs%moving_shelf_front, &
401 "Specify whether to advance shelf front (and calve).", &
403 call get_param(param_file, mdl,
"CALVE_TO_MASK", cs%calve_to_mask, &
404 "If true, do not allow an ice shelf where prohibited by a mask.", &
407 call get_param(param_file, mdl,
"MIN_THICKNESS_SIMPLE_CALVE", cs%min_thickness_simple_calve, &
408 "Min thickness rule for the VERY simple calving law",&
409 units=
"m", default=0.0, scale=us%m_to_Z)
415 if (active_shelf_dynamics)
then 417 allocate( cs%u_bdry_val(isdq:iedq,jsdq:jedq) ) ; cs%u_bdry_val(:,:) = 0.0
418 allocate( cs%v_bdry_val(isdq:iedq,jsdq:jedq) ) ; cs%v_bdry_val(:,:) = 0.0
419 allocate( cs%t_bdry_val(isd:ied,jsd:jed) ) ; cs%t_bdry_val(:,:) = -15.0
420 allocate( cs%h_bdry_val(isd:ied,jsd:jed) ) ; cs%h_bdry_val(:,:) = 0.0
421 allocate( cs%thickness_bdry_val(isd:ied,jsd:jed) ) ; cs%thickness_bdry_val(:,:) = 0.0
422 allocate( cs%u_face_mask(isdq:iedq,jsd:jed) ) ; cs%u_face_mask(:,:) = 0.0
423 allocate( cs%v_face_mask(isd:ied,jsdq:jedq) ) ; cs%v_face_mask(:,:) = 0.0
424 allocate( cs%u_face_mask_bdry(isdq:iedq,jsd:jed) ) ; cs%u_face_mask_bdry(:,:) = -2.0
425 allocate( cs%v_face_mask_bdry(isd:ied,jsdq:jedq) ) ; cs%v_face_mask_bdry(:,:) = -2.0
426 allocate( cs%u_flux_bdry_val(isdq:iedq,jsd:jed) ) ; cs%u_flux_bdry_val(:,:) = 0.0
427 allocate( cs%v_flux_bdry_val(isd:ied,jsdq:jedq) ) ; cs%v_flux_bdry_val(:,:) = 0.0
428 allocate( cs%umask(isdq:iedq,jsdq:jedq) ) ; cs%umask(:,:) = -1.0
429 allocate( cs%vmask(isdq:iedq,jsdq:jedq) ) ; cs%vmask(:,:) = -1.0
430 allocate( cs%tmask(isdq:iedq,jsdq:jedq) ) ; cs%tmask(:,:) = -1.0
433 allocate( cs%OD_rt(isd:ied,jsd:jed) ) ; cs%OD_rt(:,:) = 0.0
434 allocate( cs%ground_frac_rt(isd:ied,jsd:jed) ) ; cs%ground_frac_rt(:,:) = 0.0
436 if (cs%calve_to_mask)
then 437 allocate( cs%calve_mask(isd:ied,jsd:jed) ) ; cs%calve_mask(:,:) = 0.0
440 cs%elapsed_velocity_time = 0.0
442 call update_velocity_masks(cs, g, iss%hmask, cs%umask, cs%vmask, cs%u_face_mask, cs%v_face_mask)
446 if (active_shelf_dynamics .and. .not.new_sim)
then 447 if ((us%m_to_Z_restart /= 0.0) .and. (us%m_to_Z_restart /= us%m_to_Z))
then 448 z_rescale = us%m_to_Z / us%m_to_Z_restart
449 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
450 cs%OD_av(i,j) = z_rescale * cs%OD_av(i,j)
454 if ((us%m_to_L_restart*us%s_to_T_restart /= 0.0) .and. &
455 (us%m_to_L_restart /= us%m_s_to_L_T*us%s_to_T_restart))
then 456 vel_rescale = us%m_s_to_L_T*us%s_to_T_restart / us%m_to_L_restart
457 do j=g%jsc-1,g%jec ;
do i=g%isc-1,g%iec
458 cs%u_shelf(i,j) = vel_rescale * cs%u_shelf(i,j)
459 cs%v_shelf(i,j) = vel_rescale * cs%v_shelf(i,j)
468 if (.not. g%symmetric)
then 469 do j=g%jsd,g%jed ;
do i=g%isd,g%ied
470 if (((i+g%idg_offset) == (g%domain%nihalo+1)).and.(cs%u_face_mask(i-1,j) == 3))
then 471 cs%u_shelf(i-1,j-1) = cs%u_bdry_val(i-1,j-1)
472 cs%u_shelf(i-1,j) = cs%u_bdry_val(i-1,j)
473 cs%v_shelf(i-1,j-1) = cs%v_bdry_val(i-1,j-1)
474 cs%v_shelf(i-1,j) = cs%v_bdry_val(i-1,j)
476 if (((j+g%jdg_offset) == (g%domain%njhalo+1)).and.(cs%v_face_mask(i,j-1) == 3))
then 477 cs%u_shelf(i-1,j-1) = cs%u_bdry_val(i-1,j-1)
478 cs%u_shelf(i,j-1) = cs%u_bdry_val(i,j-1)
479 cs%v_shelf(i-1,j-1) = cs%v_bdry_val(i-1,j-1)
480 cs%v_shelf(i,j-1) = cs%v_bdry_val(i,j-1)
486 call pass_var(cs%ground_frac,g%domain)
488 call pass_var(cs%basal_traction, g%domain)
489 call pass_vector(cs%u_shelf, cs%v_shelf, g%domain, to_all, bgrid_ne)
492 if (active_shelf_dynamics)
then 494 if (cs%calve_to_mask)
then 495 call mom_mesg(
" MOM_ice_shelf.F90, initialize_ice_shelf: reading calving_mask")
497 call get_param(param_file, mdl,
"INPUTDIR", inputdir, default=
".")
498 inputdir = slasher(inputdir)
499 call get_param(param_file, mdl,
"CALVING_MASK_FILE", ic_file, &
500 "The file with a mask for where calving might occur.", &
501 default=
"ice_shelf_h.nc")
502 call get_param(param_file, mdl,
"CALVING_MASK_VARNAME", var_name, &
503 "The variable to use in masking calving.", &
504 default=
"area_shelf_h")
506 filename = trim(inputdir)//trim(ic_file)
507 call log_param(param_file, mdl,
"INPUTDIR/CALVING_MASK_FILE", filename)
508 if (.not.
file_exists(filename, g%Domain))
call mom_error(fatal, &
509 " calving mask file: Unable to open "//trim(filename))
511 call mom_read_data(filename,trim(var_name),cs%calve_mask,g%Domain)
512 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
513 if (cs%calve_mask(i,j) > 0.0) cs%calve_mask(i,j) = 1.0
515 call pass_var(cs%calve_mask,g%domain)
521 call mom_mesg(
"MOM_ice_shelf.F90, initialize_ice_shelf: initialize ice velocity.")
522 call update_od_ffrac_uncoupled(cs, g, iss%h_shelf(:,:))
523 call ice_shelf_solve_outer(cs, iss, g, us, cs%u_shelf, cs%v_shelf, iters, time)
525 if (cs%id_u_shelf > 0)
call post_data(cs%id_u_shelf, cs%u_shelf, cs%diag)
526 if (cs%id_v_shelf > 0)
call post_data(cs%id_v_shelf, cs%v_shelf,cs%diag)
530 cs%id_u_shelf = register_diag_field(
'ocean_model',
'u_shelf',cs%diag%axesCu1, time, &
531 'x-velocity of ice',
'm yr-1', conversion=365.0*86400.0*us%L_T_to_m_s)
532 cs%id_v_shelf = register_diag_field(
'ocean_model',
'v_shelf',cs%diag%axesCv1, time, &
533 'y-velocity of ice',
'm yr-1', conversion=365.0*86400.0*us%L_T_to_m_s)
534 cs%id_u_mask = register_diag_field(
'ocean_model',
'u_mask',cs%diag%axesCu1, time, &
535 'mask for u-nodes',
'none')
536 cs%id_v_mask = register_diag_field(
'ocean_model',
'v_mask',cs%diag%axesCv1, time, &
537 'mask for v-nodes',
'none')
540 cs%id_ground_frac = register_diag_field(
'ocean_model',
'ice_ground_frac',cs%diag%axesT1, time, &
541 'fraction of cell that is grounded',
'none')
542 cs%id_col_thick = register_diag_field(
'ocean_model',
'col_thick',cs%diag%axesT1, time, &
543 'ocean column thickness passed to ice model',
'm', conversion=us%Z_to_m)
544 cs%id_OD_av = register_diag_field(
'ocean_model',
'OD_av',cs%diag%axesT1, time, &
545 'intermediate ocean column thickness passed to ice model',
'm', conversion=us%Z_to_m)
554 cs%id_t_shelf = register_diag_field(
'ocean_model',
't_shelf',cs%diag%axesT1, time, &
556 cs%id_t_mask = register_diag_field(
'ocean_model',
'tmask',cs%diag%axesT1, time, &
557 'mask for T-nodes',
'none')
560 end subroutine initialize_ice_shelf_dyn
563 subroutine initialize_diagnostic_fields(CS, ISS, G, US, Time)
564 type(ice_shelf_dyn_CS),
intent(inout) :: CS
565 type(ice_shelf_state),
intent(in) :: ISS
567 type(ocean_grid_type),
intent(inout) :: G
568 type(unit_scale_type),
intent(in) :: US
569 type(time_type),
intent(in) :: Time
571 integer :: i, j, iters, isd, ied, jsd, jed
574 type(time_type) :: dummy_time
576 rhoi_rhow = cs%density_ice / cs%density_ocean_avg
577 dummy_time = set_time(0,0)
578 isd=g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
582 od = g%bathyT(i,j) - rhoi_rhow * iss%h_shelf(i,j)
586 cs%ground_frac(i,j) = 0.
589 cs%ground_frac(i,j) = 1.
594 call ice_shelf_solve_outer(cs, iss, g, us, cs%u_shelf, cs%v_shelf, iters, dummy_time)
596 end subroutine initialize_diagnostic_fields
600 function ice_time_step_cfl(CS, ISS, G)
605 real :: ice_time_step_cfl
607 real :: dt_local, min_dt
611 min_dt = 5.0e17*g%US%s_to_T
612 min_vel = (1.0e-12/(365.0*86400.0)) * g%US%m_s_to_L_T
613 do j=g%jsc,g%jec ;
do i=g%isc,g%iec ;
if (iss%hmask(i,j) == 1.0)
then 614 dt_local = 2.0*g%areaT(i,j) / &
615 ((g%dyCu(i,j) * max(abs(cs%u_shelf(i,j) + cs%u_shelf(i,j-1)), min_vel) + &
616 g%dyCu(i-1,j)* max(abs(cs%u_shelf(i-1,j)+ cs%u_shelf(i-1,j-1)), min_vel)) + &
617 (g%dxCv(i,j) * max(abs(cs%v_shelf(i,j) + cs%v_shelf(i-1,j)), min_vel) + &
618 g%dxCv(i,j-1)* max(abs(cs%v_shelf(i,j-1)+ cs%v_shelf(i-1,j-1)), min_vel)))
620 min_dt = min(min_dt, dt_local)
621 endif ;
enddo ;
enddo 623 call min_across_pes(min_dt)
625 ice_time_step_cfl = cs%CFL_factor * min_dt
627 end function ice_time_step_cfl
631 subroutine update_ice_shelf(CS, ISS, G, US, time_step, Time, ocean_mass, coupled_grounding, must_update_vel)
637 real,
intent(in) :: time_step
638 type(time_type),
intent(in) :: time
639 real,
dimension(SZDI_(G),SZDJ_(G)), &
640 optional,
intent(in) :: ocean_mass
642 logical,
optional,
intent(in) :: coupled_grounding
644 logical,
optional,
intent(in) :: must_update_vel
647 logical :: update_ice_vel, coupled_gl
649 update_ice_vel = .false.
650 if (
present(must_update_vel)) update_ice_vel = must_update_vel
653 if (
present(ocean_mass) .and.
present(coupled_grounding)) coupled_gl = coupled_grounding
655 call ice_shelf_advect(cs, iss, g, time_step, time)
656 cs%elapsed_velocity_time = cs%elapsed_velocity_time + time_step
657 if (cs%elapsed_velocity_time >= cs%velocity_update_time_step) update_ice_vel = .true.
660 call update_od_ffrac(cs, g, us, ocean_mass, update_ice_vel)
661 elseif (update_ice_vel)
then 662 call update_od_ffrac_uncoupled(cs, g, iss%h_shelf(:,:))
665 if (update_ice_vel)
then 666 call ice_shelf_solve_outer(cs, iss, g, us, cs%u_shelf, cs%v_shelf, iters, time)
669 call ice_shelf_temp(cs, iss, g, us, time_step, iss%water_flux, time)
671 if (update_ice_vel)
then 672 call enable_averages(cs%elapsed_velocity_time, time, cs%diag)
673 if (cs%id_col_thick > 0)
call post_data(cs%id_col_thick, cs%OD_av, cs%diag)
674 if (cs%id_u_shelf > 0)
call post_data(cs%id_u_shelf, cs%u_shelf, cs%diag)
675 if (cs%id_v_shelf > 0)
call post_data(cs%id_v_shelf, cs%v_shelf, cs%diag)
676 if (cs%id_t_shelf > 0)
call post_data(cs%id_t_shelf,cs%t_shelf,cs%diag)
677 if (cs%id_ground_frac > 0)
call post_data(cs%id_ground_frac, cs%ground_frac,cs%diag)
678 if (cs%id_OD_av >0)
call post_data(cs%id_OD_av, cs%OD_av,cs%diag)
680 if (cs%id_u_mask > 0)
call post_data(cs%id_u_mask,cs%umask,cs%diag)
681 if (cs%id_v_mask > 0)
call post_data(cs%id_v_mask,cs%vmask,cs%diag)
682 if (cs%id_t_mask > 0)
call post_data(cs%id_t_mask,cs%tmask,cs%diag)
684 call disable_averaging(cs%diag)
686 cs%elapsed_velocity_time = 0.0
689 end subroutine update_ice_shelf
694 subroutine ice_shelf_advect(CS, ISS, G, time_step, Time)
695 type(ice_shelf_dyn_CS),
intent(inout) :: CS
696 type(ice_shelf_state),
intent(inout) :: ISS
698 type(ocean_grid_type),
intent(inout) :: G
699 real,
intent(in) :: time_step
700 type(time_type),
intent(in) :: Time
712 real,
dimension(SZDI_(G),SZDJ_(G)) :: h_after_uflux, h_after_vflux
713 real,
dimension(SZDIB_(G),SZDJ_(G)) :: uh_ice
714 real,
dimension(SZDI_(G),SZDJB_(G)) :: vh_ice
715 type(loop_bounds_type) :: LB
716 integer :: isd, ied, jsd, jed, i, j, isc, iec, jsc, jec, stencil
718 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
719 isc = g%isc ; iec = g%iec ; jsc = g%jsc ; jec = g%jec
724 h_after_uflux(:,:) = 0.0
725 h_after_vflux(:,:) = 0.0
728 do j=jsd,jed ;
do i=isd,ied ;
if (cs%thickness_bdry_val(i,j) /= 0.0)
then 729 iss%h_shelf(i,j) = cs%thickness_bdry_val(i,j)
730 endif ;
enddo ;
enddo 733 lb%ish = g%isc ; lb%ieh = g%iec ; lb%jsh = g%jsc-stencil ; lb%jeh = g%jec+stencil
734 if (lb%jsh < jsd)
call mom_error(fatal, &
735 "ice_shelf_advect: Halo is too small for the ice thickness advection stencil.")
737 call ice_shelf_advect_thickness_x(cs, g, lb, time_step, iss%hmask, iss%h_shelf, h_after_uflux, uh_ice)
744 lb%ish = g%isc ; lb%ieh = g%iec ; lb%jsh = g%jsc ; lb%jeh = g%jec
745 call ice_shelf_advect_thickness_y(cs, g, lb, time_step, iss%hmask, h_after_uflux, h_after_vflux, vh_ice)
754 if (iss%hmask(i,j) == 1) iss%h_shelf(i,j) = h_after_vflux(i,j)
758 if (cs%moving_shelf_front)
then 759 call shelf_advance_front(cs, iss, g, iss%hmask, uh_ice, vh_ice)
760 if (cs%min_thickness_simple_calve > 0.0)
then 761 call ice_shelf_min_thickness_calve(g, iss%h_shelf, iss%area_shelf_h, iss%hmask, &
762 cs%min_thickness_simple_calve)
764 if (cs%calve_to_mask)
then 765 call calve_to_mask(g, iss%h_shelf, iss%area_shelf_h, iss%hmask, cs%calve_mask)
775 call update_velocity_masks(cs, g, iss%hmask, cs%umask, cs%vmask, cs%u_face_mask, cs%v_face_mask)
777 end subroutine ice_shelf_advect
779 subroutine ice_shelf_solve_outer(CS, ISS, G, US, u_shlf, v_shlf, iters, time)
780 type(ice_shelf_dyn_CS),
intent(inout) :: CS
781 type(ice_shelf_state),
intent(in) :: ISS
783 type(ocean_grid_type),
intent(inout) :: G
784 type(unit_scale_type),
intent(in) :: US
785 real,
dimension(SZDIB_(G),SZDJB_(G)), &
786 intent(inout) :: u_shlf
787 real,
dimension(SZDIB_(G),SZDJB_(G)), &
788 intent(inout) :: v_shlf
789 integer,
intent(out) :: iters
790 type(time_type),
intent(in) :: Time
792 real,
dimension(SZDIB_(G),SZDJB_(G)) :: taudx, taudy
793 real,
dimension(SZDIB_(G),SZDJB_(G)) :: u_bdry_cont
794 real,
dimension(SZDIB_(G),SZDJB_(G)) :: v_bdry_cont
795 real,
dimension(SZDIB_(G),SZDJB_(G)) :: Au, Av
796 real,
dimension(SZDIB_(G),SZDJB_(G)) :: err_u, err_v
797 real,
dimension(SZDIB_(G),SZDJB_(G)) :: u_last, v_last
798 real,
dimension(SZDIB_(G),SZDJB_(G)) :: H_node
799 real,
dimension(SZDI_(G),SZDJ_(G)) :: float_cond
801 character(len=160) :: mesg
802 integer :: conv_flag, i, j, k,l, iter
803 integer :: isdq, iedq, jsdq, jedq, isd, ied, jsd, jed, nodefloat, nsub
804 real :: err_max, err_tempu, err_tempv, err_init, area, max_vel, tempu, tempv
806 real,
pointer,
dimension(:,:,:,:) :: Phi => null()
808 real,
pointer,
dimension(:,:,:,:,:,:) :: Phisub => null()
810 character(2) :: iternum
811 character(2) :: numproc
814 nsub = cs%n_sub_regularize
816 isdq = g%isdB ; iedq = g%iedB ; jsdq = g%jsdB ; jedq = g%jedB
817 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
818 rhoi_rhow = cs%density_ice / cs%density_ocean_avg
820 taudx(:,:) = 0.0 ; taudy(:,:) = 0.0
821 u_bdry_cont(:,:) = 0.0 ; v_bdry_cont(:,:) = 0.0
822 au(:,:) = 0.0 ; av(:,:) = 0.0
825 float_cond(:,:) = 0.0 ; h_node(:,:) = 0.0
826 allocate(phisub(nsub,nsub,2,2,2,2)) ; phisub(:,:,:,:,:,:) = 0.0
828 call calc_shelf_driving_stress(cs, iss, g, us, taudx, taudy, cs%OD_av)
837 if (cs%GL_regularize)
then 839 call interpolate_h_to_b(g, iss%h_shelf, iss%hmask, h_node)
841 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
845 if ((iss%hmask(i,j) == 1) .and. &
846 (rhoi_rhow * h_node(i-1+k,j-1+l) - g%bathyT(i,j) <= 0))
then 847 nodefloat = nodefloat + 1
850 if ((nodefloat > 0) .and. (nodefloat < 4))
then 851 float_cond(i,j) = 1.0
852 cs%ground_frac(i,j) = 1.0
858 call bilinear_shape_functions_subgrid(phisub, nsub)
863 allocate(phi(1:8,1:4,isd:ied,jsd:jed)) ; phi(:,:,:,:) = 0.0
865 do j=jsd,jed ;
do i=isd,ied
866 call bilinear_shape_fn_grid(g, i, j, phi(:,:,i,j))
869 call calc_shelf_visc(cs, iss, g, us, u_shlf, v_shlf)
871 call pass_var(cs%ice_visc, g%domain)
872 call pass_var(cs%basal_traction, g%domain)
875 do j=g%jsd,g%jed ;
do i=g%isd,g%ied
876 cs%basal_traction(i,j) = cs%basal_traction(i,j) * cs%ground_frac(i,j)
879 call apply_boundary_values(cs, iss, g, us, time, phisub, h_node, cs%ice_visc, &
880 cs%basal_traction, float_cond, rhoi_rhow, u_bdry_cont, v_bdry_cont)
882 au(:,:) = 0.0 ; av(:,:) = 0.0
884 call cg_action(au, av, u_shlf, v_shlf, phi, phisub, cs%umask, cs%vmask, iss%hmask, h_node, &
885 cs%ice_visc, float_cond, g%bathyT, cs%basal_traction, &
886 g, us, g%isc-1, g%iec+1, g%jsc-1, g%jec+1, rhoi_rhow)
888 if (cs%nonlin_solve_err_mode == 1)
then 889 err_init = 0 ; err_tempu = 0 ; err_tempv = 0
890 do j=g%IscB,g%JecB ;
do i=g%IscB,g%IecB
891 if (cs%umask(i,j) == 1)
then 892 err_tempu = abs(au(i,j) + u_bdry_cont(i,j) - taudx(i,j))
893 if (err_tempu >= err_init) err_init = err_tempu
895 if (cs%vmask(i,j) == 1)
then 896 err_tempv = abs(av(i,j) + v_bdry_cont(i,j) - taudy(i,j))
897 if (err_tempv >= err_init) err_init = err_tempv
901 call max_across_pes(err_init)
904 u_last(:,:) = u_shlf(:,:) ; v_last(:,:) = v_shlf(:,:)
910 call ice_shelf_solve_inner(cs, iss, g, us, u_shlf, v_shlf, taudx, taudy, h_node, float_cond, &
911 iss%hmask, conv_flag, iters, time, phi, phisub)
914 call qchksum(u_shlf,
"u shelf", g%HI, haloshift=2, scale=us%L_T_to_m_s)
915 call qchksum(v_shlf,
"v shelf", g%HI, haloshift=2, scale=us%L_T_to_m_s)
918 write(mesg,*)
"ice_shelf_solve_outer: linear solve done in ",iters,
" iterations" 919 call mom_mesg(mesg, 5)
921 call calc_shelf_visc(cs, iss, g, us, u_shlf, v_shlf)
922 call pass_var(cs%ice_visc, g%domain)
923 call pass_var(cs%basal_traction, g%domain)
926 do j=g%jsd,g%jed ;
do i=g%isd,g%ied
927 cs%basal_traction(i,j) = cs%basal_traction(i,j) * cs%ground_frac(i,j)
930 u_bdry_cont(:,:) = 0 ; v_bdry_cont(:,:) = 0
932 call apply_boundary_values(cs, iss, g, us, time, phisub, h_node, cs%ice_visc, &
933 cs%basal_traction, float_cond, rhoi_rhow, u_bdry_cont, v_bdry_cont)
935 au(:,:) = 0 ; av(:,:) = 0
937 call cg_action(au, av, u_shlf, v_shlf, phi, phisub, cs%umask, cs%vmask, iss%hmask, h_node, &
938 cs%ice_visc, float_cond, g%bathyT, cs%basal_traction, &
939 g, us, g%isc-1, g%iec+1, g%jsc-1, g%jec+1, rhoi_rhow)
943 if (cs%nonlin_solve_err_mode == 1)
then 945 do j=g%jscB,g%jecB ;
do i=g%jscB,g%iecB
946 if (cs%umask(i,j) == 1)
then 947 err_tempu = abs(au(i,j) + u_bdry_cont(i,j) - taudx(i,j))
948 if (err_tempu >= err_max) err_max = err_tempu
950 if (cs%vmask(i,j) == 1)
then 951 err_tempv = abs(av(i,j) + v_bdry_cont(i,j) - taudy(i,j))
952 if (err_tempv >= err_max) err_max = err_tempv
956 call max_across_pes(err_max)
958 elseif (cs%nonlin_solve_err_mode == 2)
then 960 max_vel = 0 ; tempu = 0 ; tempv = 0
961 do j=g%jscB,g%jecB ;
do i=g%iscB,g%iecB
962 if (cs%umask(i,j) == 1)
then 963 err_tempu = abs(u_last(i,j)-u_shlf(i,j))
964 if (err_tempu >= err_max) err_max = err_tempu
969 if (cs%vmask(i,j) == 1)
then 970 err_tempv = max(abs(v_last(i,j)-v_shlf(i,j)), err_tempu)
971 if (err_tempv >= err_max) err_max = err_tempv
972 tempv = sqrt(v_shlf(i,j)**2 + tempu**2)
974 if (tempv >= max_vel) max_vel = tempv
977 u_last(:,:) = u_shlf(:,:)
978 v_last(:,:) = v_shlf(:,:)
980 call max_across_pes(max_vel)
981 call max_across_pes(err_max)
985 write(mesg,*)
"ice_shelf_solve_outer: nonlinear fractional residual = ", err_max/err_init
986 call mom_mesg(mesg, 5)
988 if (err_max <= cs%nonlinear_tolerance * err_init)
then 989 write(mesg,*)
"ice_shelf_solve_outer: exiting nonlinear solve after ",iter,
" iterations" 990 call mom_mesg(mesg, 5)
999 end subroutine ice_shelf_solve_outer
1001 subroutine ice_shelf_solve_inner(CS, ISS, G, US, u_shlf, v_shlf, taudx, taudy, H_node, float_cond, &
1002 hmask, conv_flag, iters, time, Phi, Phisub)
1003 type(ice_shelf_dyn_CS),
intent(in) :: CS
1004 type(ice_shelf_state),
intent(in) :: ISS
1006 type(ocean_grid_type),
intent(inout) :: G
1007 type(unit_scale_type),
intent(in) :: US
1008 real,
dimension(SZDIB_(G),SZDJB_(G)), &
1009 intent(inout) :: u_shlf
1010 real,
dimension(SZDIB_(G),SZDJB_(G)), &
1011 intent(inout) :: v_shlf
1012 real,
dimension(SZDIB_(G),SZDJB_(G)), &
1014 real,
dimension(SZDIB_(G),SZDJB_(G)), &
1016 real,
dimension(SZDIB_(G),SZDJB_(G)), &
1017 intent(in) :: H_node
1019 real,
dimension(SZDI_(G),SZDJ_(G)), &
1020 intent(in) :: float_cond
1022 real,
dimension(SZDI_(G),SZDJ_(G)), &
1025 integer,
intent(out) :: conv_flag
1027 integer,
intent(out) :: iters
1028 type(time_type),
intent(in) :: Time
1029 real,
dimension(8,4,SZDI_(G),SZDJ_(G)), &
1032 real,
dimension(:,:,:,:,:,:), &
1033 intent(in) :: Phisub
1044 real,
dimension(SZDIB_(G),SZDJB_(G)) :: &
1055 real :: tol, beta_k, area, dot_p1, resid0, cg_halo
1060 real :: resid2_scale
1063 integer :: iter, i, j, isd, ied, jsd, jed, isc, iec, jsc, jec, is, js, ie, je
1064 integer :: Is_sum, Js_sum, Ie_sum, Je_sum
1065 integer :: isdq, iedq, jsdq, jedq, iscq, iecq, jscq, jecq, nx_halo, ny_halo
1067 isdq = g%isdB ; iedq = g%iedB ; jsdq = g%jsdB ; jedq = g%jedB
1068 iscq = g%iscB ; iecq = g%iecB ; jscq = g%jscB ; jecq = g%jecB
1069 ny_halo = g%domain%njhalo ; nx_halo = g%domain%nihalo
1070 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
1071 isc = g%isc ; iec = g%iec ; jsc = g%jsc ; jec = g%jec
1073 rhoi_rhow = cs%density_ice / cs%density_ocean_avg
1075 zu(:,:) = 0 ; zv(:,:) = 0 ; diagu(:,:) = 0 ; diagv(:,:) = 0
1076 ru(:,:) = 0 ; rv(:,:) = 0 ; au(:,:) = 0 ; av(:,:) = 0
1077 du(:,:) = 0 ; dv(:,:) = 0 ; ubd(:,:) = 0 ; vbd(:,:) = 0
1081 is_sum = g%isc + (1-g%IsdB)
1082 ie_sum = g%iecB + (1-g%IsdB)
1084 if (g%isc+g%idg_offset==g%isg) is_sum = g%IscB + (1-g%IsdB)
1086 js_sum = g%jsc + (1-g%JsdB)
1087 je_sum = g%jecB + (1-g%JsdB)
1089 if (g%jsc+g%jdg_offset==g%jsg) js_sum = g%JscB + (1-g%JsdB)
1091 call apply_boundary_values(cs, iss, g, us, time, phisub, h_node, cs%ice_visc, &
1092 cs%basal_traction, float_cond, rhoi_rhow, ubd, vbd)
1094 rhsu(:,:) = taudx(:,:) - ubd(:,:)
1095 rhsv(:,:) = taudy(:,:) - vbd(:,:)
1097 call pass_vector(rhsu, rhsv, g%domain, to_all, bgrid_ne)
1099 call matrix_diagonal(cs, g, us, float_cond, h_node, cs%ice_visc, cs%basal_traction, &
1100 hmask, rhoi_rhow, phisub, diagu, diagv)
1102 call pass_vector(diagu, diagv, g%domain, to_all, bgrid_ne)
1104 call cg_action(au, av, u_shlf, v_shlf, phi, phisub, cs%umask, cs%vmask, hmask, &
1105 h_node, cs%ice_visc, float_cond, g%bathyT, cs%basal_traction, &
1106 g, us, isc-1, iec+1, jsc-1, jec+1, rhoi_rhow)
1108 call pass_vector(au, av, g%domain, to_all, bgrid_ne)
1110 ru(:,:) = (rhsu(:,:) - au(:,:))
1111 rv(:,:) = (rhsv(:,:) - av(:,:))
1113 resid_scale = us%L_to_m**2*us%s_to_T*us%RZ_to_kg_m2*us%L_T_to_m_s**2
1114 resid2_scale = (us%RZ_to_kg_m2*us%L_to_m*us%L_T_to_m_s**2)**2
1117 do j=jscq,jecq ;
do i=iscq,iecq
1118 if (cs%umask(i,j) == 1) sum_vec(i,j) = resid2_scale*ru(i,j)**2
1119 if (cs%vmask(i,j) == 1) sum_vec(i,j) = sum_vec(i,j) + resid2_scale*rv(i,j)**2
1124 resid0 = sqrt(dot_p1)
1128 if (cs%umask(i,j) == 1) zu(i,j) = ru(i,j) / diagu(i,j)
1129 if (cs%vmask(i,j) == 1) zv(i,j) = rv(i,j) / diagv(i,j)
1133 du(:,:) = zu(:,:) ; dv(:,:) = zv(:,:)
1146 do iter = 1,cs%cg_max_iterations
1153 is = isc - cg_halo ; ie = iecq + cg_halo
1154 js = jscq - cg_halo ; je = jecq + cg_halo
1156 au(:,:) = 0 ; av(:,:) = 0
1158 call cg_action(au, av, du, dv, phi, phisub, cs%umask, cs%vmask, hmask, &
1159 h_node, cs%ice_visc, float_cond, g%bathyT, cs%basal_traction, &
1160 g, us, is, ie, js, je, rhoi_rhow)
1165 sum_vec(:,:) = 0.0 ; sum_vec_2(:,:) = 0.0
1167 do j=jscq,jecq ;
do i=iscq,iecq
1168 if (cs%umask(i,j) == 1)
then 1169 sum_vec(i,j) = resid_scale * zu(i,j) * ru(i,j)
1170 sum_vec_2(i,j) = resid_scale * du(i,j) * au(i,j)
1172 if (cs%vmask(i,j) == 1)
then 1173 sum_vec(i,j) = sum_vec(i,j) + resid_scale * zv(i,j) * rv(i,j)
1174 sum_vec_2(i,j) = sum_vec_2(i,j) + resid_scale * dv(i,j) * av(i,j)
1178 alpha_k =
reproducing_sum( sum_vec, is_sum, ie_sum, js_sum, je_sum ) / &
1182 do j=jsd,jed ;
do i=isd,ied
1183 if (cs%umask(i,j) == 1) u_shlf(i,j) = u_shlf(i,j) + alpha_k * du(i,j)
1184 if (cs%vmask(i,j) == 1) v_shlf(i,j) = v_shlf(i,j) + alpha_k * dv(i,j)
1187 do j=jsd,jed ;
do i=isd,ied
1188 if (cs%umask(i,j) == 1)
then 1189 ru_old(i,j) = ru(i,j) ; zu_old(i,j) = zu(i,j)
1191 if (cs%vmask(i,j) == 1)
then 1192 rv_old(i,j) = rv(i,j) ; zv_old(i,j) = zv(i,j)
1201 if (cs%umask(i,j) == 1) ru(i,j) = ru(i,j) - alpha_k * au(i,j)
1202 if (cs%vmask(i,j) == 1) rv(i,j) = rv(i,j) - alpha_k * av(i,j)
1208 if (cs%umask(i,j) == 1)
then 1209 zu(i,j) = ru(i,j) / diagu(i,j)
1211 if (cs%vmask(i,j) == 1)
then 1212 zv(i,j) = rv(i,j) / diagv(i,j)
1220 sum_vec(:,:) = 0.0 ; sum_vec_2(:,:) = 0.0
1222 do j=jscq,jecq ;
do i=iscq,iecq
1223 if (cs%umask(i,j) == 1)
then 1224 sum_vec(i,j) = resid_scale * zu(i,j) * ru(i,j)
1225 sum_vec_2(i,j) = resid_scale * zu_old(i,j) * ru_old(i,j)
1227 if (cs%vmask(i,j) == 1)
then 1228 sum_vec(i,j) = sum_vec(i,j) + resid_scale * zv(i,j) * rv(i,j)
1229 sum_vec_2(i,j) = sum_vec_2(i,j) + resid_scale * zv_old(i,j) * rv_old(i,j)
1233 beta_k =
reproducing_sum(sum_vec, is_sum, ie_sum, js_sum, je_sum ) / &
1241 if (cs%umask(i,j) == 1) du(i,j) = zu(i,j) + beta_k * du(i,j)
1242 if (cs%vmask(i,j) == 1) dv(i,j) = zv(i,j) + beta_k * dv(i,j)
1249 do j=jscq,jecq ;
do i=iscq,iecq
1250 if (cs%umask(i,j) == 1) sum_vec(i,j) = resid2_scale*ru(i,j)**2
1251 if (cs%vmask(i,j) == 1) sum_vec(i,j) = sum_vec(i,j) + resid2_scale*rv(i,j)**2
1255 dot_p1 = sqrt(dot_p1)
1257 if (dot_p1 <= cs%cg_tolerance * resid0)
then 1263 cg_halo = cg_halo - 1
1265 if (cg_halo == 0)
then 1267 call pass_vector(du, dv, g%domain, to_all, bgrid_ne)
1268 call pass_vector(u_shlf, v_shlf, g%domain, to_all, bgrid_ne)
1269 call pass_vector(ru, rv, g%domain, to_all, bgrid_ne)
1277 if (cs%umask(i,j) == 3)
then 1278 u_shlf(i,j) = cs%u_bdry_val(i,j)
1279 elseif (cs%umask(i,j) == 0)
then 1283 if (cs%vmask(i,j) == 3)
then 1284 v_shlf(i,j) = cs%v_bdry_val(i,j)
1285 elseif (cs%vmask(i,j) == 0)
then 1291 call pass_vector(u_shlf, v_shlf, g%domain, to_all, bgrid_ne)
1293 if (conv_flag == 0)
then 1294 iters = cs%cg_max_iterations
1297 end subroutine ice_shelf_solve_inner
1299 subroutine ice_shelf_advect_thickness_x(CS, G, LB, time_step, hmask, h0, h_after_uflux, uh_ice)
1300 type(ice_shelf_dyn_CS),
intent(in) :: CS
1301 type(ocean_grid_type),
intent(in) :: G
1302 type(loop_bounds_type),
intent(in) :: LB
1303 real,
intent(in) :: time_step
1304 real,
dimension(SZDI_(G),SZDJ_(G)), &
1305 intent(inout) :: hmask
1307 real,
dimension(SZDI_(G),SZDJ_(G)), &
1309 real,
dimension(SZDI_(G),SZDJ_(G)), &
1310 intent(inout) :: h_after_uflux
1312 real,
dimension(SZDIB_(G),SZDJ_(G)), &
1313 intent(inout) :: uh_ice
1320 integer :: ish, ieh, jsh, jeh
1329 ish = lb%ish ; ieh = lb%ieh ; jsh = lb%jsh ; jeh = lb%jeh
1334 do j=jsh,jeh ;
do i=ish-1,ieh
1335 if (cs%u_face_mask(i,j) == 4.)
then 1336 uh_ice(i,j) = time_step * g%dyCu(i,j) * cs%u_flux_bdry_val(i,j)
1337 elseif ((hmask(i,j)==1) .or. (hmask(i+1,j) == 1))
then 1338 u_face = 0.5 * (cs%u_shelf(i,j-1) + cs%u_shelf(i,j))
1341 if (u_face > 0)
then 1342 if (hmask(i,j) == 3)
then 1343 h_face = cs%thickness_bdry_val(i,j)
1344 elseif (hmask(i,j) == 1)
then 1345 if ((hmask(i-1,j) == 1) .and. (hmask(i+1,j) == 1))
then 1346 slope_lim = slope_limiter(h0(i,j)-h0(i-1,j), h0(i+1,j)-h0(i,j))
1348 h_face = h0(i,j) - slope_lim * 0.5 * (h0(i,j)-h0(i+1,j))
1354 if (hmask(i+1,j) == 3)
then 1355 h_face = cs%thickness_bdry_val(i+1,j)
1356 elseif (hmask(i+1,j) == 1)
then 1357 if ((hmask(i,j) == 1) .and. (hmask(i+2,j) == 1))
then 1358 slope_lim = slope_limiter(h0(i+1,j)-h0(i,j), h0(i+2,j)-h0(i+1,j))
1359 h_face = h0(i+1,j) - slope_lim * 0.5 * (h0(i+1,j)-h0(i,j))
1366 uh_ice(i,j) = time_step * g%dyCu(i,j) * u_face * h_face
1372 do j=jsh,jeh ;
do i=ish,ieh
1373 if (hmask(i,j) /= 3) &
1374 h_after_uflux(i,j) = h0(i,j) + (uh_ice(i-1,j) - uh_ice(i,j)) * g%IareaT(i,j)
1377 if ((hmask(i,j) == 0) .and. ((uh_ice(i-1,j) > 0.0) .or. (uh_ice(i,j) < 0.0))) hmask(i,j) = 2
1380 end subroutine ice_shelf_advect_thickness_x
1382 subroutine ice_shelf_advect_thickness_y(CS, G, LB, time_step, hmask, h0, h_after_vflux, vh_ice)
1383 type(ice_shelf_dyn_CS),
intent(in) :: CS
1384 type(ocean_grid_type),
intent(in) :: G
1385 type(loop_bounds_type),
intent(in) :: LB
1386 real,
intent(in) :: time_step
1387 real,
dimension(SZDI_(G),SZDJ_(G)), &
1388 intent(inout) :: hmask
1390 real,
dimension(SZDI_(G),SZDJ_(G)), &
1392 real,
dimension(SZDI_(G),SZDJ_(G)), &
1393 intent(inout) :: h_after_vflux
1395 real,
dimension(SZDI_(G),SZDJB_(G)), &
1396 intent(inout) :: vh_ice
1403 integer :: ish, ieh, jsh, jeh
1408 ish = lb%ish ; ieh = lb%ieh ; jsh = lb%jsh ; jeh = lb%jeh
1413 do j=jsh-1,jeh ;
do i=ish,ieh
1414 if (cs%v_face_mask(i,j) == 4.)
then 1415 vh_ice(i,j) = time_step * g%dxCv(i,j) * cs%v_flux_bdry_val(i,j)
1416 elseif ((hmask(i,j)==1) .or. (hmask(i,j+1) == 1))
then 1418 v_face = 0.5 * (cs%v_shelf(i-1,j) + cs%v_shelf(i,j))
1421 if (v_face > 0)
then 1422 if (hmask(i,j) == 3)
then 1423 h_face = cs%thickness_bdry_val(i,j)
1424 elseif (hmask(i,j) == 1)
then 1425 if ((hmask(i,j-1) == 1) .and. (hmask(i,j+1) == 1))
then 1426 slope_lim = slope_limiter(h0(i,j)-h0(i,j-1), h0(i,j+1)-h0(i,j))
1428 h_face = h0(i,j) - slope_lim * 0.5 * (h0(i,j)-h0(i,j+1))
1434 if (hmask(i,j+1) == 3)
then 1435 h_face = cs%thickness_bdry_val(i,j+1)
1436 elseif (hmask(i,j+1) == 1)
then 1437 if ((hmask(i,j) == 1) .and. (hmask(i,j+2) == 1))
then 1438 slope_lim = slope_limiter(h0(i,j+1)-h0(i,j), h0(i,j+2)-h0(i,j+1))
1439 h_face = h0(i,j+1) - slope_lim * 0.5 * (h0(i,j+1)-h0(i,j))
1446 vh_ice(i,j) = time_step * g%dxCv(i,j) * v_face * h_face
1452 do j=jsh,jeh ;
do i=ish,ieh
1453 if (hmask(i,j) /= 3) &
1454 h_after_vflux(i,j) = h0(i,j) + (vh_ice(i,j-1) - vh_ice(i,j)) * g%IareaT(i,j)
1457 if ((hmask(i,j) == 0) .and. ((vh_ice(i,j-1) > 0.0) .or. (vh_ice(i,j) < 0.0))) hmask(i,j) = 2
1460 end subroutine ice_shelf_advect_thickness_y
1462 subroutine shelf_advance_front(CS, ISS, G, hmask, uh_ice, vh_ice)
1467 real,
dimension(SZDI_(G),SZDJ_(G)), &
1468 intent(inout) :: hmask
1470 real,
dimension(SZDIB_(G),SZDJ_(G)), &
1471 intent(inout) :: uh_ice
1472 real,
dimension(SZDI_(G),SZDJB_(G)), &
1473 intent(inout) :: vh_ice
1502 integer :: i, j, isc, iec, jsc, jec, n_flux, k, l, iter_count
1503 integer :: i_off, j_off
1504 integer :: iter_flag
1510 character(len=160) :: mesg
1511 integer,
dimension(4) :: mapi, mapj, new_partial
1512 real,
dimension(SZDI_(G),SZDJ_(G),4) :: flux_enter
1514 real,
dimension(SZDI_(G),SZDJ_(G),4) :: flux_enter_replace
1517 isc = g%isc ; iec = g%iec ; jsc = g%jsc ; jec = g%jec
1518 i_off = g%idg_offset ; j_off = g%jdg_offset
1519 iter_count = 0 ; iter_flag = 1
1521 flux_enter(:,:,:) = 0.0
1522 do j=jsc-1,jec+1 ;
do i=isc-1,iec+1
1523 if ((hmask(i,j) == 0) .or. (hmask(i,j) == 2))
then 1524 flux_enter(i,j,1) = max(uh_ice(i-1,j), 0.0)
1525 flux_enter(i,j,2) = max(-uh_ice(i,j), 0.0)
1526 flux_enter(i,j,3) = max(vh_ice(i,j-1), 0.0)
1527 flux_enter(i,j,4) = max(-vh_ice(i,j), 0.0)
1531 mapi(1) = -1 ; mapi(2) = 1 ; mapi(3:4) = 0
1532 mapj(3) = -1 ; mapj(4) = 1 ; mapj(1:2) = 0
1534 do while (iter_flag == 1)
1538 if (iter_count > 0)
then 1539 flux_enter(:,:,:) = flux_enter_replace(:,:,:)
1541 flux_enter_replace(:,:,:) = 0.0
1543 iter_count = iter_count + 1
1549 if (((j+j_off) <= g%domain%njglobal+g%domain%njhalo) .AND. &
1550 ((j+j_off) >= g%domain%njhalo+1))
then 1554 if (((i+i_off) <= g%domain%niglobal+g%domain%nihalo) .AND. &
1555 ((i+i_off) >= g%domain%nihalo+1))
then 1562 if (flux_enter(i,j,k) > 0)
then 1564 h_reference = h_reference + iss%h_shelf(i+2*k-3,j)
1565 tot_flux = tot_flux + flux_enter(i,j,k)
1566 flux_enter(i,j,k) = 0.0
1571 if (flux_enter(i,j,k+2) > 0)
then 1573 h_reference = h_reference + iss%h_shelf(i,j+2*k-3)
1574 tot_flux = tot_flux + flux_enter(i,j,k+2)
1575 flux_enter(i,j,k+2) = 0.0
1579 if (n_flux > 0)
then 1580 dxdyh = g%areaT(i,j)
1581 h_reference = h_reference /
real(n_flux)
1582 partial_vol = iss%h_shelf(i,j) * iss%area_shelf_h(i,j) + tot_flux
1584 if ((partial_vol / g%areaT(i,j)) == h_reference)
then 1586 iss%h_shelf(i,j) = h_reference
1587 iss%area_shelf_h(i,j) = g%areaT(i,j)
1588 elseif ((partial_vol / g%areaT(i,j)) < h_reference)
then 1591 iss%area_shelf_h(i,j) = partial_vol / h_reference
1592 iss%h_shelf(i,j) = h_reference
1596 iss%area_shelf_h(i,j) = g%areaT(i,j)
1598 partial_vol = partial_vol - h_reference * g%areaT(i,j)
1602 n_flux = 0 ; new_partial(:) = 0
1605 if (cs%u_face_mask(i-2+k,j) == 2)
then 1607 elseif (iss%hmask(i+2*k-3,j) == 0)
then 1611 if (cs%v_face_mask(i,j-2+k) == 2)
then 1613 elseif (iss%hmask(i,j+2*k-3) == 0)
then 1615 new_partial(k+2) = 1
1619 if (n_flux == 0)
then 1620 iss%h_shelf(i,j) = h_reference + partial_vol / g%areaT(i,j)
1622 iss%h_shelf(i,j) = h_reference
1625 if (new_partial(k) == 1) &
1626 flux_enter_replace(i+2*k-3,j,3-k) = partial_vol /
real(n_flux)
1627 if (new_partial(k+2) == 1) &
1628 flux_enter_replace(i,j+2*k-3,5-k) = partial_vol /
real(n_flux)
1644 call max_across_pes(iter_count)
1646 if (is_root_pe() .and. (iter_count > 1))
then 1647 write(mesg,*)
"shelf_advance_front: ", iter_count,
" max iterations" 1648 call mom_mesg(mesg, 5)
1651 end subroutine shelf_advance_front
1654 subroutine ice_shelf_min_thickness_calve(G, h_shelf, area_shelf_h, hmask, thickness_calve, halo)
1656 real,
dimension(SZDI_(G),SZDJ_(G)),
intent(inout) :: h_shelf
1657 real,
dimension(SZDI_(G),SZDJ_(G)),
intent(inout) :: area_shelf_h
1659 real,
dimension(SZDI_(G),SZDJ_(G)),
intent(inout) :: hmask
1661 real,
intent(in) :: thickness_calve
1662 integer,
optional,
intent(in) :: halo
1664 integer :: i, j, is, ie, js, je
1666 if (
present(halo))
then 1667 is = g%isc - halo ; ie = g%iec + halo ; js = g%jsc - halo ; je = g%jec + halo
1669 is = g%isd ; ie = g%ied ; js = g%jsd ; je = g%jed
1672 do j=js,je ;
do i=is,ie
1675 if ((h_shelf(i,j) < thickness_calve) .and. (area_shelf_h(i,j) > 0.))
then 1677 area_shelf_h(i,j) = 0.0
1682 end subroutine ice_shelf_min_thickness_calve
1684 subroutine calve_to_mask(G, h_shelf, area_shelf_h, hmask, calve_mask)
1686 real,
dimension(SZDI_(G),SZDJ_(G)),
intent(inout) :: h_shelf
1687 real,
dimension(SZDI_(G),SZDJ_(G)),
intent(inout) :: area_shelf_h
1689 real,
dimension(SZDI_(G),SZDJ_(G)),
intent(inout) :: hmask
1691 real,
dimension(SZDI_(G),SZDJ_(G)),
intent(in) :: calve_mask
1696 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
1697 if ((calve_mask(i,j) == 0.0) .and. (hmask(i,j) /= 0.0))
then 1699 area_shelf_h(i,j) = 0.0
1704 end subroutine calve_to_mask
1706 subroutine calc_shelf_driving_stress(CS, ISS, G, US, taudx, taudy, OD)
1707 type(ice_shelf_dyn_CS),
intent(in) :: CS
1708 type(ice_shelf_state),
intent(in) :: ISS
1710 type(ocean_grid_type),
intent(inout) :: G
1711 type(unit_scale_type),
intent(in) :: US
1712 real,
dimension(SZDI_(G),SZDJ_(G)), &
1714 real,
dimension(SZDIB_(G),SZDJB_(G)), &
1715 intent(inout) :: taudx
1716 real,
dimension(SZDIB_(G),SZDJB_(G)), &
1717 intent(inout) :: taudy
1731 real,
dimension(SIZE(OD,1),SIZE(OD,2)) :: S, &
1741 integer :: i, j, iscq, iecq, jscq, jecq, isd, jsd, is, js, iegq, jegq
1742 integer :: giec, gjec, gisc, gjsc, cnt, isc, jsc, iec, jec
1743 integer :: i_off, j_off
1745 isc = g%isc ; jsc = g%jsc ; iec = g%iec ; jec = g%jec
1746 iscq = g%iscB ; iecq = g%iecB ; jscq = g%jscB ; jecq = g%jecB
1747 isd = g%isd ; jsd = g%jsd
1748 iegq = g%iegB ; jegq = g%jegB
1749 gisc = g%domain%nihalo+1 ; gjsc = g%domain%njhalo+1
1750 giec = g%domain%niglobal+g%domain%nihalo ; gjec = g%domain%njglobal+g%domain%njhalo
1751 is = iscq - 1; js = jscq - 1
1752 i_off = g%idg_offset ; j_off = g%jdg_offset
1754 rho = cs%density_ice
1755 rhow = cs%density_ocean_avg
1761 base(:,:) = -g%bathyT(:,:) + od(:,:)
1762 s(:,:) = base(:,:) + iss%h_shelf(:,:)
1772 if (iss%hmask(i,j) == 1)
then 1775 if ((i+i_off) == gisc)
then 1776 if (iss%hmask(i+1,j) == 1)
then 1777 sx = (s(i+1,j)-s(i,j))/dxh
1781 elseif ((i+i_off) == giec)
then 1782 if (iss%hmask(i-1,j) == 1)
then 1783 sx = (s(i,j)-s(i-1,j))/dxh
1788 if (iss%hmask(i+1,j) == 1)
then 1794 if (iss%hmask(i-1,j) == 1)
then 1803 sx = sx / (cnt * dxh)
1810 if ((j+j_off) == gjsc)
then 1811 if (iss%hmask(i,j+1) == 1)
then 1812 sy = (s(i,j+1)-s(i,j))/dyh
1816 elseif ((j+j_off) == gjec)
then 1817 if (iss%hmask(i,j-1) == 1)
then 1818 sy = (s(i,j)-s(i,j-1))/dyh
1823 if (iss%hmask(i,j+1) == 1)
then 1829 if (iss%hmask(i,j-1) == 1)
then 1838 sy = sy / (cnt * dyh)
1843 taudx(i-1,j-1) = taudx(i-1,j-1) - .25 * rho * grav * iss%h_shelf(i,j) * sx * g%areaT(i,j)
1844 taudy(i-1,j-1) = taudy(i-1,j-1) - .25 * rho * grav * iss%h_shelf(i,j) * sy * g%areaT(i,j)
1847 taudx(i,j-1) = taudx(i,j-1) - .25 * rho * grav * iss%h_shelf(i,j) * sx * g%areaT(i,j)
1848 taudy(i,j-1) = taudy(i,j-1) - .25 * rho * grav * iss%h_shelf(i,j) * sy * g%areaT(i,j)
1851 taudx(i-1,j) = taudx(i-1,j) - .25 * rho * grav * iss%h_shelf(i,j) * sx * g%areaT(i,j)
1852 taudy(i-1,j) = taudy(i-1,j) - .25 * rho * grav * iss%h_shelf(i,j) * sy * g%areaT(i,j)
1855 taudx(i,j) = taudx(i,j) - .25 * rho * grav * iss%h_shelf(i,j) * sx * g%areaT(i,j)
1856 taudy(i,j) = taudy(i,j) - .25 * rho * grav * iss%h_shelf(i,j) * sy * g%areaT(i,j)
1858 if (cs%ground_frac(i,j) == 1)
then 1859 neumann_val = .5 * grav * (rho * iss%h_shelf(i,j)**2 - rhow * g%bathyT(i,j)**2)
1861 neumann_val = .5 * grav * (1-rho/rhow) * rho * iss%h_shelf(i,j)**2
1864 if ((cs%u_face_mask(i-1,j) == 2) .OR. (iss%hmask(i-1,j) == 0) .OR. (iss%hmask(i-1,j) == 2) )
then 1874 taudx(i-1,j-1) = taudx(i-1,j-1) - .5 * dyh * neumann_val
1875 taudx(i-1,j) = taudx(i-1,j) - .5 * dyh * neumann_val
1878 if ((cs%u_face_mask(i,j) == 2) .OR. (iss%hmask(i+1,j) == 0) .OR. (iss%hmask(i+1,j) == 2) )
then 1880 taudx(i,j-1) = taudx(i,j-1) + .5 * dyh * neumann_val
1881 taudx(i,j) = taudx(i,j) + .5 * dyh * neumann_val
1884 if ((cs%v_face_mask(i,j-1) == 2) .OR. (iss%hmask(i,j-1) == 0) .OR. (iss%hmask(i,j-1) == 2) )
then 1886 taudy(i-1,j-1) = taudy(i-1,j-1) - .5 * dxh * neumann_val
1887 taudy(i,j-1) = taudy(i,j-1) - .5 * dxh * neumann_val
1890 if ((cs%v_face_mask(i,j) == 2) .OR. (iss%hmask(i,j+1) == 0) .OR. (iss%hmask(i,j+1) == 2) )
then 1892 taudy(i-1,j) = taudy(i-1,j) + .5 * dxh * neumann_val
1893 taudy(i,j) = taudy(i,j) + .5 * dxh * neumann_val
1900 end subroutine calc_shelf_driving_stress
1902 subroutine init_boundary_values(CS, G, time, hmask, input_flux, input_thick, new_sim)
1903 type(ice_shelf_dyn_CS),
intent(inout) :: CS
1904 type(ocean_grid_type),
intent(inout) :: G
1905 type(time_type),
intent(in) :: Time
1906 real,
dimension(SZDI_(G),SZDJ_(G)), &
1909 real,
intent(in) :: input_flux
1911 real,
intent(in) :: input_thick
1912 logical,
optional,
intent(in) :: new_sim
1921 integer :: i, j , isd, jsd, ied, jed
1922 integer :: gjec, gisc, gjsc, cnt, isc, jsc, iec, jec
1923 integer :: i_off, j_off
1925 isc = g%isc ; jsc = g%jsc ; iec = g%iec ; jec = g%jec
1926 isd = g%isd ; jsd = g%jsd ; ied = g%ied ; jed = g%jed
1927 i_off = g%idg_offset ; j_off = g%jdg_offset
1934 if (hmask(i,j) == 3)
then 1935 cs%thickness_bdry_val(i,j) = input_thick
1938 if ((hmask(i,j) == 0) .or. (hmask(i,j) == 1) .or. (hmask(i,j) == 2))
then 1939 if ((i <= iec).and.(i >= isc))
then 1940 if (cs%u_face_mask(i-1,j) == 3)
then 1941 cs%u_bdry_val(i-1,j-1) = (1 - ((g%geoLatBu(i-1,j-1) - 0.5*g%len_lat)*2./g%len_lat)**2) * &
1942 1.5 * input_flux / input_thick
1943 cs%u_bdry_val(i-1,j) = (1 - ((g%geoLatBu(i-1,j) - 0.5*g%len_lat)*2./g%len_lat)**2) * &
1944 1.5 * input_flux / input_thick
1949 if (.not.(new_sim))
then 1950 if (.not. g%symmetric)
then 1951 if (((i+i_off) == (g%domain%nihalo+1)).and.(cs%u_face_mask(i-1,j) == 3))
then 1952 cs%u_shelf(i-1,j-1) = cs%u_bdry_val(i-1,j-1)
1953 cs%u_shelf(i-1,j) = cs%u_bdry_val(i-1,j)
1954 cs%v_shelf(i-1,j-1) = cs%v_bdry_val(i-1,j-1)
1955 cs%v_shelf(i-1,j) = cs%v_bdry_val(i-1,j)
1957 if (((j+j_off) == (g%domain%njhalo+1)).and.(cs%v_face_mask(i,j-1) == 3))
then 1958 cs%u_shelf(i-1,j-1) = cs%u_bdry_val(i-1,j-1)
1959 cs%u_shelf(i,j-1) = cs%u_bdry_val(i,j-1)
1960 cs%v_shelf(i-1,j-1) = cs%v_bdry_val(i-1,j-1)
1961 cs%v_shelf(i,j-1) = cs%v_bdry_val(i,j-1)
1968 end subroutine init_boundary_values
1971 subroutine cg_action(uret, vret, u_shlf, v_shlf, Phi, Phisub, umask, vmask, hmask, H_node, &
1972 ice_visc, float_cond, bathyT, basal_trac, G, US, is, ie, js, je, dens_ratio)
1974 type(ocean_grid_type),
intent(in) :: G
1975 real,
dimension(G%IsdB:G%IedB,G%JsdB:G%JedB), &
1976 intent(inout) :: uret
1977 real,
dimension(G%IsdB:G%IedB,G%JsdB:G%JedB), &
1978 intent(inout) :: vret
1979 real,
dimension(SZDI_(G),SZDJ_(G),8,4), &
1982 real,
dimension(:,:,:,:,:,:), &
1983 intent(in) :: Phisub
1985 real,
dimension(SZDIB_(G),SZDJB_(G)), &
1986 intent(in) :: u_shlf
1987 real,
dimension(SZDIB_(G),SZDJB_(G)), &
1988 intent(in) :: v_shlf
1989 real,
dimension(SZDIB_(G),SZDJB_(G)), &
1992 real,
dimension(SZDIB_(G),SZDJB_(G)), &
1995 real,
dimension(SZDIB_(G),SZDJB_(G)), &
1996 intent(in) :: H_node
1998 real,
dimension(SZDI_(G),SZDJ_(G)), &
2001 real,
dimension(SZDIB_(G),SZDJB_(G)), &
2002 intent(in) :: ice_visc
2005 real,
dimension(SZDI_(G),SZDJ_(G)), &
2006 intent(in) :: float_cond
2008 real,
dimension(SZDI_(G),SZDJ_(G)), &
2009 intent(in) :: bathyT
2010 real,
dimension(SZDIB_(G),SZDJB_(G)), &
2011 intent(in) :: basal_trac
2014 real,
intent(in) :: dens_ratio
2016 type(unit_scale_type),
intent(in) :: US
2017 integer,
intent(in) :: is
2018 integer,
intent(in) :: ie
2019 integer,
intent(in) :: js
2020 integer,
intent(in) :: je
2041 real :: ux, uy, vx, vy
2043 integer :: iq, jq, iphi, jphi, i, j, ilq, jlq, Itgt, Jtgt
2044 real,
dimension(2) :: xquad
2045 real,
dimension(2,2) :: Ucell, Vcell, Hcell, Usub, Vsub
2047 xquad(1) = .5 * (1-sqrt(1./3)) ; xquad(2) = .5 * (1+sqrt(1./3))
2049 do j=js,je ;
do i=is,ie ;
if (hmask(i,j) == 1)
then 2051 do iq=1,2 ;
do jq=1,2
2053 uq = u_shlf(i-1,j-1) * xquad(3-iq) * xquad(3-jq) + &
2054 u_shlf(i,j-1) * xquad(iq) * xquad(3-jq) + &
2055 u_shlf(i-1,j) * xquad(3-iq) * xquad(jq) + &
2056 u_shlf(i,j) * xquad(iq) * xquad(jq)
2058 vq = v_shlf(i-1,j-1) * xquad(3-iq) * xquad(3-jq) + &
2059 v_shlf(i,j-1) * xquad(iq) * xquad(3-jq) + &
2060 v_shlf(i-1,j) * xquad(3-iq) * xquad(jq) + &
2061 v_shlf(i,j) * xquad(iq) * xquad(jq)
2063 ux = u_shlf(i-1,j-1) * phi(1,2*(jq-1)+iq,i,j) + &
2064 u_shlf(i,j-1) * phi(3,2*(jq-1)+iq,i,j) + &
2065 u_shlf(i-1,j) * phi(5,2*(jq-1)+iq,i,j) + &
2066 u_shlf(i,j) * phi(7,2*(jq-1)+iq,i,j)
2068 vx = v_shlf(i-1,j-1) * phi(1,2*(jq-1)+iq,i,j) + &
2069 v_shlf(i,j-1) * phi(3,2*(jq-1)+iq,i,j) + &
2070 v_shlf(i-1,j) * phi(5,2*(jq-1)+iq,i,j) + &
2071 v_shlf(i,j) * phi(7,2*(jq-1)+iq,i,j)
2073 uy = u_shlf(i-1,j-1) * phi(2,2*(jq-1)+iq,i,j) + &
2074 u_shlf(i,j-1) * phi(4,2*(jq-1)+iq,i,j) + &
2075 u_shlf(i-1,j) * phi(6,2*(jq-1)+iq,i,j) + &
2076 u_shlf(i,j) * phi(8,2*(jq-1)+iq,i,j)
2078 vy = v_shlf(i-1,j-1) * phi(2,2*(jq-1)+iq,i,j) + &
2079 v_shlf(i,j-1) * phi(4,2*(jq-1)+iq,i,j) + &
2080 v_shlf(i-1,j) * phi(6,2*(jq-1)+iq,i,j) + &
2081 v_shlf(i,j) * phi(8,2*(jq-1)+iq,i,j)
2083 do iphi=1,2 ;
do jphi=1,2 ; itgt = i-2+iphi ; jtgt = j-2-jphi
2084 if (umask(itgt,jtgt) == 1) uret(itgt,jtgt) = uret(itgt,jtgt) + 0.25 * ice_visc(i,j) * &
2085 ((4*ux+2*vy) * phi(2*(2*(jphi-1)+iphi)-1,2*(jq-1)+iq,i,j) + &
2086 (uy+vx) * phi(2*(2*(jphi-1)+iphi),2*(jq-1)+iq,i,j))
2087 if (vmask(itgt,jtgt) == 1) vret(itgt,jtgt) = vret(itgt,jtgt) + 0.25 * ice_visc(i,j) * &
2088 ((uy+vx) * phi(2*(2*(jphi-1)+iphi)-1,2*(jq-1)+iq,i,j) + &
2089 (4*vy+2*ux) * phi(2*(2*(jphi-1)+iphi),2*(jq-1)+iq,i,j))
2091 if (float_cond(i,j) == 0)
then 2092 ilq = 1 ;
if (iq == iphi) ilq = 2
2093 jlq = 1 ;
if (jq == jphi) jlq = 2
2094 if (umask(itgt,jtgt) == 1) uret(itgt,jtgt) = uret(itgt,jtgt) + &
2095 0.25 * basal_trac(i,j) * uq * xquad(ilq) * xquad(jlq)
2096 if (vmask(itgt,jtgt) == 1) vret(itgt,jtgt) = vret(itgt,jtgt) + &
2097 0.25 * basal_trac(i,j) * vq * xquad(ilq) * xquad(jlq)
2102 if (float_cond(i,j) == 1)
then 2103 ucell(:,:) = u_shlf(i-1:i,j-1:j) ; vcell(:,:) = v_shlf(i-1:i,j-1:j)
2104 hcell(:,:) = h_node(i-1:i,j-1:j)
2105 call cg_action_subgrid_basal(phisub, hcell, ucell, vcell, bathyt(i,j), dens_ratio, usub, vsub)
2107 if (umask(i-1,j-1)==1) uret(i-1,j-1) = uret(i-1,j-1) + usub(1,1) * basal_trac(i,j)
2108 if (umask(i-1,j) == 1) uret(i-1,j) = uret(i-1,j) + usub(1,2) * basal_trac(i,j)
2109 if (umask(i,j-1) == 1) uret(i,j-1) = uret(i,j-1) + usub(2,1) * basal_trac(i,j)
2110 if (umask(i,j) == 1) uret(i,j) = uret(i,j) + usub(2,2) * basal_trac(i,j)
2112 if (vmask(i-1,j-1)==1) vret(i-1,j-1) = vret(i-1,j-1) + vsub(1,1) * basal_trac(i,j)
2113 if (vmask(i-1,j) == 1) vret(i-1,j) = vret(i-1,j) + vsub(1,2) * basal_trac(i,j)
2114 if (vmask(i,j-1) == 1) vret(i,j-1) = vret(i,j-1) + vsub(2,1) * basal_trac(i,j)
2115 if (vmask(i,j) == 1) vret(i,j) = vret(i,j) + vsub(2,2) * basal_trac(i,j)
2118 endif ;
enddo ;
enddo 2120 end subroutine cg_action
2122 subroutine cg_action_subgrid_basal(Phisub, H, U, V, bathyT, dens_ratio, Ucontr, Vcontr)
2123 real,
dimension(:,:,:,:,:,:), &
2124 intent(in) :: Phisub
2126 real,
dimension(2,2),
intent(in) :: H
2127 real,
dimension(2,2),
intent(in) :: U
2128 real,
dimension(2,2),
intent(in) :: V
2129 real,
intent(in) :: bathyT
2130 real,
intent(in) :: dens_ratio
2132 real,
dimension(2,2),
intent(out) :: Ucontr
2134 real,
dimension(2,2),
intent(out) :: Vcontr
2139 integer :: nsub, i, j, qx, qy, m, n
2141 nsub =
size(phisub,1)
2142 subarea = 1.0 / (nsub**2)
2145 ucontr(m,n) = 0.0 ; vcontr(m,n) = 0.0
2146 do qy=1,2 ;
do qx=1,2 ;
do j=1,nsub ;
do i=1,nsub
2147 hloc = (phisub(i,j,1,1,qx,qy)*h(1,1) + phisub(i,j,2,2,qx,qy)*h(2,2)) + &
2148 (phisub(i,j,1,2,qx,qy)*h(1,2) + phisub(i,j,2,1,qx,qy)*h(2,1))
2149 if (dens_ratio * hloc - bathyt > 0)
then 2150 ucontr(m,n) = ucontr(m,n) + subarea * 0.25 * phisub(i,j,m,n,qx,qy) * &
2151 ((phisub(i,j,1,1,qx,qy) * u(1,1) + phisub(i,j,2,2,qx,qy) * u(2,2)) + &
2152 (phisub(i,j,1,2,qx,qy) * u(1,2) + phisub(i,j,2,1,qx,qy) * u(2,1)))
2153 vcontr(m,n) = vcontr(m,n) + subarea * 0.25 * phisub(i,j,m,n,qx,qy) * &
2154 ((phisub(i,j,1,1,qx,qy) * v(1,1) + phisub(i,j,2,2,qx,qy) * v(2,2)) + &
2155 (phisub(i,j,1,2,qx,qy) * v(1,2) + phisub(i,j,2,1,qx,qy) * v(2,1)))
2157 enddo ;
enddo ;
enddo ;
enddo 2160 end subroutine cg_action_subgrid_basal
2163 subroutine matrix_diagonal(CS, G, US, float_cond, H_node, ice_visc, basal_trac, hmask, dens_ratio, &
2164 Phisub, u_diagonal, v_diagonal)
2166 type(ice_shelf_dyn_CS),
intent(in) :: CS
2167 type(ocean_grid_type),
intent(in) :: G
2168 type(unit_scale_type),
intent(in) :: US
2169 real,
dimension(SZDI_(G),SZDJ_(G)), &
2170 intent(in) :: float_cond
2172 real,
dimension(SZDIB_(G),SZDJB_(G)), &
2173 intent(in) :: H_node
2175 real,
dimension(SZDIB_(G),SZDJB_(G)), &
2176 intent(in) :: ice_visc
2179 real,
dimension(SZDIB_(G),SZDJB_(G)), &
2180 intent(in) :: basal_trac
2182 real,
dimension(SZDI_(G),SZDJ_(G)), &
2185 real,
intent(in) :: dens_ratio
2187 real,
dimension(:,:,:,:,:,:),
intent(in) :: Phisub
2189 real,
dimension(SZDIB_(G),SZDJB_(G)), &
2190 intent(inout) :: u_diagonal
2192 real,
dimension(SZDIB_(G),SZDJB_(G)), &
2193 intent(inout) :: v_diagonal
2199 real :: ux, uy, vx, vy
2201 real,
dimension(8,4) :: Phi
2202 real,
dimension(2) :: xquad
2203 real,
dimension(2,2) :: Hcell, sub_ground
2204 integer :: i, j, is, js, cnt, isc, jsc, iec, jec, iphi, jphi, iq, jq, ilq, jlq, Itgt, Jtgt
2206 isc = g%isc ; jsc = g%jsc ; iec = g%iec ; jec = g%jec
2208 xquad(1) = .5 * (1-sqrt(1./3)) ; xquad(2) = .5 * (1+sqrt(1./3))
2210 do j=jsc-1,jec+1 ;
do i=isc-1,iec+1 ;
if (hmask(i,j) == 1)
then 2212 call bilinear_shape_fn_grid(g, i, j, phi)
2217 do iq=1,2 ;
do jq=1,2 ;
do iphi=1,2 ;
do jphi=1,2 ; itgt = i-2+iphi ; jtgt = j-2-jphi
2218 ilq = 1 ;
if (iq == iphi) ilq = 2
2219 jlq = 1 ;
if (jq == jphi) jlq = 2
2221 if (cs%umask(itgt,jtgt) == 1)
then 2223 ux = phi(2*(2*(jphi-1)+iphi)-1, 2*(jq-1)+iq)
2224 uy = phi(2*(2*(jphi-1)+iphi), 2*(jq-1)+iq)
2228 u_diagonal(itgt,jtgt) = u_diagonal(itgt,jtgt) + &
2229 0.25 * ice_visc(i,j) * ((4*ux+2*vy) * phi(2*(2*(jphi-1)+iphi)-1,2*(jq-1)+iq) + &
2230 (uy+vy) * phi(2*(2*(jphi-1)+iphi),2*(jq-1)+iq))
2232 if (float_cond(i,j) == 0)
then 2233 uq = xquad(ilq) * xquad(jlq)
2234 u_diagonal(itgt,jtgt) = u_diagonal(itgt,jtgt) + &
2235 0.25 * basal_trac(i,j) * uq * xquad(ilq) * xquad(jlq)
2239 if (cs%vmask(itgt,jtgt) == 1)
then 2241 vx = phi(2*(2*(jphi-1)+iphi)-1, 2*(jq-1)+iq)
2242 vy = phi(2*(2*(jphi-1)+iphi), 2*(jq-1)+iq)
2246 v_diagonal(itgt,jtgt) = v_diagonal(itgt,jtgt) + &
2247 0.25 * ice_visc(i,j) * ((uy+vx) * phi(2*(2*(jphi-1)+iphi)-1,2*(jq-1)+iq) + &
2248 (4*vy+2*ux) * phi(2*(2*(jphi-1)+iphi),2*(jq-1)+iq))
2250 if (float_cond(i,j) == 0)
then 2251 vq = xquad(ilq) * xquad(jlq)
2252 v_diagonal(itgt,jtgt) = v_diagonal(itgt,jtgt) + &
2253 0.25 * basal_trac(i,j) * vq * xquad(ilq) * xquad(jlq)
2256 enddo ;
enddo ;
enddo ;
enddo 2258 if (float_cond(i,j) == 1)
then 2259 hcell(:,:) = h_node(i-1:i,j-1:j)
2260 call cg_diagonal_subgrid_basal(phisub, hcell, g%bathyT(i,j), dens_ratio, sub_ground)
2261 do iphi=1,2 ;
do jphi=1,2 ; itgt = i-2+iphi ; jtgt = j-2-jphi
2262 if (cs%umask(itgt,jtgt) == 1)
then 2263 u_diagonal(itgt,jtgt) = u_diagonal(itgt,jtgt) + sub_ground(iphi,jphi) * basal_trac(i,j)
2264 v_diagonal(itgt,jtgt) = v_diagonal(itgt,jtgt) + sub_ground(iphi,jphi) * basal_trac(i,j)
2268 endif ;
enddo ;
enddo 2270 end subroutine matrix_diagonal
2272 subroutine cg_diagonal_subgrid_basal (Phisub, H_node, bathyT, dens_ratio, sub_grnd)
2273 real,
dimension(:,:,:,:,:,:), &
2274 intent(in) :: Phisub
2276 real,
dimension(2,2),
intent(in) :: H_node
2278 real,
intent(in) :: bathyT
2279 real,
intent(in) :: dens_ratio
2281 real,
dimension(2,2),
intent(out) :: sub_grnd
2288 integer :: nsub, i, j, k, l, qx, qy, m, n
2290 nsub =
size(phisub,1)
2291 subarea = 1.0 / (nsub**2)
2294 do m=1,2 ;
do n=1,2 ;
do j=1,nsub ;
do i=1,nsub ;
do qx=1,2 ;
do qy = 1,2
2296 hloc = (phisub(i,j,1,1,qx,qy)*h_node(1,1) + phisub(i,j,2,2,qx,qy)*h_node(2,2)) + &
2297 (phisub(i,j,1,2,qx,qy)*h_node(1,2) + phisub(i,j,2,1,qx,qy)*h_node(2,1))
2299 if (dens_ratio * hloc - bathyt > 0)
then 2300 sub_grnd(m,n) = sub_grnd(m,n) + subarea * 0.25 * phisub(i,j,m,n,qx,qy)**2
2303 enddo ;
enddo ;
enddo ;
enddo ;
enddo ;
enddo 2305 end subroutine cg_diagonal_subgrid_basal
2308 subroutine apply_boundary_values(CS, ISS, G, US, time, Phisub, H_node, ice_visc, basal_trac, float_cond, &
2309 dens_ratio, u_bdry_contr, v_bdry_contr)
2311 type(ice_shelf_dyn_CS),
intent(in) :: CS
2312 type(ice_shelf_state),
intent(in) :: ISS
2314 type(ocean_grid_type),
intent(in) :: G
2315 type(unit_scale_type),
intent(in) :: US
2316 type(time_type),
intent(in) :: Time
2317 real,
dimension(:,:,:,:,:,:), &
2318 intent(in) :: Phisub
2320 real,
dimension(SZDIB_(G),SZDJB_(G)), &
2321 intent(in) :: H_node
2323 real,
dimension(SZDIB_(G),SZDJB_(G)), &
2324 intent(in) :: ice_visc
2327 real,
dimension(SZDIB_(G),SZDJB_(G)), &
2328 intent(in) :: basal_trac
2330 real,
dimension(SZDI_(G),SZDJ_(G)), &
2331 intent(in) :: float_cond
2333 real,
intent(in) :: dens_ratio
2335 real,
dimension(SZDIB_(G),SZDJB_(G)), &
2336 intent(inout) :: u_bdry_contr
2338 real,
dimension(SZDIB_(G),SZDJB_(G)), &
2339 intent(inout) :: v_bdry_contr
2345 real,
dimension(8,4) :: Phi
2346 real,
dimension(2) :: xquad
2347 real :: ux, uy, vx, vy
2350 real,
dimension(2,2) :: Ucell,Vcell,Hcell,Usubcontr,Vsubcontr
2351 integer :: i, j, isc, jsc, iec, jec, iq, jq, iphi, jphi, ilq, jlq, Itgt, Jtgt
2353 isc = g%isc ; jsc = g%jsc ; iec = g%iec ; jec = g%jec
2355 xquad(1) = .5 * (1-sqrt(1./3)) ; xquad(2) = .5 * (1+sqrt(1./3))
2357 do j=jsc-1,jec+1 ;
do i=isc-1,iec+1 ;
if (iss%hmask(i,j) == 1)
then 2362 if ((cs%umask(i-1,j-1) == 3) .OR. (cs%umask(i,j-1) == 3) .OR. &
2363 (cs%umask(i-1,j) == 3) .OR. (cs%umask(i,j) == 3))
then 2365 call bilinear_shape_fn_grid(g, i, j, phi)
2370 do iq=1,2 ;
do jq=1,2
2372 uq = cs%u_bdry_val(i-1,j-1) * xquad(3-iq) * xquad(3-jq) + &
2373 cs%u_bdry_val(i,j-1) * xquad(iq) * xquad(3-jq) + &
2374 cs%u_bdry_val(i-1,j) * xquad(3-iq) * xquad(jq) + &
2375 cs%u_bdry_val(i,j) * xquad(iq) * xquad(jq)
2377 vq = cs%v_bdry_val(i-1,j-1) * xquad(3-iq) * xquad(3-jq) + &
2378 cs%v_bdry_val(i,j-1) * xquad(iq) * xquad(3-jq) + &
2379 cs%v_bdry_val(i-1,j) * xquad(3-iq) * xquad(jq) + &
2380 cs%v_bdry_val(i,j) * xquad(iq) * xquad(jq)
2382 ux = cs%u_bdry_val(i-1,j-1) * phi(1,2*(jq-1)+iq) + &
2383 cs%u_bdry_val(i,j-1) * phi(3,2*(jq-1)+iq) + &
2384 cs%u_bdry_val(i-1,j) * phi(5,2*(jq-1)+iq) + &
2385 cs%u_bdry_val(i,j) * phi(7,2*(jq-1)+iq)
2387 vx = cs%v_bdry_val(i-1,j-1) * phi(1,2*(jq-1)+iq) + &
2388 cs%v_bdry_val(i,j-1) * phi(3,2*(jq-1)+iq) + &
2389 cs%v_bdry_val(i-1,j) * phi(5,2*(jq-1)+iq) + &
2390 cs%v_bdry_val(i,j) * phi(7,2*(jq-1)+iq)
2392 uy = cs%u_bdry_val(i-1,j-1) * phi(2,2*(jq-1)+iq) + &
2393 cs%u_bdry_val(i,j-1) * phi(4,2*(jq-1)+iq) + &
2394 cs%u_bdry_val(i-1,j) * phi(6,2*(jq-1)+iq) + &
2395 cs%u_bdry_val(i,j) * phi(8,2*(jq-1)+iq)
2397 vy = cs%v_bdry_val(i-1,j-1) * phi(2,2*(jq-1)+iq) + &
2398 cs%v_bdry_val(i,j-1) * phi(4,2*(jq-1)+iq) + &
2399 cs%v_bdry_val(i-1,j) * phi(6,2*(jq-1)+iq) + &
2400 cs%v_bdry_val(i,j) * phi(8,2*(jq-1)+iq)
2402 do iphi=1,2 ;
do jphi=1,2 ; itgt = i-2+iphi ; jtgt = j-2-jphi
2403 ilq = 1 ;
if (iq == iphi) ilq = 2
2404 jlq = 1 ;
if (jq == jphi) jlq = 2
2406 if (cs%umask(itgt,jtgt) == 1)
then 2407 u_bdry_contr(itgt,jtgt) = u_bdry_contr(itgt,jtgt) + &
2408 0.25 * ice_visc(i,j) * ( (4*ux+2*vy) * phi(2*(2*(jphi-1)+iphi)-1,2*(jq-1)+iq) + &
2409 (uy+vx) * phi(2*(2*(jphi-1)+iphi),2*(jq-1)+iq) )
2411 if (float_cond(i,j) == 0)
then 2412 u_bdry_contr(itgt,jtgt) = u_bdry_contr(itgt,jtgt) + &
2413 0.25 * basal_trac(i,j) * uq * xquad(ilq) * xquad(jlq)
2417 if (cs%vmask(itgt,jtgt) == 1)
then 2418 v_bdry_contr(itgt,jtgt) = v_bdry_contr(itgt,jtgt) + &
2419 0.25 * ice_visc(i,j) * ( (uy+vx) * phi(2*(2*(jphi-1)+iphi)-1,2*(jq-1)+iq) + &
2420 (4*vy+2*ux) * phi(2*(2*(jphi-1)+iphi),2*(jq-1)+iq) )
2422 if (float_cond(i,j) == 0)
then 2423 v_bdry_contr(itgt,jtgt) = v_bdry_contr(itgt,jtgt) + &
2424 0.25 * basal_trac(i,j) * vq * xquad(ilq) * xquad(jlq)
2430 if (float_cond(i,j) == 1)
then 2431 ucell(:,:) = cs%u_bdry_val(i-1:i,j-1:j) ; vcell(:,:) = cs%v_bdry_val(i-1:i,j-1:j)
2432 hcell(:,:) = h_node(i-1:i,j-1:j)
2433 call cg_action_subgrid_basal(phisub, hcell, ucell, vcell, g%bathyT(i,j), &
2434 dens_ratio, usubcontr, vsubcontr)
2436 if (cs%umask(i-1,j-1)==1) u_bdry_contr(i-1,j-1) = u_bdry_contr(i-1,j-1) + usubcontr(1,1) * basal_trac(i,j)
2437 if (cs%umask(i-1,j) == 1) u_bdry_contr(i-1,j) = u_bdry_contr(i-1,j) + usubcontr(1,2) * basal_trac(i,j)
2438 if (cs%umask(i,j-1) == 1) u_bdry_contr(i,j-1) = u_bdry_contr(i,j-1) + usubcontr(2,1) * basal_trac(i,j)
2439 if (cs%umask(i,j) == 1) u_bdry_contr(i,j) = u_bdry_contr(i,j) + usubcontr(2,2) * basal_trac(i,j)
2441 if (cs%vmask(i-1,j-1)==1) v_bdry_contr(i-1,j-1) = v_bdry_contr(i-1,j-1) + vsubcontr(1,1) * basal_trac(i,j)
2442 if (cs%vmask(i-1,j) == 1) v_bdry_contr(i-1,j) = v_bdry_contr(i-1,j) + vsubcontr(1,2) * basal_trac(i,j)
2443 if (cs%vmask(i,j-1) == 1) v_bdry_contr(i,j-1) = v_bdry_contr(i,j-1) + vsubcontr(2,1) * basal_trac(i,j)
2444 if (cs%vmask(i,j) == 1) v_bdry_contr(i,j) = v_bdry_contr(i,j) + vsubcontr(2,2) * basal_trac(i,j)
2447 endif ;
enddo ;
enddo 2449 end subroutine apply_boundary_values
2453 subroutine calc_shelf_visc(CS, ISS, G, US, u_shlf, v_shlf)
2454 type(ice_shelf_dyn_CS),
intent(inout) :: CS
2455 type(ice_shelf_state),
intent(in) :: ISS
2457 type(ocean_grid_type),
intent(in) :: G
2458 type(unit_scale_type),
intent(in) :: US
2459 real,
dimension(G%IsdB:G%IedB,G%JsdB:G%JedB), &
2460 intent(inout) :: u_shlf
2461 real,
dimension(G%IsdB:G%IedB,G%JsdB:G%JedB), &
2462 intent(inout) :: v_shlf
2471 integer :: i, j, iscq, iecq, jscq, jecq, isd, jsd, ied, jed, iegq, jegq
2472 integer :: giec, gjec, gisc, gjsc, cnt, isc, jsc, iec, jec, is, js
2473 real :: Visc_coef, n_g
2474 real :: ux, uy, vx, vy, eps_min
2475 real :: umid, vmid, unorm
2477 isc = g%isc ; jsc = g%jsc ; iec = g%iec ; jec = g%jec
2478 iscq = g%iscB ; iecq = g%iecB ; jscq = g%jscB ; jecq = g%jecB
2479 isd = g%isd ; jsd = g%jsd ; ied = g%ied ; jed = g%jed
2480 iegq = g%iegB ; jegq = g%jegB
2481 gisc = g%domain%nihalo+1 ; gjsc = g%domain%njhalo+1
2482 giec = g%domain%niglobal+gisc ; gjec = g%domain%njglobal+gjsc
2483 is = iscq - 1; js = jscq - 1
2485 n_g = cs%n_glen; eps_min = cs%eps_glen_min
2487 visc_coef = us%kg_m2s_to_RZ_T*us%m_to_L*us%Z_to_L*(cs%A_glen_isothermal)**(1./cs%n_glen)
2492 if (iss%hmask(i,j) == 1)
then 2493 ux = ((u_shlf(i,j) + u_shlf(i,j-1)) - (u_shlf(i-1,j) + u_shlf(i-1,j-1))) / (2*g%dxT(i,j))
2494 vx = ((v_shlf(i,j) + v_shlf(i,j-1)) - (v_shlf(i-1,j) + v_shlf(i-1,j-1))) / (2*g%dxT(i,j))
2495 uy = ((u_shlf(i,j) + u_shlf(i-1,j)) - (u_shlf(i,j-1) + u_shlf(i-1,j-1))) / (2*g%dyT(i,j))
2496 vy = ((v_shlf(i,j) + v_shlf(i-1,j)) - (v_shlf(i,j-1) + v_shlf(i-1,j-1))) / (2*g%dyT(i,j))
2497 cs%ice_visc(i,j) = 0.5 * visc_coef * (g%areaT(i,j) * iss%h_shelf(i,j)) * &
2498 (us%s_to_T**2 * (ux**2 + vy**2 + ux*vy + 0.25*(uy+vx)**2 + eps_min**2))**((1.-n_g)/(2.*n_g))
2500 umid = ((u_shlf(i,j) + u_shlf(i-1,j-1)) + (u_shlf(i,j-1) + u_shlf(i-1,j))) * 0.25
2501 vmid = ((v_shlf(i,j) + v_shlf(i-1,j-1)) + (v_shlf(i,j-1) + v_shlf(i-1,j))) * 0.25
2502 unorm = sqrt(umid**2 + vmid**2 + eps_min**2*(g%dxT(i,j)**2 + g%dyT(i,j)**2))
2503 cs%basal_traction(i,j) = g%areaT(i,j) * cs%C_basal_friction * (us%L_T_to_m_s*unorm)**(cs%n_basal_fric-1)
2508 end subroutine calc_shelf_visc
2510 subroutine update_od_ffrac(CS, G, US, ocean_mass, find_avg)
2511 type(ice_shelf_dyn_CS),
intent(inout) :: CS
2512 type(ocean_grid_type),
intent(inout) :: G
2513 type(unit_scale_type),
intent(in) :: US
2514 real,
dimension(SZDI_(G),SZDJ_(G)), &
2515 intent(in) :: ocean_mass
2516 logical,
intent(in) :: find_avg
2519 integer :: isc, iec, jsc, jec, i, j
2523 i_rho_ocean = 1.0 / cs%density_ocean_avg
2525 isc = g%isc ; jsc = g%jsc ; iec = g%iec ; jec = g%jec
2527 do j=jsc,jec ;
do i=isc,iec
2528 cs%OD_rt(i,j) = cs%OD_rt(i,j) + ocean_mass(i,j)*i_rho_ocean
2529 if (ocean_mass(i,j)*i_rho_ocean > cs%thresh_float_col_depth)
then 2530 cs%ground_frac_rt(i,j) = cs%ground_frac_rt(i,j) + 1.0
2533 cs%OD_rt_counter = cs%OD_rt_counter + 1
2536 i_counter = 1.0 /
real(CS%OD_rt_counter)
2537 do j=jsc,jec ;
do i=isc,iec
2538 cs%ground_frac(i,j) = 1.0 - (cs%ground_frac_rt(i,j) * i_counter)
2539 cs%OD_av(i,j) = cs%OD_rt(i,j) * i_counter
2541 cs%OD_rt(i,j) = 0.0 ; cs%ground_frac_rt(i,j) = 0.0
2544 call pass_var(cs%ground_frac, g%domain)
2548 end subroutine update_od_ffrac
2550 subroutine update_od_ffrac_uncoupled(CS, G, h_shelf)
2551 type(ice_shelf_dyn_CS),
intent(inout) :: CS
2552 type(ocean_grid_type),
intent(in) :: G
2553 real,
dimension(SZDI_(G),SZDJ_(G)), &
2554 intent(in) :: h_shelf
2556 integer :: i, j, iters, isd, ied, jsd, jed
2557 real :: rhoi_rhow, OD
2559 rhoi_rhow = cs%density_ice / cs%density_ocean_avg
2560 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
2564 od = g%bathyT(i,j) - rhoi_rhow * h_shelf(i,j)
2568 cs%ground_frac(i,j) = 0.
2571 cs%ground_frac(i,j) = 1.
2576 end subroutine update_od_ffrac_uncoupled
2581 subroutine bilinear_shape_functions (X, Y, Phi, area)
2582 real,
dimension(4),
intent(in) :: X
2583 real,
dimension(4),
intent(in) :: Y
2584 real,
dimension(8,4),
intent(inout) :: Phi
2586 real,
intent(out) :: area
2605 real,
dimension(4) :: xquad, yquad
2608 integer :: node, qpoint, xnode, xq, ynode, yq
2610 xquad(1:3:2) = .5 * (1-sqrt(1./3)) ; yquad(1:2) = .5 * (1-sqrt(1./3))
2611 xquad(2:4:2) = .5 * (1+sqrt(1./3)) ; yquad(3:4) = .5 * (1+sqrt(1./3))
2615 a = -x(1)*(1-yquad(qpoint)) + x(2)*(1-yquad(qpoint)) - x(3)*yquad(qpoint) + x(4)*yquad(qpoint)
2616 b = -y(1)*(1-yquad(qpoint)) + y(2)*(1-yquad(qpoint)) - y(3)*yquad(qpoint) + y(4)*yquad(qpoint)
2617 c = -x(1)*(1-xquad(qpoint)) - x(2)*(xquad(qpoint)) + x(3)*(1-xquad(qpoint)) + x(4)*(xquad(qpoint))
2618 d = -y(1)*(1-xquad(qpoint)) - y(2)*(xquad(qpoint)) + y(3)*(1-xquad(qpoint)) + y(4)*(xquad(qpoint))
2622 xnode = 2-mod(node,2) ; ynode = ceiling(
REAL(node)/2)
2624 if (ynode == 1)
then 2625 yexp = 1-yquad(qpoint)
2627 yexp = yquad(qpoint)
2630 if (1 == xnode)
then 2631 xexp = 1-xquad(qpoint)
2633 xexp = xquad(qpoint)
2636 phi(2*node-1,qpoint) = ( d * (2 * xnode - 3) * yexp - b * (2 * ynode - 3) * xexp) / (a*d-b*c)
2637 phi(2*node,qpoint) = (-c * (2 * xnode - 3) * yexp + a * (2 * ynode - 3) * xexp) / (a*d-b*c)
2642 area = quad_area(x, y)
2644 end subroutine bilinear_shape_functions
2649 subroutine bilinear_shape_fn_grid(G, i, j, Phi)
2650 type(ocean_grid_type),
intent(in) :: G
2651 integer,
intent(in) :: i
2652 integer,
intent(in) :: j
2653 real,
dimension(8,4),
intent(inout) :: Phi
2667 real,
dimension(4) :: xquad, yquad
2670 integer :: node, qpoint, xnode, xq, ynode, yq
2672 xquad(1:3:2) = .5 * (1-sqrt(1./3)) ; yquad(1:2) = .5 * (1-sqrt(1./3))
2673 xquad(2:4:2) = .5 * (1+sqrt(1./3)) ; yquad(3:4) = .5 * (1+sqrt(1./3))
2676 a = g%dxCv(i,j-1) * (1-yquad(qpoint)) + g%dxCv(i,j) * yquad(qpoint)
2677 d = g%dyCu(i-1,j) * (1-xquad(qpoint)) + g%dyCu(i,j) * xquad(qpoint)
2680 xnode = 2-mod(node,2) ; ynode = ceiling(
REAL(node)/2)
2682 if (ynode == 1)
then 2683 yexp = 1-yquad(qpoint)
2685 yexp = yquad(qpoint)
2688 if (1 == xnode)
then 2689 xexp = 1-xquad(qpoint)
2691 xexp = xquad(qpoint)
2694 phi(2*node-1,qpoint) = ( d * (2 * xnode - 3) * yexp ) / (a*d)
2695 phi(2*node,qpoint) = ( a * (2 * ynode - 3) * xexp ) / (a*d)
2700 end subroutine bilinear_shape_fn_grid
2703 subroutine bilinear_shape_functions_subgrid(Phisub, nsub)
2704 real,
dimension(nsub,nsub,2,2,2,2), &
2705 intent(inout) :: Phisub
2707 integer,
intent(in) :: nsub
2732 integer :: i, j, k, l, qx, qy, indx, indy
2733 real,
dimension(2) :: xquad
2734 real :: x0, y0, x, y, val, fracx
2736 xquad(1) = .5 * (1-sqrt(1./3)) ; xquad(2) = .5 * (1+sqrt(1./3))
2737 fracx = 1.0/
real(nsub)
2739 do j=1,nsub ;
do i=1,nsub
2740 x0 = (i-1) * fracx ; y0 = (j-1) * fracx
2741 do qy=1,2 ;
do qx=1,2
2742 x = x0 + fracx*xquad(qx)
2743 y = y0 + fracx*xquad(qy)
2744 phisub(i,j,1,1,qx,qy) = (1.0-x) * (1.0-y)
2745 phisub(i,j,1,2,qx,qy) = (1.0-x) * y
2746 phisub(i,j,2,1,qx,qy) = x * (1.0-y)
2747 phisub(i,j,2,2,qx,qy) = x * y
2751 end subroutine bilinear_shape_functions_subgrid
2754 subroutine update_velocity_masks(CS, G, hmask, umask, vmask, u_face_mask, v_face_mask)
2755 type(ice_shelf_dyn_CS),
intent(in) :: CS
2756 type(ocean_grid_type),
intent(inout) :: G
2757 real,
dimension(SZDI_(G),SZDJ_(G)), &
2760 real,
dimension(SZDIB_(G),SZDJB_(G)), &
2761 intent(out) :: umask
2763 real,
dimension(SZDIB_(G),SZDJB_(G)), &
2764 intent(out) :: vmask
2766 real,
dimension(SZDIB_(G),SZDJ_(G)), &
2767 intent(out) :: u_face_mask
2768 real,
dimension(SZDI_(G),SZDJB_(G)), &
2769 intent(out) :: v_face_mask
2775 integer :: i, j, k, iscq, iecq, jscq, jecq, isd, jsd, is, js, iegq, jegq
2776 integer :: giec, gjec, gisc, gjsc, isc, jsc, iec, jec
2777 integer :: i_off, j_off
2779 isc = g%isc ; jsc = g%jsc ; iec = g%iec ; jec = g%jec
2780 iscq = g%iscB ; iecq = g%iecB ; jscq = g%jscB ; jecq = g%jecB
2781 i_off = g%idg_offset ; j_off = g%jdg_offset
2782 isd = g%isd ; jsd = g%jsd
2783 iegq = g%iegB ; jegq = g%jegB
2784 gisc = g%Domain%nihalo ; gjsc = g%Domain%njhalo
2785 giec = g%Domain%niglobal+gisc ; gjec = g%Domain%njglobal+gjsc
2787 umask(:,:) = 0 ; vmask(:,:) = 0
2788 u_face_mask(:,:) = 0 ; v_face_mask(:,:) = 0
2790 if (g%symmetric)
then 2793 is = isd+1 ; js = jsd+1
2799 if (hmask(i,j) == 1)
then 2801 umask(i-1:i,j-1:j) = 1.
2802 vmask(i-1:i,j-1:j) = 1.
2806 select case (int(cs%u_face_mask_bdry(i-1+k,j)))
2808 umask(i-1+k,j-1:j)=3.
2809 vmask(i-1+k,j-1:j)=0.
2810 u_face_mask(i-1+k,j)=3.
2812 u_face_mask(i-1+k,j)=2.
2814 umask(i-1+k,j-1:j)=0.
2815 vmask(i-1+k,j-1:j)=0.
2816 u_face_mask(i-1+k,j)=4.
2818 umask(i-1+k,j-1:j)=0.
2819 vmask(i-1+k,j-1:j)=0.
2820 u_face_mask(i-1+k,j)=0.
2822 umask(i-1+k,j-1:j)=0.
2829 select case (int(cs%v_face_mask_bdry(i,j-1+k)))
2831 vmask(i-1:i,j-1+k)=3.
2832 umask(i-1:i,j-1+k)=0.
2833 v_face_mask(i,j-1+k)=3.
2835 v_face_mask(i,j-1+k)=2.
2837 umask(i-1:i,j-1+k)=0.
2838 vmask(i-1:i,j-1+k)=0.
2839 v_face_mask(i,j-1+k)=4.
2841 umask(i-1:i,j-1+k)=0.
2842 vmask(i-1:i,j-1+k)=0.
2843 v_face_mask(i,j-1+k)=0.
2845 vmask(i-1:i,j-1+k)=0.
2867 if ((hmask(i+1,j) == 0) .OR. (hmask(i+1,j) == 2))
then 2869 u_face_mask(i,j) = 2.
2874 if ((hmask(i-1,j) == 0) .OR. (hmask(i-1,j) == 2))
then 2876 u_face_mask(i-1,j) = 2.
2881 if ((hmask(i,j-1) == 0) .OR. (hmask(i,j-1) == 2))
then 2883 v_face_mask(i,j-1) = 2.
2888 if ((hmask(i,j+1) == 0) .OR. (hmask(i,j+1) == 2))
then 2890 v_face_mask(i,j) = 2.
2903 call pass_vector(u_face_mask, v_face_mask, g%domain, to_all, cgrid_ne)
2904 call pass_vector(umask, vmask, g%domain, to_all, bgrid_ne)
2906 end subroutine update_velocity_masks
2910 subroutine interpolate_h_to_b(G, h_shelf, hmask, H_node)
2911 type(ocean_grid_type),
intent(inout) :: G
2912 real,
dimension(SZDI_(G),SZDJ_(G)), &
2913 intent(in) :: h_shelf
2914 real,
dimension(SZDI_(G),SZDJ_(G)), &
2917 real,
dimension(SZDIB_(G),SZDJB_(G)), &
2918 intent(inout) :: H_node
2921 integer :: i, j, isc, iec, jsc, jec, num_h, k, l
2924 isc = g%isc ; jsc = g%jsc ; iec = g%iec ; jec = g%jec
2937 if (hmask(i+k,j+l) == 1.0)
then 2938 summ = summ + h_shelf(i+k,j+l)
2944 h_node(i,j) = summ / num_h
2949 call pass_var(h_node, g%domain, position=corner)
2951 end subroutine interpolate_h_to_b
2954 subroutine ice_shelf_dyn_end(CS)
2957 if (.not.
associated(cs))
return 2959 deallocate(cs%u_shelf, cs%v_shelf)
2960 deallocate(cs%t_shelf, cs%tmask)
2961 deallocate(cs%u_bdry_val, cs%v_bdry_val, cs%t_bdry_val)
2962 deallocate(cs%u_face_mask, cs%v_face_mask)
2963 deallocate(cs%umask, cs%vmask)
2965 deallocate(cs%ice_visc, cs%basal_traction)
2966 deallocate(cs%OD_rt, cs%OD_av)
2967 deallocate(cs%ground_frac, cs%ground_frac_rt)
2971 end subroutine ice_shelf_dyn_end
2975 subroutine ice_shelf_temp(CS, ISS, G, US, time_step, melt_rate, Time)
2976 type(ice_shelf_dyn_CS),
intent(inout) :: CS
2977 type(ice_shelf_state),
intent(in) :: ISS
2979 type(ocean_grid_type),
intent(inout) :: G
2980 type(unit_scale_type),
intent(in) :: US
2981 real,
intent(in) :: time_step
2982 real,
dimension(SZDI_(G),SZDJ_(G)), &
2983 intent(in) :: melt_rate
2984 type(time_type),
intent(in) :: Time
2993 real,
dimension(SZDI_(G),SZDJ_(G)) :: th_after_uflux, th_after_vflux, TH
2994 integer :: isd, ied, jsd, jed, i, j, isc, iec, jsc, jec
3001 adot = (0.1/(365.0*86400.0))*us%m_to_Z*us%T_to_s * cs%density_ice
3004 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
3005 isc = g%isc ; iec = g%iec ; jsc = g%jsc ; jec = g%jec
3007 th_after_uflux(:,:) = 0.0
3008 th_after_vflux(:,:) = 0.0
3010 do j=jsd,jed ;
do i=isd,ied
3012 if ((iss%hmask(i,j) == 3) .or. (iss%hmask(i,j) == -2))
then 3013 cs%t_shelf(i,j) = cs%t_bdry_val(i,j)
3017 do j=jsd,jed ;
do i=isd,ied
3019 th(i,j) = cs%t_shelf(i,j)*iss%h_shelf(i,j)
3029 call ice_shelf_advect_temp_x(cs, g, time_step, iss%hmask, th, th_after_uflux)
3030 call ice_shelf_advect_temp_y(cs, g, time_step, iss%hmask, th_after_uflux, th_after_vflux)
3032 do j=jsc,jec ;
do i=isc,iec
3035 if (iss%h_shelf(i,j) > 0.0)
then 3036 cs%t_shelf(i,j) = th_after_vflux(i,j) / iss%h_shelf(i,j)
3038 cs%t_shelf(i,j) = -10.0
3042 if ((iss%hmask(i,j) == 1) .or. (iss%hmask(i,j) == 2))
then 3043 if (iss%h_shelf(i,j) > 0.0)
then 3044 cs%t_shelf(i,j) = cs%t_shelf(i,j) + &
3045 time_step*(adot*tsurf - melt_rate(i,j)*iss%tfreeze(i,j))/(cs%density_ice*iss%h_shelf(i,j))
3049 cs%t_shelf(i,j) = -10.0
3052 elseif (iss%hmask(i,j) == 0)
then 3053 cs%t_shelf(i,j) = -10.0
3054 elseif ((iss%hmask(i,j) == 3) .or. (iss%hmask(i,j) == -2))
then 3055 cs%t_shelf(i,j) = cs%t_bdry_val(i,j)
3059 call pass_var(cs%t_shelf, g%domain)
3063 call hchksum(cs%t_shelf,
"temp after front", g%HI, haloshift=3)
3066 end subroutine ice_shelf_temp
3069 subroutine ice_shelf_advect_temp_x(CS, G, time_step, hmask, h0, h_after_uflux)
3070 type(ice_shelf_dyn_CS),
intent(in) :: CS
3071 type(ocean_grid_type),
intent(inout) :: G
3072 real,
intent(in) :: time_step
3073 real,
dimension(SZDI_(G),SZDJ_(G)), &
3076 real,
dimension(SZDI_(G),SZDJ_(G)), &
3078 real,
dimension(SZDI_(G),SZDJ_(G)), &
3079 intent(inout) :: h_after_uflux
3085 integer :: i, j, is, ie, js, je, isd, ied, jsd, jed, gjed, gied
3086 integer :: i_off, j_off
3087 logical :: at_east_bdry, at_west_bdry, one_off_west_bdry, one_off_east_bdry
3088 real,
dimension(-2:2) :: stencil
3090 real :: flux_diff, phi
3092 character (len=1) :: debug_str
3095 is = g%isc-2 ; ie = g%iec+2 ; js = g%jsc ; je = g%jec ; isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
3096 i_off = g%idg_offset ; j_off = g%jdg_offset
3099 if (((j+j_off) <= g%domain%njglobal+g%domain%njhalo) .AND. &
3100 ((j+j_off) >= g%domain%njhalo+1))
then 3106 if (((i+i_off) <= g%domain%niglobal+g%domain%nihalo) .AND. &
3107 ((i+i_off) >= g%domain%nihalo+1))
then 3109 if (i+i_off == g%domain%nihalo+1)
then 3112 at_west_bdry=.false.
3115 if (i+i_off == g%domain%niglobal+g%domain%nihalo)
then 3118 at_east_bdry=.false.
3121 if (hmask(i,j) == 1)
then 3123 h_after_uflux(i,j) = h0(i,j)
3125 stencil(:) = h0(i-2:i+2,j)
3131 if (cs%u_face_mask(i-1,j) == 4.)
then 3133 flux_diff = flux_diff + g%dyCu(i-1,j) * time_step * cs%u_flux_bdry_val(i-1,j) * &
3134 cs%t_bdry_val(i-1,j) / g%areaT(i,j)
3138 u_face = 0.5 * (cs%u_shelf(i-1,j-1) + cs%u_shelf(i-1,j))
3140 if (u_face > 0)
then 3144 if (at_west_bdry .AND. (hmask(i-1,j) == 3))
then 3146 flux_diff = flux_diff + abs(u_face) * g%dyCu(i-1,j) * time_step * stencil(-1) / g%areaT(i,j)
3148 elseif (hmask(i-1,j) * hmask(i-2,j) == 1)
then 3149 phi = slope_limiter(stencil(-1)-stencil(-2), stencil(0)-stencil(-1))
3150 flux_diff = flux_diff + abs(u_face) * g%dyCu(i-1,j)* time_step / g%areaT(i,j) * &
3151 (stencil(-1) - phi * (stencil(-1)-stencil(0))/2)
3157 flux_diff = flux_diff + abs(u_face) * g%dyCu(i-1,j) * time_step / g%areaT(i,j) * stencil(-1)
3161 elseif (u_face < 0)
then 3162 if (hmask(i-1,j) * hmask(i+1,j) == 1)
then 3163 phi = slope_limiter(stencil(0)-stencil(1), stencil(-1)-stencil(0))
3164 flux_diff = flux_diff - abs(u_face) * g%dyCu(i-1,j) * time_step / g%areaT(i,j) * &
3165 (stencil(0) - phi * (stencil(0)-stencil(-1))/2)
3168 flux_diff = flux_diff - abs(u_face) * g%dyCu(i-1,j) * time_step / g%areaT(i,j) * stencil(0)
3177 if (cs%u_face_mask(i,j) == 4.)
then 3179 flux_diff = flux_diff + g%dyCu(i,j) * time_step * cs%u_flux_bdry_val(i,j) *&
3180 cs%t_bdry_val(i+1,j) / g%areaT(i,j)
3183 u_face = 0.5 * (cs%u_shelf(i,j-1) + cs%u_shelf(i,j))
3185 if (u_face < 0)
then 3187 if (at_east_bdry .AND. (hmask(i+1,j) == 3))
then 3190 flux_diff = flux_diff + abs(u_face) * g%dyCu(i,j) * time_step * stencil(1) / g%areaT(i,j)
3192 elseif (hmask(i+1,j) * hmask(i+2,j) == 1)
then 3194 phi = slope_limiter(stencil(1)-stencil(2), stencil(0)-stencil(1))
3195 flux_diff = flux_diff + abs(u_face) * g%dyCu(i,j) * time_step / g%areaT(i,j) * &
3196 (stencil(1) - phi * (stencil(1)-stencil(0))/2)
3202 flux_diff = flux_diff + abs(u_face) * g%dyCu(i,j) * time_step / g%areaT(i,j) * stencil(1)
3206 elseif (u_face > 0)
then 3208 if (hmask(i-1,j) * hmask(i+1,j) == 1)
then 3210 phi = slope_limiter(stencil(0)-stencil(-1), stencil(1)-stencil(0))
3211 flux_diff = flux_diff - abs(u_face) * g%dyCu(i,j) * time_step / g%areaT(i,j) * &
3212 (stencil(0) - phi * (stencil(0)-stencil(1))/2)
3216 flux_diff = flux_diff - abs(u_face) * g%dyCu(i,j) * time_step / g%areaT(i,j) * stencil(0)
3222 h_after_uflux(i,j) = h_after_uflux(i,j) + flux_diff
3236 end subroutine ice_shelf_advect_temp_x
3238 subroutine ice_shelf_advect_temp_y(CS, G, time_step, hmask, h_after_uflux, h_after_vflux)
3239 type(ice_shelf_dyn_CS),
intent(in) :: CS
3240 type(ocean_grid_type),
intent(in) :: G
3241 real,
intent(in) :: time_step
3242 real,
dimension(SZDI_(G),SZDJ_(G)), &
3245 real,
dimension(SZDI_(G),SZDJ_(G)), &
3246 intent(in) :: h_after_uflux
3248 real,
dimension(SZDI_(G),SZDJ_(G)), &
3249 intent(inout) :: h_after_vflux
3255 integer :: i, j, is, ie, js, je, isd, ied, jsd, jed, gjed, gied
3256 integer :: i_off, j_off
3257 logical :: at_north_bdry, at_south_bdry, one_off_west_bdry, one_off_east_bdry
3258 real,
dimension(-2:2) :: stencil
3260 real :: flux_diff, phi
3261 character(len=1) :: debug_str
3263 is = g%isc ; ie = g%iec ; js = g%jsc-1 ; je = g%jec+1 ; isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
3264 i_off = g%idg_offset ; j_off = g%jdg_offset
3267 if (((i+i_off) <= g%domain%niglobal+g%domain%nihalo) .AND. &
3268 ((i+i_off) >= g%domain%nihalo+1))
then 3274 if (((j+j_off) <= g%domain%njglobal+g%domain%njhalo) .AND. &
3275 ((j+j_off) >= g%domain%njhalo+1))
then 3277 if (j+j_off == g%domain%njhalo+1)
then 3278 at_south_bdry=.true.
3280 at_south_bdry=.false.
3282 if (j+j_off == g%domain%njglobal+g%domain%njhalo)
then 3283 at_north_bdry=.true.
3285 at_north_bdry=.false.
3288 if (hmask(i,j) == 1)
then 3289 h_after_vflux(i,j) = h_after_uflux(i,j)
3291 stencil(:) = h_after_uflux(i,j-2:j+2)
3296 if (cs%v_face_mask(i,j-1) == 4.)
then 3298 flux_diff = flux_diff + g%dxCv(i,j-1) * time_step * cs%v_flux_bdry_val(i,j-1) * &
3299 cs%t_bdry_val(i,j-1)/ g%areaT(i,j)
3303 v_face = 0.5 * (cs%v_shelf(i-1,j-1) + cs%v_shelf(i,j-1))
3305 if (v_face > 0)
then 3309 if (at_south_bdry .AND. (hmask(i,j-1) == 3))
then 3311 flux_diff = flux_diff + abs(v_face) * g%dxCv(i,j-1) * time_step * stencil(-1) / g%areaT(i,j)
3313 elseif (hmask(i,j-1) * hmask(i,j-2) == 1)
then 3315 phi = slope_limiter(stencil(-1)-stencil(-2), stencil(0)-stencil(-1))
3316 flux_diff = flux_diff + abs(v_face) * g%dxCv(i,j-1) * time_step / g%areaT(i,j) * &
3317 (stencil(-1) - phi * (stencil(-1)-stencil(0))/2)
3322 flux_diff = flux_diff + abs(v_face) * g%dxCv(i,j-1) * time_step / g%areaT(i,j) * stencil(-1)
3325 elseif (v_face < 0)
then 3327 if (hmask(i,j-1) * hmask(i,j+1) == 1)
then 3328 phi = slope_limiter(stencil(0)-stencil(1), stencil(-1)-stencil(0))
3329 flux_diff = flux_diff - abs(v_face) * g%dxCv(i,j-1) * time_step / g%areaT(i,j) * &
3330 (stencil(0) - phi * (stencil(0)-stencil(-1))/2)
3332 flux_diff = flux_diff - abs(v_face) * g%dxCv(i,j-1) * time_step / g%areaT(i,j) * stencil(0)
3341 if (cs%v_face_mask(i,j) == 4.)
then 3342 flux_diff = flux_diff + g%dxCv(i,j) * time_step * cs%v_flux_bdry_val(i,j) *&
3343 cs%t_bdry_val(i,j+1)/ g%areaT(i,j)
3347 v_face = 0.5 * (cs%v_shelf(i-1,j) + cs%v_shelf(i,j))
3349 if (v_face < 0)
then 3351 if (at_north_bdry .AND. (hmask(i,j+1) == 3))
then 3353 flux_diff = flux_diff + abs(v_face) * g%dxCv(i,j) * time_step * stencil(1) / g%areaT(i,j)
3354 elseif (hmask(i,j+1) * hmask(i,j+2) == 1)
then 3355 phi = slope_limiter(stencil(1)-stencil(2), stencil(0)-stencil(1))
3356 flux_diff = flux_diff + abs(v_face) * g%dxCv(i,j) * time_step / g%areaT(i,j) * &
3357 (stencil(1) - phi * (stencil(1)-stencil(0))/2)
3361 flux_diff = flux_diff + abs(v_face) * g%dxCv(i,j) * time_step / g%areaT(i,j) * stencil(1)
3364 elseif (v_face > 0)
then 3366 if (hmask(i,j-1) * hmask(i,j+1) == 1)
then 3367 phi = slope_limiter(stencil(0)-stencil(-1), stencil(1)-stencil(0))
3368 flux_diff = flux_diff - abs(v_face) * g%dxCv(i,j) * time_step / g%areaT(i,j) * &
3369 (stencil(0) - phi * (stencil(0)-stencil(1))/2)
3373 flux_diff = flux_diff - abs(v_face) * g%dxCv(i,j) * time_step / g%areaT(i,j) * stencil(0)
3380 h_after_vflux(i,j) = h_after_vflux(i,j) + flux_diff
3387 end subroutine ice_shelf_advect_temp_y
The control structure for the ice shelf dynamics.
Structure that describes the ice shelf state.
Wraps the FMS time manager functions.
Ocean grid type. See mom_grid for details.
A structure that can be parsed to read and document run-time parameters.
Provides the ocean grid type.
Wraps the MPP cpu clock functions.
Register fields for restarts.
This module contains I/O framework code.
The MOM6 facility to parse input files for runtime parameters.
An overloaded interface to log the values of various types of parameters.
Do a halo update on a pair of arrays representing the two components of a vector. ...
Routines to calculate checksums of various array and vector types.
Interfaces to non-domain-oriented communication subroutines, including the MOM6 reproducing sums faci...
This is an older interface that has been renamed Bchksum.
Make a diagnostic available for averaging or output.
A restart registry and the control structure for restarts.
Describes various unit conversion factors.
Copy one MOM_domain_type into another.
Checksums an array (2d or 3d) staggered at tracer points.
A container for loop bounds.
Provides a transparent unit rescaling type to facilitate dimensional consistency testing.
Describes the decomposed MOM domain and has routines for communications across PEs.
Routines for error handling and I/O management.
The MOM6 facility for reading and writing restart files, and querying what has been read...
Implements the thermodynamic aspects of ocean / ice-shelf interactions, along with a crude placeholde...
Implements a crude placeholder for a later implementation of full ice shelf dynamics.
An overloaded interface to log version information about modules.
Indicate whether a file exists, perhaps with domain decomposition.
An overloaded interface to read various types of parameters.
Indicate whether a field has been read from a restart file.
Find an accurate and order-invariant sum of a distributed 2d or 3d field.
Do a halo update on an array.
Read a data field from a file.
An overloaded interface to read and log the values of various types of parameters.