Siru en Simusol · Documentación · Manual

MANUAL

Manual de uso de siru

Referencia central del lenguaje: Gramática .ds y .d (fuentes: slex/d2datdinc/doc/GRAMATICA.md), con modelos, ecuaciones, integradores, FORMAS, PARAPLOT y ejemplos descargables. Versión web.

Cómo describir un circuito —o un sistema de ecuaciones— en un archivo .d o .ds, y cómo correrlo con siru. Cubre todo lo que hoy se puede hacer; lo que no se puede está al final. El porqué de cada cosa está en siruviejo/LLAVES.md, slex/din/README.md y slex/d2datdinc/README.md; lo hecho y lo que falta, en HECHO.md.

El .ds es la descripción completa del problema que se entrega a Siru: reúne las ecuaciones, las incógnitas y sus semillas, los datos conocidos, las constantes, las funciones y, cuando corresponde, las ramas y sus modelos. Siru construye con esa información el sistema de Calcula; el usuario no necesita escribir otro archivo de ecuaciones para Calcula. Si todo está definido dentro del .ds, el archivo es autosuficiente. Si usa include, tablas externas o funciones Fortran, esos archivos referenciados también forman parte del problema y deben acompañarlo.

Con RK=[-1] en RUN_CONTROLS, Siru entrega el sistema a Calcula, le pide una sola evaluación y escribe los resultados en .simul. No hay integración temporal, etapas Runge–Kutta ni avance de estados. Las iteraciones internas que Calcula necesite para resolver el sistema siguen siendo tarea de Calcula. Véanse la gramática de .ds, la sección FORMAS y el modo de un punto.

1. Qué hace falta

El paquete opcional dibuja genera esquemas SVG cuando existe la sección FORMAS, incluso vacía. Para leer esa sección desde .ds hace falta d2datdinc 1.0-26 o posterior. El dibujante también funciona por separado, sin Siru ni Calcula; véanse FORMAS y su manual de instalación y uso.

Para dibujar los resultados, instalar también Simplot (con la opción --stdin). Siru lo llama al final de una ejecución correcta, incluyendo un solo punto, entrada .din y --continuar. siru -nosimplot archivo.ds o siru --nosimplot archivo.din ejecuta solamente el cálculo. Si falta Simplot o falla el gráfico, Siru avisa sin invalidar los resultados. Los mensajes del graficador quedan en el .log de la corrida y los gráficos en NOMBRE-simplot/, junto a su tabla de salida. Con pantalla usa el comportamiento habitual de Simplot; sin DISPLAY ni WAYLAND_DISPLAY produce archivos sin ventanas. No llama al graficador si la simulación falla o si solo se solicita ayuda.

Las instrucciones RESULTADOS/PARAPLOT se leen de la fuente .d, .ds o .dat, vinculadas a la tabla recién escrita, aunque tenga un sufijo numérico o se haya indicado --salida. Las fuentes externas de una comparación se conservan. Para un .din independiente, sin descripción gráfica, Simplot usa la primera columna como abscisa. Siru envía la tabla recién escrita y la descripción gráfica por la entrada estándar de Simplot, también cuando el resultado es CSV; el archivo original se conserva. Las limitaciones del propio Simplot siguen vigentes: por ejemplo, un modelo gráfico v2 con varias corridas debe seleccionar el bloque de su fuente explícitamente.

Hay dos maneras de tenerlo.

Instalado. El paquete siru trae /usr/bin/siru, su página de manual (man siru) y este manual, en /usr/share/doc/siru. Depende de los paquetes d2datdinc (el de slex, 1.0-10 o posterior) y calcula (6.0-34 o posterior, por las tablas con las columnas por número); de Perl usa sólo lo que viene con Perl. Hay dos maneras de instalarlo:

~/svn/siru/instalar --que-hay dice qué hay instalado y en qué versión.

Desde el árbol de fuentes, sin instalar siru:

siru sabe de cuál de las dos maneras corre por dónde está (Siru::Donde): instalado usa el d2datdinc del PATH y los catálogos de su biblioteca (/usr/share/slex/biblioteca); desde el árbol, los de slex/d2datdinc.

2. Correr

Instalado, siru circuito.d. Desde el árbol:

cd ~/svn/siru/siru
perl bin/siru circuito.d
perl bin/siru circuito.ds
perl bin/siru --salida resultado.csv circuito.d
perl bin/siru --calcula ~/svn/calcula/calcula-6.0/src/calcula \
                --bibliotecas ~/svn/calcula/calcula-6.0/src/.libs circuito.d

También acepta un .dat (el JSON de Siru) y un .din ampliado ya generado. --plazo SEGUNDOS es cuánto se espera cada respuesta de Calcula (un paso, un punto): 30 s por omisión en una corrida, 10 s en un punto; un circuito que Newton tarda en resolver necesita más. --paso-factor F corre con el paso multiplicado por F; con paso adaptivo, con las tolerancias por F elevado al orden. Sirve para ver si el resultado cambia al achicar el paso (siru/corpus/convergencia).

Qué deja, al lado del archivo:

archivo qué es
NOMBRE.simul la salida, en el formato de Simusol: una columna por cada nombre de OUTPUTS (sin OUTPUTS, los estados), una fila por paso. Con --salida X.csv, un CSV. Si ya existe no se pisa: la nueva es NOMBRE-1.simul, después -2...
NOMBRE.informe el informe: resultado: (llega al final, para en una condición, no arranca…), hasta dónde llegó y el error si lo hubo
NOMBRE.log todo lo que d2datdinc y calcula dijeron por su salida de errores, cada línea con quién la dijo, y al final el resultado. Es donde se busca el motivo de una falla (sección 13)
NOMBRE[-bits][-rkN].mdin, NOMBRE-[bits]I.mdin, NOMBRE-[bits]E.mdin, NOMBRE-[bits]D.mdin sólo si el circuito tiene llaves, lazos de capacitores, cortes de bobinas o varios métodos: los sistemas de cada configuración (integración, instante, equilibrio, punto de operación DC). Sirven para mirar qué ecuaciones se resolvieron.

Los .din de un circuito común no quedan: viven en un temporal. Para verlos, d2datdinc --din circuito.d los escribe al lado (NOMBRE-de-d2datdinc.din y -ED<N>.din); desde el árbol de fuentes hay que darle -c slex/d2datdinc/d2datdinc.slex -b slex/d2datdinc/biblioteca.

siru no simula un archivo que tenga algo que no sabe traducir: lo dice (PENDIENTE) y termina. Mejor que simular un modelo a medias.

3. .d o .ds: cuál usar

Los dos describen lo mismo con las mismas secciones y las mismas líneas de elementos; el lector es uno solo (d2datdinc) y el sistema que sale es el mismo. Difieren en lo que sigue.

.d (SCEPTRE) .ds (Siru)
de dónde viene lo que Simusol genera para SCEPTRE; el manual de SCEPTRE el formato propio de Siru
tipo de rama por la primera letra del nombre: R1 es RB, C3 es CB, E1 es EB, J1 es JB, L2 es LB, S1 es SB; un tipo propio que sea prefijo del nombre (ESIN1, MW1) explícito, con guión: RB-R1, CB-C3, SB-S1
biblioteca de elementos se incluye sola hay que escribir include .../libraryori.siru (ruta relativa al archivo)
comentarios #, y ; #; ; separa sentencias
secciones con espacio: RUN CONTROLS con espacio o con _: RUN_CONTROLS
fin de la corrida STOP TIME = 5 o T>5 en RUN CONTROLS TIEMPOFINAL=5 en DEFINED_PARAMETERS y T<TIEMPOFINAL en CONTROL_EQUATIONS
método de integración INTEGRATION ROUTINE = TRAP (12), IMPLICIT o XPO (13), RUK (7); sin ella, 13. RK=[...] no se entiende en un .d RK=[12] en RUN_CONTROLS, un índice definido en el catálogo; sin ella, Euler (0)
paso STARTING STEP SIZE = 0.05 STARTING STEP SIZE = 0.05 (desde r1890; también MINIMUM y MAXIMUM), o SIRU_PASO=[0.05]
semilla de calcula SEMILLA VL2 = 0.1 SEMILLA VL2 = 0.1, o VL2=0.1 en VARIABLES si es de una rama
condiciones iniciales INITIAL CONDITIONS (o DEFINED PARAMETERS) DEFINED_PARAMETERS
modelos de SCEPTRE (MODEL 101M (B-C-E), transistores de modellib.siru) sí no
tablas adentro del archivo (TABLE 1) sí sí (desde r1950), o por archivo aparte, Table('tabla.txt',...)
incluir otro archivo SCEPTRE no tiene include, pero siru lo acepta: include parte.d mete otro .d, que se lee como .d (desde r2066); una biblioteca (.siru, .ds) se lee como .ds. Un .d con include ya no corre en SCEPTRE include otro.ds (o input otro.ds): el otro archivo entra en ese lugar, con su ruta relativa al que lo incluye o al directorio actual; sirve para la biblioteca y para partes de un circuito
cadenas entre comillas no sí (Table('...'))

Cuál usar: .ds para lo nuevo —dice el tipo de cada rama, no lo adivina por la letra, y es el formato de Siru—; .d para correr lo que viene de SCEPTRE o de Simusol, o lo que usa sus modelos de transistor y sus tablas incorporadas. Lo que sigue muestra las dos formas donde difieren.

3.1 Estructura y reglas de escritura

La siguiente referencia describe el formato .ds que lee d2datdinc, el lector basado en slex. Las secciones explican qué significa cada sentencia; una misma expresión escrita bajo otro encabezado puede significar otra cosa. El recorrido es:

problema.ds → d2datdinc → dato del problema (.dat)
                              ├─ sistema (.din) → Calcula → resultados (.simul)
                              └─ FORMAS + ramas → dibuja → esquema (.svg)

Siru coordina ese recorrido con siru problema.ds. Los archivos intermedios pueden ser temporales: no hace falta prepararlos a mano. FORMAS aporta información de dibujo; las ecuaciones se construyen con la descripción del sistema, sin depender de que exista el dibujo.

Regla Escritura y significado
Encabezado En una línea propia: DEFINED_PARAMETERS o DEFINED PARAMETERS. En encabezados se admiten mayúsculas/minúsculas, espacios, tabuladores y _ entre palabras. Puede seguir un comentario.
Cuerpo Desde el encabezado hasta el siguiente encabezado o END. Se pueden omitir las secciones que no se necesitan y volver a abrir una sección; esto no permite redefinir arbitrariamente los mismos nombres.
Fin END, en mayúsculas, termina la fuente actual. También se acepta el fin del archivo. En una biblioteca incluida, su END permite volver al archivo que la incluyó. El texto posterior a END no es parte de ese problema.
Sentencias Una por línea, o varias separadas por ;. En .ds, ; no introduce un comentario.
Continuación Una barra inversa \ al final une la línea siguiente. Terminar en +, , o = sin \ no pide continuación en .ds.
Comentarios # o // hasta fin de línea; también /* ... */. Dentro de cadenas entre comillas no comienzan comentarios.
Inclusión include ruta o input ruta; se acepta #include ruta por compatibilidad. La ruta va sin espacios ni comillas y se busca relativa al archivo que incluye o al directorio de trabajo. La sección activa puede continuar a través de la inclusión: conviene escribir encabezados explícitos al volver.
Nombres Para parámetros e incógnitas: letra seguida de letras, dígitos o _, por ejemplo TEMP, Y1, P_T. Para tipo, rama y nodo se aceptan letras, dígitos y _, incluso un nodo numérico. No usar blancos dentro del nombre.
Mayúsculas La tolerancia de los encabezados no se extiende a todas las claves. Escribir RK, SIRU_PASO, V: y D: como se documentan y mantener la misma escritura de los nombres. Los nombres del sistema generado pueden aparecer en minúsculas.
Números Decimal con punto, signo opcional y exponente e/E: 12, -0.5, .001, 2e-6. La coma separa campos; no es separador decimal.
Cantidades con unidad En expresiones: número, blanco y unidad GNU units, por ejemplo 10 kohm, 100 uF, 25 tempC. El lector convierte la cantidad a SI. 10k no es esta sintaxis; C es coulomb, tempC es Celsius absoluto. CONSTANTS y DATA tienen sus propias reglas indicadas más abajo.
Expresiones Operadores explícitos: + - * / ^, paréntesis, funciones y condiciones de ExprTk. Ejemplos: 2*(X+1), sin(T), if(T<1,0,1). No hay multiplicación implícita. Las comillas simples o dobles delimitan cadenas, como las rutas de Table(...).

