@@ -18,6 +18,7 @@ interface SimulateArgs {
1818 interval ?: number ;
1919 format : string ;
2020 solver : string ;
21+ realtime ?: number ;
2122}
2223
2324// eslint-disable-next-line @typescript-eslint/no-empty-object-type
@@ -65,10 +66,14 @@ export const Simulate: CommandModule<{}, SimulateArgs> = {
6566 type : "string" ,
6667 choices : [ "rk4" , "dopri5" , "bdf" , "auto" ] ,
6768 default : "dopri5" ,
69+ } )
70+ . option ( "realtime" , {
71+ description : "run simulation in real-time mode with given scale factor (e.g., 1.0 for 1x)" ,
72+ type : "number" ,
6873 } ) ;
6974 // eslint-disable-next-line @typescript-eslint/no-empty-object-type
7075 } ) as CommandModule < { } , SimulateArgs > [ "builder" ] ,
71- handler : ( args ) => {
76+ handler : async ( args ) => {
7277 const parser = new Parser ( ) ;
7378 parser . setLanguage ( Modelica ) ;
7479 Context . registerParser ( ".mo" , parser ) ;
@@ -161,28 +166,56 @@ export const Simulate: CommandModule<{}, SimulateArgs> = {
161166 const step = args . interval ?? exp . interval ?? ( stopTime - startTime ) / 1000 ;
162167
163168 // Run simulation
164- const result = simulator . simulate ( startTime , stopTime , step , {
165- solver : args . solver as "rk4" | "dopri5" | "bdf" | "auto" ,
166- } ) ;
167- const states = result . states ;
168-
169- // Output results
170- if ( args . format === "json" ) {
171- const rows = result . t . map ( ( t : number , i : number ) => {
172- const row : Record < string , number > = { time : t } ;
173- states . forEach ( ( state : string , vIndex : number ) => {
174- row [ state ] = result . y [ i ] ?. [ vIndex ] ?? 0 ;
175- } ) ;
176- return row ;
169+ const states = Array . from ( simulator . stateVars ) as string [ ] ;
170+ if ( args . realtime !== undefined && args . realtime > 0 ) {
171+ if ( args . format === "csv" ) {
172+ const header = [ "time" , ...states ] . join ( "," ) ;
173+ process . stdout . write ( header + "\n" ) ;
174+ }
175+ // Stream results
176+ const res = await simulator . simulateAsync ( startTime , stopTime , step , {
177+ solver : args . solver as "rk4" | "dopri5" | "bdf" | "auto" ,
178+ realtimeFactor : args . realtime ,
177179 } ) ;
178- process . stdout . write ( JSON . stringify ( rows , null , 2 ) + "\n" ) ;
180+ // Print everything at the end for JSON. If we want we can stream CSV.
181+ if ( args . format === "json" ) {
182+ const rows = res . t . map ( ( t : number , i : number ) => {
183+ const row : Record < string , number > = { time : t } ;
184+ states . forEach ( ( state : string , vIndex : number ) => {
185+ row [ state ] = res . y [ i ] ?. [ vIndex ] ?? 0 ;
186+ } ) ;
187+ return row ;
188+ } ) ;
189+ process . stdout . write ( JSON . stringify ( rows , null , 2 ) + "\n" ) ;
190+ } else {
191+ for ( let i = 0 ; i < res . t . length ; i ++ ) {
192+ const values = [ res . t [ i ] , ...states . map ( ( _ : string , vIndex : number ) => res . y [ i ] ?. [ vIndex ] ?? 0 ) ] ;
193+ process . stdout . write ( values . join ( "," ) + "\n" ) ;
194+ }
195+ }
179196 } else {
180- // CSV format
181- const header = [ "time" , ...states ] . join ( "," ) ;
182- process . stdout . write ( header + "\n" ) ;
183- for ( let i = 0 ; i < result . t . length ; i ++ ) {
184- const values = [ result . t [ i ] , ...states . map ( ( _ : string , vIndex : number ) => result . y [ i ] ?. [ vIndex ] ?? 0 ) ] ;
185- process . stdout . write ( values . join ( "," ) + "\n" ) ;
197+ const result = simulator . simulate ( startTime , stopTime , step , {
198+ solver : args . solver as "rk4" | "dopri5" | "bdf" | "auto" ,
199+ } ) ;
200+
201+ // Output results
202+ if ( args . format === "json" ) {
203+ const rows = result . t . map ( ( t : number , i : number ) => {
204+ const row : Record < string , number > = { time : t } ;
205+ states . forEach ( ( state : string , vIndex : number ) => {
206+ row [ state ] = result . y [ i ] ?. [ vIndex ] ?? 0 ;
207+ } ) ;
208+ return row ;
209+ } ) ;
210+ process . stdout . write ( JSON . stringify ( rows , null , 2 ) + "\n" ) ;
211+ } else {
212+ // CSV format
213+ const header = [ "time" , ...states ] . join ( "," ) ;
214+ process . stdout . write ( header + "\n" ) ;
215+ for ( let i = 0 ; i < result . t . length ; i ++ ) {
216+ const values = [ result . t [ i ] , ...states . map ( ( _ : string , vIndex : number ) => result . y [ i ] ?. [ vIndex ] ?? 0 ) ] ;
217+ process . stdout . write ( values . join ( "," ) + "\n" ) ;
218+ }
186219 }
187220 }
188221 } ,
0 commit comments