Source code for microscopic_gating.unified_phase

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)