hermit.fenics.kinematics ======================== .. py:module:: hermit.fenics.kinematics .. autoapi-nested-parse:: Basis transformations and Voigt notation for the R-M shell. Ported from ``femo_alpha/rm_shell/linear_shell_fenicsx/kinematics.py`` (dev_coupling). Unchanged across DOLFINx 0.9 / 0.11 -- these are pure UFL. Note there is *no* ``gradx`` / ``J`` / ``F``: geometry sensitivity comes from differentiating w.r.t. ``SpatialCoordinate`` directly, so all gradients here are plain ``ufl.grad`` on the (possibly moved) mesh. .. !! processed by numpydoc !! Functions --------- .. autoapisummary:: hermit.fenics.kinematics.congruent_transform hermit.fenics.kinematics.constant_normal_bending_curvature hermit.fenics.kinematics.global_to_local_inplane hermit.fenics.kinematics.gradv_local hermit.fenics.kinematics.local_basis_inplane hermit.fenics.kinematics.membrane_strain hermit.fenics.kinematics.orientation_cos_sin hermit.fenics.kinematics.shear_rotation hermit.fenics.kinematics.strain2D_local_to_global hermit.fenics.kinematics.strain_rotation hermit.fenics.kinematics.unit hermit.fenics.kinematics.vec2D_local_to_global hermit.fenics.kinematics.voigt2D hermit.fenics.kinematics.voigt3D Module Contents --------------- .. py:function:: congruent_transform(T, X) ``T^T X T`` for square UFL matrices (``T`` orthogonal, ``X`` symmetric) -- rotates a laminate-axes constitutive matrix into the element frame, ``A_element = Teps^T A Teps`` (and ``As_element = R^T As R``). Index notation (not ``ufl.transpose(T) * X * T``) so it is unambiguous for any square size. .. !! processed by numpydoc !! .. py:function:: constant_normal_bending_curvature(theta, E01) Shallow-shell curvature with the cell normal held constant. Only the rotation gradient enters. In particular, a rigid rotation is a constant ``theta`` and therefore has zero curvature structurally, including on a warped quadrilateral cell. .. !! processed by numpydoc !! .. py:function:: global_to_local_inplane(E0, E1) 2x3 change-of-basis matrix T; T[i, j] is the j-th component of the i-th basis vector. .. !! processed by numpydoc !! .. py:function:: gradv_local(gradv_global, T) In-plane components of a rank-2 tensor in the local orthonormal frame. .. !! processed by numpydoc !! .. py:function:: local_basis_inplane(mesh) Local orthonormal shell basis (E0, E1 in-plane; E2 = element normal). E0 is aligned with the 0-th parametric coordinate direction. .. !! processed by numpydoc !! .. py:function:: membrane_strain(u_mid, E01) Mid-surface membrane strain in the local in-plane frame. .. !! processed by numpydoc !! .. py:function:: orientation_cos_sin(fiber_angle, fiber_direction, E0, E1, E2) ``(cos theta, sin theta)`` of the in-plane angle from the element ``E0`` to the fibre direction -- from ``fiber_angle`` directly, or projected from a global ``fiber_direction`` vector (no ``atan2``: it is more expensive and puts a branch cut at +/-pi right in the differentiated path). Exactly one of ``fiber_angle`` / ``fiber_direction`` must be given. Degenerate only when ``fiber_direction`` is parallel to the shell normal ``E2`` (the tangent-plane projection vanishes) -- a UFL expression cannot raise, so callers must guard that numerically, with concrete values, before building the form. .. !! processed by numpydoc !! .. py:function:: shear_rotation(c, s) R(theta) -- 2x2 transverse-shear rotation, element -> laminate axes, standard FSDT Voigt (xz, yz) ordering: ``gam_L = R @ gamma``. .. !! processed by numpydoc !! .. py:function:: strain2D_local_to_global(strain_local, T) 2x2 local in-plane strain -> 3x3 global Cartesian tensor. .. !! processed by numpydoc !! .. py:function:: strain_rotation(c, s) Teps(theta) -- 3x3 engineering-Voigt in-plane strain/curvature rotation, element -> laminate axes: ``eps_L = Teps @ voigt2D(eps)``. ``Teps^T == Tsig^-1`` for this convention (the identity ``hermit.csdl_helpers.rotate_abd`` also uses). .. !! processed by numpydoc !! .. py:function:: unit(v) Normalize the vector ``v``. .. !! processed by numpydoc !! .. py:function:: vec2D_local_to_global(v_local, T) length-2 local in-plane vector -> length-3 global Cartesian vector. .. !! processed by numpydoc !! .. py:function:: voigt2D(T, strain=True) 2x2 symmetric tensor -> Voigt vector. ``strain`` doubles the shear component. .. !! processed by numpydoc !! .. py:function:: voigt3D(T, strain=True) 3x3 symmetric tensor -> length-6 Voigt vector ``[xx, yy, zz, yz, xz, xy]``. ``strain`` doubles the three shear components (engineering convention, matching :func:`voigt2D`). .. !! processed by numpydoc !!