3.2 Secciones del archivo

Sección Contenido Desarrollo
CIRCUIT_DESCRIPTION Texto que describe el problema. §4
ELEMENT_DESCRIPTION, alias ELEMENT_DEFINITION Tipos de rama y sus ecuaciones; también pueden llegar mediante include. §3.3 y §5
ELEMENTS Ramas, nodos, valores y acoplamientos. Se omite en un sistema de ecuaciones sin circuito. §3.3, §5–8
CONSTANTS Constantes numéricas con nombre. §3.4
DEFINED_PARAMETERS Datos conocidos, expresiones auxiliares y valores iniciales de estados. §3.4 y §10
INITIAL_CONDITIONS Encabezado de compatibilidad con SCEPTRE. En un .ds nuevo escribir las condiciones en DEFINED_PARAMETERS. §3 y §10
VARIABLES Incógnitas y semillas para Calcula; también derivadas propias. §3.4 y §10
EQUATIONS Residuos que Calcula debe anular. §3.4 y §10
FUNCTIONS Funciones, tablas incorporadas o declaraciones EXTERNAL. §3.5 y §9
RUN_CONTROLS Selección del modo de resolución y opciones numéricas. §3.6, §11 y §12
CONTROL_EQUATIONS Condiciones para continuar una integración. §3.6 y §11
OUTPUTS Variables que se quieren observar y abscisa opcional. §3.6 y §12
FORMAS Símbolos de las ramas e información conservada del dibujo de Dia. Su presencia solicita el esquema. §3.8
DATA Datos estructurados de compatibilidad, como tablas de métodos. §3.7
DATABLOB Texto de compatibilidad con Siru antiguo; no es una sección general para programar el Siru actual. §3.7
RESULTADOS, UNIDADES, PARAPLOT, GRAFICOS, ACEPTAR_GRAFICOS, GRAFICOS_ADICIONALES Presentación de tablas y gráficos mediante Simplot. §3.9
SENSITIVITY, MONTE_CARLO, WORST_CASE / WORST-CASE Conjuntos de variables para los análisis DC correspondientes. §11 ter–quinquies

El lector reconoce además encabezados históricos como FORCED_VARIABLES, MODELS, MODEL_DESCRIPTION, MULTIELEMENT_DEFINITION, CONTROLS, ECUACIONES, OPTIMIZATION, CLEAR, RERUN_DESCRIPTION, CONTINUE y RE-OUTPUT. Reconocer el encabezado no implica implementar su contenido en .ds: los modelos de SCEPTRE, reruns y continuaciones descritos en este manual usan su sintaxis .d. FORCED_VARIABLES no tiene traducción general en .ds; usar parámetros y ecuaciones explícitos. Las órdenes de la terminal antigua (EXECUTE, PREPARE, SHOW, solve, plot, etc.) no se ejecutan al leer un .ds.

3.3 Gramática de ramas y modelos

En las reglas siguientes, las comillas indican texto literal, { ... } significa repetición y [ ... ] significa parte opcional. expresion representa una expresión del lenguaje numérico, no un nombre literal. Los separadores se interpretan fuera de paréntesis y cadenas.

rama       = tipo "-" nombre "," nodo "-" nodo "=" valores [ "=" controles ]
valores    = pieza { "&" pieza }
controles  = pieza { "&" pieza }
pieza      = expresion [ "V:" nombre { "," nombre } ]
mutua      = nombre_M "," bobina "-" bobina "=" expresion
modelo     = tipo "(" cantidad ")" "=" campo { "," campo }
campo      = expresion | marca_modelo
Parte Ejemplo y regla
Rama RB-R1, entrada-salida = 1000. RB es el tipo; R1, el nombre usado en VR1, IR1 y FORMAS.
Varios valores En .ds se separan con &: ESIN-E1, GND-1 = 5 & 2*pi*T. Son x1, x2, etc., en el modelo. Las comas dentro de una llamada separan los argumentos de esa llamada.
Control de rama El segundo = introduce el control histórico de la rama. Para una llave corriente usar el tipo SB y su valor de apertura/cierre (§6); otros controles pueden no tener traducción al motor actual.
Masa Un circuito .ds usa GND. No sustituirla por 0; esa compatibilidad pertenece a .d. Un sistema sin ramas no necesita masa.
Mutua M12, L1-L2 = 0.2; las dos bobinas deben estar declaradas. El valor es la inductancia mutua, no el coeficiente de acoplamiento (§8).
Modelo algebraico RB(1) = VOLTAGE - x1*CURRENT. Cada expresión del modelo es un residuo que se anula.
Estado de un modelo IC: CURRENT:CURRENT:DCURRENT declara la asociación de estado/derivada del modelo de bobina; véanse los modelos completos de §5 y libraryori.siru.
Otras marcas de modelo IF: expresion, INV: expresion, OP: parte:parte, VARS: nombre:nombre. Son campos del modelo; no encabezados del archivo. Las dos primeras intervienen en la definición y el signo de las fuentes. OP y VARS conservan información del modelo para su traducción.

La definición de los tipos debe estar disponible antes de construir el sistema. Se pueden copiar sólo los modelos utilizados dentro del .ds, como en los ejemplos de dibuja, o incluir la biblioteca. El valor de una rama no es su símbolo gráfico: la forma eléctrica, térmica o genérica se declara por separado en FORMAS.

3.4 Parámetros, incógnitas, constantes y ecuaciones

parametro  = nombre "=" expresion [ "D:" derivada ]
variable   = nombre "=" semilla   [ "D:" derivada ]
constante  = nombre "=" numero
ecuacion   = expresion { marca_ecuacion }
Sección y ejemplo Significado
DEFINED_PARAMETERS / PRES=101325 Dato conocido: se entrega a Calcula con ese valor.
VARIABLES / PV=1500 Incógnita: 1500 es una semilla, no un valor impuesto. Calcula la determina mediante las ecuaciones.
CONSTANTS / TKO=273.15 Constante numérica. Esta declaración acepta un número, no una expresión general ni el sufijo de unidad de las cantidades.
DEFINED_PARAMETERS / X=1 D:DX Valor inicial de X y nombre de su derivada. La derivada debe quedar determinada por el sistema. También se reconoce la relación convencional entre X y DX descrita en §10.
DEFINED_PARAMETERS / POT=V*I Definición mediante expresión; no es un dato numérico independiente. Se traduce en una incógnita con su ecuación.
EQUATIONS / PV-PW(TEMP) Calcula busca que el residuo sea cero: equivale a PV=PW(TEMP). Escribir el residuo evita confundir una ecuación con la asignación de un parámetro.

Cada incógnita necesita la relación que la determina; las semillas ayudan a resolver el sistema pero no agregan ecuaciones. No repetir la misma declaración de parámetro, variable o constante: el lector avisa y descarta la repetida. En cambio, una sección reabierta puede agregar otros nombres.

Las marcas opcionales van después de la expresión y no se repiten en una sentencia:

Marca Forma y uso
V: V:X,Y declara los nombres asociados a la ecuación. Se permite V: X, Y; escribir la coma pegada al nombre anterior.
LINEAL: Sin valor. La parte inicial pasa a ser una lista de coeficientes, alineada con V:.
INDEP: Un valor: término independiente de la forma lineal. 1,-1 V:X,Y LINEAL: INDEP:2 representa X-Y=2.
NONUCLEO: Sin valor. Marca una ecuación fuera del núcleo del sistema. Es información avanzada de compatibilidad; no usarla para una ecuación que Calcula deba resolver como parte del sistema.
RES: Un nombre asociado al resultado de una expresión.
TIPO: Un valor que clasifica la ecuación en el dato histórico; por ejemplo TIPO:POST. Su lectura no garantiza que cualquier clasificación tenga implementación en el motor actual.

3.5 Funciones y tablas

funcion    = nombre_funcion "(" cantidad_o_argumentos ")" "=" expresion
externa    = "EXTERNAL" nombre_funcion "(" cantidad ")" ruta
tabla      = "TABLE" nombre_tabla
             numero "," numero { "," numero "," numero }
Forma Ejemplo y alcance
Función por cantidad PW(1)=exp(x), COC(2)=x/y. Los argumentos formales son x, y, z, etc.
Función por nombres COC(A,B)=A/B. El lector admite la lista explícita de argumentos; los nombres de función llevan letras y dígitos, sin _.
Uso COC(PV,PRES) dentro de una expresión. Los argumentos van separados por comas y entre paréntesis.
Tabla incorporada En FUNCTIONS, TABLE 1 y después 0,0, 1,10, 2,20. También puede ir todo en una línea: TABLE 1, 0,0, 1,10, 2,20. Se usa como TABLE 1(T); §9 detalla las formas equivalentes y los saltos.
Tabla externa Table('tabla.txt','TIEMPO','VALOR',T,1). La tabla referenciada debe acompañar al .ds; §9 explica columnas e interpolación.
Función externa EXTERNAL FGEN (2) fgen.f90. Acepta entre 1 y 12 argumentos y requiere el fuente y las herramientas de compilación indicadas en §9.

3.6 Controles, condiciones y salidas

control    = clave "=" "[" valor { "," valor } "]"
condicion  = expresion_logica { marca_ecuacion }
salidas    = [ abscisa ":" ] nombre { "," nombre }
Escritura Efecto
RUN_CONTROLS / RK=[-1] Un único punto resuelto por Calcula. No integra. Véase §12.
RK=[12] Integración con el método 12. Los métodos y sus límites están en §11.
RK=[18,18,11] Secuencia de métodos; no mezclar -1 con métodos de integración.
SIRU_PASO=[0.01] y SIRU_ADAPT=[0] Paso fijo de 0.01. Sin la segunda opción, declarar un paso puede activar adaptación; véase §11.
STARTING STEP SIZE = 0.01 Forma compatible admitida también en .ds; MINIMUM STEP SIZE, MAXIMUM STEP SIZE y SEMILLA VL2 = 0.1 son otras excepciones a la lista entre corchetes.
GLM=[...], PGLM=[...], ROS=[...], SPLIT=[...] Seleccionan otras familias. Son alternativas a RK, no controles para combinar con RK=[-1]; sus contratos están en §11.
CONTROL_EQUATIONS / T<TIEMPOFINAL Condición para seguir, no para terminar. Se detiene al dejar de cumplirse. Con RK=[-1] no provoca una marcha temporal.
OUTPUTS / T:VC1,IR1 Abscisa T y variables solicitadas para una corrida. No son ecuaciones ni valores impuestos. Conviene poner la lista completa en una línea, o usar \ para continuarla.
OUTPUTS / TEMP,TBH,PRES,PV Lista de observables sin inventar una variable de tiempo. En modo de un punto la tabla de Siru contiene todas las variables del sistema de Calcula, incluidos los datos (§12).

Los valores de los controles no admiten listas anidadas; cada clave valida además sus opciones. Las repeticiones de una clave pueden acumular sus valores: declarar una sola vez el selector de método. Usar exactamente RK=[-1], con corchetes y RK en ese orden; RK=-1 y KR=[-1] no son la escritura de este modo.

3.7 DATA y DATABLOB

