Skip to content

Commit 3069a68

Browse files
committed
Test composite rheology
1 parent 6214ef3 commit 3069a68

File tree

1 file changed

+51
-6
lines changed

1 file changed

+51
-6
lines changed

test/composite_rheology_test.py

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,19 @@
1616
glen_flow_law,
1717
weertman_sliding_law,
1818
)
19-
from icepack2 import model
19+
from icepack2.model.minimization import viscous_power, ice_shelf_momentum_balance
20+
21+
22+
sparams = {
23+
"solver_parameters": {
24+
"snes_type": "newtonls",
25+
"snes_max_it": 200,
26+
"snes_linesearch_type": "nleqerr",
27+
"ksp_type": "gmres",
28+
"pc_type": "lu",
29+
"pc_factor_mat_solver_type": "mumps",
30+
},
31+
}
2032

2133

2234
def test_composite_rheology_floating():
@@ -29,13 +41,13 @@ def test_composite_rheology_floating():
2941

3042
τ_c = Constant(0.1)
3143
ε_c = Constant(0.01)
32-
A1 = ε_c / τ_c
33-
A3 = ε_c / τ_c**n
44+
A1 = ε_c / τ_c ** n1
45+
A3 = ε_c / τ_c ** n3
3446

3547
# This is an exact solution for the velocity of a floating ice shelf with
3648
# constant temperature and linearly decreasing thickness. See Greve and
3749
# Blatter for the derivation.
38-
def exact_u(x, n, A):
50+
def exact_δu(x, n, A):
3951
ρ = ρ_I * (1 - ρ_I / ρ_W)
4052
h = h0 - dh * x / Lx
4153
P = ρ * g * h / 4
@@ -49,6 +61,7 @@ def perturb_u(x, y):
4961
q = 16 * px * (1 - px) * py * (1 - py)
5062
return 60 * q * (px - 0.5)
5163

64+
degree = 1
5265
errors, mesh_sizes = [], []
5366
k_min, k_max, num_steps = 5 - degree, 8 - degree, 9
5467
for nx in np.logspace(k_min, k_max, num_steps, base=2, dtype=int):
@@ -65,7 +78,7 @@ def perturb_u(x, y):
6578
z.sub(0).assign(Constant(u_inflow, 0))
6679

6780
expr = u_inflow + exact_δu(x, n1, A1) + exact_δu(x, n3, A3)
68-
u_exact = Function(V).interpolate(as_vector((exact_u(x), 0)))
81+
u_exact = Function(V).interpolate(as_vector((expr, 0)))
6982

7083
h = Function(Q).interpolate(h0 - dh * x / Lx)
7184
inflow_ids = (1,)
@@ -76,4 +89,36 @@ def perturb_u(x, y):
7689
side_wall_bc = firedrake.DirichletBC(Z.sub(0).sub(1), 0, side_wall_ids)
7790
bcs = [inflow_bc, side_wall_bc]
7891

79-
# Miracle occurs...
92+
u, M = firedrake.split(z)
93+
fields = {"velocity": u, "membrane_stress": M, "thickness": h}
94+
boundary_ids = {"outflow_ids": outflow_ids}
95+
96+
L = (
97+
viscous_power(**fields, flow_law_exponent=n1, flow_law_coefficient=A1) +
98+
viscous_power(**fields, flow_law_exponent=n3, flow_law_coefficient=A3) +
99+
ice_shelf_momentum_balance(**fields, **boundary_ids)
100+
)
101+
102+
F = derivative(L, z)
103+
qdegree = max(8, degree ** glen_flow_law)
104+
pparams = {"form_compiler_parameters": {"quadrature_degree": qdegree}}
105+
problem = NonlinearVariationalProblem(F, z, bcs, **pparams)
106+
solver = NonlinearVariationalSolver(problem, **sparams)
107+
108+
num_continuation_steps = 5
109+
for exponent in np.linspace(1.0, glen_flow_law, num_continuation_steps):
110+
n3.assign(exponent)
111+
solver.solve()
112+
113+
u, M = z.subfunctions
114+
error = firedrake.norm(u - u_exact) / firedrake.norm(u_exact)
115+
δx = mesh.cell_sizes.dat.data_ro.min()
116+
mesh_sizes.append(δx)
117+
errors.append(error)
118+
print(".", end="", flush=True)
119+
120+
log_mesh_sizes = np.log2(np.array(mesh_sizes))
121+
log_errors = np.log2(np.array(errors))
122+
slope, intercept = np.polyfit(log_mesh_sizes, log_errors, 1)
123+
print(f"degree {degree}: log(error) ~= {slope:g} * log(dx) {intercept:+g}")
124+
assert slope > degree + 0.9

0 commit comments

Comments
 (0)