Source code for ogstools.meshlib.geo

import numpy as np
import pyvista as pv
from pint.facets.plain import PlainQuantity

from ogstools.variables import u_reg


[docs] def depth(mesh: pv.UnstructuredGrid, use_coords: bool = False) -> np.ndarray: """Returns the depth values of the mesh. For 2D, the last axis of the plane wherein the mesh is lying is used as the vertical axis (i.e. y if the mesh is in the xy-plane, z if it is in the xz-plane), for 3D, the z-axes is used. If `use_coords` is True, returns the negative coordinate value of the vertical axis. Otherwise, the vertical distance to the top facing edges surfaces are returned. """ if mesh.volume > 0: # prevents inner edge (from holes) to be detected as a top boundary edges = mesh.extract_surface().connectivity("point_seed", point_ids=[0]) vertical_dim = 2 if use_coords: return -mesh.points[:, vertical_dim] point_upwards = edges.cell_normals[..., vertical_dim] > 0 top_cells = point_upwards else: mean_normal = np.abs( np.mean(mesh.extract_surface().cell_normals, axis=0) ) vertical_dim = np.delete([0, 1, 2], int(np.argmax(mean_normal)))[-1] if use_coords: return -mesh.points[:, vertical_dim] # prevents inner edge (from holes) to be detected as a top boundary edges = mesh.extract_feature_edges().connectivity( "point_seed", point_ids=[0] ) edge_horizontal_extent = [ np.diff(np.reshape(cell.bounds, (-1, 2))).ravel()[0] for cell in edges.cell ] edge_centers = edges.cell_centers().points adj_cells = [mesh.find_closest_cell(point) for point in edge_centers] adj_centers = np.vstack( [ mesh.extract_cells(adj_cell).cell_centers().points for adj_cell in adj_cells ] ) are_above = [ edge_center[vertical_dim] > adj_center[vertical_dim] for edge_center, adj_center in zip( edge_centers, adj_centers, strict=False ) ] are_non_vertical = np.asarray(edge_horizontal_extent) > 1e-12 top_cells = are_above & are_non_vertical top = edges.extract_cells(top_cells) eucl_distance_projected_top_points = np.sum( np.abs( np.delete(mesh.points[:, None] - top.points, vertical_dim, axis=-1) ), axis=-1, ) matching_top = np.argmin(eucl_distance_projected_top_points, axis=-1) return np.abs( mesh.points[..., vertical_dim] - top.points[matching_top, vertical_dim] )
[docs] def p_fluid(mesh: pv.UnstructuredGrid) -> PlainQuantity: """Return the fluid pressure in the mesh. If "depth" is given in the mesh's point _data, it is used return a hypothetical water column defined as: .. math:: p_{fl} = 1000 \\frac{kg}{m^3} 9.81 \\frac{m}{s^2} h where `h` is the depth below surface. Otherwise, If "pressure" is given in the mesh, return the "pressure" data of the mesh. If that is also not the case, the hypothetical water column from above is returned with the depth being calculated via :py:func:`ogstools.meshlib.geo.depth`. """ Qty = u_reg.Quantity if "depth" in mesh.point_data: return ( Qty(1000, "kg/m^3") * Qty(9.81, "m/s^2") * Qty(mesh["depth"], "m") ) if "pressure" in mesh.point_data: return Qty(mesh["pressure"], "Pa") return Qty(1000, "kg/m^3") * Qty(9.81, "m/s^2") * Qty(depth(mesh), "m")