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ímbolo | Significado | Unidades |
|---|---|---|
| S | pendiente de Nernst por década | V |
| T | temperatura (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:
Para el RHE se usa el pH:
Desplazamientos tabulados (potencial de cada referencia frente a SHE, 25 °C):
| Referencia | E^{\mathrm{vs\,SHE}} (V) |
|---|---|
| SHE | 0.0 |
| SCE | 0.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:
| Símbolo | Significado | Unidades |
|---|---|---|
| E | potencial medido | V |
| I | corriente (oxidación positiva) | A |
| R_u | resistencia no compensada | Ω |
| f | fracció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:
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
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
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:
| Símbolo | Significado | Unidades |
|---|---|---|
| i_p | corriente de pico (se usa su valor absoluto) | A |
| n | electrones transferidos | — |
| A | área del electrodo | cm² |
| C | concentración (entrada en mM, convertida a mol cm⁻³) | mol cm⁻³ |
| v | velocidad de barrido | V s⁻¹ |
| D | coeficiente de difusión | cm² s⁻¹ |
| T | temperatura (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.01 | 5.043 |
| 0.025 | 8.011 |
| 0.05 | 11.27 |
| 0.1 | 15.68 |
| 0.2 | 22.68 |
| 0.4 | 31.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:
| Símbolo | Significado | Unidades |
|---|---|---|
| C_{dl} | capacitancia de doble capa (pendiente × 1000) | mF |
| v | velocidad de barrido | V s⁻¹ |
| C_s | capacitancia específica (por defecto 0.040) | mF cm⁻² |
| ECSA | área electroquímicamente activa | cm² |
| RF | factor 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
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:
- 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.
- 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.
- 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.
- Mínimos cuadrados ordinarios en esa ventana.
| Símbolo | Significado | Unidades |
|---|---|---|
| \eta | sobrepotencial | V |
| j | densidad de corriente (unidades de entrada, por defecto mA cm⁻²) | mA cm⁻² |
| b | pendiente de Tafel (se informa en mV dec⁻¹) | V dec⁻¹ |
| j_0 | densidad de corriente de intercambio (extrapolación a \eta=0) | unidades de j |
| \alpha | coeficiente de transferencia aparente | — |
Incertidumbre (k=1): \sigma_b de la regresión; para j_0, método delta con la covarianza pendiente–ordenada:
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
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
| Símbolo | Significado | Unidades |
|---|---|---|
| j | densidad de corriente | mA cm⁻² |
| j_k | corriente cinética (rotación infinita) | mA cm⁻² |
| \omega | velocidad angular | rad s⁻¹ |
| C | concentración (entrada en mol L⁻¹, convertida a mol cm⁻³) | mol cm⁻³ |
| D | coeficiente de difusión | cm² s⁻¹ |
| \nu | viscosidad cinemática | cm² s⁻¹ |
| B | constante de Levich | mA 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
(el último término se omite si no se incluye transporte de masa).
| Símbolo | Significado | Unidades |
|---|---|---|
| E_0 | potencial a corriente nula | V |
| b | pendiente de Tafel (en el código, b en mV dec⁻¹ dividido por 1000) | mV dec⁻¹ |
| j_0 | densidad de corriente de intercambio | mA cm⁻² |
| R | resistencia específica de área | Ω cm² |
| j_{\lim} | densidad de corriente límite | mA 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:
| Elemento | Impedancia | Parámetros (unidades) |
|---|---|---|
| R | Z = R | R (Ω) |
| C | Z = \dfrac{1}{\mathrm{j}\omega C} | C (F) |
| L | Z = \mathrm{j}\omega L | L (H) |
| CPE | Z = \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:
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étodotrf,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:
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ámetro | Verdadero | Ajustado | \sigma (k=1) |
|---|---|---|---|
| R0 | 20 | 19.983 | 0.029 |
| R1 | 150 | 149.95 | 0.19 |
| CPE1_0 | 2e-05 | 2.0023e-05 | 1.9e-07 |
| CPE1_1 | 0.88 | 0.87968 | 0.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:
Sin R_s (forma de Hsu–Mansfeld usada por el código):
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:
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
o hasta M_{\max} = \max(N-2, 3) o 2N \le M+3. Residuos relativos (%):
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):
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):
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ímbolo | Significado | Unidades |
|---|---|---|
| \gamma_k | densidad de la DRT en \ln\tau | Ω |
| R_\infty | resistencia de alta frecuencia | Ω |
| \tau_k | tiempo de relajación | s |
| \lambda | pará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
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
| Símbolo | Significado | Unidades |
|---|---|---|
| z_i | electrones por molécula de producto | — |
| n_i | cantidad de producto | mol |
| Q | carga transferida (>0) | C |
| j_i | densidad de corriente parcial | unidades de j_{\mathrm{total}} |
| n_{\mathrm{sitios}} | moles de sitios activos | mol |
| t | tiempo de electrólisis | s |
| TOF | frecuencia de recambio | s⁻¹ |
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).