Meshes and Data

This is the content of this module.

Data Model

This is where I tell about the data model…

Data Classes

class sigmaepsilon.solid.fem.pointdata.PointData(*args, fixity: Optional[ndarray] = None, loads: Optional[ndarray] = None, mass: Optional[ndarray] = None, fields: Optional[dict] = None, **kwargs)[source]

A subclass of polymesh.pointdata.PointData to handle data related to the pointcloud of a finite element mesh.

Parameters
  • fixity (numpy.ndarray, Optional) – A 2d boolean or float array describing essential boundary conditions. Default is None.

  • loads (numpy.ndarray, Optional) – A 2d or 3d float array of nodal loads. Default is None.

  • mass (numpy.ndarray, Optional) – 2d array of nodal masses for each degree of freedom of a node. Default is None.

  • fields (dict, Optional) – Every value of this dictionary is added to the dataset. Default is None.

  • **kwargs (dict, Optional) – For every key and value pair where the value is a numpy array with a matching shape (has entries for all points), the key is considered as a field and the value is added to the database.

Examples

We will define the point-related data of a simple linear console. At the moment this means the specification of cordinates, nodal loads, and boundary conditions. The common properties of these attributes is that each of these can be best described by arrays having the same length as the pointcloud itself. Import the necessary stuff:

>>> from sigmaepsilon.solid import Structure, LineMesh, PointData
>>> from neumann.linalg import linspace, Vector
>>> from polymesh.space import StandardFrame, PointCloud, frames_of_lines
>>> import numpy as np

Define a coordinate frame, and a coordinate array,

>>> GlobalFrame = StandardFrame(dim=3)
>>> nElem = 20  # number of finite elements to use
>>> p0 = np.array([0., 0., 0.])
>>> p1 = np.array([L, 0., 0.])
>>> coords = linspace(p0, p1, nElem+1)
>>> coords = PointCloud(coords, frame=GlobalFrame).show()

two numpy arrays resembling the boundary conditions,

>>> # support at the leftmost, load at the rightmost node
>>> loads = np.zeros((coords.shape[0], 6))
>>> fixity = np.zeros((coords.shape[0], 6)).astype(bool)
>>> global_load_vector = Vector([0., 0, F], frame=GlobalFrame).show()
>>> loads[-1, :3] = global_load_vector
>>> fixity[0, :] = True

and finally we can define our dataset.

>>> pd = PointData(coords=coords, frame=GlobalFrame,
>>>                loads=loads, fixity=fixity)

See also

sigmaepsilon.solid.fem.cells.celldata.CellData, polymesh.PolyData, polymesh.CellData, awkward.Record

property dofsol: ndarray

Returns the displacement vector.

property fixity: ndarray

Returns fixity information as a 2d numpy array.

property loads: ndarray

Returns the nodal load vector.

property mass: ndarray

Retruns nodal masses.

property reactions: ndarray

Returns the vector of reaction forces.

property vshapes: ndarray

Returns the modal shapes.

class sigmaepsilon.solid.fem.cells.celldata.CellData(*args, model: Optional[ndarray] = None, activity: Optional[ndarray] = None, density: Optional[ndarray] = None, loads: Optional[ndarray] = None, fields: Optional[dict] = None, strain_loads: Optional[ndarray] = None, t: Optional[ndarray] = None, thickness: Optional[ndarray] = None, fixity: Optional[ndarray] = None, areas: Optional[ndarray] = None, **kwargs)[source]

A subclass of :class:`polymesh.celldata.CellData`to handle data related to the cells of a finite element mesh. This class does not need to be used directly, but rather serves as a base class for finite element classes.

Parameters
  • activity (numpy.ndarray, Optional) – 1d boolean array describing the activity of the elements.

  • density (numpy.ndarray, Optional) – 1d float array describing the density as mass per unit volume if areas (or thickness) are provided, mass per unit length (or area) othervise. See the Notes. Default is None.

  • loads (numpy.ndarray, Optional) – 3d (for a single load case) or 4d (for multiple load cases) float array of body loads for each load component of each node of each cell. Default is None.

  • strain_loads (numpy.ndarray, Optional) – 2d float array of body strain loads for each cell and strain component. Default is None.

  • thickness (t or) – 1d float array of thicknesses. Only for 2d cells. Default is None.

  • fixity (numpy.ndarray, Optional) – 3d boolean array of element fixity. Default is None.

  • areas (numpy.ndarray, Optional) – 1d float array of cross sectional areas. Only for 1d cells. Default is None.

  • fields (dict, Optional) – Every value of this dictionary is added to the dataset. Default is None.

  • **kwargs (dict, Optional) – For every key and value pair where the value is a numpy array with a matching shape (has entries for all points), the key is considered as a field and the value is added to the database.

