MatLens · Ecuaciones y modelos

Electroquímica e impedancia (EIS)

Esta sección resume las ecuaciones que MatLens evalúa en el módulo de electroquímica, con las convenciones, los valores por defecto y los procedimientos de ajuste tal como están implementados en el código.

Convenciones generales del módulo: potenciales en V, corrientes en A salvo que la función indique otra cosa; corriente de oxidación (anódica) positiva. La impedancia se escribe Z = Z' - \mathrm{j}\,(-Z''), donde la columna -Z'' que entregan los lectores es positiva para espectros capacitivos. Constantes usadas: F = 96485.33212\ \mathrm{C\,mol^{-1}}, R = 8.314462618\ \mathrm{J\,mol^{-1}\,K^{-1}}.

Pendiente de Nernst

S(T) = \frac{\ln(10)\,R\,T}{F}
SímboloSignificadoUnidades
Spendiente de Nernst por décadaV
Ttemperatura (por defecto 298.15 K)K

A 298.15 K, S \approx 0.05916 V. Solo se implementa la pendiente (usada en la conversión a RHE y en el coeficiente de transferencia de Tafel); la ecuación de Nernst completa E = E^0 - (RT/nF)\ln Q no está implementada como función.

Código: matlens/core/echem.py::nernst_slope.

Referencia: Bard & Faulkner, Electrochemical Methods 2nd ed. (2001).

Conversión entre electrodos de referencia

Para escalas fijas se pasa por el SHE:

E_{\mathrm{SHE}} = E_{\mathrm{src}} + E_{\mathrm{src}}^{\mathrm{vs\,SHE}}, \qquad E_{\mathrm{dst}} = E_{\mathrm{SHE}} - E_{\mathrm{dst}}^{\mathrm{vs\,SHE}}

Para el RHE se usa el pH:

E_{\mathrm{RHE}} = E_{\mathrm{SHE}} + S(T)\,\mathrm{pH}

Desplazamientos tabulados (potencial de cada referencia frente a SHE, 25 °C):

ReferenciaE^{\mathrm{vs\,SHE}} (V)
SHE0.0
SCE0.2412
Ag/AgCl (KCl sat.)0.197
Ag/AgCl (KCl 3 M)0.210
Hg/HgO (NaOH 1 M)0.098
RHE-S(T)\,\mathrm{pH} (calculado)

Supuestos: los desplazamientos de la tabla son fijos a 25 °C; la temperatura solo entra a través de S(T) en la conversión a RHE (no se corrige la dependencia térmica del potencial de las referencias). Sin incertidumbre propagada.

Código: matlens/core/echem.py::convert_potential.

Referencia: implementación propia (valores estándar de la literatura; Bard & Faulkner, 2001).

Resistencia no compensada y corrección iR

R_u se toma como la intersección de alta frecuencia del diagrama de Nyquist con el eje real: se ordena el espectro de mayor a menor frecuencia y se interpola linealmente el primer cruce por cero de \mathrm{Im}\,Z. Si no hay cruce, se ajusta una recta Z' frente a \mathrm{Im}\,Z con los (hasta) 4 puntos de mayor frecuencia y se extrapola a \mathrm{Im}\,Z = 0.

La corrección es:

E_{\mathrm{corr}} = E - I\,R_u\,f
SímboloSignificadoUnidades
Epotencial medidoV
Icorriente (oxidación positiva)A
R_uresistencia no compensadaΩ
ffracción compensada (por defecto 1)—

Sin incertidumbre propagada. Código: matlens/core/echem.py::ru_from_eis, matlens/core/echem.py::ir_correct.

Referencia: implementación propia.

Picos de voltametría cíclica

Cada ciclo se separa en el barrido anódico (tramo creciente de E más largo) y el catódico (tramo decreciente más largo). En cada rama la línea base es una recta I = aE + b ajustada por mínimos cuadrados sobre el primer 15 % de la rama (o sobre una ventana de potencial indicada); opcionalmente la corriente se suaviza con Savitzky–Golay de orden 2. El pico es el máximo (anódico) o mínimo (catódico) de la corriente corregida por la línea base. Magnitudes derivadas:

\Delta E_p = E_{pa} - E_{pc}, \qquad E_{1/2} = \tfrac{1}{2}(E_{pa}+E_{pc}), \qquad \left|\frac{i_{pa}}{i_{pc}}\right|

El informe recuerda que para un sistema reversible monoelectrónico \Delta E_p \approx 59 mV a 25 °C.

Código: matlens/core/echem.py::cv_peaks.

Referencia: Bard & Faulkner (2001).

