hermit.fenics.shell_pde
ShellPDE – function spaces + UFL form factories for the R-M shell.
Pure FEniCSx (DOLFINx 0.9 / 0.11), no CSDL. Port of rm_shell_pde_composite.py (femo
dev_coupling), unified ABD backend. The argument functions live on the object so the
custom operations can update them by array between assemblies.
Classes
|
Module Contents
- class hermit.fenics.shell_pde.ShellPDE(mesh, element='CG2CG1', element_wise_material=False, elementwise_pressure=False, W=None, quadrature_degree=4)
W=, given, is an existing mixed state space to reuse instead of building a freshstate_space(mesh, element)–hm.solve(viahermit._solve._pde_for) passesdomain.Where so the residual / BCs / ops it builds all share the oneFunctionSpaceobject aBoundaryConditionswas compiled against (a strongDirichletBClocated against a structurally identical but distinctFunctionSpaceis silently dropped, not an error).- area_form(measure=ufl.dx)
- cg_forms(thickness=None, density=None)
Mass moments, optionally from arbitrary-space coefficients (else the fixed
density/hforms).
- coefficient(name, space) dolfinx.fem.Function
Persistent
Functionfornameonspace, memoised by(name, normalized space)– repeated calls with the same arguments return the exact same object. That matters: a residual form built against oneFunctioninstance is wrong (or raises, for a strong BC – seeShellDomain’s class docstring) if later evaluated with a different instance, and the custom ops write into the coefficient by array every solve, so it must be the one the compiled form actually references.General seam for any per-mesh input field a form needs as a UFL coefficient on a space the caller picks (materials, loads, orientation, …) rather than one of the PDE’s fixed-space attributes (
self.A/self.h/ …).
- compliance_form(loads=None)
loads=None(default) – the work conjugate of the fixedself.f/self.mVF-space coefficients.loads, given, is the same(kind, Function)listresidual_formtakes – the matching compliance term per load kind (inner(u, f)/inner(theta, m)/p * dot(n, u)), so this stays the exact work conjugate ofresidual_form’s distributed terms (every load kind must contribute both a residual term and a compliance term, or the two drift apart silently). Thepoint_load/load_vectordirect-RHS contribution is not included here (it has no distributed form) – callers addcsdl.vdot(direct, w).
- elastic_energy_form(orientation=None, material=None)
- elastic_model(w=None, orientation=None, material=None)
orientationis(name, Function)withnamein("fiber_angle", "fiber_direction"), orNone. The no-orientation path reuses the memoisedElasticModel(bit-identical to the unoriented form); an oriented call always builds a fresh one – it is only built once perShellSolveOp/ShellScalarFormsOpconstruction (themselves memoised by the structural form cache), so there is nothing to gain by caching it too.material, given, is a(A, B, D, As)tuple ofFunctions overriding the PDE’s own fixed-spaceself.A/self.B/self.D/self.As: a caller-chosenconstitutive_space(any space, viacoefficient()) reaches the solve instead of only the fixedVABD/VAsspaceelement_wise_materialpicks.None(default) keeps the fixed-space attrs – also why thematerial=Noneunoriented path is the only one eligible for theself._elasticmemo (amaterial=override is only ever built once per op anyway, same as an oriented call).
- force_to_pressure_matrix()
VF consistent mass matrix M such that M @ pressure = consistent nodal force.
- mass_form(thickness=None, density=None)
thickness=None/density=None(default) use the fixed-spaceself.h/self.density. Given, they override with an arbitrary-spaceFunction(fromcoefficient()).
- pnorm_stress_form(dx_measure, m=1e-06, rho=100.0, surface='top', thickness=None, E=None, nu=None)
- residual_form(penalty=True, dss=None, dSS=None, bc_dof_mask=None, penalty_terms=None, penalty_targets=None, orientation=None, material=None, loads=None)
penalty_terms, given, is a list of(dss, dSS, bc_dof_mask)triples whose penalty contributions are summed – multi-region penalty (hm.clamp(...) + hm.symmetry(...)); with it omitted (the common case) this is exactly the single(dss, dSS, bc_dof_mask)triple.orientationis(name, Function),materialis(A, B, D, As)Functions – seeelastic_model().loads, given, is a list of(kind, Function)pairs (kindin"traction"/"moment"/"pressure"): each term gets its own residual contribution on its own space, viaElasticModel.weak_residual’sload_terms(instead of the fixedself.f/self.mVF-space coefficients this method uses withloads=None, the default). An empty list is valid (e.g. a point-load-onlyLoadshas no distributed term at all) – onlyNoneselects the fixedf/mpath.
- restore_geometry() None
- set_geometry(mesh_nodes) None
Write
mesh.geometry.xfrom user-ordered node coords (n_nodes, gdim).
- von_mises_form(surface='top', thickness=None, E=None, nu=None)
- As
- E
- VABD
- VAs
- VF
- VT
- W
- X
- density
- f
- g
- gdim
- h
- m
- mesh
- nu
- quadrature_degree = 4
- w
- x_ref