Source code for ogstools.meshlib.data_processing
# 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 itertools import product
from typing import Optional, Union
import numpy as np
import pyvista as pv
from typeguard import typechecked
from ogstools.propertylib import Property
def _raw_differences_all_data(
    mesh1: pv.UnstructuredGrid, mesh2: pv.UnstructuredGrid
) -> pv.UnstructuredGrid:
    diff_mesh = mesh1.copy(deep=True)
    for point_data_key in mesh1.point_data:
        diff_mesh.point_data[point_data_key] -= mesh2.point_data[point_data_key]
    for cell_data_key in mesh1.cell_data:
        if cell_data_key == "MaterialIDs":
            continue
        diff_mesh.cell_data[cell_data_key] -= mesh2.cell_data[cell_data_key]
    return diff_mesh
[docs]
def difference(
    mesh1: pv.UnstructuredGrid,
    mesh2: pv.UnstructuredGrid,
    mesh_property: Optional[Union[Property, str]] = None,
) -> pv.UnstructuredGrid:
    """
    Compute the difference of properties between two meshes.
    :param mesh1: The first mesh to be subtracted from.
    :param mesh2: The second mesh whose data is subtracted from the first mesh.
    :param mesh_property:   The property of interest. If not given, all point
                            and cell_data will be processed raw.
    :returns:   A new mesh containing the difference of `mesh_property` or all
                datasets between mesh1 and mesh2.
    """
    if mesh_property is None:
        return _raw_differences_all_data(mesh1, mesh2)
    if isinstance(mesh_property, Property):
        vals = np.asarray(
            [mesh_property.transform(mesh) for mesh in [mesh1, mesh2]]
        )
        outname = mesh_property.output_name + "_difference"
    else:
        vals = np.asarray([mesh[mesh_property] for mesh in [mesh1, mesh2]])
        outname = mesh_property + "_difference"
    diff_mesh = mesh1.copy(deep=True)
    diff_mesh.clear_data()
    diff_mesh[outname] = np.empty(vals.shape[1:])
    diff_mesh[outname] = vals[0] - vals[1]
    return diff_mesh 
[docs]
def difference_pairwise(
    meshes_1: Union[list, np.ndarray],
    meshes_2: Union[list, np.ndarray],
    mesh_property: Optional[Union[Property, str]] = None,
) -> np.ndarray:
    """
    Compute pairwise difference between meshes from two lists/arrays
    (they have to be of the same length).
    :param meshes_1: The first list/array of meshes to be subtracted from.
    :param meshes_2: The second list/array of meshes whose data is subtracted
                     from the first list/array of meshes - meshes_1.
    :param mesh_property:   The property of interest. If not given, all point
                            and cell_data will be processed raw.
    :returns:   An array of meshes containing the differences of `mesh_property`
                or all datasets between meshes_1 and meshes_2.
    """
    meshes_1 = np.asarray(meshes_1).flatten()
    meshes_2 = np.asarray(meshes_2).flatten()
    if len(meshes_1) != len(meshes_2):
        msg = "Mismatch in length of provided lists/arrays. \
              Their length has to be identical to calculate pairwise \
              difference. Did you intend to use difference_matrix()?"
        raise RuntimeError(msg)
    return np.asarray(
        [
            difference(m1, m2, mesh_property)
            for m1, m2 in zip(meshes_1, meshes_2)
        ]
    ) 
[docs]
@typechecked
def difference_matrix(
    meshes_1: Union[list, np.ndarray],
    meshes_2: Optional[Union[list, np.ndarray]] = None,
    mesh_property: Optional[Union[Property, str]] = None,
) -> np.ndarray:
    """
    Compute the difference between all combinations of two meshes
    from one or two arrays based on a specified property.
    :param meshes_1: The first list/array of meshes to be subtracted from.
    :param meshes_2: The second list/array of meshes, it is subtracted from
                     the first list/array of meshes - meshes_1 (optional).
    :param mesh_property:   The property of interest. If not given, all point
                            and cell_data will be processed raw.
    :returns:   An array of meshes containing the differences of `mesh_property`
                or all datasets between meshes_1 and meshes_2 for all possible
                combinations.
    """
    meshes_1 = np.asarray(meshes_1).flatten()
    if meshes_2 is None:
        meshes_2 = meshes_1.copy()
    meshes_2 = np.asarray(meshes_2).flatten()
    diff_meshes = [
        difference(m1, m2, mesh_property)
        for m1, m2 in product(meshes_1, meshes_2)
    ]
    return np.asarray(diff_meshes).reshape((len(meshes_1), len(meshes_2)))