Carga integrada

Q = \int I\,\mathrm{d}t \quad \text{o bien} \quad Q = \frac{1}{v}\int I\,\mathrm{d}E

con integración trapezoidal, v la velocidad de barrido (V s⁻¹) y opcionalmente restringido a una ventana de potencial. Para electrólisis, charge_from_current devuelve |\int I\,\mathrm{d}t| (C).

Código: matlens/core/echem.py::integrate_charge, matlens/core/echem.py::charge_from_current.

Referencia: implementación propia.

Randles–Ševčík

i_p = 0.4463\,n F A C \left(\frac{n F v D}{R T}\right)^{1/2}

Se ajusta |i_p| frente a v^{1/2} por mínimos cuadrados lineales (con ordenada libre, o forzada por el origen si se pide), y de la pendiente s:

D = \left(\frac{s}{0.4463\,n F A C\,\sqrt{nF/(RT)}}\right)^2
SímboloSignificadoUnidades
i_pcorriente de pico (se usa su valor absoluto)A
nelectrones transferidos—
Aárea del electrodocm²
Cconcentración (entrada en mM, convertida a mol cm⁻³)mol cm⁻³
vvelocidad de barridoV s⁻¹
Dcoeficiente de difusióncm² s⁻¹
Ttemperatura (298.15 K por defecto)K

Incertidumbre (k=1): error estándar de la pendiente de la regresión, \sigma_s^2 = \frac{\sum r_i^2}{N-2}\,[(X^\top X)^{-1}]_{11} (por el origen: \sigma_s^2 = \frac{\sum r_i^2}{N-1}/\sum x_i^2), propagado como \sigma_D = 2D\,\sigma_s/s. No se propagan incertidumbres de A, C ni T.

Validez: transferencia reversible, difusión plana semiinfinita, al menos 2 velocidades.

Origen. Resolviendo la segunda ley de Fick con difusión plana semiinfinita y la condición de Nernst en la superficie durante un barrido lineal, la corriente es i = nFAC\sqrt{\pi D\sigma}\,\chi(\sigma t) con \sigma = nFv/(RT); el máximo de la función adimensional, \sqrt{\pi}\chi_\text{max} = 0.4463, da la ecuación. Cuándo falla: transferencia cuasirreversible o irreversible (el pico se desplaza con v; en el caso irreversible el coeficiente es 0.4958 y \alpha aparece dentro de la raíz), especies adsorbidas (i_p \propto v, no v^{1/2}), microelectrodos o tiempos largos (difusión radial), caída óhmica no compensada y corriente capacitiva sin restar (ambas crecen con v). Una ordenada claramente distinta de cero o una curvatura en i_p frente a v^{1/2} indican alguna de estas situaciones; la función no las detecta.

Algoritmo. Se toma |i_p| (A), x = \sqrt{v}, recta por linfit (mínimos cuadrados con ordenada, numpy.linalg.lstsq) o por el origen; C (mM) se convierte con 10^{-6} a mol cm⁻³. No hay avisos de validez en esta función; solo el error "Se necesitan al menos 2 velocidades de barrido". Con 2 puntos la incertidumbre es NaN.

Ejemplo resuelto

Caso sintético: n=1, A=0.0707 cm², C=1 mM, T=298.15 K, D_\text{verdadero}=7.0\times10^{-6} cm² s⁻¹, ruido gaussiano relativo del 1 % (semilla 1) en i_p.

v (V s⁻¹)i_p (µA)
0.015.043
0.0258.011
0.0511.27
0.115.68
0.222.68
0.431.92

randles_sevcik(v, ip, 1, 0.0707, 1.0) → pendiente = 5.053e-05 A (V/s)⁻½, R^2 = 0.999833, D = (7.078 \pm 0.091)\times10^{-6} cm² s⁻¹ (k=1).

Código: matlens/core/echem.py::randles_sevcik.

Referencia: Bard & Faulkner (2001).

Capacitancia de doble capa y ECSA

Para cada velocidad de barrido se toma la diferencia de corrientes anódica y catódica a un potencial fijo E_0 en la región no faradaica (\Delta i = i_a - i_c, interpolada en cada rama). Luego:

\frac{\Delta i}{2} = C_{dl}\,v + b, \qquad \mathrm{ECSA} = \frac{C_{dl}}{C_s}, \qquad \mathrm{RF} = \frac{\mathrm{ECSA}}{A_{\mathrm{geo}}}
SímboloSignificadoUnidades
C_{dl}capacitancia de doble capa (pendiente × 1000)mF
vvelocidad de barridoV s⁻¹
C_scapacitancia específica (por defecto 0.040)mF cm⁻²
ECSAárea electroquímicamente activacm²
RFfactor de rugosidad (si se da A_{\mathrm{geo}})—

