/////////////////////////////////////////////////////////////////////////////
//! simlib.h - SIMLIB/C++ main interface
//
// SIMLIB version: 2.18
// Date: 2004-11-07
//
// -------------------------------------------------------------------------
// SIMLIB/C++ (SIMulation LIBrary for C++)
// -------------------------------------------------------------------------
// Copyright (c) 1991-2004 Petr Peringer
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
// -------------------------------------------------------------------------
//
// This is main interface for SIMLIB/C++
//
// Supported platforms:
// Linux: GNU C++ compiler, arch i386+
// Portable to:
// FreeBSD: GNU C++, i386+
// MSDOS: DJGPP v2.0 = GNU C++ compiler for MSDOS (DPMI)
// WIN95: Borland C++ (v5.0, console application)
//
// WARNING: this is debugging version!
//
// Send bug reports to: peringer AT fit.vutbr.cz
//
// EXPERIMENTAL:
#define NEW_WULIST
#ifndef __SIMLIB_H
#define __SIMLIB_H
#define __SIMLIB__ 0x0218 // version of SIMLIB
#define SIMLIB_VERSION "2.18"
#ifndef __cplusplus
# error Use C++ compiler, please.
#endif
// system and compiler dependent part
#if defined(__MSDOS__)
# define SIMLIB_SYSTEM "MSDOS"
# if defined(__BCPLUSPLUS__)
# error Borland C++ for DOS no longer supported (use DJGPP)
# elif defined(__GNUG__)
# define SIMLIB_COMPILER "GNU C++"
# else
# error This compiler is not supported (under MSDOS)
# endif
#elif defined(__linux__)
# define SIMLIB_SYSTEM "Linux"
# define SIMLIB_COMPILER "GNU C++"
#elif defined(__WIN32__) && defined(__BCPLUSPLUS__) // check###!!!
# define SIMLIB_SYSTEM "WIN32"
# define SIMLIB_COMPILER "Borland C++"
#elif defined(__FreeBSD__)
# define SIMLIB_SYSTEM "FreeBSD"
# define SIMLIB_COMPILER "GNU C++"
#elif defined(__unix__) // ?????????????????#########
# define SIMLIB_SYSTEM "Unixware?"
# define SIMLIB_COMPILER "GNU C++"
#else
# error "SIMLIB is not implemented for this system/compiler"
#endif
////////////////////////////////////////////////////////////////////////////
// what we expect:
// type bool,
// standard ISO C++ containers and iterators (for implementation)
//
////////////////////////////////////////////////////////////////////////////
// DEBUGGING: print debug info ON/OFF/mode
//
void DebugON();
void DebugOFF();
unsigned long Debug(unsigned long mode=~0UL); // start/stop partial debugging
// experimental code for start/stop debugging at global level
#ifdef SIMLIB_DEBUG
static unsigned long SIMLIB_old_debug_flags = Debug(SIMLIB_DEBUG);
#endif
////////////////////////////////////////////////////////////////////////////
// ATEXIT: special internal class for atexit, etc...
//
class SIMLIB_module { // internal class for SIMLIB cleanup (atexit)
const char *string; // module identification string
SIMLIB_module(const SIMLIB_module&); // disable copy-ctr
SIMLIB_module &operator= (const SIMLIB_module&); // disable op=
public:
SIMLIB_module();
int Init(const char *s);
~SIMLIB_module();
};
// create single global registration object in each module
static SIMLIB_module SIMLIB_module_id;
////////////////////////////////////////////////////////////////////////////
// includes ...
//
// remove it !!! ###
#include <csetjmp> // will be removed
// Leska:
// try this instead the above if you have class list
// and don't forget to link g++ library!
#include <list>
#define dlist std::list
////////////////////////////////////////////////////////////////////////////
// overwiew of basic SIMLIB classes (abstractions)
//
class SimObject; // base abstract class
// discrete:
class Link; // list item base class (Simula-like)
class Entity; // discrete model entity
class Process; // process base
class Event; // event base
class Sampler; // periodic calls of global function
class List; // list of objects of class Link descendants
class Queue; // priority queue
class Stat; // statistics
class TStat; // time dependent statistics
class Histogram; // histogram
class Facility; // SOL-like facility
class Store; // SOL-like store
class Barrier; // barrier
class Semaphore; // semaphore
// continuous:
class aBlock; // abstract block
class aContiBlock; // blocks with continuous output
class Integrator; // integrator
class Status; // status variables
class Hyst; // hysteresis
class Blash; // backlash
class Relay; // general relay
class Function; // general function
class Constant; // constant
class Variable; // variable
class Parameter; // parameter (simulation run constant)
//class aBoolBlock; // Boolean blocks
// combined:
class aCondition; // state condition base class
class Condition; // state event detector (Boolean version)
class ConditionUp; // action by FALSE-->TRUE change
class ConditionDown; // action by TRUE-->FALSE
////////////////////////////////////////////////////////////////////////////
// CATEGORY: global constants
////////////////////////////////////////////////////////////////////////////
// simulation time limits
//
const double SIMLIB_MINTIME = 0.0;
const double SIMLIB_MAXTIME = 1.0e30;
////////////////////////////////////////////////////////////////////////////
// CATEGORY: global variables ...
extern Entity *const &Current; // active (now running) entity
// step limits of numerical integration method
extern const double &MinStep; // minimal step size
extern const double &StepSize; // actual step size
extern const double &OptStep; // optimal step size
extern const double &MaxStep; // max. step size
// error params
extern const double &AbsoluteError; // max. abs. error of num. integration
extern const double &RelativeError; // max. rel. error ...
// Phase type --- indicates current phase of experiment
enum SIMLIB_Phase_t {
START, INITIALIZATION, SIMULATION, TERMINATION, ERROREXIT
};
// phase of experiment
extern const SIMLIB_Phase_t &Phase; // for user checking ### remove?
////////////////////////////////////////////////////////////////////////////
// CATEGORY: global functions ...
inline void Init(double t0, double t1=SIMLIB_MAXTIME) // initialization
{
extern void SIMLIB_Init(double t0, double t1, unsigned version);
SIMLIB_Init(t0,t1,__SIMLIB__); // consistency check...
}
void SetStep(double dtmin, double dtmax); // set integration step interval
inline void SetStep(double dt) { SetStep(dt,dt); } // set fixed integration step
void SetAccuracy(double abserr, double relerr); // max. error
void SetAccuracy(double relerr); // rel. error
void Run(); // simulation run (experiment)
void Stop(); // stops the simulation run
void Abort(); // end of program
void Error(const char *fmt, ...); // print message & end of program
int _Print(const char *fmt, ...);// non-fatal error messages (stdout)
int Print(const char *fmt, ...); // for Output methods, can be redirected
int Print(const double x); // output double
int Print(const double x, const double y);
int Print(const double x, const double y, const double x);
void SetOutput(const char *name); // redirection of Output(), Print()
void ContractStep(); // request for shorter step of num. integ.
void ContractStep(double time); // request for step end at given time
////////////////////////////////////////////////////////////////////////////
// CATEGORY: pseudorandom generators
//
void RandomSeed(long seed=1537L);// initialize random number seed
double Random(); // base uniform generator 0-0.999999...
// default Random can be replaced by user-defined base generator:
void SetBaseRandomGenerator(double (*new_gen)());
// all following generators depend on Random()
double Beta(double th, double fi, double min, double max);
double Erlang(double alfa, int beta);
double Exponential(double mv);
double Gama(double alfa, double beta);
int Geom(double q);
int HyperGeom(double p, int n, int m);
double Logar(double mi, double delta);
int NegBinM(double p,int m);
int NegBin(double q, int k);
double Normal(double mi, double sigma);
int Poisson(double lambda);
double Rayle(double delta);
double Triag(double mod, double min, double max);
double Uniform(double l, double h);
double Weibul(double lambda, double alfa);
////////////////////////////////////////////////////////////////////////////
// CATEGORY: basics
////////////////////////////////////////////////////////////////////////////
//! base of class hierarchy in SIMLIB
//
class SimObject {
enum _Flags { _ALLOCATED = 1 }; // internal flags
protected:
const char * _name;
unsigned _flags;
public:
SimObject();
virtual ~SimObject();
void *operator new(size_t size); // allocate object, set _flags
void operator delete(void *ptr); // deallocate
virtual void Output(); // print object to default output
virtual const char *Name(); // object name
bool HasName() const { return _name !=0; }
void SetName(const char *name); // assign the name
bool IsAllocated() const { return _flags & _ALLOCATED; }
private:
SimObject(SimObject&); // disable operation
void operator= (SimObject&); // disable operation
};
////////////////////////////////////////////////////////////////////////////
//! base class for all double-linked list items
//
class Link : public SimObject {
Link(Link&); // disable operation
void operator= (Link&); // disable operation
Link *pred; // previous object in List
Link *succ; // next object in List
List *head; // pointer to List (if any)
friend class List; // only list can access pred,succ,head
protected:
Link(Link *p, Link *s, List *h);
public:
Link();
virtual ~Link();
virtual void Into(List *l); // insert last
virtual void Out(); // remove from list
List *where() { return head; } // where is linked TODO: rename
virtual bool isInQueue() { return where()!=NULL; } // in queue
};
////////////////////////////////////////////////////////////////////////////
// CATEGORY: discrete blocks
//! entity/process priority values
enum {
LOWEST_PRIORITY = 0,
HIGHEST_PRIORITY = 255,
DEFAULT_PRIORITY = LOWEST_PRIORITY
};
typedef unsigned char EntityPriority_t; // process priority
typedef unsigned char ServicePriority_t; // service priority (see Facility)
////////////////////////////////////////////////////////////////////////////
//! abstract base class of all active entities
//
class Entity : public Link {
Entity(const Entity&); //## disable
Entity&operator=(const Entity&); //## disable
protected:
static unsigned long _Number; // current number of entities
unsigned long _Ident; // unique identification of entity
// next will be changed/removed:
// Queue stores insertion time for statistics:
friend class Queue; // ### remove
double _MarkTime; // beginning of waiting in queue ###!!!
// Facility and Store use these data
friend class Facility;
friend class Store;
union {
double _RestTime; // rest of time of interrupted service (Facility) ###
unsigned long _ReqCapacity; // required store capacity of Store
};
ServicePriority_t _SPrio; // priority of service (in Facility) ###
public:
typedef EntityPriority_t Priority_t;
Priority_t Priority; // priority of the entity
Entity(Priority_t p = DEFAULT_PRIORITY);
virtual ~Entity();
operator Entity* () { return this; }
virtual const char *Name();
virtual void Activate(); // activate now
virtual void Activate(double t); // activate in time t (schedule)
virtual void Passivate(); // deactivation
// virtual void Wait(double dtime); // wait dtime time units
virtual void Terminate(); // end of behavior and remove entity
bool Idle() { return _Ev==0; } // is not scheduled
void Cancel() { Terminate(); }
// virtual void Into(Queue *q); // insert into queue
virtual void Out(); // remove from queue
private:
void *_Ev; // points into calendar, if scheduled
virtual void _Run() = 0; // run entity behavior
// friends:
friend class Calendar; // internal class
friend class EventNotice; // internal calendar class
friend void SIMLIB_DoActions(); // internal function - event dispatch
};
// global functions:
inline void Activate(Entity *e) { e->Activate(); } // activate entity e
inline void Passivate(Entity *e) { e->Passivate(); } // passivate entity e
////////////////////////////////////////////////////////////////////////////
#define WaitUntil(expr) while(_WaitUntil(expr));
////////////////////////////////////////////////////////////////////////////
//! abstract base class for processes
//
class Process : public Entity {
Process(const Process&); //## disable
Process&operator=(const Process&); //## disable
char * volatile _p; // stack contents
volatile unsigned int _size; // size of stack contents
jmp_buf _ProcStatus; // stack status (for longjmp)
enum ProcessStatus_t { _PREPARED=1, _RUNNING, _INTERRUPTED, _TERMINATED };
unsigned char _status;
#ifdef NEW_WULIST
bool _wait_until;
void _WaitUntilRemove();
friend class WaitUntilList;
#endif
bool isCurrent() { return (_status==_RUNNING); } // called from _Run()
bool Terminated() { return (_status==_TERMINATED); } // zombie...
virtual void _Run(); // point of activation
public:
Process(Priority_t p=DEFAULT_PRIORITY);
virtual ~Process();
virtual void Behavior() = 0; // behavior description
virtual void Output(); // print object
virtual const char *Name(); // name of object
virtual void Activate(); // activate now
virtual void Activate(double t); // activate in time t (schedule)
virtual void Passivate(); // sleeping process (deactivation)
virtual void Wait(double dtime); // wait dtime interval
bool _WaitUntil(bool test); // wait for condition (slow!)
void Interrupt(); // perform test of WaitUntil list ###
virtual void Terminate(); // end of process
// move to global level, use Current ???type check problem
void Seize(Facility &f, ServicePriority_t sp=0); //
void Release(Facility &f); //
void Enter(Store &s, unsigned long ReqCap=1); //
void Leave(Store &s, unsigned long ReqCap=1); //
virtual void Into(Queue &q); // insert into queue
};
////////////////////////////////////////////////////////////////////////////
//! abstract base class for events
//
class Event : public Entity {
virtual void _Run();
public:
Event(Priority_t p=DEFAULT_PRIORITY);
virtual ~Event();
virtual void Output(); // print object
virtual const char *Name();
virtual void Behavior() = 0; // behavior description
// inherited: Activate, Passivate, Cancel==Terminate
};
////////////////////////////////////////////////////////////////////////////
//! objects of this class call global function periodically
// (typicaly used for output)
//
class Sampler: public Event {
Sampler(const Sampler&); //## disable
Sampler&operator=(const Sampler&); //## disable
static Sampler *First; // list of objects
Sampler *Next; // next object
protected:
void (*function)();
double last; // last sample -- prevents Stop() from sample duplication
double step; // step of sampling
bool on; // switch on/off
virtual void Behavior(); // behavior description
public:
Sampler(void (*pf)(), double dt=0.0);
virtual ~Sampler();
virtual void Output(); // print object
void Start(); // start + sample
void Stop(); // sample + stop
void Sample(); // performs sample (function call)
double SetStep(double dt=0.0); // change step
double GetStep() const { return step; }
private:
static void InitAll(); // initialize all samplers (Init)
static void ActivateAll(); // start all samplers (Run)
};
////////////////////////////////////////////////////////////////////////////
// CATEGORY: discrete blocks - pasive
#ifdef new_version
////////////////////////////////////////////////////////////////////////////
//! abstract base class of all statistics
//
class aStat : public SimObject {
protected:
double t0; // time of initialization
double min; // minimal recorded value
double max; // maximal recorded value
unsigned long n; // number of values recorded
public:
aStat();
aStat(const char *name);
~aStat();
virtual void Clear() = 0; // initialize
virtual void Output(); // print statistic
virtual void operator () (double x) = 0; // record value
virtual double MeanValue() = 0; // compute mean value
double Min() const { /* test n==0 */ return min; }
double Max() const { /* test n==0 */ return max; }
unsigned long Number() const { return n; }
double StartTime() const { return t0; }
};
#endif
////////////////////////////////////////////////////////////////////////////
//! statistics
//
class Stat : public SimObject {
protected:
double sx; // sum of values
double sx2; // sum of value square
double min; // min value
double max; // max value
unsigned long n; // number of values recorded
public:
Stat();
Stat(const char *name);
~Stat();
virtual void Clear(); // initialize
void operator () (double x); // record the value
// Stat &operator = (Stat &x); // ??? semantics
// Stat &operator += (Stat &x);
virtual void Output(); // print statistic
unsigned long Number() const { return n; }
double Min() const { /* TODO: test n==0 */ return min; }
double Max() const { /* test n==0 */ return max; }
double Sum() const { return sx; }
double SumSquare() const { return sx2; }
double MeanValue() const;
double StdDev() const;
};
////////////////////////////////////////////////////////////////////////////
//! time dependent statistic
//
class TStat : public SimObject {
protected:
double sxt; // sum of x*time
double sx2t; // sum of squares
double min; // min value x
double max; // max value x
double t0; // time of initialization
double tl; // last record time
double xl; // last recorded value x
unsigned long n; // number of records
friend class Facility; // needs to correct n -- TODO: remove
friend class Store;
friend class Queue;
public:
TStat(double initval=0.0);
TStat(const char *name, double initval=0.0);
~TStat();
virtual void Clear(double initval=0.0); // initialize
virtual void Output(); // print
virtual void operator () (double x); // record value
unsigned long Number() const { return n; }
double Min() const { /*TODO: only if(n>0)*/ return min; }
double Max() const { return max; }
double Sum() const { return sxt; }
double SumSquare() const { return sx2t; }
double StartTime() const { return t0; }
double LastTime() const { return tl; }
double LastValue() const { return xl; }
double MeanValue() const;
};
////////////////////////////////////////////////////////////////////////////
//! list of Link* items, uses data from Link
//
class List : public Link { // circular list of Link items
List(List&); // disable
void operator= (List&); // disable
static Link *next(Link*p) { return p->succ; }
static Link *previous(Link*p) { return p->pred; }
unsigned n; // number of objects in list
protected: //## repair
class iterator {
// next two lines can be removed ##
Link *p; // position in List
public:
iterator(const iterator&x): p(x.p) {}
iterator &operator=(const iterator&x) { p = x.p; return *this; }
iterator(Link *pos) : p(pos) {}
iterator &operator++() { p = List::next(p); return *this; }
iterator &operator--() { p = List::previous(p); return *this; }
iterator operator++(int) {
Link *tmp = p; p = List::next(p); return tmp;
}
iterator operator--(int) {
Link *tmp = p; p = List::previous(p); return tmp;
}
Link * operator*() const { return p; }
bool operator != (iterator q) const { return p!=q.p; }
bool operator == (iterator q) const { return p==q.p; }
}; // iterator
friend class iterator;
public:
List();
List(const char *_name);
~List();
virtual void Output(); // print
// should be renamed:
void InsFirst(Link *e); // insert operations
void InsLast (Link *e);
void PredIns(Link *e, iterator pos); //
void PostIns(Link *e, iterator pos); //
Link *GetFirst(); // removing operations
Link *GetLast(); //
virtual Link *Get(iterator pos); // remove at position
// unsigned Length() { return size(); } // COMPATIBILITY
// virtual void Clear() { clear(); } // remove all items
// new-style:
unsigned size() const { return n; }
iterator begin() { return Link::succ; }
iterator end() { return this; }
Link *front() { return empty() ? 0 : Link::succ; }
Link *back() { return empty() ? 0 : Link::pred; }
bool empty() { return Link::succ == this; }
void clear();
}; // List
////////////////////////////////////////////////////////////////////////////
//! priority queue
//
class Queue : public List { // don't inherit interface for now
//##repair
friend class Facility;
friend class Store;
public:
typedef List::iterator iterator;
TStat StatN;
Stat StatDT; // statistics
Queue();
Queue(const char *_name);
~Queue();
virtual const char *Name();
virtual void Output(); // print
operator Queue* () { return this; } // allows Queue instead Queue*
iterator begin() { return List::begin(); }
iterator end() { return List::end(); }
Entity *front() { return (Entity*)List::front(); }
Entity *back() { return (Entity*)List::back(); }
void clear();
// size(), empty() inherited
// backward COMPATIBILITY
void Clear() { clear(); }
bool Empty() { return empty(); }
unsigned Length() { return size(); }
// to rename:
void Insert (Entity *e); // priority insert
void InsFirst(Entity *e);
void InsLast (Entity *e);
void PredIns (Entity *e, iterator pos); // insert at position
void PostIns (Entity *e, iterator pos);
Entity *Get(iterator pos); // remove entity
Entity *GetFirst();
Entity *GetLast();
};
////////////////////////////////////////////////////////////////////////////
//! histogram and statistics
//
class Histogram : public SimObject {
Histogram(const Histogram&); // ## disable
Histogram&operator=(const Histogram&); // ## disable
protected:
unsigned *dptr; // value array
double low; // low bound
double step; // interval width
unsigned count; // number of intervals
public:
Stat stat; // statistics
Histogram();
Histogram(double low, double step, unsigned count=10);
Histogram(const char *_name, double low, double step, unsigned count=10);
~Histogram();
virtual void Output(); // print
void Init(double low, double step, unsigned count);
void operator () (double x); // record value x
virtual void Clear(); // initialize (zero) value array
double Low() const { return low; }
double High() const { return low + step*count; }
double Step() const { return step; }
unsigned Count() const { return count; }
unsigned operator [](unsigned i) const; // # of items in interval[i]
};
////////////////////////////////////////////////////////////////////////////
//! (SOL-like) facility
//
class Facility : public SimObject {
Facility(const Facility&); // ## disable
Facility&operator=(const Facility&); // ## disable
unsigned char _Qflag;
public:
Entity *in; // entity in service
Queue *Q1; // input queue
Queue *Q2; // interrupted requests queue
TStat tstat; // stat
Facility();
Facility(const char *_name);
Facility(Queue *_queue1);
Facility(const char *_name, Queue *_queue1);
virtual ~Facility();
virtual void Output(); // print output
operator Facility* () { return this; }
void SetQueue(Queue *queue1); // change input queue
bool OwnQueue() const; // test
bool Busy() const { return in!=0; }
unsigned QueueLen() const { return Q1->size(); }
virtual void Seize(Entity *e, ServicePriority_t sp=DEFAULT_PRIORITY);
virtual void Release(Entity *e);
virtual void QueueIn(Entity *e, ServicePriority_t sp); // go into queue Q1
virtual void Clear(); // init
protected:
virtual void QueueIn2(Entity *e); // do into Q2
};
////////////////////////////////////////////////////////////////////////////
//! (SOL-like) store
//
class Store : public SimObject {
Store(const Store&); // ## disable
Store&operator=(const Store&); // ## disable
unsigned char _Qflag;
unsigned long capacity; // capacity of store
unsigned long used; // used capacity
public:
Queue *Q;
TStat tstat; // statistics
Store();
Store(unsigned long _capacity);
Store(const char *_name, unsigned long _capacity);
Store(unsigned long _capacity, Queue *queue);
Store(const char *_name, unsigned long _capacity, Queue *queue);
virtual ~Store();
virtual void Output(); // print
operator Store* () { return this; }
void SetCapacity(unsigned long _capacity);
void SetQueue(Queue *queue);
unsigned long Free() const { return capacity - used; } // free capacity
unsigned long Used() const { return used; } // used capacity
unsigned long Capacity() const { return capacity; } // max capacity
bool Full() const { return Free() == 0; } // store is full
bool Empty() const { return Used() == 0; } // store is empty
bool OwnQueue();
unsigned QueueLen() const { return Q->size(); }
virtual void Enter(Entity *e, unsigned long rcap); // allocate
virtual void Leave(unsigned long rcap); // deallocate
virtual void QueueIn(Entity *e, unsigned long c); // go into queue
virtual void Clear(); // init
};
////////////////////////////////////////////////////////////////////////////
// CATEGORY: continuous blocks
//
////////////////////////////////////////////////////////////////////////////
//! abstract base class for all blocks
//
class aBlock : public SimObject { // base class
};
////////////////////////////////////////////////////////////////////////////
//! abstract base for continuous blocks with single output
//
class aContiBlock : public aBlock { // abstract continuous block
aContiBlock(const aContiBlock&); // disable copy ctr
void operator= (aContiBlock&); // disable assignment
virtual void Eval() {}; // evaluate without loop detection
protected:
bool isEvaluated; // flag for loop checking ###---
public:
aContiBlock(): isEvaluated(false) {}
virtual void _Eval(); // evaluate with loop detection
virtual double Value() = 0; // output value
};
////////////////////////////////////////////////////////////////////////////
//! constant block - value can't be changed
//
class Constant : public aContiBlock {
const double value;
public:
Constant(double x) : value(x) {}
virtual double Value () { return value; }
};
////////////////////////////////////////////////////////////////////////////
//! block: variable (value can be changed)
//
class Variable : public aContiBlock {
double value;
public:
Variable(double x=0) : value(x) {}
Variable &operator= (double x) { value = x; return *this; }
virtual double Value () { return value; }
};
////////////////////////////////////////////////////////////////////////////
//! variable parameter (can't be changed at simulation time)
//
class Parameter : public aContiBlock {
double value;
public:
Parameter(double x) : value(x) {}
Parameter &operator= (double x) { value = x; return *this; } // add test ###!!!
virtual double Value () { return value; }
};
// time values:
extern const double & StartTime; // time of simulation start
extern const double & NextTime; // next-event time
extern const double & EndTime; // time of simulation end
//!WARNING: Time cannot be used in block expressions!
extern const double & Time; // model time (is NOT the block)
extern aContiBlock & T; // model time (continuous block)
////////////////////////////////////////////////////////////////////////////
//! continuous block connection (transparent reference)
//
class Input { // small objects, without virtual methods
aContiBlock *bp;
public:
Input(const Input &in): bp(in.bp) {} // copy reference
Input(aContiBlock &cb): bp(&cb) {} // reference to block
Input(aContiBlock *cb): bp(cb) {} // pointer to block
Input(const double c): bp(new Constant(c)) {} // expression of type double
// WARNING: using C++ variables in block expressions --> constant
Input Set(Input i) { Input p=bp; bp=i.bp; /*LoopCheck();*/ return p; }
double Value() const { return bp->Value(); } // get value
bool operator ==(aContiBlock *p) const { return bp==p; } // for tests only! ###
Input &operator= (const Input&x) { bp = x.bp; return *this; }
};
////////////////////////////////////////////////////////////////////////////
//! base for continuous blocks with single input and algebraic loop check
//
class aContiBlock1 : public aContiBlock {
Input input;
public:
aContiBlock1(Input i);
double InputValue() { return input.Value(); }
};
////////////////////////////////////////////////////////////////////////////
//! reference to block expression
//
struct Expression : public aContiBlock1 {
Expression(Input i) : aContiBlock1(i) {}
double Value() { return InputValue(); }
};
////////////////////////////////////////////////////////////////////////////
//! base for continuous blocks with two inputs
//
class aContiBlock2 : public aContiBlock {
Input input1;
Input input2;
public:
aContiBlock2(Input i1, Input i2);
double Input1Value() { return input1.Value(); }
double Input2Value() { return input2.Value(); }
};
////////////////////////////////////////////////////////////////////////////
//! base for continuous blocks vith three inputs and algebraic loop check
//
class aContiBlock3 : public aContiBlock {
Input input1;
Input input2;
Input input3;
public:
aContiBlock3(Input i1, Input i2, Input i3);
double Input1Value() { return input1.Value(); }
double Input2Value() { return input2.Value(); }
double Input3Value() { return input3.Value(); }
};
////////////////////////////////////////////////////////////////////////////
//! internal
// IntegratorContainer - container of integrators,
// it is a singleton
//
class IntegratorContainer {
private:
static dlist<Integrator*> * ListPtr; // list of integrators
IntegratorContainer(); // forbid constructor
static dlist<Integrator*> * Instance(void); // return list (& create)
public:
typedef dlist<Integrator*>::iterator iterator;
// is there any integrator in the list? (e.g. list is not empty)
static bool isAny(void) {
return ListPtr!=0 && !(ListPtr->empty());
}
// # of elements in the list
static size_t Size(void) {
return (ListPtr!=0) ? (ListPtr->size()) : 0;
}
// return iterator to the first element
static iterator Begin(void) {
return Instance()->begin();
}
// return iterator to the end (not to the last element!)
static iterator End(void) {
return Instance()->end();
}
static iterator Insert(Integrator* ptr); // insert element into container
static void Erase(iterator it); // exclude element
static void InitAll(); // initialize all
static void EvaluateAll(); // evaluate all integrators
static void LtoN(); // last -> now
static void NtoL(); // now -> last
}; // class IntegratorContainer
////////////////////////////////////////////////////////////////////////////
//! internal
// StatusContainer -- container of status variables,
// it is a singleton
//
class StatusContainer {
private:
static dlist<Status*>* ListPtr; // list of integrators
StatusContainer(); // forbid constructor
static dlist<Status*>* Instance(void); // return list (& create)
public:
typedef dlist<Status*>::iterator iterator;
// is there any integrator in the list? (e.g. list is not empty)
static bool isAny(void) {
return ListPtr!=0 && !(ListPtr->empty());
}
// # of elements in the list
static size_t Size(void) {
return (ListPtr!=0) ? (ListPtr->size()) : 0;
}
// return iterator to the first element
static iterator Begin(void) {
return Instance()->begin();
}
// return iterator to the end (not to the last element!)
static iterator End(void) {
return Instance()->end();
}
static iterator Insert(Status* ptr); // insert element into container
static void Erase(iterator it); // exclude element
static void InitAll(); // initialize all
static void ClearAllValueOK(); // invalidate values of all items
static void EvaluateAll(); // evaluate all integrators
static void LtoN(); // last -> now
static void NtoL(); // now -> last
}; // class StatusContainer
////////////////////////////////////////////////////////////////////////////
//! internal
// IntegrationMethod
// Abstract base class for integration methods
//
class IntegrationMethod {
IntegrationMethod(const IntegrationMethod&); // ## disable
IntegrationMethod&operator=(const IntegrationMethod&); // ## disable
private:
static IntegrationMethod* CurrentMethodPtr; // method used at present
static dlist<IntegrationMethod*>* MthLstPtr; // list of registrated methods
dlist<IntegrationMethod*>::iterator ItList; // position in the list
char* Name; // the name of the method
protected: //## repair
class Memory; // forward declaration
friend class Memory;
private: //## repair
size_t PrevINum; // # of integrators in previous step
dlist<Memory*> MList; // list of auxiliary memories
static dlist<Memory*> * PtrMList; // pointer to list being filled
IntegrationMethod(); // forbid implicit constructor
IntegrationMethod(IntegrationMethod&); // forbid implicit copy-constructor
static bool Prepare(void); // prepare system for integration step
static void Iterate(void); // compute new values of state blocks
static void Summarize(void); // set up new state after integration
protected:
static bool IsEndStepEvent; // flag - will be event at the end of the step?
typedef IntegratorContainer::iterator Iterator; // iterator of intg. list
static Iterator FirstIntegrator(void) { // it. to first integrator in list
return IntegratorContainer::Begin();
}
static Iterator LastIntegrator(void) { // it. to last integrator in list
return IntegratorContainer::End();
}
static bool StateCond(void); // check on changes of state conditions
static IntegrationMethod* SearchMethod(const char* name); // find method
/* memory of auxiliary values */
class Memory {
Memory(const Memory&); // ## disable
Memory&operator=(const Memory&); // ## disable
private:
static const size_t page_size; // size of memory page
double *arr; // array
size_t mem_size; // allocated memory size
Memory(Memory&); // forbid copy constructor
void operator= (Memory&); // disable the operation
dlist<Memory*>::iterator it_list; // position in list
dlist<Memory*> * ListPtr; // which list is memory in
public:
Memory(dlist<Memory*> * PtrList=PtrMList); // create empty memory
virtual ~Memory();
double& operator[](size_t ind) { // access the element of the array
// dprintf(("IntegrationMethod::Memory::operator[](%lu) = %g",
// (long unsigned)ind, arr[ind]));
return arr[ind];
}
virtual void Resize(size_t cs); // change size, content will be undefined!
}; // class Memory
public:
IntegrationMethod(const char* name); // registrate method and name it
virtual ~IntegrationMethod(); // destructor unregistrates method
virtual bool IsSingleStep(void)=0; // is it a single-step method?
virtual void TurnOff(void); // turn off integration method
virtual void Integrate(void) = 0; // the method does integration
virtual bool PrepareStep(void); // prepare object for integration step
virtual void Resize(size_t size); // resize all memories to given size
static void StepSim(void); // single step of numerical integration method
static void IntegrationDone(void) { // terminate integration
CurrentMethodPtr->TurnOff(); // suspend present method
}
static void SetMethod(const char* name); // set method which will be used
static char* const GetMethod(void) { // get name of method which is used
return CurrentMethodPtr->Name;
}
// auxiliary functions (interface) for user to add own method
static void InitStep(double step_frag); // initialize step
static void FunCall(double step_frag); // evaluate y'(t) = f(t, y(t))
static void SetOptStep(double opt_step) { // set optimal step size
extern double SIMLIB_OptStep; // available without including internal.h
SIMLIB_OptStep = opt_step;
}
static void SetStepSize(double step_size) { // set step size
extern double SIMLIB_StepSize; // available without including internal.h
SIMLIB_StepSize = step_size;
}
static bool IsConditionFlag(void) { // wer any changes of condition vector?
extern bool SIMLIB_ConditionFlag; // available without ... blah, blah
return SIMLIB_ConditionFlag;
}
static int GetErrNo(void) { // return # of errors
extern int SIMLIB_ERRNO;
return SIMLIB_ERRNO;
}
static void SetErrNo(int num) { // set # of errors
extern int SIMLIB_ERRNO;
SIMLIB_ERRNO = num;
}
}; // class IntegrationMethod
////////////////////////////////////////////////////////////////////////////
//! internal
// single-step integration method
//
class SingleStepMethod : public IntegrationMethod {
private:
// flag: single-step method is used to start multi-step method
// (e. g. to restrict step increasing)
bool StartMode;
public:
SingleStepMethod(const char* name) : // initialize method and registrate it
IntegrationMethod(name),
StartMode(false)
{ /* NOTHING */ }
virtual void Integrate(void) = 0; // the method does integration
virtual bool IsSingleStep(void) { // it's a single-step method
return true;
}
void SetStartMode(bool start_mode) { // set flag on/off
StartMode=start_mode;
}
bool IsStartMode(void) { // is method used to start multi-step method?
return StartMode;
}
}; // class SingleStepMethod
////////////////////////////////////////////////////////////////////////////
//! internal
// multi-step integration method
//
class MultiStepMethod : public IntegrationMethod {
MultiStepMethod(const MultiStepMethod&); // ## disable
MultiStepMethod&operator=(const MultiStepMethod&); // ## disable
private:
char* SlaveName; // the name of the method used for starting
SingleStepMethod* Slave_Ptr; // pointer to the method used for starting
protected:
SingleStepMethod* SlavePtr(void); // return pointer to the starting method
public:
// initialize method
MultiStepMethod(const char* name, const char* slave_name);
~MultiStepMethod(); // destructor frees dynamic data
virtual bool IsSingleStep(void) { // it's a multi-step method
return false;
}
// set starting method for given method
static void SetStarter(const char* name, const char* slave_name);
// set starting method for the method
virtual void SetStarter(const char* slave_name);
// get the name of starting method of given method
static char* const GetStarter(const char* name);
virtual bool PrepareStep(void); // prepare the object for the step
virtual void Integrate(void) = 0; // the method does integration
virtual void TurnOff(void); // turn off method & its slave
}; // class MultiStepMethod
////////////////////////////////////////////////////////////////////////////
//! internal
// Abstract base class for integration methods
// with status auxiliary memories
//
class StatusMethod : public SingleStepMethod {
private:
StatusMethod(); // forbid implicit constructor
StatusMethod(StatusMethod&); // forbid implicit copy-constructor
size_t PrevStatusNum; // # of status variables in previous step
dlist<Memory*> StatusMList; // list of auxiliary memories
static dlist<Memory*>* PtrStatusMList; // pointer to list being filled
protected:
typedef StatusContainer::iterator StatusIterator; // iterator of intg. list
static StatusIterator FirstStatus(void) { // it. to first status in list
return StatusContainer::Begin();
}
static StatusIterator LastStatus(void) { // it. to last status in list
return StatusContainer::End();
}
//## repair
friend class EULER;
friend class RKE;
/* memory of auxiliary status values */
class StatusMemory : public Memory {
private:
StatusMemory(StatusMemory&); // forbid copy constructor
void operator= (StatusMemory&); // disable the operation
public:
// create empty memory
StatusMemory(dlist<Memory*>* PtrList=PtrStatusMList) : Memory(PtrList) { }
// free dynamic data
virtual ~StatusMemory() { }
}; // class StatusMemory
friend class StatusMemory;
// store state of integrators and status variables
static void StoreState(Memory& di, Memory& si, StatusMemory& xi);
// restore state of integrators and status variables
static void RestoreState(double dthlf, Memory& di,
Memory& si, StatusMemory& xi);
// move startpoint to given state
static void GoToState(Memory& di, Memory& si, StatusMemory& xi);
public:
StatusMethod(const char* name); // initailization
virtual ~StatusMethod() { } // free dynamic datas
virtual void TurnOff(void); // turn off integration method
virtual void Integrate(void) = 0; // the method does integration
virtual bool PrepareStep(void); // prepare integration step
virtual void StatusResize(size_t size); // resize status memories
}; // StatusMethod
////////////////////////////////////////////////////////////////////////////
// interface for class IntegrationMethod & its descendants
//
//! select the integration method
//! Methods: "abm4", "euler", "fw", "rke"(default), "rkf3", "rkf5", "rkf8"
inline void SetMethod(const char* name)
{
IntegrationMethod::SetMethod(name);
}
//! get the name of the method which is used
inline char* const GetMethod(void)
{
return IntegrationMethod::GetMethod();
}
//! set the method which will be used to start given multistep method
inline void SetStarter(const char* name, const char* slave_name)
{
MultiStepMethod::SetStarter(name, slave_name);
}
//! set the method which will be used to start currently used multistep method
inline void SetStarter(const char* slave_name)
{
MultiStepMethod::SetStarter(IntegrationMethod::GetMethod(), slave_name);
}
//! get the name of the method which is used to start given multistep method
inline char* const GetStarter(const char* name)
{
return MultiStepMethod::GetStarter(name);
}
//! get the name of the method which is used
//! to start currently used multistep method
inline char* const GetStarter(void)
{
return MultiStepMethod::GetStarter(IntegrationMethod::GetMethod());
}
////////////////////////////////////////////////////////////////////////////
//! block for numerical integration
//
class Integrator : public aContiBlock { // integrator
private:
Integrator &operator= (const Integrator &x); // disable assignment
double dd; // input value: y'=f(t,y)
double ddl; // the same from previous step
double ss; // status: y = S f(t,y) dt
double ssl; // the same from previous step
protected:
Input input; // input expression: f(t,y)
double initval; // initial value: y(t0)
void CtrInit();
IntegratorContainer::iterator it_list; // position in list of integrators
public:
Integrator(); // implicit CTR (input = 0)
Integrator(Input i, double initvalue=0);
Integrator(Integrator &i, double initvalue=0); // copy-ctr
~Integrator();
void Init(double initvalue); // set value
void Init() { Init(initval); } // set initial value
void Set(double value); // set value
Integrator &operator= (double x) { Set(x); return *this; }
Input SetInput(Input inp) { return input.Set(inp); }
void Eval(); // input evaluation
double Value(); // status
double InputValue() { return input.Value(); }
// interface
void Save(void) { ddl=dd; ssl=ss; } // save status
void Restore(void) { dd=ddl; ss=ssl; } // restore saved status
void SetState(double s) { ss=s; }
double GetState(void) { return ss; }
void SetOldState(double s) { ssl=s; }
double GetOldState(void) { return ssl; }
void SetDiff(double d) { dd=d; }
double GetDiff(void) { return dd; }
void SetOldDiff(double d) { ddl=d; }
double GetOldDiff(void) { return ddl; }
};
////////////////////////////////////////////////////////////////////////////
//! status variables (memory)
//
class Status : public aContiBlock1 { // state-variables
Status(Status&); // disable copy ctor
void operator= (Status&); // disable assignment
protected:
double initval; // initial value
bool ValueOK; // valid-flag ###
void CtrInit();
StatusContainer::iterator it_list; // position in list of status variables
public:
double st; // status
double stl; // status from previous step
Status(Input i, double initvalue=0);
~Status();
void Init(double initvalue); // value initialization
void Init() { Init(initval); }
void Set(double value); // set status of block
virtual void Eval(); // block evaluation
virtual double Value(); // block status
// interface
void Save() { stl = st; } // save status
void Restore(); // restore saved status
void SetState(double s) { st=s; }
double GetState(void) { return st; }
void SetOldState(double s) { stl=s; }
double GetOldState(void) { return stl; }
void SetValid(bool flag) { ValueOK = flag; } // set valid flag
};
////////////////////////////////////////////////////////////////////////////
//! nonlinear block - hysteresis
//
class Hyst : public Status {
protected:
double p1,p2;
double y1,y2;
double tga;
virtual void Eval(); // block evaluation
public:
Hyst(Input i, double p1, double p2, double y1, double y2, double tga);
};
typedef Hyst Hysteresis; // alias name
////////////////////////////////////////////////////////////////////////////
//! nonlinear block - backlash
//
class Blash : public Status { // backlash
protected:
double p1,p2;
double tga;
public:
Blash(Input i, double p1, double p2, double tga);
virtual void Eval(); // block evaluation
};
typedef Blash Backlash;
////////////////////////////////////////////////////////////////////////////
//! relay detects exact time of switch
//
class Relay : public Status { // general relay block
protected:
double p1,p2,p3,p4; // points on x-axis
double y1,y2; // points on y-axis
public:
Relay(Input i, double p1, double p2, double p3, double p4,
double y1, double y2);
virtual void Eval(); // block evaluation
};
////////////////////////////////////////////////////////////////////////////
// Continuous block arithmetic operators
//
//! binary operators:
Input operator + (Input a, Input b);
Input operator - (Input a, Input b);
Input operator * (Input a, Input b);
Input operator / (Input a, Input b);
//! unary operators:
Input operator - (Input a);
//! functions:
Input Abs(Input x); // abs(x) absolute value
Input Sin(Input x); // sin(x)
Input Cos(Input x); // cos(x)
Input Tan(Input x); // tan(x)
Input ASin(Input x); // asin(x)
Input ACos(Input x); // acos(x)
Input ATan(Input x); // atan(x)
Input ATan2(Input y, Input x); // atan2(y,x)
Input Exp(Input x); // exp(x) e ** x
Input Log10(Input x); // log10(x)
Input Ln(Input x); // ln(x) natural logarithm
Input Pow(Input x, Input y); // pow(x,y) x ** y
Input Sqr(Input x); // square x * x
Input Sqrt(Input x); // square root
Input Min(Input x, Input y); // minimum
Input Max(Input x, Input y); // maximum
Input Sign(Input x); // signum ###warning-steps-not-detected
////////////////////////////////////////////////////////////////////////////
//! block parametrized by function with single argument
//
class Function : public aContiBlock1 {
Function(const Function&); // ## disable
Function&operator=(const Function&); // ## disable
double (*f)(double); // pointer to function
public:
Function(Input i, double (*pf)(double));
virtual double Value();
};
////////////////////////////////////////////////////////////////////////////
//! block parametrized by function with two arguments
//
class Function2 : public aContiBlock2 {
Function2(const Function2&); // ## disable
Function2&operator=(const Function2&); // ## disable
double (*f)(double,double); // pointer to function
public:
Function2(Input i1, Input i2, double (*pf)(double,double));
virtual double Value();
};
////////////////////////////////////////////////////////////////////////////
// CATEGORY: state conditions
////////////////////////////////////////////////////////////////////////////
//! abstract base class for all state-event blocks
//
class aCondition : public aBlock {
static aCondition *First; // list of all conditions
aCondition *Next; // next condition in list
void operator= (aCondition&); // disable operation
aCondition(aCondition&); // disable operation
public:
aCondition();
~aCondition();
static void InitAll();
static void SetAll();
static void TestAll();
static void AllActions();
static bool isAny();
virtual bool Value()=0; // state of condition
private:
virtual void Init()=0;
virtual void SetNewStatus()=0;
virtual bool Test()=0; // test of condition
virtual void Action()=0; // state event action
};
////////////////////////////////////////////////////////////////////////////
//! change detector - Boolean version (int)
//
class Condition : public aCondition { // state condition
Input in; // block input
unsigned char cc; // state
unsigned char ccl; // old state
virtual void Init();
virtual void SetNewStatus();
protected:
virtual bool Test(); // test function (input >= 0.0)
bool Up() { return ccl<cc; } // change: FALSE->TRUE
bool Down() { return ccl>cc; } // change: TRUE->FALSE
bool Change() { return ccl!=cc; } // both changes
public:
Condition(Input i);
~Condition();
virtual bool Value() { return cc; } // status
Input SetInput(Input inp) { return in.Set(inp); } // change input block
virtual void Action()=0; // state event
};
////////////////////////////////////////////////////////////////////////////
//! detector of FALSE-->TRUE
//
class ConditionUp : public Condition { // state event on FALSE-->TRUE change
public:
ConditionUp(Input i) : Condition(i) {}
bool Test() { return Condition::Test() && Up(); }
virtual void Action()=0; // state event
};
////////////////////////////////////////////////////////////////////////////
//! detector of TRUE-->FALSE
//
class ConditionDown : public Condition { // state event on TRUE-->FALSE change
public:
ConditionDown(Input i) : Condition(i) {}
bool Test() { return Condition::Test() && Down(); }
virtual void Action()=0; // state event
};
////////////////////////////////////////////////////////////////////////////
// CATEGORY: non-linear blocks
////////////////////////////////////////////////////////////////////////////
//! limitation
//
class Lim : public aContiBlock1 {
protected:
double low, high; // limits
double tgalpha; //
public:
Lim(Input in, double l, double h, double tga=1.0);
virtual void _Eval(); // evaluation with loop check
virtual double Value(); // returned value
};
typedef Lim Limitation;
////////////////////////////////////////////////////////////////////////////
//! dead zone
//
class Insv : public aContiBlock1 {
protected:
double low, high; // limits
double tgalpha,tgbeta; //
public:
Insv(Input in, double l, double h, double tga=1.0, double tgb=1.0);
virtual void _Eval(); // evaluation with loop check
virtual double Value(); // returned value
};
typedef Insv DeadZone;
////////////////////////////////////////////////////////////////////////////
//! quantizer
//
class Qntzr : public aContiBlock1 {
protected:
double step; // quantum
public:
Qntzr(Input in, double qstep=1.0);
virtual void _Eval(); // evaluation with loop check
virtual double Value(); // returned value
};
typedef Qntzr Quantizer;
////////////////////////////////////////////////////////////////////////////
//! friction
//
class Frict : public aContiBlock1 {
protected:
double low, high; // limits
double tgalpha; //
public:
Frict(Input in, double l, double h, double tga=1.0);
virtual void _Eval(); // evaluation with loop check
virtual double Value(); // returned value
};
typedef Frict Friction;
////////////////////////////////////////////////////////////////////////////
//! function defined by given table of values
//
//TODO: reimplement with std::vector
class Rline : public aContiBlock1 {
Rline(const Rline&); // ## disable
Rline&operator=(const Rline&); // ## disable
protected:
int n; // table item number
double *tableX; // tabulka X
double *tableY; // tabulka Y
public:
Rline(Input in, int num, double *X, double *Y);
~Rline();
virtual void _Eval(); // evaluation with loop check
virtual double Value(); // returned value
};
////////////////////////////////////////////////////////////////////////////
// CATEGORY: algebraic loop solvers
////////////////////////////////////////////////////////////////////////////
//! abstract base for algebraic loop solvers
//
class AlgLoop : public aContiBlock1 {
protected:
double Eps; // required accuracy
unsigned long MaxIt; // max. number of iterations
double TA; // boundary values of interval
double TB; // (also used for convergency check)
double T0; // initial value
bool was_cycle; // flag for going through loop
int phase; // phase of computation
double root; // root of equation
public:
AlgLoop(Input i, double eps, unsigned long max_it, // constructor
double t_min, double t_max, double t0);
void Set(double eps, unsigned long max_it, // set parameters
double t_min, double t_max, double t0);
void Set(double eps, unsigned long max_it, // set parameters
double t_min, double t_max);
virtual double Value()=0; // returned value
}; // AlgLoop
////////////////////////////////////////////////////////////////////////////
//! solve using iterations
//
class Iterations : public AlgLoop {
public:
Iterations(Input i, double eps, unsigned long max_it,
double t_min, double t_max, double t0):
AlgLoop(i, eps, max_it, t_min, t_max, t0)
{/*nothing*/}
virtual double Value(); // returned value
};
////////////////////////////////////////////////////////////////////////////
//! solve using halving interval method
//
class Halvint : public AlgLoop {
public:
Halvint(Input i, double eps, unsigned long max_it,
double t_min, double t_max):
AlgLoop(i, eps, max_it, t_min, t_max, t_min)
{/*nothing*/}
virtual double Value(); // returned value
};
////////////////////////////////////////////////////////////////////////////
//! solve using regula falsi method
//
class RegulaFalsi : public AlgLoop {
double eps_root; // root for force precision test
public:
RegulaFalsi(Input i, double eps, unsigned long max_it,
double t_min, double t_max):
AlgLoop(i, eps, max_it, t_min, t_max, t_min),
eps_root(0)
{/*nothing*/}
virtual double Value(); // returned value
};
////////////////////////////////////////////////////////////////////////////
//! solve using modified Newton's method
//
class Newton : public AlgLoop {
double eps_root; // root for force precision test
double prev_root; // root from previous iteration step
public:
Newton(Input i, double eps, unsigned long max_it,
double t_min, double t_max, double t0):
AlgLoop(i, eps, max_it, t_min, t_max, t0),
eps_root(0),
prev_root(0)
{/*nothing*/}
virtual double Value(); // returned value
};
////////////////////////////////////////////////////////////////////////////
// CATEGORY: global functions
////////////////////////////////////////////////////////////////////////////
// Naming Subsystem --- SimObject names (text identifiers)
// this is system dictionary: relation: objectptr---textname
//
void SetName(SimObject &o, const char *name);
void SetName(SimObject *o, const char *name);
void RemoveName(SimObject &o);
void RemoveName(SimObject *o);
const char *GetName(SimObject &o);
const char *GetName(SimObject *o);
////////////////////////////////////////////////////////////////////////////
// InstallBreak --- set function for checking if user breaks simulation
//
// f is called at each step of simulation
//
void InstallBreak(void (*f)()); // f can call Stop() or Abort()
////////////////////////////////////////////////////////////////////////////
//! basic synchronization tool for processes
//
class Semaphore : public SimObject {
protected:
int n;
public:
Queue Q; // internal quqeue
Semaphore(); // constructor
Semaphore(const char *_name); // with associated name
virtual ~Semaphore();
virtual void Clear(); // initialization
virtual void Output();
virtual void P(); // P operation
virtual void V(); // V operation
operator Semaphore* () { return this; }
};
////////////////////////////////////////////////////////////////////////////
//! synchronization tool for processes
//
class Barrier : public SimObject {
Barrier(const Barrier&); // ## disable
Barrier&operator=(const Barrier&); // ## disable
protected:
Entity **waiting; // array of waiting entities (fixed size)
unsigned n; // number of waiting entities (actual number)
const unsigned maxn; // barrier capacity ### (size)
void Init(); // initialization
public:
Barrier(unsigned N);
Barrier(const char *_name, unsigned N);
virtual ~Barrier();
// void ChangeCapacity(unsigned N); // change N
unsigned Capacity() const { return maxn; } // barrier size
virtual void Enter(Entity *e); // entity arrival
virtual int Break(); // activate all waiting entities
virtual void Clear(); // initialization
virtual void Output(); // print
operator Barrier* () { return this; }
};
#endif // ifndef __SIMLIB_H
// end of simlib.h
syntax highlighted by Code2HTML, v. 0.9.1