r"""
Unified phase model combining trapping and widening mechanisms.
This module provides a unified framework that combines all aspects of the
microscopic gating model into a single coherent interface for predicting
transport regimes and phase behavior.
Theoretical Foundation
----------------------
The unified model synthesizes two competing mechanisms:
**1. Multivalent Trapping (Suppression)**
Bridge formation suppresses diffusion through increased escape barriers:
.. math::
\Gamma = \lambda_0 (1 - e^{-\beta\epsilon_{\text{eff}}})
where :math:`\lambda_0 = M N_{\text{acc}} \langle\chi\rangle \kappa_B` is the
bridge statistics strength.
**2. Entropic Widening (Enhancement)**
TC-induced network softening reduces cage stiffness:
.. math::
\kappa(\phi) = \kappa_0 [1 - \chi_\kappa \mathcal{G}(\phi)]
This produces an enhancement coefficient:
.. math::
A = \beta \frac{1}{2} \kappa_0 x_c^2 \chi_\kappa
**Unified Expression**
The effective diffusion coefficient is:
.. math::
D_{\text{eff}}(\phi) = D_\star \exp[(A - \Gamma)\mathcal{G}(\phi)]
Transport Regimes
-----------------
The sign of :math:`A - \Gamma` determines transport behavior:
+------------------+------------------+------------------------------------------+
| Regime | Condition | Behavior |
+==================+==================+==========================================+
| Suppression | :math:`A < \Gamma` | U-shaped: minimum at :math:`\phi \approx K_d` |
+------------------+------------------+------------------------------------------+
| Enhancement | :math:`A > \Gamma` | Bell-shaped: maximum at :math:`\phi \approx K_d` |
+------------------+------------------+------------------------------------------+
| Critical | :math:`A = \Gamma` | Nearly concentration-independent |
+------------------+------------------+------------------------------------------+
**Physical interpretation:**
- **Suppression-dominated**: Bridge trapping overwhelms network softening
- **Enhancement-dominated**: Network softening facilitates transport
- **Critical balance**: Two mechanisms exactly cancel
Phase Diagram
-------------
The phase boundary :math:`A = \Gamma` defines a critical surface in
parameter space:
.. math::
\beta \frac{1}{2} \kappa_0 x_c^2 \chi_\kappa = \lambda_0 (1 - e^{-\beta\epsilon_{\text{eff}}})
**Experimental control parameters:**
- Increase :math:`M` (particle valency) → pushes toward suppression
- Increase :math:`\chi_\kappa` (softening strength) → pushes toward enhancement
- Increase :math:`\epsilon_{\text{eff}}` (bond strength) → pushes toward suppression
Capture Island in Suppression Regime
------------------------------------
For :math:`\Gamma > A`, the gated regime is defined by:
.. math::
\tau_{\text{net}} \lesssim \tau_\star \exp[(\Gamma - A)\mathcal{G}(\phi)]
\lesssim \tau_{\text{obs}}
This yields analytic concentration boundaries via :math:`\mathcal{G}(\phi)`
inversion (see :class:`DomePhaseBoundaries`).
Examples
--------
Determine transport regime:
>>> control = UnifiedControlParameters(
... beta=1.0, kappa0=1.0, x_c=1.0, chi_kappa=0.5,
... lambda0=2.0, epsilon_eff=1.0
... )
>>> control.A() # Widening gain
0.25
>>> control.Gamma() # Trapping loss
1.264...
>>> control.transport_type() # doctest: +SKIP
<TransportType.SUPPRESSION: 2>
Unified model prediction:
>>> from microscopic_gating.widening import EntropicWideningRenormalizer
>>> from microscopic_gating.gating import SymmetricGating
>>> from microscopic_gating.adsorption import LangmuirIsotherm
>>> isotherm = LangmuirIsotherm(K=1.0)
>>> gating = SymmetricGating(isotherm)
>>> renorm = EntropicWideningRenormalizer(gating, kappa0=1.0, chi_kappa=0.5)
>>> model = UnifiedModel(renorm, control, D_star=1.0, tau_star=1.0)
>>> model.Deff(1.0) # doctest: +SKIP
0.778...
See Also
--------
EntropicWideningRenormalizer : Network softening model
DomePhaseBoundaries : Phase boundary calculations
EscapeAveraging : Timescale criteria for capture island
References
----------
- Eq. (S71)-(S73): Unified diffusion expression
- Eq. (S74): Enhancement/suppression criterion
- Eq. (S77)-(S83): Unified phase diagram
- Eq. (S86)-(S89): Capture island boundaries
"""
from __future__ import annotations
from dataclasses import dataclass
from enum import Enum
from typing import Protocol
import numpy as np
from .types import ArrayLike
from .phase_boundaries import DomePhaseBoundaries, CaptureIslandWindow
class GProvider(Protocol):
def G(self, phi: ArrayLike) -> ArrayLike:
...
[docs]class TransportType(Enum):
ENHANCEMENT = 1
SUPPRESSION = 2
CRITICAL = 3
[docs]@dataclass(frozen=True)
class UnifiedControlParameters:
r"""
Unified control parameters (S5) for the minimal competition form.
Definitions
-----------
A = beta * (1/2) * kappa0 * x_c^2 * chi_kappa
Gamma = lambda0 * (1 - exp(-beta * epsilon_eff))
transport type:
- ENHANCEMENT if A > Gamma
- SUPPRESSION if A < Gamma
- CRITICAL if A == Gamma (within tolerance)
"""
beta: float
kappa0: float
x_c: float
chi_kappa: float
lambda0: float
epsilon_eff: float
[docs] def A(self) -> float:
return float(self.beta) * 0.5 * float(self.kappa0) * float(self.x_c) ** 2 * float(self.chi_kappa)
[docs] def Gamma(self) -> float:
return float(self.lambda0) * (1.0 - np.exp(-float(self.beta) * float(self.epsilon_eff)))
[docs] def transport_type(self, tol: float = 1e-12) -> TransportType:
A = self.A()
Gm = self.Gamma()
if A > Gm + tol:
return TransportType.ENHANCEMENT
if A < Gm - tol:
return TransportType.SUPPRESSION
return TransportType.CRITICAL
[docs]@dataclass(frozen=True)
class UnifiedModel:
r"""
Unified diffusion model:
Deff(phi) = D_star * exp[(A - Gamma) * G(phi)]
Here G(phi) is obtained from the renormalizer's gating function.
"""
renorm: GProvider
control: UnifiedControlParameters
D_star: float
tau_star: float
[docs] def Deff(self, phi: ArrayLike) -> ArrayLike:
G = np.asarray(self.renorm.G(phi), dtype=float)
delta = self.control.A() - self.control.Gamma()
return float(self.D_star) * np.exp(delta * G)
[docs]@dataclass(frozen=True)
class SuppressionCaptureIsland:
r"""
Capture island intervals for suppression-type (Gamma > A) using rate-averaged window.
Implements the lambda window via:
lambda_± = ln(tau_± / tau_star) / (1 - exp(-beta * epsilon_eff))
Then map to G-band via g_± = lambda_± / lambda0 and invert to phi intervals using
DomePhaseBoundaries.
"""
boundaries: DomePhaseBoundaries
control: UnifiedControlParameters
tau_star: float
def _denom(self) -> float:
return 1.0 - np.exp(-float(self.control.beta) * float(self.control.epsilon_eff))
[docs] def lambda_bounds(self, tau_net: float, tau_obs: float) -> tuple[float, float]:
denom = self._denom()
if denom <= 0.0:
raise ValueError("Invalid denom (1-exp(-alpha)) <= 0. Check beta, epsilon_eff.")
lam_minus = np.log(float(tau_net) / float(self.tau_star)) / denom
lam_plus = np.log(float(tau_obs) / float(self.tau_star)) / denom
return float(lam_minus), float(lam_plus)
[docs] def concentration_intervals(self, tau_net: float, tau_obs: float) -> list[tuple[float, float]]:
# Require suppression regime
if self.control.transport_type() != TransportType.SUPPRESSION:
return []
lam_minus, lam_plus = self.lambda_bounds(tau_net=tau_net, tau_obs=tau_obs)
window = CaptureIslandWindow(lambda0=self.control.lambda0, boundaries=self.boundaries)
g_minus = window.g_from_lambda(lam_minus)
g_plus = window.g_from_lambda(lam_plus)
return window.phi_intervals_for_g_band(g_minus=g_minus, g_plus=g_plus)