Incertidumbre (k=1): error estándar de la pendiente de la regresión lineal. C_s es un valor del usuario, sin incertidumbre.

Código: matlens/core/echem.py::delta_current, matlens/core/echem.py::cdl_from_series.

Origen y validez. En la región no faradaica la doble capa se comporta como un condensador: i = C_{dl}\,v con signo opuesto en cada barrido, así que (i_a - i_c)/2 = C_{dl}v. Falla si hay corriente faradaica a E_0 (reacciones redox de superficie, pseudocapacitancia), si la resistencia no compensada distorsiona el barrido (a v altas la respuesta deja de ser rectangular) o en electrodos porosos donde C_{dl} depende de v. C_s varía entre materiales y electrolitos (McCrory et al. citan un intervalo amplio), por lo que la ECSA tiene un sesgo sistemático que la incertidumbre no incluye.

Referencia: McCrory et al., J. Am. Chem. Soc. 135 (2013) 16977, doi:10.1021/ja407115p (C_s = 0.040 mF cm⁻² para metales planos en medio básico).

Ejemplo resuelto

Caso sintético: C_{dl} = 0.50 mF, siete velocidades de 5 a 100 mV s⁻¹, \Delta i = 2C_{dl}v con ruido relativo del 2 % (semilla 4); C_s = 0.040 mF cm⁻², A_\text{geo} = 1 cm².

cdl_from_series(v, di, 0.040, 1.0) → C_{dl} = 0.4928 \pm 0.0049 mF (k=1), R^2 = 0.9995, ECSA = 12.32 cm², RF = 12.32.

Sobrepotencial y potencial de inicio

Sobrepotencial a una densidad de corriente objetivo: \eta = E(j_{\mathrm{target}}) - E_{\mathrm{eq}}, con E(j_{\mathrm{target}}) interpolado linealmente en el cruce de la curva con j_{\mathrm{target}} (si hay varios cruces y la curva va en sentido opuesto al signo de j_{\mathrm{target}}, se usa el último; en otro caso el primero).

Potencial de inicio (método del umbral): primer potencial en que \mathrm{sgn}(j_{th})\,(j - j_{\mathrm{base}}) \ge |j_{th}|, interpolado linealmente, con j_{\mathrm{base}} la mediana del primer 5 % de la curva (0 si se desactiva).

Código: matlens/core/echem.py::overpotential_at, matlens/core/echem.py::onset_potential.

Referencia: implementación propia.

Análisis de Tafel automático

\eta = a + b\,\log_{10}|j|

Origen. De Butler–Volmer, j = j_0\left[e^{\alpha_a F\eta/RT} - e^{-\alpha_c F\eta/RT}\right]; cuando |\eta| \gg RT/F (en la práctica |\eta| \gtrsim 50–100 mV) un término domina y \eta = -\frac{\ln 10\,RT}{\alpha F}\log_{10} j_0 + \frac{\ln 10\,RT}{\alpha F}\log_{10} j. Cuándo falla: cerca del equilibrio (ambos términos), a corriente alta (transporte de masa, caída óhmica, burbujas), con mecanismos de varios pasos (la pendiente cambia con \eta) y con corriente capacitiva en barridos rápidos.

Procedimiento:

  1. Se elige la rama (anódica j>0, catódica j<0, o automática: la de mayor \sum|j|) y se filtran |j| entre j_{\min} y j_{\max} si se dan.
  2. Se construye x = \log_{10}|j|, y = \mathrm{sgn}\cdot\eta (reflejado para que la pendiente sea positiva en ambas ramas); con más de 1500 puntos se submuestrea uniformemente.
  3. Se evalúan todas las ventanas contiguas con al menos 8 puntos y al menos 0.5 décadas; se toma la de máximo R^2 (solo pendientes positivas) y, entre las que están a menos de 10^{-5} del mejor R^2, la más ancha.
  4. Mínimos cuadrados ordinarios en esa ventana.
\log_{10} j_0 = -\frac{a}{b}, \qquad \alpha = \frac{\ln(10)\,RT/F}{|b|}
SímboloSignificadoUnidades
\etasobrepotencialV
jdensidad de corriente (unidades de entrada, por defecto mA cm⁻²)mA cm⁻²
bpendiente de Tafel (se informa en mV dec⁻¹)V dec⁻¹
j_0densidad de corriente de intercambio (extrapolación a \eta=0)unidades de j
\alphacoeficiente de transferencia aparente—

