hermit.domain

ShellDomain – mesh, shell state space and index maps, built once.

No CSDL, no per-evaluation cost. Carries the mixed state space W, mesh tags and regions, and the file/FE index maps the Field builders need. Deliberately does not depend on ShellPDE: the dependency runs the other way, with hermit._solve handing domain.W to the ShellPDE it caches on the domain.

Classes

ShellDomain

Mesh, shell state space, index maps and region tags, built once.

Functions

read_mesh(path[, name])

Read a mesh from an XDMF file.

Module Contents

class hermit.domain.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_indices must 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() and from_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() and edge_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_function

build 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), rows e0, e1 in-plane and e2 the 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); see local_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
hermit.domain.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 – ShellDomain requires a serial mesh.

Examples

>>> domain = hm.ShellDomain(hm.read_mesh("plate.xdmf"))