Skip to content

Commit e9add2b

Browse files
refactoring + documentation
1 parent b8570e0 commit e9add2b

2 files changed

Lines changed: 45 additions & 52 deletions

File tree

src/festim/boundary_conditions/dirichlet_bc.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
import numpy as np
44
import numpy.typing as npt
55
import ufl
6+
import ufl.argument
67
import ufl.core
78
import ufl.core.expr
9+
import ufl.indexed
810
from dolfinx import fem
911
from dolfinx import mesh as _mesh
1012

@@ -142,6 +144,47 @@ def update(self, t: float):
142144
elif self.bc_expr is not None:
143145
self.value_fenics.interpolate(self.bc_expr)
144146

147+
def weak_formulation(
148+
self,
149+
u: fem.Function | ufl.indexed.Indexed,
150+
v: ufl.argument.Argument | ufl.indexed.Indexed,
151+
ds: ufl.Measure,
152+
) -> ufl.core.expr.Expr:
153+
"""
154+
Returns the Nitsche weak formulation for the BC
155+
This follows the dolfinx tutorial
156+
https://jsdokken.com/dolfinx-tutorial/chapter1/nitsche.html
157+
158+
Args:
159+
u: the solution function associated to the species for which the BC
160+
is applied
161+
v: the test function
162+
ds: the surface measure
163+
164+
Returns:
165+
the weak formulation
166+
"""
167+
mesh = ds.ufl_domain()
168+
n = ufl.FacetNormal(mesh)
169+
h = ufl.Circumradius(mesh) # FIXME this doesn't work for rectangles
170+
alpha = self.penalty
171+
assert alpha is not None, (
172+
"Penalty parameter must be given for weakly enforced Dirichlet BCs"
173+
)
174+
assert self.value_fenics is not None, (
175+
"value_fenics must be defined for weakly enforced Dirichlet BCs"
176+
)
177+
178+
form = -ufl.inner(n, ufl.grad(u)) * v * ds(self.subdomain.id)
179+
180+
form += (
181+
+ufl.inner(n, ufl.grad(v)) * (u - self.value_fenics) * ds(self.subdomain.id)
182+
)
183+
form += (
184+
-alpha / h * ufl.inner((u - self.value_fenics), v) * ds(self.subdomain.id)
185+
)
186+
return form
187+
145188

146189
class FixedConcentrationBC(DirichletBCBase):
147190
"""

src/festim/hydrogen_transport_problem.py

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -898,34 +898,7 @@ def create_formulation(self):
898898
if bc.enforce_weakly:
899899
u = bc.species.solution
900900
v = bc.species.test_function
901-
n = ufl.FacetNormal(self.mesh.mesh)
902-
h = ufl.Circumradius(
903-
self.mesh.mesh
904-
) # FIXME this doesn't work for rectangles
905-
alpha = bc.penalty
906-
assert alpha is not None, (
907-
"Penalty parameter must be given for weakly enforced Dirichlet BCs"
908-
)
909-
assert bc.value_fenics is not None, (
910-
"value_fenics must be defined for weakly enforced Dirichlet BCs"
911-
)
912-
913-
self.formulation += (
914-
-ufl.inner(n, ufl.grad(u)) * v * self.ds(bc.subdomain.id)
915-
)
916-
917-
self.formulation += (
918-
+ufl.inner(n, ufl.grad(v))
919-
* (u - bc.value_fenics)
920-
* self.ds(bc.subdomain.id)
921-
)
922-
self.formulation += (
923-
-alpha
924-
/ h
925-
* ufl.inner((u - bc.value_fenics), v)
926-
* self.ds(bc.subdomain.id)
927-
)
928-
901+
self.formulation += bc.weak_formulation(u, v, self.ds)
929902
for adv_term in self.advection_terms:
930903
# create vector functionspace based on the elements in the mesh
931904

@@ -1585,31 +1558,8 @@ def create_subdomain_formulation(self, subdomain: _subdomain.VolumeSubdomain):
15851558
if bc.enforce_weakly:
15861559
u = bc.species.subdomain_to_solution[subdomain]
15871560
v = bc.species.subdomain_to_test_function[subdomain]
1588-
n = ufl.FacetNormal(self.mesh.mesh)
1589-
h = ufl.Circumradius(
1590-
self.mesh.mesh
1591-
) # FIXME this doesn't work for rectangles
1592-
alpha = bc.penalty
1593-
assert alpha is not None, (
1594-
"Penalty parameter must be given for weakly enforced Dirichlet BCs"
1595-
)
1596-
assert bc.value_fenics is not None, (
1597-
"value_fenics must be defined for weakly enforced Dirichlet BCs"
1598-
)
1599-
1600-
form += -ufl.inner(n, ufl.grad(u)) * v * self.ds(bc.subdomain.id)
1561+
form += bc.weak_formulation(u, v, self.ds)
16011562

1602-
form += (
1603-
+ufl.inner(n, ufl.grad(v))
1604-
* (u - bc.value_fenics)
1605-
* self.ds(bc.subdomain.id)
1606-
)
1607-
form += (
1608-
-alpha
1609-
/ h
1610-
* ufl.inner((u - bc.value_fenics), v)
1611-
* self.ds(bc.subdomain.id)
1612-
)
16131563
# add volumetric sources
16141564
for source in self.sources:
16151565
v = source.species.subdomain_to_test_function[subdomain]

0 commit comments

Comments
 (0)