Incertidumbre (k=1): \sigma_b de la regresión; para j_0, método delta con la covarianza pendiente–ordenada:

\sigma_{\log j_0}^2 = \left(\frac{\sigma_a}{b}\right)^2 + \left(\frac{a\,\sigma_b}{b^2}\right)^2 - \frac{2a\,\mathrm{cov}(b,a)}{b^3}, \qquad \sigma_{j_0} = j_0\ln(10)\,\sigma_{\log j_0}

Avisos de validez (todos de nivel warning, en TafelResult.validity; ninguna condición produce invalid): sin corrección iR (ir_corrected=False; pendiente sesgada); b > 250 mV dec⁻¹ (control óhmico o de transporte, no cinético); ventana menor de 1 década. Errores (sin resultado): menos de min_points (8) puntos en la rama, o ninguna ventana con la extensión mínima.

Qué no incluye la incertidumbre. Solo el error estadístico de la recta dentro de la ventana elegida (k=1). No incluye la dependencia con la elección de la ventana, los residuos correlacionados de una curva continua (que hacen que \sigma_b subestime la dispersión real), el error de R_u ni el de E_\text{eq}; j_0 es una extrapolación de varias décadas y su incertidumbre relativa real suele ser mucho mayor.

Nota (diferencia con la literatura): \alpha se calcula como (\ln 10\,RT/F)/b, es decir, suponiendo n=1 en b = \ln(10)RT/(\alpha n F); la selección de la región lineal es un criterio automático de máximo R^2, no la elección manual habitual.

Entrada desde tablas de autor (CSV/xlsx sin lector de instrumento; matlens/readers/echem.py::resolve_generic): el potencial y la corriente se asignan por nombre, unidad y referencia del encabezado ("Potential (V vs. RHE)", "E-iR", "j / mA cm⁻²", "η (mV)"). Un potencial corregido por iR tiene prioridad sobre el bruto, y éste sobre un sobrepotencial; los mV se pasan a V. Una tabla de Tafel ya calculada (\log_{10}|j| frente a \eta) se convierte con j = \pm 10^{x}, con el signo del potencial asociado; un |\eta| tabulado frente a una corriente con signo toma el signo de la corriente. La pendiente no depende de esas elecciones de escala o signo (b es invariante a \eta \to \eta + c y a j \to k\,j). Cada asignación que no es una coincidencia directa de encabezado (columna nombrada solo con la muestra, varias candidatas, tabla logarítmica) se informa en meta["column_roles_note"] y como aviso del análisis.

Código: matlens/core/echem.py::tafel_auto.

Referencia: Bard & Faulkner (2001).

Ejemplo resuelto

Caso sintético: rama anódica \eta = 0.060\log_{10}(j/10^{-3}) + 2\times10^{-4} j^2 (V; j en mA cm⁻², término cuadrático que imita la curvatura óhmica/de transporte a corriente alta), 81 puntos en -2.5 \le \log_{10} j \le 1.5, ruido gaussiano de 1 mV (semilla 2).

tafel_auto(eta, j) → ventana \log_{10}|j| \in [-2.50, 0.60] (3.10 décadas, 63 puntos), b = 60.5 \pm 0.15 mV dec⁻¹, R^2 = 0.999623, j_0 = (1.027 \pm 0.013)\times10^{-3} mA cm⁻², \alpha = 0.978 (k=1).

Estado de validez: ok.

El valor verdadero es b = 60 mV dec⁻¹, j_0 = 1\times10^{-3} mA cm⁻²; la diferencia restante es el sesgo del término cuadrático dentro de la ventana elegida, que la incertidumbre k=1 no incluye.

Koutecký–Levich

\frac{1}{j} = \frac{1}{j_k} + \frac{1}{B\,\omega^{1/2}}, \qquad B = 0.62\,n F C D^{2/3}\nu^{-1/6}

Se ajusta 1/j frente a \omega^{-1/2} por mínimos cuadrados lineales, con \omega = 2\pi\,\mathrm{rpm}/60 (rad s⁻¹). B = 1/\text{pendiente}, j_k = 1/\text{ordenada} y

n = \frac{|B|}{0.62\,F C D^{2/3}\nu^{-1/6}\cdot 1000}
SímboloSignificadoUnidades
jdensidad de corrientemA cm⁻²
j_kcorriente cinética (rotación infinita)mA cm⁻²
\omegavelocidad angularrad s⁻¹
Cconcentración (entrada en mol L⁻¹, convertida a mol cm⁻³)mol cm⁻³
Dcoeficiente de difusióncm² s⁻¹
\nuviscosidad cinemáticacm² s⁻¹
Bconstante de LevichmA cm⁻² rad⁻¹ᐟ² s¹ᐟ²

