hermit
Hermit – Reissner-Mindlin shell analysis in FEniCSx, connected to CSDL.
The public API is a ShellDomain (mesh + state space + index maps) plus free
functions that build its inputs – Field builders, BoundaryConditions,
Geometry, Material / Orientation, Loads – fed to solve(),
whose ShellState the postprocess functions (compliance / mass /
stress_field / …) consume. The FEniCSx custom operations live in
hermit.fenics.ops and are called only from hermit._solve /
hermit.outputs / hermit.transfer.
Note on module names: several implementation modules are underscore-prefixed
(_solve / _field / _geometry / _laminate) precisely so they cannot
shadow the public function of the same name. import hermit.solve would otherwise
rebind hermit.solve from the function to the module – silently, with no error.
Submodules
Classes
Located facets, dofs and measures, compiled once against a domain. |
|
A finite-element field on a |
|
The mesh coordinate field, in any configuration |
|
A laminate layup. |
|
A composable bundle of load terms. |
|
The constitutive input bundle consumed by the solve and the outputs. |
|
The laminate fibre orientation carried on a |
|
Mesh, shell state space, index maps and region tags, built once. |
|
The solved shell state, and back-references to everything that produced it. |
Functions
|
Smooth aggregate of isotropic von Mises stress, |
|
Coerce a scalar, array or field to a |
|
Mass-weighted centre of gravity, in global Cartesian coordinates. |
|
Fix all six generalized dofs on a region. |
|
Work done by the applied loads on the solution. |
|
Material from pre-computed ABD stiffness fields. |
|
Build a uniform field by broadcasting one value to every dof. |
|
Mid-surface displacement as a field. |
|
Moment per unit length on selected exterior facets. |
|
Pressure per unit length along the shell normal, on selected exterior facets. |
|
Force per unit length on selected exterior facets. |
|
Stored shell strain energy. |
|
Per-cell, per-ply-face Tsai-Wu failure indices. |
|
KS-aggregated Tsai-Wu failure index over the whole laminate. |
|
Orientation given as an angle from each element's own in-plane axis. |
|
Orientation given as a global fibre direction. |
|
Apply a function to the coefficients of one or more fields. |
|
Build a DG0 field from per-cell values in mesh-file order. |
|
Build a field from raw coefficients in FE dof order. |
|
Build a field by evaluating a function at the space's dof coordinates. |
|
Build a CG1 field from per-vertex values in mesh-file order. |
|
Pin selected dofs at a single point, to remove rigid-body modes. |
|
Build the geometry input for a solve. |
|
Collocate a field at another space's dof points -- the default transfer. |
|
Isotropic single-layer material. |
|
Composite material from a ply stack, via classical lamination theory. |
|
A generalised right-hand side given directly in state-space dof order. |
|
Structural mass, |
|
Distributed moment per unit area, in global components. |
|
Build a |
|
Displacements at the mesh vertices. |
|
Director rotations at the mesh vertices. |
|
Build a |
|
Fix a chosen subset of the six generalized dofs on a region. |
|
Area-normalized p-norm stress integral, |
|
A consistent point force and/or moment at a physical coordinate. |
|
Scalar pressure acting along the shell normal. |
|
L2-project a field onto another space, |
|
Read a mesh from an XDMF file. |
|
Director rotation as a field. |
|
Solve the linear shell problem. |
|
Membrane strain, bending curvature and transverse shear. |
|
Isotropic von Mises stress field. |
|
Suggest the stress scaling |
|
Apply a symmetry-plane constraint (penalty enforcement). |
|
Thickness and density only, for a surrogate solve. |
|
Distributed force per unit area, in global components. |
Package Contents
- class hermit.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
- class hermit.Field(domain, space, coeffs, *, kind='scalar', frame=None, global_frame=False)
A finite-element field on a
ShellDomain.The input/output primitive of the API: every material, load, geometry and output field is a
Field. Build one withconstant(),from_nodal(),from_cells(),from_function()orfrom_coeffs()rather than calling this constructor directly.- Parameters:
- domainShellDomain
The domain the field lives on.
- spacetuple
FE space descriptor,
(family, degree)or(family, degree, value_shape), e.g.("Lagrange", 1)or("DG", 0, (3,)).- coeffscsdl.Variable or array_like
Coefficients in FE dof order, either flat
(n_scalar_dofs * bs,)or(n_scalar_dofs, *value_shape). Stored flat, in the interleaved block layoutFunction(V).x.arrayuses.- kind{‘scalar’, ‘vector3’, ‘strain2’, ‘shear2’, ‘tensor3’}, optional
Component layout, which fixes how the components transform under a change of frame. Default
'scalar'(frame-invariant).- framendarray, optional
The frame
coeffsare expressed in:(3, 3)whenglobal_frameis True, otherwise(n_cells, 3, 3)in FE cell order.Nonemeans frame-free.- global_framebool, optional
True for a single Cartesian frame shared by every dof, False for a per-cell local frame. Default False.
- Attributes:
- coeffscsdl.Variable
Flat coefficients, FE dof order.
- spacetuple
Normalized
(family, degree, value_shape).- valuesndarray
Centroid value per cell, file cell order (see
values).
See also
hermit.interpolate,hermit.projectmove a field between spaces.
Notes
Two fields combine elementwise (
+ - * /) only when they already share a space; a plain scalar also works, but acsdl.Variablescalar must go on the right (fld * var, notvar * fld).- cell_values()
Centroid value of every cell.
- Returns:
- csdl.Variable
Shape
(n_cells, bs), in file cell order.
- eval(cells, ref_points)
Evaluate the field at reference points inside given cells.
- Parameters:
- cellsarray_like of int
Cell ids in file order, one per query point.
- ref_pointsarray_like
Reference-cell coordinates: one point broadcast to every query, or one point per query.
- Returns:
- csdl.Variable
Shape
(n_query, bs), or(n_query,)for a scalar field.
- Raises:
- ValueError
If the field is on a Quadrature space, which has no basis to tabulate.
- to_frame(target) Field
Re-express a frame-relative field in another frame.
- Parameters:
- targetarray_like
For a global-frame field, a full
(3, 3)Cartesian frame whose rows are the new basis axes in world coordinates; every dof is rotated by the same transform.For a per-cell field, the direction the in-plane
e0is aligned to: a(3,)global direction, a(3, 3)frame (row 0 is the direction), or a per-cell(n_cells, 3)/(n_cells, 3, 3)array in file cell order. The tangent plane (e2) is unchanged.
- Returns:
- Field
The same field in the new frame. A scalar or frame-free field is returned unchanged.
- Raises:
- ValueError
If a per-cell field is on a continuous (CG) space, where per-cell frames are ambiguous at shared nodes, or if a global-frame field is given anything but a full
(3, 3)frame.
See also
to_globalre-express in world x/y/z.
- to_global() Field
Re-express the field in the world x/y/z frame.
- Returns:
- Field
Equivalent to
to_frame(np.eye(3)). A scalar or frame-free field is returned unchanged.
- property V
- property block_size
- coeffs
- domain
- global_frame = False
- property is_dg
- kind = 'scalar'
- property n_dofs
- property n_scalar_dofs
- space
- property value_shape
- property values: numpy.ndarray
ndarray:
cell_values()as plain numpy – for inspection and plotting.
- class hermit.Geometry(domain, *, node_disp=None, nodes=None)
The mesh coordinate field, in any configuration
solve()accepts.Build one with
geometry(). Giving neithernode_dispnornodesselects the reference configuration and no mesh-derivative forms are built, so leaving it out costs nothing.- Parameters:
- domainShellDomain
- node_dispcsdl.Variable or array_like, optional
(n_nodes, 3)displacement added to the reference coordinates, in file vertex order. The usual shape design variable.- nodescsdl.Variable or array_like, optional
(n_nodes, 3)absolute coordinates, in file vertex order.
- Attributes:
- fieldField
The coordinates as a
("Lagrange", 1, (3,))field, for uniformity with every other input.- nodescsdl.Variable
(n_nodes, 3)file-order coordinates, the layout the FEniCSx operations consume.- is_differentiablebool
True when
node_dispornodeswas supplied.
- Raises:
- ValueError
If both
node_dispandnodesare given, or if the mesh has a higher-order (curved) coordinate element.
- domain
- field
- class hermit.Layup
Bases:
csdl_alpha.VariableGroupA laminate layup.
- Parameters:
- materialsMaterial | list[Material]
The ply materials. A single
Materialis broadcast to every ply.- anglescsdl.Variable | np.ndarray | float
Ply orientation angles in radians. A scalar is broadcast to every ply.
- heightscsdl.Variable | np.ndarray | float
Ply thicknesses. A scalar is broadcast to every ply.
- num_pliesint, optional
Number of plies. Inferred from the other arguments when omitted.
- angles: csdl_alpha.Variable | numpy.ndarray | float
- heights: csdl_alpha.Variable | numpy.ndarray | float
- materials: caddee_materials.Material | list
- num_plies: int = None
- class hermit.Loads(domain, *, traction_terms=(), moment_terms=(), pressure_terms=(), edge_traction_terms=(), edge_moment_terms=(), edge_pressure_terms=(), direct=None)
A composable bundle of load terms.
Build one with
pressure(),traction(),moment(),edge_pressure(),edge_traction(),edge_moment(),point_load()orload_vector()rather than calling this constructor directly.a + bmerges twoLoadson the same domain, concatenating the term lists and summing the direct right-hand sides.- Parameters:
- domainShellDomain
- traction_terms, moment_termssequence of Field, optional
Distributed
(3,)vector fields.- pressure_termssequence of Field, optional
Distributed scalar fields, acting along the shell normal.
- edge_traction_terms, edge_moment_terms, edge_pressure_termssequence, optional
Edge terms, each pairing a field with the exterior-facet measure it acts on.
- directcsdl.Variable, optional
A generalised right-hand side in
domain.Wdof ordering.
Examples
>>> loads = hm.pressure(domain, 2.0) + hm.point_load(domain, at=tip, force=[0, 0, -1])
- combined_moment(space=('Lagrange', 1, (3,))) hermit._field.Field | None
Sum the distributed moment terms onto one space.
- Parameters:
- spacetuple, optional
Target space. Exact when every term is already on it.
- Returns:
- Field or None
Nonewhen there are no moment terms.
- combined_traction(space=('Lagrange', 1, (3,))) hermit._field.Field | None
Sum the traction and pressure terms onto one space.
Pressure is converted to a traction with a numpy snapshot of the reference normal.
solve()does not use this – it takes each term directly, with the live normal.- Parameters:
- spacetuple, optional
Target space. Exact when every term is already on it.
- Returns:
- Field or None
Nonewhen there are no such terms.
- direct_vector(ndof=None) csdl_alpha.Variable
The combined point-load and load-vector right-hand side.
- Parameters:
- ndofint, optional
Length to use when there is no direct term. Defaults to the number of
domain.Wdofs.
- Returns:
- csdl.Variable
Shape
(ndof,)indomain.Wdof order; zeros when there is no point load or load vector.
- direct = None
- domain
- edge_moment_terms = []
- edge_pressure_terms = []
- edge_traction_terms = []
- moment_terms = []
- pressure_terms = []
- traction_terms = []
- class hermit.Material(A, B, D, As, thickness, density, *, orientation=None, E=None, nu=None, layup=None)
The constitutive input bundle consumed by the solve and the outputs.
Build one with
isotropic(),laminate(),composite()orthickness_only()rather than calling this constructor directly.- Parameters:
- A, B, DField or None
Membrane, coupling and bending stiffness, each a
(3, 3)field in the laminate’s own material axes, unrotated.Noneonly for athickness_only()material.- AsField or None
Transverse-shear stiffness, a
(2, 2)field in the(xz, yz)ordering the shell form uses.- thickness, densityField
Scalar fields, on any space.
- orientationOrientation, optional
Applied to
A/B/D/Asinside the shell form.Nonemeans no rotation, which is correct for an isotropic material.- E, nuField, optional
Isotropic constants, needed by the von Mises stress outputs.
- layupLayup, optional
The ply stack, needed by the Tsai-Wu failure outputs.
- Attributes:
- domainShellDomain
Taken from
thickness.
- E = None
- density
- property domain
- layup = None
- nu = None
- orientation = None
- thickness
- class hermit.Orientation(domain, *, kind, value)
The laminate fibre orientation carried on a
Material.Build one with
fiber_angle()orfiber_direction(). It does not rotate anything at construction time: the rotation into each element’s frame happens inside the shell form duringsolve(), and again in the Tsai-Wu failure recovery.- Parameters:
- domainShellDomain
- kind{‘angle’, ‘direction’}
Whether
valueis an in-plane angle or a global direction vector.- valueField
Scalar field of angles (rad) for
kind='angle', or a(3,)vector field forkind='direction'.
- domain
- kind
- value
- class hermit.ShellDomain(mesh, *, element='CG2CG1', cell_tags=None, regions=None, quadrature_degree=4)
Mesh, shell state space, index maps and region tags, built once.
The first object in every Hermit workflow. It carries no CSDL and no per-solve cost, so build it once and reuse it across every load case, sweep or optimizer iteration.
- Parameters:
- meshdolfinx.mesh.Mesh
A serial, straight-sided (P1 geometry) surface mesh of triangles or quadrilaterals.
- element{‘CG2CG1’, ‘CG1CG1’, ‘CG2CR1’}, optional
Displacement x rotation element pair. Default
'CG2CG1'.'CG2CR1'uses a Crouzeix-Raviart rotation that resists shear locking on thin shells, and is triangle meshes only.- cell_tagsdolfinx.mesh.MeshTags, optional
Cell tags, for per-region output integrals.
- regionsdict, optional
Maps region names to tag values, so outputs can take
region="skin".- quadrature_degreeint, optional
Degree for every integral this package pins by hand: the penalty-BC facet measures, the stress measures, the DG0
'average'field method and the oriented elastic energy. Default 4, which is deep in the converged regime for the shell integrand.
- Attributes:
- Wdolfinx.fem.FunctionSpace
The mixed state space for this domain, shared by everything downstream.
- n_nodes, n_cellsint
- node_coordsndarray
(n_nodes, 3)vertex coordinates in file order.- cell_centroidsndarray
(n_cells, 3)centroids in file order.- node_input_idx, cell_input_idxndarray
File-to-FE gather indices,
fe_order = file_order[node_input_idx].- reverse_node_idx, reverse_cell_idxndarray
Their inverses,
file_order = fe_order[reverse_node_idx].
- Raises:
- ValueError
If the mesh is not serial (its
input_global_indicesmust form a node permutation), or if CG1 / DG0 dof order does not coincide with the mesh’s own vertex / cell order.
Notes
Serial meshes only. This is a requirement of every use, not only of the shape-derivative path: an MPI-partitioned mesh raises here, before any solve.
Three coefficient orderings coexist on any mesh: file (the mesh-file vertex and cell numbering, which external arrays use), local (DOLFINx’s post-read reordering) and FE dof (per function space, indexing
Function.x.array).from_nodal()andfrom_cells()take file order and permute;from_coeffs()takes FE dof order directly.One state space per domain. DOLFINx does not treat two independently built but structurally identical function spaces as interchangeable for boundary conditions: a strong BC located against a second instance is silently dropped, with no exception and a wrong answer. Everything downstream therefore shares
domain.W.Examples
>>> domain = hm.ShellDomain(hm.read_mesh("plate.xdmf"), element="CG2CG1")
- check_cell_orientation_consistency(tol=0.0)
Verify that cell normals do not flip across shared interior facets.
Called by
pressure()andedge_pressure(), whose sign convention is only well defined on a consistently wound mesh.- Parameters:
- tolfloat, optional
Two adjacent normals are inconsistent when their dot product is at or below this. Default 0.
- Raises:
- ValueError
Naming the offending cell pair. Fix the mesh winding upstream, or use
traction(), which takes an explicit global vector.
Notes
Cheap and memoized; a no-op after the first successful call.
- dof_coords(space)
Coordinates of a space’s scalar dofs, in FE dof order.
- Parameters:
- spacetuple
(family, degree)or(family, degree, value_shape).
- Returns:
- ndarray
Shape
(n_scalar_dofs, 3). For a blocked (vector or tensor) space these are per scalar dof, not per component: all components of one dof share a coordinate.
See also
hermit.from_coeffs,hermit.from_functionbuild coefficients on this space.
- function_space(space)
The DOLFINx function space for a space descriptor.
- Parameters:
- spacetuple
(family, degree)or(family, degree, value_shape).
- Returns:
- dolfinx.fem.FunctionSpace
Memoized, one per normalized descriptor.
- local_frames()
The orthonormal local shell frame of every cell.
- Returns:
- ndarray
Shape
(n_cells, 3, 3), rowse0,e1in-plane ande2the element normal, at the reference geometry, in FE cell order. Memoized.
- local_frames_at(points, cells)
The local shell frame at chosen points inside chosen cells.
- Parameters:
- pointsarray_like
Reference-cell coordinates: one point broadcast to every query, or one point per query.
- cellsarray_like of int
Cell ids in file order.
- Returns:
- ndarray
Shape
(n, 3, 3); seelocal_frames()for the row convention.
- W
- cell_centroids
- cell_input_idx
- cell_tags = None
- element = 'CG2CG1'
- mesh
- n_cells
- n_nodes
- node_coords
- node_input_idx
- quadrature_degree = 4
- regions
- reverse_cell_idx
- reverse_node_idx
- class hermit.ShellState(domain, geometry, material, loads, bcs, *, disp_solid)
The solved shell state, and back-references to everything that produced it.
Returned by
solve(). Because it carries its own inputs, every output function inhermit.outputsneeds only the state. A surrogate solve should return one of these to be a drop-in replacement.- Parameters:
- domainShellDomain
- geometryGeometry or None
Noneis normalised to the reference configuration, sostate.geometryis neverNone.- materialMaterial
- loadsLoads
- bcsBoundaryConditions
- disp_solidcsdl.Variable
The raw mixed-space dof vector, in
domain.Wdof order.
- bcs
- disp_solid
- domain
- geometry
- loads
- material
- hermit.aggregated_stress(state, *, rho=100, m=1e-06, region=None, surface='top', quadrature_degree=None)
Smooth aggregate of isotropic von Mises stress,
(1/m) * pnorm**(1/rho).A differentiable stand-in for the peak stress, suitable as an optimizer constraint.
- Parameters:
- stateShellState
- rhofloat, optional
Aggregation exponent. Default 100.
- mfloat, optional
Stress scaling; see
pnorm_stress(). Default 1e-6.- regionstr or int, optional
Restrict to a mesh-tagged region.
- surface{‘top’, ‘bottom’, ‘mid’}, optional
Through-thickness station. Default
'top'.- quadrature_degreeint, optional
Overrides the domain’s degree for this integral.
- Returns:
- csdl.Variable
Scalar, in stress units.
- Warns:
- UserWarning
If
mis degenerate for this problem, which would otherwise return a number that barely depends on the solution.
Notes
Approaches
max(vm)from below asrhogrows: this is the area-averaged integral p-norm, bounded above by the pointwise maximum, unlike the discrete log-sum-exp aggregatefailure_index()uses.Examples
>>> m = hm.stress_scaling(state) >>> peak = hm.aggregated_stress(state, m=m)
- hermit.as_field(domain, value, *, space=None) Field
Coerce a scalar, array or field to a
Field.This is how the rest of the API accepts a bare number or array wherever a
Fieldis expected.- Parameters:
- domainShellDomain
- valueField, float, array_like or csdl.Variable
The value to resolve.
- spacetuple, optional
Space to use for a broadcast scalar, and to test an array’s leading axis against before falling back to the per-vertex / per-cell orderings.
- Returns:
- Field
- Raises:
- ValueError
If an array’s leading axis matches neither
domain.n_nodes,domain.n_cells, nor the given space’s scalar-dof count.
Notes
Resolution order:
A
Fieldis returned unchanged (spaceis ignored – reconcile a mismatch yourself withinterpolate()orproject()).A scalar, or a length-1 array /
csdl.Variable, is broadcast withconstant()onspace(default("Lagrange", 1)).An array with a leading axis longer than 1 is read as FE dof order when it matches
space’s scalar-dof count, else as file order viafrom_nodal()(n_nodes) orfrom_cells()(n_cells).
- hermit.center_of_gravity(state)
Mass-weighted centre of gravity, in global Cartesian coordinates.
- Parameters:
- stateShellState
- Returns:
- csdl.Variable
Shape
(3,).
- hermit.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.compliance(state)
Work done by the applied loads on the solution.
- Parameters:
- stateShellState
- Returns:
- csdl.Variable
Scalar. Conjugate to the exact
Loadsobject that was solved, including edge and point terms.
- hermit.composite(domain, *, A, B, D, As, thickness, density, orientation=None, E=None, nu=None) Material
Material from pre-computed ABD stiffness fields.
Nothing is assembled here, so there is no
constitutive_spaceto choose: each field keeps whatever space it was built on.- Parameters:
- domainShellDomain
- A, B, DField or array_like
(3, 3)membrane, coupling and bending stiffness, in laminate axes.- AsField or array_like
(2, 2)transverse-shear stiffness,(xz, yz)ordering.- thickness, densityField, float or array_like
- orientationOrientation, optional
Rotates the supplied ABD into each element’s frame inside the shell form.
- E, nuField, float or array_like, optional
Supply these to enable the isotropic von Mises stress outputs.
- Returns:
- Material
Notes
The result carries no
layup, so the Tsai-Wu outputs (failure_index(),failure_field()) do not work on it. Those needlaminate(), which knows the ply stack the criterion is evaluated over.
- hermit.constant(domain, space, value) Field
Build a uniform field by broadcasting one value to every dof.
- Parameters:
- domainShellDomain
- spacetuple
(family, degree)or(family, degree, value_shape).- valuefloat, array_like or csdl.Variable
A scalar, or a value of the space’s
value_shape. Stays differentiable when it is acsdl.Variable.
- Returns:
- Field
- hermit.displacement_field(state)
Mid-surface displacement as a field.
- Parameters:
- stateShellState
- Returns:
- Field
(3,)vector field on the displacement subspace of the element, in global Cartesian components.
See also
nodal_displacementthe same quantity at mesh vertices, in file order.
- hermit.edge_moment(domain, m, *, where, space=('Lagrange', 1)) Loads
Moment per unit length on selected exterior facets.
- Parameters:
- domainShellDomain
- mField or array_like
A
(3,)global vector, or aFieldof(3,)vectors.- wherecallable
Coordinate predicate selecting the loaded edge; see
edge_traction().- spacetuple, optional
Space for a non-
Fieldvalue. Default("Lagrange", 1).
- Returns:
- Loads
- Raises:
- ValueError
If
mdoes not resolve to a(3,)vector field.
- hermit.edge_pressure(domain, p, *, where, space=('DG', 0)) Loads
Pressure per unit length along the shell normal, on selected exterior facets.
- Parameters:
- domainShellDomain
- pField, float or array_like
Scalar pressure; positive acts along
+n.- wherecallable
Coordinate predicate selecting the loaded edge; see
edge_traction().- spacetuple, optional
Space for a non-
Fieldvalue. Default("DG", 0).
- Returns:
- Loads
- Raises:
- ValueError
If
spaceis not scalar, or if the domain’s cell normals are not consistently oriented.
- hermit.edge_traction(domain, t, *, where, space=('Lagrange', 1)) Loads
Force per unit length on selected exterior facets.
- Parameters:
- domainShellDomain
- tField or array_like
A
(3,)global vector, or aFieldof(3,)vectors.- wherecallable
Coordinate predicate selecting the loaded edge, with the same contract as
clamp(): it receives a(3, N)coordinate array and returns an(N,)boolean mask. Only exterior facets are selected.- spacetuple, optional
Space for a non-
Fieldvalue. Default("Lagrange", 1).
- Returns:
- Loads
- Raises:
- ValueError
If
tdoes not resolve to a(3,)vector field.
Examples
>>> tip = hm.edge_traction(domain, [0.0, 0.0, -1.0], where=hm.near("x", 10.0))
- hermit.elastic_energy(state)
Stored shell strain energy.
- Parameters:
- stateShellState
- Returns:
- csdl.Variable
Scalar. For a linear solve this is half the compliance, up to the round-off of the direct solve.
- Raises:
- ValueError
If the material carries no
A/B/D/As(athickness_only()material).
- hermit.failure_field(state, *, sampling='average')
Per-cell, per-ply-face Tsai-Wu failure indices.
- Parameters:
- stateShellState
- sampling{‘average’, ‘midpoint’}, optional
How the DG0 strain measures are sampled per cell. Default
'average'.
- Returns:
- Field
DG0 field with one component per ply face.
- Raises:
- ValueError
If the material carries no layup. Only
laminate()sets one.
- hermit.failure_index(state, *, rho=100, sampling='average')
KS-aggregated Tsai-Wu failure index over the whole laminate.
- Parameters:
- stateShellState
- rhofloat, optional
KS aggregation exponent. Default 100.
- sampling{‘average’, ‘midpoint’}, optional
How the DG0 strain measures are sampled per cell. Default
'average'.
- Returns:
- csdl.Variable
Scalar. Below 1 means no ply face has failed; the log-sum-exp KS aggregate bounds the true maximum from above.
- Raises:
- ValueError
If the material carries no layup. Only
laminate()sets one.
- hermit.fiber_angle(domain, angle) Orientation
Orientation given as an angle from each element’s own in-plane axis.
- Parameters:
- domainShellDomain
- angleField, float or array_like
Angle in radians from the element’s
e0to the fibre direction, on any space. Acsdl.Variablemakes it a differentiable design field.
- Returns:
- Orientation
- Raises:
- ValueError
If
angleis not a scalar field.
See also
fiber_directionorientation given as a global direction.
Notes
The angle is measured from
e0, which follows the mesh parametrisation. On a mesh wheree0is not uniform, a continuous (CG) angle field makes the physical fibre direction kink slightly at element interfaces – fine on a flat or structured mesh, otherwise preferfiber_direction().
- hermit.fiber_direction(domain, direction) Orientation
Orientation given as a global fibre direction.
- Parameters:
- domainShellDomain
- directionField or array_like
A
(3,)global vector, or aFieldof(3,)vectors on any space (e.g. a per-cell curvilinear fibre path).
- Returns:
- Orientation
- Raises:
- ValueError
If
directionis not a(3,)vector field.
See also
fiber_angleorientation given as an element-relative angle.
Notes
The shell form projects the direction into each element’s tangent plane and never forms the angle explicitly, so there is no branch cut. The projection is degenerate only where
directionis parallel to the shell normal, which is detected when concrete values reach the form.
- hermit.field_fn(*args, fn=None) Field
Apply a function to the coefficients of one or more fields.
- Parameters:
- *argsField
Operands, all on the same domain and the same space.
fnmay be passed as the last positional argument instead of as a keyword.- fncallable
Applied to the operands’ flat
coeffs, one argument per field.
- Returns:
- Field
On the shared space.
kind/frame/global_framecarry through only when every operand agrees, otherwise the result is scalar and frame-free.
- Raises:
- ValueError
If no operand is given, or if the operands are on different domains or different spaces. Use
interpolate()orproject()to reconcile spaces first; there is no implicit coercion.- TypeError
If an operand is not a
Field.
Examples
>>> total = field_fn(a, b, fn=lambda x, y: x + y)
- hermit.from_cells(domain, values) Field
Build a DG0 field from per-cell values in mesh-file order.
- Parameters:
- domainShellDomain
- valuescsdl.Variable or array_like
Shape
(n_cells,)or(n_cells, k), in file cell order.
- Returns:
- Field
On
("DG", 0)or("DG", 0, (k,)). The file-to-FE permutation is applied as a CSDL gather, so acsdl.Variableinput stays differentiable.
- Raises:
- ValueError
If the leading axis is not
domain.n_cells.
See also
from_nodalthe per-vertex (CG1) counterpart.
- hermit.from_coeffs(domain, space, coeffs, *, kind='scalar', frame=None, global_frame=False) Field
Build a field from raw coefficients in FE dof order.
The explicit way to say “these are FE dof coefficients”; pair it with
dof_coords()to know where each dof lives.- Parameters:
- domainShellDomain
- spacetuple
(family, degree)or(family, degree, value_shape).- coeffscsdl.Variable or array_like
FE dof order, flat or
(n_scalar_dofs, *value_shape).- kind, frame, global_frame
Orientation bookkeeping; see
Field.
- Returns:
- Field
- hermit.from_function(domain, space, fn) Field
Build a field by evaluating a function at the space’s dof coordinates.
- Parameters:
- domainShellDomain
- spacetuple
(family, degree)or(family, degree, value_shape).- fncallable
Called once with the
(n_scalar_dofs, 3)dof coordinates and returning the coefficients. Returning numpy gives a constant field; returning acsdl.Variable(e.g. closing over a design variable) is passed through undisturbed and stays differentiable.
- Returns:
- Field
Notes
The sample points are the reference dof coordinates, so the result is not differentiable with respect to the geometry.
Examples
>>> taper = from_function(domain, ("Lagrange", 1), lambda x: 0.2 - 0.01 * x[:, 0])
- hermit.from_nodal(domain, values) Field
Build a CG1 field from per-vertex values in mesh-file order.
- Parameters:
- domainShellDomain
- valuescsdl.Variable or array_like
Shape
(n_nodes,)or(n_nodes, k), in file vertex order (the ordering an external geometry or CADDEE-side array uses).
- Returns:
- Field
On
("Lagrange", 1)or("Lagrange", 1, (k,)). The file-to-FE permutation is applied as a CSDL gather, so acsdl.Variableinput stays differentiable.
- Raises:
- ValueError
If the leading axis is not
domain.n_nodes.
See also
from_cellsthe per-cell (DG0) counterpart.
from_coeffswhen the array is already in FE dof order.
- hermit.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.geometry(domain, *, node_disp=None, nodes=None) Geometry
Build the geometry input for a solve.
- Parameters:
- domainShellDomain
- node_dispcsdl.Variable or array_like, optional
(n_nodes, 3)displacement from the reference coordinates, file order.- nodescsdl.Variable or array_like, optional
(n_nodes, 3)absolute coordinates, file order.
- Returns:
- Geometry
The reference configuration when neither argument is given.
Examples
>>> nd = csdl.Variable(value=np.zeros((domain.n_nodes, 3)), name="node_disp") >>> state = hm.solve(domain, mat, loads, bcs, ... geometry=hm.geometry(domain, node_disp=nd))
- hermit.interpolate(src_field, space) hermit._field.Field
Collocate a field at another space’s dof points – the default transfer.
- Parameters:
- src_fieldField
- spacetuple
Target space; its value shape must match the source’s.
- Returns:
- Field
On the target space, or
src_fielditself if already there.
- Raises:
- ValueError
If the value shapes differ, or if either space is not point-evaluation (Lagrange, DG, DQ or Quadrature). Piola-mapped families such as RT and Nedelec drag in the geometric Jacobian and are rejected, as does Crouzeix-Raviart. A Quadrature source has no basis to tabulate – use
project().
See also
projectthe geometry-dependent L2 alternative.
Notes
A constant sparse matrix, memoized per source/target pair, so this is a plain
csdl.sparse.matvec: fully differentiable in the coefficients and independent of the geometry, because the target dofs’ reference coordinates never move.
- hermit.isotropic(domain, *, E, nu, thickness, density, constitutive_space=None, orientation=None) Material
Isotropic single-layer material.
A/B/D/Asare assembled from the closed form in plain CSDL, with a 0.833 shear-correction factor.- Parameters:
- domainShellDomain
- E, nu, thickness, densityField, float or array_like
Young’s modulus, Poisson’s ratio, shell thickness and mass density. Each may be a scalar (broadcast), a per-vertex / per-cell array, or a
Fieldon its own space. Acsdl.Variablemakes it a design variable.- constitutive_spacetuple, optional
Space the ABD fields are evaluated on. Defaults to
("DG", d)wheredis the highest degree amongE,nuandthickness.- orientationOrientation, optional
Accepted and ignored – an isotropic in-plane stiffness has no preferred axis, so rotating it is a no-op. The parameter exists so that one orientation object can be passed uniformly to any material constructor.
- Returns:
- Material
Notes
The ABD fields are an interpolant of the closed form at the
constitutive_spacedofs, not an exact representation of it:E*tandt**3have higher polynomial degree than any fixed space carries. Raiseconstitutive_spaceif that matters for a strongly graded thickness.Examples
>>> mat = hm.isotropic(domain, E=4.32e8, nu=0.0, thickness=0.2, density=1.0)
- hermit.laminate(domain, *, layup, density, orientation=None, shear_correction=0.833, constitutive_space=None) Material
Composite material from a ply stack, via classical lamination theory.
- Parameters:
- domainShellDomain
- layupLayup
The ply stack (materials, angles, heights). Its angles and heights may be
csdl.Variables, making the ABD differentiable in the layup.- densityField, float or array_like
Mass density.
- orientationOrientation, optional
Rotates the laminate axes into each element’s frame inside the shell form. Without it the laminate 0-degree axis is taken to be the element
e0.- shear_correctionfloat, optional
Multiplies the CLT transverse-shear stiffness. Default 0.833, the same factor
isotropic()applies.- constitutive_spacetuple, optional
Space the ABD fields are broadcast onto. Defaults to
("DG", d)wheredis the highest degree amongdensityandorientation.
- Returns:
- Material
Carrying
layup, sofailure_index()andfailure_field()work on the resulting state.
Notes
One layup is broadcast uniformly to every cell; spatial variation of the stack itself is not part of this API. Use
composite()with per-point ABD fields for that.Examples
>>> layup = hm.Layup(ud, np.radians([0.0, 90.0, 0.0]), np.full(3, 0.002)) >>> mat = hm.laminate(domain, layup=layup, density=1.6e3, ... orientation=hm.fiber_direction(domain, [1.0, 0.0, 0.0]))
- hermit.load_vector(domain, vec) Loads
A generalised right-hand side given directly in state-space dof order.
- Parameters:
- domainShellDomain
- veccsdl.Variable or array_like
One entry per
domain.Wdof, in that space’s dof ordering.
- Returns:
- Loads
- Raises:
- ValueError
If
vecdoes not have exactlydomain.W’s dof count.
- hermit.mass(state)
Structural mass,
int density * thickness dx.- Parameters:
- stateShellState
- Returns:
- csdl.Variable
Scalar.
- hermit.moment(domain, m, *, space=('Lagrange', 1)) Loads
Distributed moment per unit area, in global components.
Contributes
int m . dtheta dxto the residual.- Parameters:
- domainShellDomain
- mField or array_like
A
(3,)global vector, or aFieldof(3,)vectors.- spacetuple, optional
Space for a non-
Fieldvalue. Default("Lagrange", 1).
- Returns:
- Loads
- Raises:
- ValueError
If
mdoes not resolve to a(3,)vector field.
- hermit.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.nodal_displacement(state)
Displacements at the mesh vertices.
- Parameters:
- stateShellState
- Returns:
- csdl.Variable
Shape
(n_nodes, 3), in file vertex order – the ordering an external geometry pipeline uses.
- hermit.nodal_rotation(state)
Director rotations at the mesh vertices.
- Parameters:
- stateShellState
- Returns:
- csdl.Variable
Shape
(n_nodes, 3), in file vertex order.
- hermit.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.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.pnorm_stress(state, *, rho=100, m=1e-06, region=None, surface='top', quadrature_degree=None)
Area-normalized p-norm stress integral,
(1/A) int (m*vm)**rho dx.- Parameters:
- stateShellState
- rhofloat, optional
Aggregation exponent. Default 100.
- mfloat, optional
Stress scaling; see Notes. Default 1e-6.
- regionstr or int, optional
Restrict the integral to a mesh-tagged region. Needs a domain built with
cell_tags=andregions=.- surface{‘top’, ‘bottom’, ‘mid’}, optional
Through-thickness station the stress is recovered at. Default
'top'.- quadrature_degreeint, optional
Overrides the domain’s degree for this integral.
- Returns:
- csdl.Variable
Scalar.
- Raises:
- ValueError
If the material carries no
Eandnu(stress recovery is isotropic-only – usefailure_index()for laminates), or ifregion=is given without mesh tags.- KeyError
If
regionis not among the mesh tags.
See also
aggregated_stressthe same quantity reduced back to stress units.
Notes
mis a problem-specific scaling, not a smoothing knob. It enters as(m*vm)**rho, so it must putm*max(vm)near 1 or the integrand runs off the end of double precision: with the defaultmand a peak von Mises of 1.4e4,(m*vm)**100is 1e-186. Usestress_scaling()to compute one.mmust also be constant with respect to the design variables. It is not differentiated and cancels out of the aggregate exactly; recomputing it inside the recorded graph each optimizer iteration silently makes the reported derivative wrong.
- hermit.point_load(domain, *, at, force=None, moment=None) Loads
A consistent point force and/or moment at a physical coordinate.
The cell containing
atis located, the state-space basis is evaluated there, and the result is scattered into the direct right-hand side – the weak form of a Dirac delta,int F . delta(x - at) . du dx = F . du(at). The point need not be a mesh vertex.- Parameters:
- domainShellDomain
- atarray_like
Physical coordinate, shape
(3,).- forcecsdl.Variable or array_like, optional
(3,)point force.- momentcsdl.Variable or array_like, optional
(3,)point moment.
- Returns:
- Loads
- Raises:
- ValueError
If neither
forcenormomentis given, or ifatlies in no cell.
Notes
Differentiable in
forceandmoment, but not inator the mesh coordinates: the containing cell is fixed at construction.
- hermit.pressure(domain, p, *, space=('DG', 0)) Loads
Scalar pressure acting along the shell normal.
Positive
pacts along+n. The residual uses the liveufl.CellNormal, so the load is differentiable with respect to the mesh coordinates.- Parameters:
- domainShellDomain
- pField, float or array_like
Scalar pressure.
- spacetuple, optional
Space for a non-
Fieldvalue. Default("DG", 0).
- Returns:
- Loads
- Raises:
- ValueError
If
spaceis not scalar, or if the domain’s cell normals are not consistently oriented. On a badly-wound imported mesh a uniform pressure would otherwise become a sign-alternating load with no other symptom.
See also
tractionan explicit global vector, independent of the normal.
- hermit.project(src_field, space, *, geometry=None) hermit._field.Field
L2-project a field onto another space,
M c = int(phi_target . src) dx.- Parameters:
- src_fieldField
- spacetuple
Target space; its value shape must match the source’s.
- geometryGeometry, ndarray or csdl.Variable, optional
Defaults to the domain’s reference coordinates, which lets the mass-matrix factorization be cached across calls. Passing a live geometry enables the shape-derivative branch.
- Returns:
- Field
On the target space. Projecting onto the same space is the identity up to solver round-off.
- Raises:
- ValueError
If the value shapes differ, if
geometrybelongs to another domain, or if the source and target Quadrature degrees disagree.
Notes
Both sides carry
dx, so unlikeinterpolate()this depends on the geometry. It is a custom operation with a mass-matrix quotient-rule VJP, reverse mode only: one cotangent solve per call, never a dense Jacobian.
- hermit.read_mesh(path, name='Grid')
Read a mesh from an XDMF file.
- Parameters:
- pathstr or pathlib.Path
- namestr, optional
Grid name inside the file. Default
"Grid".
- Returns:
- dolfinx.mesh.Mesh
Read on
MPI.COMM_WORLD. Run serially –ShellDomainrequires a serial mesh.
Examples
>>> domain = hm.ShellDomain(hm.read_mesh("plate.xdmf"))
- hermit.rotation_field(state)
Director rotation as a field.
- Parameters:
- stateShellState
- Returns:
- Field
(3,)vector field on the rotation subspace of the element, in global Cartesian components.
- hermit.solve(domain, material, loads, bcs, *, geometry=None) ShellState
Solve the linear shell problem.
- Parameters:
- domainShellDomain
- materialMaterial
Must carry
A/B/D/As; athickness_only()material is surrogate-only.- loadsLoads
- bcsBoundaryConditions
- geometryGeometry, optional
Defaults to the reference configuration. Pass
hm.geometry(domain, node_disp=...)to make the mesh coordinates a differentiable input.
- Returns:
- ShellState
- Raises:
- ValueError
If
material,loadsorbcswas built against a differentShellDomain, or if the material has no ABD stiffness.
Notes
The formulation is linear and the solve is a direct MUMPS factorization, wrapped as a CSDL implicit custom operation. Because the shell tangent is symmetric, one factorization serves both the forward solve and the adjoint.
Every input must be built against this exact
domain. DOLFINx silently drops a boundary condition located against a structurally identical but distinct function space, so this is checked rather than assumed.solveis swappable: anyCallable[(domain, material, loads, bcs), ShellState]is a drop-in surrogate, and the output functions consume its result unchanged.Examples
>>> state = hm.solve(domain, material, hm.pressure(domain, 2.0), ... hm.clamp(domain, where=hm.near("x", 0.0)))
- hermit.strain_fields(state, *, space=('DG', 2), method='project', frame=None)
Membrane strain, bending curvature and transverse shear.
- Parameters:
- stateShellState
- spacetuple, optional
Target space for all three fields. Default
("DG", 2).- method{‘project’, ‘interpolate’, ‘average’}, optional
Recovery method.
'average'is the DG0 cell average. Default'project'.- frame{‘local’, ‘global’}, optional
Component frame. Defaults to the element-local in-plane frame on a DG space, and to global Cartesian on a CG space, where per-cell frames would be ambiguous at shared nodes.
- Returns:
- tuple of Field
(mid_strain, curvature, shear_strain). The component layout follows the frame: in the element-local frame the first two are in-plane engineering Voigt[xx, yy, 2xy]and the third is[xz, yz]; in the global frame they become full symmetric tensors,[xx, yy, zz, 2yz, 2xz, 2xy]and a 3-vector.
- Raises:
- ValueError
If
methodorframeis not one of the accepted values, or if a local frame is requested on a continuous (CG) space.
See also
hermit.Field.to_frame,hermit.Field.to_globalre-express the components.
Examples
>>> eps, kappa, gamma = hm.strain_fields(state) >>> kappa_global = kappa.to_global().values
- hermit.stress_field(state, *, space=('DG', 2), method='project', surface='top')
Isotropic von Mises stress field.
- Parameters:
- stateShellState
- spacetuple, optional
Target space. Default
("DG", 2).- method{‘project’, ‘interpolate’, ‘average’}, optional
Recovery method. Default
'project'.- surface{‘top’, ‘bottom’, ‘mid’}, optional
Through-thickness station. Default
'top'.
- Returns:
- Field
Scalar field.
- Raises:
- ValueError
If the material carries no
Eandnu; von Mises recovery is isotropic-only.composite()acceptsE=/nu=for this.
- hermit.stress_scaling(state, *, surface='top', space=('DG', 2), method='project')
Suggest the stress scaling
m = 1 / max|von Mises|for the aggregates.- Parameters:
- stateShellState
- surface{‘top’, ‘bottom’, ‘mid’}, optional
Through-thickness station. Default
'top'.- spacetuple, optional
Space the stress field is recovered on. Default
("DG", 2).- method{‘project’, ‘interpolate’, ‘average’}, optional
Field recovery method. Default
'project'.
- Returns:
- float
A plain Python float, deliberately: it is a snapshot taken outside the differentiated path, so it cannot contaminate the derivative of
aggregated_stress().
- Raises:
- ValueError
If the stress field has no value (run under an inline
csdl.Recorder), or if the peak is not finite and positive.
Notes
Costs one extra stress-field assembly. Call it once when setting a problem up, not inside an optimizer loop – a design-dependent
mmakes the reported gradient wrong even though the value looks better scaled.
- hermit.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])
- hermit.thickness_only(domain, *, thickness, density) Material
Thickness and density only, for a surrogate solve.
AthroughAsstayNone, sosolve()rejects this material: it is for a surrogate that carries its own constitutive model but still needsmass()andcenter_of_gravity().- Parameters:
- domainShellDomain
- thickness, densityField, float or array_like
- Returns:
- Material
- hermit.traction(domain, t, *, space=('Lagrange', 1)) Loads
Distributed force per unit area, in global components.
Contributes
int t . du dxto the residual. Unlikepressure()this never touches the shell normal, so it is the right choice for a body force such as self weight on a curved surface.- Parameters:
- domainShellDomain
- tField or array_like
A
(3,)global vector, or aFieldof(3,)vectors.- spacetuple, optional
Space for a non-
Fieldvalue. Default("Lagrange", 1).
- Returns:
- Loads
- Raises:
- ValueError
If
tdoes not resolve to a(3,)vector field.
See also
pressurea scalar load following the shell normal.
edge_tractionthe same load on selected exterior facets.