Notes

For 1d and 2d cells, it is the user’s responsibility to ensure that the input data makes sense. For example, ‘areas’ can be omitted, but then ‘density’ must be ‘mass per unit length’. The same way, ‘thickness’ can be omitted for 2d cells if ‘density’ is ‘mass per unit area’. Otherwise ‘density’ is expected as ‘mass per unit volume’.

Example

All cell types are subclasses of CellData

>>> from sigmaepsilon.solid.fem.cells import B2 as Beam
>>> import numpy as np
>>> random_topo = np.zeros((10, 2), dtype=int)  # random erroneous topology
>>> random_data = np.random.rand(10, 3)
>>> celldata = Beam(topo=random_topo, random_field = random_data)

Then, the attached data is available as either

>>> celldata['random_field']

or

>>> celldata.random_field
property activity: ndarray

Returns activity of the cells.

property density: ndarray

Returns densities.

property fixity: ndarray

Returns the fixity of the cells.

property loads: ndarray

Returns body loads.

property nodes: ndarray

Returns the topology of the cells.

property strain_loads: ndarray

Returns strain loads.

Mesh Classes

class sigmaepsilon.solid.fem.mesh.FemMesh(*args, model=None, cell_fields: Optional[dict] = None, point_fields: Optional[dict] = None, **kwargs)[source]

A descendant of polymesh.PolyData to handle polygonal meshes for the Finite Element Method.

Parameters
  • pd (polymesh.PolyData or polymesh.CellData, Optional) – A PolyData or a CellData instance. Dafault is None.

  • cd (polymesh.CellData, Optional) – A CellData instance, if the first argument is provided. Dafault is None.

Note

The suggested way of usage is to create the pointdata and celldata objects in advance, and provide them as the firts argument when building the model.

Examples

>>> from sigmaepsilon.solid import FemMesh
>>> from polymesh.grid import grid
>>> size = Lx, Ly, Lz = 100, 100, 100
>>> shape = nx, ny, nz = 10, 10, 10
>>> coords, topo = grid(size=size, shape=shape, eshape='H27')
>>> pd = FemMesh(coords=coords)
>>> pd['A']['Part1'] = FemMesh(topo=topo[:10])
>>> pd['B']['Part2'] = FemMesh(topo=topo[10:-10])
>>> pd['C']['Part3'] = FemMesh(topo=topo[-10:])

See also

polymesh.PolyData, polymesh.CellData

property cd: FiniteElement

Returns the attached celldata.

See also

class

sigmaepsilon.solid.fem.cells.elem.FiniteElement

class

sigmaepsilon.solid.fem.cells.celldata.CellData

cell_dof_solution(*, squeeze: bool = True, **kwargs)

Returns degree of freedom solution for each cell or just some.

Parameters
  • cells (Iterable, Optional) – Indices of cells for which data is requested. If specified, the result is a dictionary with the indices being the keys. Default is None.

  • flatten (bool, Optional) – If True, nodal results are flattened. Default is True.

  • squeeze (bool, Optional) – If True, dummy axes are removed. This may be relevant if you only have one load case or element, but still want to have results with predictable shape. Default is True.

Returns

A dictionary if cell indices are specified, or a NumPy array.

Return type

numpy.ndarray or dict

cell_load_vector(*, squeeze: bool = True, **kwargs)

Returns the nodal load vector from body and strain loads.

Parameters
  • assemble (bool, Optional) – If True, the values are returned with a matching shape to the total system. Default is False.

  • transform (bool, Optional) – If True, local matrices are transformed to the global frame. Default is False.

Returns

The shape depends on the arguments.

Return type

numpy.ndarray

cellblocks(*args, **kwargs) Collection[FemMesh][source]

Returns an iterable over blocks with cell data.

cells_coords(*args, points: Optional[Iterable] = None, cells: Optional[Iterable] = None, **kwargs) Union[ndarray, List[ndarray]][source]

Returns the coordinates of the cells as a 3d numpy array if the subblocks form a regular mesh, or a list of such arrays.

condensate_cell_fixity() FemMesh[source]

Performs static condensation of the system equations to account for cell fixity. Returns the mesh object for continuation.

consistent_mass_matrix(*, eliminate_zeros: bool = True, sum_duplicates: bool = True, sparse: bool = False, transform: bool = True, **kwargs) Union[ndarray, coo_matrix][source]

