Materials and reservoir data
Material fields, physical loads and integration across interfaces.
Explicit acquisition and loading of the pinned SPE10 Model 2 properties.
The dataset retains ECLIPSE I-fastest ordering, mD/ft units and published porosity values. No network request occurs except an explicit download call.
load_spe10_model2(directory: str | Path) -> ReservoirData
Load the OPM Model 2 property includes as a 60×220×85 reservoir.
This function performs no network requests. Use :func:download_spe10_model2
to obtain the pinned files explicitly. Source porosity values, including the
OPM zero replacement of 1e-7, are preserved.
download_spe10_model2(directory: str | Path) -> Path
Explicitly download ~77 MB of pinned OPM properties with SHA-256 checks.
Valid cached files are reused. A mismatched existing file raises, avoiding an unnoticed change to user-provided data. Incomplete or corrupt downloads never replace the target file. OPM attributes these property files to Christie and Blunt; dataset/deck licensing is documented by OPM/opm-data.
Discrete point-source functionals with geometric sharing at mesh interfaces.
split_point_sources(mesh: TriangleMesh | CartesianMacroMesh | PolygonMesh, sources: Any) -> tuple[FloatArray, ...]
Share source strengths among cells in proportion to their incident angles.
Triangular, Cartesian and simple polygonal meshes are supported. Interior points belong to one cell; interface points are split by the incident angular sectors. At an interior edge this gives half to either cell, and at a vertex it uses the actual triangle angles. This is the limit of a radially symmetric regularization of the load, restricted to the domain. The total specified strength is preserved, including at domain corners, without duplicating wells shared by several macrocells.
point_load_vector(mesh: TriangleMesh | CartesianMacroMesh, degree: int, sources: Any) -> FloatArray
Assemble sum Q_j v(x_j) for continuous triangular Pk or Cartesian Qk tests.
A source on an internal fine edge/vertex is evaluated once; continuity of
the nodal finite-element test space makes the containing-cell choice
immaterial. Use :func:split_point_sources first to allocate sources across
a broken macro space. Two-dimensional Dirac sources are not H⁻¹ loads;
this discrete operation does not imply a finite continuum energy norm.
assemble_load(tests: Any, samples: Any, weights: Any, rows: Any, size: int) -> Any
Scatter sum_q weights[t,q]*tests[t,q,i]*samples[t,q] into test rows.
Tests have axes (cell, point, local test). Physical Jacobians and any conjugation are explicit parts of the supplied tests or weights; none is inferred. Samples/weights broadcast to (cell, point). Real and complex coefficients are supported. Continuous and discontinuous spaces differ only in the integer row map, whose repeated coordinates are summed.
assemble_mass(tests: Any, trials: Any, weights: Any, rows: Any, columns: Any, shape: tuple[int, int]) -> Any
Scatter the literal test/trial pairing with physical weighted measure.
Tabs have axes (cell, point, local basis), with possibly different trial
and test counts. weights broadcasts to (cell, point) and may contain
density, capacity or signed/Petrov coefficients. This operation makes no
positivity, Hermitian or time-scheme assumption. A sesquilinear form
supplies conjugated test values explicitly.
Positive quadrature on intersections of triangular elements and material pixels.
cartesian_trace_values(field: CartesianCellField, points: Any, interior_points: Any) -> FloatArray
Evaluate exact pixel traces selected by incident-cell interior points.
points has shape (n,2); interior_points has shape (2,) or (n,2).
Coordinates on a pixel line use the side containing the corresponding
interior point. Values elsewhere use the containing pixel. A direction
tangent to an interface cannot define its one-sided value and is rejected.
Coordinate comparisons propagate physical representation and transform roundoff;
no sampling point is displaced.
cartesian_edge_quadrature(start: Any, end: Any, field: CartesianCellField, order: int = 5, *, interior_point: Any) -> tuple[FloatArray, FloatArray, FloatArray]
Integrate material traces from one specified side of a physical edge.
Return physical points, nonnegative weights summing to one, and material values with a leading point axis. Multiply weights by the edge length. Integration splits at all Cartesian pixel intersections. On a face lying on a material line, the strictly interior point of the incident cell selects the side by its coordinate relative to that line. No coordinate perturbation or average of opposite material traces is used.
material_triangle_quadrature(mesh: TriangleMesh, material: Any, order: int = 5) -> tuple[FloatArray, FloatArray, Any]
Return cellwise barycentric integration and unambiguously sampled material.
Cartesian piecewise-constant materials are integrated on every positive-area
intersection, and the last return value contains flattened material samples
from pixel indices. A TriangleQuadratureField supplies its own positive
rule and samples, including arbitrary tensor trailing axes. Such a provider
may omit support where its field is exactly zero. For ordinary coefficients
the common Gaussian rule is broadcast without copying and the coefficient
itself is returned unchanged.
Arrays have shapes (cells, points, 3) and (cells, points); weights
must be multiplied by physical triangle areas. Whole-cell material rules
sum to one per cell; compact-support field rules integrate only that support.
fit_material_faces(skeleton: SkeletonSpace, field: CartesianCellField) -> SkeletonSpace
Split macroface segments at intersections with a Cartesian material grid.
The macro and fine triangulations are unchanged. Every segment inherits its original degree; vector component count and continuity within each macroface are preserved. This fits the multiplier partition to material pixel edges, including boundaries between equal-valued pixels. It does not enrich local trial spaces or claim that an unfitted continuous local polynomial represents an exact solution with a gradient jump.
fit_material_mesh(mesh: TriangleMesh, field: CartesianCellField) -> TriangleMesh
Triangulate every original triangle/pixel intersection into a fitted mesh.
Original edges and material interfaces remain mesh edges. Convex intersection
polygons with more than three vertices use an interior centroid fan, retaining
every boundary vertex and avoiding collinear fan triangles. Coincident vertices
are identified within the propagated coordinate-roundoff envelope, including
the grid-scaled arithmetic bound. Identification precedes triangulation. Sliver
cells below the geometric distinguishability of TriangleMesh are rejected;
no minimum-angle improvement or arbitrary-interface meshing is claimed.
cartesian_triangle_quadrature(mesh: TriangleMesh, field: CartesianCellField, order: int = 5, *, return_cells: bool = False) -> tuple[FloatArray, FloatArray] | tuple[FloatArray, FloatArray, IntArray]
Integrate each triangle separately over all positive-area material pixels.
Return barycentric coordinates (cells, points, 3) and nonnegative,
unit-sum weights (cells, points). Multiply weights by the triangle's
physical area for integration. Each convex pixel intersection is triangulated
and receives the ordinary Duffy-product Gauss rule of the requested order.
Triangles with fewer points repeat their first point with zero padding weight.
With return_cells=True, also return pixel indices (cells, points, 2).
Use these to retrieve discontinuous material values without rounding an
interface-adjacent physical point into its neighboring pixel. Every material
pixel with geometrically resolved positive intersection area is represented.
Vertices within the propagated coordinate error of an integer grid line
use that same line throughout material integration. This rule resolves
coefficient jumps; it does not change the finite-element trial space.
Positive piecewise-constant tensors on explicitly described planar material regions.
PlanarRegion
dataclass
Intersection of halfspaces n_i dot x <= b_i carrying a constant SPD tensor.
Normals may be unnormalized. Halfspaces can describe bounded inclusions or unbounded layers. The region dimension must be two or three; geometry is expressed in the same physical coordinates as the mesh.
__post_init__() -> None
Normalize the physical plane equations without changing their halfspaces.
box(lower: Any, upper: Any, permeability: Any) -> PlanarRegion
classmethod
Describe an axis-aligned inclusion using physical lower and upper coordinates.
PlanarMaterial
dataclass
Background tensor with ordered planar inclusions; the last containing region wins.
Region zero denotes the background. Positive region IDs are one-based in
regions. Values exactly on a plane belong to its closed halfspace;
trace_values instead selects a physical one-sided value using the
incident-cell interior, without displacing evaluation coordinates.
dimension: int
property
Physical dimension of every tensor and plane.
planes: tuple[FloatArray, FloatArray]
property
All interface planes, including repeated planes with identical geometry.
tensors: FloatArray
property
Tensor table indexed by background/region identifiers.
__post_init__() -> None
Validate common dimension and retain immutable physical material data.
region_ids(points: Any) -> IntArray
Identify the last closed material region containing each point.
__call__(points: Any) -> FloatArray
Evaluate the physical permeability tensor at each point.
trace_values(points: Any, interior_points: Any) -> FloatArray
Select exact incident-side material traces on planar interfaces.
The zero-distance envelope bounds floating-point plane evaluation. An interior point tangent to a relevant plane cannot define a side and is rejected. No shifted material sampling or averaging is used.
Conforming simplex partitions fitted to arbitrary affine material interfaces.
PlanarFittedMesh
dataclass
Material-fitted simplex mesh with exact original-cell and material-region ownership.
tensors: FloatArray
property
One physical permeability tensor per fitted simplex, including background.
fit_planar_material(mesh: TriangleMesh | TetraMesh, material: PlanarMaterial) -> PlanarFittedMesh
Fit a conforming simplex mesh to all planes defining a material.
Planes are extended across each cell before triangulation, so intersections match on incident cells. Canonical face fans preserve conformity in 3D. This operation enriches geometry; it does not automatically enrich a MHM trace. Its original-cell ancestry lets callers retain their macro mesh. Geometric predicates use a coordinate-roundoff envelope, and independent parent-volume and interior-face checks reject unresolved output geometry.
fit_planar_skeleton(mesh: TriangleMesh, material: PlanarMaterial, *, degree: int = 0) -> SkeletonSpace
Insert exact interface intersections into every two-dimensional macroface.
planar_face_partitions(mesh: TetraMesh, material: PlanarMaterial) -> tuple[FloatArray, ...]
Partition each original triangular macroface at all material-plane intersections.
Each returned array contains subtriangle vertices in the original face's barycentric coordinates. The same physical boundary fan as volume fitting fixes its diagonals. These partitions describe actual unequal subface areas; consumers must integrate using their area fractions, not a uniform count.
Positive integration rules split at explicitly described planar material interfaces.
planar_simplex_quadrature(mesh: TriangleMesh | TetraMesh, material: PlanarMaterial, order: int = 5) -> tuple[FloatArray, FloatArray, FloatArray]
Return cellwise barycentric rules and flattened material tensor samples.
Every material subregion receives a positive Gaussian rule. Weights sum to
one in each original cell; multiply them by that cell's area or volume.
Shapes are (cells, points, dimension + 1), (cells, points) and
(cells * points, dimension, dimension). Different rule lengths are
padded with zero weights at the original-cell centroid. Integration is
fitted to interfaces without modifying the original approximation space.
planar_edge_quadrature(start: Any, end: Any, material: PlanarMaterial, order: int = 5, *, interior_point: Any) -> tuple[FloatArray, FloatArray, FloatArray]
Integrate exact incident-side tensor traces along a physical edge.
Return physical points, positive weights summing to one and one tensor per point. Multiply weights by physical edge length. Each plane intersection splits the rule. The supplied incident-cell interior selects the side of an edge lying on a material interface; no sample coordinate is displaced.
One-sided piecewise constant fields on Cartesian material grids.
CartesianCellField
dataclass
Piecewise constant scalar/tensor values on a Cartesian cell grid.
The first len(spacing) array axes are spatial (x, y, optionally z).
Remaining axes are value components. Internal interfaces use the cell on
their positive side; the external upper boundary uses the last cell. This
pointwise convention resolves grid-line representations within their propagated
physical-coordinate roundoff; it does not average material jumps. Quadrature must
resolve those jumps when using this field as a PDE coefficient.
__post_init__() -> None
Validate and freeze independent real field and geometry arrays.
__call__(points: Any) -> Array
Evaluate points of shape (n, dimension) without extrapolation.
Explicit positive quadrature for layered coefficients and circular radial loads.
The quadrature protocol retains the original triangular approximation space. Returned weights are divided by original-cell area; a supported load may cover only part of a cell. Material values carry arbitrary trailing scalar/vector/ tensor axes, so a two-dimensional Kelvin stiffness may have shape (3, 3).
TriangleQuadratureField
Bases: Protocol
A field supplying points, area-normalized weights and flattened values.
Arrays have shapes (cells, points, 3), (cells, points), and (cells * points, ...). Zero weights pad shorter cell rules. Quadrature may omit regions where the field is exactly zero; it never changes trial DOFs.
triangle_quadrature(mesh: TriangleMesh, order: int) -> tuple[FloatArray, FloatArray, FloatArray]
Return a positive integration rule for this field on the given mesh.
TimeDependentTriangleField
Bases: Protocol
A time-dependent load with a spatial quadrature provider at each time.
at_time(time: float) -> TriangleQuadratureField
Return the physical field at a finite time, without density weighting.
SeparableTriangleField
Bases: Protocol
Explicit spatial quadrature snapshot multiplied by a real scalar in time.
This opt-in contract is f(t,x)=time_scale(t)*spatial_field(x). Both methods
use the same physical force-density convention as at_time. Preparation
integrates the spatial snapshot through the original local basis/rule once;
a changing support, material-weighted load or nonseparable callback must
continue to use the ordinary at_time/callback path.
spatial_field() -> TriangleQuadratureField
Return the declared time-independent spatial force-density provider.
time_scale(time: float) -> float
Return its finite real scalar amplitude at a finite real time.
PolylineLayerField
dataclass
Piecewise-constant data separated by noncrossing two-dimensional polylines.
abscissae is strictly increasing. heights has one row per interface
and increases strictly down its first axis at every abscissa. Layers are
ordered by increasing second coordinate; an interface point belongs to the
layer with the smaller index. Outside the abscissa range, each interface
continues at its endpoint height. values has one leading entry per
layer and arbitrary trailing axes, with no implicit Kelvin/Voigt conversion.
Positivity or tensor symmetry is checked by the physical assembly owner.
__post_init__() -> None
Validate and freeze the geometric partition and its finite real data.
__call__(points: Any) -> FloatArray
Evaluate the declared layer convention at finite physical coordinate pairs.
triangle_quadrature(mesh: TriangleMesh, order: int) -> tuple[FloatArray, FloatArray, FloatArray]
Integrate on exact polygonal intersections with every relevant layer segment.
Positive Duffy rules integrate polynomial factors without fitting or enriching the original trial space. Splits use coordinate-roundoff envelopes from the shared planar geometry owner.
RadialDiskLoad
dataclass
A finite-radius radial force density with independent cut-disk quadrature.
The field is amplitude*(x-center)/|x-center| for 0<distance<radius and
zero elsewhere. Amplitude is force per volume, not acceleration; no density
factor is applied. An optional scalar time_function is sampled by
at_time. Angular adaptivity controls all scalar and radial-vector
monomials through degree 2*order-2 in coordinates normalized by radius.
tolerance bounds the absolute estimated error of these dimensionless
moments per original cell, before multiplication by radius squared.
The difference of two Gaussian rules is an estimator, not a certified bound.
__post_init__() -> None
Freeze a finite center and reject invalid support or integration parameters.
__setstate__(state: dict[str, Any]) -> None
Restore validated, read-only spatial coordinates after pickle/spawn.
at_time(time: float) -> RadialDiskLoad
Freeze the physical field and its declared base-vector temporal scaling.
Public amplitude and samples carry the physical product. The separable protocol retains the unscaled spatial provider and sampled scalar, so force assembly integrates the same spatial load before multiplying it. Replacing public data resets this private snapshot contract.
spatial_field() -> RadialDiskLoad
Return the declared unscaled disk and its original quadrature controls.
time_scale(time: float) -> float
Evaluate a finite real scalar temporal factor without changing spatial support.
__call__(points: Any) -> FloatArray
Evaluate the static amplitude; call at_time first for a temporal modulation.
triangle_quadrature(mesh: TriangleMesh, order: int) -> tuple[FloatArray, FloatArray, FloatArray]
Integrate exact circular intersections without polygonizing the source disk.
triangle_field_quadrature(mesh: TriangleMesh, field: TriangleQuadratureField, order: int) -> tuple[FloatArray, FloatArray, FloatArray]
Validate a provider's cellwise coordinates, positive weights and values.
Providers own their integration error controls. This check enforces the
array/geometry contract, not accuracy for an arbitrary integrand. Inactive
support has zero weight; a whole-cell material rule must additionally
conserve cell area, as done by :class:PolylineLayerField.
Finite coefficient evaluation with explicit two- and three-dimensional conventions.
Scalar, vector and SPD tensor inputs use the existing point-major layouts. The dimension-specific symmetry checks and returned storage conventions stay separate so material validation preserves each formulation's numerical contract.
scalar_values(field: Any, points: FloatArray) -> FloatArray
Evaluate a finite real scalar coefficient on points shaped (n, 2).
vector_values(field: Any, points: FloatArray) -> FloatArray
Evaluate a finite real two-component coefficient with point-major storage.
tensor_values(field: Any, points: FloatArray) -> FloatArray
Evaluate positive scalar or SPD 2x2 diffusion in writable binary64 storage.
Scalar eigenvalues are checked directly; matrix inputs retain the explicit symmetry and spectral checks. Scalars expand to the same diagonal tensors.
scalar_values_3d(coefficient: Any, points: FloatArray) -> FloatArray
Evaluate finite real scalar data at points of shape (n, 3).
tensor_values_3d(coefficient: Any, points: FloatArray) -> FloatArray
Evaluate positive scalar or SPD 3x3 diffusion in read-only binary64 views.
Scalar eigenvalues are checked directly; matrix inputs retain their scaled symmetry and spectral checks. Broadcasting preserves the tensor layout.
vector_values_3d(coefficient: Any, points: FloatArray) -> FloatArray
Evaluate finite real vectors with exactly three Cartesian components.