Skip to content

Commit f684073

Browse files
KarsKnookpefarrellconnorjwardABaierReiniopbrubeck
committed
Knook/multicomponent (#4322)
Multicomponent microfluidics demo --------- Co-authored-by: Patrick E. Farrell <patrick.farrell@maths.ox.ac.uk> Co-authored-by: Connor Ward <c.ward20@imperial.ac.uk> Co-authored-by: Aaron Baier-Reinio <130484015+ABaierReinio@users.noreply.github.com> Co-authored-by: Pablo Brubeck <brubeck@protonmail.com> Co-authored-by: ABaierReinio <baierreinio@maths.ox.ac.uk>
1 parent 4be2fee commit f684073

File tree

9 files changed

+693
-36
lines changed

9 files changed

+693
-36
lines changed

demos/boussinesq/boussinesq.py.rst

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -160,43 +160,46 @@ cannot always be sure that the linear solver at hand is correctly utilising the
160160
To directly eliminate the nullspace we introduce a class :code:`FixAtPointBC` which
161161
implements a boundary condition that fixes a field at a single point. ::
162162

163-
import firedrake.utils as firedrake_utils
164-
165-
class FixAtPointBC(firedrake.DirichletBC):
166-
r'''A special BC object for pinning a function at a point.
167-
168-
:arg V: the :class:`.FunctionSpace` on which the boundary condition should be applied.
169-
:arg g: the boundary condition value.
170-
:arg bc_point: the point at which to pin the function.
171-
The location of the finite element DOF nearest to bc_point is actually used.
172-
'''
173-
def __init__(self, V, g, bc_point):
174-
super(FixAtPointBC, self).__init__(V, g, bc_point)
175-
if isinstance(bc_point, tuple):
176-
bc_point = as_vector(bc_point)
177-
self.bc_point = bc_point
178-
179-
@firedrake_utils.cached_property
180-
def nodes(self):
181-
V = self.function_space()
182-
x = firedrake.SpatialCoordinate(V.mesh())
183-
xdist = x - self.bc_point
184-
185-
test = firedrake.TestFunction(V)
186-
trial = firedrake.TrialFunction(V)
187-
xphi = firedrake.assemble(ufl.inner(xdist * test, xdist * trial) * ufl.dx, diagonal=True)
188-
phi = firedrake.assemble(ufl.inner(test, trial) * ufl.dx, diagonal=True)
189-
with xphi.dat.vec as xu, phi.dat.vec as u:
190-
xu.pointwiseDivide(xu, u)
191-
min_index, min_value = xu.min() # Find the index of the DOF closest to bc_point
192-
193-
nodes = V.dof_dset.lgmap.applyInverse([min_index])
194-
nodes = nodes[nodes >= 0]
195-
return nodes
196-
163+
import functools
164+
165+
class FixAtPointBC(DirichletBC):
166+
r'''A special BC object for pinning a function at a point.
167+
168+
:arg V: the :class:`.FunctionSpace` on which the boundary condition should be applied.
169+
:arg g: the boundary condition value.
170+
:arg bc_point: the point at which to pin the function.
171+
The location of the finite element DOF nearest to bc_point is actually used.
172+
'''
173+
def __init__(self, V, g, bc_point):
174+
super().__init__(V, g, bc_point)
175+
176+
@functools.cached_property
177+
def nodes(self):
178+
V = self.function_space()
179+
if V.mesh().ufl_coordinate_element().degree() != 1:
180+
# Ensure a P1 mesh
181+
coordinates = V.mesh().coordinates
182+
P1 = coordinates.function_space().reconstruct(degree=1)
183+
P1_mesh = Mesh(Function(P1).interpolate(coordinates))
184+
V = V.reconstruct(mesh=P1_mesh)
185+
186+
point = [tuple(self.sub_domain)]
187+
vom = VertexOnlyMesh(V.mesh(), point)
188+
P0 = FunctionSpace(vom, "DG", 0)
189+
Fvom = Cofunction(P0.dual()).assign(1)
190+
191+
# Take the basis function with the largest abs value at bc_point
192+
v = TestFunction(V)
193+
F = assemble(Interpolate(inner(v, v), Fvom))
194+
with F.dat.vec as Fvec:
195+
max_index, _ = Fvec.max()
196+
nodes = V.dof_dset.lgmap.applyInverse([max_index])
197+
nodes = nodes[nodes >= 0]
198+
return nodes
199+
197200
We use this to fix the pressure and auxiliary temperature at the origin::
198201

199-
aux_bcs = [FixAtPointBC(Z.sub(1), 0, as_vector([0, 0])),
202+
aux_bcs = [FixAtPointBC(Z.sub(1), 0, (0, 0)),
200203
FixAtPointBC(Z.sub(2), 0, as_vector([0, 0]))]
201204

202205
:code:`FixAtPointBC` takes three arguments: the function space to fix, the value with which it

demos/demo_references.bib

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ @Book{2006:SV
3434
year = 2006
3535
}
3636

37+
@book{Perry:2007,
38+
title = {Perry’s Chemical Engineers’ Handbook},
39+
edition = {8th},
40+
author = {Green, Don W. and Perry, Robert H.},
41+
year = 2007,
42+
publisher = {McGraw Hill Professional}
43+
}
44+
3745
@InBook{2015:lmscup,
3846
author = {O. Bokhove and A. Kalogirou},
3947
title = {Lectures on the Theory of Water Waves},
@@ -309,6 +317,25 @@ @article{Ricker:1953
309317
doi={https://doi.org/10.1190/1.1437843}
310318
}
311319

320+
@article{Krishna:1997,
321+
title={The {M}axwell--{S}tefan approach to mass transfer},
322+
author={Krishna, Rajamani and Wesselingh, Johannes A},
323+
journal={Chemical Engineering Science},
324+
volume={52},
325+
number={6},
326+
pages={861--911},
327+
year={1997},
328+
publisher={Elsevier},
329+
doi={10.1016/S0009-2509(96)00458-7}
330+
}
331+
332+
@article{BaierReinio:2025,
333+
title={High-order finite element methods for three-dimensional multicomponent convection-diffusion},
334+
author={Baier-Reinio, Aaron and Farrell, Patrick E},
335+
journal={arXiv preprint arXiv:2408.17390},
336+
year={2025}
337+
}
338+
312339
@article{Brubeck2022,
313340
author = {Brubeck, Pablo D. and Farrell, Patrick E.},
314341
doi = {10.1137/21M1444187},

demos/multicomponent/benzene_0.png

192 KB
Loading

demos/multicomponent/benzene_4.png

213 KB
Loading
390 KB
Loading

0 commit comments

Comments
 (0)