Returns the stiffness-consistent mass matrix as a dense or a sparse matrix.

Parameters
  • sparse (bool, Optional) – If True, the result is a sparse matrix. Default is False.

  • eliminate_zeros (bool, Optional) – Eliminates zero entries. Only if ‘sparse’ is True. Default is True.

  • sum_duplicates (bool, Optional) – Sums duplicate entries. Only if ‘sparse’ is True. Default is True.

  • transform (bool, Optional) – If True, local matrices are transformed to the global frame. Default is True.

Returns

The mass matrix as a 3d dense or a 2d sparse array.

Return type

numpy.ndarray or scipy.sparse.coo_matrix

elastic_stiffness_matrix(*, eliminate_zeros: bool = True, sum_duplicates: bool = True, sparse: bool = False, transform: bool = True, **kwargs) Union[ndarray, coo_matrix][source]

Returns the elastic stiffness matrix in dense or sparse format.

Parameters
  • sparse (bool, Optional) – If True, the result is a sparse matrix. Default is False.

  • eliminate_zeros (bool, Optional) – Eliminates zero entries. Only if ‘sparse’ is True. Default is True.

  • sum_duplicates (bool, Optional) – Sums duplicate entries. Only if ‘sparse’ is True. Default is True.

  • transform (bool, Optional) – If True, local matrices are transformed to the global frame. Default is True.

Return type

numpy.ndarray or scipy.sparse.coo_matrix

element_dof_numbering() ndarray[source]

Returns global ids of the local degrees of freedoms for each cell.

element_fixity() ndarray[source]

Returns element fixity data.

essential_penalty_matrix(fixity: Optional[ndarray] = None, *, eliminate_zeros: bool = True, sum_duplicates: bool = True, penalty: float = 1000000000000.0, **kwargs) coo_matrix[source]

A penalty matrix that enforces Dirichlet boundary conditions. Returns a scipy sparse matrix in coo format.

Parameters
  • fixity (numpy.ndarray, Optional) – The fixity values as a 2d array. The length of the first axis must equal the number of nodes, the second the number of DOFs of the model. If not specified, the data is assumed to be stored in the attached pointdata with the same key. Default is None.

  • penalty (float, Optional) – The Courant-type penalty value. Default is sigmaepsilon.solid.fem.constants.DEFAULT_DIRICHLET_PENALTY.

  • eliminate_zeros (bool, Optional) – Eliminates zeros from the matrix. Default is True.

  • eliminate_zeros – Summs duplicate entries in the matrix. Default is True.

Return type

scipy.sparse.coo_matrix

external_forces(*, squeeze: bool = True, **kwargs)

Returns external forces for each cell or just some.

Parameters
  • cells (Iterable, Optional) – Indices of cells for which external forces are requested. If specified, the result is a dictionary with the indices being the keys. Default is None.

  • flatten (bool, Optional) – If True, nodal results are flattened. Default is True.

  • squeeze (bool, Optional) – If True, dummy axes are removed. This may be relevant if you only have one load case or element, but still want to have results with predictable shape. Default is True.

Returns

A dictionary if cell indices are specified, or a NumPy array.

Return type

numpy.ndarray or dict

internal_forces(*, squeeze: bool = True, **kwargs)

Returns internal forces for each cell or just some.

Parameters
  • cells (Iterable, Optional) – Indices of cells for which internal forces are requested. If specified, the result is a dictionary with the indices being the keys. Default is None.

  • flatten (bool, Optional) – If True, nodal results are flattened. Default is True.

  • squeeze (bool, Optional) – If True, dummy axes are removed. This may be relevant if you only have one load case or element, but still want to have results with predictable shape. Default is True.

Returns

A dictionary if cell indices are specified, or a NumPy array.

Return type

numpy.ndarray or dict

mass(*args, **kwargs) float[source]

Returns the total mass of the structure.

mass_matrix(*, eliminate_zeros: bool = True, sum_duplicates: bool = True, **kwargs) coo_matrix[source]

Returns the mass matrix in coo format.The resulting matrix is the sum of the consistent mass matrix and the nodal mass matrix.

Parameters
  • eliminate_zeros (bool, Optional) – Eliminates zero entries. Default is True.

  • sum_duplicates (bool, Optional) – Sums duplicate entries. Default is True.

Returns

The mass matrix in sparse COO format.

Return type

scipy.sparse.coo_matrix

masses(*args, **kwargs) ndarray[source]

