Materials ========= Material properties are set with :meth:`femorph_solver.Model.mp`, the direct analogue of MAPDL's ``MP`` command. Every property is a scalar attached to a material id; an element references its material by stamping a ``MAT`` id with :meth:`~femorph_solver.Model.mat` before :meth:`~femorph_solver.Model.e` creates it. MP -- .. code-block:: python m = femorph_solver.Model() m.mp("EX", 1, 2.1e11) # Young's modulus (Pa) m.mp("PRXY", 1, 0.30) # Poisson ratio m.mp("DENS", 1, 7850.0) # density (kg/m^3) The first argument is the property name, the second is the material id, the third is the scalar value. Units are whatever's consistent across ``EX``, the element geometry, and any forces — femorph-solver does not track units. Supported properties -------------------- The :class:`femorph_solver.MaterialProperty` enum enumerates every property name femorph-solver's element kernels currently look up. Accepting the enum member or the raw string is equivalent: .. list-table:: :widths: 15 55 30 :header-rows: 1 * - Token - Meaning - Used by * - ``EX`` - Young's modulus - All solids, beams, shells, plane, truss. * - ``PRXY`` - Poisson's ratio (isotropic) - All solids, beams, shells, plane. * - ``DENS`` - Mass density - Every element that contributes to :math:`M`. * - ``GXY`` - Transverse shear modulus - Reserved for future shell / beam transverse-shear paths. * - ``ALPX`` - Thermal expansion coefficient - Reserved for future thermal-strain coupling. .. code-block:: python from femorph_solver import MaterialProperty as MP m.mp(MP.EX, 1, 2.1e11) # enum-typed — identical to "EX" Multiple materials ------------------ Assign different materials to different element groups by alternating the :meth:`~femorph_solver.Model.mat` stamp:: m.mat(1) # MAT,1 m.e(1, 2, 3, 4, 5, 6, 7, 8) # uses material 1 m.mat(2) # MAT,2 m.e(9, 10, 11, 12, 13, 14, 15, 16) # uses material 2 m.mp("EX", 1, 2.1e11) # material 1: steel-ish m.mp("PRXY", 1, 0.30) m.mp("DENS", 1, 7850.0) m.mp("EX", 2, 7.0e10) # material 2: aluminium-ish m.mp("PRXY", 2, 0.33) m.mp("DENS", 2, 2700.0) When a CDB is loaded, each element arrives with a material id already stamped; there's no additional registration step beyond calling :meth:`mp` for every ``mat_id`` that appears on the grid. Introspection ------------- The current material table is available as :attr:`Model.materials`:: m.materials # {1: {'EX': 2.1e11, 'PRXY': 0.3, 'DENS': 7850.0}, # 2: {'EX': 7.0e10, 'PRXY': 0.33, 'DENS': 2700.0}} Element kernels read the matching dict directly, so any additional scalar you stash under a known property name is visible to them — this is the extension path for per-element-class switches (e.g. ``_SOLID185_FORMULATION``; see the :doc:`SOLID185 reference `). Limitations (today) ------------------- - **Linear isotropic only.** Orthotropic / anisotropic tensors, rate dependence, plasticity, temperature-dependent curves are not yet implemented. - **Scalar per id.** Tensor-valued ``DMATRIX`` / ``ANEL`` MAPDL blocks aren't round-tripped yet; they're parsed on CDB load but ignored during assembly. See also -------- - :doc:`real-constants` — per-element-type geometric data (``R`` command). - :doc:`/user-guide/pre-processing/elements/index` — which properties each element class reads.