Skip to content

Commit b77345e

Browse files
committed
Make it work with a continuation method
1 parent 57eecda commit b77345e

File tree

1 file changed

+48
-38
lines changed

1 file changed

+48
-38
lines changed

test/momentum_balance_test.py

Lines changed: 48 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
import pytest
22
import numpy as np
33
import firedrake
4-
from firedrake import as_vector, max_value, Constant, Function, derivative
4+
from firedrake import (
5+
as_vector,
6+
max_value,
7+
Constant,
8+
Function,
9+
derivative,
10+
NonlinearVariationalProblem,
11+
NonlinearVariationalSolver,
12+
)
513
from icepack2.constants import (
614
ice_density as ρ_I,
715
water_density as ρ_W,
816
gravity as g,
9-
glen_flow_law as n,
10-
weertman_sliding_law as m,
17+
glen_flow_law,
18+
weertman_sliding_law,
1119
)
1220
from icepack2.model import VariationalForm, MinimizationForm
1321

@@ -19,6 +27,9 @@ def test_convergence_rate_grounded(degree, form):
1927
h0, dh = Constant(500.0), Constant(100.0)
2028
u_inflow = Constant(100.0)
2129

30+
n = firedrake.Constant(glen_flow_law)
31+
m = firedrake.Constant(glen_flow_law)
32+
2233
τ_c = Constant(0.1)
2334
ε_c = Constant(0.01)
2435
A = ε_c / τ_c**n
@@ -81,6 +92,9 @@ def friction(x):
8192
side_wall_bc = firedrake.DirichletBC(Z.sub(0).sub(1), 0, side_wall_ids)
8293
bcs = [inflow_bc, side_wall_bc]
8394

95+
n = firedrake.Constant(1.0)
96+
m = firedrake.Constant(1.0)
97+
8498
# Make the material parameters and input fields
8599
rheology = {
86100
"flow_law_exponent": n,
@@ -89,14 +103,6 @@ def friction(x):
89103
"sliding_coefficient": u_c / τ_c ** m,
90104
}
91105

92-
λ = firedrake.Constant(1e-3)
93-
regularized_rheology = {
94-
"flow_law_exponent": 1,
95-
"flow_law_coefficient": λ * ε_c / τ_c,
96-
"sliding_exponent": 1,
97-
"sliding_coefficient": λ * u_c / τ_c,
98-
}
99-
100106
u, M, τ = firedrake.split(z)
101107
fields = {
102108
"velocity": u,
@@ -108,6 +114,8 @@ def friction(x):
108114

109115
boundary_ids = {"outflow_ids": outflow_ids}
110116

117+
qdegree = max(8, degree ** glen_flow_law)
118+
pparams = {"form_compiler_parameters": {"quadrature_degree": qdegree}}
111119
if form == "minimization":
112120
fns = [
113121
MinimizationForm.viscous_power,
@@ -116,49 +124,49 @@ def friction(x):
116124
MinimizationForm.momentum_balance,
117125
]
118126

119-
L = sum(fn(**fields, **rheology, **boundary_ids) for fn in fns)
120-
F = derivative(L, z)
121-
122-
K = sum(
123-
fn(**fields, **regularized_rheology)
124-
for fn in [
125-
MinimizationForm.viscous_power, MinimizationForm.friction_power
126-
]
127-
)
128-
J = derivative(derivative(L + K, z), z)
127+
def form_problem(rheology):
128+
L = sum(fn(**fields, **rheology, **boundary_ids) for fn in fns)
129+
F = derivative(L, z)
130+
J = derivative(F, z)
131+
problem = NonlinearVariationalProblem(F, z, bcs, J=J, **pparams)
132+
return problem
129133
elif form == "variational":
130134
v, N, σ = firedrake.TestFunctions(Z)
131-
kfns = [
135+
fns = [
132136
(VariationalForm.flow_law, N),
133137
(VariationalForm.friction_law, σ),
134-
]
135-
fns = kfns + [
136138
(VariationalForm.calving_terminus, v),
137139
(VariationalForm.momentum_balance, v),
138140
]
139141

140-
F = sum(fn(**fields, **rheology, **boundary_ids, test_function=φ) for fn, φ in fns)
141-
G = sum(fn(**fields, **regularized_rheology, test_function=φ) for fn, φ in kfns)
142-
J = derivative(F + G, z)
142+
def form_problem(rheology):
143+
F = sum(
144+
fn(**fields, **rheology, **boundary_ids, test_function=φ)
145+
for fn, φ in fns
146+
)
147+
J = derivative(F, z)
148+
problem = NonlinearVariationalProblem(F, z, bcs, J=J, **pparams)
149+
return problem
143150

144-
qdegree = max(8, degree ** n)
145-
pparams = {"form_compiler_parameters": {"quadrature_degree": qdegree}}
146-
problem = firedrake.NonlinearVariationalProblem(F, z, bcs, J=J, **pparams)
147151
sparams = {
148152
"solver_parameters": {
149153
"snes_type": "newtonls",
150154
"snes_max_it": 200,
151155
"snes_linesearch_type": "nleqerr",
152156
"ksp_type": "gmres",
153157
"pc_type": "lu",
154-
"pc_factor_mat_solver_type": "umfpack",
158+
"pc_factor_mat_solver_type": "mumps",
155159
}
156160
}
157-
solver = firedrake.NonlinearVariationalSolver(problem, **sparams)
158161

159-
solver.solve()
160-
λ.assign(0.0)
161-
solver.solve()
162+
num_continuation_steps = 5
163+
λs = np.linspace(0.0, 1.0, num_continuation_steps)
164+
for λ in λs:
165+
n.assign((1 - λ) + λ * glen_flow_law)
166+
m.assign((1 - λ) + λ * weertman_sliding_law)
167+
problem = form_problem(rheology)
168+
solver = NonlinearVariationalSolver(problem, **sparams)
169+
solver.solve()
162170

163171
u, M, τ = z.subfunctions
164172
error = firedrake.norm(u - u_exact) / firedrake.norm(u_exact)
@@ -180,6 +188,8 @@ def test_convergence_rate_floating(degree):
180188
h0, dh = Constant(500.0), Constant(100.0)
181189
u_inflow = Constant(100.0)
182190

191+
n = firedrake.Constant(glen_flow_law)
192+
183193
τ_c = Constant(0.1)
184194
ε_c = Constant(0.01)
185195
A = ε_c / τ_c**n
@@ -255,10 +265,10 @@ def perturb_u(x, y):
255265
K = MinimizationForm.viscous_power(**fields, **regularized_rheology)
256266
J = derivative(derivative(L + K, z), z)
257267

258-
qdegree = max(8, degree ** n)
268+
qdegree = max(8, degree ** glen_flow_law)
259269
pparams = {"form_compiler_parameters": {"quadrature_degree": qdegree}}
260-
problem = firedrake.NonlinearVariationalProblem(F, z, bcs, J=J, **pparams)
261-
solver = firedrake.NonlinearVariationalSolver(problem)
270+
problem = NonlinearVariationalProblem(F, z, bcs, J=J, **pparams)
271+
solver = NonlinearVariationalSolver(problem)
262272

263273
solver.solve()
264274
λ.assign(0.0)

0 commit comments

Comments
 (0)