Source code for ogstools.meshlib.mesh

# Copyright (c) 2012-2024, OpenGeoSys Community (http://www.opengeosys.org)
#            Distributed under a Modified BSD License.
#            See accompanying file LICENSE.txt or
#            http://www.opengeosys.org/project/license
#

from __future__ import annotations

from importlib.util import find_spec
from pathlib import Path
from typing import Any

import numpy as np
import pyvista as pv

import ogstools.meshlib as ml
from ogstools import plot
from ogstools._internal import copy_method_signature

from . import data_processing, geo, ip_mesh, shape_meshing


[docs] class Mesh(pv.UnstructuredGrid): """ A wrapper around pyvista.UnstructuredGrid. Contains additional data and functions mainly for postprocessing. """ filepath: Path | None = None # pylint: disable=C0116 @copy_method_signature(data_processing.difference) def difference(self, *args: Any, **kwargs: Any) -> Any: return data_processing.difference(self, *args, **kwargs) @copy_method_signature(geo.depth) def depth(self, *args: Any, **kwargs: Any) -> Any: return geo.depth(self, *args, **kwargs) @copy_method_signature(geo.p_fluid) def p_fluid(self, *args: Any, **kwargs: Any) -> Any: return geo.p_fluid(self, *args, **kwargs) @copy_method_signature(plot.contourf) def plot_contourf(self, *args: Any, **kwargs: Any) -> Any: return plot.contourf(self, *args, **kwargs) @copy_method_signature(plot.quiver) def plot_quiver(self, *args: Any, **kwargs: Any) -> Any: return plot.quiver(self, *args, **kwargs) @copy_method_signature(plot.streamlines) def plot_streamlines(self, *args: Any, **kwargs: Any) -> Any: return plot.streamlines(self, *args, **kwargs)
[docs] def to_ip_mesh(self) -> Mesh: return Mesh(ip_mesh.to_ip_mesh(self))
[docs] def to_ip_point_cloud(self) -> Mesh: return Mesh(ip_mesh.to_ip_point_cloud(self))
to_ip_mesh.__doc__ = ip_mesh.to_ip_mesh.__doc__ to_ip_point_cloud.__doc__ = ip_mesh.to_ip_point_cloud.__doc__ # pylint: enable=C0116
[docs] def __init__( self, pv_mesh: pv.UnstructuredGrid | None = None, **kwargs: dict, ): """ Initialize a Mesh object :param pv_mesh: Underlying pyvista mesh. """ if not pv_mesh: # for copy constructor # TODO: maybe better way? super().__init__(**kwargs) else: super().__init__(pv_mesh, **kwargs)
[docs] @classmethod def read(cls, filepath: str | Path) -> Mesh: """ Initialize a Mesh object :param filepath: Path to the mesh or shapefile file. :returns: A Mesh object """ if Path(filepath).suffix == ".shp": mesh = cls(ml.read_shape(filepath)) else: mesh = cls(pv.read(filepath)) mesh.filepath = Path(filepath).with_suffix(".vtu") return mesh
@classmethod @copy_method_signature(shape_meshing.read_shape) def read_shape( cls, shapefile: str | Path, simplify: bool = False, mesh_generator: str = "triangle", cellsize: int | None = None, ) -> Mesh: return cls( shape_meshing.read_shape( shapefile, simplify, mesh_generator, cellsize ) )
[docs] def reindex_material_ids(self) -> None: unique_mat_ids = np.unique(self["MaterialIDs"]) id_map = dict( zip(*np.unique(unique_mat_ids, return_inverse=True), strict=True) ) self["MaterialIDs"] = np.int32( list(map(id_map.get, self["MaterialIDs"])) ) return
if find_spec("ifm") is not None:
[docs] @classmethod def read_feflow( cls, feflow_file: Path | str, ) -> Mesh: """ Initialize a Mesh object read from a FEFLOW file. This mesh stores all model specific information such as boundary conditions or material parameters. :param feflow_file: Path to the feflow file. :returns: A Mesh object """ import ifm_contrib as ifm from ogstools.feflowlib._feflowlib import convert_properties_mesh doc = ifm.loadDocument(str(feflow_file)) return cls(convert_properties_mesh(doc))