DATA conserva datos estructurados; no ejecuta Perl. Su gramática es:

asignacion = camino "=" valor
camino     = clave { [ "->" ] ( clave | indice ) }
clave      = "{" cadena "}"
indice     = "[" entero_sin_signo "]"
valor      = cuenta | cadena | "undef" | "[" [ valor { "," valor } ] "]"
Elemento Regla
Ejemplo {'rungekutta'}->[3]->{'a'}=[[0,0],[1/2,0]]. Se conservan listas, objetos, números y textos.
Cuentas + - * / **, paréntesis, sqrt, exp, log, sin, cos, abs, int, atan2. Aquí la potencia se escribe **.
Índices [0], [3]: enteros no negativos, sin signo. No confundir un índice con un valor: [-1] sí puede ser el valor de una lista.
Compatibilidad {'lnumrk'}=[-1] aparece en archivos antiguos. Para pedir un punto al Siru actual declarar explícitamente RK=[-1] en RUN_CONTROLS; no depender de ese dato histórico.
Errores No se acepta código, un índice negativo, una cadena sin cerrar ni cambiar un objeto ya creado por una lista al recorrer un camino.

DATABLOB transporta el texto histórico y sólo tiene traducciones específicas, entre ellas el selector antiguo de método numrk. No constituye un lenguaje general admitido por el motor actual. Para un archivo nuevo usar ecuaciones, funciones y controles declarativos; el documento del lector (fuentes: slex/d2datdinc/README.md) precisa el patrón heredado que reconoce.

3.8 FORMAS: el dibujo dentro del .ds

FORMAS permite incluir en el propio .ds la información de NOMBRE.formas, el archivo que dia2formas extrae de un dibujo de Dia. No sustituye ELEMENTS: las ramas y sus conexiones siguen siendo la fuente del circuito. Puede aparecer entre las demás secciones; termina al comenzar otra sección o al llegar a END.

El formato completo tiene siete campos separados por tabuladores reales, uno por renglón:

nombre<TAB>forma<TAB>orientacion<TAB>x<TAB>y<TAB>ancho<TAB>alto

<TAB> representa un tabulador, no los cinco caracteres de esa indicación ni la secuencia literal \t. Los espacios interiores pertenecen al campo. En este ejemplo las separaciones son tabuladores reales:

FORMAS
# nombre	forma	orientacion	x	y	ancho	alto
R1	Electrico - hresistor	horizontal	4	1	3	1.5
masa	Electrico - tierra	fija	8	6	2	2
nodo 1	Electrico - nodo	fija	3	1	1	1
END
Campo Contenido
nombre Nombre de rama sin el prefijo de tipo (R1, no RB-R1), masa o el nombre de nodo de Dia (nodo 1).
forma Nombre de la forma, por ejemplo Electrico - hresistor, Termico - acumulador o Termico - 0gradosc. Se conserva como texto.
orientacion Texto de Dia, por ejemplo horizontal, vertical, fija, hacia la izquierda o con indicaciones de volteo. No es un código numérico.
x, y Coordenadas de la esquina de la forma en Dia, en cm; y crece hacia abajo.
ancho, alto Dimensiones en las mismas unidades de Dia.

Los siete campos deben tener contenido y los cuatro últimos deben ser números finitos. Campos de más, campos vacíos o coordenadas no numéricas hacen fallar la lectura sin publicar un DAT parcial. Como formato abreviado también se admite R1 Electrico - hresistor, o dos campos separados por tabulador: sólo nombre y forma, sin geometría. No escribir siete campos separados por espacios: se interpretarían como la forma abreviada.

El lector conserva el orden, los nodos y las masas repetidas. En el .dat el bloque queda en GLOBAL.formas:

{"GLOBAL":{"formas":[{"nombre":"R1","forma":"Electrico - hresistor","orientacion":"horizontal","x":4,"y":1,"ancho":3,"alto":1.5}]}}

Es un fragmento del dato, no un circuito completo. FORMAS vacía produce "formas":[]; sin la sección, la clave no existe. Esa diferencia es deliberada:

Entrada Acción de Siru
Sin FORMAS Resuelve el problema sin solicitar esquema.
FORMAS vacía Invoca dibuja para construir el esquema a partir de las ramas y conexiones, con símbolos automáticos.
FORMAS con registros Invoca dibuja y le entrega las formas del dato ya leído.
FORMAS y RK=[-1] Solicita el esquema y resuelve un punto con Calcula; dibujar no implica integrar.
dibuja ausente Continúa el cálculo y deja constancia en .log.
Error de dibuja Avisa y continúa el cálculo.

Para pedir el dibujo automático basta poner, antes de END:

FORMAS
END

dibuja elige símbolos con esta información y escribe NOMBRE.svg junto al circuito. Las formas internas prevalecen, por nombre, sobre las del archivo externo NOMBRE.formas; los nombres no cubiertos internamente pueden seguir tomando la forma externa. Las ramas restantes usan el conjunto predominante o los símbolos automáticos. Para nombres repetidos se toma la primera forma; los registros de nodos se conservan pero todavía no seleccionan símbolos de nodo. --electrico permite pedir explícitamente la representación eléctrica al ejecutar dibuja por separado.

Alcance actual de la geometría: slex transporta orientación, posición y tamaño, pero dibuja usa ELK para distribuir el esquema. Todavía no reproduce las coordenadas, tamaños ni volteos originales de Dia. Siru activa este recorrido para .d, .ds y .dat, también al continuar una corrida; un .din no transporta FORMAS.

Ejemplo completo Contenido
automatico.ds FORMAS vacía: esquema automático.
divisor.ds Divisor de tensión con formas eléctricas y modelos incorporados.
termico.ds Circuito con formas térmicas.

Los tres tienen sus .dat y .svg de ejemplo al lado. Para trasladar la información de Dia: ejecutar dia2formas circuito.dia, insertar el contenido de circuito.formas bajo FORMAS antes de END y conservar sus tabuladores. Para dibujar por separado: dibuja circuito.ds o dibuja circuito.dat; la segunda forma no necesita Calcula, Siru ni el lector .ds.

3.9 Gráficos de resultados y unidades de presentación

Estas secciones describen gráficos de las tablas numéricas, mientras que FORMAS describe el esquema del circuito. Se transportan en GLOBAL.simplot; Simplot las procesa cuando los resultados están disponibles.

Sección Ejemplo
RESULTADOS TEMP(Interior,temperatura,tempC),PV pide columnas con leyenda, magnitud y unidad de presentación opcionales.
UNIDADES TEMP:K,temperatura declara el origen cuando la tabla no lo trae. No cambia por sí sola las ecuaciones ni convierte números del sistema.
PARAPLOT / GRAFICOS / ACEPTAR_GRAFICOS archivo F = caso.simul, lineas G = F,1:2,3, titulo G = Resultado: una orden por sentencia.
GRAFICOS_ADICIONALES Agrega gráficos a los pedidos principales.
Controles asociados SIMPLOT_VERSION=[2] selecciona el contrato tipado; ANADIR_GRAFICOS=[1] suma los pedidos explícitos a los automáticos. Van en RUN_CONTROLS.

Las órdenes, su prioridad y las conversiones se detallan en los contratos DAT/PARAPLOT (fuentes: simplot/doc/DAT-PARAPLOT.md) y DAT/Simplot v2 (fuentes: simplot/doc/DAT-SIMPLOT-V2.md). Las unidades de presentación no deben confundirse con las cantidades con unidad de §3.1: estas últimas sí se convierten a SI al construir el problema.

3.10 Cómo comprobar la lectura

Con el lector instalado, d2datdinc -v problema.ds -o problema.dat genera el dato y muestra advertencias de sintaxis o compatibilidad. Desde la raíz del árbol de fuentes:

slex/d2datdinc/d2datdinc -v \
  -c slex/d2datdinc/d2datdinc.slex \
  -b slex/d2datdinc/biblioteca problema.ds -o problema.dat
perl siru/bin/siru problema.ds

Algunas construcciones históricas mal escritas se descartan con aviso; por eso generar un .dat no prueba por sí solo que todo lo escrito haya sido utilizado. Revisar los avisos de -v. Siru rechaza un sistema con traducciones pendientes. Para comprobar una regla en el código, la gramática léxica está en d2datdinc.slex (fuentes: slex/d2datdinc/d2datdinc.slex); las gramáticas de sentencias, en parametros.y, ecuacion.y, declaraciones.y, control.y, data.y, edef.y y piezas.y del mismo directorio. dato.c implementa la interpretación de secciones y de FORMAS.

4. Un archivo mínimo

Un RC alimentado por una batería, con la resistencia dependiendo del voltaje del capacitor. Da lo mismo en los dos formatos.

.d:

CIRCUIT DESCRIPTION
  Un RC con resistencia no lineal
ELEMENTS
 E1, GND-1 = 1
 R1, 1-2 = 1+0.1*VC1
 C1, 2-GND = 1
OUTPUTS
VC1, IR1
INITIAL CONDITIONS
QC1 = 0
RUN CONTROLS
INTEGRATION ROUTINE = TRAP
STOP TIME = 2
END

.ds:

include ../slex/d2datdinc/biblioteca/libraryori.siru
CIRCUIT_DESCRIPTION
  Un RC con resistencia no lineal
ELEMENTS
 EB-E1, GND-1 = 1
 RB-R1, 1-2 = 1+0.1*VC1
 CB-C1, 2-GND = 1
OUTPUTS
T:VC1,IR1
DEFINED_PARAMETERS
T=0
TIEMPOFINAL=2
QC1=0
RUN_CONTROLS
RK=[12]
CONTROL_EQUATIONS
T<TIEMPOFINAL
END

La línea de un elemento es NOMBRE, NODO1-NODO2 = VALOR. La masa es GND. Un .ds tiene que tenerla: sin GND, o con un nodo 0, d2datdinc se para y pide ponerla. Un .d es la entrada de SCEPTRE, que no pide masa, y se acepta sin GND: la masa es el nodo 0, o si no lo hay el nodo más chico (los números por su valor, antes que los nombres), y se avisa por la salida de errores (el .d no tiene nodo GND: la masa es el nodo 1). La corriente de la rama va del primer nodo al segundo y su tensión es u(NODO1) - u(NODO2). Una fuente de tensión E1, GND-1 = 1 pone el nodo 1 a +1 V.

5. Los elementos

5.1 La biblioteca (slex/d2datdinc/biblioteca/libraryori.siru)

tipo qué es modelo estado
RB resistencia V = x1·I
CB capacitor, x1 la capacidad total Q/V dQ/dt = I, Q = x1·V la carga Q
CINC capacitor, x1 la capacidad incremental dQ/dV; CINC1, 1-GND = … I = x1·dV/dt el voltaje V
LB bobina V = x1·dI/dt la corriente I
EB fuente de tensión V = x1 (E1, GND-1 = 1 pone 1 V en el nodo 1)
JB fuente de corriente I = x1
SB llave V·x1 + I·(1-x1) = 0; x1 es 1 cerrada, 0 abierta
ESIN fuente senoidal, ESIN1, GND-1 = A, T V = A·sin(x2), con su derivada
MW devanado de un transformador con núcleo, MW1, 2-GND = N, DPHI1 V = N·dPHI/dt
LNL bobina no lineal, LNL1, 2-3 = L, n L·dI/dt = V^n I
RC, EC, JC lo mismo que RB, EB, JB

Los dos capacitores. Con capacidad constante CB y CINC dan lo mismo. Con una capacidad que depende del voltaje (o de una corriente que depende del voltaje) no, porque el número significa otra cosa:

