Source code for porereax.regions
"""
Module for defining regions in the simulation box.
"""
import numpy as np
from numpy.typing import NDArray
from collections.abc import Callable
entry = 3
[docs]
def get_region_function(region: str, box: NDArray[np.float64], system_properties: dict | None = None) -> Callable[[NDArray[np.float64]], NDArray[np.bool_]]:
"""
Retrieve the region function based on the provided region identifier.
Parameters
----------
region : str
The region identifier defining the region.
box : np.ndarray
Simulation box dimensions.
system_properties : dict or None
System properties for defining regions, if applicable.
Returns
-------
callable
A function that takes coordinates and returns a boolean mask.
"""
if region == "Box":
return box_region
elif region == "Reservoir":
if system_properties is None:
raise ValueError("System properties must be provided for the 'Reservoir' region.")
return lambda coords: reservoir_region(coords, system_properties)
elif region == "Pore":
if system_properties is None:
raise ValueError("System properties must be provided for the 'Pore' region.")
return lambda coords: pore_region(coords, system_properties)
elif region.startswith("Wall"):
if region == "Wall":
layer_thickness = 5
elif region.startswith("Wall_"):
try:
layer_thickness = float(region.split("_")[1])
except ValueError:
raise ValueError(f"Invalid layer thickness specified in region identifier: {region}")
else:
raise ValueError(f"Unknown region identifier: {region}")
if system_properties is None:
raise ValueError("System properties must be provided for the 'Wall' region.")
return lambda coords: wall_region(coords, system_properties, layer_thickness)
else:
raise ValueError(f"Unknown region identifier: {region}")
[docs]
def box_region(coords: NDArray[np.float64]) -> NDArray[np.bool_]:
"""
Region function that includes all coordinates within the simulation box.
Parameters
----------
coords : np.ndarray
Array of coordinates to check.
Returns
-------
np.ndarray
Boolean mask indicating which coordinates are inside the box.
"""
return np.ones(coords.shape[0], dtype=bool)
[docs]
def reservoir_region(coords: NDArray[np.float64], system_properties: dict) -> NDArray[np.bool_]:
"""
Region function that defines a reservoir region outside the pore.
Parameters
----------
coords : np.ndarray
Array of coordinates to check.
system_properties : dict
System properties containing pore range, center, and radius.
Returns
-------
np.ndarray
Boolean mask indicating which coordinates are within the reservoir region.
"""
pore_range = system_properties["range"]
pore_center = system_properties["center"]
pore_radius = system_properties["radius"]
lower_bound = pore_range[0] + entry
upper_bound = pore_range[1] - entry
distance_from_center = np.linalg.norm(coords[:, :2] - pore_center[:2], axis=1)
return ((coords[:, 2] <= lower_bound) | (coords[:, 2] >= upper_bound)) & (distance_from_center >= pore_radius)
[docs]
def pore_region(coords: NDArray[np.float64], system_properties: dict) -> NDArray[np.bool_]:
"""
Region function that defines a pore region inside the pore.
Parameters
----------
coords : np.ndarray
Array of coordinates to check.
system_properties : dict
System properties containing pore range, center, and radius.
Returns
-------
np.ndarray
Boolean mask indicating which coordinates are within the pore region.
"""
pore_range = system_properties["range"]
lower_bound = pore_range[0] + entry
upper_bound = pore_range[1] - entry
return (coords[:, 2] > lower_bound) & (coords[:, 2] < upper_bound)
[docs]
def wall_region(coords: NDArray[np.float64], system_properties: dict, layer_thickness: float) -> NDArray[np.bool_]:
"""
Region function that defines a wall region around the pore.
Parameters
----------
coords : np.ndarray
Array of coordinates to check.
system_properties : dict
System properties containing pore range, center, and radius.
layer_thickness : float
Thickness of the wall layer.
Returns
-------
np.ndarray
Boolean mask indicating which coordinates are within the wall region.
"""
pore_range = system_properties["range"]
pore_center = system_properties["center"]
pore_radius = system_properties["radius"]
lower_bound_left = pore_range[0] - layer_thickness
upper_bound_left = pore_range[0] + layer_thickness
lower_bound_right = pore_range[1] - layer_thickness
upper_bound_right = pore_range[1] + layer_thickness
distance_from_center = np.linalg.norm(coords[:, :2] - pore_center[:2], axis=1)
reservoir_wall_left = (coords[:, 2] >= lower_bound_left) & (coords[:, 2] <= upper_bound_left) & (distance_from_center >= pore_radius - layer_thickness)
reservoir_wall_right = (coords[:, 2] >= lower_bound_right) & (coords[:, 2] <= upper_bound_right) & (distance_from_center >= pore_radius - layer_thickness)
pore_wall = (coords[:, 2] >= lower_bound_left) & (coords[:, 2] <= upper_bound_right) & (distance_from_center >= pore_radius - layer_thickness) & (distance_from_center <= pore_radius + layer_thickness)
return reservoir_wall_left | reservoir_wall_right | pore_wall