SIMLIB/C++  3.07
simlib.h
Go to the documentation of this file.
1 /////////////////////////////////////////////////////////////////////////////
2 //! \file simlib.h Main SIMLIB/C++ interface.
3 //!
4 //! \defgroup simlib SIMLIB/C++
5 
6 #ifndef __SIMLIB__
7 
8 #define __SIMLIB__ 0x0308 // version of SIMLIB (numerical)
9 #define SIMLIB_VERSION "3.08" // version of SIMLIB (string)
10 
11 #define SIMLIB_COPYRIGHT "(c) Petr Peringer, 1991-2021"
12 // -------------------------------------------------------------------------
13 // SIMLIB/C++ (SIMulation LIBrary for C++)
14 // -------------------------------------------------------------------------
15 // This library is free software; you can redistribute it and/or
16 // modify it under the terms of the GNU Library General Public
17 // License as published by the Free Software Foundation; either
18 // version 2 of the License, or (at your option) any later version.
19 //
20 // This library is distributed in the hope that it will be useful,
21 // but WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 // Library General Public License for more details.
24 //
25 // You should have received a copy of the GNU Library General Public
26 // License along with this library; if not, write to the Free Software
27 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28 // USA.
29 // -------------------------------------------------------------------------
30 //
31 // This is main header file for SIMLIB/C++
32 //
33 // Supported platforms:
34 // Linux: GNU C++ compiler, architectures: i386+, x86_64
35 // Portable to:
36 // FreeBSD: GNU C++, i386+
37 // Windows XP: MinGW
38 //
39 // Send bug reports to: peringer AT fit.vutbr.cz
40 //
41 
42 #ifndef __cplusplus
43 # error "Use C++ compiler, please."
44 #endif
45 
46 #if (__cplusplus < 201103L)
47 # error "Use C++11 (or newer) compiler, please."
48 #endif
49 
50 ////////////////////////////////////////////////////////////////////////////
51 // includes
52 #include <cstdlib> // size_t
53 #include <list> // std::list<>
54 #include <string> // std::string
55 
56 // /////////////////////////////////////////////////////////////////////////
57 //! \namespace simlib3 Main SIMLIB (version 3+) namespace.
58 //!
59 //! Usage: using namespace simlib3;
60 namespace simlib3 {
61 
62 extern const unsigned SIMLIB_version; // for header compatibility check only
63 const char *SIMLIB_version_string(); // get SIMLIB version string
64 
65 ////////////////////////////////////////////////////////////////////////////
66 // System and compiler dependent part
67 #if defined(__MSDOS__)
68 # error "MSDOS not supported - please, use older version of SIMLIB"
69 
70 #elif defined(__linux__) && defined(__GNUC__)
71 
72 # define SIMLIB_SYSTEM "Linux"
73 # define SIMLIB_COMPILER "GNU C++"
74 
75 #elif defined(__WIN32__)
76 
77 # define SIMLIB_SYSTEM "WIN32"
78 # if defined(__BCPLUSPLUS__)
79 # define SIMLIB_COMPILER "Borland C++"
80 # elif defined(__GNUC__)
81 # define SIMLIB_COMPILER "GNU C++"
82 # endif
83 
84 #elif defined(__FreeBSD__) && defined(__GNUC__)
85 
86 # define SIMLIB_SYSTEM "FreeBSD"
87 # define SIMLIB_COMPILER "GNU C++"
88 
89 #else
90 # error "SIMLIB is not implemented for this system/compiler"
91 #endif
92 
93 ////////////////////////////////////////////////////////////////////////////
94 // DEBUGGING: print debug info ON/OFF/mode
95 //
96 void DebugON(); //!< start debugging output
97 void DebugOFF(); //!< stop debugging output
98 unsigned long Debug(unsigned long mode=~0UL); // start/stop partial debugging
99 // experimental code for start/stop debugging at global level
100 #ifdef SIMLIB_DEBUG
101 static unsigned long SIMLIB_old_debug_flags = Debug(SIMLIB_DEBUG);
102 #endif
103 
104 ////////////////////////////////////////////////////////////////////////////
105 // overwiew of basic SIMLIB classes (abstractions)
106 //
107 
108 class SimObject; // base abstract class
109 // discrete:
110 class Link; // list item base class (Simula-like)
111 class Entity; // discrete model entity
112 class Process; // process base
113 class Event; // event base
114 class Sampler; // periodic calls of global function
115 class List; // list of objects of class Link descendants
116 class Queue; // priority queue
117 class Stat; // statistics
118 class TStat; // time dependent statistics
119 class Histogram; // histogram
120 class Facility; // SOL-like facility
121 class Store; // SOL-like store
122 class Barrier; // barrier
123 class Semaphore; // semaphore
124 // continuous:
125 class aBlock; // abstract block
126 class aContiBlock; // blocks with continuous output
127 class Integrator; // integrator
128 class Status; // status variables
129 class Hyst; // hysteresis
130 class Blash; // backlash
131 class Relay; // general relay
132 class Function; // general function
133 class Constant; // constant
134 class Variable; // variable
135 class Parameter; // parameter (simulation run constant)
136 // combined:
137 class aCondition; // state condition base class
138 class Condition; // state event detector (Boolean version)
139 class ConditionUp; // action by FALSE-->TRUE change
140 class ConditionDown; // action by TRUE-->FALSE
141 
142 ////////////////////////////////////////////////////////////////////////////
143 // CATEGORY: global constants
144 
145 ////////////////////////////////////////////////////////////////////////////
146 // model time limits
147 const double SIMLIB_MINTIME = 0.0; //!< minimal time value
148 const double SIMLIB_MAXTIME = 1.0e30; //!< maximum time (1e30 works for float, too)
149 
150 ////////////////////////////////////////////////////////////////////////////
151 // CATEGORY: global variables
152 // Warning: NOT THREAD-SAFE! --- TODO: change to methods of SimulationContext
153 
154 extern Entity *const &Current; //!< pointer to active (now running) entity
155 
156 // time values:
157 extern const double & StartTime; //!< time of simulation start
158 extern const double & NextTime; //!< next-event time
159 extern const double & EndTime; //!< time of simulation end
160 
161 // WARNING: Time cannot be used in block expressions!
162 extern const double & Time; //!< model time (is NOT the block)
163 extern aContiBlock & T; //!< model time (continuous block)
164 
165 // read-only step limits of numerical integration method
166 extern const double &MinStep; //!< minimal step size
167 extern const double &StepSize; //!< current step size
168 extern const double &OptStep; //!< optimal step size
169 extern const double &MaxStep; //!< maximal step size
170 
171 // error params for numerical integration methods
172 extern const double &AbsoluteError; //!< max absolute error
173 extern const double &RelativeError; //!< max relative error
174 
175 ////////////////////////////////////////////////////////////////////////////
176 // CATEGORY: global functions ...
177 
178 //! Initialize simulator and model time
179 //! @param t0 simulation start time
180 //! @param t1 simulation end time
181 inline void Init(double t0, double t1=SIMLIB_MAXTIME) {
182  extern void SIMLIB_Init(double t0, double t1, unsigned version);
183  SIMLIB_Init(t0,t1,__SIMLIB__); // version consistency check
184 }
185 
186 //! Set calendar implementation.
187 //! @param name String identification of calendar: "list", "cq"
188 void SetCalendar(const char *name);
189 
190 //! Set integration step interval.
191 //! @param dtmin min. step size
192 //! @param dtmax max. step size (can be slightly increased)
193 void SetStep(double dtmin, double dtmax);
194 //! set fixed integration step
195 //! @param dt (almost) fixed step size
196 inline void SetStep(double dt) { SetStep(dt,dt); }
197 
198 //! set max. error estimate for numerical integration method
199 //! used for adaptive stepsize control
200 //! @param abserr absolute tolerance
201 //! @param relerr tolerance relative to integrator value
202 void SetAccuracy(double abserr, double relerr);
203 //! set max. relative error estimate for numerical integration method
204 //! @param relerr tolerance relative to integrator value
205 void SetAccuracy(double relerr);
206 
207 //! run simulation experiment
208 void Run();
209 //! stop current simulation run
210 void Stop();
211 //! end simulation program
212 void Abort();
213 
214 //! print message and terminate program
215 [[noreturn]] void Error(const char *fmt, ...);
216 
217 // TODO: convert to iostreams (SIMLIB4)
218 //! for Output methods, can be redirected
219 int Print(const char *fmt, ...);
220 //! output of messages to stdout, too
221 //! @param fmt format string (the same as for printf() )
222 int _Print(const char *fmt, ...);
223 
224 //! output single value
225 //! @param x value to print
226 int Print(const double x);
227 //! output 2 values
228 //! @param x value to print
229 //! @param y value to print
230 int Print(const double x, const double y);
231 //! output 3 values
232 //! @param x value to print
233 //! @param y value to print
234 //! @param z value to print
235 int Print(const double x, const double y, const double z);
236 
237 //! redirects Output(), Print() to file
238 //! @param name name of output file
239 void SetOutput(const char *name);
240 
241 // functions for special blocks implementation (public)
242 //! request for shorter step of num. integ.
243 void ContractStep();
244 //! request for step end (at most) at given time
245 void ContractStep(double time);
246 
247 
248 ////////////////////////////////////////////////////////////////////////////
249 // CATEGORY: pseudorandom number generators
250 
251 //! initialize random number seed
252 //! @param seed initial value of generator state
253 void RandomSeed(long seed);
254 //! base uniform generator (range 0-0.999999...)
255 //! the default implementation is simple LCG 32bit
256 double Random();
257 //! set another random generator
258 //! default Random() implementation can be replaced
259 //! @param new_gen pointer to user-defined function
260 void SetBaseRandomGenerator(double (*new_gen)());
261 
262 // following generators depend on Random()
263 //! Beta distribution generator @param th @param fi @param min @param max
264 double Beta(double th, double fi, double min, double max);
265 //! Erlang distribution generator @param alfa @param beta
266 double Erlang(double alfa, int beta);
267 //! Exponential distribution generator @param mv mean value
268 double Exponential(double mv);
269 //! Gamma distribution generator @param alfa @param beta
270 double Gamma(double alfa, double beta);
271 
272 int Geom(double q);
273 int HyperGeom(double p, int n, int m);
274 double Logar(double mi, double delta);
275 int NegBinM(double p,int m);
276 int NegBin(double q, int k);
277 
278 //! Gauss distribution generator @param mi mean value @param sigma std. deviation
279 double Normal(double mi, double sigma);
280 //! Poisson distribution generator @param lambda
281 int Poisson(double lambda);
282 double Rayle(double delta);
283 double Triag(double mod, double min, double max);
284 //! Uniform distribution generator @param l low limit @param h high limit
285 double Uniform(double l, double h);
286 //! Weibul distribution generator @param lambda @param alfa
287 double Weibul(double lambda, double alfa);
288 
289 
290 ////////////////////////////////////////////////////////////////////////////
291 // CATEGORY: basics
292 
293 ////////////////////////////////////////////////////////////////////////////
294 //! Base class for almost all SIMLIB classes.
295 //!
296 //! - objects can have name
297 //! - objects know if they are created dynamically (using new)
298 //! \ingroup simlib
299 class SimObject {
300  public:
301  enum _Flags { //!< internal flags (bitmasks: 1bit set)
303  _ALLOCATED_FLAG = 1<<0, // object is on heap
304  _EVAL_FLAG = 1<<1, // currently evaluated (aBlock)
305  _HAS_NAME_FLAG = 1<<2 // object has name (in dictionary)
306  };
307  protected:
308  unsigned _flags; //!< bool flags for internal use (TODO bitfield?)
309  public:
310  bool TestAndSetFlag(bool new_value, unsigned n); // internal use only
311  SimObject();
312  virtual ~SimObject();
313  void *operator new(size_t size); //!< allocate object, set _flags
314  void operator delete(void *ptr); //!< deallocate object
315  void *operator new[](size_t size) = delete;
316  void operator delete[](void *ptr) = delete;
317 // TODO: FIXME inconsistent name:
318  bool isAllocated() const { return (_flags & _ALLOCATED_FLAG)!=0; }
319 
320  virtual std::string Name() const; //!< get object name
321  bool HasName() const { return (_flags & _HAS_NAME_FLAG)!=0; }
322  void SetName(const std::string &name); //!< assign the name
323 
324  // TODO: define friend operator <<
325  virtual void Output() const; //!< print object to default output
326  private:
327  SimObject(const SimObject &) = delete; //!< disable copy operation
328  SimObject &operator= (const SimObject &) = delete; //!< disable assign operation
329 };
330 
331 ////////////////////////////////////////////////////////////////////////////
332 //! base class for all double-linked list items
333 //! <br> item can be at single place only (identified by where() method)
334 //! <br> used for Queue implementation
335 //! \ingroup simlib
336 class Link : public SimObject {
337  Link *pred; //!< previous object in List
338  Link *succ; //!< next object in List
339  List *head; //!< pointer to List (if any)
340  friend class List; // only list can access pred,succ,head
341  protected:
342  Link(Link *p, Link *s, List *h);
343  public:
344  Link();
345  virtual ~Link();
346  virtual void Into(List *l); //!< insert last
347  virtual void Out(); //!< remove from list
348  List *Where() { return head; } //!< where is linked
349  virtual bool isInQueue() { return Where()!=NULL; } //!< present in queue
350 };
351 
352 ////////////////////////////////////////////////////////////////////////////
353 // CATEGORY: discrete blocks
354 
355 //! entity/process priority values
356 //! <br> (Warning: changed from 0..255 in SIMLIB v 3.03)
357 enum {
361 };
362 //! Priority of the process/event
363 typedef signed char EntityPriority_t;
364 //! Service priority (see Facility::Seize)
365 typedef unsigned char ServicePriority_t;
366 
367 //! struct EventNotice is private to calendar implementation
368 struct EventNotice; // we use only pointer to this class here
369 
370 ////////////////////////////////////////////////////////////////////////////
371 //! abstract base class for active entities (Process, Event)
372 //! instances of derived classes provide Behavior() method implementation,
373 //! execution can be scheduled in calendar
374 //! \ingroup simlib
375 class Entity : public Link {
376  protected:
377  static unsigned long _Number; //!< current number of entities
378  unsigned long _Ident; //!< unique identification number of entity
379  ////////////////////////////////////////////////////////////////////////////
380  // TODO: next attributes will be changed/removed:
381  // all should be in special records stored into queues
382  // Queue stores insertion time for statistics:
383  friend class Queue; // ### remove
384  double _MarkTime; // beginning of waiting in queue ###!!!
385  // Facility and Store use these data
386  friend class Facility;
387  friend class Store;
388  // TODO: this should be stored in queues at Facility/Store
389  union {
390  double _RemainingTime; // rest of time of interrupted service (Facility) ###
391  unsigned long _RequiredCapacity; // required store capacity of Store
392  };
393  ServicePriority_t _SPrio; //!< priority of service in Facility
394  ////////////////////////////////////////////////////////////////////////////
395  public:
396  unsigned long id() const { return _Ident; }
397  typedef EntityPriority_t Priority_t;
398  //! priority of the entity (scheduling,queues)
399  Priority_t Priority; //!< priority of the entity
400  Entity(Priority_t p = DEFAULT_PRIORITY);
401  virtual ~Entity();
402 
403  // common interface for Events and Processes
404  operator Entity* () { return this; } // default conversion
405 // virtual const char *Name() const; //!< name of the entity
406  double ActivationTime(); // get activation time if scheduled
407 
408  void Activate() { Activate(Time); } //!< activate now
409  virtual void Activate(double t); //!< activate at time t (schedule)
410  virtual void Passivate(); //!< deactivation
411  virtual void Terminate() = 0; //!< end Behavior() and remove entity
412  bool Idle() { return _evn==0; } //!< entity activation is not scheduled in calendar
413  void Cancel() { Terminate(); } //!< end Behavior() and remove entity
414 // virtual void Into(Queue *q); // insert itself into queue
415  virtual void Out() override; //!< remove entity from queue
416 
417  private:
418  // Simulation control algorithm interface:
419  virtual void _Run() noexcept = 0; //!< run the Behavior() function
420  // friends:
421  friend void SIMLIB_DoActions(); // internal function - event dispatcher
422 
423  // Calendar interface:
424  friend struct EventNotice; // internal calendar class sets _Ev
425  EventNotice *_evn; //!< points to calendar item, iff scheduled
426  public:
427  EventNotice *GetEventNotice() { return _evn; }
428 };
429 
430 // global wrapper functions:
431 inline void Activate(Entity *e) { e->Activate(); } //!< activate entity e
432 inline void Passivate(Entity *e) { e->Passivate(); } //!< passivate entity e
433 
434 ////////////////////////////////////////////////////////////////////////////
435 //! Abstract base class for all simulation processes
436 //! @ingroup process
437 //! Process behavior is specified by Behavior method and can be interrupted
438 //! during execution by e.g. Wait method call (it is coroutine)
439 //! \ingroup simlib
440 class Process : public Entity {
441  void * _context; //!< process context pointer
442  virtual void _Run() noexcept override; // internal point of activation
443 
444  //! possible process status values
446  _PREPARED=1, _RUNNING, _INTERRUPTED, _TERMINATED
447  } _status;
448  bool isPrepared() const { return (_status==_PREPARED); } // before start
449  bool isCurrent() const { return (_status==_RUNNING); } // Behavior() runs
450  bool isInterrupted() const{ return (_status==_INTERRUPTED); } // can continue
451  bool isTerminated() const { return (_status==_TERMINATED); } // zombie
452 
453  friend class WaitUntilList;
454  bool _wait_until; // waiting for condition
455  void _WaitUntilRemove();
456 
457  public:
459  virtual ~Process();
460  virtual void Behavior() = 0; //!< behavior description
461  virtual void Output() const override; //!< print object to default output
462  virtual std::string Name() const override; //!< name of object
463  using Entity::Activate; // inherited: Activate()
464  virtual void Activate(double t) override; //!< activate at time t (schedule)
465  virtual void Passivate() override; //!< process deactivation (sleep)
466  virtual void Wait(double dtime); //!< wait for dtime interval
467  bool _WaitUntil(bool test); //!< wait for condition (slow!)
468 #ifdef I_REALLY_KNOW_HOW_TO_USE_WAITUNTIL
469 //! wait until the condition is true (lazy evaluation of condition)
470 # define WaitUntil(condition) while(_WaitUntil(condition)) /*empty body*/;
471 #endif
472  void Interrupt(); //!< test of WaitUntil list, allow running others
473  virtual void Terminate() override; //!< kill process
474 
475  void Seize(Facility &f, ServicePriority_t sp=0); //!< seize facility
476  void Release(Facility &f); //!< release facility
477  void Enter(Store &s, unsigned long ReqCap=1); //!< acquire some capacity
478  void Leave(Store &s, unsigned long ReqCap=1); //!< return some capacity
479 
480  using Entity::Into;
481  virtual void Into(Queue &q); //!< insert process into queue
482 };
483 
484 ////////////////////////////////////////////////////////////////////////////
485 //! abstract base class for events
486 //! Event behavior is simple function (can not be interrupted)
487 //! \ingroup simlib
488 class Event : public Entity {
489  virtual void _Run() noexcept override;
490  virtual void Terminate() override; // do not use (deprecated)
491  public:
493  virtual ~Event();
494  virtual void Behavior() = 0; //!< behavior description
495  virtual void Output() const override; //!< print object to default output
496  virtual std::string Name() const override; //!< name of object
497  // public inherited: Passivate(), Cancel()
498  virtual void Activate(double t) override; //!< activate at time t (schedule)
499  using Entity::Activate; // inherited: Activate()
500 };
501 
502 ////////////////////////////////////////////////////////////////////////////
503 //! objects of this class call global function periodically
504 //! (typicaly used for output of continuous model)
505 //! \ingroup simlib
506 class Sampler: public Event {
507  static Sampler *First; // list of objects TODO: use container
508  Sampler *Next; // next object
509  protected:
510  void (*function)(); //!< function to call periodically
511  double last; //!< last sample time -- prevents sample duplication
512  double step; //!< step of sampling
513  bool on; //!< switch on/off
514  virtual void Behavior() override; //!< behavior description
515  public:
516  Sampler(void (*pf)(), double dt=0.0);
517  virtual ~Sampler();
518  virtual void Output() const override; //!< print object to default output
519  void Start(); //!< start + sample
520  void Stop(); //!< sample + stop
521  void Sample(); //!< performs sample (function call)
522  double SetStep(double dt=0.0); //!< change step
523  double GetStep() const { return step; } //!< get current step
524  private:
525  static void InitAll(); //!< initialize all samplers (Init)
526  static void ActivateAll(); //!< start all samplers (Run)
527 };
528 
529 
530 ////////////////////////////////////////////////////////////////////////////
531 // CATEGORY: discrete blocks - pasive
532 
533 #ifdef new_version
534 ////////////////////////////////////////////////////////////////////////////
535 //! abstract base class of all statistics
536 //! TODO:
537 class aStat : public SimObject {
538  protected:
539  double min; // minimal recorded value
540  double max; // maximal recorded value
541  unsigned long n; // number of values recorded
542  public:
543  //class aStatException {};
544  aStat();
545  aStat(const char *name);
546  ~aStat();
547  virtual void Clear() = 0; // initialize
548 
549  virtual void operator () (double x) = 0; //!< record value
550  virtual void Record(double x) = 0; //!< record value
551 
552  virtual double MeanValue() = 0; //!< compute mean value
553  double Min() const { /* test n==0 +exception */ return min; }
554  double Max() const { /* test n==0 */ return max; }
555  unsigned long NumberOfRecords() const { return n; }
556  virtual void Output() const override; //!< Print all values to output file
557 };
558 #endif
559 
560 ////////////////////////////////////////////////////////////////////////////
561 //! class for statistical information gathering
562 //! \ingroup simlib
563 class Stat : public SimObject {
564  protected:
565  double sx; // sum of values
566  double sx2; // sum of value square
567  double min; // min value
568  double max; // max value
569  unsigned long n; // number of values recorded
570  public:
571  Stat();
572  explicit Stat(const char *name);
573  ~Stat();
574  virtual void Clear(); //!< initialize
575  void operator () (double x); //!< record the value
576 // Stat &operator = (Stat &x); // TODO: copy semantics
577 // Stat &operator += (Stat &x); // sum two statistics + template operator +
578  virtual void Output() const override; //!< print statistics
579  unsigned long Number() const { return n; }
580  double Min() const { /* TODO: test n==0 */ return min; }
581  double Max() const { /* test n==0 */ return max; }
582  double Sum() const { return sx; }
583  double SumSquare() const { return sx2; }
584  double MeanValue() const;
585  double StdDev() const;
586 };
587 
588 
589 ////////////////////////////////////////////////////////////////////////////
590 //! time dependent statistic
591 //! \ingroup simlib
592 class TStat : public SimObject {
593  protected:
594  double sxt; // sum of x*time
595  double sx2t; // sum of squares
596  double min; // min value x
597  double max; // max value x
598  double t0; // time of initialization
599  double tl; // last record time
600  double xl; // last recorded value x
601  unsigned long n; // number of records
602  friend class Facility; // needs to correct n -- TODO: remove
603  friend class Store;
604  friend class Queue;
605  public:
606  explicit TStat(double initval=0.0);
607  explicit TStat(const char *name, double initval=0.0);
608  ~TStat();
609  virtual void Clear(double initval=0.0); //!< initialize
610  virtual void Output() const override; //!< print object to default output
611  virtual void operator () (double x); //!< record the value
612  unsigned long Number() const { return n; }
613  double Min() const { /*TODO: only if(n>0)*/ return min; }
614  double Max() const { return max; }
615  double Sum() const { return sxt; }
616  double SumSquare() const { return sx2t; }
617  double StartTime() const { return t0; }
618  double LastTime() const { return tl; }
619  double LastValue() const { return xl; }
620  double MeanValue() const;
621 };
622 
623 
624 ////////////////////////////////////////////////////////////////////////////
625 //! list of Link* items, uses data from Link
626 //
627 // prehistoric implementation, TODO: use list<Link*>
628 //
629 //! \ingroup simlib
630 class List : public Link { // circular list of Link items
631  static Link *next(Link*p) { return p->succ; }
632  static Link *previous(Link*p) { return p->pred; }
633  unsigned n; // number of objects in list
634  protected:
635  class iterator {
636  Link *p; // position in List
637  public:
638  iterator(const iterator&x): p(x.p) {}
639  iterator &operator=(const iterator&x) { p = x.p; return *this; }
640  // explicit?
641  iterator(Link *pos) : p(pos) {}
642  iterator &operator++() { p = List::next(p); return *this; }
643  iterator &operator--() { p = List::previous(p); return *this; }
645  Link *tmp = p; p = List::next(p); return tmp;
646  }
648  Link *tmp = p; p = List::previous(p); return tmp;
649  }
650  Link * operator*() const { return p; }
651  bool operator != (iterator q) const { return p!=q.p; }
652  bool operator == (iterator q) const { return p==q.p; }
653  }; // iterator
654  friend class iterator;
655  public:
656  List();
657  explicit List(const char *_name);
658  ~List();
659  virtual void Output() const override; //!< print object to default output
660  // should be renamed:
661  void InsFirst(Link *e); // insert operation
662  void InsLast (Link *e);
663  void PredIns(Link *e, iterator pos); //
664  void PostIns(Link *e, iterator pos); //
665  Link *GetFirst(); //!< remove first
666  Link *GetLast(); //!< remove last
667  virtual Link *Get(iterator pos); //!< remove at position
668  // unsigned Length() { return size(); } // COMPATIBILITY
669  // virtual void Clear() { clear(); } // remove all items
670  // new-style:
671  unsigned size() const { return n; }
672  iterator begin() { return Link::succ; }
673  iterator end() { return this; }
674  Link *front() { return empty() ? 0 : Link::succ; }
675  Link *back() { return empty() ? 0 : Link::pred; }
676  bool empty() { return Link::succ == this; }
677  void clear();
678 }; // List
679 
680 
681 ////////////////////////////////////////////////////////////////////////////
682 //! priority queue
683 //
684 //! \ingroup simlib
685 class Queue : public List { // don't inherit interface for now
686 //TODO:remove
687  friend class Facility;
688  friend class Store;
689  public:
692  Stat StatDT; // statistics
693  Queue();
694  explicit Queue(const char *_name);
695  ~Queue(); // list destructor clears content
696  //virtual const char *Name() const;
697  virtual void Output() const override; //!< print statistics
698  operator Queue* () { return this; } // allows Queue instead Queue*
699  iterator begin() { return List::begin(); }
700  iterator end() { return List::end(); }
701  Entity *front() { return static_cast<Entity*>(List::front()); }
702  Entity *back() { return static_cast<Entity*>(List::back()); }
703  void clear(); //!< initialize
704  // size(), empty() inherited
705  // backward COMPATIBILITY
706  void Clear() { clear(); }
707  bool Empty() { return empty(); }
708  unsigned Length() { return size(); }
709  // to rename:
710  virtual void Insert (Entity *e); // priority insert
711  void InsFirst(Entity *e);
712  void InsLast (Entity *e);
713  void PredIns (Entity *e, iterator pos); // insert at position
714  void PostIns (Entity *e, iterator pos);
715  virtual Entity *Get(iterator pos); // remove entity
716  Entity *GetFirst();
717  Entity *GetLast();
718 };
719 
720 ////////////////////////////////////////////////////////////////////////////
721 //! histogram
722 //! statistics
723 //! \ingroup simlib
724 class Histogram : public SimObject {
725  protected:
726  unsigned *dptr; // value array
727  double low; // low bound
728  double step; // interval width
729  unsigned count; // number of intervals
730  public:
731  Stat stat; // statistics
732  Histogram();
733  Histogram(double low, double step, unsigned count=10);
734  Histogram(const char *_name, double low, double step, unsigned count=10);
735  ~Histogram();
736  virtual void Output() const override; //!< print to default output
737  void Init(double low, double step, unsigned count);
738  void operator () (double x); // record value x
739  virtual void Clear(); // initialize (zero) value array
740  double Low() const { return low; }
741  double High() const { return low + step*count; }
742  double Step() const { return step; }
743  unsigned Count() const { return count; }
744  unsigned operator [](unsigned i) const; // # of items in interval[i]
745 };
746 
747 
748 
749 ////////////////////////////////////////////////////////////////////////////
750 //! (SOL-like) facility
751 //! Facility with exclusive access and service priority
752 //! \ingroup simlib
753 class Facility : public SimObject {
754  unsigned char _Qflag; //!< true if facility is owner of input queue
755  protected:
756  Entity *in; //!< Entity currently in service
757  Queue *Q1; //!< Input queue
758  Queue *Q2; //!< Interrupted requests queue
759  TStat tstat; //!< usage statistics
760  public:
761  Facility(); // for arrays only, TODO: FacilityArray
762  explicit Facility(const char *_name);
763  explicit Facility(Queue *_queue1);
764  Facility(const char *_name, Queue *_queue1);
765  virtual ~Facility();
766  virtual void Output() const override; //!< print statistics
767  operator Facility* () { return this; }
768  void SetQueue(Queue *queue1); //!< change input queue
769  bool OwnQueue() const; //!< test for default queue
770  bool Busy() const { return in!=nullptr; } //!< in service
771  Entity * In() const { return in; } //!< current entity or nullptr
772  unsigned QueueLen() const { return Q1->size(); }
773  virtual void Seize(Entity *e, ServicePriority_t sp=DEFAULT_PRIORITY);
774  virtual void Release(Entity *e);
775  virtual void QueueIn(Entity *e, ServicePriority_t sp); // go into queue Q1
776  virtual void Clear(); //!< initialize
777  protected:
778  virtual void QueueIn2(Entity *e); // go into Q2
779 };
780 
781 ////////////////////////////////////////////////////////////////////////////
782 //! (SOL-like) store
783 //! store capacity can be changed dynamically
784 //! \ingroup simlib
785 class Store : public SimObject {
786  unsigned char _Qflag; //!< true if store is owner of input queue
787  protected:
788  unsigned long capacity; //!< Capacity of store
789  unsigned long used; //!< Currently used capacity
790  Queue *Q; //!< input queue
791  TStat tstat; //!< usage statistics
792  public:
793  Store();
794  explicit Store(unsigned long _capacity);
795  Store(const char *_name, unsigned long _capacity);
796  Store(unsigned long _capacity, Queue *queue);
797  Store(const char *_name, unsigned long _capacity, Queue *queue);
798  virtual ~Store();
799  virtual void Output() const override; //!< print statistics
800  operator Store* () { return this; }
801  void SetCapacity(unsigned long _capacity); //!< change the capacity
802  void SetQueue(Queue *queue); //!< change input queue
803  unsigned long Free() const { return capacity - used; }//!< free capacity
804  unsigned long Used() const { return used; } //!< used capacity
805  unsigned long Capacity() const { return capacity; } //!< max capacity
806  bool Full() const { return Free() == 0; } //!< store is full
807  bool Empty() const { return Used() == 0; } //!< store is empty
808  bool OwnQueue() const;
809  unsigned QueueLen() const { return Q->size(); }
810  virtual void Enter(Entity *e, unsigned long rcap); //!< allocate capacity
811  virtual void Leave(unsigned long rcap); //!< deallocate capacity
812  virtual void QueueIn(Entity *e, unsigned long c); //!< insert entity into queue
813  virtual void Clear(); //!< initialize
814 };
815 
816 
817 ////////////////////////////////////////////////////////////////////////////
818 // CATEGORY: continuous blocks
819 //
820 
821 ////////////////////////////////////////////////////////////////////////////
822 //! abstract base class for all blocks
823 //! \ingroup simlib
824 /// blocks/SimObject have not copy semantics (TODO: add move semantics)
825 class aBlock : public SimObject { // base class
826 };
827 
828 ////////////////////////////////////////////////////////////////////////////
829 //! abstract base for continuous blocks with single output
830 //! suitable for expression-tree building and evaluation
831 //! \ingroup simlib
832 class aContiBlock : public aBlock {
833  //! evaluate without loop detection
834  virtual void Eval() {};
835  protected:
836  bool isEvaluated; //TODO:remove this flag for algebraic loop detection
837  public:
838  aContiBlock(): isEvaluated(false) {}
839  virtual void _Eval(); //!< evaluate block (with loop detection)
840  //! get block output value <br>
841  //! this method should be defined in classes derived from aContiBlock
842  virtual double Value() = 0;
843 };
844 
845 ////////////////////////////////////////////////////////////////////////////
846 //! block: constant (value can not be changed)
847 //! \ingroup simlib
848 class Constant : public aContiBlock {
849  const double value;
850  public:
851  explicit Constant(double x) : value(x) {}
852  virtual double Value () override { return value; }
853 };
854 
855 ////////////////////////////////////////////////////////////////////////////
856 //! block: variable (value can be changed)
857 //! \ingroup simlib
858 class Variable : public aContiBlock {
859  double value;
860  public:
861  explicit Variable(double x=0) : value(x) {}
862  Variable &operator= (double x) { value = x; return *this; }
863  virtual double Value () override { return value; }
864 };
865 
866 ////////////////////////////////////////////////////////////////////////////
867 //! block: parameter (can not be changed during simulation run)
868 //! \ingroup simlib
869 class Parameter : public aContiBlock {
870  double value;
871  public:
872  explicit Parameter(double x) : value(x) {}
873  Parameter &operator= (double x) { value = x; return *this; }
874  virtual double Value () override { return value; }
875 };
876 
877 
878 
879 //TODO: add map<aContiBlockPtr,int> for reference counting or use shared_ptr
880 // speed is not important, Inputs are created only in the model construction phase
881 // (and in dynamical structure models at simulation time, too).
882 #define RegisterReference(aContiBlockPtr)
883 #define UnRegisterReference(aContiBlockPtr)
884 
885 ////////////////////////////////////////////////////////////////////////////
886 //! continuous block connection (transparent reference)
887 //! wrapper for pointer to objects of aContiBlock derived classes <br>
888 //! (small object, without virtual methods)
889 //! <br>
890 //! It is used for referencing of continuous blocks in block-expressions.
891 //! All references are transparent. There is a problem with initialization
892 //! order. Using uninitialized Input is an error. If you
893 //! need a block independent on initialization order, use Expression.
894 //! \ingroup simlib
895 class Input {
897  Input() = delete; // disable default constructor
898  public:
899  //! transparent copy of block reference
900  Input(const Input &i): bp(i.bp) { RegisterReference(bp); }
901 
902  // ## we use implicit conversions to simplify block expressions
903  Input(aContiBlock &cb): bp(&cb) { RegisterReference(bp); } //!< reference to block
904  Input(aContiBlock *cb): bp(cb) { RegisterReference(bp); } //!< pointer to block
905 
906  //! create block of type Constant
907  //! WARNING: using C++ variable in block expression creates Constant block
908  Input(const double c): bp(new Constant(c)) { RegisterReference(bp); }
909 
911 
912  //! Redirect the reference
914  Input p = bp; // old value
916  bp=i.bp;
917  RegisterReference(bp);
918  // TODO: LoopCheck();
919  return p; // returns old value
920  }
921 
922  //! Redirect the reference
923  Input &operator= (const Input&x) {
925  bp = x.bp;
926  RegisterReference(bp);
927  // TODO: LoopCheck();
928  return *this;
929  }
930 
931  double Value() const { return bp->Value(); } //!< get target block value
932 
933  bool operator ==(aContiBlock *p) const { return bp==p; } // for tests only
934 };
935 
936 
937 ////////////////////////////////////////////////////////////////////////////
938 //! base for continuous blocks with single input and algebraic loop check
939 //! \ingroup simlib
940 class aContiBlock1 : public aContiBlock {
942  public:
943  explicit aContiBlock1(Input i);
944  double InputValue() { return input.Value(); }
945 };
946 
947 ////////////////////////////////////////////////////////////////////////////
948 //! reference to block expression
949 //! This block can be used as handle for block expression trees
950 //! \ingroup simlib
951 struct Expression : public aContiBlock1 {
952  explicit Expression(Input i) : aContiBlock1(i) {}
953  double Value() override; //!< Evaluate expression and return the value
954 };
955 
956 ////////////////////////////////////////////////////////////////////////////
957 //! base for continuous blocks with two inputs
958 //! \ingroup simlib
959 class aContiBlock2 : public aContiBlock {
962  public:
963  aContiBlock2(Input i1, Input i2);
964  double Input1Value() { return input1.Value(); }
965  double Input2Value() { return input2.Value(); }
966 };
967 
968 ////////////////////////////////////////////////////////////////////////////
969 //! base for continuous blocks vith three inputs and algebraic loop check
970 //! \ingroup simlib
971 class aContiBlock3 : public aContiBlock {
975  public:
976  aContiBlock3(Input i1, Input i2, Input i3);
977  double Input1Value() { return input1.Value(); }
978  double Input2Value() { return input2.Value(); }
979  double Input3Value() { return input3.Value(); }
980 };
981 
982 
983 ////////////////////////////////////////////////////////////////////////////
984 //! IntegratorContainer - internal container of integrators (singleton)
985 //TODO: move to implementation header
987 private:
988  static std::list<Integrator*> * ListPtr; // list of integrators
989  IntegratorContainer(); // forbid constructor
990  static std::list<Integrator*> * Instance(void); // return list (& create)
991 public:
992  typedef std::list<Integrator*>::iterator iterator;
993  // is there any integrator in the list? (e.g. list is not empty)
994  static bool isAny(void) {
995  return ListPtr!=0 && !(ListPtr->empty());
996  }
997  // # of elements in the list
998  static size_t Size(void) {
999  return (ListPtr!=0) ? (ListPtr->size()) : 0;
1000  }
1001  // return iterator to the first element
1002  static iterator Begin(void) {
1003  return Instance()->begin();
1004  }
1005  // return iterator to the end (not to the last element!)
1006  static iterator End(void) {
1007  return Instance()->end();
1008  }
1009  static iterator Insert(Integrator* ptr); // insert element into container
1010  static void Erase(iterator it); // exclude element
1011  static void InitAll(); // initialize all
1012  static void EvaluateAll(); // evaluate all integrators
1013  static void LtoN(); // last -> now
1014  static void NtoL(); // now -> last
1015 }; // class IntegratorContainer
1016 
1017 
1018 ////////////////////////////////////////////////////////////////////////////
1019 //! StatusContainer - internal container of status variables (singleton)
1020 //TODO: move to implementation header
1022 private:
1023  static std::list<Status*>* ListPtr; // list of integrators
1024  StatusContainer(); // forbid constructor
1025  static std::list<Status*>* Instance(void); // return list (& create)
1026 public:
1027  typedef std::list<Status*>::iterator iterator;
1028  // is there any integrator in the list? (e.g. list is not empty)
1029  static bool isAny(void) {
1030  return ListPtr!=0 && !(ListPtr->empty());
1031  }
1032  // # of elements in the list
1033  static size_t Size(void) {
1034  return (ListPtr!=0) ? (ListPtr->size()) : 0;
1035  }
1036  // return iterator to the first element
1037  static iterator Begin(void) {
1038  return Instance()->begin();
1039  }
1040  // return iterator to the end (not to the last element!)
1041  static iterator End(void) {
1042  return Instance()->end();
1043  }
1044  static iterator Insert(Status* ptr); // insert element into container
1045  static void Erase(iterator it); // exclude element
1046  static void InitAll(); // initialize all
1047  static void ClearAllValueOK(); // invalidate values of all items
1048  static void EvaluateAll(); // evaluate all integrators
1049  static void LtoN(); // last -> now
1050  static void NtoL(); // now -> last
1051 }; // class StatusContainer
1052 
1053 
1054 ////////////////////////////////////////////////////////////////////////////
1055 //! IntegrationMethod - Abstract base class for integration methods
1056 //TODO: reduce to simple public interface,
1057 // delegate implementation to internal (hidden) class
1059  IntegrationMethod(const IntegrationMethod&) = delete;
1061 private:
1062  static IntegrationMethod* CurrentMethodPtr; // method used at present
1063  static std::list<IntegrationMethod*>* MthLstPtr; // list of registrated methods
1064  std::list<IntegrationMethod*>::iterator ItList; // position in the list
1065  const char* method_name; // C-string --- the name of the method
1066 protected: //## repair
1067  class Memory; // forward declaration
1068  friend class Memory;
1069 private: //## repair
1070  size_t PrevINum; // # of integrators in previous step
1071  std::list<Memory*> MList; // list of auxiliary memories
1072  static std::list<Memory*> * PtrMList; // pointer to list being filled
1073  IntegrationMethod(); // forbid implicit constructor
1074  IntegrationMethod(IntegrationMethod&); // forbid implicit copy-constructor
1075  static bool Prepare(void); // prepare system for integration step
1076  static void Iterate(void); // compute new values of state blocks
1077  static void Summarize(void); // set up new state after integration
1078 protected:
1079  static bool IsEndStepEvent; // flag - will be event at the end of the step?
1080  typedef IntegratorContainer::iterator Iterator; // iterator of intg. list
1081  static Iterator FirstIntegrator(void) { // it. to first integrator in list
1082  return IntegratorContainer::Begin();
1083  }
1084  static Iterator LastIntegrator(void) { // it. to last integrator in list
1085  return IntegratorContainer::End();
1086  }
1087  static bool StateCond(void); // check on changes of state conditions
1088  static IntegrationMethod* SearchMethod(const char* name); // find method
1089 
1090  /* memory of auxiliary values */
1091 
1092  class Memory {
1093  Memory(const Memory&) = delete;
1094  Memory&operator=(const Memory&) = delete;
1095  private:
1096  static const size_t page_size; // size of memory page
1097  double *arr; // array
1098  size_t mem_size; // allocated memory size
1099  std::list<Memory*>::iterator it_list; // position in list
1100  std::list<Memory*> * ListPtr; // which list is memory in
1101  public:
1102  explicit Memory(std::list<Memory*> * PtrList=PtrMList); // create empty memory
1103  virtual ~Memory();
1104  double& operator[](size_t ind) { // access the element of the array
1105  // dprintf(("IntegrationMethod::Memory::operator[](%lu) = %g",
1106  // (long unsigned)ind, arr[ind]));
1107  return arr[ind];
1108  }
1109  virtual void Resize(size_t cs); // change size, content will be undefined!
1110  }; // class Memory
1111 
1112 public:
1113  explicit IntegrationMethod(const char* name); // register the method with name
1114  virtual ~IntegrationMethod(); // destructor unregistrates method
1115  virtual bool IsSingleStep(void)=0; // is it a single-step method?
1116  virtual void TurnOff(void); // turn off integration method
1117  virtual void Integrate(void) = 0; // the method does integration
1118  virtual bool PrepareStep(void); // prepare object for integration step
1119  virtual void Resize(size_t size); // resize all memories to given size
1120  static void StepSim(void); // single step of numerical integration method
1121  static void IntegrationDone(void) { // terminate integration
1122  CurrentMethodPtr->TurnOff(); // suspend present method
1123  }
1124  static void SetMethod(const char* name); // set method which will be used
1125  static const char* GetMethod(void) { // get name of method which is used
1126  return CurrentMethodPtr->method_name;
1127  }
1128  // auxiliary functions (interface) for user to add own method
1129  static void InitStep(double step_frag); // initialize step
1130  static void FunCall(double step_frag); // evaluate y'(t) = f(t, y(t))
1131  static void SetOptStep(double opt_step); // set optimal step size
1132  static void SetStepSize(double step_size); // set step size
1133  static bool IsConditionFlag(void); // any changes of condition vector?
1134  static int GetErrNo(void); // return # of errors
1135  static void SetErrNo(int num); // set # of errors
1136 }; // class IntegrationMethod
1137 
1138 
1139 ////////////////////////////////////////////////////////////////////////////
1140 //! base for single-step integration methods
1142 private:
1143  // flag: single-step method is used to start multi-step method
1144  // (e. g. to restrict step increasing)
1146 public:
1147  explicit SingleStepMethod(const char* name):
1148  IntegrationMethod(name),
1149  StartMode(false) { /* NOTHING */ }
1150  virtual bool IsSingleStep(void) override { return true; }
1151  void SetStartMode(bool start_mode) { // set flag on/off
1152  StartMode=start_mode;
1153  }
1154  bool IsStartMode(void) { // is method used to start multi-step method?
1155  return StartMode;
1156  }
1157 }; // class SingleStepMethod
1158 
1159 
1160 ////////////////////////////////////////////////////////////////////////////
1161 //! base for multi-step integration method
1163 private:
1164  char* SlaveName; // the name of the method used for starting
1165  SingleStepMethod* Slave_Ptr; // pointer to the method used for starting
1166 protected:
1167  SingleStepMethod* SlavePtr(void); // return pointer to the starting method
1168 public:
1169  // initialize method
1170  MultiStepMethod(const char* name, const char* slave_name);
1171  ~MultiStepMethod(); // destructor frees dynamic data
1172  virtual bool IsSingleStep(void) override { return false; }
1173  // set starting method for given method
1174  static void SetStarter(const char* name, const char* slave_name);
1175  // set starting method for the method
1176  virtual void SetStarter(const char* slave_name);
1177  // get the name of starting method of given method
1178  static const char* GetStarter(const char* name);
1179  virtual bool PrepareStep(void) override; // prepare the object for the step
1180  virtual void TurnOff(void) override; // turn off method & its slave
1181 }; // class MultiStepMethod
1182 
1183 
1184 ////////////////////////////////////////////////////////////////////////////
1185 //! Abstract base class for integration methods with status auxiliary memories
1187 private:
1188  StatusMethod(const StatusMethod&) = delete;
1189  size_t PrevStatusNum; // # of status variables in previous step
1190  std::list<Memory*> StatusMList; // list of auxiliary memories
1191  static std::list<Memory*>* PtrStatusMList; // pointer to list being filled
1192 protected:
1193  typedef StatusContainer::iterator StatusIterator; // iterator of intg. list
1194  static StatusIterator FirstStatus(void) { // it. to first status in list
1195  return StatusContainer::Begin();
1196  }
1197  static StatusIterator LastStatus(void) { // it. to last status in list
1198  return StatusContainer::End();
1199  }
1200 
1201 //## repair
1202  friend class EULER;
1203  friend class RKE;
1204  /* memory of auxiliary status values */
1205  class StatusMemory : public Memory {
1206  private:
1207  StatusMemory(const StatusMemory&) = delete;
1208  void operator= (const StatusMemory&) = delete;
1209  public:
1210  // create empty memory
1211  explicit StatusMemory(std::list<Memory*>* PtrList=PtrStatusMList) : Memory(PtrList) { }
1212  // free dynamic data
1213  virtual ~StatusMemory() { }
1214  }; // class StatusMemory
1215 
1216  friend class StatusMemory;
1217 
1218  // store state of integrators and status variables
1219  static void StoreState(Memory& di, Memory& si, StatusMemory& xi);
1220  // restore state of integrators and status variables
1221  static void RestoreState(double dthlf, Memory& di,
1222  Memory& si, StatusMemory& xi);
1223  // move startpoint to given state
1224  static void GoToState(Memory& di, Memory& si, StatusMemory& xi);
1225 
1226 public:
1227  explicit StatusMethod(const char* name); // initailization
1228  virtual ~StatusMethod() { } // free dynamic datas
1229  virtual void TurnOff(void) override; // turn off integration method
1230  virtual bool PrepareStep(void) override; // prepare integration step
1231  virtual void StatusResize(size_t size); // resize status memories
1232 }; // StatusMethod
1233 
1234 
1235 ////////////////////////////////////////////////////////////////////////////
1236 // interface for class IntegrationMethod & its descendants
1237 //
1238 
1239 //! select the integration method
1240 //! @param name "abm4", "euler", "fw", "rke"(default), "rkf3", "rkf5", "rkf8"
1241 //! \ingroup simlib
1242 inline void SetMethod(const char* name)
1243 {
1245 }
1246 
1247 //! get the name of the method which is used
1248 //! \ingroup simlib
1249 inline const char* GetMethod(void)
1250 {
1252 }
1253 
1254 //! set the method which will be used to start given multistep method
1255 //! \ingroup simlib
1256 inline void SetStarter(const char* name, const char* slave_name)
1257 {
1258  MultiStepMethod::SetStarter(name, slave_name);
1259 }
1260 
1261 //! set the method which will be used to start currently used multistep method
1262 //! \ingroup simlib
1263 inline void SetStarter(const char* slave_name)
1264 {
1266 }
1267 
1268 //! get the name of the method which is used to start given multistep method
1269 //! \ingroup simlib
1270 inline const char* GetStarter(const char* name)
1271 {
1272  return MultiStepMethod::GetStarter(name);
1273 }
1274 
1275 //! get the name of the method which is used
1276 //! to start currently used multistep method
1277 //! \ingroup simlib
1278 inline const char* GetStarter(void)
1279 {
1281 }
1282 
1283 
1284 ////////////////////////////////////////////////////////////////////////////
1285 //! block for numerical integration
1286 //! input is derivative, output is state
1287 //! \ingroup simlib
1288 class Integrator : public aContiBlock { // integrator
1289  Integrator &operator= (const Integrator &x) = delete; // disable assignment
1290  double dd; // input value: y'=f(t,y)
1291  double ddl; // the same from previous step
1292  double ss; // status: y = S f(t,y) dt
1293  double ssl; // the same from previous step
1294  protected:
1295  Input input; //!< input expression: f(t,y)
1296  double initval; //!< initial value: y(t0)
1297  void CtrInit();
1298  IntegratorContainer::iterator it_list; //!< position in list of integrators
1299  public:
1300  Integrator(); // implicit CTR (input = 0)
1301  // we use implicit conversions in block expressions
1302  Integrator(Input i, double initvalue=0);
1303  Integrator(Integrator &i, double initvalue=0); // copy-ctr
1304  ~Integrator();
1305  void Init(double initvalue); // set value
1306  void Init() { Init(initval); } //!< use preset initial value
1307  void Set(double value); // set integrator state value
1308  //! set integrator state value
1309  Integrator &operator= (double x) { Set(x); return *this; }
1310  //! set integrator input block expression
1311  Input SetInput(Input inp) { return input.Set(inp); }
1312  void Eval() override; // integrator input evaluation
1313  double Value() override; //!< the state of integrator
1314  double InputValue() { return input.Value(); } //!< current input value
1315  //virtual const char *Name() const;
1316 
1317  // private interface
1318  void Save(void) { ddl=dd; ssl=ss; } // save status
1319  void Restore(void) { dd=ddl; ss=ssl; } // restore saved status
1320  void SetState(double s) { ss=s; }
1321  double GetState(void) { return ss; }
1322  void SetOldState(double s) { ssl=s; }
1323  double GetOldState(void) { return ssl; }
1324  void SetDiff(double d) { dd=d; }
1325  double GetDiff(void) { return dd; }
1326  void SetOldDiff(double d) { ddl=d; }
1327  double GetOldDiff(void) { return ddl; }
1328 };
1329 
1330 
1331 ////////////////////////////////////////////////////////////////////////////
1332 //! State variables (memory)
1333 //! base for blocks with internal state (Relay, ...)
1334 //! \ingroup simlib
1335 class Status : public aContiBlock1 { // state-variables
1336  protected:
1337  double initval; //!< initial value
1338  bool ValueOK; // valid-flag ###
1339  void CtrInit();
1340  StatusContainer::iterator it_list; //!< position in list of status variables
1341  public:
1342  double st; //!< status
1343  double stl; //!< status from previous step
1344  Status(Input i, double initvalue=0);
1345  ~Status();
1346  void Init(double initvalue); // value initialization
1347  void Init() { Init(initval); }
1348  void Set(double value); // set status of block
1349  virtual void Eval() override; // block evaluation
1350  virtual double Value() override; // block status
1351  //virtual const char *Name() const;
1352  // internal interface
1353  void Save() { stl = st; } // save status
1354  void Restore(); // restore saved status
1355  void SetState(double s) { st=s; }
1356  double GetState(void) { return st; }
1357  void SetOldState(double s) { stl=s; }
1358  double GetOldState(void) { return stl; }
1359  void SetValid(bool flag) { ValueOK = flag; } // set valid flag
1360 };
1361 
1362 
1363 ////////////////////////////////////////////////////////////////////////////
1364 // Nonlinear blocks
1365 
1366 ////////////////////////////////////////////////////////////////////////////
1367 //! nonlinear block - hysteresis
1368 //! \ingroup simlib
1369 class Hyst : public Status {
1370  protected:
1371  double p1,p2;
1372  double y1,y2;
1373  double tga;
1374  virtual void Eval() override; // block evaluation
1375  public:
1376  Hyst(Input i, double p1, double p2, double y1, double y2, double tga);
1377  //virtual const char *Name() const;
1378 };
1379 
1380 typedef Hyst Hysteresis; // alias name
1381 
1382 
1383 ////////////////////////////////////////////////////////////////////////////
1384 //! nonlinear block - backlash
1385 //! \ingroup simlib
1386 class Blash : public Status { // backlash
1387  protected:
1388  double p1,p2;
1389  double tga;
1390  public:
1391  Blash(Input i, double p1, double p2, double tga);
1392  virtual void Eval() override; // block evaluation
1393  //virtual const char *Name() const;
1394 };
1395 
1396 typedef Blash Backlash; // alias
1397 
1398 ////////////////////////////////////////////////////////////////////////////
1399 //! Relay
1400 //! this implementation detects exact time of switch
1401 //! \ingroup simlib
1402 class Relay : public Status { // general relay block
1403  protected:
1404  double p1,p2,p3,p4; // points on x-axis
1405  double y1,y2; // points on y-axis
1406  public:
1407  Relay(Input i, double p1, double p2, double p3, double p4,
1408  double y1, double y2);
1409  virtual void Eval() override; //!< block evaluation
1410  //virtual const char *Name() const;
1411 };
1412 
1413 
1414 ////////////////////////////////////////////////////////////////////////////
1415 // Continuous block functions
1416 //
1417 
1418 // Block arithmetic binary operators:
1423 
1424 // Block unary operators:
1426 
1427 // Block functions:
1428 Input Abs(Input x); // abs(x) absolute value
1429 Input Sin(Input x); // sin(x)
1430 Input Cos(Input x); // cos(x)
1431 Input Tan(Input x); // tan(x)
1432 Input ASin(Input x); // asin(x)
1433 Input ACos(Input x); // acos(x)
1434 Input ATan(Input x); // atan(x)
1435 Input ATan2(Input y, Input x); // atan2(y,x)
1436 Input Exp(Input x); // exp(x) e ** x
1437 Input Log10(Input x); // log10(x)
1438 Input Ln(Input x); // ln(x) natural logarithm
1439 Input Pow(Input x, Input y); // pow(x,y) x ** y
1440 Input Sqr(Input x); // square x * x
1441 Input Sqrt(Input x); // square root
1442 Input Min(Input x, Input y); // minimum
1443 Input Max(Input x, Input y); // maximum
1444 Input Sign(Input x); // signum ###warning-steps-not-detected
1445 
1446 
1447 ////////////////////////////////////////////////////////////////////////////
1448 //! block parametrized by function with single argument
1449 //
1450 //! \ingroup simlib
1451 class Function1 : public aContiBlock1 {
1452  Function1(const Function1&) = delete;
1453  Function1&operator=(const Function1&) = delete;
1454  double (*f)(double); // pointer to function
1455  public:
1456  Function1(Input i, double (*pf)(double));
1457  virtual double Value() override;
1458  //virtual const char *Name() const;
1459 };
1460 
1461 ////////////////////////////////////////////////////////////////////////////
1462 //! block parametrized by function with two arguments
1463 //
1464 //! \ingroup simlib
1465 class Function2 : public aContiBlock2 {
1466  Function2(const Function2&) = delete;
1467  Function2&operator=(const Function2&) = delete;
1468  double (*f)(double,double); // pointer to function
1469  public:
1470  Function2(Input i1, Input i2, double (*pf)(double,double));
1471  virtual double Value() override;
1472  //virtual const char *Name() const;
1473 };
1474 
1475 
1476 ////////////////////////////////////////////////////////////////////////////
1477 // CATEGORY: state conditions
1478 
1479 ////////////////////////////////////////////////////////////////////////////
1480 //! abstract base class for all state-condition blocks
1481 //! State event in combined model is executed at the time when the condition
1482 //! changes its boolean value
1483 //! \ingroup simlib
1484 class aCondition : public aBlock {
1485  static aCondition *First; // list of all state conditions
1486  aCondition *Next; // next condition in list
1487  void operator= (const aCondition&) = delete;
1488  aCondition(const aCondition&) = delete;
1489  public:
1490  aCondition();
1491  ~aCondition();
1492  static void InitAll();
1493  static void SetAll();
1494  static void TestAll();
1495  static void AllActions();
1496  static bool isAny();
1497  private:
1498  virtual void Init()=0; //!< initialize
1499  virtual void SetNewStatus()=0; //!< update
1500  virtual bool Test()=0; //!< test of the condition
1501  virtual void Action()=0; //!< state event description
1502 };
1503 
1504 ////////////////////////////////////////////////////////////////////////////
1505 //! change detector - Boolean version (int)
1506 class Condition : public aCondition { // state condition
1507  Input in; // block input
1508  unsigned char cc; //!< state
1509  unsigned char ccl; //!< old state
1510  virtual void Init() override;
1511  virtual void SetNewStatus() override;
1512  protected:
1513  virtual bool Test() override; // test function (input >= 0.0)
1514  bool Up() { return ccl<cc; } // change: FALSE->TRUE
1515  bool Down() { return ccl>cc; } // change: TRUE->FALSE
1516  bool Change() { return ccl!=cc; } // both changes
1517  public:
1518  explicit Condition(Input i);
1519  ~Condition();
1520  bool Value() { return cc; } //!< boolean state of condition
1521  Input SetInput(Input inp) { return in.Set(inp); } // change input block
1522  //virtual const char *Name() const;
1523 };
1524 
1525 ////////////////////////////////////////////////////////////////////////////
1526 //! detector of FALSE-->TRUE
1527 //! \ingroup simlib
1528 class ConditionUp : public Condition { // state event on FALSE-->TRUE change
1529  public:
1530  explicit ConditionUp(Input i) : Condition(i) {}
1531  bool Test() override { return Condition::Test() && Up(); }
1532  //virtual const char *Name() const;
1533 };
1534 
1535 ////////////////////////////////////////////////////////////////////////////
1536 //! detector of TRUE-->FALSE
1537 //! \ingroup simlib
1538 class ConditionDown : public Condition { // state event on TRUE-->FALSE change
1539  public:
1540  explicit ConditionDown(Input i) : Condition(i) {}
1541  bool Test() override { return Condition::Test() && Down(); }
1542  //virtual const char *Name() const;
1543 };
1544 
1545 
1546 
1547 
1548 ////////////////////////////////////////////////////////////////////////////
1549 // CATEGORY: non-linear blocks
1550 
1551 
1552 ////////////////////////////////////////////////////////////////////////////
1553 //! nonlinear block: limitation
1554 //
1555 //! \ingroup simlib
1556 class Lim : public aContiBlock1 {
1557  protected:
1558  double low, high; // limits
1559  double tgalpha; //
1560  public:
1561  Lim(Input in, double l, double h, double tga=1.0);
1562  virtual void _Eval() override; // evaluation with loop check
1563  virtual double Value() override; // returned value
1564  //virtual const char *Name() const;
1565 };
1566 
1567 typedef Lim Limitation;
1568 
1569 ////////////////////////////////////////////////////////////////////////////
1570 //! nonlinear block: dead zone
1571 //
1572 //! \ingroup simlib
1573 class Insv : public aContiBlock1 {
1574  protected:
1575  double low, high; // limits
1576  double tgalpha,tgbeta; //
1577  public:
1578  Insv(Input in, double l, double h, double tga=1.0, double tgb=1.0);
1579  virtual void _Eval() override; // evaluation with loop check
1580  virtual double Value() override; // returned value
1581  //virtual const char *Name() const;
1582 };
1583 
1584 typedef Insv DeadZone;
1585 
1586 ////////////////////////////////////////////////////////////////////////////
1587 //! nonlinear block: quantizer
1588 //
1589 //! \ingroup simlib
1590 class Qntzr : public aContiBlock1 {
1591  protected:
1592  double step; // quantum
1593  public:
1594  Qntzr(Input in, double qstep=1.0);
1595  virtual void _Eval() override; // evaluation with loop check
1596  virtual double Value() override; // returned value
1597  //virtual const char *Name() const;
1598 };
1599 
1601 
1602 ////////////////////////////////////////////////////////////////////////////
1603 //! nonlinear block: friction
1604 //
1605 //! \ingroup simlib
1606 class Frict : public aContiBlock1 {
1607  protected:
1608  double low, high; // limits
1609  double tgalpha; //
1610  public:
1611  Frict(Input in, double l, double h, double tga=1.0);
1612  virtual void _Eval() override; // evaluation with loop check
1613  virtual double Value() override; // returned value
1614  //virtual const char *Name() const;
1615 };
1616 
1617 typedef Frict Friction;
1618 
1619 ////////////////////////////////////////////////////////////////////////////
1620 //! nonlinear block: function defined by given table of values
1621 //
1622 //TODO: reimplement with std::vector
1623 //! \ingroup simlib
1624 class Rline : public aContiBlock1 {
1625  protected:
1626  int n; // table item number
1627  double *tableX; // tabulka X
1628  double *tableY; // tabulka Y
1629  public:
1630  Rline(Input in, int num, double *X, double *Y);
1631 //TODO Rline(Input in, int num, double table[][2]);
1632  ~Rline();
1633  virtual void _Eval() override; // evaluation with loop check
1634  virtual double Value() override; // returned value
1635  //virtual const char *Name() const;
1636 };
1637 
1638 ////////////////////////////////////////////////////////////////////////////
1639 // CATEGORY: algebraic loop solvers
1640 
1641 
1642 ////////////////////////////////////////////////////////////////////////////
1643 //! abstract base for algebraic loop solvers
1644 // (not checked, needs improvements)
1645 //! \ingroup simlib
1646 class AlgLoop : public aContiBlock1 {
1647  protected:
1648  double Eps; // required accuracy
1649  unsigned long MaxIt; // max. number of iterations
1650  double TA; // boundary values of interval
1651  double TB; // (also used for convergency check)
1652  double T0; // initial value
1653  bool was_cycle; // flag for going through loop
1654  int phase; // phase of computation
1655  double root; // root of equation
1656  public:
1657  AlgLoop(Input i, double eps, unsigned long max_it, // constructor
1658  double t_min, double t_max, double t0);
1659  void Set(double eps, unsigned long max_it, // set parameters
1660  double t_min, double t_max, double t0);
1661  void Set(double eps, unsigned long max_it, // set parameters
1662  double t_min, double t_max);
1663  //virtual const char *Name() const;
1664 }; // AlgLoop
1665 
1666 
1667 ////////////////////////////////////////////////////////////////////////////
1668 //! solve using iterations
1669 //
1670 //! \ingroup simlib
1671 class Iterations : public AlgLoop {
1672  public:
1673  Iterations(Input i, double eps, unsigned long max_it,
1674  double t_min, double t_max, double t0):
1675  AlgLoop(i, eps, max_it, t_min, t_max, t0)
1676  {/*nothing*/}
1677  virtual double Value() override; // returned value
1678 };
1679 
1680 
1681 ////////////////////////////////////////////////////////////////////////////
1682 //! solve using bisection method
1683 //
1684 //! \ingroup simlib
1685 class Bisect : public AlgLoop {
1686  public:
1687  Bisect(Input i, double eps, unsigned long max_it,
1688  double t_min, double t_max):
1689  AlgLoop(i, eps, max_it, t_min, t_max, t_min)
1690  {/*nothing*/}
1691  virtual double Value() override; // returned value
1692 };
1693 
1694 
1695 ////////////////////////////////////////////////////////////////////////////
1696 //! solve using regula falsi method
1697 //
1698 //! \ingroup simlib
1699 class RegulaFalsi : public AlgLoop {
1700  double eps_root; // root for force precision test
1701  public:
1702  RegulaFalsi(Input i, double eps, unsigned long max_it,
1703  double t_min, double t_max):
1704  AlgLoop(i, eps, max_it, t_min, t_max, t_min),
1705  eps_root(0)
1706  {/*nothing*/}
1707  virtual double Value() override; // returned value
1708 };
1709 
1710 
1711 ////////////////////////////////////////////////////////////////////////////
1712 //! solve using modified Newton's method
1713 //
1714 //! \ingroup simlib
1715 class Newton : public AlgLoop {
1716  double eps_root; // root for force precision test
1717  double prev_root; // root from previous iteration step
1718  public:
1719  Newton(Input i, double eps, unsigned long max_it,
1720  double t_min, double t_max, double t0):
1721  AlgLoop(i, eps, max_it, t_min, t_max, t0),
1722  eps_root(0),
1723  prev_root(0)
1724  {/*nothing*/}
1725  virtual double Value() override; // returned value
1726 };
1727 
1728 
1729 ////////////////////////////////////////////////////////////////////////////
1730 // CATEGORY: global functions
1731 
1732 ////////////////////////////////////////////////////////////////////////////
1733 // Naming Subsystem --- SimObject names (text identifiers for printing)
1734 // this is system dictionary: relation: objectptr---textname
1735 // ### TODO: use strings in objects OR unordered_map
1736 //
1737 void SetName(SimObject &o, const std::string &name);
1738 void SetName(SimObject *o, const std::string &name);
1739 void RemoveName(SimObject &o);
1740 void RemoveName(SimObject *o);
1741 std::string GetName(SimObject &o);
1742 std::string GetName(SimObject *o);
1743 
1744 
1745 ////////////////////////////////////////////////////////////////////////////
1746 //! InstallBreak --- set function for checking if user breaks simulation
1747 //! @param f is called at each step of simulation
1748 //! f can call Stop() or Abort()
1749 //! \ingroup simlib
1750 void InstallBreak(void (*f)());
1751 
1752 
1753 ////////////////////////////////////////////////////////////////////////////
1754 //! basic synchronization tool for processes
1755 //! simplified implementation
1756 //! \ingroup simlib
1757 class Semaphore : public SimObject {
1758  protected:
1759  int n;
1760  public:
1761  Queue Q; //!< internal quqeue
1762  Semaphore(); // constructor
1763  explicit Semaphore(const char *_name); // with associated name
1764  virtual ~Semaphore();
1765  void Clear(); //!< initialization
1766  virtual void Output() const override;
1767  virtual void P(); //!< P operation
1768  virtual void V(); //!< V operation
1769 // operator Semaphore* () { return this; }
1770 };
1771 
1772 ////////////////////////////////////////////////////////////////////////////
1773 //! synchronization tool for processes
1774 //
1775 //! \ingroup simlib
1776 class Barrier : public SimObject {
1777  protected:
1778  Entity **waiting; //!< array of waiting entities (fixed size)
1779  unsigned n; //!< current number of waiting entities
1780  unsigned maxn; //!< barrier height/size
1781  void Init(); //!< initialization
1782  public:
1783  explicit Barrier(unsigned N);
1784  Barrier(const char *_name, unsigned N);
1785  virtual ~Barrier();
1786  void ChangeHeight(unsigned new_maxn); //!< change size
1787  unsigned Height() const { return maxn; } //!< barrier size
1788  virtual void Enter(Entity *e); //!< wait for barrier break TODO: remove/rename
1789  virtual bool Wait(); //!< wait for barrier break (Current)
1790  virtual int Break(); //!< activate all waiting entities
1791  void Clear(); //!< initialization
1792  virtual void Output() const override; //!< print status
1793 };
1794 
1795 /////////////////////////////////////////////////////////////////////////////
1796 //! internal statistics structure
1797 //! <br> contains basic statistics of simulator execution
1798 // TODO: add interface and hide variables
1799 // TODO: add real time of execution ?
1800 //! \ingroup simlib
1802  double StartTime;
1803  double EndTime;
1804  long EventCount; // for discrete simulation
1805  long StepCount; // for continuous simulation
1806  double MinStep;
1807  double MaxStep;
1808  //! constructor runs SIMLIB_statistics_t::Init()
1810  //! initialize - used at the start of each Run()
1811  void Init();
1812  //! print run-time statistics to output
1813  void Output() const;
1814 };
1815 
1816 //! interface to internal run-time statistics structure
1817 extern const SIMLIB_statistics_t & SIMLIB_statistics;
1818 
1819 } // namespace simlib3
1820 
1821 using namespace simlib3; // default for "simlib.h"
1822 
1823 #endif // ifndef __SIMLIB__
1824 
iterator begin()
Definition: simlib.h:699
bool isInterrupted() const
Definition: simlib.h:450
SingleStepMethod * Slave_Ptr
Definition: simlib.h:1165
double Low() const
Definition: simlib.h:740
std::list< Integrator * >::iterator iterator
Definition: simlib.h:992
void Init()
use preset initial value
Definition: simlib.h:1306
StatusContainer::iterator it_list
position in list of status variables
Definition: simlib.h:1340
unsigned QueueLen() const
Definition: simlib.h:809
unsigned Count() const
Definition: simlib.h:743
double max
Definition: simlib.h:597
double GetDiff(void)
Definition: simlib.h:1325
base for continuous blocks with two inputs
Definition: simlib.h:959
double prev_root
Definition: simlib.h:1717
std::list< Status * >::iterator iterator
Definition: simlib.h:1027
double eps_root
Definition: simlib.h:1716
(SOL-like) facility Facility with exclusive access and service priority
Definition: simlib.h:753
unsigned long _RequiredCapacity
Definition: simlib.h:391
nonlinear block: dead zone
Definition: simlib.h:1573
double Random()
base uniform generator (range 0-0.999999...) the default implementation is simple LCG 32bit ...
Definition: random1.cc:95
bool Empty() const
store is empty
Definition: simlib.h:807
Input Sqr(Input x)
square function
Definition: continuous.cc:233
bool on
switch on/off
Definition: simlib.h:513
double LastValue() const
Definition: simlib.h:619
const double SIMLIB_MAXTIME
maximum time (1e30 works for float, too)
Definition: simlib.h:148
void SetAccuracy(double _abserr, double _relerr)
set max.
Definition: intg.cc:106
static bool IsEndStepEvent
Definition: simlib.h:1079
Queue * Q1
Input queue.
Definition: simlib.h:757
Qntzr Quantizer
Definition: simlib.h:1600
unsigned n
current number of waiting entities
Definition: simlib.h:1779
nonlinear block: limitation
Definition: simlib.h:1556
virtual bool Test() override
Condition::operator ()
Definition: cond.cc:106
double step
step of sampling
Definition: simlib.h:512
block: parameter (can not be changed during simulation run)
Definition: simlib.h:869
const char * GetStarter(const char *name)
get the name of the method which is used to start given multistep method
Definition: simlib.h:1270
double Rayle(double delta)
Definition: random2.cc:219
Input operator/(Input a, Input b)
block operator /
Definition: continuous.cc:230
unsigned long n
Definition: simlib.h:601
unsigned char ServicePriority_t
Service priority (see Facility::Seize)
Definition: simlib.h:365
Expression(Input i)
Definition: simlib.h:952
static unsigned long _Number
current number of entities
Definition: simlib.h:377
void DebugON()
start debugging output
Definition: debug.cc:36
double low
Definition: simlib.h:1558
int _Print(const char *fmt,...)
output of messages to stdout, too
Definition: print.cc:68
double SumSquare() const
Definition: simlib.h:616
const double & AbsoluteError
max. abs. error of integration
Definition: intg.cc:53
nonlinear block: function defined by given table of values
Definition: simlib.h:1624
double sx2t
Definition: simlib.h:595
Input Tan(Input x)
Definition: fun.cc:98
double Exponential(double mv)
Exponential distribution generator.
Definition: random2.cc:152
Input Min(Input x, Input y)
Definition: fun.cc:114
void SetState(double s)
Definition: simlib.h:1355
(SOL-like) store store capacity can be changed dynamically
Definition: simlib.h:785
int Poisson(double lambda)
Poisson distribution generator.
Definition: random2.cc:229
State variables (memory) base for blocks with internal state (Relay, ...)
Definition: simlib.h:1335
double Min() const
Definition: simlib.h:613
double Step() const
Definition: simlib.h:742
double low
Definition: simlib.h:1608
IntegrationMethod - Abstract base class for integration methods.
Definition: simlib.h:1058
void * _context
process context pointer
Definition: simlib.h:441
synchronization tool for processes
Definition: simlib.h:1776
Abstract base class for integration methods with status auxiliary memories.
Definition: simlib.h:1186
Input Sin(Input x)
Definition: fun.cc:96
void SetName(const std::string &name)
assign the name
Definition: object.cc:125
bool isPrepared() const
Definition: simlib.h:448
nonlinear block: friction
Definition: simlib.h:1606
SimObject()
constructor
Definition: object.cc:100
Input Max(Input x, Input y)
Definition: fun.cc:115
bool Full() const
store is full
Definition: simlib.h:806
const double value
Definition: simlib.h:849
unsigned QueueLen() const
Definition: simlib.h:772
double tgalpha
Definition: simlib.h:1609
Priority_t Priority
priority of the entity (scheduling,queues)
Definition: simlib.h:399
const double & StepSize
actual integration step
Definition: intg.cc:48
double stl
status from previous step
Definition: simlib.h:1343
solve using bisection method
Definition: simlib.h:1685
void SetOldState(double s)
Definition: simlib.h:1357
SimObject & operator=(const SimObject &)=delete
disable assign operation
void Clear()
Definition: simlib.h:706
double & operator[](size_t ind)
Definition: simlib.h:1104
void Stop()
stop current simulation run
Definition: run.cc:147
bool _wait_until
Definition: simlib.h:454
bool Test() override
Condition::operator ()
Definition: simlib.h:1541
continuous block connection (transparent reference) wrapper for pointer to objects of aContiBlock der...
Definition: simlib.h:895
double max
Definition: simlib.h:568
double last
last sample time – prevents sample duplication
Definition: simlib.h:511
signed char EntityPriority_t
Priority of the process/event.
Definition: simlib.h:363
Newton(Input i, double eps, unsigned long max_it, double t_min, double t_max, double t0)
Definition: simlib.h:1719
EventNotice * GetEventNotice()
Definition: simlib.h:427
unsigned long used
Currently used capacity.
Definition: simlib.h:789
TStat StatN
Definition: simlib.h:691
bool Busy() const
in service
Definition: simlib.h:770
double Weibul(double lambda, double alfa)
Weibul distribution generator.
Definition: random2.cc:94
int NegBin(double q, int k)
Definition: random2.cc:121
bool Test() override
Condition::operator ()
Definition: simlib.h:1531
Input Sign(Input x)
Definition: fun.cc:110
static void SetStarter(const char *name, const char *slave_name)
set starting method for given multi-step method
Definition: numint.cc:474
void Run()
run simulation experiment
Definition: run.cc:228
aContiBlock & T
simulation time block reference
Definition: continuous.cc:276
Entity * back()
Definition: simlib.h:702
static void IntegrationDone(void)
Definition: simlib.h:1121
const double & OptStep
optimal integration step
Definition: intg.cc:49
static iterator End(void)
Definition: simlib.h:1041
double GetOldState(void)
Definition: simlib.h:1358
double StartTime() const
Definition: simlib.h:617
double t0
Definition: simlib.h:598
double Triag(double mod, double min, double max)
Definition: random2.cc:193
class for statistical information gathering
Definition: simlib.h:563
Input ATan(Input x)
Definition: fun.cc:102
#define __SIMLIB__
Definition: simlib.h:8
base for single-step integration methods
Definition: simlib.h:1141
#define SIMLIB_DEBUG
Definition: _test_.cc:4
base for continuous blocks vith three inputs and algebraic loop check
Definition: simlib.h:971
void ContractStep()
contract step of integration
Definition: intg.cc:64
unsigned _flags
bool flags for internal use (TODO bitfield?)
Definition: simlib.h:308
double sx2
Definition: simlib.h:566
virtual void Passivate()
deactivation
Definition: entity.cc:68
Entity * In() const
current entity or nullptr
Definition: simlib.h:771
void Get(Entity *e)
remove selected entity activation record from calendar
Definition: calendar.cc:1308
Insv DeadZone
Definition: simlib.h:1584
std::list< Memory * >::iterator it_list
Definition: simlib.h:1099
unsigned count
Definition: simlib.h:729
solve using modified Newton&#39;s method
Definition: simlib.h:1715
unsigned size() const
Definition: simlib.h:671
bool HasName() const
Definition: simlib.h:321
double High() const
Definition: simlib.h:741
double Value() const
get target block value
Definition: simlib.h:931
static Sampler * First
Definition: simlib.h:507
EventNotice * _evn
points to calendar item, iff scheduled
Definition: simlib.h:425
bool isAllocated() const
Definition: simlib.h:318
int Print(const char *fmt,...)
for Output methods, can be redirected
Definition: print.cc:92
double * tableX
Definition: simlib.h:1627
objects of this class call global function periodically (typicaly used for output of continuous model...
Definition: simlib.h:506
unsigned long Debug(unsigned long mode)
Definition: debug.cc:48
Input(aContiBlock &cb)
reference to block
Definition: simlib.h:903
double Min() const
Definition: simlib.h:580
bool isTerminated() const
Definition: simlib.h:451
double GetStep() const
get current step
Definition: simlib.h:523
bool Value()
boolean state of condition
Definition: simlib.h:1520
double Beta(double th, double fi, double min, double max)
Beta distribution generator.
Definition: random2.cc:181
unsigned char _Qflag
true if store is owner of input queue
Definition: simlib.h:786
Input operator+(Input a, Input b)
block operator +
Definition: continuous.cc:224
static iterator Begin(void)
Definition: simlib.h:1002
std::list< Memory * > * ListPtr
Definition: simlib.h:1100
iterator & operator++()
Definition: simlib.h:642
double p4
Definition: simlib.h:1404
double Max() const
Definition: simlib.h:614
base for multi-step integration method
Definition: simlib.h:1162
void SetStarter(const char *name, const char *slave_name)
set the method which will be used to start given multistep method
Definition: simlib.h:1256
double LastTime() const
Definition: simlib.h:618
static std::list< IntegrationMethod * > * MthLstPtr
Definition: simlib.h:1063
reference to block expression This block can be used as handle for block expression trees ...
Definition: simlib.h:951
block: variable (value can be changed)
Definition: simlib.h:858
Implementation of class CalendarList interface is static - using global functions in SQS namespace...
Definition: algloop.cc:32
double max(double a, double b)
Definition: internal.h:286
double * tableY
Definition: simlib.h:1628
double SumSquare() const
Definition: simlib.h:583
static bool isAny(void)
Definition: simlib.h:994
bool isCurrent() const
Definition: simlib.h:449
Link * operator*() const
Definition: simlib.h:650
virtual void Output() const
print object to default output
Definition: object.cc:144
iterator & operator--()
Definition: simlib.h:643
static void SetMethod(const char *name)
set method which will be used
Definition: numint.cc:75
Bisect(Input i, double eps, unsigned long max_it, double t_min, double t_max)
Definition: simlib.h:1687
const double & RelativeError
max. rel. error
Definition: intg.cc:54
ConditionUp(Input i)
Definition: simlib.h:1530
iterator operator++(int)
Definition: simlib.h:644
double Max() const
Definition: simlib.h:581
double tgbeta
Definition: simlib.h:1576
double xl
Definition: simlib.h:600
static size_t Size(void)
Definition: simlib.h:1033
unsigned long _Ident
unique identification number of entity
Definition: simlib.h:378
void SIMLIB_DoActions()
Definition: run.cc:135
Input ASin(Input x)
Definition: fun.cc:100
iterator & operator=(const iterator &x)
Definition: simlib.h:639
static Link * next(Link *p)
Definition: simlib.h:631
List::iterator iterator
Definition: simlib.h:690
abstract base class for active entities (Process, Event) instances of derived classes provide Behavio...
Definition: simlib.h:375
Entity *const & Current
pointer to active (now running) entity
Definition: run.cc:54
Base class for almost all SIMLIB classes.
Definition: simlib.h:299
static std::list< Memory * > * PtrMList
Definition: simlib.h:1072
static bool isAny(void)
Definition: simlib.h:1029
abstract base for algebraic loop solvers
Definition: simlib.h:1646
const double & Time
model time (is NOT the block)
Definition: run.cc:48
void Error(const char *fmt,...)
print message and terminate program
Definition: print.cc:123
void RandomSeed(long seed)
initialize random number seed
Definition: random1.cc:64
double y2
Definition: simlib.h:1405
double tga
Definition: simlib.h:1389
static bool flag
Definition: waitunti.cc:89
void SetStep(double _dtmin, double _dtmax)
Set integration step interval.
Definition: intg.cc:92
aContiBlock * bp
Definition: simlib.h:896
void SetOldState(double s)
Definition: simlib.h:1322
void SetValid(bool flag)
Definition: simlib.h:1359
double initval
initial value: y(t0)
Definition: simlib.h:1296
std::list< Memory * > StatusMList
Definition: simlib.h:1190
detector of FALSE–>TRUE
Definition: simlib.h:1528
void RemoveName(SimObject &o)
remove name
Definition: name.cc:54
void Passivate(Entity *e)
passivate entity e
Definition: simlib.h:432
std::string GetName(SimObject &o)
get name of object
Definition: name.cc:66
StatusMemory(std::list< Memory *> *PtrList=PtrStatusMList)
Definition: simlib.h:1211
void SIMLIB_Init(double T0, double T1, unsigned version)
Definition: run.cc:177
virtual ~SimObject()
virtual destructor
Definition: object.cc:114
static aCondition * First
Definition: simlib.h:1485
unsigned Height() const
barrier size
Definition: simlib.h:1787
Frict Friction
Definition: simlib.h:1617
static std::list< Memory * > * PtrStatusMList
Definition: simlib.h:1191
unsigned * dptr
Definition: simlib.h:726
Input Set(Input i)
Redirect the reference.
Definition: simlib.h:913
nonlinear block - hysteresis
Definition: simlib.h:1369
Test t(F)
Queue Q
internal quqeue
Definition: simlib.h:1761
double tl
Definition: simlib.h:599
unsigned long Number() const
Definition: simlib.h:612
double Sum() const
Definition: simlib.h:582
virtual double Value() override
get block output value this method should be defined in classes derived from aContiBlock ...
Definition: simlib.h:874
basic synchronization tool for processes simplified implementation
Definition: simlib.h:1757
void Sample()
Definition: _test_.cc:38
double tga
Definition: simlib.h:1373
unsigned char _Qflag
true if facility is owner of input queue
Definition: simlib.h:754
static iterator Begin(void)
Definition: simlib.h:1037
Input operator*(Input a, Input b)
block operator *
Definition: continuous.cc:228
aCondition * Next
Definition: simlib.h:1486
void Save()
Definition: simlib.h:1353
const char * SIMLIB_version_string()
Get version of SIMLIB.
Definition: version.cc:13
double p2
Definition: simlib.h:1388
virtual bool IsSingleStep(void) override
Definition: simlib.h:1150
unsigned long Used() const
used capacity
Definition: simlib.h:804
Input(const double c)
create block of type Constant WARNING: using C++ variable in block expression creates Constant block ...
Definition: simlib.h:908
double Normal(double mi, double sigma)
Gauss distribution generator.
Definition: random2.cc:82
static IntegrationMethod * CurrentMethodPtr
pointer to the method currently used "rke" is a predefined method (historical reasons, we need rk45)
Definition: simlib.h:1062
bool operator==(const ParameterVector &p1, const ParameterVector &p2)
Definition: opt-param.cc:86
const double & EndTime
time of simulation end
Definition: run.cc:50
iterator end()
Definition: simlib.h:700
Entity * front()
Definition: simlib.h:701
solve using iterations
Definition: simlib.h:1671
double min(double a, double b)
Definition: internal.h:285
double Gamma(double alfa, double beta)
Gamma distribution generator.
Definition: random2.cc:141
abstract base for continuous blocks with single output suitable for expression-tree building and eval...
Definition: simlib.h:832
double Input1Value()
Definition: simlib.h:964
static iterator End(void)
Definition: simlib.h:1006
unsigned n
Definition: simlib.h:633
double Input2Value()
Definition: simlib.h:965
void SetOldDiff(double d)
Definition: simlib.h:1326
unsigned Length()
Definition: simlib.h:708
Entity * GetFirst()
remove entity with minimum activation time
Definition: calendar.cc:1327
internal flags (bitmasks: 1bit set)
Definition: simlib.h:302
bool empty()
Definition: simlib.h:676
Relay this implementation detects exact time of switch.
Definition: simlib.h:1402
const char * method_name
Definition: simlib.h:1065
change detector - Boolean version (int)
Definition: simlib.h:1506
Input Abs(Input x)
Definition: fun.cc:94
TStat tstat
usage statistics
Definition: simlib.h:791
Input Log10(Input x)
Definition: fun.cc:106
Lim Limitation
Definition: simlib.h:1567
virtual double Value() override
get block output value this method should be defined in classes derived from aContiBlock ...
Definition: simlib.h:852
virtual void TurnOff(void)
turn off integration method: flush memories etc...
Definition: numint.cc:261
void InstallBreak(void(*f)())
InstallBreak — set function for checking if user breaks simulation.
Definition: run.cc:104
Input Cos(Input x)
Definition: fun.cc:97
Hyst Hysteresis
Definition: simlib.h:1380
int HyperGeom(double p, int n, int m)
Definition: random2.cc:270
StatusContainer - internal container of status variables (singleton)
Definition: simlib.h:1021
static Iterator LastIntegrator(void)
Definition: simlib.h:1084
iterator(const iterator &x)
Definition: simlib.h:638
unsigned long Capacity() const
max capacity
Definition: simlib.h:805
void Init(double t0, double t1=SIMLIB_MAXTIME)
Initialize simulator and model time.
Definition: simlib.h:181
nonlinear block: quantizer
Definition: simlib.h:1590
void Save(void)
Definition: simlib.h:1318
void Init()
Definition: simlib.h:1347
const double & NextTime
next-event time
Definition: run.cc:49
Queue * Q
input queue
Definition: simlib.h:790
std::list< Memory * > MList
Definition: simlib.h:1071
abstract base class for events Event behavior is simple function (can not be interrupted) ...
Definition: simlib.h:488
void Activate(Entity *e)
activate entity e
Definition: simlib.h:431
Iterations(Input i, double eps, unsigned long max_it, double t_min, double t_max, double t0)
Definition: simlib.h:1673
abstract base class for all state-condition blocks State event in combined model is executed at the t...
Definition: simlib.h:1484
double sx
Definition: simlib.h:565
void SetMethod(const char *name)
select the integration method
Definition: simlib.h:1242
Constant(double x)
Definition: simlib.h:851
static Iterator FirstIntegrator(void)
Definition: simlib.h:1081
double value
Definition: simlib.h:859
double Erlang(double alfa, int beta)
Erlang distribution generator.
Definition: random2.cc:109
unsigned maxn
barrier height/size
Definition: simlib.h:1780
double y2
Definition: simlib.h:1372
unsigned long Number() const
Definition: simlib.h:579
#define RegisterReference(aContiBlockPtr)
Definition: simlib.h:882
histogram statistics
Definition: simlib.h:724
unsigned long n
Definition: simlib.h:569
double st
status
Definition: simlib.h:1342
void SetCalendar(const char *name)
choose calendar implementation default is list
Definition: calendar.cc:1250
virtual ~StatusMethod()
Definition: simlib.h:1228
virtual std::string Name() const
get object name
Definition: object.cc:134
Variable(double x=0)
Definition: simlib.h:861
double Uniform(double l, double h)
Uniform distribution generator.
Definition: random2.cc:71
iterator operator--(int)
Definition: simlib.h:647
RegulaFalsi(Input i, double eps, unsigned long max_it, double t_min, double t_max)
Definition: simlib.h:1702
void Cancel()
end Behavior() and remove entity
Definition: simlib.h:413
void SetOutput(const char *name)
redirects Output(), Print() to file
Definition: print.cc:50
IntegratorContainer::iterator Iterator
Definition: simlib.h:1080
Input ATan2(Input y, Input x)
Definition: fun.cc:103
const char * GetMethod(void)
get the name of the method which is used
Definition: simlib.h:1249
iterator(Link *pos)
Definition: simlib.h:641
block parametrized by function with two arguments
Definition: simlib.h:1465
IntegratorContainer - internal container of integrators (singleton)
Definition: simlib.h:986
void Restore(void)
Definition: simlib.h:1319
Input input
input expression: f(t,y)
Definition: simlib.h:1295
static const size_t page_size
Definition: simlib.h:1096
static std::list< Status * > * ListPtr
list of status variables
Definition: simlib.h:1023
void SetBaseRandomGenerator(double(*new_gen)())
set another random generator default Random() implementation can be replaced
Definition: random1.cc:103
bool Idle()
entity activation is not scheduled in calendar
Definition: simlib.h:412
Parameter(double x)
Definition: simlib.h:872
unsigned long id() const
Definition: simlib.h:396
Link * back()
Definition: simlib.h:675
Input operator-(Input a, Input b)
block operator -
Definition: continuous.cc:226
bool TestAndSetFlag(bool new_value, unsigned n)
internal method for flag manipulation is used for algebraic loop checking in continuous blocks ...
Definition: internal.h:293
iterator begin()
Definition: simlib.h:672
#define UnRegisterReference(aContiBlockPtr)
Definition: simlib.h:883
IntegratorContainer::iterator it_list
position in list of integrators
Definition: simlib.h:1298
Link * front()
Definition: simlib.h:674
static std::list< Integrator * > * ListPtr
list of integrators
Definition: simlib.h:988
ConditionDown(Input i)
Definition: simlib.h:1540
abstract base class for all blocksblocks/SimObject have not copy semantics (TODO: add move semantics)...
Definition: simlib.h:825
Entity ** waiting
array of waiting entities (fixed size)
Definition: simlib.h:1778
double Input1Value()
Definition: simlib.h:977
double _RemainingTime
Definition: simlib.h:390
Input Pow(Input x, Input y)
Definition: fun.cc:108
Queue * Q2
Interrupted requests queue.
Definition: simlib.h:758
void SetDiff(double d)
Definition: simlib.h:1324
activation record
Definition: calendar.cc:145
double InputValue()
current input value
Definition: simlib.h:1314
Input SetInput(Input inp)
set integrator input block expression
Definition: simlib.h:1311
double InputValue()
Definition: simlib.h:944
unsigned char cc
state
Definition: simlib.h:1508
virtual double Value() override
get block output value this method should be defined in classes derived from aContiBlock ...
Definition: simlib.h:863
int NegBinM(double p, int m)
Definition: random2.cc:164
bool IsStartMode(void)
Definition: simlib.h:1154
static Link * previous(Link *p)
Definition: simlib.h:632
block: constant (value can not be changed)
Definition: simlib.h:848
base for continuous blocks with single input and algebraic loop check
Definition: simlib.h:940
unsigned char ccl
old state
Definition: simlib.h:1509
static size_t Size(void)
Definition: simlib.h:998
void Activate()
activate now
Definition: simlib.h:408
Abstract base class for all simulation processesProcess behavior is specified by Behavior method and ...
Definition: simlib.h:440
Input(aContiBlock *cb)
pointer to block
Definition: simlib.h:904
EntityPriority_t Priority_t
Definition: simlib.h:397
static const char * GetStarter(const char *name)
obtain the name of the starting method of given method
Definition: numint.cc:503
Input SetInput(Input inp)
Definition: simlib.h:1521
double Logar(double mi, double delta)
Definition: random2.cc:210
virtual double Value()=0
get block output value this method should be defined in classes derived from aContiBlock ...
block for numerical integration input is derivative, output is state
Definition: simlib.h:1288
void SetState(double s)
Definition: simlib.h:1320
double GetOldState(void)
Definition: simlib.h:1323
priority queue
Definition: simlib.h:685
double low
Definition: simlib.h:1575
ServicePriority_t _SPrio
priority of service in Facility
Definition: simlib.h:393
void DebugOFF()
stop debugging output
Definition: debug.cc:42
double min
Definition: simlib.h:596
Input Ln(Input x)
Definition: fun.cc:107
list of Link* items, uses data from Link
Definition: simlib.h:630
static const char * GetMethod(void)
Definition: simlib.h:1125
double Input3Value()
Definition: simlib.h:979
const double & MinStep
minimal integration step
Definition: intg.cc:46
virtual bool IsSingleStep(void) override
Definition: simlib.h:1172
double Input2Value()
Definition: simlib.h:978
Input Sqrt(Input x)
Definition: fun.cc:112
unsigned long MaxIt
Definition: simlib.h:1649
double p2
Definition: simlib.h:1371
Blash Backlash
Definition: simlib.h:1396
double sxt
Definition: simlib.h:594
std::list< IntegrationMethod * >::iterator ItList
Definition: simlib.h:1064
const double SIMLIB_MINTIME
minimal time value
Definition: simlib.h:147
void SetStartMode(bool start_mode)
Definition: simlib.h:1151
ProcessStatus_t
possible process status values
Definition: simlib.h:445
bool Empty()
Definition: simlib.h:707
double step
Definition: simlib.h:1592
solve using regula falsi method
Definition: simlib.h:1699
double GetState(void)
Definition: simlib.h:1321
Sampler * Next
Definition: simlib.h:508
time dependent statistic
Definition: simlib.h:592
TStat tstat
usage statistics
Definition: simlib.h:759
iterator end()
Definition: simlib.h:673
Definition: _test_.cc:10
StatusContainer::iterator StatusIterator
Definition: simlib.h:1193
const SIMLIB_statistics_t & SIMLIB_statistics
interface to internal run-time statistics structure
Definition: run.cc:78
block parametrized by function with single argument
Definition: simlib.h:1451
static StatusIterator FirstStatus(void)
Definition: simlib.h:1194
void Abort()
end simulation program
Definition: run.cc:159
detector of TRUE–>FALSE
Definition: simlib.h:1538
Entity * in
Entity currently in service.
Definition: simlib.h:756
nonlinear block - backlash
Definition: simlib.h:1386
Input Exp(Input x)
Definition: fun.cc:105
unsigned long capacity
Capacity of store.
Definition: simlib.h:788
Input(const Input &i)
transparent copy of block reference
Definition: simlib.h:900
double _MarkTime
Definition: simlib.h:384
const double & MaxStep
maximal integration step
Definition: intg.cc:47
double Sum() const
Definition: simlib.h:615
double tgalpha
Definition: simlib.h:1559
internal statistics structure contains basic statistics of simulator execution
Definition: simlib.h:1801
unsigned long Free() const
free capacity
Definition: simlib.h:803
double GetState(void)
Definition: simlib.h:1356
SingleStepMethod(const char *name)
Definition: simlib.h:1147
double GetOldDiff(void)
Definition: simlib.h:1327
Stat StatDT
Definition: simlib.h:692
const double & StartTime
time of simulation start
Definition: run.cc:47
Input ACos(Input x)
Definition: fun.cc:101
const unsigned SIMLIB_version
library version
Definition: version.cc:9
int Geom(double q)
Definition: random2.cc:257
static StatusIterator LastStatus(void)
Definition: simlib.h:1197
void SetErrNo(int num)
Definition: numint.cc:327
double min
Definition: simlib.h:567
double initval
initial value
Definition: simlib.h:1337
void Clear()
remove all scheduled entities
Definition: calendar.cc:1346