Un .d escrito para SCEPTRE con capacidades variables hay que correrlo con CINC para que dé lo mismo: en un .d es CINC toda rama cuyo nombre empiece con CINC (para SCEPTRE es un capacitor más); las demás C… son CB. En un .ds, CINC-C1, 1-GND = …. La misma capacidad en los dos: c(V) = 1 + 0.2·V² cargada a 10 V por 1 Ω da, en t = 4, V = 4.74 con CB y 6.17 con CINC (y con SCEPTRE). CINC no puede estar en un lazo de capacitores: no tiene la carga como estado. Ejemplos: slex/d2datdinc/pruebas/sceptre/dos-capacitores.d (los dos lado a lado) y a01-cinc.d (el inversor a01 con CE y CC como CINC: igual a SCEPTRE; con CB, a01-tabla2.d, difiere de 6 a 15 %).

Los nombres R, E, J, S, L, C sin la B son de una biblioteca vieja por incrementos y no sirven para siru: una C o una L así en un .ds da el mensaje «modelo por incrementos». Usar CB, LB.

5.2 Lo que un elemento puede nombrar en su valor

en el archivo qué es
un número el valor, constante
PL un parámetro de DEFINED PARAMETERS (PL = 22); dos ramas que nombren PL comparten el valor
VC1, IR1, QC1, IL1 la tensión, la corriente, la carga, la corriente de otra rama (o de la misma): así se escriben los elementos no lineales y las fuentes controladas
T el tiempo
DT, TICK el paso en uso y la cantidad de pasos dados (los pone el simulador, el archivo no los fija)
QC(PC,VC1) una función de FUNCTIONS
T1(T), TABLE 1 (T), Table('tabla.txt','X','Y',T,1) una tabla (sección 9)
sin, cos, exp, log, abs, sqrt, if(c,a,b), <, >, and, or… lo que entiende ExprTk

Las expresiones van en notación de ExprTk: la multiplicación es * y no se sobreentiende (2*(x+1), no 2 (x+1)); ^ es la potencia; una condición vale 1 o 0, así que (T<1)+(T>3) es «antes de 1 o después de 3».

Ejemplos:

 R1, 1-2 = 1+0.1*VC1              resistencia que depende del voltaje del capacitor
 C1, 2-GND = 1+0.5*VC1            capacidad que depende de su propio voltaje
 E2, GND-3 = 2e5*VR1              fuente de tensión controlada (amplificador)
 J2, GND-3 = 0.98*IR1             fuente de corriente controlada
 E3, GND-4 = 0.5+0.2*sin(3*T)     fuente que varía en el tiempo
 ESIN1, GND-1 = 1, 6.28*T         la senoidal de la biblioteca: amplitud y fase
 J3, GND-5 = 1e-13*(exp(38*VJ3)-1)  un diodo: fuente de corriente función de su tensión

5.3 Tipos propios

Un modelo nuevo se declara en ELEMENT DEFINITION (.d) o ELEMENT_DESCRIPTION (.ds, que es la sección de una biblioteca): el nombre con la cantidad de parámetros, y las ecuaciones en VOLTAGE, CURRENT, sus derivadas DVOLTAGE, DCURRENT, y la carga CHARGE, DCHARGE; x1, x2… son los valores que da la línea del elemento, separados por & en .ds y por comas en .d.

ELEMENT DEFINITION
   EV(2) = IF: VOLTAGE, VOLTAGE + x1, DVOLTAGE + x2     fuente con su derivada
   MZER(1) = 0                                           elemento nulo
   RQ(1) = VOLTAGE - x1 * CURRENT^3                      resistencia cúbica

5.4 Modelos de SCEPTRE (sólo .d)

MODEL 101M (B-C-E) bajo MODEL DESCRIPTION, o los permanentes de slex/d2datdinc/biblioteca/modellib.siru (T1, 2-3-1 = MODEL 2N2222 (PERM)): subcircuitos con patas que se expanden donde se usan; cada elemento interno lleva el nombre de la instancia como sufijo (CET1). Diodos: DIODE EQUATION (Is, T) es Is*(exp(T*VJ)-1). Ejemplos en slex/d2datdinc/pruebas/sceptre/modelo.d y diodos.d.

5.5 Convolución: una caja descripta por su respuesta (K)

Una parte del circuito se puede dar por cómo responde en lugar de por sus elementos: su respuesta al impulso h(t), por tabla o por ecuación. Es la convolución de SCEPTRE (manual, volumen 1, apéndice F), con la diferencia de que la respuesta va en el mismo archivo y no en el «Disk 12».

.d                                          .ds
ELEMENTS                                    ELEMENTS
 K1, 1-GND = FCONVE (H1)    impedancia       KE-K1, 1-GND = H1
 K2, 3-4 = FCONVJ (H2)      admitancia       KJ-K2, 3-4 = H2
FUNCTIONS                                   FUNCTIONS
 TABLE H1                   por tabla        TABLE H1
  0, 2,  0.05, 1.9025, ...                    0, 2,  0.05, 1.9025, ...
 H2 (T) = EXP(-2*T)         por ecuación     H2(1) = exp(-2*x)

Una caja de varias puertas se arma, como en SCEPTRE, con un K entre cada par de nodos. Por dentro, como SCEPTRE, el elemento es una fuente (la historia, lo ya calculado) en serie con una resistencia (el último tramo, que depende de la corriente desconocida): v = e + r·i. siru guarda la historia en cada paso aceptado y calcula e y r para cada etapa del Runge-Kutta, suponiendo h e i lineales entre puntos (la fórmula F.9 del manual, exacta para esa suposición): el error es del orden del cuadrado del paso. Si el circuito no tiene otros estados, el .din lleva un estado reloj (conv_reloj, derivada 1) para que haya algo que integrar.

Cuidados:

Ejemplos, con su prueba en tests/convolucion.t: en siru/corpus/corpus/inventados, la caja RC escrita (caja-rc.ds) y como K por ecuación y por tabla (caja-k-ecuacion.ds, caja-k-tabla.ds); la caja RL escrita (caja-rl.d) y como FCONVJ (caja-kj.d). El plan y las fórmulas: PLAN_CONVOLUCION.md.

6. Llaves

Una llave es un elemento SB (S1 en un .d) cuyo valor es su condición: 1 (o verdadero) cerrada, 0 abierta.

 S1, 2-3 = T<1                       .d
 SB-S1, 2-3 = (T<1)+(T>3)            .ds
 S2, 3-GND = VC1>0.5                 por una variable del circuito

La condición puede usar cualquier variable del circuito, los parámetros y T. Se evalúa al empezar cada paso; si cambia en medio de un paso, la llave cambia en el siguiente. Cada combinación de llaves es una configuración, y su sistema se arma la primera vez que se entra en ella (quedan los .mdin). Una llave abierta puede dejar nodos sin camino a masa (una isla): se les fija potencial cero y no es error. Ejemplos: slex/d2datdinc/pruebas/isla.d, llave-lazo.ds, llave-corte.ds.

6.1 Llaves o if(...): la diferencia

Las dos eligen entre ecuaciones según una condición. La diferencia es cuándo se decide y qué pasa en el salto.

llave (SB, S1) if(c, a, b) en una ecuación
cuándo se evalúa la condición una vez, al empezar cada paso (el sistema del instante) en cada iteración de Newton y en cada etapa del Runge-Kutta
durante el paso la configuración queda fija: un sistema suave, sin saltos puede cambiar de rama en medio del paso, o ir y volver entre dos iteraciones
el salto siru lo resuelve: trasvase de carga o flujo y equilibrio (-I.mdin, -E.mdin) no hay tratamiento: los estados siguen como estaban
para qué sirve cambios de topología, donde los estados pueden saltar leyes por tramos con los estados continuos
robustez buena: cada configuración es su propio sistema más frágil: cerca del cambio, con paso grande, Newton puede oscilar entre las ramas

Un ejemplo de if es el cambio de fase (siru/corpus/corpus/Simul_varios_Siru_perl_examples/cambiofase.ds): la entalpía es continua y sólo cambia la ley, calor sensible fuera del intervalo de fusión y latente adentro. Las llaves de hoy son ramas de un circuito, así que un sistema sin circuito, como ese, sólo puede usar if.

if, and, or, not y xor pasan tal cual al .din (desde r1899) y Calcula los evalúa con ExprTk. Un estado se puede declarar TEMP=0 D:DTEMP en DEFINED_PARAMETERS con la derivada dada por una ecuación de EQUATIONS (desde r1901), como en cambiofase.ds: la temperatura sube hasta la de fusión, se queda ahí mientras funde y después sigue subiendo.

7. Lazos de capacitores y cortes de bobinas

Dos capacitores en paralelo, un capacitor en paralelo con una batería, o una malla de capacitores y baterías, es un lazo: los voltajes no son independientes. Bobinas en serie en un nodo sin otra salida, o con una fuente de corriente, es un corte: las corrientes no son independientes. No hay nada que escribir: siru los encuentra, integra con la ley del lazo (o del corte) en derivadas, y cuando una llave hace aparecer un lazo o un corte con los estados desparejos hace el equilibrio —el trasvase instantáneo de carga o de flujo— y escribe una fila más con el mismo t. En el .simul se ve como un salto.

Al arrancar, si una fuente impone un estado —una bobina en serie con una fuente de corriente, un capacitor en paralelo con una batería— y el archivo no da su condición inicial, el estado arranca con lo que impone la fuente y no hay salto (arranque: il44 = 10 (lo impone una fuente y el archivo no da su condicion inicial)); es lo que hace SCEPTRE. Si el archivo la da (IL44 = 0), hay equilibrio como en cualquier otro caso: la bobina salta a 10 y las acopladas con ella reciben el golpe.

Una fuente que varía adentro de un lazo o un corte entra con su derivada: la del modelo si la trae (EV, ESIN), y si no la numérica. En un lazo la capacidad puede ser constante o depender del voltaje de capacitores:

