SIMLIB/C++ 3.09
Loading...
Searching...
No Matches
run.cc
Go to the documentation of this file.
1/////////////////////////////////////////////////////////////////////////////
2//! \file run.cc Simulation control algorithm
3//
4// Copyright (c) 1991-2008 Petr Peringer
5//
6// This library is licensed under GNU Library GPL. See the file COPYING.
7//
8
9//
10// description: control of simulation
11//
12
13
14////////////////////////////////////////////////////////////////////////////
15// interface
16////////////////////////////////////////////////////////////////////////////
17
18#include "simlib.h"
19#include "internal.h"
20#include <cstdlib> // exit()
21
22
23////////////////////////////////////////////////////////////////////////////
24// implementation
25////////////////////////////////////////////////////////////////////////////
26
27namespace simlib3 {
28
30
31////////////////////////////////////////////////////////////////////////////
32// SIMLIB global variables ### move to extra module!!!
33//
34// SIMLIB_* --- internal variables
35// [A-Z]* --- user-level variables
36//
37
38
39// time-related variables
40double SIMLIB_StartTime; // time of simulation start
41double SIMLIB_Time; // simulation time
42double SIMLIB_NextTime; // next-event time
43double SIMLIB_EndTime; // time of simulation end
44
45// read-only references to time variables
46// ASSERTION: StartTime <= Time <= NextTime <= EndTime
47const double & StartTime = SIMLIB_StartTime; // time of simulation start
48const double & Time = SIMLIB_Time; // simulation time
49const double & NextTime = SIMLIB_NextTime; // next-event time
50const double & EndTime = SIMLIB_EndTime; // time of simulation end
51
52// current entity pointer
54Entity *const &Current = SIMLIB_Current; // read-only reference
55
56// phase of simulation experiment
58const SIMLIB_Phase_t & Phase = SIMLIB_Phase; // read-only reference
59
60// experiment counter
61unsigned long SIMLIB_experiment_no = 0;
62
63////////////////////////////////////////////////////////////////////////////
64/// internal statistical information
66 Init();
67}
69 StepCount = 0;
70 MinStep = -1;
71 MaxStep = -1;
72 EventCount = 0;
73 StartTime = -1;
74 EndTime = -1;
75}
76
79
80////////////////////////////////////////////////////////////////////////////
81// private module variables
82
83static bool StopFlag = false; // if set, stop simulation run
84
85////////////////////////////////////////////////////////////////////////////
86// support for Delay blocks (internal)
87//
88DEFINE_HOOK(Delay); // called in Run() and SampleDelays()
89DEFINE_HOOK(DelayInit); // called in Init()
90
91// for explicit sampling
92void SampleDelays() { // used at step-wise changes !!!###
94}
95
96// ZDelays:
97DEFINE_HOOK(ZDelayTimerInit); // called in Run()
98
99////////////////////////////////////////////////////////////////////////////
100// support for simulation interrupt (user-level)
101//
102DEFINE_HOOK(Break); // called in Run()
103
104void InstallBreak(void (*f)()) { // for user interface (in simlib.h)
105 INSTALL_HOOK( Break, f );
106}
107
108////////////////////////////////////////////////////////////////////////////
109// support for Samplers (internal)
110//
111DEFINE_HOOK(SamplerAct); // called in Run()
112DEFINE_HOOK(SamplerInit); // called in Init()
113
114
115////////////////////////////////////////////////////////////////////////////
116// WUclear hook --- if non-empty WUlist, call init function
117//
118DEFINE_HOOK(WUclear); // should be in run.cc
119
120////////////////////////////////////////////////////////////////////////////
121// SIMLIB_WUClear --- remove all items in WaitUntil list
122//
123void SIMLIB_WUClear() // should be removed -- ise CALL_HOOK instead
124{
125 CALL_HOOK(WUclear);
126}
127
128////////////////////////////////////////////////////////////////////////////
129// special WaitUntil processing
130DEFINE_HOOK(WUget_next);
131////////////////////////////////////////////////////////////////////////////
132// SIMLIB_DoActions --- central calling of interruptable procedures
133// WARNING: SIMLIB_Current->_Run() should be called from this place only!
134//
136{
137 do {
138 SIMLIB_Current->_Run(); // perform event-dispatch
139 SIMLIB_Current = 0;
140 CALL_HOOK(WUget_next); // check and activate next in WUlist
141 }while( SIMLIB_Current != 0 );
142}
143
144////////////////////////////////////////////////////////////////////////////
145// Stop --- break the simulation run, can continue with another run
146//
147void Stop()
148{
149 Dprintf(("\n ********************* STOP *********************\n"));
150 if( SIMLIB_Phase != SIMULATION ) // if runs a simulation experiment
152 StopFlag = true;
153}
154
155
156////////////////////////////////////////////////////////////////////////////
157// Abort --- end of simulation program
158//
159void Abort()
160{
161 Dprintf(("\n ********************* ABORT *********************\n"));
163 std::exit(1); // end of program, errorcode 1
164}
165
166
167////////////////////////////////////////////////////////////////////////////
168// SIMLIB_Init --- initialization of simulation system and some parts of
169// model; some checks
170// initialize:
171// - Time, StartTime, EndTime
172// - calendar (SQS)
173// - WaitUntilList
174// - existing continuous blocks, ...
175// - Delay blocks
176//
177void SIMLIB_Init(double T0, double T1, unsigned version)
178{
180 Dprintf(("\n\t ************************* Init(%g,%g) #%lu \n",
181 T0, T1, SIMLIB_experiment_no));
182 // first some checks
183 if(version != SIMLIB_version) { // check versions
184 Dprintf(("\n SIMLIB library version %x.%02x ",
185 SIMLIB_version >> 8, SIMLIB_version & 0xFF));
186 Dprintf((" SIMLIB header version %x.%02x \n",
187 version >> 8, version & 0xFF));
188 SIMLIB_error(InconsistentHeader); // exit program
189 }
193 /////////////////////////////////////////////////////////////////
196 if( T0 >= T1 ) SIMLIB_error(InitError);
197 /////////////////////////////////////////////////////////////////
198 // set simulation parameters
200 _SetTime(Time,T0);
201 _SetTime(EndTime,T1);
202
203// set reasonable defaults for Step limits ???
204// if not set by user first ### add flag to SetStep
205// MaxStep = tend/100;
206// MinStep = MaxStep/1000;
207
208 // TODO: add SIMLIB_RunNumber++
209 // TODO: add real-time stderr/cerr output message for long computations?
210 // on-demand print of "RunNumber:Time ETArun:minutes" each minute?
211
212 // ADD list of functions to call: (dynamically!, priority)
213 // something like atexit(): atInit, atRunStart, atRunEnd
214
215 SQS::Clear(); // initialize calendar
216 SIMLIB_WUClear(); // initialize WaitUntilList
217 SIMLIB_ContinueInit(); // initialize status variables 1 ###
218
219 CALL_HOOK(SamplerInit); // initialize all Samplers
220 CALL_HOOK(DelayInit); // initialize all Delays
221
222}
223
224
225////////////////////////////////////////////////////////////////////////////
226// Run --- main simulation control
227//
228void Run() {
229 Dprintf(("\n\t ********** Run() --- START \n"));
230
231 // first some checks
233 SIMLIB_error(RunUseError); // bad use of Run()
234 if( NextTime < StartTime )
235 SIMLIB_internal_error(); // never reached
236
237 // welcome to the SIMLIB simulation control algorithm :-)
238
239 // initialize variables
241 StopFlag = false; // flag for stop simulation
242
243 SIMLIB_run_statistics.Init(); // initialize internal statistics
245
246 // call init functions
247 SIMLIB_ContinueInit(); // initialize status variables 2 ###
248
249 CALL_HOOK(ZDelayTimerInit); // activate all ZDelayTimers
250 CALL_HOOK(SamplerAct); // activate all Samplers
251 CALL_HOOK(Break); // user can stop simulation by any key?
252
253// TODO: try using special lowest priority end-event to stop simulation
254// It should be simpler
255
256 // main loop
257 while( Time < EndTime && !StopFlag ) {
258 int endFlag = NextTime > EndTime; // if no event at end time
259 if( endFlag )
260 _SetTime( NextTime, EndTime ); // limit NextTime to EndTime
261
262 if( Time < NextTime ) { // no event at current Time
264 // there are integrators or status variables, so we enter
265 // -------------- CONTINUOUS SIMULATION ---------------
266 SIMLIB_ResetStatus = true; // don't use previous step buffers
267 // TODO: is it really needed always?
268 CALL_HOOK(Delay); // DELAY: sample input
269 while( Time < NextTime ) { // do continuous steps
270 // until scheduled event or end ...
271 IntegrationMethod::StepSim(); // *** continuous step ***
272
273 SIMLIB_run_statistics.StepCount++; // some runtime statistics
281
282 SIMLIB_DoConditions(); // perform state events
283 CALL_HOOK(Delay); // DELAY: sample input at each step
284 CALL_HOOK(Break); // user can stop simulation by any key?
285 // TODO: use signal handler, ^C=SIGINT
286 if(StopFlag)
287 break; // end of simulation run was required
288 // by a state-event
289 } // while continuous steps
290 // _SetTime( Time, NextTime ); // set next event activation time
291 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^ should be in StepSim()
292 } else { // no integrators, status blocks, ...
293 _SetTime( Time, NextTime ); // set next event activation time
294 }
295 } // if (NextTime>Time)
296
297 // assert(is event in Time OR end of simulation)
298 if( endFlag ) break; // end of simulation if no event at endtime
299 ///////////// (TODO: ###BUG? state-conditions can schedule!)
300
301 while( Time >= NextTime && !StopFlag && !SQS::Empty() ) {
302 // there are events scheduled at current Time
303 // >= because of rounding errors
304 SIMLIB_Current = SQS::GetFirst(); // get first record from calendar
305 SIMLIB_DoActions(); // perform actions (see waitunti.cc)
306 SIMLIB_run_statistics.EventCount++; // internal statistics
307 // assert: SIMLIB_Current is NULL
308 CALL_HOOK(Break); // Callback: user can stop simulation by key or GUI
309 }
310 } // main loop
311 IntegrationMethod::IntegrationDone(); // terminate integration run
312 SQS::Clear(); // terminate all scheduled events/processes
315 Dprintf(("\n\t ********** Run() --- END \n"));
316}
317
318} // namespace
319
continuous signal delay block
Definition: delay.h:26
abstract base class for active entities (Process, Event) instances of derived classes provide Behavio...
Definition: simlib.h:375
virtual void _Run() noexcept=0
run the Behavior() function
static void IntegrationDone(void)
Definition: simlib.h:1121
static void StepSim(void)
step of numerical integration method
Definition: numint.cc:52
static bool isAny(void)
Definition: simlib.h:994
static bool isAny(void)
Definition: simlib.h:1029
@ InitError
Definition: errors.h:14
@ InitInRunError
Definition: errors.h:16
@ SFunctionUseError
Definition: errors.h:22
@ RunUseError
Definition: errors.h:17
@ TwiceInitError
Definition: errors.h:15
@ InconsistentHeader
Definition: errors.h:68
void InstallBreak(void(*f)())
InstallBreak — set function for checking if user breaks simulation.
Definition: run.cc:104
Internal header file for SIMLIB/C++.
#define Dprintf(f)
Definition: internal.h:100
#define SIMLIB_internal_error()
Definition: internal.h:167
#define DEFINE_HOOK(name)
Definition: internal.h:267
#define _SetTime(t, x)
macro for simple assignement to internal time variables
Definition: internal.h:228
#define CALL_HOOK(name)
Definition: internal.h:278
#define INSTALL_HOOK(name, function)
Definition: internal.h:255
Entity * GetFirst()
remove entity with minimum activation time
Definition: calendar.cc:1327
void Clear()
remove all scheduled entities
Definition: calendar.cc:1346
bool Empty()
empty calendar predicate
Definition: calendar.cc:1280
Implementation of class CalendarList interface is static - using global functions in SQS namespace.
Definition: algloop.cc:32
const double & Time
model time (is NOT the block)
Definition: run.cc:48
const double & StepSize
actual integration step
Definition: intg.cc:48
double SIMLIB_StartTime
Definition: run.cc:40
void Stop()
stop current simulation run
Definition: run.cc:147
static SIMLIB_statistics_t SIMLIB_run_statistics
Definition: run.cc:77
void SIMLIB_ContinueInit()
Definition: intg.cc:125
const double & NextTime
next-event time
Definition: run.cc:49
double SIMLIB_NextTime
Definition: run.cc:42
void Abort()
end simulation program
Definition: run.cc:159
const double & StartTime
time of simulation start
Definition: run.cc:47
const unsigned SIMLIB_version
library version
Definition: version.cc:9
void SIMLIB_error(const enum _ErrEnum N)
print error message and abort program
Definition: error.cc:38
void SIMLIB_DoActions()
Definition: run.cc:135
const SIMLIB_Phase_t & Phase
This variable contains the current phase of experiment (used for internal checking)
Definition: run.cc:58
SIMLIB_Phase_t
values indicate current phase of experiment
Definition: internal.h:76
@ TERMINATION
Definition: internal.h:80
@ INITIALIZATION
Definition: internal.h:78
@ SIMULATION
Definition: internal.h:79
@ START
Definition: internal.h:77
@ ERROREXIT
Definition: internal.h:81
SIMLIB_IMPLEMENTATION
Definition: algloop.cc:34
Entity * SIMLIB_Current
Definition: run.cc:53
void SampleDelays()
Definition: run.cc:92
const double & EndTime
time of simulation end
Definition: run.cc:50
bool SIMLIB_ResetStatus
flag set if there is a need for integration method restart
Definition: intg.cc:86
void SIMLIB_DoConditions()
Definition: cond.cc:139
unsigned long SIMLIB_experiment_no
Definition: run.cc:61
const double SIMLIB_MINTIME
minimal time value
Definition: simlib.h:147
void Run()
run simulation experiment
Definition: run.cc:228
double SIMLIB_Time
Definition: internal.h:209
double SIMLIB_EndTime
Definition: run.cc:43
SIMLIB_Phase_t SIMLIB_Phase
Definition: run.cc:57
void SIMLIB_Init(double T0, double T1, unsigned version)
Definition: run.cc:177
void SIMLIB_WUClear()
Definition: run.cc:123
static bool StopFlag
Definition: run.cc:83
const double SIMLIB_MAXTIME
maximum time (1e30 works for float, too)
Definition: simlib.h:148
Entity *const & Current
pointer to active (now running) entity
Definition: run.cc:54
const SIMLIB_statistics_t & SIMLIB_statistics
interface to internal run-time statistics structure
Definition: run.cc:78
Main SIMLIB/C++ interface.
internal statistics structure contains basic statistics of simulator execution
Definition: simlib.h:1801
SIMLIB_statistics_t()
constructor runs SIMLIB_statistics_t::Init()
Definition: run.cc:65
void Init()
initialize - used at the start of each Run()
Definition: run.cc:68