Source code for febio_python.core.meta_data

# from collections import namedtuple
from dataclasses import dataclass
from numpy import ndarray
from typing import Dict, Union, List


# Geometry
# ------------------------------
[docs] @dataclass class Nodes: name: str # Name of the nodes (e.g. 'NodesPart1') coordinates: ndarray[float] # 2-d array of floats, where each row is the coordinates of a node (e.g. [[0, 0, 0], [1, 0, 0]]) ids: ndarray[int] = None # If not provided, it will be inferred from the length of the coordinates list
[docs] @dataclass class Elements: name: str # Name of the element set type: str # Element type (e.g. 'tri3', 'quad4', 'tet4', 'hex8') connectivity: ndarray[int] # 2-d array of integers, where each row is the connectivity of an element (e.g. [[1, 2, 3], [2, 3, 4]]) ids: ndarray[int] = None # If not provided, it will be inferred from the length of the connectivity list mat: int = None # Required for spec 2.5, optional for later versions part: int = None # Optional for spec 3.0, required for earlier versions
[docs] @dataclass class Surfaces(Elements): pass
[docs] @dataclass class NodeSet: name: str # Name of the node set ids: ndarray[int] # Node IDs as a 1-d array of integers
[docs] @dataclass class SurfaceSet: name: str # Name of the surface set ids: ndarray[int] # Surface IDs as a 1-d array of integers
[docs] @dataclass class ElementSet: name: str # Name of the element set ids: ndarray[int] # Element IDs as a 1-d array of integers
[docs] @dataclass class DiscreteSet: name: str # Name of the discrete set src: Union[ndarray[int], str] # Source node set or surface set dst: Union[ndarray[int], str] # Destination node set or surface set dmat: int # Discrete material ID
# Materials # ------------------------------
[docs] @dataclass class Material: id: int # Material ID type: str # Material type (e.g. 'rigid body', 'neo-Hookean', 'uncoupled solid mixture') name: str # Material name (will be used to attach a domain or element set to the material) parameters: Dict[str, Union[int, float, str]] # Material parameters (e.g. {'E': 1e6, 'v': 0.3}) attributes: Dict[str, Union[int, float, str]] = None # Optional TAG attributes (e.g. {'density': 1e3})
[docs] @dataclass class DiscreteMaterial(Material): pass
# Loads # ------------------------------
[docs] @dataclass class NodalLoad: node_set: str # Name of the node set to which the load is applied load_curve: int # Load curve ID scale: Union[float, str, tuple, ndarray] # Load scale factor name: str = None # Optional name for the load dof: str = None # Degree of freedom - Will be used for spec <4 type: str = "nodal_load" # Load type (e.g. 'nodal_force', 'nodal_traction' only for spec >=4 shell_bottom: bool = False # Only for spec >=4, when type=nodal_force relative: bool = False # Only for spec >=4, when type=nodal_force def __post__(self): if self.type != "nodal_load" or self.type != "nodal_force": raise ValueError(f"Invalid type {self.type} for {self.__class__.__name__}" "Valid types are 'nodal_load' and 'nodal_force'") if self.type == "nodal_force" and not isinstance(self.scale, (tuple, ndarray)): raise ValueError(f"Invalid scale {self.scale} for {self.__class__.__name__}" "Scale must be a tuple or ndarray when type='nodal_force'") if self.type == "nodal_load" and self.dof is None: raise ValueError("dof cannot be None when type='nodal_load'")
[docs] @dataclass class SurfaceLoad: surface: str # Name of the surface to which the load is applied load_curve: int # Load curve ID scale: Union[float, str, tuple, ndarray] # Load scale factor type: str = "pressure" name: str = None # Optional name for the load linear: bool = False # Linear pressure load symmetric_stiffness: bool = True # Symmetric stiffness matrix attributes: Dict[str, Union[int, float, str]] = None # Pressure load attributes (e.g. {'lc': 1})
[docs] @dataclass class PressureLoad(SurfaceLoad): type: str = "pressure" # Default type is 'pressure' -- mainly an alias for SurfaceLoad
[docs] @dataclass class SurfaceTractionLoad(SurfaceLoad): type: str = "traction"
[docs] @dataclass class LoadCurve: id: int # Load curve ID interpolate_type: str # Interpolation type (e.g. 'linear', 'smooth', 'step') data: ndarray # Load curve data as a 2-d array (e.g. [[0, 0], [1, 1]]) extend: str = "CONSTANT" # Extend type (e.g. 'CONSTANT', 'EXTRAPOLATE')
# Boundary conditions # ------------------------------
[docs] @dataclass class BoundaryCondition: dof: str # Degree of freedom (e.g. 'x', 'y', 'z') type: str # Boundary condition type (e.g. 'fix', 'prescribe', 'rigid body', 'rigid body velocity') node_set: str = None # Name of the node set to which the boundary condition is applied surf_set: str = None # Name of the surface set to which the boundary condition is applied elem_set: str = None # Name of the element set to which the boundary condition is applied material: Union[int, str] = None # Material ID or name name: str = None # Optional name for the boundary condition attributes: Dict[str, Union[int, float, str]] = None # Optional attributes for the boundary condition tags: Dict[str, Union[int, float, str]] = None # Optional TAG attributes
[docs] @dataclass class FixCondition(BoundaryCondition): type: str = "fix" # Default type is 'fix' def __post_init__(self): if self.node_set is None: raise ValueError(f"node_set cannot be None for {self.__class__.__name__}")
[docs] @dataclass class ZeroDisplacementCondition(FixCondition): type: str = "zero displacement" # Default type is 'zero displacement' def __post_init__(self): if self.node_set is None: raise ValueError(f"node_set cannot be None for {self.__class__.__name__}")
[docs] @dataclass class ZeroShellDisplacementCondition(FixCondition): type: str = "zero shell displacement" # Default type is 'zero shell displacement' def __post_init__(self): if self.node_set is None: raise ValueError(f"node_set cannot be None for {self.__class__.__name__}")
[docs] @dataclass class RigidBodyCondition(BoundaryCondition): material: Union[int, str] # Material ID or name dof: str # Degree of freedom (e.g. 'x', 'y', 'z') name: str = None # Optional name for the boundary condition type: str = "rigid body" # Default type is 'rigid body'
# Mesh data # ------------------------------
[docs] @dataclass class NodalData: node_set: str # Name of the node set to which the data is applied name: str # Name of the data data: ndarray[float] # Data values ids: ndarray[int] = None # Node IDs, refer to the nodes in the node set (optional) data_type: str = None # Data type (e.g. 'scalar', 'vector', 'tensor')
[docs] @dataclass class SurfaceData: surf_set: str # Name of the surface set to which the data is applied name: str # Name of the data data: ndarray[float] # Data values ids: ndarray[int] = None # Surface IDs, refer to the surfaces in the surface set (optional) data_type: str = None # Data type (e.g. 'scalar', 'vector', 'tensor')
[docs] @dataclass class ElementData: elem_set: str # Name of the element set to which the data is applied name: str # Name of the data data: ndarray[float] # Data values ids: ndarray[int] = None # Element IDs, refer to the elements in the element set (optional) data_type: str = None # Data type (e.g. 'scalar', 'vector', 'tensor') var: str = None # Data variable (e.g. 'shell thickness', 'fiber density') Used for spec <4.0
# Mesh Domains # ------------------------------
[docs] @dataclass class GenericDomain: name: str # Domain name (must match at least one of the Elements of the model) mat: Union[int, str] # Material ID or name id: int = None # Domain ID tag_name: str = None # Optional tag name
[docs] @dataclass class SolidDomain(GenericDomain): tag_name: str = "SolidDomain"
[docs] @dataclass class ShellDomain(GenericDomain): type: str = "elastic-shell" # used for spec >=4 shell_normal_nodal: float = 1.0 # normal to the shell, used for spec >=4 shell_thickness: float = 0.01 # shell thickness, used for spec >=4 tag_name: str = "ShellDomain"
# ================================ # Xplt data # ================================ # Mesh parts # ------------------------------
[docs] @dataclass class XpltMeshPart: id: int # Part ID name: str # Part name
[docs] @dataclass class XpltMesh: nodes: List[Nodes] elements: List[Elements] surfaces: List[SurfaceSet] nodesets: List[NodeSet] parts: List[XpltMeshPart]
# States # ------------------------------
[docs] @dataclass class StatesDict: types: List[str] # List of state types as defined in XPLT_DATA_TYPES, e.g. scalar, vector, matrix formats: List[str] # List of state formats, e.g. node, element, surface names: List[str] # List of state names, e.g. displacement, velocity, acceleration
[docs] @dataclass class StateVariable: name: str # Name of the state variable dim: int # Dimension of the state variable (e.g. 1 for scalar, 3 for vector, 6 for symmetric matrix) dom: str # Domain to which the state variable is attached data: ndarray[float] # State variable data
[docs] @dataclass class StateData: name: str # Name of the state data dom: str # Domain to which the state data is attached data: ndarray[float] # State data
[docs] @dataclass class States: nodes: List[StateData] elements: List[StateData] surfaces: List[StateData] timesteps: ndarray[float]