SIMLIB/C++ 3.09
Loading...
Searching...
No Matches
intg.cc
Go to the documentation of this file.
1/////////////////////////////////////////////////////////////////////////////
2//! \file intg.cc Integrator block implementation
3//
4// Copyright (c) 1991-2004 Petr Peringer
5//
6// This library is licensed under GNU Library GPL. See the file COPYING.
7//
8
9//
10// description: continuous system - integrator & status variables
11//
12// clas Integrator and Status implementation
13//
14
15
16////////////////////////////////////////////////////////////////////////////
17// interface
18
19#include "simlib.h"
20#include "internal.h"
21
22#include <cmath>
23
24
25////////////////////////////////////////////////////////////////////////////
26// implementation
27
28namespace simlib3 {
29
31
33
34double SIMLIB_StepStartTime; //!< last step time
35double SIMLIB_DeltaTime; //!< Time-SIMLIB_StepStartTime
36
37double SIMLIB_OptStep; //!< optimal step
38double SIMLIB_MinStep=1e-10; //!< minimal step
39double SIMLIB_MaxStep=1; //!< max. step
40double SIMLIB_StepSize; //!< actual step
41
42double SIMLIB_AbsoluteError=0; //!< absolute error
43double SIMLIB_RelativeError=0.001; //!< relative error
44
45// step limits
46const double &MinStep=SIMLIB_MinStep; //!< minimal integration step
47const double &MaxStep=SIMLIB_MaxStep; //!< maximal integration step
48const double &StepSize=SIMLIB_StepSize; //!< actual integration step
49const double &OptStep=SIMLIB_OptStep; //!< optimal integration step
50//const double &StepStartTime=SIMLIB_StepStartTime; // start of step
51
52// error params
53const double &AbsoluteError=SIMLIB_AbsoluteError; //!< max. abs. error of integration
54const double &RelativeError=SIMLIB_RelativeError; //!< max. rel. error
55
56bool SIMLIB_DynamicFlag = false; //!< in dynamic section
57
58bool SIMLIB_ContractStepFlag = false; //!< requests shorter step
59double SIMLIB_ContractStep = SIMLIB_MAXTIME; //!< requested step size
60
61
62////////////////////////////////////////////////////////////////////////////
63/// contract step of integration
65 SIMLIB_ContractStepFlag = true; // contract to default value (usually 1/2)
66}
67
68
69////////////////////////////////////////////////////////////////////////////
70/// contract step of integration to end step time
71/// @param time expected end of step time
72void ContractStep(double time)
73{ // parameter is required end step time
74 SIMLIB_ContractStepFlag = true; // flag
75 double newCS = time - SIMLIB_StepStartTime;
76 if (newCS<SIMLIB_ContractStep)
77 SIMLIB_ContractStep = newCS; // can be only less
78 if (newCS<SIMLIB_MinStep)
80}
81
82
83////////////////////////////////////////////////////////////////////////////
84/// \var bool SIMLIB_ResetStatus
85/// flag set if there is a need for integration method restart
86bool SIMLIB_ResetStatus = false;
87
88
89////////////////////////////////////////////////////////////////////////////
90// SetStep -- set range of step
91//
92void SetStep(double _dtmin, double _dtmax)
93{
94 SIMLIB_MinStep = _dtmin;
95 SIMLIB_MaxStep = _dtmax;
97// if (SIMLIB_MinStep/SIMLIB_MaxStep < 1e-12) SIMLIB_error(SetStepError2);
98// if(MinStep/tend<1e-15) SIMLIB_error(InitMinStepError); // moznost chyby ???
99 Dprintf(("SetStep: StepSize = %g .. %g ",SIMLIB_MinStep,SIMLIB_MaxStep));
100}
101
102
103////////////////////////////////////////////////////////////////////////////
104// SetAccuracy -- set allowed error of integration method
105//
106void SetAccuracy(double _abserr, double _relerr)
107{
108 SIMLIB_AbsoluteError = _abserr;
109 if(_relerr>1) _relerr=1; // 100% error is maximum
110 SIMLIB_RelativeError = _relerr;
112 Dprintf(("SetAccuracy: maxerror = %g + %g * X ",
114}
115
116void SetAccuracy(double relerr)
117{
118 SetAccuracy(0,relerr);
119}
120
121
122////////////////////////////////////////////////////////////////////////////
123// SIMLIB_ContinueInit -- initialize continuous subsystem
124//
126{
127 SIMLIB_OptStep = SIMLIB_MaxStep; // initial step size
129 SIMLIB_DeltaTime = 0.0;
132 || Condition::isAny())
133 { // ------------------- initialize status --------------------
136 Condition::InitAll(); // really needed ???
137 SIMLIB_Dynamic(); // initial state evaluation
138 SIMLIB_DynamicFlag = true;
139 Condition::TestAll(); // evaluate conditions
140 SIMLIB_DynamicFlag = false;
141 Condition::SetAll(); // set state
142 }
143}
144
145
146/*************************************************/
147/***** Outline members of class Integrator *****/
148/*************************************************/
149
150
151////////////////////////////////////////////////////////////////////////////
152// Integrator::CtrInit -- integrator initialization
153//
156 SIMLIB_error(CantCreateIntg); // can't in 'dynamic section' !!!
157 }
158 // put integrator into list & retain position of it
160 // Dprintf(("constructor: Integrator[%p] #%d", this, Number));
161 SIMLIB_ResetStatus = true; //???????????????????????????????
162}
163
164
165////////////////////////////////////////////////////////////////////////////
166// Integrator::Integrator -- integrator creation
167//
168
169/// dummy input with zero value
171
172/// constructor for special cases (arrays of integrators)
173/// Input can be set using method Integrator::Set
175{
176 Dprintf(("Integrator[%p]::Integrator() #%d",
177 this, IntegratorContainer::Size()+1));
178 CtrInit();
179 initval = 0.0;
180}
181
182/// constructor
183/// @param i input block expression
184/// @param initvalue initial value (optional, default=0)
185Integrator::Integrator(Input i, double initvalue) : input(i)
186{
187 Dprintf(("Integrator[%p]::Integrator(Input,%g) #%d",
188 this, initvalue, IntegratorContainer::Size()+1));
189 CtrInit();
190 initval = initvalue;
191}
192
193
194////////////////////////////////////////////////////////////////////////////
195/// special copy constructor needed for i1(i2) connection
196Integrator::Integrator(Integrator &i, double initvalue) :
197 aContiBlock(),
198 input(i)
199{
200 Dprintf(("Integrator[%p]::Integrator(Integrator[%p],%g) #%d",
201 this, &i, initvalue, IntegratorContainer::Size()+1));
202 CtrInit();
203 initval = initvalue;
204}
205
206
207////////////////////////////////////////////////////////////////////////////
208/// destructor removes integrator from list
210{
211 Dprintf(("destructor: Integrator[%p] #%d",
214 SIMLIB_error(CantDestroyIntg); // can't in 'dynamic section' !!!
215 }
216 IntegratorContainer::Erase(it_list); // remove integrator from list
217}
218
219
220////////////////////////////////////////////////////////////////////////////
221/// set initial value of integrator
222void Integrator::Init(double initvalue) {
223 ss = initval = initvalue;
224 SIMLIB_ResetStatus = true; // if in simulation
225}
226
227
228////////////////////////////////////////////////////////////////////////////
229/// set the integrator status value (step change)
230void Integrator::Set(double value)
231{
232 ss = value;
233 SIMLIB_ResetStatus = true; // always
234}
235
236
237////////////////////////////////////////////////////////////////////////////
238/// evaluate integrator input
240{
241// Dprintf(("START: Integrator[%p]::Eval()", this));
242 dd = InputValue();
243// Dprintf(("STOP: Integrator[%p]::Eval() %g ", this, dd));
244}
245
246
247////////////////////////////////////////////////////////////////////////////
248/// get integrator status (output value)
250{
251// Dprintf(("Integrator[%p]::Value() = %g ", this, ss));
252 return ss;
253}
254
255
256#if 0
257const char *Integrator::Name() const
258{
259 if (HasName())
260 return _name;
261 else
262 return SIMLIB_create_tmp_name("Integrator{%p}", this);
263}
264#endif
265
266/**********************************************************/
267/***** Outline members of class IntegratorContainer *****/
268/**********************************************************/
269
270/// list of integrators
271std::list<Integrator*>* IntegratorContainer::ListPtr=NULL;
272
273////////////////////////////////////////////////////////////////////////////
274// IntegratorContainer::Instance
275// return pointer to list, also create list if it is not created
276//
277std::list<Integrator*>* IntegratorContainer::Instance(void)
278{
279 Dprintf(("IntegratorContainer::Instance()(%p)",ListPtr));
280 if(ListPtr==NULL) { // list is not created
281 ListPtr = new std::list<Integrator*>; // create it
282 Dprintf(("created: %p", ListPtr));
283 }
284 return ListPtr;
285} // Instance
286
287
288////////////////////////////////////////////////////////////////////////////
289// IntegratorContainer::Insert
290// insert element into random (any) position in the container
291//
293{
294 Dprintf(("IntegratorContainer::Insert(%p)",ptr));
295 (void)Instance(); // create list if it is not created
296 return ListPtr->insert(ListPtr->end(),ptr); // insert element
297} // Insert
298
299
300////////////////////////////////////////////////////////////////////////////
301// IntegratorContainer::Erase - exclude element from container
302//
304{
305 Dprintf(("IntegratorContainer::Erase(...)"));
306 if(ListPtr!=NULL) { // list is created
307 ListPtr->erase(it); // exclude element
308 }
309} // Erase
310
311
312////////////////////////////////////////////////////////////////////////////
313// IntegratorContainer::NtoL
314// save statuses of blocks -- Now to Last
315//
317{
318 Dprintf(("IntegratorContainer::NtoL()"));
319 if(ListPtr!=NULL) { // list is created
320 iterator end_it=ListPtr->end();
321 for(iterator ip=ListPtr->begin(); ip!=end_it; ++ip) {
322 (*ip)->Save();
323 }
324 }
325} // NtoL
326
327
328////////////////////////////////////////////////////////////////////////////
329// IntegratorContainer::LtoN -- restore saved statuses
330//
332{
333 Dprintf(("IntegratorContainer::LtoN)"));
334 if(ListPtr!=NULL) { // list is created
335 iterator end_it=ListPtr->end();
336 for(iterator ip=ListPtr->begin(); ip!=end_it; ++ip) {
337 (*ip)->Restore();
338 }
339 }
340} // LtoN
341
342
343////////////////////////////////////////////////////////////////////////////
344// IntegratorContainer::InitAll() -- initialize all integrators
345//
347{
348 Dprintf(("IntegratorContainer::InitAll)"));
349 if(ListPtr!=NULL) { // list is created
350 iterator end_it=ListPtr->end();
351 for(iterator ip=ListPtr->begin(); ip!=end_it; ++ip) {
352 (*ip)->SetState(0.0); // zero values
353 (*ip)->SetDiff(0.0);
354 (*ip)->Init();
355 }
356 }
357} // InitAll
358
359
360////////////////////////////////////////////////////////////////////////////
361// static IntegratorContainer::EvaluateAll -- without loop detection
362//
364{
365 Dprintf(("IntegratorContainer::EvaluateAll)"));
366 if(ListPtr!=NULL) { // list is created
367 iterator end_it=ListPtr->end();
368 for(iterator ip=ListPtr->begin(); ip!=end_it; ++ip) {
369 (*ip)->Eval(); // evaluate inputs ...
370 }
371 }
372} // EvaluateAll
373
374
375/*********************************************/
376/***** Outline members of class Status *****/
377/*********************************************/
378
379
380////////////////////////////////////////////////////////////////////////////
381// Status::CtrInit -- status variable initialization
382//
385 SIMLIB_error(CantCreateStatus); // can't in 'dynamic section' !!!
386 }
387 // put status into list & retain position of it
389 ValueOK = false; // important !!! ###
390 Dprintf(("constructor: Status[%p] #%d", this, StatusContainer::Size()));
391 SIMLIB_ResetStatus = true; // ??????????
392}
393
394
395////////////////////////////////////////////////////////////////////////////
396// Status::Status -- initialize status variable
397//
398Status::Status(Input i, double initvalue): aContiBlock1(i)
399{
400 CtrInit();
401 initval = initvalue;
402}
403
404
405////////////////////////////////////////////////////////////////////////////
406// Status::~Status -- remove status block from list
407//
409 Dprintf(("destructor: Status[%p] #%d", this, StatusContainer::Size()));
412 }
413 StatusContainer::Erase(it_list); // remove status variable from list
414}
415
416
417////////////////////////////////////////////////////////////////////////////
418/// set initial value
419void Status::Init(double initvalue)
420{
421 st = initval = initvalue;
422 ValueOK = false; // important !!! ??? ###
423}
424
425
426////////////////////////////////////////////////////////////////////////////
427/// set state variable value (step change)
428//
429void Status::Set(double value)
430{
431 st = value;
432 ValueOK = false; // important !!!
433}
434
435
436////////////////////////////////////////////////////////////////////////////
437// Restore -- restore saved status
438//
440{
441 st = stl;
442 ValueOK = false; // important !!!
443}
444
445
446////////////////////////////////////////////////////////////////////////////
447/// value of state variable
449{
450 if(!ValueOK)
451 _Eval(); // if not, evaluate
452 return st; // return status
453}
454
455
456#if 0
457const char *Status::Name() const
458{
459 if (HasName())
460 return _name;
461 else
462 return SIMLIB_create_tmp_name("Status{%p}", this);
463}
464#endif
465
466////////////////////////////////////////////////////////////////////////////
467// virtual void Status::Eval() -- evaluate without loop detection ###
468//
470{
471 st = InputValue(); // input ---> output
472 ValueOK = true;
473}
474
475
476/******************************************************/
477/***** Outline members of class StatusContainer *****/
478/******************************************************/
479
480/// list of status variables
481std::list<Status*>* StatusContainer::ListPtr=NULL;
482
483
484////////////////////////////////////////////////////////////////////////////
485// StatusContainer::Instance
486// return pointer to list, also create list if it is not created
487//
488std::list<Status*>* StatusContainer::Instance(void)
489{
490 Dprintf(("StatusContainer::Instance()(%p)",ListPtr));
491 if(ListPtr==NULL) { // list is not created
492 ListPtr = new std::list<Status*>; // create it
493 Dprintf(("created: %p", ListPtr));
494 }
495 return ListPtr;
496} // Instance
497
498
499////////////////////////////////////////////////////////////////////////////
500// StatusContainer::Insert
501// insert element into random (any) position in the container
502//
504{
505 Dprintf(("StatusContainer::Insert(%p)",ptr));
506 (void)Instance(); // create list if it is not created
507 return ListPtr->insert(ListPtr->end(),ptr); // insert element
508} // Insert
509
510
511////////////////////////////////////////////////////////////////////////////
512// StatusContainer::Erase - exclude element from container
513//
515{
516 Dprintf(("StatusContainer::Erase(...)"));
517 if(ListPtr!=NULL) { // list is created
518 ListPtr->erase(it); // exclude element
519 }
520} // Erase
521
522
523////////////////////////////////////////////////////////////////////////////
524// StatusContainer::NtoL
525// save statuses of blocks -- Now to Last
526//
528{
529 Dprintf(("StatusContainer::NtoL()"));
530 if(ListPtr!=NULL) { // list is created
531 iterator end_it=ListPtr->end();
532 for(iterator sp=ListPtr->begin(); sp!=end_it; ++sp) {
533 (*sp)->Save();
534 }
535 }
536} // NtoL
537
538
539////////////////////////////////////////////////////////////////////////////
540// StatusContainer::LtoN -- restore saved statuses
541//
543{
544 Dprintf(("StatusContainer::LtoN)"));
545 if(ListPtr!=NULL) { // list is created
546 iterator end_it=ListPtr->end();
547 for(iterator sp=ListPtr->begin(); sp!=end_it; ++sp) {
548 (*sp)->Restore();
549 }
550 }
551} // LtoN
552
553
554////////////////////////////////////////////////////////////////////////////
555// StatusContainer::InitAll() -- initialize all status variables
556//
558{
559 Dprintf(("StatusContainer::InitAll)"));
560 if(ListPtr!=NULL) { // list is created
561 iterator end_it=ListPtr->end();
562 for(iterator sp=ListPtr->begin(); sp!=end_it; ++sp) {
563 (*sp)->SetState(0.0); // zero values
564 (*sp)->Init();
565 }
566 }
567} // InitAll
568
569
570////////////////////////////////////////////////////////////////////////////
571// static StatusContainer::EvaluateAll -- with loop detection
572//
574{
575 Dprintf(("StatusContainer::EvaluateAll)"));
576 if(ListPtr!=NULL) { // list is created
577 iterator end_it=ListPtr->end();
578 for(iterator sp=ListPtr->begin(); sp!=end_it; ++sp) {
579 (*sp)->_Eval(); // evaluate inputs with loop detection
580 }
581 }
582} // EvaluateAll
583
584
585////////////////////////////////////////////////////////////////////////////
586// StatusContainer::ClearAllValueOK
587// invalidate values of all status variables
588//
590{
591 Dprintf(("StatusContainer::EvaluateAll)"));
592 if(ListPtr!=NULL) { // list is created
593 iterator end_it=ListPtr->end();
594 for(iterator sp=ListPtr->begin(); sp!=end_it; ++sp) {
595 (*sp)->SetValid(false); // invalidate values
596 }
597 }
598} // EvaluateAll
599
600
601}
602// end
603
block: constant (value can not be changed)
Definition: simlib.h:848
continuous block connection (transparent reference) wrapper for pointer to objects of aContiBlock der...
Definition: simlib.h:895
static iterator Insert(Integrator *ptr)
Definition: intg.cc:292
static bool isAny(void)
Definition: simlib.h:994
static void InitAll()
Definition: intg.cc:346
static void Erase(iterator it)
Definition: intg.cc:303
static void NtoL()
Definition: intg.cc:316
static void EvaluateAll()
Definition: intg.cc:363
static std::list< Integrator * > * ListPtr
list of integrators
Definition: simlib.h:988
std::list< Integrator * >::iterator iterator
Definition: simlib.h:992
static void LtoN()
Definition: intg.cc:331
static std::list< Integrator * > * Instance(void)
Definition: intg.cc:277
static size_t Size(void)
Definition: simlib.h:998
block for numerical integration input is derivative, output is state
Definition: simlib.h:1288
double Value() override
the state of integrator
Definition: intg.cc:249
double initval
initial value: y(t0)
Definition: simlib.h:1296
void Set(double value)
set the integrator status value (step change)
Definition: intg.cc:230
Integrator()
constructor for special cases (arrays of integrators) Input can be set using method Integrator::Set
Definition: intg.cc:174
double InputValue()
current input value
Definition: simlib.h:1314
IntegratorContainer::iterator it_list
position in list of integrators
Definition: simlib.h:1298
void Eval() override
evaluate integrator input
Definition: intg.cc:239
void CtrInit()
Definition: intg.cc:154
~Integrator()
destructor removes integrator from list
Definition: intg.cc:209
void Init()
use preset initial value
Definition: simlib.h:1306
bool HasName() const
Definition: simlib.h:321
virtual std::string Name() const
get object name
Definition: object.cc:134
static std::list< Status * > * Instance(void)
Definition: intg.cc:488
static iterator Insert(Status *ptr)
Definition: intg.cc:503
static void NtoL()
Definition: intg.cc:527
std::list< Status * >::iterator iterator
Definition: simlib.h:1027
static void EvaluateAll()
Definition: intg.cc:573
static std::list< Status * > * ListPtr
list of status variables
Definition: simlib.h:1023
static void LtoN()
Definition: intg.cc:542
static void InitAll()
Definition: intg.cc:557
static size_t Size(void)
Definition: simlib.h:1033
static bool isAny(void)
Definition: simlib.h:1029
static void ClearAllValueOK()
Definition: intg.cc:589
static void Erase(iterator it)
Definition: intg.cc:514
State variables (memory) base for blocks with internal state (Relay, ...)
Definition: simlib.h:1335
void Restore()
Definition: intg.cc:439
virtual void Eval() override
evaluate without loop detection
Definition: intg.cc:469
void Init()
Definition: simlib.h:1347
void Set(double value)
set state variable value (step change)
Definition: intg.cc:429
double st
status
Definition: simlib.h:1342
virtual double Value() override
value of state variable
Definition: intg.cc:448
double stl
status from previous step
Definition: simlib.h:1343
Status(Input i, double initvalue=0)
Definition: intg.cc:398
double initval
initial value
Definition: simlib.h:1337
void CtrInit()
Definition: intg.cc:383
StatusContainer::iterator it_list
position in list of status variables
Definition: simlib.h:1340
static void InitAll()
Definition: cond.cc:56
static void TestAll()
Definition: cond.cc:123
static bool isAny()
Definition: cond.cc:70
static void SetAll()
Definition: cond.cc:65
base for continuous blocks with single input and algebraic loop check
Definition: simlib.h:940
double InputValue()
Definition: simlib.h:944
abstract base for continuous blocks with single output suitable for expression-tree building and eval...
Definition: simlib.h:832
virtual void _Eval()
evaluate block (with loop detection)
Definition: continuous.cc:48
@ CantDestroyIntg
Definition: errors.h:42
@ SetAccuracyError
Definition: errors.h:21
@ SetStepError
Definition: errors.h:18
@ CantCreateStatus
Definition: errors.h:43
@ CantDestroyStatus
Definition: errors.h:44
@ CantCreateIntg
Definition: errors.h:41
Internal header file for SIMLIB/C++.
#define Dprintf(f)
Definition: internal.h:100
Implementation of class CalendarList interface is static - using global functions in SQS namespace.
Definition: algloop.cc:32
const double & StepSize
actual integration step
Definition: intg.cc:48
void SIMLIB_ContinueInit()
Definition: intg.cc:125
bool SIMLIB_DynamicFlag
in dynamic section
Definition: intg.cc:56
const double & RelativeError
max. rel. error
Definition: intg.cc:54
void SIMLIB_error(const enum _ErrEnum N)
print error message and abort program
Definition: error.cc:38
double SIMLIB_RelativeError
relative error
Definition: intg.cc:43
void SetAccuracy(double _abserr, double _relerr)
set max.
Definition: intg.cc:106
double SIMLIB_OptStep
optimal step
Definition: intg.cc:37
SIMLIB_IMPLEMENTATION
Definition: algloop.cc:34
void SetStep(double _dtmin, double _dtmax)
Set integration step interval.
Definition: intg.cc:92
const double & MaxStep
maximal integration step
Definition: intg.cc:47
bool SIMLIB_ContractStepFlag
requests shorter step
Definition: intg.cc:58
const double & AbsoluteError
max. abs. error of integration
Definition: intg.cc:53
std::string SIMLIB_create_tmp_name(const char *fmt,...)
printf-like function to create temporary name (the length of temporary names is limited) used only ...
Definition: name.cc:80
Constant SIMLIB_Integrator_0input(0)
dummy input with zero value
void SIMLIB_Dynamic()
performs evaluation of integrators and status blocks
Definition: continuous.cc:35
bool SIMLIB_ResetStatus
flag set if there is a need for integration method restart
Definition: intg.cc:86
double SIMLIB_Time
Definition: internal.h:209
const double & MinStep
minimal integration step
Definition: intg.cc:46
double SIMLIB_AbsoluteError
absolute error
Definition: intg.cc:42
double SIMLIB_MinStep
minimal step
Definition: intg.cc:38
double SIMLIB_MaxStep
max. step
Definition: intg.cc:39
int SIMLIB_ERRNO
Definition: intg.cc:32
const double & OptStep
optimal integration step
Definition: intg.cc:49
double SIMLIB_ContractStep
requested step size
Definition: intg.cc:59
double SIMLIB_StepStartTime
last step time
Definition: intg.cc:34
const double SIMLIB_MAXTIME
maximum time (1e30 works for float, too)
Definition: simlib.h:148
double SIMLIB_StepSize
actual step
Definition: intg.cc:40
double SIMLIB_DeltaTime
Time-SIMLIB_StepStartTime.
Definition: intg.cc:35
void ContractStep()
contract step of integration
Definition: intg.cc:64
Main SIMLIB/C++ interface.