# Plan: BDF2 en la ruta `.din` de siru

**Implementación realizada:** GLM 21 está habilitado mediante el generador común. Sus variables históricas son `glm_h1_y`/`glm_next1_y` y sus coeficientes se suministran como datos `glm_a/u/b/v/c_*`. Los metadatos nuevos usan `metodo GLM` y un descriptor JSON comentado. [GLM_CONTRATO.md](GLM_CONTRATO.md) describe el contrato efectivo. Los apartados siguientes conservan la especificación previa y sus criterios; las referencias a «reservado» o «pendiente» describen el estado anterior, no el actual.

**Actualización de arquitectura (2026-10-04):** seguir primero los hitos de [REVISION_GLM_PLAN.md](REVISION_GLM_PLAN.md). Las ecuaciones, alcance y pruebas de este plan se conservan, pero GLM 21 deberá generarse mediante el contrato común `A,U,B,V,c`, no mediante otra fórmula independiente por ID. Las funciones u opciones específicas mencionadas abajo serán interfaces del generador común. Antes de habilitar GLM 21 deben corregirse la dependencia no validada de RK 1, la colisión de caché y la pérdida del selector GLM al generar el `.din`.

**Estado al redactar el plan original:** solo GLM 20 estaba operativo y GLM 21 estaba reservado. Las dos variantes ya están implementadas; [BDF2_VARIANTES.md](BDF2_VARIANTES.md) explica la diferencia actual. No tomar el futuro verbal de la especificación original de abajo como una lista de funciones aún ausentes.

## Alcance y resultado esperado

Implementar la variante **BDF2 directa (GLM 21)** para sistemas sin llaves, lazos de capacitores ni cortes de bobinas que se simulan mediante un `.din` ampliado. El recorrido buscado es `.d` → `slex/d2datdinc --din-bdf2-directo` → `NOMBRE-BDF2-DIRECTO.din` → `siru/bin/siru NOMBRE-BDF2-DIRECTO.din` → `.simul` (o CSV con `--salida`). El `.din` seguirá siendo autosuficiente: ecuaciones y datos de corrida en el mismo archivo, sin JSON vecino. Calcula permanecerá abierto durante toda la simulación y su protocolo `--machine` no necesita cambios.

El reparto de lenguajes actual es: **`libdin` y `d2datdinc`, que arman las ecuaciones, están en C; `bin/siru` y los integradores de siru, que ejecutan los pasos, están en Perl**. Esta propuesta tiene una parte en C (generar BDF2) y otra en Perl (guardar y suministrar la historia), sin volver a armar ecuaciones en Perl.

Quedan fuera de esta primera etapa los `.mdin`, la conmutación de llaves, los equilibrios de lazos o cortes, el control adaptativo, los cambios de orden y otros métodos multipaso. No se modifica el comportamiento ni el nombre de los `-EDNRO.din` Runge–Kutta. `-BDF2-DIRECTO.din` es un sufijo distinto porque BDF2 no tiene un número en la tabla RK histórica. La generación a partir de un `.din` base arbitrario y el conversor Perl `dat2din` tampoco forman parte del primer entregable: se usa el árbol que `d2datdinc` ya construye directamente del `.d`.

## Ecuaciones en un único `.din`

Para cada estado `y` con derivada `dy`, copiar una vez las ecuaciones del modelo al instante futuro y añadir:

`a0*p_y + a1*y + a2*prev_y = beta*dt*next_dy`

`p_y` y `next_dy` son incógnitas; `y`, `prev_y`, `dt`, `a0`, `a1`, `a2` y `beta` son datos que el integrador proporciona a Calcula en cada consulta. Los nombres concretos se reservarán y validarán contra los del sistema para evitar colisiones. Si el modelo depende del tiempo, la copia futura debe usar `t_next = t + dt`, no el `t` actual. Las ecuaciones del modelo y las marcas `# @lineal` se trasladan con el mismo criterio que hoy usan las etapas RK; la ecuación BDF2 es lineal en las incógnitas cuando sus coeficientes y `dt` son datos.

| Uso del mismo sistema | `a0` | `a1` | `a2` | `beta` |
| --- | ---: | ---: | ---: | ---: |
| Primer paso: Euler implícito | 1 | -1 | 0 | 1 |
| BDF2 con paso constante | 3 | -4 | 1 | 2 |
| BDF2 con último paso acortado, `r = dt/dt_anterior` | `(1+2*r)/(1+r)` | `-(1+r)` | `r*r/(1+r)` | 1 |

El primer paso de Euler implícito obtiene el segundo estado necesario sin inventar un `y` anterior. Es un solo paso de arranque; la convergencia de orden 2 del algoritmo completo se comprobará numéricamente, no se asumirá. El tamaño de paso será fijo salvo el último, que se acorta para llegar exactamente a `hasta`. En ese último paso se usarán los coeficientes BDF2 de razón `r` indicados arriba, calculados con el tamaño del **último paso aceptado**. Si `hasta` cae en el primer paso, se usa únicamente Euler implícito. Rechazar números no finitos y pasos para los que `t + dt == t`.

## Contrato del archivo y selección del método

