MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
drive.cc
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/mbdyn/base/drive.cc,v 1.60 2017/01/12 14:46:09 masarati Exp $ */
2 /*
3  * MBDyn (C) is a multibody analysis code.
4  * http://www.mbdyn.org
5  *
6  * Copyright (C) 1996-2017
7  *
8  * Pierangelo Masarati <masarati@aero.polimi.it>
9  * Paolo Mantegazza <mantegazza@aero.polimi.it>
10  *
11  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
12  * via La Masa, 34 - 20156 Milano, Italy
13  * http://www.aero.polimi.it
14  *
15  * Changing this copyright notice is forbidden.
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation (version 2 of the License).
20  *
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */
31 
32 /* drivers */
33 
34 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
35 
36 #include "drive.h"
37 
40 
41 /* Drive - begin */
42 
43 Drive::Drive(unsigned int uL, const DriveHandler* pDH)
44 : WithLabel(uL), pDrvHdl(pDH)
45 {
46  NO_OP;
47 }
48 
49 
51  NO_OP;
52 }
53 
54 /* Drive - end */
55 
56 
57 /* DriveHandler - begin */
58 
60 : Parser(mp),
61 pTime(0),
62 pTimeStep(0),
63 pStep(0),
64 pVar(0),
65 pXCurr(0),
66 pXPrimeCurr(0),
67 iCurrStep(0),
68 Meter(0),
69 Rand(0),
70 ClosestNext(0),
71 SH(0)
72 {
73 #ifdef USE_MULTITHREAD
74  pthread_mutexattr_t ma;
75  pthread_mutexattr_init(&ma);
76  pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE);
77  int rc = pthread_mutex_init(&parser_mutex, &ma);
78  pthread_mutexattr_destroy(&ma);
79  if (rc) {
80  silent_cerr("DriveHandler::DriveHandler(): mutex init failed"
81  << std::endl);
83  }
84 #endif /* USE_MULTITHREAD */
85 
86  NamedValue *v;
87 
88  /* Inserisce la variabile Time nella tabella dei simboli; sara'
89  * mantenuta aggiornata dal DriveHandler */
90  v = Parser.GetSymbolTable().Get("Time");
91  if (v == 0) {
92  pTime = Parser.GetSymbolTable().Put("Time", Real(0));
93  if (pTime == 0) {
94  silent_cerr("DriveHandler::DriveHandler(): "
95  "error while inserting symbol 'Time'"
96  << std::endl);
98  }
99 
100  } else {
101  if (!v->IsVar()) {
102  silent_cerr("Symbol 'Time' must be a variable"
103  << std::endl);
105  }
106  pTime = dynamic_cast<Var *>(v);
107  }
108 
109  /* Inserisce la variabile TimeStep nella tabella dei simboli; sara'
110  * mantenuta aggiornata dal DriveHandler */
111  v = Parser.GetSymbolTable().Get("TimeStep");
112  if (v == 0) {
113  pTimeStep = Parser.GetSymbolTable().Put("TimeStep", Real(-1.));
114  if (pTimeStep == 0) {
115  silent_cerr("DriveHandler::DriveHandler(): "
116  "error while inserting symbol 'TimeStep'"
117  << std::endl);
119  }
120 
121  } else {
122  if (!v->IsVar()) {
123  silent_cerr("Symbol 'TimeStep' must be a variable"
124  << std::endl);
126  }
127  pTimeStep = dynamic_cast<Var *>(v);
128  }
129 
130  /* Inserisce la variabile Step nella tabella dei simboli; sara'
131  * mantenuta aggiornata dal DriveHandler */
132  v = Parser.GetSymbolTable().Get("Step");
133  if (v == 0) {
134  pStep = Parser.GetSymbolTable().Put("Step", Int(-1));
135  if (pStep == 0) {
136  silent_cerr("DriveHandler::DriveHandler(): "
137  "error while inserting symbol 'Step'"
138  << std::endl);
140  }
141 
142  } else {
143  if (!v->IsVar()) {
144  silent_cerr("Symbol 'Step' must be a variable"
145  << std::endl);
147  }
148  pStep = dynamic_cast<Var *>(v);
149  }
150 
151  /* Inserisce la variabile Var nella tabella dei simboli; sara'
152  * mantenuta aggiornata dai DriveCaller attraverso il DriveHandler */
153  v = Parser.GetSymbolTable().Get("Var");
154  if (v == 0) {
155  pVar = Parser.GetSymbolTable().Put("Var", Real(0));
156  if (pVar == 0) {
157  silent_cerr("DriveHandler::DriveHandler(): "
158  "error while insterting symbol 'Var'"
159  << std::endl);
161  }
162 
163  } else {
164  if (!v->IsVar()) {
165  silent_cerr("Symbol 'Var' must be a variable"
166  << std::endl);
168  }
169  pVar = dynamic_cast<Var *>(v);
170  }
171 
172  /* Calcola il seed di riferimento per i numeri random */
173  srand(time(NULL));
174 }
175 
177 {
178 #ifdef USE_MULTITHREAD
179  pthread_mutex_destroy(&parser_mutex);
180 #endif /* USE_MULTITHREAD */
181 
182  for (std::vector<MyMeter *>::iterator i = Meter.begin();
183  i != Meter.end(); ++i)
184  {
185  SAFEDELETE(*i);
186  }
187 
188  for (std::vector<MyRand *>::iterator i = Rand.begin();
189  i != Rand.end(); ++i)
190  {
191  SAFEDELETE(*i);
192  }
193 
194  for (std::vector<MyClosestNext*>::iterator i = ClosestNext.begin();
195  i != ClosestNext.end(); ++i)
196  {
197  SAFEDELETE(*i);
198  }
199 
200  for (std::vector<MySH *>::iterator i = SH.begin();
201  i != SH.end(); ++i)
202  {
203  SAFEDELETE(*i);
204  }
205 }
206 
207 void
209  const integer& s)
210 {
211  /* Setta la variabile Time nella tabella dei simboli */
212  ASSERT(pTime != 0);
213  pTime->SetVal(dt);
214 
215  /* Setta la variabile TimeStep nella tabella dei simboli */
216  if (dts >= 0.) {
217  ASSERT(pTimeStep != 0);
218  pTimeStep->SetVal(dts);
219  }
220 
221  /* Setta la variabile Step nella tabella dei simboli */
222  if (s >= 0) {
223  ASSERT(pStep != 0);
224  pStep->SetVal(s);
225 
226  /* in case of new step */
227  if (s != iCurrStep) {
228  ASSERT(iCurrStep + 1 == s);
229  iCurrStep = s;
230 
231  for (std::vector<MyMeter *>::iterator i = Meter.begin();
232  i != Meter.end(); ++i)
233  {
234  (*i)->Set();
235  }
236 
237  for (std::vector<MyRand *>::iterator i = Rand.begin();
238  i != Rand.end(); ++i)
239  {
240  (*i)->Set();
241  }
242 
243  for (std::vector<MyClosestNext*>::iterator i = ClosestNext.begin();
244  i != ClosestNext.end(); ++i)
245  {
246  (*i)->Set();
247  }
248 
249  for (std::vector<MySH *>::iterator i = SH.begin();
250  i != SH.end(); ++i)
251  {
252  (*i)->Set();
253  }
254  }
255  }
256 }
257 
258 
259 void
261  const VectorHandler& XPrimeCurr)
262 {
263  pXCurr = const_cast<VectorHandler *>(&XCurr);
264  pXPrimeCurr = const_cast<VectorHandler *>(&XPrimeCurr);
265 }
266 
267 integer
269 {
270  MyRand* pmr = 0;
271  integer iNumber = Rand.size();
273  MyRand,
274  MyRand((unsigned int)iNumber, iSteps, rand()));
275  Rand.push_back(pmr);
276 
277  return iNumber;
278 }
279 
280 integer
282 {
283  MyMeter* pmm = 0;
284  integer iNumber = Meter.size();
286  MyMeter,
287  MyMeter((unsigned int)iNumber, iSteps));
288  Meter.push_back(pmm);
289 
290  return iNumber;
291 }
292 
293 integer
296 {
297  MyClosestNext* pmc = 0;
298  integer iNumber = ClosestNext.size();
301  MyClosestNext((unsigned int)iNumber, this,
302  pIncrement, dStartTime));
303  ClosestNext.push_back(pmc);
304 
305  return iNumber;
306 }
307 
308 
309 integer
310 DriveHandler::iSHInit(const DriveCaller *pFunc, const DriveCaller *pTrigger,
311  const doublereal dVal0)
312 {
313  MySH* pms = 0;
314  integer iNumber = SH.size();
316  MySH,
317  MySH((unsigned int)iNumber, pFunc, pTrigger, dVal0));
318  SH.push_back(pms);
319 
320  return iNumber;
321 }
322 
323 const DriveCaller *
325 {
326  return SH[iNumber]->pGetFunc();
327 }
328 
329 const DriveCaller *
331 {
332  return SH[iNumber]->pGetTrigger();
333 }
334 
335 const doublereal
337 {
338  return SH[iNumber]->dGetVal0();
339 }
340 
341 void
343 {
345 }
346 
347 
348 void
350 {
351  ASSERT(pVar != 0);
352  pVar->SetVal(dVar);
353 }
354 
355 
356 #ifndef USE_EE
359 {
360  doublereal d;
361 
362 #ifdef USE_MULTITHREAD
363  // FIXME: risk recursive lock
364  pthread_mutex_lock(&parser_mutex);
365 #endif /* USE_MULTITHREAD */
366 
367  try {
368  d = Parser.GetLastStmt(InStr);
369 
370  } catch (MBDynErrBase& e) {
371  silent_cerr("StringDrive: " << e.what() << std::endl);
372 
373 #ifdef USE_MULTITHREAD
374  pthread_mutex_unlock(&parser_mutex);
375 #endif /* USE_MULTITHREAD */
376 
377  throw e;
378 
379 #if 0
380  } catch (ErrGeneric e) {
381  silent_cerr("StringDrive: " << e.what() << std::endl);
382  throw e;
383 #endif
384 
385  } catch (...) {
386  silent_cerr("StringDrive generic error" << std::endl);
387 
388 #ifdef USE_MULTITHREAD
389  pthread_mutex_unlock(&parser_mutex);
390 #endif /* USE_MULTITHREAD */
391 
392  throw;
393  }
394 
395 #ifdef USE_MULTITHREAD
396  pthread_mutex_unlock(&parser_mutex);
397 #endif /* USE_MULTITHREAD */
398 
399  return d;
400 }
401 #endif // ! USE_EE
402 
403 DriveHandler::MyRand::MyRand(unsigned int uLabel, integer iS, integer iR)
404 : MyMeter(uLabel, iS), iRand(iR)
405 {
406  NO_OP;
407 }
408 
410 {
411  NO_OP;
412 }
413 
414 DriveHandler::MyMeter::MyMeter(unsigned int uLabel, integer iS)
415 : WithLabel(uLabel), iSteps(iS), iCurr(0)
416 {
417  NO_OP;
418 }
419 
421 {
422  NO_OP;
423 }
424 
426  const DriveHandler *pDH,
427  const DriveCaller *pIncrement,
429 : WithLabel(uLabel), pDH(pDH), Increment(pIncrement), bMustSetNext(false), dNext(dStartTime)
430 {
431  NO_OP;
432 }
433 
435 {
436  NO_OP;
437 }
438 
439 DriveHandler::MySH::MySH(unsigned int uLabel,
440  const DriveCaller *pFunc,
441  const DriveCaller *pTrigger,
442  const doublereal dVal0)
443 : WithLabel(uLabel), dVal0(dVal0), dVal(dVal0), Func(pFunc), Trigger(pTrigger)
444 {
445  NO_OP;
446 }
447 
449 {
450  NO_OP;
451 }
452 
453 const DriveCaller *
455 {
456  return Func.pGetDriveCaller();
457 }
458 
459 const DriveCaller *
461 {
462  return Trigger.pGetDriveCaller();
463 }
464 
465 const doublereal
467 {
468  return dVal0;
469 }
470 
471 /* DriveHandler - end */
472 
473 /* DriveCaller - begin */
474 
476 : pDrvHdl(const_cast<DriveHandler *>(pDH))
477 {
478  NO_OP;
479 }
480 
482 {
483  NO_OP;
484 }
485 
486 void
488 {
489  pDrvHdl = const_cast<DriveHandler *>(pDH);
490 }
491 
492 const DriveHandler *
494 {
495  return pDrvHdl;
496 }
497 
499 DriveCaller::dGetP(const doublereal& dVar) const
500 {
501  /* shouldn't get called if not differentiable,
502  * or should be overridden if differentiable */
504 }
505 
507 {
508  const flag fOut = fToBeOutput();
509 
510  if (fOut & flag(1)) {
512  std::ostream& os = OH.DriveCallers();
513 
514  os << GetLabel();
515 
516  if (fOut & OUTPUT_VALUE) {
517  os << ' ' << dGet();
518  }
519 
520  if (fOut & OUTPUT_DERIVATIVE) {
522 
523  os << ' ' << dGetP();
524  }
525 
526  os << std::endl;
527  }
528  }
529 }
530 
532 {
533  const flag fTrace = fToBeTraced();
534 
535  if (fTrace) {
536  if (OH.UseText(OutputHandler::TRACES)) {
537  std::ostream& os = OH.Traces();
538 
539  os << GetLabel();
540 
541  if (fTrace & TRACE_VALUE) {
542  os << ' ' << dGet();
543  }
544 
545  if (fTrace & TRACE_DERIVATIVE) {
547 
548  os << ' ' << dGetP();
549  }
550 
551  os << std::endl;
552  }
553  }
554 }
555 
556 /* DriveCaller - end */
557 
558 
559 /* NullDriveCaller - begin */
560 
562 : DriveCaller(0)
563 {
564  NO_OP;
565 }
566 
568 {
569  NO_OP;
570 }
571 
572 /* Copia */
573 DriveCaller *
575 {
576  DriveCaller* pDC = 0;
577  SAFENEW(pDC, NullDriveCaller);
578 
579  return pDC;
580 }
581 
582 /* Scrive il contributo del DriveCaller al file di restart */
583 std::ostream&
584 NullDriveCaller::Restart(std::ostream& out) const
585 {
586  return out << "null";
587 }
588 
589 /* NullDriveCaller - end */
590 
591 
592 /* OneDriveCaller - begin */
593 
595 : DriveCaller(0)
596 {
597  NO_OP;
598 }
599 
601 {
602  NO_OP;
603 }
604 
605 /* Copia */
606 DriveCaller *
608 {
609  DriveCaller* pDC = 0;
610  SAFENEW(pDC, OneDriveCaller);
611 
612  return pDC;
613 }
614 
615 /* Scrive il contributo del DriveCaller al file di restart */
616 std::ostream&
617 OneDriveCaller::Restart(std::ostream& out) const
618 {
619  return out << "one";
620 }
621 
622 /* OneDriveCaller - end */
623 
624 
625 /* DriveOwner - begin */
626 
628 : pDriveCaller(const_cast<DriveCaller*>(pDC))
629 {
630  NO_OP;
631 }
632 
634 : pDriveCaller(drive.pDriveCaller ? drive.pDriveCaller->pCopy() : 0)
635 {
636  NO_OP;
637 }
638 
640 {
641  if (pDriveCaller != 0) {
643  }
644 }
645 
646 void
648 {
649  ASSERT(pDC != 0);
650  if (pDriveCaller != 0) {
651  DEBUGCOUT("warning: the original pointer to a drive caller is not null!" << std::endl);
653  }
654  pDriveCaller = const_cast<DriveCaller*>(pDC);
655 }
656 
657 DriveCaller *
659 {
660  return pDriveCaller;
661 }
662 
664 DriveOwner::dGet(const doublereal& dVal) const
665 {
666  return pDriveCaller->dGet(dVal);
667 }
668 
669 
671 DriveOwner::dGet(void) const
672 {
673  return pDriveCaller->dGet();
674 }
675 
676 bool
678 {
680 }
681 
683 DriveOwner::dGetP(const doublereal& dVal) const
684 {
685  return pDriveCaller->dGetP(dVal);
686 }
687 
688 
690 DriveOwner::dGetP(void) const
691 {
692  return pDriveCaller->dGetP();
693 }
694 
695 /* DriveOwner - end */
696 
MySH(unsigned int uLabel, const DriveCaller *pFunc, const DriveCaller *pTrigger, const doublereal dVal0)
Definition: drive.cc:439
DriveHandler(MathParser &mp)
Definition: drive.cc:59
static doublereal dReturnValue
Definition: drive.h:110
virtual DriveCaller * pCopy(void) const
Definition: drive.cc:607
Definition: mathtyp.h:175
long int flag
Definition: mbdyn.h:43
virtual ~Drive(void)
Definition: drive.cc:50
#define MBDYN_EXCEPT_ARGS
Definition: except.h:63
virtual ~MyRand(void)
Definition: drive.cc:409
Var * Put(const std::string &name, const TypedValue &v)
Definition: table.cc:110
const DriveCaller * pGetSHTrigger(integer iNumber) const
Definition: drive.cc:330
integer iSHInit(const DriveCaller *pFunc, const DriveCaller *pTrigger, const doublereal dVal0)
Definition: drive.cc:310
virtual const DriveHandler * pGetDrvHdl(void) const
Definition: drive.cc:493
const char * what(void) const
Definition: except.cc:54
doublereal dGet(void) const
Definition: drive.cc:671
Var * pTime
Definition: drive.h:185
virtual ~DriveCaller(void)
Definition: drive.cc:481
virtual void Trace(OutputHandler &OH) const
Definition: drive.cc:531
DriveCaller * pDriveCaller
Definition: drive.h:133
const DriveCaller * pGetFunc(void) const
Definition: drive.cc:454
MyClosestNext(unsigned int uLabel, const DriveHandler *pDH, const DriveCaller *pIncrementDC, doublereal dStartTime)
Definition: drive.cc:425
#define NO_OP
Definition: myassert.h:74
void SetVar(const doublereal &dVar)
Definition: drive.cc:349
bool bIsDifferentiable(void) const
Definition: drive.cc:677
MathParser & Parser
Definition: drive.h:182
OneDriveCaller(void)
Definition: drive.cc:594
int Int
Definition: mathtyp.h:40
std::vector< MyMeter * > Meter
Definition: drive.h:265
virtual std::ostream & Restart(std::ostream &out) const
Definition: drive.cc:584
virtual doublereal dGetP(const doublereal &dVar) const
Definition: drive.cc:499
const doublereal dGetVal0(void) const
Definition: drive.cc:466
void PutSymbolTable(Table &T)
Definition: drive.cc:342
doublereal dGetP(void) const
Definition: drive.cc:690
std::vector< MyClosestNext * > ClosestNext
Definition: drive.h:267
DriveCaller(const DriveHandler *pDH)
Definition: drive.cc:475
std::ostream & Traces(void) const
Definition: output.h:608
virtual void SetDrvHdl(const DriveHandler *pDH)
Definition: drive.cc:487
Drive(unsigned int uL, const DriveHandler *pDH)
Definition: drive.cc:43
VectorHandler * pXCurr
Definition: drive.h:192
integer iMeterInit(integer iSteps)
Definition: drive.cc:281
virtual std::ostream & Restart(std::ostream &out) const
Definition: drive.cc:617
virtual bool bIsDifferentiable(void) const
Definition: drive.h:495
const DriveCaller * pGetSHFunc(integer iNumber) const
Definition: drive.cc:324
#define SAFENEW(pnt, item)
Definition: mynewmem.h:695
NullDriveCaller(void)
Definition: drive.cc:561
flag fTrace
Definition: output.h:697
Definition: mbdyn.h:76
static doublereal dDriveHandlerReturnValue
Definition: drive.h:190
#define DEBUGCOUT(msg)
Definition: myassert.h:232
std::vector< MyRand * > Rand
Definition: drive.h:266
virtual ~DriveOwner(void)
Definition: drive.cc:639
Var * pStep
Definition: drive.h:187
virtual ~MyClosestNext(void)
Definition: drive.cc:434
DriveHandler * pDrvHdl
Definition: drive.h:444
#define ASSERT(expression)
Definition: colamd.c:977
~DriveHandler(void)
Definition: drive.cc:176
#define SAFENEWWITHCONSTRUCTOR(pnt, item, constructor)
Definition: mynewmem.h:698
DriveCaller * pGetDriveCaller(void) const
Definition: drive.cc:658
virtual DriveCaller * pCopy(void) const
Definition: drive.cc:574
virtual flag fToBeTraced(void) const
Definition: output.cc:914
virtual doublereal dGet(void) const
Definition: drive.h:489
VectorHandler * pXPrimeCurr
Definition: drive.h:193
integer iRandInit(integer iSteps)
Definition: drive.cc:268
virtual doublereal dGet(const doublereal &dVar) const =0
std::ostream & DriveCallers(void) const
Definition: output.h:601
void LinkToSolution(const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
Definition: drive.cc:260
Var * pVar
Definition: drive.h:188
virtual doublereal dGetP(void) const
Definition: drive.h:501
NamedValue * Get(const std::string &name) const
Definition: table.cc:150
std::vector< MySH * > SH
Definition: drive.h:268
Real GetLastStmt(Real d=0., Token t=ARGSEP)
Definition: mathp.cc:4402
integer iCurrStep
Definition: drive.h:195
virtual flag fToBeOutput(void) const
Definition: output.cc:884
void Set(const DriveCaller *pDC)
Definition: drive.cc:647
virtual ~NullDriveCaller(void)
Definition: drive.cc:567
Var * pTimeStep
Definition: drive.h:186
void SetTime(const doublereal &dt, const doublereal &dts, const integer &s)
Definition: drive.cc:208
virtual ~MyMeter(void)
Definition: drive.cc:420
Definition: table.h:43
void PutSymbolTable(Table &T)
Definition: mathp.cc:1937
integer iClosestNextInit(const DriveCaller *pIncrement, doublereal dStartTime)
Definition: drive.cc:294
doublereal dStartTime
MyMeter(unsigned int uLabel, integer iS=1)
Definition: drive.cc:414
virtual ~MySH(void)
Definition: drive.cc:448
double doublereal
Definition: colamd.c:52
long int integer
Definition: colamd.c:51
void SetVal(const bool &b)
Definition: mathp.cc:1829
double Real
Definition: mathtyp.h:39
Table & GetSymbolTable(void) const
Definition: mathp.cc:1931
const doublereal dGetSHVal0(integer iNumber) const
Definition: drive.cc:336
unsigned int GetLabel(void) const
Definition: withlab.cc:62
doublereal dGet(InputStream &InStr) const
Definition: drive.cc:358
static int drive(const MathParser::MathArgs &args)
Definition: modelns.cc:716
virtual void Output(OutputHandler &OH) const
Definition: drive.cc:506
virtual bool IsVar(void) const
Definition: mathp.cc:1745
const DriveCaller * pGetTrigger(void) const
Definition: drive.cc:460
DriveOwner(const DriveCaller *pDC=0)
Definition: drive.cc:627
bool UseText(int out) const
Definition: output.cc:446
MyRand(unsigned int uLabel, integer iS=1, integer iR=0)
Definition: drive.cc:403
virtual ~OneDriveCaller(void)
Definition: drive.cc:600
#define SAFEDELETE(pnt)
Definition: mynewmem.h:710