Skip to content

Commit 1c70ca3

Browse files
committed
2 parents ec40144 + 875516a commit 1c70ca3

14 files changed

+43831
-23
lines changed

Jupyterbook/Notebooks/Examples-Annulus-Stokes/Ex_Stokes_Annulus_Benchmark_Kramer.py

Lines changed: 743 additions & 0 deletions
Large diffs are not rendered by default.

Jupyterbook/Notebooks/Examples-Annulus-Stokes/Ex_Stokes_Annulus_Benchmark_Thieulot.py

Lines changed: 709 additions & 0 deletions
Large diffs are not rendered by default.

Jupyterbook/Notebooks/Examples-Convection/Ex_AdvectionDiffusionSwarm_RotationTest.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,11 @@
2424
# os.environ["SYMPY_USE_CACHE"]="no"
2525

2626
# options.getAll()
27-
# +
28-
import meshio
29-
27+
# -
3028
meshball = uw.meshing.Annulus(
3129
radiusOuter=1.0, radiusInner=0.5, cellSize=0.2, refinement=1, qdegree=3
3230
)
3331
x, y = meshball.X
34-
# -
3532

3633

3734
v_soln = uw.discretisation.MeshVariable("U", meshball, meshball.dim, degree=2)
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
# ---
2+
# jupyter:
3+
# jupytext:
4+
# formats: py:light
5+
# text_representation:
6+
# extension: .py
7+
# format_name: light
8+
# format_version: '1.5'
9+
# jupytext_version: 1.16.1
10+
# kernelspec:
11+
# display_name: Python 3 (ipykernel)
12+
# language: python
13+
# name: python3
14+
# ---
15+
16+
# # Darcy flow (1d) using xy coordinates to define permeability distribution
17+
18+
# to fix trame issue
19+
import nest_asyncio
20+
nest_asyncio.apply()
21+
22+
# + editable=true slideshow={"slide_type": ""}
23+
from petsc4py import PETSc
24+
import underworld3 as uw
25+
import numpy as np
26+
import sympy
27+
from sympy import Piecewise, ceiling, Abs
28+
import matplotlib.pyplot as plt
29+
# %matplotlib inline
30+
31+
options = PETSc.Options()
32+
33+
# + editable=true slideshow={"slide_type": ""}
34+
# vis tools
35+
if uw.mpi.size == 1:
36+
import pyvista as pv
37+
import underworld3.visualisation as vis
38+
39+
# + editable=true slideshow={"slide_type": ""}
40+
minX, maxX = -1.0, 0.0
41+
minY, maxY = -1.0, 0.0
42+
43+
mesh = uw.meshing.UnstructuredSimplexBox(minCoords=(minX, minY), maxCoords=(maxX, maxY),
44+
cellSize=1/25, qdegree=3)
45+
46+
# x and y coordinates
47+
x = mesh.N.x
48+
y = mesh.N.y
49+
50+
# +
51+
# Create Darcy Solver
52+
darcy = uw.systems.SteadyStateDarcy(mesh)
53+
54+
p_soln = darcy.Unknowns.u
55+
v_soln = darcy.v
56+
57+
# Needs to be smaller than the contrast in properties
58+
darcy.petsc_options["snes_rtol"] = 1.0e-6
59+
60+
darcy.constitutive_model = uw.constitutive_models.DarcyFlowModel
61+
# -
62+
63+
64+
p_soln_0 = p_soln.clone("P_no_g", r"{p_\textrm{(no g)}}")
65+
v_soln_0 = v_soln.clone("V_no_g", r"{v_\textrm{(no g)}}")
66+
67+
68+
# + editable=true slideshow={"slide_type": ""}
69+
def plot_P_V(_mesh, _p_soln, _v_soln):
70+
'''
71+
Plot pressure and velcity streamlines
72+
'''
73+
pvmesh = vis.mesh_to_pv_mesh(_mesh)
74+
pvmesh.point_data["P"] = vis.scalar_fn_to_pv_points(pvmesh, _p_soln.sym)
75+
pvmesh.point_data["V"] = vis.vector_fn_to_pv_points(pvmesh, _v_soln.sym)
76+
77+
velocity_points = vis.meshVariable_to_pv_cloud(_v_soln)
78+
velocity_points.point_data["V"] = vis.vector_fn_to_pv_points(velocity_points, _v_soln.sym)
79+
80+
# point sources at cell centres
81+
points = np.zeros((_mesh._centroids.shape[0], 3))
82+
points[:, 0] = _mesh._centroids[:, 0]
83+
points[:, 1] = _mesh._centroids[:, 1]
84+
point_cloud = pv.PolyData(points[::3])
85+
86+
pvstream = pvmesh.streamlines_from_source(point_cloud, vectors="V", integrator_type=45,
87+
integration_direction="both", max_steps=1000,
88+
max_time=0.1, initial_step_length=0.001,
89+
max_step_length=0.01,)
90+
91+
pl = pv.Plotter(window_size=(750, 750))
92+
pl.add_mesh(pvmesh, cmap="coolwarm", edge_color="Black", show_edges=True, scalars="P",
93+
use_transparency=False, opacity=1.0,)
94+
pl.add_mesh(pvstream, line_width=1.0)
95+
# pl.add_arrows(velocity_points.points, velocity_points.point_data["V"], mag=0.005, opacity=0.75)
96+
97+
pl.show(cpos="xy")
98+
99+
100+
# +
101+
# set up two materials
102+
interfaceY = -0.25
103+
k1 = 1.0
104+
k2 = 1.0e-4
105+
106+
# Groundwater pressure boundary condition on the bottom wall
107+
max_pressure = 0.5
108+
109+
# The piecewise version
110+
kFunc = Piecewise((k1, y >= interfaceY), (k2, y < interfaceY), (1.0, True))
111+
112+
# A smooth version
113+
darcy.constitutive_model.Parameters.permeability = kFunc
114+
darcy.constitutive_model.Parameters.s = sympy.Matrix([0, 0]).T
115+
darcy.f = 0.0
116+
117+
# set up boundary conditions
118+
darcy.add_dirichlet_bc(0.0, "Top")
119+
darcy.add_dirichlet_bc(-1.0 * minY * max_pressure, "Bottom")
120+
# + editable=true slideshow={"slide_type": ""}
121+
# darcy solve without gravity
122+
darcy.solve()
123+
124+
125+
# + editable=true slideshow={"slide_type": ""}
126+
# plotting soln without gravity
127+
plot_P_V(mesh, p_soln, v_soln)
128+
129+
# + editable=true slideshow={"slide_type": ""}
130+
# copying solution
131+
with mesh.access(p_soln_0, v_soln_0):
132+
p_soln_0.data[...] = p_soln.data[...]
133+
v_soln_0.data[...] = v_soln.data[...]
134+
# -
135+
136+
# now switch on gravity
137+
darcy.constitutive_model.Parameters.s = sympy.Matrix([0, -1]).T
138+
darcy.solve()
139+
# + editable=true slideshow={"slide_type": ""}
140+
# plotting soln with gravity
141+
plot_P_V(mesh, p_soln, v_soln)
142+
143+
# +
144+
# set up interpolation coordinates
145+
ycoords = np.linspace(minY + 0.001 * (maxY - minY), maxY - 0.001 * (maxY - minY), 100)
146+
xcoords = np.full_like(ycoords, -0.5)
147+
xy_coords = np.column_stack([xcoords, ycoords])
148+
149+
pressure_interp = uw.function.evaluate(p_soln.sym[0], xy_coords)
150+
pressure_interp_0 = uw.function.evaluate(p_soln_0.sym[0], xy_coords)
151+
152+
153+
# + editable=true slideshow={"slide_type": ""}
154+
La = -1.0 * interfaceY
155+
Lb = 1.0 + interfaceY
156+
dP = max_pressure
157+
158+
S = 1
159+
Pa = (dP / Lb - S + k1 / k2 * S) / (1.0 / Lb + k1 / k2 / La)
160+
pressure_analytic = np.piecewise(
161+
ycoords,
162+
[ycoords >= -La, ycoords < -La],
163+
[
164+
lambda ycoords: -Pa * ycoords / La,
165+
lambda ycoords: Pa + (dP - Pa) * (-ycoords - La) / Lb,
166+
],
167+
)
168+
169+
y = sympy.symbols('y')
170+
P1 = -Pa * y / La
171+
P2 = Pa + (dP - Pa) * (-y - La) / Lb
172+
print(P1)
173+
print(P2)
174+
175+
S = 0
176+
Pa = (dP / Lb - S + k1 / k2 * S) / (1.0 / Lb + k1 / k2 / La)
177+
pressure_analytic_noG = np.piecewise(
178+
ycoords,
179+
[ycoords >= -La, ycoords < -La],
180+
[
181+
lambda ycoords: -Pa * ycoords / La,
182+
lambda ycoords: Pa + (dP - Pa) * (-ycoords - La) / Lb,
183+
],
184+
)
185+
186+
y = sympy.symbols('y')
187+
P1 = -Pa * y / La
188+
P2 = Pa + (dP - Pa) * (-y - La) / Lb
189+
print(P1)
190+
print(P2)
191+
192+
# + editable=true slideshow={"slide_type": ""}
193+
# plotting numerical and analytical solution
194+
fig = plt.figure()
195+
ax1 = fig.add_subplot(111, xlabel="Pressure", ylabel="Depth")
196+
ax1.plot(pressure_interp, ycoords, linewidth=3, label="Numerical solution")
197+
ax1.plot(pressure_interp_0, ycoords, linewidth=3, label="Numerical solution (no G)")
198+
ax1.plot(pressure_analytic, ycoords, linewidth=3, linestyle="--", label="Analytic solution")
199+
ax1.plot(pressure_analytic_noG, ycoords, linewidth=3, linestyle="--", label="Analytic (no gravity)")
200+
ax1.grid("on")
201+
ax1.legend()
202+
# + editable=true slideshow={"slide_type": ""}
203+

0 commit comments

Comments
 (0)