Source code for felupe.mesh._container

# -*- coding: utf-8 -*-
"""
This file is part of FElupe.

FElupe is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

FElupe is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with FElupe.  If not, see <http://www.gnu.org/licenses/>.
"""

from copy import deepcopy

import numpy as np

from ._mesh import Mesh
from ._tools import sweep


[docs]class MeshContainer: """A container which operates on a list of meshes with identical dimensions. Parameters ---------- meshes : [felupe.Mesh, ...] A list with meshes. Attributes ---------- dim : int The (identical) dimension of all underlying meshes. points : ndarray Point coordinates. meshes : [felupe.Mesh, ...] A list with meshes. """ def __init__(self, meshes, merge=False, decimals=None): """A container which operates on a list of meshes with identical dimensions.""" # obtain the dimension from the first mesh self.dim = meshes[0].dim # init points and list of meshes self.points = np.zeros((0, self.dim)) self.meshes = [] # append all meshes [self.append(mesh) for mesh in meshes] if merge: self.merge_duplicate_points(decimals=decimals)
[docs] def append(self, mesh): "Append a Mesh to the list of meshes." # number of points points = np.vstack([self.points, mesh.points]) self.meshes.append(Mesh(points, mesh.cells + len(self.points), mesh.cell_type)) # ensure identical points-arrays for i, m in enumerate(self.meshes): self.meshes[i].points = self.points = points
[docs] def pop(self, index): "Pop an item of the list of meshes." item = self.meshes.pop(index) return item
[docs] def cells(self): "Return a list of tuples with cell-types and cell-connectivities." return [(mesh.cell_type, mesh.cells) for mesh in self.meshes]
[docs] def merge_duplicate_points(self, decimals=None): "Merge duplicate points and update meshes." # sweep points for i, mesh in enumerate(self.meshes): self.meshes[i] = sweep(mesh, decimals=decimals) # ensure identical points-arrays points = self.meshes[0].points for i, m in enumerate(self.meshes): self.meshes[i].points = self.points = points
[docs] def as_meshio(self, combined=True, **kwargs): "Export a (combined) mesh object as ``meshio.Mesh``." import meshio if not combined: cells = [ meshio.CellBlock(cell_type, data) for cell_type, data in self.cells() ] else: cells = {} for mesh in self.meshes: if mesh.cell_type not in cells.keys(): cells[mesh.cell_type] = mesh.cells else: cells[mesh.cell_type] = np.vstack( [cells[mesh.cell_type], mesh.cells] ) return meshio.Mesh(self.points, cells, **kwargs)
[docs] def copy(self): "Return a deepcopy of the mesh container." return deepcopy(self)
def __iadd__(self, mesh): self.append(mesh) return self def __getitem__(self, index): return self.meshes[index] def __repr__(self): header = "<felupe mesh container object>" points = f" Number of points: {len(self.points)}" cells_header = " Number of cells:" cells = [] for cells_type, cells_data in self.cells(): cells.append(f" {cells_type}: {len(cells_data)}") return "\n".join([header, points, cells_header, *cells]) def __str__(self): return self.__repr__()