Skip to content

Commit 3a9caf7

Browse files
authored
Merge pull request #105 from dngoldberg/cornford_sliding_law
Cornford sliding law
2 parents 38a72f8 + 3ae590a commit 3a9caf7

File tree

3 files changed

+49
-14
lines changed

3 files changed

+49
-14
lines changed

fenics_ice/config.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ class IceDynamicsCfg(ConfigPrinter):
389389

390390
def __post_init__(self):
391391
"""Check options valid"""
392-
assert self.sliding_law in ['linear', 'budd']
392+
assert self.sliding_law in ['linear', 'budd', 'corn']
393393
if self.min_thickness is not None:
394394
assert self.min_thickness >= 0.0
395395

@@ -400,6 +400,7 @@ class MomsolveCfg(ConfigPrinter):
400400
Configuration of MomentumSolver with sensible defaults for picard & newton params
401401
"""
402402

403+
quadrature_degree: int = -1
403404
picard_params: dict = field(default_factory=lambda: {
404405
'nonlinear_solver': 'newton',
405406
'newton_solver': {'linear_solver': 'cg',

fenics_ice/model.py

+20-5
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ def __init__(self, mesh_in, input_data, param_in, init_fields=True,
9292
self.H_DG = None
9393
self.H_np = None
9494
self.surf = None
95+
self.Umag_DG = None
9596

9697
if init_vel_obs:
9798
# Load the velocity observations
@@ -145,7 +146,7 @@ def init_fields_from_data(self):
145146
self.H_DG = Function(self.M2, name="H_DG")
146147
self.bed_DG = Function(self.M2, name="bed_DG")
147148
self.H_DG.assign(project(self.H,self.M2))
148-
self.bed_DG.assign(project(self.bed,self.M2))
149+
self.bed_DG.assign(project(self.bed,self.M2))
149150

150151
self.gen_surf() # surf = bed + thick
151152

@@ -455,26 +456,40 @@ def gen_surf(self):
455456
def bdrag_to_alpha(self, B2):
456457
"""Convert basal drag to alpha"""
457458
sl = self.params.ice_dynamics.sliding_law
459+
460+
458461
if sl == 'linear':
459462
alpha = sqrt(B2)
460463

461-
elif sl == 'budd':
464+
elif sl in ['budd','corn']:
462465
bed = self.bed
463466
H = self.H
464467
g = self.params.constants.g
465468
rhoi = self.params.constants.rhoi
466469
rhow = self.params.constants.rhow
470+
H_flt = -rhow/rhoi * bed
467471
u_obs = self.u_obs_M
468472
v_obs = self.v_obs_M
469473
vel_rp = self.params.constants.vel_rp
470474

471475
# Flotation Criterion
472-
H_flt = -rhow/rhoi * bed
473476
fl_ex = conditional(H <= H_flt, 1.0, 0.0)
474-
475477
N = (1-fl_ex)*(H*rhoi*g + ufl.Min(bed, 0.0)*rhow*g)
476478
U_mag = sqrt(u_obs**2 + v_obs**2 + vel_rp**2)
477-
alpha = (1-fl_ex)*sqrt(B2 * ufl.Max(N, 0.01)**(-1.0/3.0) * U_mag**(2.0/3.0))
479+
480+
if sl == 'budd':
481+
alpha = (1-fl_ex)*sqrt(B2 * ufl.Max(N, 0.01)**(-1.0/3.0) * U_mag**(2.0/3.0))
482+
483+
elif sl == 'corn':
484+
485+
# the relationship between alpha and B2 is too nontrivial to "invert", and an exact
486+
# solution is not sought. Rather, since the sliding law is expected to deviate from
487+
# the weertman law (B2 = alpha^2 U^(-2/3)) only within a few km of the grounding line,
488+
# we initialise based on the weertman sliding law
489+
alpha = (1-fl_ex)*sqrt(B2 * U_mag**(2.0/3.0))
490+
491+
else:
492+
raise RuntimeError(f"Invalid sliding law: '{sl:s}'")
478493

479494
return alpha
480495

fenics_ice/solver.py

+27-8
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import time
3030
import ufl
3131
import weakref
32+
from IPython import embed
3233

3334
log = logging.getLogger("fenics_ice")
3435

@@ -492,15 +493,31 @@ def sliding_law(self, alpha, U):
492493
if sl == 'linear':
493494
B2 = C
494495

495-
elif sl == 'budd':
496-
N = (1-fl_ex)*(H*rhoi*g + ufl.Min(bed, 0.0)*rhow*g)
496+
elif sl in ['budd','corn']:
497497
U_mag = sqrt(U[0]**2 + U[1]**2 + vel_rp**2)
498-
# Need to catch N <= 0.0 here, as it's raised to
499-
# 1/3 (forward) and -2/3 (adjoint)
500-
N_term = ufl.conditional(N > 0.0, N ** (1.0/3.0), 0)
501-
B2 = (1-fl_ex)*(C * N_term * U_mag**(-2.0/3.0))
498+
N = (1-fl_ex)*(H*rhoi*g + ufl.Min(bed, 0.0)*rhow*g)
499+
500+
if sl == 'budd':
501+
# Need to catch N <= 0.0 here, as it's raised to
502+
# 1/3 (forward) and -2/3 (adjoint)
503+
N_term = ufl.conditional(N > 0.0, N ** (1.0/3.0), 0)
504+
B2 = (1-fl_ex)*(C * N_term * U_mag**(-2.0/3.0))
505+
506+
elif sl == 'corn':
507+
# see eq 11 of Asay-Davis et al, Experimental design for
508+
# three interrelated marine ice sheet and ocean model intercomparison projects ...
509+
# Geosci. Model Dev., 9, 2471–2497
510+
511+
# Need to catch N <= 0.0 here, as it's raised to
512+
# 1/3 (forward) and -2/3 (adjoint)
513+
N_term = ufl.conditional(N > 0.0, N, 0)
514+
denom_term = (C**3 * U_mag + (0.5 * N_term)**3)**(1.0/3.0)
515+
B2 = (1-fl_ex)*(C * 0.5 * N_term * U_mag**(-2.0/3.0) / denom_term)
516+
517+
else:
518+
raise RuntimeError(f"Invalid sliding law: '{sl:s}'")
502519

503-
return B2
520+
return B2
504521

505522
def solve_mom_eq(self, annotate_flag=None):
506523
"""Solve the momentum equation defined in def_mom_eq"""
@@ -509,14 +526,16 @@ def solve_mom_eq(self, annotate_flag=None):
509526

510527
newton_params = self.params.momsolve.newton_params
511528
picard_params = self.params.momsolve.picard_params
529+
quad_degree = self.params.momsolve.quadrature_degree
512530
J_p = self.mom_Jac_p
513531

514532
momsolver = MomentumSolver(self.mom_F == 0,
515533
self.U,
516534
bcs=self.flow_bcs,
517535
J_p=J_p,
518536
picard_params=picard_params,
519-
solver_parameters=newton_params)
537+
solver_parameters=newton_params,
538+
form_compiler_parameters=None if quad_degree == -1 else {"quadrature_degree": quad_degree})
520539

521540
momsolver.solve(annotate=annotate_flag)
522541

0 commit comments

Comments
 (0)