Spaces:
Sleeping
Sleeping
| """Maxwell–Garnett effective medium model (generalized for ellipsoids). | |
| The Maxwell–Garnett (MG) mixing formula predicts the effective composite | |
| property P_eff for dilute-to-moderate concentrations of ellipsoidal inclusions | |
| embedded in a continuous matrix. It treats the inclusions as non-interacting | |
| dipoles in the matrix background—an asymmetric host/guest assumption that | |
| distinguishes MG from the symmetric Bruggeman approach. | |
| The depolarization factor L encodes filler shape along the measurement axis: | |
| * L = 0 (needle parallel to field) → Voigt (parallel) bound | |
| * L = 1/3 (sphere) → Maxwell (1873); equals Hashin–Shtrikman | |
| lower bound when P_f > P_m | |
| * L = 1 (disk perpendicular to field) → Reuss (series) bound | |
| Mathematical equivalences | |
| ------------------------- | |
| For the same L value, the MG formula is **algebraically identical** to the | |
| Mori–Tanaka method (Mori & Tanaka 1973; Benveniste 1987). Both expressions | |
| collapse to the Maxwell formula for spheres (L = 1/3) and equal the | |
| Hashin–Shtrikman lower bound when P_f > P_m. | |
| References | |
| ---------- | |
| Maxwell, J.C. (1873). | |
| *A Treatise on Electricity and Magnetism*, Oxford. | |
| Maxwell Garnett, J.C. (1904). | |
| *Phil. Trans. Roy. Soc. London* 203, 385. | |
| Mori, T., & Tanaka, K. (1973). | |
| *Acta Metall.* 21, 571. | |
| Benveniste, Y. (1987). | |
| *Mech. Mater.* 6, 147. | |
| """ | |
| from __future__ import annotations | |
| import numpy as np | |
| __all__ = [ | |
| "maxwell_garnett", | |
| "maxwell_garnett_anisotropic", | |
| "mori_tanaka", | |
| ] | |
| def maxwell_garnett( | |
| P_m: float | np.ndarray, | |
| P_f: float | np.ndarray, | |
| phi: float | np.ndarray, | |
| L: float | np.ndarray = 1.0 / 3.0, | |
| ) -> float | np.ndarray: | |
| """Maxwell–Garnett effective property for ellipsoidal inclusions. | |
| Computes the effective composite property along the axis corresponding to | |
| depolarization factor *L*: | |
| .. math:: | |
| P_{\\text{eff}} = P_m \\left[1 + | |
| \\frac{\\phi\\,(P_f - P_m)}{P_m + L\\,(1-\\phi)\\,(P_f - P_m)} | |
| \\right] | |
| Parameters | |
| ---------- | |
| P_m : float or np.ndarray | |
| Matrix (host) property (positive; any transport property P > 0). | |
| P_f : float or np.ndarray | |
| Filler (inclusion) property (positive, same units as P_m). | |
| phi : float or np.ndarray | |
| Filler volume fraction ∈ [0, 1]. | |
| L : float or np.ndarray, optional | |
| Depolarization factor of the inclusion along the measurement axis, | |
| ∈ [0, 1]. Defaults to ``1/3`` (sphere). | |
| Returns | |
| ------- | |
| P_eff : float or np.ndarray | |
| Effective composite property (same units as P_m). | |
| Raises | |
| ------ | |
| ValueError | |
| If *phi* is outside [0, 1], *L* outside [0, 1], or *P_m* / *P_f* | |
| is non-positive. | |
| Notes | |
| ----- | |
| Special limits: | |
| * ``L = 0`` → Voigt (parallel) bound: P_eff = (1−φ)·P_m + φ·P_f. | |
| * ``L = 1/3`` → Maxwell (1873) for spheres; equals the Hashin–Shtrikman | |
| lower bound when P_f > P_m. | |
| * ``L = 1`` → Reuss (series) bound: 1/P_eff = (1−φ)/P_m + φ/P_f. | |
| The formula is algebraically identical to the Mori–Tanaka method for the | |
| same depolarization factor; ``mori_tanaka`` is provided as an alias. | |
| References | |
| ---------- | |
| Maxwell Garnett, J.C. (1904). *Phil. Trans. Roy. Soc. London* 203, 385. | |
| Examples | |
| -------- | |
| >>> maxwell_garnett(1.0, 10.0, 0.3) # spheres, L = 1/3 | |
| 1.8709677... | |
| >>> maxwell_garnett(1.0, 10.0, 0.3, L=0.0) # needle → Voigt | |
| 3.7 | |
| >>> maxwell_garnett(1.0, 10.0, 0.3, L=1.0) # disk → Reuss ≈ 1.3699 | |
| 1.3698630... | |
| """ | |
| P_m = np.asarray(P_m, dtype=float) | |
| P_f = np.asarray(P_f, dtype=float) | |
| phi = np.asarray(phi, dtype=float) | |
| L = np.asarray(L, dtype=float) | |
| if np.any((phi < 0.0) | (phi > 1.0)): | |
| raise ValueError("phi must be in [0, 1].") | |
| if np.any((L < 0.0) | (L > 1.0)): | |
| raise ValueError("L must be in [0, 1].") | |
| if np.any(P_m <= 0.0): | |
| raise ValueError("P_m must be positive.") | |
| if np.any(P_f <= 0.0): | |
| raise ValueError("P_f must be positive.") | |
| delta = P_f - P_m | |
| denom = P_m + L * (1.0 - phi) * delta | |
| result = P_m * (1.0 + phi * delta / denom) | |
| return float(result) if result.ndim == 0 else result | |
| def maxwell_garnett_anisotropic( | |
| P_m: float, | |
| P_f: float, | |
| phi: float, | |
| L_tuple: tuple[float, float, float], | |
| ) -> tuple[float, float, float]: | |
| """Maxwell–Garnett effective property along each principal axis. | |
| For aligned ellipsoidal inclusions described by three depolarization | |
| factors (L_1, L_2, L_3) with L_1 + L_2 + L_3 = 1, returns the | |
| directional effective properties (P_eff_1, P_eff_2, P_eff_3). | |
| Parameters | |
| ---------- | |
| P_m : float | |
| Matrix property (positive). | |
| P_f : float | |
| Filler property (positive, same units as P_m). | |
| phi : float | |
| Filler volume fraction ∈ [0, 1]. | |
| L_tuple : tuple of three floats | |
| Depolarization factors (L_1, L_2, L_3) along the three principal | |
| axes. Each L_i ∈ [0, 1]; together they must sum to 1 ± 1e-8. | |
| Returns | |
| ------- | |
| (P_eff_1, P_eff_2, P_eff_3) : tuple of float | |
| Effective property along each principal axis. | |
| Raises | |
| ------ | |
| ValueError | |
| If the depolarization factors do not sum to 1, or if any individual | |
| L_i is outside [0, 1], or if the scalar inputs are invalid. | |
| Notes | |
| ----- | |
| For a sphere (L_1 = L_2 = L_3 = 1/3), all three components are equal | |
| and recover the isotropic Maxwell result. | |
| The out-of-plane (e.g. L_3) direction for a prolate spheroid (fiber) | |
| has L_3 < 1/3 and gives a higher effective property, reflecting the | |
| enhanced conductance along the fiber axis. | |
| References | |
| ---------- | |
| Maxwell Garnett, J.C. (1904). *Phil. Trans. Roy. Soc. London* 203, 385. | |
| Mori, T., & Tanaka, K. (1973). *Acta Metall.* 21, 571. | |
| Examples | |
| -------- | |
| >>> maxwell_garnett_anisotropic(1.0, 10.0, 0.3, (1/3, 1/3, 1/3)) | |
| (1.8709677..., 1.8709677..., 1.8709677...) | |
| """ | |
| L_1, L_2, L_3 = L_tuple | |
| L_sum = L_1 + L_2 + L_3 | |
| if abs(L_sum - 1.0) > 1e-8: | |
| raise ValueError( | |
| f"Depolarization factors must sum to 1; got {L_sum:.6g}." | |
| ) | |
| P1 = maxwell_garnett(P_m, P_f, phi, L=L_1) | |
| P2 = maxwell_garnett(P_m, P_f, phi, L=L_2) | |
| P3 = maxwell_garnett(P_m, P_f, phi, L=L_3) | |
| return (P1, P2, P3) | |
| #: Alias: Mori–Tanaka for aligned spheroidal inclusions is algebraically | |
| #: identical to Maxwell–Garnett for the same depolarization factor. | |
| mori_tanaka = maxwell_garnett | |