Skip to content

Commit 515e7ab

Browse files
committed
Simplifications to dome notebook + unit test
* Remove the initial SIA solve. This is unnecessary once you use continuation or a composite rheology. * In the initial momentum solve, use the full function space `V * Σ * V * Q` and make the `h` block the identity matrix. This lets us reuse the momentum part of the equation and only change the mass part of the full problem.
1 parent 5d97bb5 commit 515e7ab

File tree

2 files changed

+53
-159
lines changed

2 files changed

+53
-159
lines changed

notebooks/rainier-monolithic.ipynb

Lines changed: 30 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,7 @@
155155
"r_h = Constant(5e3)\n",
156156
"H = Constant(100.0)\n",
157157
"expr = H * firedrake.max_value(0, 1 - inner(x, x) / r_h**2)\n",
158-
"h = firedrake.Function(Q).interpolate(expr)\n",
159-
"h_0 = h.copy(deepcopy=True)"
158+
"h_init = firedrake.Function(Q).interpolate(expr)"
160159
]
161160
},
162161
{
@@ -168,7 +167,7 @@
168167
"source": [
169168
"fig, ax = plt.subplots()\n",
170169
"ax.set_aspect(\"equal\")\n",
171-
"colors = firedrake.tripcolor(h, axes=ax)\n",
170+
"colors = firedrake.tripcolor(h_init, axes=ax)\n",
172171
"fig.colorbar(colors);"
173172
]
174173
},
@@ -187,7 +186,7 @@
187186
"metadata": {},
188187
"outputs": [],
189188
"source": [
190-
"s = firedrake.Function(Q).interpolate(b + h)\n",
189+
"s = firedrake.Function(Q).interpolate(b + h_init)\n",
191190
"a = firedrake.Function(Q).interpolate(smb(s))"
192191
]
193192
},
@@ -227,10 +226,12 @@
227226
},
228227
{
229228
"cell_type": "markdown",
230-
"id": "bec1a763-ab01-4f63-ae93-d92f0ce0ef2a",
229+
"id": "922938b5-e240-4573-be3d-a6f6302951c2",
231230
"metadata": {},
232231
"source": [
233-
"We'll use the shallow ice approximation, which diagnoses the velocity at a point in a purely local fashion using the thickness and surface slope, to initialize the ice velocity."
232+
"To proceed, we have to make function spaces to represent the membrane and basal stresses and create a variable that stores the velocity and stresses.\n",
233+
"Here we use piecewise constant finite elements for the membrane stresses.\n",
234+
"In general, if you use $CG(k)$ elements for the velocity, you need to use $DG(k - 1)$ elements for the stresses."
234235
]
235236
},
236237
{
@@ -242,63 +243,10 @@
242243
"source": [
243244
"V = firedrake.VectorFunctionSpace(mesh, cg1)\n",
244245
"\n",
245-
"u = firedrake.Function(V)\n",
246-
"v = firedrake.TestFunction(V)\n",
247-
"\n",
248-
"ρ_I = Constant(ice_density)\n",
249-
"g = Constant(gravity)\n",
250-
"\n",
251-
"n = Constant(glen_flow_law)\n",
252-
"\n",
253-
"P = ρ_I * g * h\n",
254-
"S_n = inner(grad(s), grad(s))**((n - 1) / 2)\n",
255-
"u_shear = -2 * A * P ** n / (n + 2) * h * S_n * grad(s)\n",
256-
"F = inner(u - u_shear, v) * dx\n",
257-
"\n",
258-
"solver_params = {\"snes_type\": \"ksponly\", \"ksp_type\": \"gmres\"}\n",
259-
"fc_params = {\"quadrature_degree\": 6}\n",
260-
"params = {\"solver_parameters\": solver_params, \"form_compiler_parameters\": fc_params}\n",
261-
"firedrake.solve(F == 0, u, **params)"
262-
]
263-
},
264-
{
265-
"cell_type": "code",
266-
"execution_count": null,
267-
"id": "5a32887c-dcd3-4aae-844e-1a6c70b183db",
268-
"metadata": {},
269-
"outputs": [],
270-
"source": [
271-
"fig, ax = plt.subplots()\n",
272-
"ax.set_aspect(\"equal\")\n",
273-
"colors = firedrake.tripcolor(u, axes=ax)\n",
274-
"fig.colorbar(colors);"
275-
]
276-
},
277-
{
278-
"cell_type": "markdown",
279-
"id": "9a900c91-a77f-4d7a-86e3-9c014512e3b9",
280-
"metadata": {},
281-
"source": [
282-
"Now we'll get to the real modeling.\n",
283-
"To proceed, we have to make function spaces to represent the membrane and basal stresses and create a variable that stores the velocity and stresses.\n",
284-
"Here we use piecewise constant finite elements for the stresses.\n",
285-
"In general, if you use $CG(k)$ elements for the velocity, you need to use $DG(k - 1)$ elements for the stresses."
286-
]
287-
},
288-
{
289-
"cell_type": "code",
290-
"execution_count": null,
291-
"id": "db935250-689e-4ca7-aee5-c5b0f212c4d4",
292-
"metadata": {},
293-
"outputs": [],
294-
"source": [
295246
"dg0 = firedrake.FiniteElement(\"DG\", \"triangle\", 0)\n",
296247
"Σ = firedrake.TensorFunctionSpace(mesh, dg0, symmetry=True)\n",
297-
"T = firedrake.VectorFunctionSpace(mesh, cg1)\n",
298-
"Z = V * Σ * T\n",
299-
"z = firedrake.Function(Z)\n",
300-
"\n",
301-
"z.sub(0).assign(u);"
248+
"Z = V * Σ * V * Q\n",
249+
"z = firedrake.Function(Z)"
302250
]
303251
},
304252
{
@@ -322,6 +270,8 @@
322270
"metadata": {},
323271
"outputs": [],
324272
"source": [
273+
"n = Constant(glen_flow_law)\n",
274+
"\n",
325275
"τ_c = Constant(0.1)\n",
326276
"ε_c = Constant(A * τ_c ** n)"
327277
]
@@ -351,6 +301,8 @@
351301
"metadata": {},
352302
"outputs": [],
353303
"source": [
304+
"u, M, τ, h = firedrake.split(z)\n",
305+
"\n",
354306
"K = h * A / (n + 2)\n",
355307
"U_c = Constant(100.0)\n",
356308
"u_c = K * τ_c ** n + U_c"
@@ -378,16 +330,15 @@
378330
" \"sliding_coefficient\": u_c / τ_c,\n",
379331
"}\n",
380332
"\n",
381-
"u, M, τ = firedrake.split(z)\n",
382333
"fields = {\n",
383334
" \"velocity\": u,\n",
384335
" \"membrane_stress\": M,\n",
385336
" \"basal_stress\": τ,\n",
386337
" \"thickness\": h,\n",
387-
" \"surface\": s,\n",
338+
" \"surface\": b + h,\n",
388339
"}\n",
389340
"\n",
390-
"v, N, σ = firedrake.TestFunctions(Z)"
341+
"v, N, σ, η = firedrake.TestFunctions(Z)"
391342
]
392343
},
393344
{
@@ -441,14 +392,17 @@
441392
"from icepack2 import model\n",
442393
"from icepack2.model.variational import momentum_balance, flow_law, friction_law\n",
443394
"\n",
444-
"F = (\n",
395+
"F_momentum = (\n",
445396
" momentum_balance(**fields, test_function=v)\n",
446397
" + firedrake.replace(flow_law(**fields, **glen_rheology, test_function=N), {h: H})\n",
447398
" + α * firedrake.replace(flow_law(**fields, **linear_rheology, test_function=N), {h: H})\n",
448399
" + friction_law(**fields, **glen_rheology, test_function=σ)\n",
449400
" + α * friction_law(**fields, **linear_rheology, test_function=σ)\n",
450401
")\n",
451402
"\n",
403+
"F_mass = (h - h_init) * η * dx\n",
404+
"\n",
405+
"F = F_momentum + F_mass\n",
452406
"momentum_problem = firedrake.NonlinearVariationalProblem(F, z, **pparams)\n",
453407
"momentum_solver = firedrake.NonlinearVariationalSolver(momentum_problem, **sparams)"
454408
]
@@ -482,7 +436,7 @@
482436
"metadata": {},
483437
"outputs": [],
484438
"source": [
485-
"u_init, M_init, τ_init = z.subfunctions\n",
439+
"u_init, M_init, τ_init, h_init = z.subfunctions\n",
486440
"\n",
487441
"fig, axes = plt.subplots()\n",
488442
"axes.set_aspect(\"equal\")\n",
@@ -526,21 +480,6 @@
526480
"Pack in the initial values of the velocity, membrane stress, and basal stress that we computed before."
527481
]
528482
},
529-
{
530-
"cell_type": "code",
531-
"execution_count": null,
532-
"id": "873be577-b14f-4f6a-bd69-fbe9a6cc2f34",
533-
"metadata": {},
534-
"outputs": [],
535-
"source": [
536-
"W = V * Σ * T * Q\n",
537-
"w = firedrake.Function(W)\n",
538-
"w.sub(0).assign(u_init)\n",
539-
"w.sub(1).assign(M_init)\n",
540-
"w.sub(2).assign(τ_init)\n",
541-
"w.sub(3).assign(h);"
542-
]
543-
},
544483
{
545484
"cell_type": "markdown",
546485
"id": "0573021d-eade-4e73-b8b1-563c56da95aa",
@@ -556,27 +495,7 @@
556495
"metadata": {},
557496
"outputs": [],
558497
"source": [
559-
"u, M, τ, h = firedrake.split(w)\n",
560-
"v, N, σ, η = firedrake.TestFunctions(W)\n",
561-
"\n",
562-
"fields = {\n",
563-
" \"velocity\": u,\n",
564-
" \"membrane_stress\": M,\n",
565-
" \"basal_stress\": τ,\n",
566-
" \"thickness\": h,\n",
567-
" \"surface\": b + h,\n",
568-
"}\n",
569-
"\n",
570-
"F_momentum = (\n",
571-
" momentum_balance(**fields, test_function=v)\n",
572-
" + firedrake.replace(flow_law(**fields, **glen_rheology, test_function=N), {h: H})\n",
573-
" + α * firedrake.replace(flow_law(**fields, **linear_rheology, test_function=N), {h: H})\n",
574-
" + friction_law(**fields, **glen_rheology, test_function=σ)\n",
575-
" + α * friction_law(**fields, **linear_rheology, test_function=σ)\n",
576-
")\n",
577-
"\n",
578498
"F_mass = model.mass_balance(thickness=h, velocity=u, accumulation=a, test_function=η)\n",
579-
"\n",
580499
"F = F_momentum + F_mass"
581500
]
582501
},
@@ -591,8 +510,8 @@
591510
"t = Constant(0.0)\n",
592511
"dt = Constant(1.0 / 6)\n",
593512
"\n",
594-
"lower = firedrake.Function(W)\n",
595-
"upper = firedrake.Function(W)\n",
513+
"lower = firedrake.Function(Z)\n",
514+
"upper = firedrake.Function(Z)\n",
596515
"lower.assign(-np.inf)\n",
597516
"upper.assign(+np.inf)\n",
598517
"lower.subfunctions[3].assign(0.0)\n",
@@ -603,18 +522,17 @@
603522
" \"snes_monitor\": \":rainier-output-vi.log\",\n",
604523
" \"snes_type\": \"vinewtonrsls\",\n",
605524
" \"snes_max_it\": 200,\n",
606-
" #\"snes_linesearch_type\": \"nleqerr\",\n",
607525
" \"ksp_type\": \"gmres\",\n",
608526
" \"pc_type\": \"lu\",\n",
609527
" \"pc_factor_mat_solver_type\": \"mumps\",\n",
610528
" },\n",
611-
" \"form_compiler_parameters\": fc_params,\n",
529+
" \"form_compiler_parameters\": {\"quadrature_degree\": 6},\n",
612530
" \"stage_type\": \"value\",\n",
613531
" \"basis_type\": \"Bernstein\",\n",
614532
" \"bounds\": bounds,\n",
615533
"}\n",
616534
"\n",
617-
"solver = irksome.TimeStepper(F, tableau, t, dt, w, **bparams)"
535+
"solver = irksome.TimeStepper(F, tableau, t, dt, z, **bparams)"
618536
]
619537
},
620538
{
@@ -632,18 +550,18 @@
632550
"metadata": {},
633551
"outputs": [],
634552
"source": [
635-
"us = [w.subfunctions[0].copy(deepcopy=True)]\n",
636-
"hs = [w.subfunctions[3].copy(deepcopy=True)]\n",
553+
"us = [z.subfunctions[0].copy(deepcopy=True)]\n",
554+
"hs = [z.subfunctions[3].copy(deepcopy=True)]\n",
637555
"\n",
638556
"final_time = 500.0\n",
639557
"num_steps = int(final_time / float(dt))\n",
640558
"for step in trange(num_steps):\n",
641559
" solver.advance()\n",
642-
" h = w.subfunctions[3]\n",
560+
" h = z.subfunctions[3]\n",
643561
" a.interpolate(smb(b + h))\n",
644562
"\n",
645-
" us.append(w.subfunctions[0].copy(deepcopy=True))\n",
646-
" hs.append(w.subfunctions[3].copy(deepcopy=True))"
563+
" us.append(z.subfunctions[0].copy(deepcopy=True))\n",
564+
" hs.append(z.subfunctions[3].copy(deepcopy=True))"
647565
]
648566
},
649567
{
@@ -679,7 +597,7 @@
679597
"metadata": {},
680598
"outputs": [],
681599
"source": [
682-
"u, M, τ, h = w.subfunctions\n",
600+
"u, M, τ, h = z.subfunctions\n",
683601
"\n",
684602
"fig, axes = plt.subplots()\n",
685603
"axes.set_aspect(\"equal\")\n",

0 commit comments

Comments
 (0)