Incertidumbre (k=1): \sigma_n = n\,\sigma_{\text{pend}}/|\text{pend}|; no se propagan errores de C, D ni \nu.

Validez: electrodo de disco rotatorio, flujo laminar, cinética de primer orden; al menos 2 velocidades de rotación. La constante 0.62 corresponde a \omega en rad s⁻¹.

Código: matlens/core/echem.py::koutecky_levich.

Referencia: Bard & Faulkner (2001).

Ajuste de la curva de polarización

E(j) = E_0 - b\log_{10}\frac{j}{j_0} - \frac{j R}{1000} - b\log_{10}\frac{j_{\lim}}{j_{\lim}-j}

(el último término se omite si no se incluye transporte de masa).

SímboloSignificadoUnidades
E_0potencial a corriente nulaV
bpendiente de Tafel (en el código, b en mV dec⁻¹ dividido por 1000)mV dec⁻¹
j_0densidad de corriente de intercambiomA cm⁻²
Rresistencia específica de áreaΩ cm²
j_{\lim}densidad de corriente límitemA cm⁻²

Ajuste: mínimos cuadrados no lineales sin ponderar (lmfit) sobre los puntos con j>0. Límites: 1 \le b \le 1000 mV dec⁻¹, 10^{-12} \le j_0 \le 10^3, R \ge 0, 1.0001\,j_{\max} \le j_{\lim} \le 10^6. Si se da E_{\mathrm{eq}}, E_0 se fija en ese valor. Valores iniciales: b de la recta E frente a \log_{10} j en el tercio de menor corriente; R de la pendiente del residuo de esa recta en el tercio de mayor corriente; j_0 extrapolando desde el primer punto; j_{\lim} = 1.4\,j_{\max}.

Incertidumbre: intervalo de confianza al 95 %, \pm 1.96\,\sigma (k = 1.96) con \sigma el error estándar de lmfit.

Avisos: si E_0 no está fijado, E_0 y j_0 no son separables (solo se determina E_0 + b\log_{10}j_0); si j_{\lim} \le 1.02\,j_{\max}, la región de transporte de masa no está definida.

Código: matlens/core/echem.py::fit_polarization.

Referencias: Bard & Faulkner (2001); O'Hayre et al., Fuel Cell Fundamentals 3rd ed. (2016).

Elementos de circuito equivalente (EIS)

Los circuitos se escriben como texto: serie con -, paralelo con p(a,b,...), p. ej. R0-p(R1,CPE1)-W1. Serie: Z = \sum Z_i; paralelo: Z = \left(\sum Z_i^{-1}\right)^{-1}. Con \omega = 2\pi f:

ElementoImpedanciaParámetros (unidades)
RZ = RR (Ω)
CZ = \dfrac{1}{\mathrm{j}\omega C}C (F)
LZ = \mathrm{j}\omega LL (H)
CPEZ = \dfrac{1}{Q(\mathrm{j}\omega)^{\alpha}}Q (F s^{\alpha-1}), \alpha (—)
W (Warburg semiinfinito)Z = A_W\dfrac{1-\mathrm{j}}{\sqrt{\omega}}A_W (Ω s^{-1/2})
Wo (Warburg finito, frontera abierta/reflectante)Z = Z_0\dfrac{\coth\sqrt{\mathrm{j}\omega\tau}}{\sqrt{\mathrm{j}\omega\tau}}Z_0 (Ω), \tau (s)
Ws (Warburg finito, frontera corta/transmisiva)Z = Z_0\dfrac{\tanh\sqrt{\mathrm{j}\omega\tau}}{\sqrt{\mathrm{j}\omega\tau}}Z_0 (Ω), \tau (s)
G (Gerischer)Z = \dfrac{R_G}{\sqrt{1+\mathrm{j}\omega t_G}}R_G (Ω), t_G (s)

Los elementos Wo y Ws usan el exponente fijo 1/2 (no hay variante con exponente libre). Circuitos predefinidos: R0-p(R1,CPE1), R0-p(R1,CPE1)-W1, R0-p(R1,C1), R0-p(R1,CPE1)-p(R2,CPE2), R0-p(R1,CPE1)-p(R2,CPE2)-W1.

Código: matlens/core/echem.py::Circuit.impedance.

Referencia: implementación propia.

Ajuste complejo no lineal por mínimos cuadrados (CNLS)

Función objetivo, con ponderación por módulo de los datos:

