hermit.bcs
BoundaryConditions – the BC builders clamp / pin / symmetry /
gauge, compiled once against a hermit.ShellDomain.
No CSDL is involved, so a compiled BoundaryConditions survives across every
solve for its domain. Two enforcement paths are available: a penalty term over
the selected facets (the default; it eliminates no dofs and supports several
independently masked regions in one form) and strong Dirichlet constraints
(method="strong"). The penalty scale is large, so under a large geometry
perturbation the strong path conditions better – see the shape-derivative docs.
Selecting a region: where
where is the raw DOLFINx entity locator, Callable[[ndarray], ndarray[bool]],
receiving coordinates of shape (3, N) and returning an (N,) boolean mask.
Two helpers build the common cases:
near()–x[axis] == valuewithin an absolute tolerance.on_plane()– points on a plane through a point with a given normal, which need not be axis-aligned.
Prescribed values
Every builder takes value= – a scalar, a (6,) vector over
(ux, uy, uz, rx, ry, rz), or a callable returning (N, 6) for its (N, 3)
coordinates. It defaults to zero. A csdl.Variable is deliberately not
accepted: an enforced displacement is interpolated once, not carried as a
differentiable solve input, so it cannot be a design variable. Loads and material
properties can.
The symmetry mask
On a symmetry plane with unit normal n, the constrained dofs are the
displacement along n and the two rotations about the in-plane axes; the
rotation about n itself is left free. For an axis-aligned plane with normal
index k that is mask = (m0, m1, m2, r0, r1, r2) with m_k = 1 and
r_i = 1 for i != k – normal +x gives (1, 0, 0, 0, 1, 1), the
standard “SPC on trans-x / rot-y / rot-z” convention. The penalty machinery supports
only an axis-aligned 6-component mask, so symmetry raises on a rotated normal.
Merging: later terms win on overlap
a + b merges two BoundaryConditions on the same domain. Walking the merged
term list from last-added to first, each term’s located entities are removed from
every earlier term before that term’s measures are recompiled. So on a facet claimed
by two regions only the later region’s mask governs, rather than the sum of both
masks; a term that loses all of its entities is dropped. Strong constraints are
concatenated in + order, and DOLFINx applies them in order, giving the same
“later wins” rule.
penalty_beta
Stored on the whole compiled object (default 1e15); the effective penalty is
beta / h through the form’s own CellDiameter. Merging two objects that both
carry penalty terms with different explicit penalty_beta raises rather than
silently picking one.
One state space per domain
A BoundaryConditions is valid only for a solve sharing its domain.W object.
DOLFINx does not treat two independently built but structurally identical
FunctionSpaces as interchangeable for DirichletBC application: it does not
raise, it silently solves the wrong problem. See hermit.ShellDomain.
Classes
Located facets, dofs and measures, compiled once against a domain. |
Functions
|
Fix all six generalized dofs on a region. |
|
Pin selected dofs at a single point, to remove rigid-body modes. |
|
Build a |
|
Build a |
|
Fix a chosen subset of the six generalized dofs on a region. |
|
Apply a symmetry-plane constraint (penalty enforcement). |
Module Contents
- class hermit.bcs.BoundaryConditions(domain, *, penalty_terms=(), strong=(), penalty_beta=None)
Located facets, dofs and measures, compiled once against a domain.
Build one with
clamp(),pin(),symmetry()orgauge()rather than calling this constructor directly.a + bmerges two objects on the same domain, with later terms winning on overlapping entities.- Parameters:
- domainShellDomain
- penalty_termssequence, optional
Compiled penalty regions, each carrying a dof mask, a prescribed target and its facet measures.
- strongsequence of dolfinx.fem.DirichletBC, optional
Strong constraints.
- penalty_betafloat, optional
Penalty scale for the whole object;
Noneselects the default 1e15.
- Attributes:
- strong_dofsndarray
Sorted unique dof indices held by the strong constraints.
Notes
Valid only for a solve that shares this
domain’s state space; see the module docstring.- to_bc_data()
Pack this object for the FEniCSx solve operation.
- Returns:
- hermit.fenics.bcs.BCData
Carrying a single masked penalty region when there is at most one, and a list of independently masked regions when several survive a merge.
- domain
- penalty_beta = None
- penalty_terms = []
- strong = []
- property strong_dofs
- hermit.bcs.clamp(domain, *, where, method='penalty', penalty_beta=None, value=0.0)
Fix all six generalized dofs on a region.
- Parameters:
- domainShellDomain
- wherecallable
Coordinate predicate; receives a
(3, N)array and returns an(N,)boolean mask.near()andon_plane()build the common cases.- method{‘penalty’, ‘strong’}, optional
Enforcement path. Default
'penalty'.- penalty_betafloat, optional
Penalty scale,
'penalty'only. Default 1e15.- valuefloat, array_like or callable, optional
Prescribed value: a scalar, a
(6,)vector over(ux, uy, uz, rx, ry, rz), or a callable returning(N, 6)for its(N, 3)coordinates. Default 0. Not differentiable – see the module docstring.
- Returns:
- BoundaryConditions
- Raises:
- ValueError
If
methodis not recognised, or ifpenalty_betais given withmethod='strong'.
See also
pinconstrain a subset of the six dofs.
Examples
>>> bcs = hm.clamp(domain, where=hm.near("x", 0.0))
- hermit.bcs.gauge(domain, *, at, dofs, value=0.0)
Pin selected dofs at a single point, to remove rigid-body modes.
Always enforced strongly. Use it to fix the residual null space of an otherwise softly supported model.
- Parameters:
- domainShellDomain
- atarray_like
A
(3,)point; the nearest dof of each selected component is used.- dofssequence of str
Any subset of
('ux', 'uy', 'uz', 'rx', 'ry', 'rz').- valuefloat, array_like or callable, optional
Prescribed value; see
clamp(). Default 0.
- Returns:
- BoundaryConditions
- Raises:
- ValueError
If a dof name is not one of the six.
Examples
>>> bcs = supports + hm.gauge(domain, at=[0.0, 0.0, 0.0], dofs=("ux", "uy"))
- hermit.bcs.near(axis, value, *, tol=1e-12)
Build a
wherepredicate selecting an axis-aligned plane.- Parameters:
- axis{0, 1, 2, ‘x’, ‘y’, ‘z’}
Coordinate axis to test.
- valuefloat
Coordinate value the plane sits at.
- tolfloat, optional
Absolute tolerance. Default 1e-12.
- Returns:
- callable
Suitable as
where=for any BC or edge-load builder.
- Raises:
- ValueError
If
axisis not one of the accepted names.
Notes
The comparison is purely absolute. A relative tolerance would swamp
tolfar from the origin –near("x", 10.0)would select everything within 1e-4 of the plane.Examples
>>> bcs = hm.clamp(domain, where=hm.near("x", 0.0))
- hermit.bcs.on_plane(point, normal, *, tol=1e-12)
Build a
wherepredicate selecting an arbitrary plane.- Parameters:
- pointarray_like
A
(3,)point on the plane.- normalarray_like
A
(3,)plane normal; need not be unit or axis-aligned.- tolfloat, optional
Absolute distance tolerance. Default 1e-12.
- Returns:
- callable
Suitable as
where=for any BC or edge-load builder.
See also
nearthe axis-aligned shorthand.
- hermit.bcs.pin(domain, *, where, dofs, method='penalty', penalty_beta=None, value=0.0)
Fix a chosen subset of the six generalized dofs on a region.
- Parameters:
- domainShellDomain
- wherecallable
Coordinate predicate; see
clamp().- dofssequence of str
Any subset of
('ux', 'uy', 'uz', 'rx', 'ry', 'rz').- method{‘penalty’, ‘strong’}, optional
Enforcement path. Default
'penalty'.- penalty_betafloat, optional
Penalty scale,
'penalty'only.- valuefloat, array_like or callable, optional
Prescribed value; see
clamp(). Default 0.
- Returns:
- BoundaryConditions
- Raises:
- ValueError
If a dof name is unknown, if
methodis not recognised, or ifpenalty_betais given withmethod='strong'.
Examples
>>> diaphragm = hm.pin(domain, where=hm.near("x", 0.0), dofs=("uy", "uz"))
- hermit.bcs.symmetry(domain, *, where, normal, penalty_beta=None, value=0.0)
Apply a symmetry-plane constraint (penalty enforcement).
Constrains the displacement along
normaland the two rotations about the in-plane axes, leaving the rotation aboutnormalfree.- Parameters:
- domainShellDomain
- wherecallable
Coordinate predicate selecting the plane; see
clamp().- normalarray_like
A
(3,)plane normal, which must be (close to) axis-aligned.- penalty_betafloat, optional
Penalty scale. Default 1e15.
- valuefloat, array_like or callable, optional
Prescribed value; see
clamp(). Default 0.
- Returns:
- BoundaryConditions
- Raises:
- ValueError
If
normalis zero or not axis-aligned. The penalty form carries a 6-component mask in global x/y/z, with no rotated-frame projection.
Examples
>>> half = hm.symmetry(domain, where=hm.near("y", 0.0), normal=[0, 1, 0])