Returns masses of the cells as a 1d numpy array.

material_stiffness_matrix() ndarray[source]

Returns the model of the mesh if there is any. This is not important if all the celldata in the mesh are filled up with appropriate model stiffness matrices. Otherwise, the model stiffness matrix is calcualated on the mesh level during the initialization stage and is spread among the subblocks.

property model

Returns the attached model object if there is any.

nodal_dof_solution(*, squeeze: bool = True, **kwargs)

Returns nodal degree of freedom solution.

Parameters

flatten (bool, Optional) – If True, nodal results are flattened. Default is False.

Return type

numpy.ndarray

nodal_load_vector(*, squeeze: bool = True, **kwargs)

Returns the nodal load vector.

Return type

numpy.ndarray

nodal_mass_matrix(*, eliminate_zeros: bool = False, sum_duplicates: bool = False, **kw)[source]

Returns the mass matrix from nodal masses only, in coo format.

Parameters
  • eliminate_zeros (bool, Optional) – Eliminates zero entries. Default is True.

  • sum_duplicates (bool, Optional) – Sums duplicate entries. Default is True.

Returns

The nodal mass matrix in sparse COO format.

Return type

scipy.sparse.coo_matrix

property pd: PointData

Returns the attached pointdata.

See also

class

sigmaepsilon.solid.fem.pointdata.PointData

postprocess(*args, **kwargs)[source]

General postprocessing. This may be reimplemented in subclasses, currently nothing happens here.

prostproc_dof_solution(*args, **kwargs)[source]

Calculates approximate solution of the primary variables as a list of arrays for each block in the mesh.

strains(*, squeeze: bool = True, **kwargs)

Returns strains for each cell or just some.

Parameters
  • cells (Iterable, Optional) – Indices of cells for which data is requested. If specified, the result is a dictionary with the indices being the keys. Default is None.

  • flatten (bool, Optional) – If True, nodal results are flattened. Default is True.

  • squeeze (bool, Optional) – If True, dummy axes are removed. This may be relevant if you only have one load case or element, but still want to have results with predictable shape. Default is True.

Returns

A dictionary if cell indices are specified, or a NumPy array.

Return type

numpy.ndarray or dict

stresses_at_cells_nodes(*args, **kwargs) ndarray[source]

Returns stresses at all nodes of all cells.

stresses_at_centers(*args, **kwargs) ndarray[source]

Returns stresses at the centers of all cells.

Return type

numpy.ndarray

class sigmaepsilon.solid.fem.linemesh.LineMesh(*args, areas: Optional[ndarray] = None, model: Optional[ndarray] = None, section: Optional[BeamSection] = None, **kwargs)[source]

A data class dedicated to 1d cells. It handles sections and other line related information, plotting, etc.

plot(*args, scalars=None, backend='plotly', scalar_labels=None, **kwargs)[source]

Plots the line elements using one of the supported backends.

Parameters
  • scalars (numpy.ndarray, Optional) – Data to plot. Default is None.

  • backend (str, Optional) – The backend to use for plotting. Available options are ‘plotly’ and ‘vtk’. Default is ‘plotly’.

  • scalar_labels (Iterable, Optional) – Labels of the scalars in ‘scalars’. Only if Plotly is selected as the backend. Defaeult is None.

Returns

A PyVista or a Plotly object.

Return type

Any

plot_dof_solution(*args, backend: str = 'plotly', case: int = 0, component: int = 0, labels: Optional[Iterable] = None, **kwargs) Any[source]

Plots degrees of freedom solution using ‘vtk’ or ‘plotly’.

Parameters
  • scalars (numpy.ndarray, Optional) – Data to plot. Default is None.

  • case (int, Optional) – The index of the load case. Default is 0.

  • component (int, Optional) – The index of the DOF component. Default is 0.

  • labels (Iterable, Optional) – Labels of the DOFs. Only if Plotly is selected as the backend. Defaeult is None.

  • **kwargs (dict, Optional) – Keyqord arguments forwarded to pvplot().

Returns

A figure object or None, depending on the selected backend.

Return type

Any

property section: BeamSection

Returns the section of the cells or None if there is no associated data.

Returns

The section instance associated with the beams of the block.

Return type

BeamSection

class sigmaepsilon.solid.fem.linemesh.BernoulliFrame(*args, areas: Optional[ndarray] = None, model: Optional[ndarray] = None, section: Optional[BeamSection] = None, **kwargs)[source]

A subclass of LineMesh to handle input and output of 1d meshes.

Note

This in experimental stage.