S(\mathbf{p}) = \sum_{i=1}^{N} w_i^2\left[\left(Z'_{\mathrm{mod}}(\omega_i;\mathbf{p}) - Z'_i\right)^2 + \left(Z''_{\mathrm{mod}}(\omega_i;\mathbf{p}) - Z''_i\right)^2\right], \qquad w_i = \frac{1}{|Z_i|}

Procedimiento:

  • Parámetros positivos se ajustan en escala logarítmica (q = \ln p); los exponentes \alpha de los CPE en escala lineal con límites 0.3 \le \alpha \le 1.
  • Algoritmo: región de confianza (scipy.optimize.least_squares, método trf, x_scale="jac", hasta 400 evaluaciones, tolerancias 10^{-12}).
  • Multiarranque: 6 arranques por defecto (semilla 0); el primero desde el valor inicial y los siguientes con perturbación gaussiana \mathcal{N}(0, 0.8(1+s/3)) en \ln p y \mathcal{N}(0, 0.05) en \alpha; se conserva el de menor coste. Si los valores iniciales vienen del árbol de parámetros, se usa un único arranque (refinamiento).
  • Valores iniciales heurísticos: R_{hf} = \mathrm{Re}\,Z a la frecuencia más alta, R_{lf} a la más baja, R_{tot} = R_{lf} - R_{hf}; \tau = 1/(2\pi f_{pk}) con f_{pk} la frecuencia del máximo de -Z''. La primera R recibe R_{hf}; las demás R_{tot}/n_{ct}; C y Q reciben \tau/(R_{tot}/n_{ct}) con \alpha = 0.9; L = 10^{-6}; A_W = |Z(f_{\min})|\sqrt{2\pi f_{\min}}/2; Wo/Ws: Z_0 = R_{tot}/n_{ct}, \tau = 1/(2\pi f_{\min}); G: R_G = R_{tot}/n_{ct}, t_G = \tau.
  • Se exige 2N > n_{\mathrm{par}}.

Bondad de ajuste:

\chi^2_{\mathrm{red}} = \frac{S(\hat{\mathbf{p}})}{2N - n_{\mathrm{par}}}

Incertidumbre (k=1): \mathrm{cov}(\mathbf{q}) = (J^\top J)^{-1}\chi^2_{\mathrm{red}} con el jacobiano en el espacio transformado; para parámetros en escala logarítmica \sigma_p = p\,\sigma_q (primer orden), para \alpha directamente \sigma_q.

Detalles adicionales leídos del código: se descartan frecuencias no finitas o \le 0 y se aplica el filtro f_\min \le f \le f_\max; los valores iniciales no positivos se sustituyen por 10^{-9}; en el espacio logarítmico q se recorta a [-60, 60] antes de exponenciar; el arranque perturbado se recorta a los límites (\pm10^{-6}). Un arranque que lanza una excepción se ignora; si todos fallan, error "El ajuste de impedancia no convergió". success refleja el indicador de convergencia de SciPy del mejor arranque; no hay avisos de validez en el resultado.

Ponderación y significado de \chi^2_\text{red}. Con w_i = 1/|Z_i| los residuos son relativos; si el ruido es proporcional a |Z| con desviación relativa \sigma_r en cada parte, \chi^2_\text{red} \approx \sigma_r^2 (no 1). Por eso \chi^2_\text{red} sirve para comparar modelos sobre los mismos datos, no como prueba absoluta.

Qué no incluye la incertidumbre. Es la aproximación lineal local (jacobiano) escalada por el residuo, k=1; no recoge la no linealidad (intervalos asimétricos), la correlación entre parámetros del mismo arco (p. ej. Q y \alpha), la posibilidad de mínimos locales distintos, ni el error del modelo de circuito (varios circuitos pueden ajustar igual de bien).

Código: matlens/core/echem.py::fit_eis, matlens/core/echem.py::Circuit.initial_guess.

Referencia: implementación propia.

Ejemplo resuelto

Caso sintético: circuito R0-p(R1,CPE1), 61 frecuencias logarítmicas de 10^5 a 10^{-1} Hz, ruido complejo gaussiano proporcional del 0.5 % en cada parte (semilla 3).

fit_eis("R0-p(R1,CPE1)", f, Z) (6 arranques, semilla 0):

ParámetroVerdaderoAjustado\sigma (k=1)
R02019.9830.029
R1150149.950.19
CPE1_02e-052.0023e-051.9e-07
CPE1_10.880.879680.0012

\chi^2_\text{red} = 3.01e-05 con 61 frecuencias (con pesos 1/|Z| y ruido relativo \sigma_r = 0.005 se espera \chi^2_\text{red} \approx \sigma_r^2 = 2.5\times10^{-5}).