Extender las secciones comentadas del `.din` sin alterar las existentes para RK: incluir `metodo BDF2_DIRECTO` en `# corrida` y una sección `# historia` que relacione cada estado actual con su variable `prev_y`. La sección `# estados` conserva sus cuatro campos actuales; `estimacion` será `-`, ya que BDF2 no trae un par `bc`. El lector `Siru::Din`, usado por `bin/siru`, debe aceptar `metodo BDF2_DIRECTO` solo cuando todas las variables históricas estén declaradas y la sección sea consistente con las ecuaciones; si falta o es `RK`, ejecutar el camino actual. Rechazar métodos desconocidos y metadatos parciales, en vez de interpretarlos como RK.

La selección principal en un `.ds` será `GLM=[21]`; el número está reservado, pero la selección aún se rechaza hasta implementar el generador y el integrador. `GLM` y `RK` son excluyentes. La opción `--din-bdf2-directo` de `d2datdinc` podrá servir para generar el sistema explícitamente desde un `.d`; no cambia la selección `--din NRO` de RK. Antes de generar un BDF2 ejecutable, reutilizar el análisis de degeneraciones de `main.c`: si el circuito necesita `.mdin` por llaves, lazos o cortes, **fallar con un diagnóstico explícito**. También rechazar modelos con `PENDIENTE`. La salida no debe aparentar ser ejecutable cuando la representación `.din` no alcanza.

El generador incorporará `paso` como paso **fijo**. Hoy algunos controles del `.d` activan automáticamente `# adaptacion`; para BDF2 debe haber una rama específica que no traduzca esos controles en adaptación silenciosa. `SIRU ADAPTIVE STEP = 1`, tolerancias o límites de paso incompatibles con el prototipo deben producir un diagnóstico claro; `SIRU ADAPTIVE STEP = 0` y un paso fijo explícito son admisibles. Mantener la traducción RK actual intacta.

## Cambios por componente

1. **`slex/din/din.c` y `din.h`:** añadir funciones separadas de `din_ampliado`/`din_corrida` para construir y validar el BDF2, sus grados de libertad, ecuaciones, marcas de linealidad y secciones comentadas. Reutilizar la construcción del sistema base y el reemplazo de variables, sin copiar toda la generación RK.
2. **`slex/d2datdinc/dato.c` y `main.c`:** conservar la lista numérica `GLM`, validarla contra `RK`, incorporar `--din-bdf2-directo` como selección explícita, la guarda de degeneraciones y la escritura de `NOMBRE-BDF2-DIRECTO.din`. El camino `--din NRO` queda igual.
3. **`Siru::Din` y `siru/bin/siru` (Perl):** leer `metodo` y `# historia`, comprobar correspondencia uno a uno con `# estados` y pasar un descriptor BDF2 al integrador. Conservar compatibilidad con los `.din` RK existentes.
4. **`Siru::IntegradorGLM` (Perl):** ampliar el motor GLM independiente para separar la preparación de datos de un intento de paso de su aceptación. Para BDF2 conservar el estado actual, el anterior y `dt_anterior`; enviar ambos estados y los cuatro coeficientes a la misma sesión de Calcula. Después de una respuesta válida, desplazar la historia y escribir la fila. Ante fallo de Calcula, abortar sin publicar una trayectoria parcial, como hoy; no transformar automáticamente un fallo del resolvedor en un reintento. Mantener `Siru::Integrador` y su flujo RK sin alteraciones.
5. **Documentación:** añadir el uso de `--din-bdf2-directo`, los límites y la convención `-BDF2-DIRECTO.din` al README, con enlace a `METODOS_INTEGRACION.md`.

## Verificación antes de darlo por terminado

| Prueba | Resultado exigido |
| --- | --- |
| Generación desde un `.d` sencillo | Produce un `.din` BDF2 con las variables históricas, ecuaciones futuras y metadatos consistentes; Calcula lo carga sin símbolos faltantes. |
| Primer paso y dos pasos completos | El primero usa Euler implícito; desde el segundo se aplica BDF2 con la historia efectivamente aceptada. |
| Final no múltiplo de `paso` | Llega exactamente a `hasta` usando la fórmula de razón `r`, sin repetir ni omitir un instante. |
| Problema lineal con solución analítica y tres tamaños de paso | Verifica convergencia global de orden cercano a 2 y datos con al menos 17 cifras significativas. |
| Modelo dependiente del tiempo | Evalúa las ecuaciones en `t + dt`, no en `t`. |
| Circuito con llaves, corte o lazo; `PENDIENTE`; controles adaptativos | Se rechaza la generación BDF2 con diagnóstico específico; no se entrega un archivo engañosamente ejecutable. |
| Error de Calcula, salida preexistente y datos no finitos | La historia no avanza ante error y no se publica una trayectoria parcial ni se pisa el archivo existente. |
| Regresión RK | Los `-EDNRO.din` y las pruebas actuales siguen funcionando sin cambios. |

El primer hito útil es generar y resolver **un paso implícito** con el nuevo `.din`; el segundo es añadir la historia BDF2 y contrastar convergencia; el tercero, el último paso desigual y los rechazos. Cada hito debe quedar probado antes de ampliar el alcance a adaptación o `.mdin`.
