Source code for ogstools.meshlib.boundary

import tempfile
from abc import ABC, abstractmethod
from dataclasses import dataclass
from math import ceil
from pathlib import Path

import pyvista as pv
from ogs import cli

from .boundary_subset import Surface


[docs]class Boundary(ABC): """ Abstract base class representing a boundary within a mesh. A boundary refers to the set of edges or faces that defines the delineation between the interior region and exterior regions of a mesh. In a 2D mesh, it is formed by a closed collection of line segments (1D). In a 3D mesh, it is formed by a closed collection of faces (2D). """
[docs] @abstractmethod def dim(self): """ Get the dimension of the boundary. Returns: int: The dimension of the boundary. For example, the dimension of a boundary of a cube (3D) is 2. """ return
[docs]@dataclass(frozen=True) class Layer(Boundary): top: Surface bottom: Surface material_id: int = 0 num_subdivisions: int = 0 """ Class representing a geological layer with top and bottom surfaces. A geological layer is a distinct unit of rock or sediment that has unique properties and characteristics, associated by the material_id. It is often bounded by two surfaces: the top surface and the bottom surface. These surfaces delineate the spatial extent of the layer in the GIS system. """ def __post_init__(self): if not self.material_id: object.__setattr__(self, "material_id", self.bottom._material_id)
[docs] def create_raster(self, resolution: float) -> list[Path]: """ Create raster representations for the layer. For each surface, including intermediate surfaces (num_of_subdivisions > 0), this method generates .asc files. Args: resolution (float): The resolution for raster creation. Returns: list[Path]: A list of filenames to .asc raster files. """ top_raster = self.top.create_raster_file(resolution) bottom_raster = self.bottom.create_raster_file(resolution) if self.num_subdivisions < 1: return [top_raster, bottom_raster] outfile = Path(tempfile.mkstemp(".asc")[1]) ret = cli.createIntermediateRasters( file1=top_raster, file2=bottom_raster, o=outfile, n=self.num_subdivisions, ) if ret: raise ValueError new_names = [ outfile.with_name(outfile.stem + str(i) + ".asc") for i in range(0, self.num_subdivisions) ] rasters = [top_raster] rasters.extend(new_names) rasters.append(bottom_raster) return rasters
[docs] def dim(self): return 3
[docs]@dataclass class LocationFrame: xmin: float xmax: float ymin: float ymax: float
[docs] def as_gml(self, filename: Path): """ Generate GML representation of the location frame. Args: filename (Path): The filename to save the GML representation to. Returns: None """ cli.generateGeometry( geometry_name="SceneRectangle", x0=str(self.xmin), x1=str(self.xmax), y0=str(self.ymin), y1=str(self.ymax), z0="0", z1="0", nx="0", nx1="0", ny="0", ny1="0", nz="0", nz1="0", polyline_name="bounding_rectangle", o=str(filename), )
[docs]@dataclass class Raster: """ Class representing a raster representation of a location frame. This class provides methods to create and save a raster representation based on a specified location frame and resolution. """ # 3D - 4 Points frame: LocationFrame resolution: float
[docs] def as_vtu(self, outfilevtu: Path) -> Path: """ Create and save a raster representation as a VTK unstructured grid. Args: outfilevtu (Path): The path to save the VTK unstructured grid representation. Returns: Path: The path to the saved VTK unstructured grid representation. """ centroid = ( (self.frame.xmax + self.frame.xmin) / 2, (self.frame.ymax + self.frame.ymin) / 2, 0, ) i_size = self.frame.xmax - self.frame.xmin j_size = self.frame.ymax - self.frame.ymin abs_resolution = ceil(i_size / self.resolution) plane = pv.Plane( centroid, i_size=i_size, j_size=j_size, i_resolution=abs_resolution, j_resolution=abs_resolution, ) pt = plane.triangulate() pv.save_meshio(outfilevtu, pt) return outfilevtu