Magnitudes derivadas (eis_derived): Rct = 149.9, Cdl = 6.75e-06, alpha = 0.8797, Rs = 19.98.

lin_kk(f, Z) → M = 18, \mu = 0.811, |residuo| medio = 0.40 %, máximo = 1.49 % → no cumple el criterio del 1 %.

Capacitancia efectiva de un CPE (Brug)

Con resistencia en serie R_s conocida:

C_{\mathrm{eff}} = Q^{1/\alpha}\left(\frac{1}{R_s} + \frac{1}{R_p}\right)^{(\alpha-1)/\alpha}

Sin R_s (forma de Hsu–Mansfeld usada por el código):

C_{\mathrm{eff}} = \left(Q\,R_p^{1-\alpha}\right)^{1/\alpha}

En eis_derived, R_{ct} es la primera R de la primera rama paralela que contiene una R y un CPE/C, y R_s es la primera R del circuito (si es distinta de R_{ct}). Si el elemento es un C puro, C_{dl} = C. No se propaga incertidumbre a C_{\mathrm{eff}}.

Código: matlens/core/echem.py::brug_capacitance, matlens/core/echem.py::eis_derived.

Referencia: Brug, van den Eeden, Sluyters-Rehbach & Sluyters, J. Electroanal. Chem. 176 (1984) 275, doi:10.1016/S0022-0728(84)80324-1.

Validación Lin-KK (Kramers–Kronig)

Modelo de M elementos de Voigt en serie con una resistencia óhmica y, opcionalmente, una inductancia:

Z_{\mathrm{KK}}(\omega) = R_0 + \sum_{k=1}^{M}\frac{R_k}{1+\mathrm{j}\omega\tau_k} + \mathrm{j}\omega L

Los \tau_k están espaciados logarítmicamente entre 1/\omega_{\max} y 1/\omega_{\min}. Los coeficientes (R_0, R_k, L) se obtienen por mínimos cuadrados lineales sobre partes real e imaginaria juntas, con peso 1/|Z_i| (sin restricción de signo). El número de elementos crece desde M_{\min} = \lceil 3\cdot\text{décadas}\rceil (décadas \ge 1) hasta que

\mu = 1 - \frac{\sum_{R_k<0}|R_k|}{\sum_{R_k\ge 0}|R_k|} \le c, \qquad c = 0.85

o hasta M_{\max} = \max(N-2, 3) o 2N \le M+3. Residuos relativos (%):

\Delta_{\mathrm{re},i} = 100\,\frac{Z'_i - Z'_{\mathrm{KK},i}}{|Z_i|}, \qquad \Delta_{\mathrm{im},i} = 100\,\frac{Z''_i - Z''_{\mathrm{KK},i}}{|Z_i|}

Criterio: los datos se consideran consistentes con Kramers–Kronig si el máximo de |\Delta| es menor que 1 %. Este umbral se aplica al máximo, de modo que depende del nivel de ruido y del número de frecuencias: con ruido gaussiano relativo de 0.5 % y unas 120 componentes, el máximo esperado de |\Delta| ya ronda el 1 % aunque el sistema sea lineal y estable (véase el ejemplo resuelto del ajuste CNLS). Compare el residuo medio con el nivel de ruido y busque tendencias sistemáticas antes de descartar un espectro.

Nota (diferencia con la literatura): Schönleber et al. aumentan M desde valores pequeños; MatLens empieza en \lceil 3\cdot\text{décadas}\rceil porque el criterio \mu solo se detiene demasiado pronto en mallas gruesas. No se incluye capacitancia en serie. El umbral del 1 % es una regla del código.

Código: matlens/core/echem.py::lin_kk.

Referencia: Schönleber, Klotz & Ivers-Tiffée, Electrochim. Acta 131 (2014) 20, doi:10.1016/j.electacta.2014.01.034.

Distribución de tiempos de relajación (DRT)

Núcleo (bases constantes a trozos sobre \ln\tau):

Z(\omega) = R_\infty + \sum_{k=1}^{K}\gamma_k\,\frac{\Delta\ln\tau}{1+\mathrm{j}\omega\tau_k}

con K = 80 valores de \tau espaciados logarítmicamente entre 10^{-1}/\omega_{\max} y 10^{+1}/\omega_{\min} (extensión de 1 década a cada lado por defecto) y R_k = \gamma_k\,\Delta\ln\tau.

Objetivo (Tikhonov con penalización de segunda derivada, resuelto por mínimos cuadrados no negativos, NNLS):

