hermit.material

Material + Orientation – the constitutive input bundle.

A Material bundles the Field objects the residual and the mass / stress / failure outputs consume. The constitutive tensors are stored in the laminate’s own material axes, unrotated: the rotation into each element’s frame happens inside the shell form, so there is no space restriction on any of these fields – A/B/D/As and orientation may each live on their own space.

Classes

Material

The constitutive input bundle consumed by the solve and the outputs.

Orientation

The laminate fibre orientation carried on a Material.

Functions

composite(→ Material)

Material from pre-computed ABD stiffness fields.

fiber_angle(→ Orientation)

Orientation given as an angle from each element's own in-plane axis.

fiber_direction(→ Orientation)

Orientation given as a global fibre direction.

isotropic(→ Material)

Isotropic single-layer material.

laminate(→ Material)

Composite material from a ply stack, via classical lamination theory.

thickness_only(→ Material)

Thickness and density only, for a surrogate solve.

Module Contents

class hermit.material.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() or thickness_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. None only for a thickness_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/As inside the shell form. None means 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.material.Orientation(domain, *, kind, value)

The laminate fibre orientation carried on a Material.

Build one with fiber_angle() or fiber_direction(). It does not rotate anything at construction time: the rotation into each element’s frame happens inside the shell form during solve(), and again in the Tsai-Wu failure recovery.

Parameters:
domainShellDomain
kind{‘angle’, ‘direction’}

Whether value is an in-plane angle or a global direction vector.

valueField

Scalar field of angles (rad) for kind='angle', or a (3,) vector field for kind='direction'.

domain
kind
value
hermit.material.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_space to 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 need laminate(), which knows the ply stack the criterion is evaluated over.

hermit.material.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 e0 to the fibre direction, on any space. A csdl.Variable makes it a differentiable design field.

Returns:
Orientation
Raises:
ValueError

If angle is not a scalar field.

See also

fiber_direction

orientation given as a global direction.

Notes

The angle is measured from e0, which follows the mesh parametrisation. On a mesh where e0 is 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 prefer fiber_direction().

hermit.material.fiber_direction(domain, direction) → Orientation

Orientation given as a global fibre direction.

Parameters:
domainShellDomain
directionField or array_like

A (3,) global vector, or a Field of (3,) vectors on any space (e.g. a per-cell curvilinear fibre path).

Returns:
Orientation
Raises:
ValueError

If direction is not a (3,) vector field.

See also

fiber_angle

orientation 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 direction is parallel to the shell normal, which is detected when concrete values reach the form.

hermit.material.isotropic(domain, *, E, nu, thickness, density, constitutive_space=None, orientation=None) → Material

Isotropic single-layer material.

A/B/D/As are 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 Field on its own space. A csdl.Variable makes it a design variable.

constitutive_spacetuple, optional

Space the ABD fields are evaluated on. Defaults to ("DG", d) where d is the highest degree among E, nu and thickness.

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_space dofs, not an exact representation of it: E*t and t**3 have higher polynomial degree than any fixed space carries. Raise constitutive_space if 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.material.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) where d is the highest degree among density and orientation.

Returns:
Material

Carrying layup, so failure_index() and failure_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.material.thickness_only(domain, *, thickness, density) → Material

Thickness and density only, for a surrogate solve.

A through As stay None, so solve() rejects this material: it is for a surrogate that carries its own constitutive model but still needs mass() and center_of_gravity().

Parameters:
domainShellDomain
thickness, densityField, float or array_like
Returns:
Material