Si depende de otra cosa (el tiempo, una corriente cualquiera), en un lazo es un error que lo dice. Ejemplos: siru/corpus/corpus/llaves_equilibrio/*.d, slex/d2datdinc/pruebas/capacidad-variable.d, slex/d2datdinc/pruebas/sceptre/lazo-c-ajeno.d.

El estado de un capacitor es su carga, Q = C·V, y la corriente es dQ/dt: con una capacidad variable eso incluye el término V·dC/dt. SCEPTRE hace otra cosa: integra I = C·dV/dt, con C evaluada en el punto (la capacidad incremental). Con capacidad constante es lo mismo; con capacidad variable los resultados difieren y no es un error de ninguno de los dos: en slex/d2datdinc/pruebas/sceptre/c-variable.d (C1 = 1 + 0.2·VC1² cargado a 10 V por 1 Ω) SCEPTRE da VC1 = 6.17 en t = 4 y siru 4.74. Para escribir en siru la capacidad incremental de SCEPTRE c(V) hay que dar C = (1/V)·∫c dV (para c = 1 + 0.2·V², C = 1 + 0.2·V²/3): con eso siru da lo mismo que SCEPTRE (c-variable-q.d: 6.166829 contra 6.166827).

Con lazos o cortes, el punto de operación (11 bis) se resuelve en un sistema aparte, NOMBRE-[bits]D.mdin: el instante con las ecuaciones originales en lugar de las leyes derivadas, que con las derivadas en cero no atan nada.

8. Acoplamientos magnéticos

Inductancia mutua, como en SCEPTRE: una línea M, L1-L2 = valor entre dos bobinas LB que ya existen. Agrega M·dI2/dt a la tensión de L1 y viceversa. Si una llave abre la rama de una de las dos, la otra recibe el golpe: ΔI2 = (M/L2)·I1 (se conserva el flujo concatenado).

 L1, 2-GND = 1
 L2, 3-GND = 4
 M,  L1-L2 = 1.8

Transformador con núcleo: cada devanado es un MW con sus vueltas y la derivada del flujo del núcleo; el flujo es un estado propio y la fuerza magnetomotriz una ecuación propia (sección 10).

ELEMENTS
    MW1, 2-GND = 1, DPHI1          N1 = 1 vuelta
    MW2, 3-GND = 2, DPHI1          N2 = 2 vueltas
VARIABLES
    DPHI1 = 0
EQUATIONS
    1*IMW1 + 2*IMW2 - REL*PHI1     N1·I1 + N2·I2 = reluctancia · flujo
DEFINED PARAMETERS
    REL = 1
    PHI1 = 0

REL puede ser una expresión (un núcleo que satura). Ejemplos: slex/d2datdinc/pruebas/mutua.d, nucleo.d, siru/corpus/.../trafo*.d.

9. Funciones y tablas

FUNCTIONS: NOMBRE(args) = expresión. En un .d los argumentos llevan nombre. En un .ds se puede declarar la cantidad y llamarlos x, y, z…; también se admite la lista explícita de nombres de §3.5.

FUNCTIONS                              .d
QC(PC,V) = PC*(1+0.1*V)

FUNCTIONS                              .ds
QC(2) = x*(1+0.1*y)

Hasta 6 argumentos las compila Calcula; con más, d2datdinc reemplaza cada llamada por el cuerpo de la función, así que andan igual. Las constantes de CONSTANTS se pueden usar adentro.

Tablas: una función de una variable dada por puntos, interpolada (lineal; un x repetido es un salto). Si la tabla se evalúa en el tiempo, como TABLE 1(TIME), cada salto es un punto de quiebre de la corrida. siru corta el paso justo antes del salto y lo cruza con un paso mínimo, así ningún paso promedia el valor de antes con el de después. La salida muestra el salto en dos filas, una a cada lado (Integrador, r2104; siru/corpus/EXACTAS.md). Vale también para una tabla en archivo aparte, y para funciones que saltan en el tiempo, aunque el tiempo esté transformado de forma lineal: if(T<1,...), if(4*T-2 < 2,...), T < TCORTE con un parámetro, sgn(T-1), mod(T,2), T % 3, floor(T/2), una tabla evaluada en 2*T+1, o una función propia evaluada en T que haga eso. Vale con Runge-Kutta, con GLM y con PGLM. En un método multipaso, como BDF2, el paso que cruza el salto y el siguiente se dan como el primero de la corrida. Lo que no se reconoce, como sin(T) > 0.5 o un salto de una variable del circuito, pierde medio paso en cada salto. Ejemplos: siru/corpus/corpus/inventados/salto-*.ds.

FUNCTIONS                              .d: adentro del archivo
TABLE 1
  0,0, 1,1, 2,0
ELEMENTS
 E1, GND-1 = TABLE 1 (T)              o T1(T), o XTABLE(T1, VC1)

ELEMENTS                               .ds: en un archivo de dos columnas
 EB-E1, GND-1 = Table('tabla.txt','TIEMPO','DATO',T,1)

Desde el 02/10/2026 un .ds también acepta la forma de SCEPTRE, con la tabla adentro del archivo: en FUNCTIONS TABLE 1 y debajo los pares (o TABLE 1, 0,0, 1,1, 2,0 en una línea), y en el valor TABLE 1 (T) o TABLE 1(TIME). La forma corta T1(T) en un .ds sólo vale si la tabla ya se leyó (antes de ELEMENTS); si no, se toma por una función. Ejemplo: siru/corpus/.../needsderiJ.ds, que da lo mismo que su .d.

El archivo tabla.txt es de tabular2: una línea #TIEMPO DATO y las filas; su ruta es relativa al .ds (o al directorio de arriba, como corría Siru). Las x tienen que ir creciendo. Table() también se puede usar adentro de una función. Ejemplos: slex/d2datdinc/pruebas/tablas.d, siru/corpus/.../tabla.ds.

Funciones en Fortran: EXTERNAL. Una función escrita en Fortran, en un .f90, .f o .for aparte (la "External Function" del manual de SCEPTRE, 2.2.2 y 2.7), se declara en FUNCTIONS con su nombre, su cantidad de argumentos (de 1 a 12) y la ruta del fuente, relativa al .d o al .ds:

ELEMENTS                               .d
 E1, GND-1 = FGEN (0., 5., 20., 40., 100., 100., 300., 2., TIME)
 L2, 2-GND = FCOR (IL2, IR1, 25., 100.)
FUNCTIONS
 EXTERNAL FGEN (9) fgen.f90
 EXTERNAL FCOR (4) fcor.for

El fuente tiene que ser una FUNCTION de doble precisión, con los argumentos por referencia, que es lo normal en Fortran:

      FUNCTION FCOR(IL, IR, L0, ISAT)
      DOUBLE PRECISION FCOR, IL, IR, L0, ISAT
      FCOR = L0 / (1D0 + ((IL + IR)/ISAT)**2)
      END FUNCTION

d2datdinc lleva la declaración al .din (sección externas, con la ruta absoluta); Calcula compila el fuente con gfortran -shared -fPIC -O2 a un .so en ~/.cache/calcula/externas, lo vuelve a compilar si el fuente cambia, lo carga y llama a fgen_, el nombre en minúsculas con el _ que le pone gfortran. También acepta un .so ya compilado como ruta. Hace falta gfortran donde se corre, y CALCULA_EXTERNAS=1 en el entorno: es código de afuera, y Calcula no lo carga sin ese permiso. Por eso Puyuspa, que corre archivos de cualquiera, no ejecuta un ejemplo con funciones externas salvo que se lo instale en el servidor. Los mensajes de error están en la sección 13. Ejemplo: siru/corpus/corpus/fortran/subprograma.d, con fgen.f90 y fcor.f90.

ETABLE: una tabla en un archivo aparte, por número. Es la forma de SCEPTRE y Simusol: ETABLE(N, X, Y, V, M) es la tabla número N, interpolada en V, con las abscisas en la columna X y los valores en la columna Y (contadas desde 0) y el método M (1 lineal, 2 spline). Qué archivo es cada número lo dice etable.txt, junto al archivo, con una línea número archivo por tabla:

DEFINED PARAMETERS                     con_FOR.d
PP = X1(ETABLE(2,0,2,TIME,2))

2 con_FOR.etable                       etable.txt

siru la tiene de dos maneras. La normal: no hay que declarar nada; libdin la traduce a tabla('con_FOR.etable','0','2',t,2) de Calcula (desde calcula 6.0-34, que acepta las columnas por número). La de Fortran: si el archivo la declara EXTERNAL ETABLE (5) RUTA/tabular2/fortran/etable.f90, se llama a esa función —la misma que enlaza SCEPTRE—, con CALCULA_EXTERNAS=1. Las dos dan lo mismo. Ejemplos: siru/corpus/corpus/fortran/con_FOR_1.d (la normal) y con_FOR_1.ds (la de Fortran).

Un archivo sin circuito ni estados que pide una corrida —una tabla o una función a lo largo del tiempo, como esos— se resuelve punto por punto, con el paso de SIRU_PASO, o el de MAXIMUM STEP SIZE en un .d, o la milésima parte del tiempo final (11); la salida lleva el tiempo y los OUTPUTS.

10. Ecuaciones propias, estados propios, parámetros

Un circuito puede traer ecuaciones además de las suyas, y un archivo puede no tener circuito y ser sólo ecuaciones.

Un sistema sin circuito:

CIRCUIT_DESCRIPTION
  y'' = -y
VARIABLES
DY1=0
DY2=0
EQUATIONS
DY1-Y2
DY2+Y1
OUTPUTS
T:Y1,Y2
DEFINED_PARAMETERS
T=0
TIEMPOFINAL=3
Y1=1
Y2=0
RUN_CONTROLS
RK=[12]
CONTROL_EQUATIONS
T<TIEMPOFINAL
END

Ejemplos: slex/d2datdinc/pruebas/propias.d, parametros-propios.d, nucleo.d, nulo.d.

11. La corrida

Composición de subflujos (SPLIT)

Se declara cómo avanzar cada subproblema, no solamente su derivada. Para el oscilador Q'=P, P'=-Q, A mueve Q manteniendo P y B mueve P manteniendo Q. En RUN_CONTROLS de un .ds:

SPLIT=[2]
SPLIT_AUTONOMO=[1]
SPLIT_EXACTOS=[1]
SPLIT_A=[Q,Q+SPLIT_H*P,P,P]
SPLIT_B=[Q,Q,P,P-SPLIT_H*Q]
SIRU_PASO=[0.1]
SIRU_ADAPT=[0]
Selector Orden de ejecución de subavances Orden esperado con subflujos exactos suaves
SPLIT=[1] A(h), luego B(h) 1 (Lie–Trotter)
SPLIT=[2] A(h/2), luego B(h), luego A(h/2) 2 (Strang)

Cada lista debe incluir una expresión para todos los estados, incluso los que se conservan. Las expresiones de un mismo mapa se evalúan simultáneamente sobre su estado de entrada. SPLIT_H es la duración de ese subavance: no es el tiempo físico ni el paso completo. Se permite aritmética + - * / ^ y paréntesis con estados y parámetros constantes. No se admiten referencias al tiempo, derivadas, variables algebraicas, funciones o tablas en estos mapas iniciales.

SPLIT_AUTONOMO=[1] y SPLIT_EXACTOS=[1] son declaraciones del autor: los mapas deben ser flujos exactos de las partes del modelo y valer la identidad con duración cero. El programa verifica forma, nombres y capacidades, no demuestra esas propiedades matemáticas. Reemplazarlos por un Euler aproximado puede perder el orden dos de Strang. El modelo residual completo se conserva y Calcula lo resuelve en los estados intermedios; debe ser válido allí.

En .d se escriben SPLIT AUTONOMO, SPLIT EXACTOS, SPLIT A, SPLIT B (con espacios), y los controles habituales STARTING STEP SIZE y SIRU ADAPTIVE STEP = 0. El ejemplo lc-strang.d (fuentes: siru/corpus/corpus/SPLIT/lc-strang.d) declara mapas de QC1, la carga que libdin usa como estado, aunque pide VC1 como salida; C=L=1. También están oscilador-1.ds (fuentes: siru/corpus/corpus/SPLIT/oscilador-1.ds) y oscilador-2.ds (fuentes: siru/corpus/corpus/SPLIT/oscilador-2.ds).

La cadena es .d/.ds → d2datdinc --din → NOMBRE-de-d2datdinc-SPLIT1.din o -SPLIT2.din → siru. El .din contiene las ecuaciones de ambos mapas y un descriptor # split v1 con su secuencia, estados y salidas; no requiere fuente, .dat ni catálogo. split_h y split_flujo son datos internos de Calcula, split_p_estado es la salida del mapa y p_estado es la salida virtual del paso completo. Los prefijos split_ y p_ están reservados.

Solo se confirma el reloj y se escribe una fila al terminar toda la secuencia. Los tiempos internos no se suman: A(h/2), B(h), A(h/2) representan un único paso físico h, no 2h. Un fallo de subflujo aborta sin publicar trayectoria parcial. El informe cuenta pasos completos, subavances y consultas; se aceptan último paso acortado y --paso-factor.

Límites: un selector, paso fijo positivo, modelo autónomo, dos flujos declarados exactos, sin adaptación, .mdin, llaves, eventos, convolución, DT/TICK, DC/AC, RERUN/CONTINUE, funciones propias o externas ni tablas internas o externas. Quedan para otra ampliación los subflujos aproximados, sus tolerancias, pasos negativos, más particiones y el tiempo no autónomo. El núcleo genérico es Siru::Composicion, y Siru::SPLIT lo conecta con el conductor transaccional y Calcula. Pruebas: prove -Ilib tests/split_nucleo.t tests/split.t.

GLM fijo o adaptativo

GLM=[1] selecciona Euler explícito, [20] BDF2 efectivo, [21] BDF2 directo y [30] Adams–Bashforth 2. Son IDs propios del catálogo GLM, no índices RK. Solo se admite uno por corrida, con .din simple, sin llaves, lazos/cortes, convoluciones ni RERUN. El artefacto generado contiene el descriptor y se ejecuta sin fuente ni .dat.

En RUN_CONTROLS de un .ds, por ejemplo:

GLM=[21]
SIRU_ADAPT=[1]
SIRU_PASO=[0.1]
SIRU_PASO_MIN=[1e-8]
SIRU_PASO_MAX=[0.2]
SIRU_ABSOLUTO=[1e-5]
SIRU_RELATIVO=[0]
SIRU_ORDEN_ERROR=[2]

En .d se usan los controles con espacios de la tabla de abajo. [0] en SIRU_ADAPT conserva el modo fijo. En adaptación, el orden del estimador debe ser 2: se compara BDF2/AB2 con un paso Euler desde el mismo estado confirmado; el arranque/Euler se comparan con dos medios pasos Euler. Se acepta siempre el candidato principal. Es una primera política conservadora, no BDF de orden variable ni una garantía de error global. Un fallo de Calcula aborta; el rechazo por tolerancia no mueve historia ni tiempo. No se admite DT/TICK dentro del modelo adaptativo.

Los .din nuevos usan contrato GLM v2; los v1 archivados conservan el paso fijo y deben regenerarse para activar adaptación. estadisticas ultima integracion: en el .informe registra intentos, aceptaciones, descartes y consultas del conductor, incluyendo las de comparación. En RERUN/CONTINUE de otros motores describe la última integración, no la suma de corridas. ROS conserva su registro estadisticas ROS:. Fórmulas, límites y ejemplos en GLM_CONTRATO.md.

Rosenbrock (extension ROS)

ROS=[1] en RUN CONTROLS (.d) o RUN_CONTROLS (.ds) selecciona ROS2 de orden dos. Es excluyente con RK, GLM, PGLM e IMEX_EXPLICITA. SIRU ADAPTIVE STEP = 0 en .d o SIRU_ADAPT=[0] en .ds selecciona paso fijo; con 1 usa el estimador embebido ROS2 2(1), las tolerancias SIRU y los limites de paso existentes. El orden del error es 2. No admite todavia llaves, lazos/cortes, convoluciones, DT/TICK, paradas adicionales, inicializacion algebraica, analisis DC, sensibilidad, Monte Carlo, peor caso, RERUN ni CONTINUE.

El archivo generado termina en -ROS1.din y se puede ejecutar sin su fuente; incluye OUTPUTS si se pidieron. El motor consulta el campo diferencial en Calcula, calcula un Jacobiano por diferencias y resuelve las etapas lineales. No usa la numeracion RK ni supone que el Jacobiano de Newton sea el de la ecuacion diferencial. Detalles y precauciones de escalas y precision en ROS.md.

Los din nuevos usan descriptor ROS v2 fijo o v3 adaptativo, con escalas configurables y comprobacion de diferencias a dos perturbaciones; los v1 archivados conservan el comportamiento anterior. En .ds: ROS_ESCALAS=[X,1e-6,Z,1e6], ROS_ESCALA_TIEMPO=[1], ROS_DELTA=[1e-4], ROS_CONTROL_JACOBIANO=[1e-6,1e-3,3]. En .d los nombres llevan espacios en lugar de guiones bajos. Estas opciones controlan la diferenciacion numerica, no activan adaptacion temporal ni cambian la precision interna de Calcula. v3 agrega la seccion adaptacion y los errores virtuales e_estado; solo publica pasos aceptados. Fallos del campo/Jacobiano abortan, no se ocultan reduciendo el paso temporal.

Con adaptacion activa, ROS_TOLERANCIAS=[X,1e-11,1e-4,Z,10,1e-4] declara grupos estado, absoluta, relativa; en .d se llama ROS TOLERANCIAS. Los estados omitidos usan las tolerancias globales. Se guarda el mapa completo en descriptor v4, de modo que el din sigue siendo autosuficiente. No confundir estas tolerancias temporales con ROS_ESCALAS. El informe .informe incluye estadisticas ROS: en JSON: pasos aceptados/rechazados, intentos, consultas a Calcula y estado de finalizacion; las consultas del campo y de OUTPUTS se cuentan por separado. Detalles en ROS.md.

Para ROS tambien se puede elegir ROS_JACOBIANO=[SENSIBILIDADES] (en .d, ROS JACOBIANO): genera descriptor v5 y requiere un Calcula con capacidad SENS1. Este resuelve el punto y obtiene el Jacobiano reducido mediante las sensibilidades de los residuos, sin resolver otro punto por cada perturbacion. ROS_ESCALAS_RESIDUO=[Z,1] permite escalas de cualquier variable, incluidas algebraicas. Es optativo: los archivos anteriores mantienen campo_central. Funciona con paso fijo o adaptativo; sus fallos abortan sin cambio silencioso de proveedor. Limites y controles numericos en ROS.md.

Controles generales y Runge-Kutta

qué .d .ds
hasta cuándo STOP TIME = 5, o T>5 TIEMPOFINAL=5 y T<TIEMPOFINAL en CONTROL_EQUATIONS
desde cuándo START TIME = 0 (0 si no) T=0 en DEFINED_PARAMETERS
otra parada TICK>1000, VC1>0.9 en RUN CONTROLS TICK<=1000, VC1<=0.9 en CONTROL_EQUATIONS (se sigue mientras vale)
método INTEGRATION ROUTINE = TRAP (sólo TRAP, IMPLICIT, XPO, RUK) RK=[12], cualquiera de la tabla
varios métodos, rotando no RK=[18,18,11]
paso STARTING STEP SIZE = 0.05 STARTING STEP SIZE = 0.05 (desde r1890; también MINIMUM y MAXIMUM), o SIRU_PASO=[0.05]
semilla de calcula SEMILLA VL2 = 0.1 SEMILLA VL2 = 0.1, o VL2=0.1 en VARIABLES si es de una rama
paso adaptativo MINIMUM/MAXIMUM STEP SIZE, SIRU ABSOLUTE TOLERANCE, SIRU RELATIVE TOLERANCE, SIRU ERROR ORDER, SIRU ADAPTIVE STEP = 1 SIRU_PASO_MIN=[..], _PASO_MAX, _ABSOLUTO, _RELATIVO, _ORDEN_ERROR, SIRU_ADAPT=[1]
qué sale OUTPUTS con VC1, IR1 igual, o T:VC1,IR1

Hasta el 05/10/2026 los nombres que empiezan con SIRU empezaban con SIMUL2 (SIMUL2_PASO=[0.05], SIMUL2 ADAPTIVE STEP = 0). Un circuito que todavía los trae así corre igual: d2datdinc los lee como los de ahora, y con -v lo avisa.

Un .d sin INTEGRATION ROUTINE usa 13, como SCEPTRE; un .ds sin RK= usa Euler (0) y siru lo dice.

El paso, si el archivo no lo dice: la milésima parte del tiempo final, y adaptativo, que es lo que hace SCEPTRE —el programa para el que se escribieron estos archivos— cuando no le dan controles de paso. Hasta el 06/10/2026 era 0.1 fijo, un número que no tiene nada que ver con la escala de cada circuito: con él los planetas (STOP TIME = 0.1) hacían toda la corrida en un paso, auditorio (120 horas) pedía 4,3 millones de pasos y los rígidos (λ = −25, escala 0.04) no convergían. Un paso fijo hay que pedirlo: SIRU ADAPTIVE STEP = 0 (.d) o SIRU_ADAPT=[0] (.ds), y conviene dar también el paso, porque si no es esa misma milésima parte. Cualquier control de paso o de tolerancia prende la adaptación. Con adaptación y sin MAXIMUM STEP SIZE, el paso máximo es el de SCEPTRE: 2 % del tiempo final. Los métodos de rk.siru:

N método N método
0 Euler 10 Bogacki–Shampine
1 Euler implícito 11 Punto medio implícito
2 Punto medio explícito 12 Lobatto IIIA (trapecio; TRAP)
3 Heun 13 Lobatto IIIC, stiff (IMPLICIT, XPO)
5 Ralston 14 Lobatto IIIC*
6 Kutta 15 Runge–Kutta–Fehlberg
7 Runge–Kutta clásico (RUK) 16 Cash–Karp
17 Dormand–Prince
18 Gauss–Legendre 6

Para un circuito con diodos o constantes de tiempo muy distintas, 12 o 13. RK=[-1] pide resolver un punto sin integrar, incluso si el modelo tiene estados: se fijan en sus valores iniciales. Véase §12.

OUTPUTS puede pedir cualquier variable del circuito (VC1, IR1, QC1, IL1, VS1), un estado propio, un parámetro, T; lo que no se pueda traducir queda anotado con - y no impide simular. Sin OUTPUTS salen los estados.

Las semillas. Calcula resuelve cada paso con Newton, y arranca de la semilla de cada incógnita: la solución del paso anterior, o al principio el valor del .din, que para las variables de las ramas es 0. Si el modelo no se puede evaluar ahí --una bobina L2 = 1/VL2 da 1/0 con VL2 = 0 (circuito-T3.ds)--, calcula falla antes de iterar. SEMILLA VL2 = 0.1 en RUN CONTROLS (un .d o un .ds, una línea por variable) le da otro punto de partida; en un .ds, también un valor en VARIABLES para la tensión o la corriente de una rama. No cambia el problema, sólo de dónde arranca Newton. Si el nombre no es una incógnita (un parámetro, un estado), se avisa por la salida de errores y se ignora.

T, DT y TICK los pone el simulador en cada paso: el tiempo, el paso en uso y la cantidad de pasos dados. Lo que el archivo les ponga (CONSTANTS DT=0.01) no fija nada.

11 bis. El punto de operación (RUN INITIAL CONDITIONS)

Como en SCEPTRE: con RUN INITIAL CONDITIONS en RUN CONTROLS (sólo en un .d), siru calcula los estados en t = 0 con las derivadas en cero —capacitores abiertos, bobinas en corto— partiendo de las condiciones iniciales del archivo como semilla, y arranca la corrida desde ahí. Con RUN INITIAL CONDITIONS ONLY escribe ese punto, una fila, y termina. Es lo que SCEPTRE llama «initial conditions calculation» (manual 2.2.5, 2.2.7), y la base de la sensibilidad, Monte Carlo y el peor caso (pendientes, PLAN_DC_RERUN.md). Ejemplo: siru/corpus/corpus/Nsceptresimusol_samples/a03.d.

Cuando Newton no llega al punto de operación (varios transistores, exp(38·v)), o cuando el archivo dice RUN IC VIA IMPLICIT, siru lo busca integrando, como SCEPTRE: integra el circuito con el tiempo quieto en el inicial, desde las condiciones iniciales del archivo, en tramos del largo de la corrida (hasta 20), y desde el estado de cada tramo prueba Newton sobre el sistema del punto de operación. En la pantalla: punto DC por integracion: tramo 1 (50 de tiempo), el estado se mueve 3.52 por tramo; Newton llega. El primer paso de la corrida, el instante de cada fila de salida y el equilibrio arrancan Newton de esa solución y no de las semillas del archivo. Ejemplo: siru/corpus/corpus/Nsceptresimusol_samples/d04.d.

11 ter. Sensibilidad (RUN SENSITIVITY)

Como en SCEPTRE (manual 2.2.8), sólo en un .d: bajo CIRCUIT DESCRIPTION una subsección SENSITIVITY con conjuntos (dependientes / independientes), y RUN SENSITIVITY en RUN CONTROLS:

SENSITIVITY
   (VC1, PABC / R1, E1)
RUN CONTROLS
   RUN SENSITIVITY

siru calcula el punto de operación DC (11 bis) y, para cada dependiente y cada independiente, la derivada parcial por diferencias centradas y la normalizada (dy/dx)(x/y), y las escribe en NOMBRE.dc, una tabla de texto. Dependientes: VC, IR, VR, IL, IE, una fuente de corriente (su corriente) o un parámetro definido (PABC). Independientes: un valor que sea un dato —una resistencia, una fuente, un parámetro definido con un número—; una rama que vale una expresión no lo es, y hay que pedir la derivada respecto de sus parámetros. Ojo: la tabla de sensibilidad de SCEPTRE no coincide con sus propias corridas (PLAN_DC_RERUN.md, paso 3); la de siru sí.

11 quater. Monte Carlo (RUN MONTE CARLO)

Como en SCEPTRE (manual 2.2.9), sólo en un .d: una subsección MONTE CARLO con conjuntos (dependientes / independientes), cotas en los independientes —R1 = 100 (90, 110) mínimo y máximo, o R1 = 100 (10) en porcentaje— y RUN MONTE CARLO = n en RUN CONTROLS (10 si no se da n):

MONTE CARLO
   (VC1, IR2 / R1, E1)
RUN CONTROLS
   RUN MONTE CARLO = 50
   INITIAL RANDOM NUMBER = 127263527
   DISTRIBUTION = UNIFORM

siru hace exactamente lo que SCEPTRE: n puntos de operación DC (11 bis) con cada independiente en media + sigma·g, media (max+min)/2, sigma (max−min)/6, g gaussiana (suma de 12 uniformes menos 6) o uniforme; el generador es el de SCEPTRE (RANDU) con su semilla, así que con la misma semilla salen las mismas muestras. Escribe en NOMBRE.mc una tabla con, por independiente y dependiente, el nominal, el mínimo, el máximo, la media y el sigma muestral (con N−1). Ojo, dos cosas heredadas de SCEPTRE: la "uniforme" cae en [media, media+sigma), no entre las cotas; y tras RUN MONTE CARLO los OUTPUTS que lista SCEPTRE son los de la última muestra, los de siru los nominales. siru/corpus/sceptre compara NOMBRE.mc con las OBSERVED STATISTICS de SCEPTRE (NOMBRE.sceptre-mc); en a07 coinciden en ocho cifras.

11 quinquies. Peor caso (RUN WORST CASE)

Como en SCEPTRE (manual 2.2.7), sólo en un .d: una subsección WORST CASE con conjuntos (dependientes / independientes), cotas en los independientes (como en Monte Carlo) y RUN WORST CASE en RUN CONTROLS:

WORST CASE
   (VCET1, VCCT1 / P1T1, P1T2, R3)
RUN CONTROLS
   RUN WORST CASE

Por cada dependiente, siru calcula el gradiente respecto de los independientes en el punto de operación nominal, lo normaliza y avanza por esa recta hasta la primera cota que toca, a favor del gradiente (HIGH) y en contra (LOW); en esos dos puntos resuelve el punto de operación. Es exactamente el método de SCEPTRE (worst.f): no pone cada independiente en su cota, sólo el más cercano llega a la suya. Escribe NOMBRE.wc: por (dependiente, independiente) el nominal, HIGH y LOW del dependiente, y el valor y el gradiente del independiente en los tres puntos; en comentarios, la distancia y la cota que toca cada extremo. Ojo: los extremos de siru no son los de SCEPTRE, porque el gradiente de SCEPTRE está mal (11 ter); en a09 los de siru son más extremos, y SCEPTRE corrido en los puntos de siru da lo mismo que siru (PLAN_DC_RERUN.md, paso 5). Con RUN WORST CASE = LOW | HIGH la corrida en el tiempo sigue con los valores de ese extremo del último dependiente (y desde su punto de operación); con NOMINAL, por omisión, con los nominales. Ojo: SCEPTRE integra con los valores contrarios (con HIGH deja los LOW y al revés; worst.f calcula HIGH y después LOW y queda lo último): siru hace lo que dice el manual.

11 sexies. Reruns (RERUN DESCRIPTION)

Como en SCEPTRE (manual 2.4), sólo en un .d: después de RUN CONTROLS, RERUN DESCRIPTION (N) con las secciones que cambian y, en cada línea, los N valores, uno por rerun:

RERUN DESCRIPTION (2)
ELEMENTS
   R1 = 9.3, 9.5
DEFINED PARAMETERS
   PF = 500, 600
INITIAL CONDITIONS
   VC1 = 1, 2
FUNCTIONS
   TABLE 1 = 0, 0, 0
            40, 1.2, .4
RUN CONTROLS
   STOP TIME = 600, 700
   INTEGRATION ROUTINE = XPO, RUK
   IC FOR RERUNS = PRECEDING RESULTS

siru corre la maestra y después cada rerun con sus cambios (elementos, parámetros, condiciones iniciales, tablas, STOP TIME, START TIME, INTEGRATION ROUTINE; lo demás se avisa y no se aplica). Cada rerun parte de las condiciones iniciales del archivo (IC FOR RERUNS = MASTER RESULTS, por omisión) o del estado final de la corrida anterior (PRECEDING RESULTS). Todo va al mismo NOMBRE.simul, un bloque por corrida con su cabecera y una línea # RERUN k/N (R1 = 9.3, STOP TIME = 600) (0 es la maestra). Ojo: interpola y tabular leen el archivo entero como una tabla; para una corrida sola hay que cortar su bloque (empieza en # Archivo). siru/corpus/sceptre compara bloque por bloque; a03 y tanque_par_1 coinciden con SCEPTRE (PLAN_DC_RERUN.md, paso 6).

11 septies. Seguir una corrida (CONTINUE, --continuar)

Una corrida terminada se sigue desde donde quedó:

siru --continuar --hasta 40 circuito.d

siru lee el estado final que dejó en circuito.informe (estado final: t=20 qc1=6.87; si no está, la corrida no terminó bien y hay que correrla de nuevo), integra de ahí hasta 40 y anexa el bloque # CONTINUE (desde t = 20, STOP TIME = 40) al mismo circuito.simul; el .informe queda con el nuevo estado final, así que se puede volver a continuar. No se recalcula el punto de operación ni las opciones DC; los valores que dejó el peor caso (WORST CASE = LOW | HIGH) se heredan. En un .d, la sección CONTINUE de SCEPTRE (manual 2.5) con sus RUN CONTROLS (STOP TIME = 2000) hace lo mismo al final de la corrida, siguiendo la última (la maestra o el último rerun):

CONTINUE
RUN CONTROLS
   STOP TIME = 2000

11 octies. El análisis en frecuencia (RUN AC)

RUN AC (manual de SCEPTRE 2.2.4) no integra en el tiempo: linealiza el circuito alrededor de su punto de operación y resuelve en frecuencia. Es un análisis de pequeña señal.

ELEMENTS
  EDC, GND-1 = 0.6                 la polarización, como siempre
  EAC, 1-2 = (0.001, 0.)           la excitación: magnitud y fase en grados
  ...
RUN CONTROLS
  RUN AC
  INITIAL FREQUENCY = 100
  FINAL FREQUENCY = 10000
  NUMBER FREQUENCY STEPS = 2       dos intervalos, o sea tres frecuencias
  TYPE FREQUENCY RUN = LOG         o LINEAR (el que se toma si no se dice)

Una fuente que vale (magnitud, fase) es la excitación. En el tiempo vale 0: es una perturbación, no una fuente de la corrida. Pueden ser varias, y sus respuestas se suman.

El punto de operación se calcula siempre, aunque el archivo no diga RUN INITIAL CONDITIONS: el análisis es alrededor de él. Si el archivo no trae STOP TIME, el análisis es toda la corrida y no hay nada en el tiempo, como con RUN INITIAL CONDITIONS ONLY.

La salida es NOMBRE.ac: una fila por frecuencia y, por cada variable de OUTPUTS, cuatro columnas, su parte real, su imaginaria, su módulo y su fase en grados. El encabezado dice la excitación y los estados.

Cómo lo hace (Siru::AC): el circuito es dq/dt = f(q, u) con las salidas y = g(q, u), y hace falta A = df/dq, B = df/du, C = dg/dq y D = dg/du. Esas derivadas salen por diferencias centradas del sistema del punto de operación, el que tiene las derivadas como datos y los estados como incógnitas: una corrida por cada dato que se mueve. No se deriva ninguna expresión. Después, para cada frecuencia, (sI − A) X = B U y Y = C X + D U, con s = j·2πf y U el fasor; el sistema complejo se resuelve por eliminación gaussiana con pivoteo.

No se usa el sistema del instante, el que tiene los estados como datos, porque en un circuito con transistores no converge: dada la carga de una juntura, hallar su tensión es el problema difícil.

Probado (tests/ac.t, los circuitos en corpus/corpus/inventados/ac-*.d): un pasabajos RC coincide con su transferencia 1/(1 + jωRC) en 6·10⁻¹¹, y un diodo polarizado, que no tiene fórmula, coincide con la corrida en el tiempo del mismo circuito excitado con 0.001·sin(2πft) en 2,5·10⁻⁵, que es el error del paso.

Lo que no hace:

PRINT EIGENVALUES, PRINT EIGENVECTORS los valores propios del circuito linealizado; se avisa
COMPLEX, NYQUIST, DEGREES, RADIANS en OUTPUTS el formato de columnas de SCEPTRE; el .ac trae siempre las cuatro
(10,4), COMPLEX en el valor el fasor dado por parte real e imaginaria en lugar de magnitud y fase
parámetros y funciones complejas lo que prueba complex.d: aritmética compleja en las expresiones

11 nonies. Relajación de forma de onda (siru-relaja)

siru-relaja simula un circuito partido en subcircuitos, cada uno en su proceso, por relajación de forma de onda (waveform relaxation; Lelarasmee, Ruehli y Sangiovanni-Vincentelli, 1982). Es el camino para repartir una simulación entre varios procesos, o máquinas, cuando el circuito es grande. Pedido del autor, 06/10/2026; el porqué está en calcula-6.0/PENDIENTE-iterativos.md, método 4.

perl bin/siru-relaja --partes 4 --ventana 5 grilla-rc-10x10.d
perl bin/siru-relaja --partes 3 relaja-cadena.d

Cómo parte. Los nodos (sin la masa) se reparten en --partes partes por bisección del grafo de ramas, o como diga --particion ARCHIVO (una línea NODO PARTE por nodo, las partes desde 1). Cada rama va a la parte de sus nodos. Una rama cortada, que une un nodo de una parte con uno de otra, va a las dos: en cada una, el nodo ajeno se maneja con una fuente de tensión EWR<nodo> cuyo valor es una TABLE con la forma de onda de ese nodo de la iteración anterior. Así cada nodo tiene su ley de corrientes completa en su parte. La parte dueña de cada nodo de frontera lo mide con una fuente de corriente de cero, JWR<nodo>, que no cambia el circuito.

Cómo itera. En cada iteración las partes corren a la vez (--procesos, por omisión una por parte), cada una con las formas de onda de la iteración anterior (Jacobi), y se para cuando ninguna forma de onda de frontera cambia más que --tolerancia (1e-6, relativo a la mayor). La primera vez las fronteras valen 0. Con --ventana T el tiempo se parte en ventanas: cada una se itera hasta converger, y la siguiente arranca de los estados finales de cada parte (los del .informe). --iter-max (50) es el tope por ventana; --charla dice cada iteración.

Qué deja. En NOMBRE-relajacion/, al lado del archivo: el .d de cada parte (parte01.d...) con su .csv, .informe y .log de la última iteración, y NOMBRE.csv con las salidas pedidas de todas las partes (--salida para otro nombre).

Cuándo converge rápido. Cuando las partes están débilmente acopladas: la cadena RC de corpus/corpus/inventados/relaja-cadena.d (las etapas unidas por una resistencia veinte veces la de entrada) converge en 9 iteraciones con una sola ventana, y la de diodos (relaja-diodos.d, no lineal) en 18. Con acoplamiento fuerte hacen falta ventanas cortas: la grilla RC de 10×10 (grilla-rc-10x10.d) en cuatro partes y ventanas de 5 converge en 15 a 24 iteraciones por ventana. En los tres casos da la curva de la corrida entera: 3e-9, 2e-9 y 6e-6 de diferencia como mucho.

Lo que cuesta. Cada iteración corre las partes enteras otra vez, así que en una sola máquina tarda más que la corrida directa (la grilla: 296 s contra 8 s; la cadena: 43 contra 3,5). Lo que da es que cada parte es un proceso independiente, que podría ir a otra máquina, y que solo se intercambian las formas de onda de la frontera.

Lo que no hace todavía. Solo .d (SCEPTRE), con ramas de dos nodos (no MODEL DESCRIPTION). Una rama que nombra en su valor a otra (una fuente controlada, VC1 en el valor de R2) tiene que quedar en la misma parte: si la partición las separa, se avisa y no se corre; con --particion se las junta. El reparto es entre procesos de la misma máquina; a otras máquinas, falta.

11 decies. GPU: muchas copias de un circuito (ejemplos/montecarlo-gpu)

siru y calcula resuelven un circuito paso a paso, y eso no le conviene a una GPU: cada paso depende del anterior, la matriz es dispersa e irregular y una consulta dura alrededor de un milisegundo. siru-relaja (11 nonies) tampoco, porque son pocas tareas grandes. Lo que le conviene a una GPU es muchas copias independientes de un circuito chico: Montecarlo, barridos de parámetros, peor caso.

ejemplos/montecarlo-gpu es ese caso, listo para probar:

INFORME-GPU.md, en el mismo directorio, tiene las conclusiones: que la doble precisión decide la placa (solo las de cálculo científico la tienen rápida), que no hace falta CUDA, qué sirve también para IA, precios del 06/10/2026, y los pasos para usar una GPU gratis o alquilada. No se probó todavía en una GPU real.

12. Un punto, sin integración: RK=[-1]

El .ds contiene la información necesaria para Calcula: incógnitas, semillas, datos conocidos, constantes, funciones y ecuaciones; si hay circuito, también sus ramas y modelos. Con RK=[-1], Siru construye el sistema, llama a Calcula para resolverlo una vez y pone sus resultados en .simul. No hace falta escribir un .din aparte, preparar una simulación temporal ni declarar un tiempo ficticio.

Aspecto Comportamiento con RK=[-1]
Lugar y escritura En RUN_CONTROLS o RUN CONTROLS, una línea RK=[-1]. Es sintaxis .ds; no escribir KR, rk=-1 ni quitar los corchetes.
Resolución Una evaluación del sistema de Calcula. Calcula puede hacer las iteraciones internas necesarias para converger.
Incógnitas Los valores de VARIABLES son semillas. Los valores finales salen de resolver las ecuaciones.
Datos Los parámetros numéricos quedan fijados en los valores dados.
Estados Si existen, se fijan en sus valores iniciales; se pueden calcular sus derivadas, pero no se avanza en el tiempo.
Controles temporales No se hace un barrido aunque permanezcan T, TIEMPOFINAL, un paso o condiciones de continuación en el archivo.
Otros análisis Este modo no lanza los barridos/análisis DC adicionales. Para esos análisis usar el modo y los controles de §11 bis–quinquies.
Salida Una fila numérica con todas las variables declaradas en el sistema enviado a Calcula, incluidos sus datos. OUTPUTS no recorta esta tabla de un punto.
Precisión Los números se copian tal como los devuelve el protocolo de Calcula, sin un segundo redondeo ni sustituir resultados ausentes por cero. Algunos números pueden mostrar muchos decimales: ésa puede ser la escritura que entrega Calcula.
Nombres Se usan los nombres del sistema generado, habitualmente en minúsculas. Si OUTPUTS conserva nombres originales distintos, se agrega la fila sceptrevars para que Simplot pueda relacionarlos con la fuente. No se duplica una fila de nombres idénticos.
Unidades Se escribe la fila de unidades sólo cuando el sistema declara alguna. Para columnas sin unidad, dentro de esa fila, se usa -; si ninguna tiene unidad, se omite toda la fila. No se inventan ??, magnitudes ni unidades a partir del nombre de una variable.
Dibujo Si hay ramas y una sección FORMAS, incluso vacía, también se solicita el SVG al paquete opcional dibuja.
Limitación El modo de un punto con llaves SB se rechaza: requiere un tratamiento de las conmutaciones que este modo no implementa.

Las cantidades que el lector convierte a SI no conservan necesariamente una etiqueta de unidad en cada variable del sistema generado. La sección UNIDADES de gráficos no se usa para atribuir unidades a los resultados de Calcula: pertenece a la presentación de Simplot (§3.9).

Ejemplo completo, autosuficiente, sin bibliotecas externas, circuito ni tiempo. Guardarlo como punto.ds:

CIRCUIT_DESCRIPTION
Un dato y una incognita: X al cuadrado es A.
DEFINED_PARAMETERS
A=4
VARIABLES
X=1
EQUATIONS
X^2-A
OUTPUTS
X,A
RUN_CONTROLS
RK=[-1]
END

Al ejecutar siru punto.ds, Calcula resuelve X^2=A desde la semilla X=1 y entrega la raíz positiva, aproximadamente 2. punto.simul contiene los nombres a, x, sus nombres originales A, X y una fila numérica con 4 y el resultado de Calcula. No hay columna de tiempo ni fila de unidades porque no se declararon. Si ya existe la salida, Siru conserva la anterior y usa punto-1.simul, luego punto-2.simul, etc.

La llamada automática a Simplot descrita en §1 puede presentar la tabla al terminar. Para ejecutar exclusivamente el cálculo y escribir la tabla, usar siru -nosimplot punto.ds; esto no cambia el significado de RK=[-1] ni sus resultados.

Un ejemplo real es psicro_r_srk.ds, copia de psicro_5.ds con RK=[-1] explícito. TEMP, TBH y PRES son datos; XXX, WWW y PV son incógnitas. Sus ecuaciones y funciones están en el mismo archivo. Se ejecuta desde la raíz del repositorio con:

siru siru/corpus/corpus/loli2_nuesiru_PMP_Siru_examples/psicro_r_srk.ds

Sin RK=[-1]: un circuito sin estados y sin corrida temporal también se resuelve automáticamente en un punto, como slex/d2datdinc/pruebas/nulo.d. Si no tiene estados pero sí pide una corrida temporal, Siru puede resolver un punto por cada T de la grilla, usando la solución anterior como semilla del siguiente. Eso es un barrido y produce varias filas; no es el modo explícito RK=[-1].

13. Los mensajes, y qué hacer

Dónde aparece un error. En tres lugares, del más corto al más completo:

  1. En la pantalla, la última línea: siru: NO CONVERGE en t=78.3 (paso 783), o siru: no arranca en t=0 (paso 0).
  2. En NOMBRE.informe: resultado:, hasta: (el paso y el tiempo, contra el TIEMPOFINAL) y error:, la primera línea del motivo.
  3. En NOMBRE.log: todo, sin cortar. Cada línea dice quién la escribió: d2datdinc: ... (la traducción), calcula: ... (el sistema y el solver, y adentro de él tabular2 y las funciones externas) y al final siru: resultado: ....

siru/corpus/regenera deja el mismo NOMBRE.log al lado de cada fuente, con lo que dicen d2datdinc y clasificar al regenerarla, y siru/corpus/clasificar copia el resultado de NOMBRE.informe al .tipo (campo siru).

Los resultados del .informe:

resultado qué quiere decir
llega al final integró hasta TIEMPOFINAL (o resolvió el punto)
NO CONVERGE arrancó y en algún paso posterior al primero el solver no encontró solución; el hasta: dice dónde. Las filas hasta ahí son válidas
no arranca falló antes de integrar o en el paso 0: la traducción, la carga del sistema, o el solver en el punto inicial

Las tablas. Un error de tabla() lo detecta tabular2 y lo informa calcula, con el código, su motivo y el dato concreto:

calcula: tabla('jx','X','Y'): error -3 de tabular2: columnas mal especificadas:
la columna de abscisas (la X) tiene que crecer de una fila a la siguiente
(puede repetirse, no bajar), y las columnas pedidas tienen que existir
(la columna 0 de la tabla (la X) baja en la linea de datos 3: 1 despues de 2)

Los códigos de tabular2 (tabular2/src/table.h; el motivo lo da tb_mensaje(), el dato tb_detalle(), desde tabular2 2.0-10):

código motivo qué hacer
−1 no se pudo leer la tabla: no tiene el formato de tabular2 una línea # con los nombres de columna y después los datos
−2 no se pudo abrir el archivo ver la ruta: una relativa se busca junto al archivo que la usa
−3 la X no crece de una fila a la siguiente, o las columnas pedidas no existen ordenar la tabla; el detalle dice en qué línea baja
−4 la misma columna como X y como Y pedir dos columnas distintas
−5 datos no válidos (algo que no es número, un número de tabla repetido en etable.txt) corregir el dato
−6 argumento no válido (método distinto de 1 o 2, un número negativo) método 1 lineal o 2 spline
−7 la tabla no tiene datos en esas columnas revisar la tabla
−8 error de entrada o salida el disco, los permisos
−15 sin memoria
−888 no hay una columna con ese nombre en el encabezado usar el nombre de la línea #
−889 no se pudieron relacionar esas dos columnas la X no crece, o faltan datos

Las funciones externas (EXTERNAL NOMBRE (N) RUTA, sección 9):

mensaje qué pasa qué hacer
el .din declara funciones externas (codigo de afuera); calcula las carga solo con CALCULA_EXTERNAS=1 calcula no carga código de afuera sin permiso CALCULA_EXTERNAS=1 en el entorno
gfortran no pudo compilar RUTA el fuente tiene un error, o no hay gfortran compilarlo a mano: gfortran -shared -fPIC RUTA
la biblioteca de RUTA no tiene la funcion nombre_ el nombre del EXTERNAL no es el de la FUNCTION que coincidan
NOMBRE pide N argumentos y le dieron M la cantidad del EXTERNAL no es la del llamado corregir la N

Los demás:

mensaje qué pasa qué hacer
PENDIENTE ... algo del archivo no se pudo traducir; no se simula mirar qué es: un símbolo que no está, un control que Simul no tiene
tipo X de R: no tiene modelo en el dato un .ds sin include de la biblioteca, o un tipo que no existe agregar el include o declarar el tipo
modelo por incrementos L o C de la biblioteca vieja usar LB, CB
valor de R: no se puede traducir el simbolo X X no es rama, parámetro, función ni T declararlo
la funcion F no esta en el dato se usa sin definir en FUNCTIONS definirla
grados de libertad ... las ecuaciones propias no cierran con sus incógnitas una VARIABLE por ecuación, o una ecuación menos
aviso: los nodos 1 2 no tienen camino a la masa (GND) una parte del circuito no toca la masa (una isla) no es un error: en la isla un nodo va a potencial cero, de referencia; las tensiones y corrientes de las ramas no cambian. Si es un descuido, conectarla
los datos dados no determinan el sistema: ... incognitas que ninguna ecuacion libre siente Calcula: hay una incógnita que ninguna ecuación fija (un nodo que flota, una ecuación repetida) mirar las que nombra
no se obtuvo una solucion valida ... not making progress Newton no converge desde la semilla (diodos con mucha ganancia) semillas razonables en DEFINED PARAMETERS; método 13
la capacidad de C depende de X: en un lazo de capacitores en un lazo sólo puede depender del voltaje de capacitores (el propio u otro) o de una fuente en paralelo con uno (sección 7) sacar el lazo o la dependencia
vale (1,0), un fasor: es el analisis AC de SCEPTRE Diagnóstico de versiones antiguas sin AC Actualizar y usar el análisis AC de §11 octies; respetar sus límites.
se usa el metodo 0 un .ds sin RK= RK=[12]
para en TICK<=1000 la parada que puso el archivo es lo pedido

14. Lo que no se puede