\min_{R_\infty \ge 0,\ \boldsymbol{\gamma}\ge 0}\ \left\|W\left(A\begin{bmatrix}R_\infty\\ \boldsymbol{\gamma}\end{bmatrix} - \mathbf{z}\right)\right\|^2 + \lambda\,\|L\boldsymbol{\gamma}\|^2

donde A apila partes real e imaginaria, W = \mathrm{diag}(1/|Z_i|) y L es la matriz de segundas diferencias (1,-2,1) sobre \boldsymbol{\gamma} (no actúa sobre R_\infty).

SímboloSignificadoUnidades
\gamma_kdensidad de la DRT en \ln\tauΩ
R_\inftyresistencia de alta frecuenciaΩ
\tau_ktiempo de relajacións
\lambdaparámetro de regularización—

El sistema NNLS apila \sqrt{\lambda}\,L bajo WA, de modo que la penalización es exactamente \lambda\|L\gamma\|^2, como en Wan et al.

Elección de \lambda: si no se indica, se resuelve para 25 valores geométricos entre 10^{-10} y 1 y se elige la esquina de la curva L (máxima curvatura de \ln\|\text{residuo}\| frente a \ln\|L\gamma\|, excluyendo extremos).

Picos: regiones contiguas con \gamma > 0.02\,\gamma_{\max}; cada pico da \tau en el máximo, f = 1/(2\pi\tau) y R = \sum\gamma_k\,\Delta\ln\tau.

Avisos: residuo relativo rms \sqrt{\langle|Z-Z_{\mathrm{fit}}|^2/|Z|^2\rangle} > 2\,\%; más del 5 % de \sum\gamma en los dos primeros o dos últimos puntos (procesos fuera de la ventana). Requiere al menos 10 frecuencias. No se estima incertidumbre de \gamma.

Nota (diferencia con la literatura): se usan funciones base constantes a trozos en lugar de las funciones de base radial de Wan et al., y se impone no negatividad.

Código: matlens/core/echem.py::drt.

Referencias: Wan, Saccoccio, Chen & Ciucci, Electrochim. Acta 184 (2015) 483, doi:10.1016/j.electacta.2015.09.097; Hansen, SIAM Rev. 34 (1992) 561, doi:10.1137/1034115 (curva L).

Estabilidad

\text{retención} = 100\,\frac{\bar y_{\mathrm{fin}}}{\bar y_{\mathrm{ini}}}

con \bar y_{\mathrm{ini}} y \bar y_{\mathrm{fin}} promedios sobre el primer y último 2 % de los puntos (mínimo 2). Velocidad lineal: pendiente de y frente a t (h) por mínimos cuadrados, también como 100\,\text{pend}/\bar y_{\mathrm{ini}} (% h⁻¹). Decaimiento exponencial (si y no cambia de signo): \ln|y| = c - k t por regresión lineal, t_{1/2} = \ln 2/k (si k>0).

Nota (diferencia con la literatura): el ajuste exponencial es log-lineal sin asíntota (y_\infty = 0), no un ajuste no lineal con y_\infty libre.

Código: matlens/core/echem.py::stability.

Referencia: implementación propia.

Eficiencia faradaica y TOF

\mathrm{FE}_i = 100\,\frac{z_i\,n_i\,F}{Q}, \qquad j_i = \frac{\mathrm{FE}_i}{100}\,j_{\mathrm{total}}, \qquad \mathrm{TOF}_i = \frac{n_i}{n_{\mathrm{sitios}}\,t}
SímboloSignificadoUnidades
z_ielectrones por molécula de producto—
n_icantidad de productomol
Qcarga transferida (>0)C
j_idensidad de corriente parcialunidades de j_{\mathrm{total}}
n_{\mathrm{sitios}}moles de sitios activosmol
ttiempo de electrólisiss
TOFfrecuencia de recambios⁻¹

Valores de z tabulados: CO 2, HCOOH 2, H₂ 2, CH₄ 8, C₂H₄ 12, EtOH/C₂H₅OH 12, CH₃OH 6, C₂H₆ 14, n-PrOH 18, CH₃COOH 8, O₂ 4, NH₃ 8. Se informa la FE total \sum\mathrm{FE}_i; la lista de verificación de CO2RR la considera correcta si |\sum\mathrm{FE}_i - 100| \le 5\,\%. Sin incertidumbre propagada.

Código: matlens/core/echem.py::faradaic_efficiency, matlens/core/echem.py::co2rr_checklist.

Referencia: Bard & Faulkner (2001).

Generado desde MatLens c0ab138. ← Todas las técnicas