Siru en Simusol · Documentación · Manual
Referencia central: Gramática .ds y .d (fuentes: slex/d2datdinc/doc/GRAMATICA.md), con su sección en Simusol.
Este directorio reúne la documentación general de Siru. Las órdenes de compilación, instalación y pruebas de estos documentos se ejecutan desde la raíz del programa (siru/siru, el directorio superior), salvo que se indique otra ubicación.
| Documento | Contenido |
|---|---|
| MANUAL.md | Uso del programa, gramática .ds, FORMAS y RK=[-1]. |
HECHO.md y ChangeLog (fuentes: siru/doc/ChangeLog) |
Estado de implementación e historia de cambios. |
| CATALOGO_INTEGRADORES.md y METODOS_INTEGRACION.md | Métodos y familias de integración. |
| CONTRATO_PASO.md, GLM_CONTRATO.md, ROS.md e IMEX.md | Contratos y funcionamiento de los motores. |
PLAN*.md, DISENO_GLM.md, REVISION_GLM_PLAN.md, ESPECIFICACION_MULTIPASO.md, ARS222.md, BDF2_VARIANTES.md |
Diseño, planes y fundamentos numéricos. |
man/ |
Fuentes de las páginas siru(1), dat2din(1) y siru-relaja(1); instaladas, se consultan con man. |
| Siru en simusol.org | Presentación pública, instalación, manual navegable y ejemplos descargables. Fuentes y publicación en web/. |
Corpus (fuentes: siru/corpus/README.md) y ejemplo de Monte Carlo (fuentes: siru/ejemplos/montecarlo-gpu/LEEME.md) |
Documentación específica, junto a sus archivos de trabajo. |
Mapa global de entradas, salidas, archivos y pantallas de todos los paquetes (fuentes: MAPA-FLUJOS.txt): incluye el camino de cálculo, gráficos, Puyuspa, bibliotecas, distribución y ramas históricas; distingue lo actual de la política acordada.
Regla común acordada, pendiente de implementación: la salida nueva conserva el nombre original y el archivo anterior pasa a NOMBRE_vN.EXT, con numeración creciente y sin sobrescribir respaldos. Reemplazará el comportamiento actual que numera la salida nueva como circuito-1.simul. Alcance y publicación segura: política de archivos del conjunto (fuentes: POLITICA-ARCHIVOS.txt).
La política también exige entrada completa por stdin y resultados por stdout, sin generar archivos salvo con -save. Los gráficos se mostrarán en X por defecto; -noX suprime la ventana y -save guarda SVG. Estas opciones deberán propagarse a los graficadores. Todavía no está implementado ese comportamiento general: lo que se describe a continuación es el funcionamiento actual.
Si el dato contiene GLOBAL.formas (sección FORMAS, aun vacía), Siru genera NOMBRE.svg usando el paquete opcional dibuja. Si falta el programa o falla el dibujo, la simulación continúa; el detalle queda en el .log. Formato, ejemplos y funcionamiento independiente de dibuja.
Al terminar correctamente, Siru llama a Simplot y le envía por un pipe la descripción gráfica ya leída (RESULTADOS/PARAPLOT, unidades y OUTPUTS) y todos los bytes de la tabla calculada. Simplot recibe por --stdin: no abre el .ds ni el .simul de Siru. El archivo de resultados se conserva como registro; no es el medio de comunicación. siru -nosimplot circuito.ds desactiva esa llamada (también acepta --nosimplot). Los gráficos quedan en NOMBRE-simplot/; sin entorno gráfico genera archivos sin abrir ventanas. Si Simplot falta o falla, avisa y conserva la simulación correcta; los detalles quedan en el .log. Desde los fuentes usa el Simplot hermano; instalado lo busca en PATH. SIRU_SIMPLOT=/ruta/simplot permite elegir otro ejecutable. Véase el contrato de entrada estándar (fuentes: simplot/doc/DAT-PARAPLOT.md).
Cómo usarlo —qué se puede escribir en un .d o un .ds, cuál usar y cómo correrlo— está en MANUAL.md; lo hecho hasta el 30/09/2026, con lo que falta y lo que no está verificado, en HECHO.md.
El registro de cambios por revisión, a partir de r2180, está en ChangeLog (fuentes: siru/doc/ChangeLog).
El corpus de circuitos y sus herramientas (clasificar, sceptre, exactas, convergencia, compara-dat...) están en corpus/ (fuentes: siru/corpus/README.md), dentro del programa desde r2275. Simul 1, el simulador anterior, está en ../siruviejo respecto de la raíz del programa (hasta r2275, Simul/); ahí quedó también LLAVES.md, que este código cita en todas partes.
Se corre desde la raíz del programa (perl bin/siru) o instalado: hacer-pkg arma el paquete siru (/usr/bin/siru, los módulos Siru::*, las páginas de manual de doc/man/ y esta documentación), que depende de los paquetes d2datdinc y calcula; ../instalar lo arma y lo instala junto con los demás del repositorio. Ver MANUAL.md, §1.
siru separa la creación del sistema de su integración temporal. El camino directo es .d → slex/d2datdinc → .din ampliado → bin/siru: la simulación no necesita un .dat aparte. El camino histórico por .dat y bin/dat2din sigue disponible. El diseño original está en PLAN.md.
El orden de las próximas ampliaciones está en PLAN_CAPACIDADES_MOTOR.md: primero capacidades del motor (intentos, historia, evaluaciones, particiones y demás operaciones), cada una con un método mínimo de verificación; después ampliación de catálogos. Es un plan, no una lista de funciones ya disponibles.
Avance del 2026-10-06: CONTRATO_PASO.md cubre GLM y el conductor compartido RK/PGLM/ROS/SPLIT. Se corrigió la historia del predictor, se extrajeron el control de paso y el anillo físico, y GLM incorpora adaptación optativa. ROS2 usa servicios numéricos y un motor de etapas extensible; SPLIT incorpora el primer bloque de M4. Orden variable, listas GLM, ampliaciones de M4 y las etapas M5–M8 siguen pendientes.
Entrega Debian siru 1.0-3 junto con slex/d2datdinc 1.0-24; requiere calcula >= 6.0-37. Incluye M1–M3 iniciales y SPLIT (M4 inicial). M5 está especificado en el plan (r2451), pero todavía no implementado: SIRU_SALIDA_PASO y SIRU OUTPUT STEP no son opciones disponibles. Los paquetes se generan con slex/hacer-pkg y siru/hacer-pkg, desde la raíz del repositorio, y quedan en esos directorios; generarlos no los instala.
Composición de subflujos: SPLIT=[1] selecciona Lie–Trotter y SPLIT=[2], Strang. El modelo declara dos mapas autónomos exactos con SPLIT_A/SPLIT_B; Calcula evalúa cada subavance y el conductor confirma solo la composición completa. El primer contrato exige paso fijo y .din simple: no admite dependencia temporal, subintegradores aproximados ni eventos. No deduce una partición de las ecuaciones ni verifica simbólicamente que los mapas sean los flujos exactos. Uso en MANUAL.md; contrato y continuación en PLAN_CAPACIDADES_MOTOR.md.
Rosenbrock se selecciona con ROS=[1] (ROS2, orden dos): motor independiente con evaluaciones del campo reducido en Calcula, Jacobiano numerico y una factorizacion lineal reutilizada en dos etapas. Funciona desde .d, .ds, .dat o .din autosuficiente, con paso fijo o adaptativo embebido 2(1), sin cambios de topologia. SIRU_ADAPT=[0] conserva paso fijo; [1] activa adaptacion con las tolerancias y limites SIRU existentes. Uso, costo y limites numericos en ROS.md; decisiones y siguientes ampliaciones en PLAN_ROS.md.
IMEX aditivo se selecciona con PGLM=[1] (Euler, orden uno) o PGLM=[2] (ARS222, orden dos), con particion explicita declarada por estado y .din autosuficiente. Ambos usan un generador comun desde tablas aditivas del catalogo. Sintaxis, limites y ejemplos en IMEX.md; conclusiones y ampliacion a otras familias en PLAN_MOTORES_IMEX.md. RK y GLM mantienen sus caminos anteriores.
El protocolo --machine está en Calcula y el adaptador Perl en lib/Siru/Calcula.pm. Calcula se inicia una sola vez y permanece vivo entre consultas. El conductor en lib/Siru/Integrador.pm pide el estado siguiente: en RK/PGLM lo obtiene del sistema ampliado; en ROS lo proporciona el motor que consulta las derivadas del modelo. bin/siru lee el .din (o el circuito: ver «Llaves, lazos y cortes»), encadena los pasos y publica la salida solo al completar la simulación. La salida es un .simul, el formato de Simusol, con el nombre del archivo; con --salida ARCHIVO.csv sale un CSV. La escribe Siru::Salida, que es el único escritor.
ROS admite tolerancias temporales por estado: ROS_TOLERANCIAS=[X,1e-11,1e-4,Z,10,1e-4], con respaldo global para los omitidos y descriptor v4 autosuficiente. El informe .informe registra intentos, pasos aceptados/rechazados y consultas a Calcula; diferencia EVAL del campo, OUTPUTS y SENS. El proveedor optativo ROS_JACOBIANO=[SENSIBILIDADES] genera v5 y requiere SENS1 de Calcula; evita resolver nuevamente el modelo en cada perturbacion del Jacobiano. Uso y limites en ROS.md; estado y continuidad en PLAN_ROS.md.
siru también recibe el archivo mismo, .d, .ds o .dat (Siru::Circuito). siru no arma ecuaciones: las arma libdin (slex/din), que es el único armador, y siru se las pide por d2datdinc (desde 2026-09-30; antes había un segundo armador en Perl, Siru::Mdin. Ver PLAN_UN_ARMADOR.md y siruviejo/LLAVES.md 13).
La corrida es una sola para todo lo que se integra —sin circuito, circuito común, con llaves, con lazos o cortes, con varios métodos de Runge–Kutta—. Antes de cada paso se mira la configuración de ese paso, que es (estado de las llaves, método), y si todavía no tiene su sistema se lo prepara ahí (Siru::Preparador: d2datdinc --din N --llaves S1=1,S2=0). Nunca se prepara de antemano: con n llaves serían 2^n. Lo que no se integra —sin estados— lo resuelve Calcula punto a punto (Siru::UnPunto): una vez, o una por T de la grilla si el archivo pidió corrida (MANUAL 12). Cuál es el caso lo dice el selector, Siru::Circuito::caso, que pregunta con d2datdinc --topologia y no arma nada.
Lo que libdin no pudo traducir queda en el .din como # PENDIENTE, y con alguno el archivo no se simula: siru dice cuáles son.
El archivo recibe del simulador tres cosas, que no fija: T, el tiempo; DT, el paso que se está usando; y TICK, la cantidad de pasos dados. Un circuito puede traer ecuaciones propias (EQUATIONS con sus VARIABLES). Y las paradas de RUN CONTROLS sobre una variable (TICK>1000) se evalúan al empezar cada paso. Ver siruviejo/LLAVES.md 13.
SB) y arma la configuración: un dígito por llave, en el orden en que las nombra d2datdinc --topologia, 1 cerrada y 0 abierta;NOMBRE-<bits>.mdin (la integración) y, si la configuración tiene lazos de capacitores (con o sin baterías) o cortes de bobinas (con o sin fuentes de corriente), NOMBRE-<bits>E.mdin (el equilibrio: el trasvase instantáneo de carga o de flujo, que entra con pre_ESTADO y sale con ESTADO);En una configuración con lazo o corte la integración lleva la ley del lazo (o del corte) en derivadas, I1/C1 = I2/C2 o V1/L1 = V2/L2, en vez de la ley misma: en las etapas explícitas de un Runge-Kutta (Lobatto IIIA, Heun...) la ley quedaba sobre datos y el reparto de corriente sin determinar (jacobiano singular); la derivada anda con cualquier método, y la ley se cumple sola porque el estado arranca equilibrado. Un circuito sin llaves es una sola configuración (NOMBRE.mdin, y NOMBRE-E.mdin si tiene lazos o cortes). tests/llaves.t corre los cuatro ejemplos de siru/corpus/llaves_equilibrio y verifica el trasvase.
Las llaves se evalúan solo al comienzo de cada paso: si una condición cambia en medio de un paso, la llave cambia en el siguiente (decisión del autor). Al evaluarlas, t se redondea a 12 cifras, porque el t acumulado trae redondeo (diez pasos de 0.1 dan 0.9999999999999999, y T<1 tiene que dejar de valer en el paso que empieza en 1). La condición de una llave puede usar cualquier variable del circuito (voltajes y corrientes de rama, estados, parámetros, T): se evalúa con el instante de la configuración vigente (din_instante de libdin: el circuito en t, con los estados como datos); al arrancar, desde todas abiertas hasta que la configuración no cambie. Una fuente que varía en un lazo o un corte entra en la ley en derivadas con su derivada: la del .d si el modelo la declara (DVOLTAGE, DCURRENT; por ejemplo un tipo propio EV(2) = IF: VOLTAGE, VOLTAGE + x1, DVOLTAGE + x2 en ELEMENT DEFINITION, o ESIN), y si no la numérica, (f(t+h) - f(t-h))/(2h) con h = 1e-6 (ejemplos lazo-bateria-variable-llave.d y ...-numerica-llave.d, que dan lo mismo).
d2datdinc --din circuito.d
perl bin/siru circuito-de-d2datdinc-ED12.din
El número ED depende del método RK elegido en el .d. El .din ampliado generado lleva la corrida adentro, en secciones comentadas: # corrida (desde, hasta, paso y tiempo, que nombra la variable del tiempo), # adaptacion, # parametros y # estados, una línea por estado con actual siguiente inicial estimacion. Van comentadas porque Calcula compila con ExprTk toda línea que no sea comentario. No contiene rutas del equipo, ni hay un archivo de configuración al lado. siru usa el archivo recibido como sistema y, por omisión, escribe un CSV con el mismo nombre base. Para un Calcula instalado en otra ruta se indican --calcula EJECUTABLE y --bibliotecas DIR; --salida ARCHIVO cambia el CSV. Los .din anteriores sin esas secciones deben regenerarse.
El archivo conserva el nombre del sistema y termina en -EDNRO.din, donde NRO es el número histórico de Runge–Kutta de Simul: Euler explícito es 0. El ejemplo ejemplos/circuito-rlc-ED0.din agrega dt, tres variables de estado siguiente y sus ecuaciones de Euler. Tiene 22 variables y 12 ecuaciones, por lo que recibe diez datos por paso: seis parámetros, tres estados actuales y dt.
El .din base declara cada relación necesaria para integrar mediante una línea # @estado nombre derivada. Por ejemplo, # @estado il2 dil2dt. Calcula ignora esos comentarios; no afectan su uso independiente. dat2din produce automáticamente esas anotaciones al leer el .dat y genera el -EDNRO.din desde los mismos datos. Además, cada ecuación lineal en las incógnitas, con los datos del sistema, termina en # @lineal (parámetros y estados; en el ampliado, también dt). Calcula puede aprovecharla para no recalcular el jacobiano, y la verifica: ver calcula-6.0/RESOLUCION.md §4.4. Se marca solo lo que se sabe lineal: Kirchhoff, las tensiones de rama, las sumas de Butcher y los modelos que no dividen, elevan ni pasan una incógnita a una función. slex/din marca con el mismo criterio. El -ED0 del ejemplo anterior sigue siendo una versión escrita a mano; generar un ampliado a partir de un .din arbitrario ya existente queda pendiente.
ejemplos/circuito-rlc-ED0.din lleva la corrida en sus secciones: cada estado actual con su variable siguiente, los parámetros y el intervalo. Para probarlo sin escribir en el árbol:
cd ~/svn/calcula/calcula-6.0 && make -j2
cd ~/svn/siru/siru
perl bin/siru --salida /tmp/circuito-rlc-ED0.csv ejemplos/circuito-rlc-ED0.din
La salida contiene t,il2,il23,vc3, con 17 cifras y una fila por estado, incluido el inicial. siru no pisa una salida existente —escribe NOMBRE-1.simul, -2..., con su .informe del mismo nombre— ni publica una trayectoria incompleta si falla un paso.
El paso fijo sigue siendo el comportamiento por defecto. La adaptación se declara en el .d (y va a la sección # adaptacion del .din). paso es entonces el tamaño inicial; los límites paso_min y paso_max son opcionales. absoluto debe ser positivo y relativo no negativo. orden_error es el exponente del error local usado por el controlador: 2 para la diferencia Heun/Euler; 3 para comparar pasos de un método de orden 2. No se infiere automáticamente del número de etapas.
# adaptacion
# metodo embebido
# orden_error 2
# absoluto 0.000001
# relativo 0.0001
# paso_min 1e-12
# paso_max 0.1
embebido requiere que cada estado tenga una salida estimacion (por ejemplo q_il2). Cuando el método RK trae bc, los generadores Perl y C agregan esas variables y ecuaciones al .din y sus nombres a la sección # estados. Los coeficientes b producen p_estado y los bc producen q_estado; la diferencia controla el error sin resolver de nuevo las etapas. Para un método sin bc, metodo doble: siru compara un paso completo con dos medios, acepta el resultado de los dos medios y necesita tres consultas a Calcula por intento. En ambos casos un intento rechazado no agrega fila al CSV; si no se alcanza la tolerancia en el paso mínimo o tras intentos_max intentos, falla sin publicar la trayectoria. Los errores del resolvedor se informan y no se convierten automáticamente en reintentos.
La revisión y plan de continuación de GLM dio lugar al generador matricial compartido y a las correcciones de selección y caché. El contrato implementado detalla el catálogo, la memoria, los ejemplos y los límites actuales.
GLM=[ID] en RUN_CONTROLS de un .d o .ds selecciona el motor alternativo. Los IDs pertenecen a un catálogo propio y no son índices RK.
| Selector | Método | Sistema que compila libdin | Historia |
|---|---|---|---|
GLM=[1] |
Euler explícito | Bloques GLM propios, sin usar RK 0 | 1 estado |
GLM=[20] |
BDF2 por datos efectivos; operativo | Euler implícito (RK 1), con datos efectivos | 2 estados |
GLM=[21] |
BDF2 directo; operativo | Bloques GLM con historia declarada en .din |
2 estados |
GLM=[30] |
Adams–Bashforth 2; operativo | Bloques GLM con memoria de derivadas | Estado y derivada anterior |
RUN_CONTROLS
GLM=[20]
SIRU_PASO=[0.1]
SIRU_ADAPT=[0]
BDF2 arranca con Euler implícito y después usa dos estados aceptados. GLM 20 los combina como datos efectivos del sistema Euler; GLM 21 los entrega como memoria de las ecuaciones BDF2. Ambas variantes recalculan coeficientes para el último paso desigual. AB2 arranca con Euler explícito y conserva derivadas, reescalando la memoria al cambiar el paso final. --din sin número respeta el selector GLM del dato; también están --din-glm ID, --din-bdf2 y --din-bdf2-directo. Los .din llevan el descriptor completo en comentarios y se ejecutan sin un .dat vecino. GLM 1 usa ahora -GLM1.din para conservar su identidad; RK mantiene -EDNRO.din.
Los cuatro IDs admiten paso fijo o adaptativo en .din simple. Con SIRU_ADAPT=[1], los controles de paso y tolerancia existentes seleccionan el estimador glm_arranque, de orden de error 2: BDF2/AB2 se comparan con Euler; el arranque y Euler se estiman con dos medios pasos independientes. Se acepta el candidato principal, no la comparación. Es un estimador conservador, no uno del error local de orden tres de BDF2 ni un algoritmo de orden variable. Los .din nuevos llevan descriptor v2; los v1 siguen funcionando a paso fijo. Detalles, límites de razón y ejemplos en GLM_CONTRATO.md.
Siguen sin admitirse listas múltiples, llaves, lazos, cortes, RERUN ni convoluciones en GLM. El modo adaptativo rechaza DT/TICK en el modelo; GLM 20 mantiene además la prohibición de DT en fijo y verifica la tabla RK 1 antes de usarla. GLM y RK son excluyentes. Ejecutar prove -Ilib tests/*.t para las regresiones; los cuatro ejemplos decaimiento-adaptativo-*.ds están en corpus/corpus/GLM/. Las variantes BDF2 se explican en BDF2_VARIANTES.md.
El lector slex/d2datdinc incorpora controles de RUN CONTROLS al .din ampliado. Los tres nombres de SCEPTRE STARTING STEP SIZE, MINIMUM STEP SIZE y MAXIMUM STEP SIZE fijan paso, paso_min y paso_max. Cualquiera de esos controles activa la adaptación, salvo que se indique SIRU ADAPTIVE STEP = 0. También puede activarse expresamente con SIRU ADAPTIVE STEP = 1.
RUN CONTROLS
STOP TIME = 1
INTEGRATION ROUTINE = TRAP
STARTING STEP SIZE = 0.05
MINIMUM STEP SIZE = 0.000001
MAXIMUM STEP SIZE = 0.1
SIRU ADAPTIVE STEP = 1
SIRU ABSOLUTE TOLERANCE = 0.000001
SIRU RELATIVE TOLERANCE = 0.0001
SIRU ERROR ORDER = 2
END
Las tolerancias y SIRU ERROR ORDER también activan la adaptación por sí solas. El orden vale 2 por omisión, una elección conservadora; para mayor eficiencia conviene declararlo según el método y el estimador. El generador elige embebido si ese RK tiene bc, y doble en caso contrario. Los controles de SCEPTRE MINIMUM/MAXIMUM ABSOLUTE/RELATIVE ERROR no se traducen: representan otra política y no equivalen directamente a estas tolerancias. Las instrucciones anteriores aplican al camino directo .d → d2datdinc → .din. El conversor Perl dat2din también puede leer esos controles si el .dat los trae.
bin/dat2din lee las ramas, nodos, modelos de componentes y coeficientes RK del JSON de Siru. Produce NOMBRE.din y NOMBRE-EDNRO.din, que lleva la corrida en las mismas secciones comentadas que escribe d2datdinc (# corrida, # adaptacion, # parametros, # estados), así bin/siru lo corre sin nada más; no escribe ningún .json (desde el 2026-09-29, como d2datdinc). Sin --rk usa el método seleccionado en el .dat; circuitoB.dat selecciona 3 (Heun). El paso es 0,1 si el dato no indica otro. La adaptación es optativa y no reproduce todas las decisiones del Simul viejo.
mkdir -p /tmp/siru-circuitoB
perl bin/dat2din --directorio /tmp/siru-circuitoB ../siruviejo/perl/data/circuitoB.dat
perl bin/siru /tmp/siru-circuitoB/circuitoB-ED3.din
Por ahora admite ramas RB, LB, CB y EB con un valor numérico constante cada una y nodos conectados al nodo 0. Traduce las ecuaciones de los modelos y genera las leyes de Kirchhoff con potenciales nodales; no importa los módulos Perl antiguos ni sus dependencias SWIG. Otros tipos y valores variables aún no se traducen a un circuito coherente, por lo que dan error. Las secciones globales y los controles no traducidos (incluido un DATABLOB no vacío) quedan como comentarios # PENDIENTE en ambos .din; en ese caso el .din ampliado sale sin las secciones de la corrida, para evitar simular un modelo incompleto. Las ecuaciones de etapas se generan tanto para métodos explícitos como implícitos, pero la verificación numérica automatizada cubre Euler 0, Heun 3 y una corrida de Euler implícito 1. Los métodos con bc generan además la segunda estimación q_estado; la adaptación se activa mediante los controles del dato.
Las expresiones tabla() se conservan sin modificar los nombres de tabla ni de columnas. Si un .dat trae GLOBAL.tablas como objeto nombre → texto de tabular2, el mismo texto pasa a la sección tablas de ambos .din; por ejemplo: {"tablas": {"ntc": "#T R\n0 28704.3\n25 10000"}}. El circuitoB.dat histórico no trae ese campo. Una tabla referida por ruta externa no se copia: debe seguir siendo accesible desde el directorio del .din generado o usarse una ruta absoluta. Las tablas embebidas requieren Calcula 6.0-23 y tabular2 2.0-9 o posteriores.
dat2din se niega a sobrescribir archivos existentes; para otra prueba use un directorio vacío. Pruebas: perl tests/desde_dat.t.
Los dos resuelven el mismo circuito y usan el mismo motor de expresiones, ExprTk. La diferencia no es el lenguaje ni el motor: es cuándo se arma el sistema y quién lo resuelve.
Simul 1 no conoce el .din: no aparece nombrado en ninguna parte de siru/siruviejo. Lee el .dat, que es su formato, y arma las ecuaciones del circuito cada vez que corre. Eso está dicho en Simulparser/DOCUMENTACION.md §3.4: el .dat describe el problema, no su solución.
.d / .ds --[d2datdinc]--------> .dat --> Simul 1, que arma las
ecuaciones al correr
.d / .ds --[d2datdinc --din]--> .din --> Calcula, por siru
El .din es justamente lo que el .dat no trae: el sistema ya armado, y para un método concreto. De ahí que un .dat dé hasta 19 .din, uno por método de Runge–Kutta.
Mientras Simul 1 exista, el .dat hace falta para él.
Simul 1 usa ExprTk desde Perl, por SWIG. El binding está en siru/siruviejo/varios/ExprTk/perl/src/Swig_ExprTk.i: 16 líneas sobre una cabecera de siete funciones, todas con int, double y const char *.
extern int add_equation(const char*, int); devuelve un indice
extern double evaluate(int); calcula esa ecuacion
extern void set_var(int, double); pone un valor
Registra cada ecuación por separado y las evalúa de a una. La orquestación —qué ecuación toca, en qué orden, cuál es explícita y cuál va al solver— es código Perl que corre en cada paso: Math.pm recorre las ecuaciones, evalúa en orden las que puede y manda sólo el núcleo implícito a GSL.
Calcula recibe el sistema entero. El .din trae las variables con su semilla y su dominio, todas las ecuaciones, las funciones y las tablas; compila todo una vez y resuelve con Newton y GSL. No evalúa una ecuación: resuelve un sistema.
| Simul 1 | siru con Calcula | |
|---|---|---|
| dónde vive el sistema | en código Perl, se arma en cada corrida | escrito en el .din |
| qué se le pide al motor | evaluar una expresión | resolver todo junto |
| el método de integración | lo decide el Perl al correr | está adentro del .din (-ED<N>) |
| ExprTk | por SWIG desde Perl | enlazado en C++ |
| cuántas idas y vueltas por paso | una por ecuación | una por el protocolo |
No hay respuesta única, y conviene no suponerla. Calcula resuelve el sistema expandido por etapas con Newton y jacobiano numérico, lo que cuesta del orden de NE² evaluaciones por iteración, con NE ≈ etapas × ecuaciones. Simul 1 evalúa lo explícito directo y resuelve un sistema mucho más chico, pero paga Perl en el lazo interno.
En circuitos chicos debería ganar Calcula, porque domina el costo fijo de Perl; en circuitos grandes, Simul 1, porque el término cuadrático supera a cualquier constante. El cruce depende del circuito y hay que medirlo.
El análisis completo, con lo que se puede mejorar en Calcula, está en calcula/calcula-6.0/RESOLUCION.md.
cd ~/svn/calcula/calcula-6.0
make -j2
cd ~/svn/siru/siru
perl tests/protocolo.t
perl tests/integracion.t
La prueba usa el calcula recién compilado y los sistemas de su árbol de fuentes; no instala nada en el sistema. Comprueba varios estados del circuito RLC en un mismo proceso, errores de dominio, una derivada pequeña, respuestas fragmentadas, stderr abundante, timeout e identificadores equivocados. El formato exacto de intercambio y los códigos de error están en ~/svn/calcula/calcula-6.0/PROTOCOLO-MAQUINA.md.
Ejemplo de uso desde otro módulo Perl:
use Siru::Calcula;
my $sesion = Siru::Calcula->new(
ejecutable => '/ruta/a/calcula',
sistema => 'circuito-rlc',
timeout => 10,
);
my $salida = $sesion->evaluar(
{ e1 => 1, r12 => 1, l2 => 1, l23 => 1, c3 => 1, r3 => 1,
il2 => 0, il23 => 0, vc3 => 0 },
[qw(dil2dt dil23dt dvc3dt)],
);
$sesion->cerrar();
Cuando se usa el binario del árbol de fuentes, hay que indicar LD_LIBRARY_PATH para sus bibliotecas y CALCULA_SISTEMAS para los archivos .sis, como hace tests/protocolo.t. Un Calcula instalado encuentra sus bibliotecas y sistemas por las rutas de instalación.