Source code for stoneforge.rock_physics.elastic_constants

# -*- coding: utf-8 -*-

import numpy as np
from typing import Annotated

[docs] def bulk_modulus( rho: Annotated[np.array, "Density data"], vp: Annotated[np.array, "Compressional velocity data"], vs: Annotated[np.array, "Shear velocity data"])-> np.array: """Computes the bulk modulus using density, shear wave velocity and compressional wave velocity (:footcite:t:`simm2014`). Parameters ---------- rho : array_like Density data in g/cm³. vp : array_like Compressional wave velocity data in km/s. vs : array_like Shear wave velocity data in km/s. Returns ------- K : array_like Bulk modulus data in Pascal unit (S/I). """ A = vp**2 B = (4/3) * (vs**2) return rho * (A - B)
[docs] def compressional_modulus( rho: Annotated[np.array, "Density data"], vp: Annotated[np.array, "Compressional velocity data"])-> np.array: """Computes the Compressional modulus using density and compressional wave velocity (:footcite:t:`simm2014`). Parameters ---------- rho : array_like, float Density data in g/cm³. vp: array_like, float Compressional wave velocity in km/s². Returns ------- M : array_like, float Compressional modulus data Pascal (Pa). """ return rho * (vp)**2
[docs] def shear_modulus( rho: Annotated[np.array, "Density data"], vs: Annotated[np.array, "Shear velocity data"]) -> np.array: """Computes the shear modulus using density and s wave velocity (:footcite:t:`simm2014`). Parameters ---------- rho : array_like Density data in g/cm³. vs : array_like Compressional wave velocity data in km/s. Returns ------- U : array_like Shear modulus data in Pascal unit. """ return rho * (vs**2)
[docs] def shear_wave_velocity( rho: Annotated[np.array, "Density data"], u: Annotated[np.array, "Shear modulus data"]) -> np.array: """Computes the shear wave velocity using density and shear modulus (:footcite:t:`simm2014`). Parameters ---------- rho : array_like, float Density data in g/cm³. u: array_like, float Shear modulus data in Pascal unit. Returns ------- vs : array_like, float Shear wave velocity data km/s. """ return (u / rho)**0.5
[docs] def compressional_wave_velocity( method: Annotated[str, "Chosen method to compute compressional wave velocity"] = "rhob_and_g_and_k", **kwargs) -> np.array: """ Compute the compressional (P-wave) velocity using different elastic property methods (:footcite:t:`simm2014`). Parameters ---------- method : {'rhob_and_g_and_k', 'rhob_and_m'} Method used to compute compressional wave velocity. - 'rhob_and_g_and_k' : Requires bulk modulus (K), shear modulus (G), and density (RHOB). - 'rhob_and_m' : Requires compressional modulus (M) and density (RHOB). rhob : float or array_like Bulk density of the medium [g/cm³ or kg/m³ depending on units consistency]. g : float or array_like, (optional) Shear modulus (G) [same unit system as K]. Required for 'rhob_and_g_and_k'. k : float or array_like, (optional) Bulk modulus (K) [Pa or similar]. Required for 'rhob_and_g_and_k'. m : float or array_like, (optional) Compressional modulus (M = K + 4G/3) [Pa]. Required for 'rhob_and_m'. Returns ------- vp : float or array_like Compressional wave velocity [m/s] or consistent unit. Raises ------ TypeError If required parameters are missing for the selected method. Examples -------- >>> compressional_wave_velocity('rhob_and_g_and_k', rhob=2.5, g=30e9, k=45e9) 6000.0 >>> compressional_wave_velocity('rhob_and_m', rhob=2.5, m=75e9) 6000.0 """ def from_rhob_g_k(rhob, g, k): return ((k + (4 / 3) * g) / rhob) ** 0.5 def from_rhob_m(rhob, m): return (m / rhob) ** 0.5 method_map = { "rhob_and_g_and_k": (from_rhob_g_k, ["rhob", "g", "k"]), "rhob_and_m": (from_rhob_m, ["rhob", "m"]), } if method not in method_map: raise ValueError(f"Unsupported method '{method}'. Choose from: {list(method_map.keys())}") func, required_args = method_map[method] missing = [arg for arg in required_args if arg not in kwargs] if missing: raise TypeError(f"Missing required arguments for method '{method}': {', '.join(missing)}") return func(**{key: kwargs[key] for key in required_args})
[docs] def poisson( method: Annotated[str, "Chosen method to compute Poisson's ratio"] = "k_and_g", **kwargs) -> np.array: """ Compute Poisson's ratio (ν) using different pairs of elastic moduli (:footcite:t:`simm2014`). Parameters ---------- method : {'k_and_g', 'vp_and_vs', 'e_and_k'} Method used to compute Poisson's ratio: - 'k_and_g' : Requires bulk modulus (K) and shear modulus (G). - 'vp_and_vs' : Requires compressional (P-wave) velocity (VP) and shear (S-wave) velocity (VS). - 'e_and_k' : Requires Young's modulus (E) and bulk modulus (K). k : float or array_like, (optional) Bulk modulus [Pa or similar]. Required for 'k_and_g' and 'e_and_k'. g : float or array_like, (optional) Shear modulus [Pa]. Required for 'k_and_g'. e : float or array_like, (optional) Young's modulus [Pa]. Required for 'e_and_k'. vp : float or array_like, (optional) Compressional wave velocity [m/s]. Required for 'vp_and_vs'. vs : float or array_like, (optional) Shear wave velocity [m/s]. Required for 'vp_and_vs'. Returns ------- v : float or array_like Poisson's ratio (dimensionless). Raises ------ TypeError If required parameters for the selected method are missing. Examples -------- >>> poisson('k_and_g', k=36e9, g=45e9) 0.2 >>> poisson('vp_and_vs', vp=6000, vs=3464) 0.25 >>> poisson('e_and_k', e=90e9, k=36e9) 0.2 """ def from_k_and_g(k, g): return (3 * k - 2 * g) / (6 * k + 2 * g) def from_vp_and_vs(vp, vs): return ((vp**2 - 2 * vs**2) / (2 * (vp**2 - vs**2))) def from_e_and_k(e, k): return (3 * k - e) / (6 * k) method_map = { "k_and_g": (from_k_and_g, ["k", "g"]), "vp_and_vs": (from_vp_and_vs, ["vp", "vs"]), "e_and_k": (from_e_and_k, ["e", "k"]), } if method not in method_map: raise ValueError(f"Unsupported method '{method}'. Choose from: {list(method_map.keys())}") func, required_args = method_map[method] missing = [arg for arg in required_args if arg not in kwargs] if missing: raise TypeError(f"Missing required arguments for method '{method}': {', '.join(missing)}") return func(**{key: kwargs[key] for key in required_args})