1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/mbdyn/base/drive_.cc,v 1.118 2017/08/28 10:34:39 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 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
33
34 #include <limits>
35 #include <cmath>
36 #include <cfloat>
37
38 #ifdef USE_MPI
39 #include "mbcomm.h"
40 #endif /* USE_MPI */
41
42 #include "dataman.h"
43 #include "drive_.h"
44 #include "dofdrive.h"
45 #include "privdrive.h"
46 #include "ddrive.h"
47 #include "shdrive.h"
48
49 #include "filedrv.h"
50 #include "fixedstep.h"
51 #include "varstep.h"
52 #include "sockdrv.h"
53 #include "streamdrive.h"
54 #include "socketstreamdrive.h"
55 #include "bufferstreamdrive.h"
56
57 #ifdef USE_GINAC
58 #include "ginacdrive.h"
59 #endif // USE_GINAC
60
61 #ifdef STATIC_MODULES
62 #ifdef USE_OCTAVE
63 #include "module-octave/module-octave.h"
64 #endif // USE_OCTAVE
65 #include "module-nodedistdrive/module-nodedistdrive.h"
66 #include "module-minmaxdrive/module-minmaxdrive.h"
67 #endif // STATIC_MODULES
68
69 /* StringDriveCaller - begin */
70
71 #ifdef USE_EE
StringDriveCaller(const DriveHandler * pDH,const std::string & sTmpStr,const ExpressionElement * expr)72 StringDriveCaller::StringDriveCaller(const DriveHandler* pDH,
73 const std::string& sTmpStr, const ExpressionElement *expr)
74 : DriveCaller(pDH), sEvalStr(sTmpStr), m_expr(new SharedExpr(expr))
75 {
76 ASSERT(!sEvalStr.empty());
77 ASSERT(m_expr->Get() != 0);
78 }
79
80
StringDriveCaller(const DriveHandler * pDH,const std::string & sTmpStr,SharedExprPtr_t expr)81 StringDriveCaller::StringDriveCaller(const DriveHandler* pDH,
82 const std::string& sTmpStr, SharedExprPtr_t expr)
83 : DriveCaller(pDH), sEvalStr(sTmpStr), m_expr(expr)
84 {
85 ASSERT(!sEvalStr.empty());
86 ASSERT(m_expr->Get() != 0);
87 }
88
89
~StringDriveCaller(void)90 StringDriveCaller::~StringDriveCaller(void)
91 {
92 ASSERT(m_expr->Get() != 0);
93 }
94
95
96 /* Copia */
97 DriveCaller *
pCopy(void) const98 StringDriveCaller::pCopy(void) const
99 {
100 DriveCaller* pDC = 0;
101
102 SAFENEWWITHCONSTRUCTOR(pDC,
103 StringDriveCaller,
104 StringDriveCaller(pDrvHdl, sEvalStr, m_expr->pCopy()));
105
106 return pDC;
107 }
108
109 #else // ! USE_EE
110
StringDriveCaller(const DriveHandler * pDH,const std::string & sTmpStr)111 StringDriveCaller::StringDriveCaller(const DriveHandler* pDH,
112 const std::string& sTmpStr)
113 : DriveCaller(pDH), sEvalStr(sTmpStr)
114 {
115 ASSERT(!sEvalStr.empty());
116 }
117
118
~StringDriveCaller(void)119 StringDriveCaller::~StringDriveCaller(void)
120 {
121 NO_OP;
122 }
123
124 DriveCaller *
pCopy(void) const125 StringDriveCaller::pCopy(void) const
126 {
127 DriveCaller* pDC = 0;
128 SAFENEWWITHCONSTRUCTOR(pDC,
129 StringDriveCaller,
130 StringDriveCaller(pDrvHdl, sEvalStr));
131
132 return pDC;
133 }
134
135 #endif // ! USE_EE
136
137
138 /* Scrive il contributo del DriveCaller al file di restart */
139 std::ostream&
Restart(std::ostream & out) const140 StringDriveCaller::Restart(std::ostream& out) const
141 {
142 return out << "string, \"" << sEvalStr << "\"";
143 }
144
145 /* StringDriveCaller - end */
146
147
148 /* TimeDriveCaller - begin */
149
TimeDriveCaller(const DriveHandler * pDH)150 TimeDriveCaller::TimeDriveCaller(const DriveHandler* pDH)
151 : DriveCaller(pDH)
152 {
153 NO_OP;
154 }
155
~TimeDriveCaller(void)156 TimeDriveCaller::~TimeDriveCaller(void)
157 {
158 NO_OP;
159 }
160
161 /* Copia */
162 DriveCaller *
pCopy(void) const163 TimeDriveCaller::pCopy(void) const
164 {
165 DriveCaller* pDC = 0;
166 SAFENEWWITHCONSTRUCTOR(pDC, TimeDriveCaller, TimeDriveCaller(pDrvHdl));
167 return pDC;
168 }
169
170 /* Scrive il contributo del DriveCaller al file di restart */
171 std::ostream&
Restart(std::ostream & out) const172 TimeDriveCaller::Restart(std::ostream& out) const
173 {
174 return out << "time";
175 }
176
177 /* TimeDriveCaller - end */
178
179
180 /* TimeStepDriveCaller - begin */
181
TimeStepDriveCaller(const DriveHandler * pDH)182 TimeStepDriveCaller::TimeStepDriveCaller(const DriveHandler* pDH)
183 : DriveCaller(pDH)
184 {
185 NO_OP;
186 }
187
~TimeStepDriveCaller(void)188 TimeStepDriveCaller::~TimeStepDriveCaller(void)
189 {
190 NO_OP;
191 }
192
193 /* Copia */
194 DriveCaller *
pCopy(void) const195 TimeStepDriveCaller::pCopy(void) const
196 {
197 DriveCaller* pDC = 0;
198 SAFENEWWITHCONSTRUCTOR(pDC, TimeStepDriveCaller, TimeStepDriveCaller(pDrvHdl));
199 return pDC;
200 }
201
202 /* Scrive il contributo del DriveCaller al file di restart */
203 std::ostream&
Restart(std::ostream & out) const204 TimeStepDriveCaller::Restart(std::ostream& out) const
205 {
206 return out << "timestep";
207 }
208
209 /* TimeStepDriveCaller - end */
210
211
212 /* MultDriveCaller - begin */
213
MultDriveCaller(const DriveHandler * pDH,const DriveCaller * pDC1,const DriveCaller * pDC2)214 MultDriveCaller::MultDriveCaller(const DriveHandler *pDH,
215 const DriveCaller* pDC1, const DriveCaller *pDC2)
216 : DriveCaller(pDH),
217 DO1(pDC1), DO2(pDC2)
218 {
219 NO_OP;
220 }
221
~MultDriveCaller(void)222 MultDriveCaller::~MultDriveCaller(void)
223 {
224 NO_OP;
225 }
226
227 /* Copia */
228 DriveCaller *
pCopy(void) const229 MultDriveCaller::pCopy(void) const
230 {
231 DriveCaller* pDC = 0;
232 SAFENEWWITHCONSTRUCTOR(pDC, MultDriveCaller,
233 MultDriveCaller(pDrvHdl,
234 DO1.pGetDriveCaller()->pCopy(), DO2.pGetDriveCaller()->pCopy()));
235 return pDC;
236 }
237
238 /* Scrive il contributo del DriveCaller al file di restart */
239 std::ostream&
Restart(std::ostream & out) const240 MultDriveCaller::Restart(std::ostream& out) const
241 {
242 return out << "mult, ",
243 DO1.pGetDriveCaller()->Restart(out) << ", ";
244 DO2.pGetDriveCaller()->Restart(out);
245 }
246
247 /* MultDriveCaller - end */
248
249
250 /* ConstDriveCaller - begin */
251
ConstDriveCaller(doublereal d)252 ConstDriveCaller::ConstDriveCaller(doublereal d)
253 : DriveCaller(0), dConst(d)
254 {
255 NO_OP;
256 }
257
~ConstDriveCaller(void)258 ConstDriveCaller::~ConstDriveCaller(void)
259 {
260 NO_OP;
261 }
262
263 /* Copia */
264 DriveCaller*
pCopy(void) const265 ConstDriveCaller::pCopy(void) const
266 {
267 DriveCaller* pDC = 0;
268 SAFENEWWITHCONSTRUCTOR(pDC, ConstDriveCaller, ConstDriveCaller(dConst));
269 return pDC;
270 }
271
272 /* Scrive il contributo del DriveCaller al file di restart */
273 std::ostream&
Restart(std::ostream & out) const274 ConstDriveCaller::Restart(std::ostream& out) const
275 {
276 return out << " const, " << dConst;
277 }
278
279 /* ConstDriveCaller - end */
280
281
282 /* LinearDriveCaller - begin */
283
LinearDriveCaller(const DriveHandler * pDH,doublereal d0,doublereal d1)284 LinearDriveCaller::LinearDriveCaller(const DriveHandler* pDH,
285 doublereal d0, doublereal d1)
286 : DriveCaller(pDH), dC0(d0), dC1(d1)
287 {
288 NO_OP;
289 }
290
~LinearDriveCaller(void)291 LinearDriveCaller::~LinearDriveCaller(void)
292 {
293 NO_OP;
294 }
295
296 /* Copia */
297 DriveCaller *
pCopy(void) const298 LinearDriveCaller::pCopy(void) const
299 {
300 DriveCaller* pDC = 0;
301 SAFENEWWITHCONSTRUCTOR(pDC, LinearDriveCaller, LinearDriveCaller(pDrvHdl, dC0, dC1));
302 return pDC;
303 }
304
305 /* Scrive il contributo del DriveCaller al file di restart */
306 std::ostream&
Restart(std::ostream & out) const307 LinearDriveCaller::Restart(std::ostream& out) const
308 {
309 return out << " linear, " << dC0 << ", " << dC1;
310 }
311
312 /* LinearDriveCaller - end */
313
314
315 /* ParabolicDriveCaller - begin */
316
ParabolicDriveCaller(const DriveHandler * pDH,doublereal d0,doublereal d1,doublereal d2)317 ParabolicDriveCaller::ParabolicDriveCaller(const DriveHandler* pDH,
318 doublereal d0, doublereal d1, doublereal d2)
319 : DriveCaller(pDH), dC0(d0), dC1(d1), dC2(d2)
320 {
321 NO_OP;
322 }
323
~ParabolicDriveCaller(void)324 ParabolicDriveCaller::~ParabolicDriveCaller(void)
325 {
326 NO_OP;
327 }
328
329 /* Copia */
330 DriveCaller *
pCopy(void) const331 ParabolicDriveCaller::pCopy(void) const
332 {
333 DriveCaller* pDC = 0;
334 SAFENEWWITHCONSTRUCTOR(pDC, ParabolicDriveCaller, ParabolicDriveCaller(pDrvHdl, dC0, dC1, dC2));
335 return pDC;
336 }
337
338 /* Scrive il contributo del DriveCaller al file di restart */
339 std::ostream&
Restart(std::ostream & out) const340 ParabolicDriveCaller::Restart(std::ostream& out) const
341 {
342 return out << " parabolic, " << dC0 << ", " << dC1 << ", " << dC2;
343 }
344
345 /* ParabolicDriveCaller - end */
346
347
348 /* CubicDriveCaller - begin */
349
CubicDriveCaller(const DriveHandler * pDH,doublereal d0,doublereal d1,doublereal d2,doublereal d3)350 CubicDriveCaller::CubicDriveCaller(const DriveHandler* pDH,
351 doublereal d0, doublereal d1,
352 doublereal d2, doublereal d3)
353 : DriveCaller(pDH), dC0(d0), dC1(d1), dC2(d2), dC3(d3)
354 {
355 NO_OP;
356 }
357
~CubicDriveCaller(void)358 CubicDriveCaller::~CubicDriveCaller(void)
359 {
360 NO_OP;
361 }
362
363 /* Copia */
364 DriveCaller *
pCopy(void) const365 CubicDriveCaller::pCopy(void) const
366 {
367 DriveCaller* pDC = 0;
368 SAFENEWWITHCONSTRUCTOR(pDC, CubicDriveCaller, CubicDriveCaller(pDrvHdl, dC0, dC1, dC2, dC3));
369 return pDC;
370 }
371
372 /* Scrive il contributo del DriveCaller al file di restart */
373 std::ostream&
Restart(std::ostream & out) const374 CubicDriveCaller::Restart(std::ostream& out) const
375 {
376 return out << " cubic, "
377 << dC0 << ", " << dC1 << ", " << dC2 << ", " << dC3;
378 }
379
380 /* CubicDriveCaller - end */
381
382
383 /* StepDriveCaller - begin */
384
StepDriveCaller(const DriveHandler * pDH,doublereal d1,doublereal d2,doublereal d3)385 StepDriveCaller::StepDriveCaller(const DriveHandler* pDH,
386 doublereal d1, doublereal d2, doublereal d3)
387 : DriveCaller(pDH),
388 dStepTime(d1), dStepValue(d2), dInitialValue(d3)
389 {
390 NO_OP;
391 }
392
~StepDriveCaller(void)393 StepDriveCaller::~StepDriveCaller(void)
394 {
395 NO_OP;
396 }
397
398 /* Copia */
399 DriveCaller *
pCopy(void) const400 StepDriveCaller::pCopy(void) const
401 {
402 DriveCaller* pDC = 0;
403 SAFENEWWITHCONSTRUCTOR(pDC,
404 StepDriveCaller,
405 StepDriveCaller(pDrvHdl, dStepTime, dStepValue, dInitialValue));
406 return pDC;
407 }
408
409 /* Scrive il contributo del DriveCaller al file di restart */
410 std::ostream&
Restart(std::ostream & out) const411 StepDriveCaller::Restart(std::ostream& out) const
412 {
413 return out
414 << " step, " << dStepTime
415 << ", " << dStepValue
416 << ", " << dInitialValue;
417 }
418
419 /* StepDriveCaller - end */
420
421
422 /* DoubleStepDriveCaller - begin */
423
DoubleStepDriveCaller(const DriveHandler * pDH,doublereal d1,doublereal d2,doublereal d3,doublereal d4)424 DoubleStepDriveCaller::DoubleStepDriveCaller(const DriveHandler* pDH,
425 doublereal d1, doublereal d2, doublereal d3, doublereal d4)
426 : DriveCaller(pDH), dStepTime(d1), dStepValue(d2),
427 dEndStepTime(d3), dInitialValue(d4)
428 {
429 NO_OP;
430 }
431
~DoubleStepDriveCaller(void)432 DoubleStepDriveCaller::~DoubleStepDriveCaller(void)
433 {
434 NO_OP;
435 }
436
437
438 /* Copia */
439 DriveCaller *
pCopy(void) const440 DoubleStepDriveCaller::pCopy(void) const
441 {
442 DriveCaller* pDC = 0;
443 SAFENEWWITHCONSTRUCTOR(pDC,
444 DoubleStepDriveCaller,
445 DoubleStepDriveCaller(pDrvHdl, dStepTime, dStepValue, dEndStepTime, dInitialValue));
446 return pDC;
447 }
448
449
450 /* Scrive il contributo del DriveCaller al file di restart */
451 std::ostream&
Restart(std::ostream & out) const452 DoubleStepDriveCaller::Restart(std::ostream& out) const
453 {
454 return out
455 << " double step, " << dStepTime
456 << ", " << dEndStepTime
457 << ", " << dStepValue
458 << ", " << dInitialValue;
459 }
460
461 /* DoubleStepDriveCaller - end */
462
463
464 /* RampDriveCaller - begin */
465
RampDriveCaller(const DriveHandler * pDH,doublereal d1,doublereal d2,doublereal d3,doublereal d4)466 RampDriveCaller::RampDriveCaller(const DriveHandler* pDH,
467 doublereal d1, doublereal d2, doublereal d3, doublereal d4)
468 : DriveCaller(pDH), dSlope(d1), dStartTime(d2), dEndTime(d3), dInitialValue(d4)
469 {
470 NO_OP;
471 }
472
~RampDriveCaller(void)473 RampDriveCaller::~RampDriveCaller(void)
474 {
475 NO_OP;
476 }
477
478 /* Copia */
479 DriveCaller *
pCopy(void) const480 RampDriveCaller::pCopy(void) const
481 {
482 DriveCaller* pDC = 0;
483 SAFENEWWITHCONSTRUCTOR(pDC,
484 RampDriveCaller,
485 RampDriveCaller(pDrvHdl, dSlope, dStartTime, dEndTime, dInitialValue));
486 return pDC;
487 }
488
489 /* Scrive il contributo del DriveCaller al file di restart */
490 std::ostream&
Restart(std::ostream & out) const491 RampDriveCaller::Restart(std::ostream& out) const
492 {
493 return out
494 << "ramp, " << dSlope
495 << ", " << dStartTime
496 << ", " << dEndTime
497 << ", " << dInitialValue;
498 }
499
500 /* RampDriveCaller - end */
501
502
503 /* DoubleRampDriveCaller - begin */
504
DoubleRampDriveCaller(const DriveHandler * pDH,doublereal d1,doublereal d2,doublereal d3,doublereal d4,doublereal d5,doublereal d6,doublereal d7)505 DoubleRampDriveCaller::DoubleRampDriveCaller(const DriveHandler* pDH,
506 doublereal d1, doublereal d2, doublereal d3,
507 doublereal d4, doublereal d5, doublereal d6,
508 doublereal d7)
509 : DriveCaller(pDH),
510 dAscendingSlope(d1), dAscendingStartTime(d2), dAscendingEndTime(d3),
511 dDescendingSlope(d4), dDescendingStartTime(d5), dDescendingEndTime(d6),
512 dInitialValue(d7)
513 {
514 NO_OP;
515 }
516
~DoubleRampDriveCaller(void)517 DoubleRampDriveCaller::~DoubleRampDriveCaller(void)
518 {
519 NO_OP;
520 }
521
522 /* Copia */
523 DriveCaller *
pCopy(void) const524 DoubleRampDriveCaller::pCopy(void) const
525 {
526 DriveCaller* pDC = 0;
527 SAFENEWWITHCONSTRUCTOR(pDC,
528 DoubleRampDriveCaller,
529 DoubleRampDriveCaller(pDrvHdl, dAscendingSlope, dAscendingStartTime, dAscendingEndTime,
530 dDescendingSlope, dDescendingStartTime, dDescendingEndTime, dInitialValue));
531 return pDC;
532 }
533
534 /* Scrive il contributo del DriveCaller al file di restart */
535 std::ostream&
Restart(std::ostream & out) const536 DoubleRampDriveCaller::Restart(std::ostream& out) const
537 {
538 return out
539 << " double ramp, " << dAscendingSlope
540 << ", " << dAscendingStartTime
541 << ", " << dAscendingEndTime
542 << ", " << dDescendingSlope
543 << ", " << dDescendingStartTime
544 << ", " << dDescendingEndTime
545 << ", " << dInitialValue;
546 }
547
548 /* DoubleRampDriveCaller - end */
549
550
551 /* SineDriveCaller - begin */
552
SineDriveCaller(const DriveHandler * pDH,doublereal d1,doublereal d2,doublereal d3,integer iNumCyc,doublereal d4)553 SineDriveCaller::SineDriveCaller(const DriveHandler* pDH,
554 doublereal d1, doublereal d2, doublereal d3,
555 integer iNumCyc, doublereal d4)
556 : DriveCaller(pDH),
557 dStartTime(d1), dOmega(d2), dAmplitude(d3),
558 iNumCycles(iNumCyc), dInitialValue(d4), bNeverEnd(false)
559 {
560 /* Onde di seno che partono da zero ed arrivano a0 */
561 if (iNumCycles > 0) {
562 dEndTime = dStartTime + 2.*M_PI/dOmega*(doublereal(iNumCycles) - .5);
563 dFinalValue = dInitialValue;
564
565 /* Onde di seno che continuano all'infinito */
566 } else if (iNumCycles == 0) {
567 dEndTime = 0.;
568 bNeverEnd = true;
569
570 /* Onde di seno che partono da 0 ed arrivano ad 1
571 * con tangente orizzontale */
572 } else {
573 dEndTime = dStartTime + 2.*M_PI/dOmega*(doublereal(-iNumCycles) - .75);
574 dFinalValue = dInitialValue + dAmplitude;
575 }
576 }
577
~SineDriveCaller(void)578 SineDriveCaller::~SineDriveCaller(void)
579 {
580 NO_OP;
581 }
582
583 /* Copia */
584 DriveCaller *
pCopy(void) const585 SineDriveCaller::pCopy(void) const
586 {
587 DriveCaller* pDC = 0;
588 SAFENEWWITHCONSTRUCTOR(pDC,
589 SineDriveCaller,
590 SineDriveCaller(pDrvHdl, dStartTime, dOmega, dAmplitude, iNumCycles, dInitialValue));
591 return pDC;
592 }
593
594 /* Scrive il contributo del DriveCaller al file di restart */
595 std::ostream&
Restart(std::ostream & out) const596 SineDriveCaller::Restart(std::ostream& out) const
597 {
598 return out
599 << " sine, " << dStartTime
600 << ", " << dOmega
601 << ", " << dAmplitude
602 << ", " << iNumCycles
603 << ", " << dInitialValue;
604 }
605
606 /* SineDriveCaller - end */
607
608
609 /* FourierSeriesDriveCaller - begin */
610
FourierSeriesDriveCaller(const DriveHandler * pDH,doublereal dStartTime,doublereal dOmega,std::vector<doublereal> & a,integer iNumCyc,doublereal dInitialValue)611 FourierSeriesDriveCaller::FourierSeriesDriveCaller(const DriveHandler* pDH,
612 doublereal dStartTime,
613 doublereal dOmega,
614 std::vector<doublereal>& a,
615 integer iNumCyc,
616 doublereal dInitialValue)
617 : DriveCaller(pDH),
618 dStartTime(dStartTime),
619 dOmega(dOmega),
620 iNumCycles(iNumCyc),
621 dInitialValue(dInitialValue),
622 bNeverEnd(false)
623 {
624 ASSERT(iNumCycles >= 0);
625
626 if (iNumCycles > 0) {
627 dEndTime = dStartTime
628 + 2.*M_PI/dOmega*doublereal(iNumCycles);
629
630 /* Onde di coseno che continuano all'infinito */
631 } else if (iNumCycles == 0) {
632 dEndTime = 0.;
633 bNeverEnd = true;
634 }
635
636 amplitudes.resize(a.size());
637 for (unsigned i = 0; i < a.size(); i++) {
638 amplitudes[i] = a[i];
639 }
640 }
641
~FourierSeriesDriveCaller(void)642 FourierSeriesDriveCaller::~FourierSeriesDriveCaller(void)
643 {
644 NO_OP;
645 }
646
647 /* Copia */
648 DriveCaller *
pCopy(void) const649 FourierSeriesDriveCaller::pCopy(void) const
650 {
651 DriveCaller* pDC = 0;
652
653 SAFENEWWITHCONSTRUCTOR(pDC,
654 FourierSeriesDriveCaller,
655 FourierSeriesDriveCaller(pDrvHdl,
656 dStartTime,
657 dOmega,
658 amplitudes,
659 iNumCycles,
660 dInitialValue));
661 return pDC;
662 }
663
664
665 /* Scrive il contributo del DriveCaller al file di restart */
666 std::ostream&
Restart(std::ostream & out) const667 FourierSeriesDriveCaller::Restart(std::ostream& out) const
668 {
669 out
670 << " fourier series, "
671 << dStartTime << ", "
672 << dOmega << ", "
673 << amplitudes.size()/2 << ", "
674 << 2.*amplitudes[0] << ", ";
675
676 for (unsigned i = 1; i < amplitudes.size(); i++) {
677 out << amplitudes[i] << ", ";
678 }
679
680 out
681 << iNumCycles << ", "
682 << dInitialValue;
683
684 return out;
685 }
686
687 /* FourierSeriesDriveCaller - end */
688
689
690 /* CosineDriveCaller - begin */
691
CosineDriveCaller(const DriveHandler * pDH,doublereal d1,doublereal d2,doublereal d3,integer iNumCyc,doublereal d4)692 CosineDriveCaller::CosineDriveCaller(const DriveHandler* pDH,
693 doublereal d1, doublereal d2,
694 doublereal d3,
695 integer iNumCyc, doublereal d4)
696 : DriveCaller(pDH),
697 dStartTime(d1), dOmega(d2), dAmplitude(d3),
698 iNumCycles(iNumCyc), dInitialValue(d4), bNeverEnd(false)
699 {
700 /* Onde di coseno che partono da zero ed arrivano a 0 */
701 if (iNumCycles > 0) {
702 dEndTime = dStartTime + 2.*M_PI/dOmega*doublereal(iNumCycles);
703 dFinalValue = dInitialValue;
704
705 /* Onde di coseno che continuano all'infinito */
706 } else if (iNumCycles == 0) {
707 dEndTime = 0.;
708 bNeverEnd = true;
709
710 /* Onde di coseno che partono da 0 ed arrivano ad 1
711 * con tangente orizzontale */
712 } else {
713 dEndTime = dStartTime + 2.*M_PI/dOmega*(doublereal(-iNumCycles) - .5);
714 dFinalValue = dInitialValue + 2.*dAmplitude;
715 }
716 }
717
~CosineDriveCaller(void)718 CosineDriveCaller::~CosineDriveCaller(void)
719 {
720 NO_OP;
721 }
722
723 /* Copia */
724 DriveCaller*
pCopy(void) const725 CosineDriveCaller::pCopy(void) const
726 {
727 DriveCaller* pDC = 0;
728 SAFENEWWITHCONSTRUCTOR(pDC,
729 CosineDriveCaller,
730 CosineDriveCaller(pDrvHdl, dStartTime, dOmega, dAmplitude, iNumCycles, dInitialValue));
731 return pDC;
732 }
733
734 /* Scrive il contributo del DriveCaller al file di restart */
735 std::ostream&
Restart(std::ostream & out) const736 CosineDriveCaller::Restart(std::ostream& out) const
737 {
738 return out
739 << " cosine, " << dStartTime
740 << ", " << dOmega
741 << ", " << dAmplitude
742 << ", " << iNumCycles
743 << ", " << dInitialValue;
744 }
745
746 /* CosineDriveCaller - end */
747
748
749 /* TanhDriveCaller - begin */
750
TanhDriveCaller(const DriveHandler * pDH,doublereal ds,doublereal da,doublereal db,doublereal di)751 TanhDriveCaller::TanhDriveCaller(const DriveHandler* pDH,
752 doublereal ds, doublereal da,
753 doublereal db, doublereal di)
754 : DriveCaller(pDH),
755 dStart(ds), dA(da), dB(db), dInitialValue(di)
756 {
757 NO_OP;
758 }
759
~TanhDriveCaller(void)760 TanhDriveCaller::~TanhDriveCaller(void)
761 {
762 NO_OP;
763 }
764
765 /* Copia */
766 DriveCaller*
pCopy(void) const767 TanhDriveCaller::pCopy(void) const
768 {
769 DriveCaller* pDC = 0;
770 SAFENEWWITHCONSTRUCTOR(pDC,
771 TanhDriveCaller,
772 TanhDriveCaller(pDrvHdl, dStart, dA, dB, dInitialValue));
773 return pDC;
774 }
775
776 /* Scrive il contributo del DriveCaller al file di restart */
777 std::ostream&
Restart(std::ostream & out) const778 TanhDriveCaller::Restart(std::ostream& out) const
779 {
780 return out
781 << " tanh, " << dStart
782 << ", " << dA
783 << ", " << dB
784 << ", " << dInitialValue;
785 }
786
787 /* TanhDriveCaller - end */
788
789
790 /* FreqSweepDriveCaller - begin */
791
FreqSweepDriveCaller(const DriveHandler * pDH,doublereal d1,const DriveCaller * pOmega,const DriveCaller * pAmplitude,doublereal d2,doublereal d3,doublereal d4)792 FreqSweepDriveCaller::FreqSweepDriveCaller(const DriveHandler* pDH,
793 doublereal d1,
794 const DriveCaller* pOmega,
795 const DriveCaller* pAmplitude,
796 doublereal d2,
797 doublereal d3,
798 doublereal d4)
799 : DriveCaller(pDH),
800 dStartTime(d1), pOmega(pOmega),
801 pAmplitude(pAmplitude),
802 dInitialValue(d2), dEndTime(d3), dFinalValue(d4),
803 bNeverEnd(false)
804 {
805 ASSERT(pOmega != 0);
806 ASSERT(pAmplitude != 0);
807
808 if (dEndTime <= dStartTime) {
809 bNeverEnd = true;
810 }
811 }
812
~FreqSweepDriveCaller(void)813 FreqSweepDriveCaller::~FreqSweepDriveCaller(void)
814 {
815 if (pOmega) {
816 SAFEDELETE(pOmega);
817 }
818
819 if (pAmplitude) {
820 SAFEDELETE(pAmplitude);
821 }
822 }
823
824 /* Copia */
825 DriveCaller *
pCopy(void) const826 FreqSweepDriveCaller::pCopy(void) const
827 {
828 DriveCaller* pDC = 0;
829 SAFENEWWITHCONSTRUCTOR(pDC,
830 FreqSweepDriveCaller,
831 FreqSweepDriveCaller(pDrvHdl, dStartTime, pOmega->pCopy(),
832 pAmplitude->pCopy(), dInitialValue, dEndTime, dFinalValue));
833 return pDC;
834 }
835
836 /* Scrive il contributo del DriveCaller al file di restart */
837 std::ostream&
Restart(std::ostream & out) const838 FreqSweepDriveCaller::Restart(std::ostream& out) const
839 {
840 out
841 << " frequency sweep, " << dStartTime
842 << ", ", pOmega->Restart(out)
843 << ", ", pAmplitude->Restart(out)
844 << ", " << dInitialValue
845 << ", " << dEndTime
846 << ", " << dFinalValue;
847 return out;
848 }
849
850 /* FreqSweepDriveCaller - end */
851
852
853 /* ExpDriveCaller - begin */
854
ExpDriveCaller(const DriveHandler * pDH,doublereal dA,doublereal dT,doublereal dS,doublereal dI)855 ExpDriveCaller::ExpDriveCaller(const DriveHandler* pDH,
856 doublereal dA, doublereal dT,
857 doublereal dS, doublereal dI)
858 : DriveCaller(pDH),
859 dAmplitude(dA), dTimeConst(dT), dStartTime(dS), dInitialValue(dI)
860 {
861 NO_OP;
862 }
863
~ExpDriveCaller(void)864 ExpDriveCaller::~ExpDriveCaller(void)
865 {
866 NO_OP;
867 }
868
869 /* Copia */
870 DriveCaller*
pCopy(void) const871 ExpDriveCaller::pCopy(void) const
872 {
873 DriveCaller* pDC = 0;
874 SAFENEWWITHCONSTRUCTOR(pDC,
875 ExpDriveCaller,
876 ExpDriveCaller(pDrvHdl, dAmplitude, dTimeConst, dStartTime, dInitialValue));
877 return pDC;
878 }
879
880 /* Scrive il contributo del DriveCaller al file di restart */
881 std::ostream&
Restart(std::ostream & out) const882 ExpDriveCaller::Restart(std::ostream& out) const
883 {
884 return out
885 << " exponential, " << dAmplitude
886 << ", " << dTimeConst
887 << ", " << dStartTime
888 << ", " << dInitialValue;
889 }
890
891 /* ExpDriveCaller - end */
892
893
894 /* RandDriveCaller - begin */
895
RandDriveCaller(const DriveHandler * pDH,doublereal dA,doublereal dR,doublereal dS,doublereal dE,integer iS)896 RandDriveCaller::RandDriveCaller(const DriveHandler* pDH,
897 doublereal dA, doublereal dR,
898 doublereal dS, doublereal dE, integer iS)
899 : DriveCaller(pDH), dAmplitude(dA), dRefVal(dR),
900 dStartTime(dS), dEndTime(dE), iSteps(iS)
901 {
902 iBase = rand();
903 iRandDriveNumber = pDrvHdl->iRandInit(iSteps);
904 }
905
~RandDriveCaller(void)906 RandDriveCaller::~RandDriveCaller(void)
907 {
908 NO_OP;
909 }
910
911 /* Copia */
912 DriveCaller *
pCopy(void) const913 RandDriveCaller::pCopy(void) const
914 {
915 DriveCaller* pDC = 0;
916 SAFENEWWITHCONSTRUCTOR(pDC,
917 RandDriveCaller,
918 RandDriveCaller(pDrvHdl, dAmplitude, dRefVal, dStartTime, dEndTime, iSteps));
919 return pDC;
920 }
921
922 /* Scrive il contributo del DriveCaller al file di restart */
923 std::ostream&
Restart(std::ostream & out) const924 RandDriveCaller::Restart(std::ostream& out) const
925 {
926 out
927 << " random, " << dAmplitude
928 << ", " << dRefVal
929 << ", " << dStartTime
930 << ", " << dEndTime;
931 if (iSteps > 1) {
932 out << ", steps, " << iSteps;
933 }
934 return out;
935 }
936
937 /* RandDriveCaller - end */
938
939
940 /* MeterDriveCaller - begin */
941
MeterDriveCaller(const DriveHandler * pDH,doublereal dS,doublereal dE,integer iS)942 MeterDriveCaller::MeterDriveCaller(const DriveHandler* pDH,
943 doublereal dS, doublereal dE, integer iS)
944 : DriveCaller(pDH),
945 dStartTime(dS),
946 dEndTime(dE),
947 iSteps(iS)
948 {
949 iMeterDriveNumber = pDrvHdl->iMeterInit(iSteps);
950 }
951
~MeterDriveCaller(void)952 MeterDriveCaller::~MeterDriveCaller(void)
953 {
954 NO_OP;
955 }
956
957 /* Copia */
958 DriveCaller *
pCopy(void) const959 MeterDriveCaller::pCopy(void) const
960 {
961 DriveCaller* pDC = 0;
962 SAFENEWWITHCONSTRUCTOR(pDC,
963 MeterDriveCaller,
964 MeterDriveCaller(pDrvHdl, dStartTime, dEndTime, iSteps));
965 return pDC;
966 }
967
968 /* Scrive il contributo del DriveCaller al file di restart */
969 std::ostream&
Restart(std::ostream & out) const970 MeterDriveCaller::Restart(std::ostream& out) const
971 {
972 out
973 << " meter, " << dStartTime
974 << ", " << dEndTime;
975 if (iSteps > 1) {
976 out << ", steps, " << iSteps;
977 }
978 return out;
979 }
980
981 /* MeterDriveCaller - end */
982
983
984 /* ClosestNextDriveCaller - begin */
985
ClosestNextDriveCaller(const DriveHandler * pDH,doublereal dS,doublereal dE,const DriveCaller * pIncrement)986 ClosestNextDriveCaller::ClosestNextDriveCaller(const DriveHandler* pDH,
987 doublereal dS, doublereal dE, const DriveCaller *pIncrement)
988 : DriveCaller(pDH),
989 dStartTime(dS), dEndTime(dE),
990 pIncrement(pIncrement)
991 {
992 iDriveNumber = pDrvHdl->iClosestNextInit(pIncrement, dStartTime);
993 }
994
~ClosestNextDriveCaller(void)995 ClosestNextDriveCaller::~ClosestNextDriveCaller(void)
996 {
997 NO_OP;
998 }
999
1000 /* Copia */
1001 DriveCaller *
pCopy(void) const1002 ClosestNextDriveCaller::pCopy(void) const
1003 {
1004 DriveCaller* pDC = 0;
1005 SAFENEWWITHCONSTRUCTOR(pDC,
1006 ClosestNextDriveCaller,
1007 ClosestNextDriveCaller(pDrvHdl, dStartTime, dEndTime,
1008 pIncrement->pCopy()));
1009 return pDC;
1010 }
1011
1012 /* Scrive il contributo del DriveCaller al file di restart */
1013 std::ostream&
Restart(std::ostream & out) const1014 ClosestNextDriveCaller::Restart(std::ostream& out) const
1015 {
1016 out
1017 << " closest next, " << dStartTime
1018 << ", " << dEndTime
1019 << ", ", pIncrement->Restart(out);
1020
1021 return out;
1022 }
1023
1024 /* ClosestNextDriveCaller - end */
1025
1026
1027 /* DirectDriveCaller - begin */
1028
DirectDriveCaller(const DriveHandler * pDH)1029 DirectDriveCaller::DirectDriveCaller(const DriveHandler* pDH)
1030 : DriveCaller(pDH)
1031 {
1032 NO_OP;
1033 }
1034
~DirectDriveCaller(void)1035 DirectDriveCaller::~DirectDriveCaller(void)
1036 {
1037 NO_OP;
1038 }
1039
1040 /* Copia */
1041 DriveCaller *
pCopy(void) const1042 DirectDriveCaller::pCopy(void) const
1043 {
1044 DriveCaller* pDC = 0;
1045 SAFENEWWITHCONSTRUCTOR(pDC,
1046 DirectDriveCaller,
1047 DirectDriveCaller(pDrvHdl));
1048 return pDC;
1049 }
1050
1051 /* Scrive il contributo del DriveCaller al file di restart */
1052 std::ostream&
Restart(std::ostream & out) const1053 DirectDriveCaller::Restart(std::ostream& out) const
1054 {
1055 return out << " direct";
1056 }
1057
1058 /* DirectDriveCaller - end */
1059
1060
1061 /* PiecewiseLinearDriveCaller - begin */
1062
PiecewiseLinearDriveCaller(const DriveHandler * pDH,unsigned int i,doublereal * p)1063 PiecewiseLinearDriveCaller::PiecewiseLinearDriveCaller(const DriveHandler* pDH,
1064 unsigned int i, doublereal *p)
1065 : DriveCaller(pDH), iNumPoints(i), pPoints(p), pVals(p + i)
1066 {
1067 ASSERT(i >= 2);
1068 ASSERT(p != 0);
1069 }
1070
~PiecewiseLinearDriveCaller(void)1071 PiecewiseLinearDriveCaller::~PiecewiseLinearDriveCaller(void)
1072 {
1073 if (pPoints != 0) {
1074 SAFEDELETEARR(pPoints);
1075 }
1076 }
1077
1078 /* Copia */
1079 DriveCaller *
pCopy(void) const1080 PiecewiseLinearDriveCaller::pCopy(void) const
1081 {
1082 doublereal *p = 0;
1083 SAFENEWARR(p, doublereal, 2*iNumPoints);
1084 for (unsigned int i = 0; i < 2*iNumPoints; i++) {
1085 p[i] = pPoints[i];
1086 }
1087
1088 DriveCaller* pDC = 0;
1089 SAFENEWWITHCONSTRUCTOR(pDC,
1090 PiecewiseLinearDriveCaller,
1091 PiecewiseLinearDriveCaller(pDrvHdl, iNumPoints, p));
1092
1093 return pDC;
1094 }
1095
1096 /* Scrive il contributo del DriveCaller al file di restart */
1097 std::ostream&
Restart(std::ostream & out) const1098 PiecewiseLinearDriveCaller::Restart(std::ostream& out) const
1099 {
1100 out << "piecewise linear, " << iNumPoints;
1101
1102 for (unsigned int i = 0; i < iNumPoints; i++) {
1103 out << ", " << pPoints[i] << ", " << pVals[i];
1104 }
1105
1106 return out;
1107 }
1108
1109 /* PiecewiseLinearDriveCaller - end */
1110
1111
1112 /* DriveArrayCaller - begin */
1113
DriveArrayCaller(const DriveHandler * pDH,dcv_t & DC)1114 DriveArrayCaller::DriveArrayCaller(const DriveHandler* pDH, dcv_t& DC)
1115 : DriveCaller(pDH), m_dc(DC)
1116 {
1117 #ifdef DEBUG
1118 ASSERT(!m_dc.empty());
1119 for (dcv_t::const_iterator i = m_dc.begin(); i != m_dc.end(); ++i) {
1120 ASSERT((*i) != 0);
1121 }
1122 #endif /* DEBUG */
1123 }
1124
~DriveArrayCaller(void)1125 DriveArrayCaller::~DriveArrayCaller(void)
1126 {
1127 ASSERT(!m_dc.empty());
1128
1129 for (dcv_t::iterator i = m_dc.begin(); i != m_dc.end(); ++i) {
1130 SAFEDELETE(*i);
1131 }
1132 }
1133
1134 /* Copia */
1135 DriveCaller *
pCopy(void) const1136 DriveArrayCaller::pCopy(void) const
1137 {
1138 ASSERT(!m_dc.empty());
1139
1140 dcv_t DC(m_dc.size());
1141
1142 for (unsigned i = 0; i < m_dc.size(); i++) {
1143 DC[i] = m_dc[i]->pCopy();
1144 }
1145
1146 DriveCaller* pDC = 0;
1147 SAFENEWWITHCONSTRUCTOR(pDC,
1148 DriveArrayCaller,
1149 DriveArrayCaller(pDrvHdl, DC));
1150
1151 return pDC;
1152 }
1153
1154 /* Scrive il contributo del DriveCaller al file di restart */
1155 std::ostream&
Restart(std::ostream & out) const1156 DriveArrayCaller::Restart(std::ostream& out) const
1157 {
1158 out << " array, " << m_dc.size();
1159
1160 for (dcv_t::const_iterator i = m_dc.begin(); i != m_dc.end(); ++i) {
1161 ASSERT((*i) != 0);
1162
1163 out << ", ", (*i)->Restart(out);
1164 }
1165
1166 return out;
1167 }
1168
1169 /* DriveArrayCaller - end */
1170
1171 /* PeriodicDriveCaller - begin */
1172
PeriodicDriveCaller(const DriveHandler * pDH,const DriveCaller * pDC,doublereal dT0,doublereal dPeriod)1173 PeriodicDriveCaller::PeriodicDriveCaller(const DriveHandler *pDH,
1174 const DriveCaller* pDC, doublereal dT0, doublereal dPeriod)
1175 : DriveCaller(pDH),
1176 DO(pDC), dT0(dT0), dPeriod(dPeriod)
1177 {
1178 NO_OP;
1179 }
1180
~PeriodicDriveCaller(void)1181 PeriodicDriveCaller::~PeriodicDriveCaller(void)
1182 {
1183 NO_OP;
1184 }
1185
1186 /* Copia */
1187 DriveCaller *
pCopy(void) const1188 PeriodicDriveCaller::pCopy(void) const
1189 {
1190 DriveCaller* pDC = 0;
1191 SAFENEWWITHCONSTRUCTOR(pDC, PeriodicDriveCaller,
1192 PeriodicDriveCaller(pDrvHdl,
1193 DO.pGetDriveCaller()->pCopy(), dT0, dPeriod));
1194 return pDC;
1195 }
1196
1197 /* Scrive il contributo del DriveCaller al file di restart */
1198 std::ostream&
Restart(std::ostream & out) const1199 PeriodicDriveCaller::Restart(std::ostream& out) const
1200 {
1201 return out << "periodic, " << dT0 << ", " << dPeriod << ", ",
1202 DO.pGetDriveCaller()->Restart(out);
1203 }
1204
1205 /* PeriodicDriveCaller - end */
1206
1207 /* PostponedDriveCaller - begin */
1208
1209 void
Check(void) const1210 PostponedDriveCaller::Check(void) const
1211 {
1212 if (!DO.pGetDriveCaller()) {
1213 const DriveCaller *pDC = HP.GetDrive(uDriveLabel);
1214 if (pDC == 0) {
1215 silent_cerr("PostponedDriveCaller: unable to resolve postponed drive caller \"" << uDriveLabel << "\"" << std::endl);
1216 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
1217 }
1218 DO.Set(pDC->pCopy());
1219 const_cast<PostponedDriveCaller *>(this)->SetDrvHdl(DO.pGetDriveCaller()->pGetDrvHdl());
1220 }
1221 }
1222
PostponedDriveCaller(MBDynParser & HP,unsigned uLabel)1223 PostponedDriveCaller::PostponedDriveCaller(MBDynParser& HP, unsigned uLabel)
1224 : DriveCaller(0),
1225 HP(HP), uDriveLabel(uLabel), DO(0)
1226 {
1227 NO_OP;
1228 }
1229
~PostponedDriveCaller(void)1230 PostponedDriveCaller::~PostponedDriveCaller(void)
1231 {
1232 NO_OP;
1233 }
1234
1235 /* Scrive il contributo del DriveCaller al file di restart */
1236 std::ostream&
Restart(std::ostream & out) const1237 PostponedDriveCaller::Restart(std::ostream& out) const
1238 {
1239 Check();
1240
1241 out << ", deferred, " << uDriveLabel << " /* actual drive: ",
1242 DO.pGetDriveCaller()->Restart(out) << " */";
1243
1244 return out;
1245 }
1246
1247 /* Copia */
1248 DriveCaller *
pCopy(void) const1249 PostponedDriveCaller::pCopy(void) const
1250 {
1251 DriveCaller *pDC = 0;
1252 SAFENEWWITHCONSTRUCTOR(pDC, PostponedDriveCaller,
1253 PostponedDriveCaller(HP, uDriveLabel));
1254 return pDC;
1255 }
1256
1257 /* PostponedDriveCaller - end */
1258
1259
1260 /* bag that contains functions to parse drives */
1261
1262 typedef std::map<std::string, DriveRead *, ltstrcase> DriveFuncMapType;
1263 static DriveFuncMapType DriveFuncMap;
1264
1265 struct DriveWordSetType : public HighParser::WordSet {
IsWordDriveWordSetType1266 bool IsWord(const std::string& s) const {
1267 return DriveFuncMap.find(s) != DriveFuncMap.end();
1268 };
1269 };
1270
1271 static DriveWordSetType DriveWordSet;
1272
1273 bool
SetDriveData(const std::string & name,DriveRead * rf)1274 SetDriveData(const std::string& name, DriveRead *rf)
1275 {
1276 pedantic_cout("registering drive \"" << name << "\"" << std::endl);
1277 return DriveFuncMap.insert(DriveFuncMapType::value_type(name, rf)).second;
1278 }
1279
1280 /* Reads drives */
1281
1282 Drive *
ReadDriveData(unsigned uLabel,const DataManager * pDM,MBDynParser & HP)1283 ReadDriveData(unsigned uLabel, const DataManager* pDM, MBDynParser& HP)
1284 {
1285 DEBUGCOUTFNAME("ReadDriveData()");
1286
1287 const char *s = HP.IsWord(DriveWordSet);
1288 if (s == 0) {
1289 silent_cerr("ReadDriveData(" << uLabel << "): "
1290 "unknown drive type "
1291 "at line " << HP.GetLineData() << std::endl);
1292 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
1293 }
1294
1295 DriveFuncMapType::iterator func = DriveFuncMap.find(std::string(s));
1296 if (func == DriveFuncMap.end()) {
1297 silent_cerr("unknown drive type \"" << s << "\" "
1298 "at line " << HP.GetLineData() << std::endl);
1299 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1300 }
1301
1302 return func->second->Read(uLabel, pDM, HP);
1303 }
1304
~DriveRead(void)1305 DriveRead::~DriveRead(void)
1306 {
1307 NO_OP;
1308 }
1309
1310 /* bag that contains functions to parse drive callers */
1311
1312 typedef std::map<std::string, DriveCallerRead *, ltstrcase> DriveCallerFuncMapType;
1313 static DriveCallerFuncMapType DriveCallerFuncMap;
1314
1315 struct DriveCallerWordSetType : public HighParser::WordSet {
IsWordDriveCallerWordSetType1316 bool IsWord(const std::string& s) const {
1317 return DriveCallerFuncMap.find(s) != DriveCallerFuncMap.end();
1318 };
1319 };
1320
1321 static DriveCallerWordSetType DriveCallerWordSet;
1322
1323 bool
SetDriveCallerData(const char * name,DriveCallerRead * rf)1324 SetDriveCallerData(const char *name, DriveCallerRead *rf)
1325 {
1326 pedantic_cout("registering drive caller \"" << name << "\"" << std::endl);
1327 return DriveCallerFuncMap.insert(DriveCallerFuncMapType::value_type(name, rf)).second;
1328 }
1329
1330 /* Reads drive callers */
1331
1332 DriveCaller *
ReadDriveCallerData(const DataManager * pDM,MBDynParser & HP,bool bDeferred)1333 ReadDriveCallerData(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
1334 {
1335 DEBUGCOUTFNAME("ReadDriveCallerData()");
1336
1337 const char *s = HP.IsWord(DriveCallerWordSet);
1338 if (s == 0) {
1339 pedantic_cerr("ReadDriveCallerData: warning, assuming \"const\" drive caller at line " << HP.GetLineData() << std::endl);
1340 s = "const";
1341 }
1342
1343 DriveCallerFuncMapType::iterator func = DriveCallerFuncMap.find(std::string(s));
1344 if (func == DriveCallerFuncMap.end()) {
1345 silent_cerr("unknown drive caller type \"" << s << "\" "
1346 "at line " << HP.GetLineData() << std::endl);
1347 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1348 }
1349
1350 return func->second->Read(pDM, HP, bDeferred);
1351 }
1352
1353 void
NeedDM(const DataManager * pDM,MBDynParser & HP,bool bDeferred,const char * const name)1354 DriveCallerRead::NeedDM(const DataManager* pDM, MBDynParser& HP, bool bDeferred,
1355 const char *const name)
1356 {
1357 if (pDM == 0 && !bDeferred) {
1358 silent_cerr("\"" << name << "\" drive caller needs data manager "
1359 "at line " << HP.GetLineData() << std::endl);
1360 throw DataManager::ErrNeedDataManager(MBDYN_EXCEPT_ARGS);
1361 }
1362 }
1363
~DriveCallerRead(void)1364 DriveCallerRead::~DriveCallerRead(void)
1365 {
1366 NO_OP;
1367 }
1368
ReadOutput(DriveCaller * pDC,const DataManager * pDM,MBDynParser & HP)1369 void DriveCallerRead::ReadOutput(DriveCaller* pDC, const DataManager* pDM, MBDynParser& HP)
1370 {
1371 flag fOutput = pDM->bOutputDriveCallers()
1372 ? DriveCaller::OUTPUT_VALUE
1373 : 0;
1374
1375 if (HP.IsKeyWord("output")) {
1376 bool bGotKeyWord = false;
1377
1378 if (HP.IsKeyWord("value")) {
1379 bGotKeyWord = true;
1380
1381 if (HP.GetYesNoOrBool()) {
1382 fOutput |= DriveCaller::OUTPUT_VALUE;
1383 } else {
1384 fOutput &= ~DriveCaller::OUTPUT_VALUE;
1385 }
1386 }
1387
1388 if (HP.IsKeyWord("derivative")) {
1389 bGotKeyWord = true;
1390
1391 if (HP.GetYesNoOrBool()) {
1392 fOutput |= DriveCaller::OUTPUT_DERIVATIVE;
1393 } else {
1394 fOutput &= ~DriveCaller::OUTPUT_DERIVATIVE;
1395 }
1396 }
1397
1398 if (!bGotKeyWord) {
1399 if (HP.GetYesNoOrBool()) {
1400 fOutput |= DriveCaller::OUTPUT_VALUE;
1401
1402 if (pDC->bIsDifferentiable()) {
1403 fOutput |= DriveCaller::OUTPUT_DERIVATIVE;
1404 }
1405 } else {
1406 fOutput = flag(0);
1407 }
1408 }
1409 }
1410
1411 if (fOutput & DriveCaller::OUTPUT_DERIVATIVE) {
1412 if (!pDC->bIsDifferentiable()) {
1413 silent_cerr("warning invalid output flag: drive caller(" << pDC->GetLabel()
1414 << ") is not differentiable at line "
1415 << HP.GetLineData() << std::endl);
1416
1417 fOutput &= ~DriveCaller::OUTPUT_DERIVATIVE;
1418 }
1419 }
1420
1421 if (fOutput) {
1422 fOutput |= DriveCaller::OUTPUT;
1423 }
1424
1425 pDC->SetOutputFlag(fOutput);
1426
1427 flag fTrace = 0;
1428
1429 if (HP.IsKeyWord("output" "trace")) {
1430 bool bGotKeyWord = false;
1431
1432 if (HP.IsKeyWord("value")) {
1433 bGotKeyWord = true;
1434
1435 if (HP.GetYesNoOrBool()) {
1436 fTrace |= DriveCaller::TRACE_VALUE;
1437 } else {
1438 fTrace &= ~DriveCaller::TRACE_VALUE;
1439 }
1440 }
1441
1442 if (HP.IsKeyWord("derivative")) {
1443 bGotKeyWord = true;
1444
1445 if (HP.GetYesNoOrBool()) {
1446 fTrace |= DriveCaller::TRACE_DERIVATIVE;
1447 } else {
1448 fTrace &= ~DriveCaller::TRACE_DERIVATIVE;
1449 }
1450 }
1451
1452 if (!bGotKeyWord) {
1453 if (HP.GetYesNoOrBool()) {
1454 fTrace |= DriveCaller::TRACE_VALUE;
1455
1456 if (pDC->bIsDifferentiable()) {
1457 fTrace |= DriveCaller::TRACE_DERIVATIVE;
1458 }
1459 } else {
1460 fTrace = flag(0);
1461 }
1462 }
1463 }
1464
1465 if (fTrace & DriveCaller::TRACE_DERIVATIVE) {
1466 if (!pDC->bIsDifferentiable()) {
1467 silent_cerr("warning invalid trace flag: drive caller (" << pDC->GetLabel()
1468 << ") is not differentiable at line "
1469 << HP.GetLineData() << std::endl);
1470
1471 fTrace &= ~DriveCaller::TRACE_DERIVATIVE;
1472 }
1473 }
1474
1475 if (fTrace) {
1476 fTrace |= DriveCaller::TRACE;
1477 }
1478
1479 pDC->SetTraceFlag(fTrace);
1480 }
1481
1482 struct TimeDCR : public DriveCallerRead {
1483 DriveCaller *
1484 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
1485 };
1486
1487 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)1488 TimeDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
1489 {
1490 NeedDM(pDM, HP, bDeferred, "time");
1491
1492 const DriveHandler* pDrvHdl = 0;
1493 if (pDM != 0) {
1494 pDrvHdl = pDM->pGetDrvHdl();
1495 }
1496
1497 DriveCaller *pDC = 0;
1498
1499 SAFENEWWITHCONSTRUCTOR(pDC, TimeDriveCaller, TimeDriveCaller(pDrvHdl));
1500
1501 return pDC;
1502 }
1503
1504 struct TimeStepDCR : public DriveCallerRead {
1505 DriveCaller *
1506 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
1507 };
1508
1509 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)1510 TimeStepDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
1511 {
1512 NeedDM(pDM, HP, bDeferred, "timestep");
1513
1514 const DriveHandler* pDrvHdl = 0;
1515 if (pDM != 0) {
1516 pDrvHdl = pDM->pGetDrvHdl();
1517 }
1518
1519 DriveCaller *pDC = 0;
1520
1521 SAFENEWWITHCONSTRUCTOR(pDC, TimeStepDriveCaller, TimeStepDriveCaller(pDrvHdl));
1522
1523 return pDC;
1524 }
1525
1526 struct MultDCR : public DriveCallerRead {
1527 DriveCaller *
1528 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
1529 };
1530
1531 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)1532 MultDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
1533 {
1534 NeedDM(pDM, HP, bDeferred, "mult");
1535
1536 const DriveHandler* pDrvHdl = 0;
1537 if (pDM != 0) {
1538 pDrvHdl = pDM->pGetDrvHdl();
1539 }
1540
1541 DriveCaller* pDC1 = HP.GetDriveCaller();
1542 DriveCaller* pDC2 = HP.GetDriveCaller();
1543
1544 DriveCaller *pDC = 0;
1545 SAFENEWWITHCONSTRUCTOR(pDC,
1546 MultDriveCaller,
1547 MultDriveCaller(pDrvHdl, pDC1, pDC2));
1548
1549 return pDC;
1550 }
1551
1552 struct NullDCR : public DriveCallerRead {
1553 DriveCaller *
1554 Read(const DataManager* /* pDM */ , MBDynParser& /* HP */ , bool /* bDeferred */ );
1555 };
1556
1557 DriveCaller *
Read(const DataManager *,MBDynParser &,bool)1558 NullDCR::Read(const DataManager* /* pDM */ , MBDynParser& /* HP */ , bool /* bDeferred */ )
1559 {
1560 DriveCaller *pDC = 0;
1561
1562 SAFENEW(pDC, NullDriveCaller);
1563
1564 return pDC;
1565 }
1566
1567 struct OneDCR : public DriveCallerRead {
1568 DriveCaller *
1569 Read(const DataManager* /* pDM */ , MBDynParser& /* HP */ , bool /* bDeferred */ );
1570 };
1571
1572 DriveCaller *
Read(const DataManager *,MBDynParser &,bool)1573 OneDCR::Read(const DataManager* /* pDM */ , MBDynParser& /* HP */ , bool /* bDeferred */ )
1574 {
1575 DriveCaller *pDC = 0;
1576
1577 SAFENEW(pDC, OneDriveCaller);
1578
1579 return pDC;
1580 }
1581
1582 struct ConstDCR : public DriveCallerRead {
1583 DriveCaller *
1584 Read(const DataManager* pDM, MBDynParser& HP, bool /* bDeferred */ );
1585 };
1586
1587 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool)1588 ConstDCR::Read(const DataManager* pDM, MBDynParser& HP, bool /* bDeferred */ )
1589 {
1590 DriveCaller *pDC = 0;
1591
1592 /* lettura dei dati specifici */
1593 doublereal dConst = HP.GetReal();
1594 DEBUGCOUT("Const value: " << dConst << std::endl);
1595
1596 /* allocazione e creazione */
1597 if (dConst == 0.) {
1598 SAFENEW(pDC, NullDriveCaller);
1599
1600 } else if (dConst == 1.) {
1601 SAFENEW(pDC, OneDriveCaller);
1602
1603 } else {
1604 SAFENEWWITHCONSTRUCTOR(pDC, ConstDriveCaller, ConstDriveCaller(dConst));
1605 }
1606
1607 return pDC;
1608 }
1609
1610 struct LinearDCR : public DriveCallerRead {
1611 DriveCaller *
1612 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
1613 };
1614
1615 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)1616 LinearDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
1617 {
1618 NeedDM(pDM, HP, bDeferred, "linear");
1619
1620 const DriveHandler* pDrvHdl = 0;
1621 if (pDM != 0) {
1622 pDrvHdl = pDM->pGetDrvHdl();
1623 }
1624
1625 DriveCaller *pDC = 0;
1626
1627 /* lettura dei dati specifici */
1628 doublereal dC0 = HP.GetReal();
1629 DEBUGCOUT("Offset: " << dC0 << std::endl);
1630
1631 doublereal dC1 = HP.GetReal();
1632 DEBUGCOUT("Slope: " << dC1 << std::endl);
1633
1634 /* allocazione e creazione */
1635 SAFENEWWITHCONSTRUCTOR(pDC,
1636 LinearDriveCaller,
1637 LinearDriveCaller(pDrvHdl, dC0, dC1));
1638
1639 return pDC;
1640 }
1641
1642 struct ParabolicDCR : public DriveCallerRead {
1643 DriveCaller *
1644 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
1645 };
1646
1647 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)1648 ParabolicDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
1649 {
1650 NeedDM(pDM, HP, bDeferred, "parabolic");
1651
1652 const DriveHandler* pDrvHdl = 0;
1653 if (pDM != 0) {
1654 pDrvHdl = pDM->pGetDrvHdl();
1655 }
1656
1657 DriveCaller *pDC = 0;
1658
1659 /* lettura dei dati specifici */
1660 doublereal dC0 = HP.GetReal();
1661 DEBUGCOUT("Offset: " << dC0 << std::endl);
1662
1663 doublereal dC1 = HP.GetReal();
1664 DEBUGCOUT("Slope: " << dC1 << std::endl);
1665
1666 doublereal dC2 = HP.GetReal();
1667 DEBUGCOUT("Parabolic slope: " << dC2 << std::endl);
1668
1669 /* allocazione e creazione */
1670 SAFENEWWITHCONSTRUCTOR(pDC,
1671 ParabolicDriveCaller,
1672 ParabolicDriveCaller(pDrvHdl, dC0, dC1, dC2));
1673
1674 return pDC;
1675 }
1676
1677 struct CubicDCR : public DriveCallerRead {
1678 DriveCaller *
1679 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
1680 };
1681
1682 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)1683 CubicDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
1684 {
1685 NeedDM(pDM, HP, bDeferred, "cubic");
1686
1687 const DriveHandler* pDrvHdl = 0;
1688 if (pDM != 0) {
1689 pDrvHdl = pDM->pGetDrvHdl();
1690 }
1691
1692 DriveCaller *pDC = 0;
1693
1694 /* lettura dei dati specifici */
1695 doublereal dC0 = HP.GetReal();
1696 DEBUGCOUT("Offset: " << dC0 << std::endl);
1697
1698 doublereal dC1 = HP.GetReal();
1699 DEBUGCOUT("Slope: " << dC1 << std::endl);
1700
1701 doublereal dC2 = HP.GetReal();
1702 DEBUGCOUT("Parabolic slope: " << dC2 << std::endl);
1703
1704 doublereal dC3 = HP.GetReal();
1705 DEBUGCOUT("Cubic slope: " << dC3 << std::endl);
1706
1707 /* allocazione e creazione */
1708 SAFENEWWITHCONSTRUCTOR(pDC,
1709 CubicDriveCaller,
1710 CubicDriveCaller(pDrvHdl, dC0, dC1, dC2, dC3));
1711
1712 return pDC;
1713 }
1714
1715 /*
1716 * this allows each drive to be preceded by the keyword "function"
1717 */
1718 struct FunctionDCR : public DriveCallerRead {
1719 DriveCaller *
1720 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
1721 };
1722
1723 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)1724 FunctionDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
1725 {
1726 return HP.GetDriveCaller(bDeferred);
1727 }
1728
1729 struct StepDCR : public DriveCallerRead {
1730 DriveCaller *
1731 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
1732 };
1733
1734 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)1735 StepDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
1736 {
1737 NeedDM(pDM, HP, bDeferred, "step");
1738
1739 const DriveHandler* pDrvHdl = 0;
1740 if (pDM != 0) {
1741 pDrvHdl = pDM->pGetDrvHdl();
1742 }
1743
1744 DriveCaller *pDC = 0;
1745
1746 doublereal dStepTime = HP.GetReal();
1747 DEBUGCOUT("Initial time: " << dStepTime << std::endl);
1748
1749 doublereal dStepValue = HP.GetReal(1.);
1750 DEBUGCOUT("Step Value: " << dStepValue << std::endl);
1751
1752 doublereal dInitialValue = HP.GetReal();
1753 DEBUGCOUT("InitialValue: " << dInitialValue << std::endl);
1754
1755 SAFENEWWITHCONSTRUCTOR(pDC,
1756 StepDriveCaller,
1757 StepDriveCaller(pDrvHdl, dStepTime, dStepValue, dInitialValue));
1758
1759 return pDC;
1760 }
1761
1762 struct DoubleStepDCR : public DriveCallerRead {
1763 DriveCaller *
1764 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
1765 };
1766
1767 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)1768 DoubleStepDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
1769 {
1770 NeedDM(pDM, HP, bDeferred, "double step");
1771
1772 const DriveHandler* pDrvHdl = 0;
1773 if (pDM != 0) {
1774 pDrvHdl = pDM->pGetDrvHdl();
1775 }
1776
1777 DriveCaller *pDC = 0;
1778
1779 doublereal dStepTime = HP.GetReal();
1780 DEBUGCOUT("Initial time: " << dStepTime << std::endl);
1781
1782 doublereal dEndStepTime = HP.GetReal();
1783 DEBUGCOUT("Final time: " << dEndStepTime << std::endl);
1784
1785 if (dEndStepTime <= dStepTime) {
1786 silent_cerr("Warning at line "
1787 << HP.GetLineData()
1788 << ": final time " << dEndStepTime
1789 << " is less than or equal to initial time " << dStepTime
1790 << " in double step func drive" << std::endl);
1791 }
1792
1793 doublereal dStepValue = HP.GetReal(1.);
1794 DEBUGCOUT("Step Value: " << dStepValue << std::endl);
1795
1796 doublereal dInitialValue = HP.GetReal();
1797 DEBUGCOUT("InitialValue: " << dInitialValue << std::endl);
1798
1799 SAFENEWWITHCONSTRUCTOR(pDC,
1800 DoubleStepDriveCaller,
1801 DoubleStepDriveCaller(pDrvHdl,
1802 dStepTime,
1803 dStepValue,
1804 dEndStepTime,
1805 dInitialValue));
1806
1807 return pDC;
1808 }
1809
1810 struct RampDCR : public DriveCallerRead {
1811 DriveCaller *
1812 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
1813 };
1814
1815 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)1816 RampDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
1817 {
1818 NeedDM(pDM, HP, bDeferred, "ramp");
1819
1820 const DriveHandler* pDrvHdl = 0;
1821 if (pDM != 0) {
1822 pDrvHdl = pDM->pGetDrvHdl();
1823 }
1824
1825 DriveCaller *pDC = 0;
1826
1827 /* Rampa saturata */
1828 doublereal dSlope = HP.GetReal(1.);
1829 DEBUGCOUT("Slope Value: " << dSlope << std::endl);
1830
1831 doublereal dInitialTime = HP.GetReal();
1832 DEBUGCOUT("Initial time: " << dInitialTime << std::endl);
1833
1834 doublereal dFinalTime = std::numeric_limits<double>::max();
1835 if (!HP.IsKeyWord("forever")) {
1836 dFinalTime = HP.GetReal();
1837 }
1838 DEBUGCOUT("Final time: " << dFinalTime << std::endl);
1839
1840 if (dFinalTime <= dInitialTime) {
1841 silent_cerr("Warning at line "
1842 << HP.GetLineData()
1843 << ": final time " << dFinalTime
1844 << " is less than or equal to initial time " << dInitialTime
1845 << " in ramp func drive" << std::endl);
1846 }
1847
1848 doublereal dInitialValue = HP.GetReal();
1849 DEBUGCOUT("InitialValue: " << dInitialValue << std::endl);
1850
1851 SAFENEWWITHCONSTRUCTOR(pDC,
1852 RampDriveCaller,
1853 RampDriveCaller(pDrvHdl, dSlope, dInitialTime,
1854 dFinalTime, dInitialValue));
1855
1856 return pDC;
1857 }
1858
1859 struct DoubleRampDCR : public DriveCallerRead {
1860 DriveCaller *
1861 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
1862 };
1863
1864 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)1865 DoubleRampDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
1866 {
1867 NeedDM(pDM, HP, bDeferred, "double ramp");
1868
1869 const DriveHandler* pDrvHdl = 0;
1870 if (pDM != 0) {
1871 pDrvHdl = pDM->pGetDrvHdl();
1872 }
1873
1874 DriveCaller *pDC = 0;
1875
1876 /* Rampa doppia */
1877 doublereal dAscendingSlope = HP.GetReal(1.);
1878 DEBUGCOUT("Ascending Slope Value: " << dAscendingSlope << std::endl);
1879
1880 doublereal dAscendingInitialTime = HP.GetReal();
1881 DEBUGCOUT("Ascending Initial time: " << dAscendingInitialTime << std::endl);
1882
1883 doublereal dAscendingFinalTime = HP.GetReal();
1884 DEBUGCOUT("Ascending Final time: " << dAscendingFinalTime << std::endl);
1885
1886 if (dAscendingFinalTime <= dAscendingInitialTime) {
1887 silent_cerr("Warning at line "
1888 << HP.GetLineData() << ": ascending final time "
1889 << dAscendingFinalTime
1890 << " is less than or equal to ascending initial time "
1891 << dAscendingInitialTime
1892 << " in double ramp func drive" << std::endl);
1893 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1894 }
1895
1896 doublereal dDescendingSlope = HP.GetReal(-1.);
1897 DEBUGCOUT("Descending Slope Value: " << dDescendingSlope << std::endl);
1898
1899 doublereal dDescendingInitialTime = std::numeric_limits<doublereal>::max();
1900 if (!HP.IsKeyWord("forever")) {
1901 dDescendingInitialTime = HP.GetReal();
1902 }
1903 DEBUGCOUT("Descending Initial time: " << dDescendingInitialTime << std::endl);
1904
1905 if (dDescendingInitialTime < dAscendingFinalTime) {
1906 silent_cerr("Warning at line "
1907 << HP.GetLineData() << ": descending initial time "
1908 << dDescendingInitialTime
1909 << " is less than ascending final time "
1910 << dAscendingFinalTime
1911 << " in double ramp func drive" << std::endl);
1912 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1913 }
1914
1915 doublereal dDescendingFinalTime;
1916 if (HP.IsKeyWord("forever")) {
1917 dDescendingFinalTime = std::numeric_limits<doublereal>::max();
1918
1919 } else {
1920 dDescendingFinalTime = HP.GetReal();
1921 }
1922
1923 DEBUGCOUT("Descending Final time: " << dDescendingFinalTime << std::endl);
1924
1925 if (dDescendingFinalTime <= dDescendingInitialTime) {
1926 silent_cerr("Warning at line "
1927 << HP.GetLineData() << ": descending final time "
1928 << dDescendingFinalTime
1929 << " is less than descending initial time "
1930 << dDescendingInitialTime
1931 << " in double ramp func drive" << std::endl);
1932 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
1933 }
1934
1935 doublereal dInitialValue = HP.GetReal();
1936 DEBUGCOUT("InitialValue: " << dInitialValue << std::endl);
1937
1938 SAFENEWWITHCONSTRUCTOR(pDC,
1939 DoubleRampDriveCaller,
1940 DoubleRampDriveCaller(pDrvHdl,
1941 dAscendingSlope, dAscendingInitialTime, dAscendingFinalTime,
1942 dDescendingSlope, dDescendingInitialTime, dDescendingFinalTime,
1943 dInitialValue));
1944
1945 return pDC;
1946 }
1947
1948 struct SineCosineDCR {
1949 protected:
~SineCosineDCRSineCosineDCR1950 virtual ~SineCosineDCR(void) { NO_OP; };
1951 virtual DriveCaller *
1952 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred, bool bSine);
1953 };
1954
1955 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred,bool bSine)1956 SineCosineDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred, bool bSine)
1957 {
1958 const DriveHandler* pDrvHdl = 0;
1959 if (pDM != 0) {
1960 pDrvHdl = pDM->pGetDrvHdl();
1961 }
1962
1963 DriveCaller *pDC = 0;
1964
1965 /* Seno e coseno (limitati, illimitati, saturati) */
1966 doublereal dInitialTime = HP.GetReal();
1967 DEBUGCOUT("Initial time: " << dInitialTime << std::endl);
1968
1969 doublereal dOmega = HP.GetReal(1.);
1970 DEBUGCOUT("Omega: " << dOmega << std::endl);
1971
1972 doublereal dAmplitude = HP.GetReal();
1973 DEBUGCOUT("Amplitude: " << dAmplitude << std::endl);
1974
1975 integer iNumCycles;
1976 if (HP.IsKeyWord("forever")) {
1977 iNumCycles = 0;
1978
1979 } else if (HP.IsKeyWord("one")) {
1980 iNumCycles = 1;
1981
1982 } else if (HP.IsKeyWord("half")) {
1983 iNumCycles = -1;
1984
1985 } else {
1986 iNumCycles = HP.GetInt();
1987 }
1988 DEBUGCOUT("Number of cycles: " << iNumCycles << std::endl);
1989
1990 doublereal dInitialValue = HP.GetReal();
1991 DEBUGCOUT("InitialValue: " << dInitialValue << std::endl);
1992
1993 if (bSine) {
1994 SAFENEWWITHCONSTRUCTOR(pDC,
1995 SineDriveCaller,
1996 SineDriveCaller(pDrvHdl, dInitialTime, dOmega, dAmplitude, iNumCycles, dInitialValue));
1997
1998 } else {
1999 SAFENEWWITHCONSTRUCTOR(pDC,
2000 CosineDriveCaller,
2001 CosineDriveCaller(pDrvHdl, dInitialTime, dOmega, dAmplitude, iNumCycles, dInitialValue));
2002 }
2003
2004 return pDC;
2005 }
2006
2007 struct SineDCR : public DriveCallerRead, protected SineCosineDCR {
2008 DriveCaller *
2009 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2010 };
2011
2012 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2013 SineDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2014 {
2015 NeedDM(pDM, HP, bDeferred, "sine");
2016
2017 return SineCosineDCR::Read(pDM, HP, bDeferred, true);
2018 }
2019
2020 struct CosineDCR : public DriveCallerRead, protected SineCosineDCR {
2021 DriveCaller *
2022 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2023 };
2024
2025 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2026 CosineDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2027 {
2028 NeedDM(pDM, HP, bDeferred, "cosine");
2029
2030 return SineCosineDCR::Read(pDM, HP, bDeferred, false);
2031 }
2032
2033 struct TanhDCR : public DriveCallerRead {
2034 virtual DriveCaller *
2035 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2036 };
2037
2038 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2039 TanhDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2040 {
2041 NeedDM(pDM, HP, bDeferred, "tanh");
2042
2043 const DriveHandler* pDrvHdl = 0;
2044 if (pDM != 0) {
2045 pDrvHdl = pDM->pGetDrvHdl();
2046 }
2047
2048 DriveCaller *pDC = 0;
2049
2050 /* Seno e coseno (limitati, illimitati, saturati) */
2051 doublereal dStart = HP.GetReal();
2052 DEBUGCOUT("Initial time: " << dStart << std::endl);
2053
2054 doublereal dA = HP.GetReal(1.);
2055 DEBUGCOUT("Amplitude: " << dA << std::endl);
2056
2057 doublereal dB = HP.GetReal();
2058 DEBUGCOUT("Slope: " << dB << std::endl);
2059
2060 doublereal dInitialValue = HP.GetReal();
2061 DEBUGCOUT("InitialValue: " << dInitialValue << std::endl);
2062
2063 SAFENEWWITHCONSTRUCTOR(pDC,
2064 TanhDriveCaller,
2065 TanhDriveCaller(pDrvHdl, dStart, dA, dB, dInitialValue));
2066
2067 return pDC;
2068 }
2069
2070 struct FourierSeriesDCR : public DriveCallerRead {
2071 DriveCaller *
2072 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2073 };
2074
2075 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2076 FourierSeriesDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2077 {
2078 NeedDM(pDM, HP, bDeferred, "Fourier series");
2079
2080 const DriveHandler* pDrvHdl = 0;
2081 if (pDM != 0) {
2082 pDrvHdl = pDM->pGetDrvHdl();
2083 }
2084
2085 DriveCaller *pDC = 0;
2086
2087 doublereal dInitialTime = HP.GetReal();
2088 DEBUGCOUT("Initial time: " << dInitialTime << std::endl);
2089
2090 doublereal dOmega = HP.GetReal(1.);
2091 DEBUGCOUT("Omega: " << dOmega << std::endl);
2092
2093 int n = HP.GetInt();
2094 if (n <= 0) {
2095 silent_cerr("FourierSeriesDriveCaller: invalid order " << n
2096 << " at line " << HP.GetLineData() << std::endl);
2097 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2098 }
2099
2100 std::vector<doublereal> a(1 + 2*n);
2101 for (unsigned i = 0; i < 1 + 2*unsigned(n); i++) {
2102 a[i] = HP.GetReal();
2103 }
2104
2105 /* don't remember why, but the series starts with a_0/2 */
2106 a[0] /= 2.;
2107
2108 integer iNumCycles;
2109 if (HP.IsKeyWord("forever")) {
2110 iNumCycles = 0;
2111
2112 } else if (HP.IsKeyWord("one")) {
2113 iNumCycles = 1;
2114
2115 } else {
2116 iNumCycles = HP.GetInt();
2117 }
2118 DEBUGCOUT("Number of cycles: " << iNumCycles << std::endl);
2119 if (iNumCycles < 0) {
2120 silent_cerr("FourierSeriesDriveCaller: invalid number of cycles "
2121 << iNumCycles << " at line " << HP.GetLineData() << std::endl);
2122 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2123 }
2124
2125 doublereal dInitialValue = HP.GetReal();
2126 DEBUGCOUT("InitialValue: " << dInitialValue << std::endl);
2127
2128 SAFENEWWITHCONSTRUCTOR(pDC,
2129 FourierSeriesDriveCaller,
2130 FourierSeriesDriveCaller(pDrvHdl,
2131 dInitialTime,
2132 dOmega,
2133 a,
2134 iNumCycles,
2135 dInitialValue));
2136
2137 return pDC;
2138 }
2139
2140 struct FrequencySweepDCR : public DriveCallerRead {
2141 DriveCaller *
2142 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2143 };
2144
2145 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2146 FrequencySweepDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2147 {
2148 NeedDM(pDM, HP, bDeferred, "frequency sweep");
2149
2150 const DriveHandler* pDrvHdl = 0;
2151 if (pDM != 0) {
2152 pDrvHdl = pDM->pGetDrvHdl();
2153 }
2154
2155 DriveCaller *pDC = 0;
2156
2157 doublereal dInitialTime = HP.GetReal();
2158 DEBUGCOUT("Initial time: " << dInitialTime << std::endl);
2159
2160 DriveCaller* pOmega = 0;
2161 pOmega = HP.GetDriveCaller();
2162
2163 DriveCaller* pAmplitude = 0;
2164 pAmplitude = HP.GetDriveCaller();
2165
2166 doublereal dInitialValue = HP.GetReal();
2167 DEBUGCOUT("Initial value: " << dInitialValue << std::endl);
2168
2169 doublereal dFinalTime = std::numeric_limits<double>::max();
2170 if (!HP.IsKeyWord("forever")) {
2171 dFinalTime = HP.GetReal();
2172 }
2173 DEBUGCOUT("Final time: " << dFinalTime << std::endl);
2174
2175 doublereal dFinalValue = HP.GetReal();
2176 DEBUGCOUT("Final value: " << dFinalValue << std::endl);
2177
2178 SAFENEWWITHCONSTRUCTOR(pDC,
2179 FreqSweepDriveCaller,
2180 FreqSweepDriveCaller(pDrvHdl, dInitialTime, pOmega, pAmplitude,
2181 dInitialValue, dFinalTime, dFinalValue));
2182
2183 return pDC;
2184 }
2185
2186 struct ExponentialDCR : public DriveCallerRead {
2187 DriveCaller *
2188 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2189 };
2190
2191 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2192 ExponentialDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2193 {
2194 NeedDM(pDM, HP, bDeferred, "exponential");
2195
2196 const DriveHandler* pDrvHdl = 0;
2197 if (pDM != 0) {
2198 pDrvHdl = pDM->pGetDrvHdl();
2199 }
2200
2201 DriveCaller *pDC = 0;
2202
2203 doublereal dAmplitude = HP.GetReal(1.);
2204 DEBUGCOUT("Amplitude value: " << dAmplitude << std::endl);
2205
2206 doublereal dTimeConst = HP.GetReal();
2207 DEBUGCOUT("Time constant value: " << dTimeConst << std::endl);
2208
2209 doublereal dInitialTime = HP.GetReal();
2210 DEBUGCOUT("Initial time: " << dInitialTime << std::endl);
2211
2212 doublereal dInitialValue = HP.GetReal();
2213 DEBUGCOUT("Initial value: " << dInitialValue << std::endl);
2214
2215 SAFENEWWITHCONSTRUCTOR(pDC,
2216 ExpDriveCaller,
2217 ExpDriveCaller(pDrvHdl, dAmplitude, dTimeConst,
2218 dInitialTime, dInitialValue));
2219
2220 return pDC;
2221 }
2222
2223 struct RandomDCR : public DriveCallerRead {
2224 DriveCaller *
2225 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2226 };
2227
2228 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2229 RandomDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2230 {
2231 NeedDM(pDM, HP, bDeferred, "random");
2232
2233 const DriveHandler* pDrvHdl = 0;
2234 if (pDM != 0) {
2235 pDrvHdl = pDM->pGetDrvHdl();
2236 }
2237
2238 DriveCaller *pDC = 0;
2239
2240 /* Numero casuale */
2241 doublereal dAmplitude = HP.GetReal(1.);
2242 DEBUGCOUT("Amplitude value: " << dAmplitude << std::endl);
2243
2244 doublereal dRefVal = HP.GetReal();
2245 DEBUGCOUT("Mean value: " << dRefVal << std::endl);
2246
2247 doublereal dInitialTime = HP.GetReal();
2248 DEBUGCOUT("Initial time: " << dInitialTime << std::endl);
2249
2250 doublereal dFinalTime = std::numeric_limits<double>::max();
2251 if (!HP.IsKeyWord("forever")) {
2252 dFinalTime = HP.GetReal();
2253 }
2254 DEBUGCOUT("Final time: " << dFinalTime << std::endl);
2255
2256 /* Type of random number (additional data) */
2257 integer iSteps = 1;
2258 while (true) {
2259 if (HP.IsKeyWord("steps")) {
2260 iSteps = HP.GetInt();
2261 if (iSteps <= 0) {
2262 silent_cerr("Warning: Steps number " << iSteps
2263 << " is illegal; resorting to default value" << std::endl);
2264 iSteps = 1;
2265 }
2266 DEBUGCOUT("Force changes every " << iSteps
2267 << " steps" << std::endl);
2268
2269 } else if (HP.IsKeyWord("seed")) {
2270 if (HP.IsKeyWord("time")) {
2271 DEBUGCOUT("(Re)Seeding random numbers with current time ...");
2272 srand(time(0));
2273 } else {
2274 DEBUGCOUT("(Re)Seeding random numbers with given value ...");
2275 srand(HP.GetInt());
2276 }
2277 } else {
2278 break;
2279 }
2280 }
2281
2282 SAFENEWWITHCONSTRUCTOR(pDC,
2283 RandDriveCaller,
2284 RandDriveCaller(pDrvHdl, dAmplitude, dRefVal, dInitialTime, dFinalTime, iSteps));
2285
2286 return pDC;
2287 }
2288
2289 struct MeterDCR : public DriveCallerRead {
2290 DriveCaller *
2291 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2292 };
2293
2294 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2295 MeterDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2296 {
2297 NeedDM(pDM, HP, bDeferred, "meter");
2298
2299 const DriveHandler* pDrvHdl = 0;
2300 if (pDM != 0) {
2301 pDrvHdl = pDM->pGetDrvHdl();
2302 }
2303
2304 DriveCaller *pDC = 0;
2305
2306 /* spike every N steps */
2307 doublereal dInitialTime = HP.GetReal();
2308 DEBUGCOUT("Initial time: " << dInitialTime << std::endl);
2309
2310 doublereal dFinalTime = std::numeric_limits<double>::max();
2311 if (!HP.IsKeyWord("forever")) {
2312 dFinalTime = HP.GetReal();
2313 }
2314 DEBUGCOUT("Final time: " << dFinalTime << std::endl);
2315
2316 /* Type of random number (additional data) */
2317 integer iSteps = 1;
2318 while (true) {
2319 if (HP.IsKeyWord("steps")) {
2320 iSteps = HP.GetInt();
2321 if (iSteps <= 0) {
2322 silent_cerr("Warning: Steps number " << iSteps
2323 << " is illegal; resorting to default value" << std::endl);
2324 iSteps = 1;
2325 }
2326 DEBUGCOUT("Force changes every " << iSteps
2327 << " steps" << std::endl);
2328 } else {
2329 break;
2330 }
2331 }
2332
2333 SAFENEWWITHCONSTRUCTOR(pDC,
2334 MeterDriveCaller,
2335 MeterDriveCaller(pDrvHdl, dInitialTime, dFinalTime, iSteps));
2336
2337 return pDC;
2338 }
2339
2340 struct ClosestNextDCR : public DriveCallerRead {
2341 DriveCaller *
2342 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2343 };
2344
2345 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2346 ClosestNextDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2347 {
2348 NeedDM(pDM, HP, bDeferred, "closest next");
2349
2350 const DriveHandler* pDrvHdl = 0;
2351 if (pDM != 0) {
2352 pDrvHdl = pDM->pGetDrvHdl();
2353 }
2354
2355 DriveCaller *pDC = 0;
2356
2357 doublereal dInitialTime = HP.GetReal();
2358 DEBUGCOUT("Initial time: " << dInitialTime << std::endl);
2359
2360 doublereal dFinalTime = std::numeric_limits<double>::max();
2361 if (!HP.IsKeyWord("forever")) {
2362 dFinalTime = HP.GetReal();
2363 }
2364 DEBUGCOUT("Final time: " << dFinalTime << std::endl);
2365
2366 const DriveCaller *pIncrement = HP.GetDriveCaller(bDeferred);
2367
2368 SAFENEWWITHCONSTRUCTOR(pDC,
2369 ClosestNextDriveCaller,
2370 ClosestNextDriveCaller(pDrvHdl, dInitialTime, dFinalTime,
2371 pIncrement));
2372
2373 return pDC;
2374 }
2375
2376 struct DirectDCR : public DriveCallerRead {
2377 DriveCaller *
2378 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2379 };
2380
2381 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2382 DirectDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2383 {
2384 NeedDM(pDM, HP, bDeferred, "direct");
2385
2386 const DriveHandler* pDrvHdl = 0;
2387 if (pDM != 0) {
2388 pDrvHdl = pDM->pGetDrvHdl();
2389 }
2390
2391 DriveCaller *pDC = 0;
2392
2393 SAFENEWWITHCONSTRUCTOR(pDC,
2394 DirectDriveCaller,
2395 DirectDriveCaller(pDrvHdl));
2396
2397 return pDC;
2398 }
2399
2400 struct PiecewiseLinearDCR : public DriveCallerRead {
2401 DriveCaller *
2402 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2403 };
2404
2405 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2406 PiecewiseLinearDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2407 {
2408 NeedDM(pDM, HP, bDeferred, "piecewise linear");
2409
2410 const DriveHandler* pDrvHdl = 0;
2411 if (pDM != 0) {
2412 pDrvHdl = pDM->pGetDrvHdl();
2413 }
2414
2415 DriveCaller *pDC = 0;
2416
2417 /* Lineare a pezzi */
2418 unsigned int n = HP.GetInt();
2419 DEBUGCOUT("number of points: " << n << std::endl);
2420
2421 if (n < 2) {
2422 silent_cerr("Need at least two points for piecewise linear drive at line "
2423 << HP.GetLineData() << std::endl);
2424 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2425 }
2426
2427 doublereal *p = 0;
2428 SAFENEWARR(p, doublereal, 2*n);
2429 p[0] = HP.GetReal();
2430 p[n] = HP.GetReal();
2431 for (unsigned int i = 1; i < n; i++) {
2432 p[i] = HP.GetReal();
2433 if (p[i] <= p[i-1]) {
2434 silent_cerr("point " << p[i]
2435 << " is smaller than or equal to preceding point " << p[i-1]
2436 << " at line " << HP.GetLineData() << std::endl);
2437 SAFEDELETE(p);
2438 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2439 }
2440 p[i+n] = HP.GetReal();
2441 }
2442
2443 /* allocazione e creazione */
2444 SAFENEWWITHCONSTRUCTOR(pDC,
2445 PiecewiseLinearDriveCaller,
2446 PiecewiseLinearDriveCaller(pDrvHdl, n, p));
2447
2448 return pDC;
2449 }
2450
2451 struct StringDCR : public DriveCallerRead {
2452 DriveCaller *
2453 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2454 };
2455
2456 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2457 StringDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2458 {
2459 NeedDM(pDM, HP, bDeferred, "string");
2460
2461 const DriveHandler* pDrvHdl = 0;
2462 if (pDM != 0) {
2463 pDrvHdl = pDM->pGetDrvHdl();
2464 }
2465
2466 DriveCaller *pDC = 0;
2467
2468 /* driver stringa da valutare */
2469 /* lettura dei dati specifici */
2470 std::string s(HP.GetStringWithDelims());
2471
2472 #ifdef USE_EE
2473 std::istringstream in(s);
2474 InputStream In(in);
2475
2476 ExpressionElement *expr = HP.GetMathParser().GetExpr(In);
2477
2478 if (pedantic_out) {
2479 std::string out = EEStrOut(expr);
2480 pedantic_cout("StringDriveCaller: \"" << s << "\" => \"" << out << "\"" << std::endl);
2481 }
2482
2483 /* allocazione e creazione */
2484 SAFENEWWITHCONSTRUCTOR(pDC,
2485 StringDriveCaller,
2486 StringDriveCaller(pDrvHdl, s, expr));
2487
2488 #else // ! USE_EE
2489
2490 // #define TRIM_ALL_SPACES
2491 #define TRIM_ALL_SPACES_BUT_ONE
2492
2493 #if defined(TRIM_ALL_SPACES)
2494 for (std::string::iterator i = s.begin(); i != s.end();) {
2495 if (isspace(*i)) {
2496 i = s.erase(i);
2497
2498 } else {
2499 ++i;
2500 }
2501 }
2502 #elif defined(TRIM_ALL_SPACES_BUT_ONE)
2503 bool bString(false);
2504 for (std::string::iterator i = s.begin(); i != s.end();) {
2505 if (isspace(*i)) {
2506 if (!bString) {
2507 bString = true;
2508 ++i;
2509
2510 } else {
2511 i = s.erase(i);
2512 }
2513
2514 } else {
2515 if (bString) {
2516 bString = false;
2517 }
2518 ++i;
2519 }
2520 }
2521 #endif // TRIM_ALL_SPACES_BUT_ONE
2522
2523 DEBUGCOUT("String to evaluate: \"" << s << '\"' << std::endl);
2524
2525 /* allocazione e creazione */
2526 SAFENEWWITHCONSTRUCTOR(pDC,
2527 StringDriveCaller,
2528 StringDriveCaller(pDrvHdl, s));
2529
2530 #endif // ! USE_EE
2531
2532 return pDC;
2533 }
2534
2535 struct DofDCR : public DriveCallerRead {
2536 DriveCaller *
2537 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2538 };
2539
2540 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2541 DofDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2542 {
2543 NeedDM(pDM, HP, bDeferred, "dof");
2544
2545 const DriveHandler* pDrvHdl = 0;
2546 if (pDM != 0) {
2547 pDrvHdl = pDM->pGetDrvHdl();
2548 }
2549
2550 DriveCaller *pDC = 0;
2551
2552 /* driver legato ad un grado di liberta' nodale */
2553 if (pDM == 0) {
2554 silent_cerr("sorry, since the driver is not owned by a DataManager" << std::endl
2555 << "no DOF dependent drivers are allowed;" << std::endl
2556 << "aborting..." << std::endl);
2557 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2558 }
2559
2560 ScalarDof SD = ReadScalarDof(pDM, HP, true, true);
2561
2562 #ifdef USE_MPI
2563 if (MPI::Is_initialized() && MBDynComm.Get_size() > 1) {
2564 silent_cerr("warning: add explicit connection entry for "
2565 << psNodeNames[SD.pNode->GetNodeType()]
2566 << "(" << SD.pNode->GetLabel() << ") dof drive"
2567 " at line " << HP.GetLineData() << std::endl);
2568 }
2569 #endif /* USE_MPI */
2570
2571 /* Chiamata ricorsiva a leggere il drive supplementare */
2572 DriveCaller* pTmp = 0;
2573 pTmp = HP.GetDriveCaller();
2574
2575 /* allocazione e creazione */
2576 SAFENEWWITHCONSTRUCTOR(pDC,
2577 DofDriveCaller,
2578 DofDriveCaller(pDrvHdl, pTmp, SD));
2579
2580 return pDC;
2581 }
2582
2583 /*
2584 * shared by "node" and "element" private data drives
2585 */
2586 struct SimulationEntityDCR : public DriveCallerRead {
2587 protected:
2588 DriveCaller *
2589 Read(const DataManager* pDM, MBDynParser& HP,
2590 const SimulationEntity *pSE, const std::string& msg);
2591 };
2592
2593 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,const SimulationEntity * pSE,const std::string & msg)2594 SimulationEntityDCR::Read(const DataManager* pDM,
2595 MBDynParser& HP, const SimulationEntity *pSE, const std::string& msg)
2596 {
2597 const DriveHandler* pDrvHdl = pDM->pGetDrvHdl();
2598 DriveCaller *pDC = 0;
2599
2600 unsigned int iIndex = 0;
2601 std::string sIndexName;
2602 if (HP.IsKeyWord("string")) {
2603 sIndexName = HP.GetStringWithDelims();
2604 if (sIndexName.empty()) {
2605 silent_cerr("empty string for " << msg
2606 << " at line " << HP.GetLineData()
2607 << std::endl);
2608 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2609 }
2610 iIndex = pSE->iGetPrivDataIdx(sIndexName.c_str());
2611 if (iIndex == 0) {
2612 silent_cerr("illegal string \"" << sIndexName << "\""
2613 " for " << msg
2614 << " at line " << HP.GetLineData()
2615 << std::endl);
2616 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2617 }
2618
2619 } else if (HP.IsKeyWord("index")) {
2620 silent_cout("\"index\" deprecated for " << msg
2621 << "; use \"string\" instead at line " << HP.GetLineData() << std::endl);
2622
2623 iIndex = HP.GetInt();
2624
2625 } else if (pSE->iGetNumPrivData() == 1) {
2626 iIndex = 1;
2627
2628 } else {
2629 silent_cerr("need a private data index for " << msg
2630 << " at line " << HP.GetLineData() << std::endl);
2631 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2632 }
2633
2634 if (iIndex < 1 || iIndex > pSE->iGetNumPrivData()) {
2635 silent_cerr("illegal index " << iIndex << " for " << msg
2636 << " at line " << HP.GetLineData() << std::endl);
2637 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2638 }
2639
2640 #ifdef USE_MPI
2641 /* FIXME: todo ... */
2642 if (MPI::Is_initialized() && MBDynComm.Get_size() > 1) {
2643 silent_cerr("warning: add explicit connection entry for " << msg
2644 << " at line " << HP.GetLineData() << std::endl);
2645 }
2646 #endif /* USE_MPI */
2647
2648 /* Chiamata ricorsiva a leggere il drive supplementare */
2649 DriveCaller* pTmp = 0;
2650 pTmp = HP.GetDriveCaller();
2651
2652 /* allocazione e creazione */
2653 SAFENEWWITHCONSTRUCTOR(pDC,
2654 PrivDriveCaller,
2655 PrivDriveCaller(pDrvHdl, pTmp, pSE, iIndex, sIndexName.c_str()));
2656
2657 return pDC;
2658 }
2659
2660 struct ElementDCR : public SimulationEntityDCR {
2661 DriveCaller *
2662 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2663 };
2664
2665 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2666 ElementDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2667 {
2668 NeedDM(pDM, HP, bDeferred, "element");
2669
2670 /* driver legato ai dati privati di un elemento */
2671 if (pDM == 0) {
2672 silent_cerr("since the driver is not owned by a DataManager" << std::endl
2673 << "no element dependent drivers are allowed;" << std::endl
2674 << "aborting..." << std::endl);
2675 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2676 }
2677
2678 unsigned uLabel = HP.GetInt();
2679 KeyTable Kel(HP, psReadElemsElems);
2680 int k = HP.IsKeyWord();
2681 if (k == -1) {
2682 const char *s = HP.GetString();
2683 silent_cerr("unknown element type \"" << s
2684 << "\" at line " << HP.GetLineData()
2685 << std::endl);
2686 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2687 }
2688
2689 /* Type(Label) */
2690 std::ostringstream os;
2691 os << psElemNames[Elem::Type(k)] << "(" << uLabel << ")";
2692
2693 const Elem *pElem = pDM->pFindElem(Elem::Type(k), uLabel);
2694 if (pElem == 0) {
2695 silent_cerr("unable to find " << os.str() << " at line "
2696 << HP.GetLineData() << std::endl);
2697 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2698 }
2699
2700 return SimulationEntityDCR::Read(pDM, HP, pElem, os.str());
2701 }
2702
2703 struct NodeDCR : public SimulationEntityDCR {
2704 DriveCaller *
2705 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2706 };
2707
2708 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2709 NodeDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2710 {
2711 NeedDM(pDM, HP, bDeferred, "node");
2712
2713 /* driver legato ai dati privati di un nodo */
2714 if (pDM == 0) {
2715 silent_cerr("since the driver is not owned by a DataManager" << std::endl
2716 << "no node dependent drivers are allowed;" << std::endl
2717 << "aborting..." << std::endl);
2718 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2719 }
2720
2721 unsigned uLabel = HP.GetInt();
2722 KeyTable Kel(HP, psReadNodesNodes);
2723 int k = HP.IsKeyWord();
2724 if (k == -1) {
2725 const char *s = HP.GetString();
2726 silent_cerr("unknown node type \"" << s
2727 << "\" at line " << HP.GetLineData()
2728 << std::endl);
2729 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2730 }
2731
2732 /* Type(Label) */
2733 std::ostringstream os;
2734 os << psNodeNames[Elem::Type(k)] << "(" << uLabel << ")";
2735
2736 const Node *pNode = pDM->pFindNode(Node::Type(k), uLabel);
2737 if (pNode == 0) {
2738 silent_cerr("unable to find " << os.str() << " at line "
2739 << HP.GetLineData() << std::endl);
2740 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2741 }
2742
2743 return SimulationEntityDCR::Read(pDM, HP, pNode, os.str());
2744 }
2745
2746 struct DriveDCR : public DriveCallerRead {
2747 DriveCaller *
2748 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2749 };
2750
2751 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2752 DriveDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2753 {
2754 const DriveHandler* pDrvHdl = 0;
2755 if (pDM != 0) {
2756 pDrvHdl = pDM->pGetDrvHdl();
2757 }
2758
2759 DriveCaller *pDC = 0;
2760
2761 DriveCaller *pD1 = HP.GetDriveCaller(bDeferred);
2762 DriveCaller *pD2 = HP.GetDriveCaller(bDeferred);
2763
2764 SAFENEWWITHCONSTRUCTOR(pDC,
2765 DriveDriveCaller,
2766 DriveDriveCaller(pDrvHdl, pD1, pD2));
2767
2768 return pDC;
2769 }
2770
2771 struct SHDCR : public DriveCallerRead {
2772 DriveCaller *
2773 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2774 };
2775
2776 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2777 SHDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2778 {
2779 const DriveHandler* pDrvHdl = 0;
2780 if (pDM != 0) {
2781 pDrvHdl = pDM->pGetDrvHdl();
2782 }
2783
2784 DriveCaller *pDC = 0;
2785
2786 DriveCaller *pFunc = HP.GetDriveCaller(bDeferred);
2787 DriveCaller *pTrigger = HP.GetDriveCaller(bDeferred);
2788
2789 doublereal dVal0 = 0.;
2790 if (HP.IsKeyWord("initial" "value")) {
2791 dVal0 = HP.GetReal();
2792 }
2793
2794 SAFENEWWITHCONSTRUCTOR(pDC,
2795 SHDriveCaller,
2796 SHDriveCaller(pDrvHdl, pFunc, pTrigger, dVal0));
2797
2798 return pDC;
2799 }
2800
2801 struct ArrayDCR : public DriveCallerRead {
2802 DriveCaller *
2803 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2804 };
2805
2806 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2807 ArrayDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2808 {
2809 const DriveHandler* pDrvHdl = 0;
2810 if (pDM != 0) {
2811 pDrvHdl = pDM->pGetDrvHdl();
2812 }
2813
2814 DriveCaller *pDC = 0;
2815
2816 /* driver legato ad un grado di liberta' nodale */
2817 unsigned short int iNumDr = (unsigned short int)HP.GetInt();
2818 if (iNumDr == 0) {
2819 silent_cerr("Sorry, at least one driver is required" << std::endl);
2820 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2821
2822 /* creazione di un driver normale mediante chiamata ricorsiva */
2823 } else if (iNumDr == 1) {
2824 pDC = HP.GetDriveCaller();
2825
2826 } else {
2827 DriveArrayCaller::dcv_t DC(iNumDr);
2828 for (int i = 0; i < iNumDr; i++) {
2829 DC[i] = HP.GetDriveCaller();
2830 }
2831
2832 /* allocazione e creazione array */
2833 SAFENEWWITHCONSTRUCTOR(pDC,
2834 DriveArrayCaller,
2835 DriveArrayCaller(pDrvHdl, DC));
2836 }
2837
2838 return pDC;
2839 }
2840
2841 struct FileDCR : public DriveCallerRead {
2842 DriveCaller *
2843 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2844 };
2845
2846 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2847 FileDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2848 {
2849 NeedDM(pDM, HP, bDeferred, "file");
2850
2851 /* driver legato ai driver */
2852 if (pDM == 0) {
2853 silent_cerr("sorry, since the driver is not owned by a DataManager" << std::endl
2854 << "no driver dependent drivers are allowed;" << std::endl
2855 << "aborting..." << std::endl);
2856 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2857 }
2858
2859 const DriveHandler* pDrvHdl = pDM->pGetDrvHdl();
2860 DriveCaller *pDC = 0;
2861
2862 /* drive file */
2863 /* lettura dei dati specifici */
2864 unsigned int uL = HP.GetInt();
2865 FileDrive* pDrv = dynamic_cast<FileDrive*>(pDM->pFindDrive(Drive::FILEDRIVE, uL));
2866 if (pDrv == 0) {
2867 silent_cerr("line " << HP.GetLineData()
2868 << ": can't find FileDrive(" << uL << ")" << std::endl);
2869 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2870 }
2871
2872 integer id = 1;
2873
2874 const char *s = HP.IsWord(fileDriveCallerTypeWordSet);
2875 if (s != NULL) {
2876 FileDriveCallerTypeMap::iterator it = fileDriveCallerTypeMap.find(std::string(s));
2877 id = it->second->Read(pDM, HP, pDrv);
2878 } else {
2879 if (HP.IsArg()) {
2880 id = HP.GetInt(id);
2881 if (id < 1 || id > pDrv->iGetNumDrives()) {
2882 silent_cerr("line " << HP.GetLineData()
2883 << ": invalid column number " << id
2884 << " (must be between 1 and "
2885 << pDrv->iGetNumDrives() << ")" << std::endl);
2886 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2887 }
2888 }
2889 }
2890
2891 doublereal da = 1.;
2892 if (HP.IsKeyWord("amplitude")) {
2893 da = HP.GetReal();
2894 }
2895
2896 /* allocazione e creazione */
2897 SAFENEWWITHCONSTRUCTOR(pDC,
2898 FileDriveCaller,
2899 FileDriveCaller(pDrvHdl, pDrv, id, da));
2900
2901 return pDC;
2902 }
2903
2904 /*----------------------------------------------------------------------------
2905 management of FileDriveCaller type
2906 ------------------------------------------------------------------------------
2907
2908 Coded by Luca Conti (May 2017)
2909 */
2910
2911 FileDriveCallerTypeMap fileDriveCallerTypeMap;
2912 FileDriveCallerTypeWordSet fileDriveCallerTypeWordSet;
2913
2914 /* FileDriveCaller type parsing checker: allows the parser
2915 to understand if the next keyword is a FileDriveCaller type */
IsWord(const std::string & s) const2916 bool FileDriveCallerTypeWordSet::IsWord(const std::string& s) const {
2917 return fileDriveCallerTypeMap.find(std::string(s)) != fileDriveCallerTypeMap.end();
2918 };
2919
setFileDriveCallerType(const char * name,FileDriveCallerTypeReader * rf)2920 bool setFileDriveCallerType(const char *name, FileDriveCallerTypeReader *rf){
2921 pedantic_cout("registering FileDriveCaller type \"" << name << "\""
2922 << std::endl );
2923 return fileDriveCallerTypeMap.insert(FileDriveCallerTypeMap::value_type(name, rf)).second;
2924 }
2925
DestroyFileDriveCallerTypes(void)2926 void DestroyFileDriveCallerTypes(void){
2927 for (FileDriveCallerTypeMap::iterator i = fileDriveCallerTypeMap.begin(); i != fileDriveCallerTypeMap.end(); ++i) {
2928 delete i->second;
2929 }
2930 fileDriveCallerTypeMap.clear();
2931 }
2932
2933 /*---------------------------------------------------------------------------*/
2934
2935 struct PeriodicDCR : public DriveCallerRead {
2936 DriveCaller *
2937 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2938 };
2939
2940 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2941 PeriodicDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2942 {
2943 NeedDM(pDM, HP, bDeferred, "periodic");
2944
2945 /* driver legato ai driver */
2946 if (pDM == 0) {
2947 silent_cerr("sorry, since the driver is not owned by a DataManager" << std::endl
2948 << "no driver dependent drivers are allowed;" << std::endl
2949 << "aborting..." << std::endl);
2950 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2951 }
2952
2953 const DriveHandler* pDrvHdl = pDM->pGetDrvHdl();
2954 DriveCaller *pDC = 0;
2955
2956 doublereal dT0 = HP.GetReal();
2957 doublereal dPeriod = HP.GetReal();
2958 if (dPeriod <= 0.) {
2959 silent_cerr("PeriodicDriveCaller: invalid negative or null period at line " << HP.GetLineData() << std::endl);
2960 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2961 }
2962
2963 const DriveCaller *pDC1 = HP.GetDriveCaller();
2964
2965 /* allocazione e creazione */
2966 SAFENEWWITHCONSTRUCTOR(pDC,
2967 PeriodicDriveCaller,
2968 PeriodicDriveCaller(pDrvHdl, pDC1, dT0, dPeriod));
2969
2970 return pDC;
2971 }
2972
2973
2974 struct PostponedDCR : public DriveCallerRead {
2975 DriveCaller *
2976 Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred);
2977 };
2978
2979 DriveCaller *
Read(const DataManager * pDM,MBDynParser & HP,bool bDeferred)2980 PostponedDCR::Read(const DataManager* pDM, MBDynParser& HP, bool bDeferred)
2981 {
2982 integer label = HP.GetInt();
2983 if (label < 0) {
2984 silent_cerr("PostponedDriveCaller: invalid negative label \"" << label << "\" at line " << HP.GetLineData() << std::endl);
2985 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
2986 }
2987
2988 /* allocazione e creazione */
2989 DriveCaller *pDC = 0;
2990 SAFENEWWITHCONSTRUCTOR(pDC,
2991 PostponedDriveCaller,
2992 PostponedDriveCaller(HP, unsigned(label)));
2993
2994 return pDC;
2995 }
2996
2997
2998
2999 static unsigned d_done;
3000
3001 void
InitDriveData(void)3002 InitDriveData(void)
3003 {
3004 if (::d_done++ > 0) {
3005 return;
3006 }
3007
3008 SetDriveData("fixed" "step", new FixedStepDR);
3009 SetDriveData("variable" "step", new VariableStepDR);
3010 #ifdef USE_SOCKET
3011 SetDriveData("socket", new SocketDR);
3012 SetDriveData("socket" "stream", new StreamDR("socket stream"));
3013 SetDriveData("rtai" "input", new StreamDR("RTAI input"));
3014 SetDriveData("stream", new StreamDR);
3015 #endif // USE_SOCKET
3016 SetDriveData("buffer" "stream", new BufferStreamDR);
3017
3018 /* NOTE: add here initialization of new built-in drives;
3019 * alternative ways to register new custom drives are:
3020 * - call SetDriveData() from anywhere in the code
3021 * - write a module that calls SetDriveData() from inside a function
3022 * called module_init(), and run-time load it using "module load"
3023 * in the input file.
3024 */
3025 }
3026
3027 void
DestroyDriveData(void)3028 DestroyDriveData(void)
3029 {
3030 if (::d_done == 0) {
3031 silent_cerr("DestroyDriveData() called once too many" << std::endl);
3032 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
3033 }
3034
3035 if (--::d_done > 0) {
3036 return;
3037 }
3038
3039 /* free stuff */
3040 for (DriveFuncMapType::iterator i = DriveFuncMap.begin(); i != DriveFuncMap.end(); ++i) {
3041 delete i->second;
3042 }
3043 DriveFuncMap.clear();
3044 }
3045
3046
3047 static unsigned dc_done;
3048
3049 void
InitDriveCallerData(void)3050 InitDriveCallerData(void)
3051 {
3052 if (::dc_done++ > 0) {
3053 return;
3054 }
3055
3056 SetDriveCallerData("array", new ArrayDCR);
3057 SetDriveCallerData("closest" "next", new ClosestNextDCR);
3058 SetDriveCallerData("const", new ConstDCR);
3059 SetDriveCallerData("cosine", new CosineDCR);
3060 SetDriveCallerData("cubic", new CubicDCR);
3061 SetDriveCallerData("direct", new DirectDCR);
3062 SetDriveCallerData("dof", new DofDCR);
3063 SetDriveCallerData("double" "ramp", new DoubleRampDCR);
3064 SetDriveCallerData("double" "step", new DoubleStepDCR);
3065 SetDriveCallerData("drive", new DriveDCR);
3066 SetDriveCallerData("element", new ElementDCR);
3067 SetDriveCallerData("exponential", new ExponentialDCR);
3068 SetDriveCallerData("file", new FileDCR);
3069 SetDriveCallerData("fourier" "series", new FourierSeriesDCR);
3070 SetDriveCallerData("frequency" "sweep", new FrequencySweepDCR);
3071 SetDriveCallerData("function", new FunctionDCR);
3072 #ifdef USE_GINAC
3073 SetDriveCallerData("ginac", new GiNaCDCR);
3074 #endif // USE_GINAC
3075 SetDriveCallerData("linear", new LinearDCR);
3076 SetDriveCallerData("meter", new MeterDCR);
3077 SetDriveCallerData("mult", new MultDCR);
3078 SetDriveCallerData("node", new NodeDCR);
3079 SetDriveCallerData("null", new NullDCR);
3080 SetDriveCallerData("one", new OneDCR); /* deprecated */
3081 SetDriveCallerData("parabolic", new ParabolicDCR);
3082 SetDriveCallerData("periodic", new PeriodicDCR);
3083 SetDriveCallerData("piecewise" "linear", new PiecewiseLinearDCR);
3084 SetDriveCallerData("postponed", new PostponedDCR);
3085 SetDriveCallerData("ramp", new RampDCR);
3086 SetDriveCallerData("random", new RandomDCR);
3087 SetDriveCallerData("sample" "and" "hold", new SHDCR);
3088 SetDriveCallerData("sine", new SineDCR);
3089 SetDriveCallerData("step", new StepDCR);
3090 SetDriveCallerData("string", new StringDCR);
3091 SetDriveCallerData("tanh", new TanhDCR);
3092 SetDriveCallerData("time", new TimeDCR);
3093 SetDriveCallerData("timestep", new TimeStepDCR);
3094 SetDriveCallerData("unit", new OneDCR);
3095
3096 /* NOTE: add here initialization of new built-in drive callers;
3097 * alternative ways to register new custom drive callers are:
3098 * - call SetDriveCallerData() from anywhere in the code
3099 * - write a module that calls SetDriveCallerData() from inside a function
3100 * called module_init(), and run-time load it using "module load"
3101 * in the input file.
3102 */
3103 #ifdef STATIC_MODULES
3104 #ifdef USE_OCTAVE
3105 mbdyn_octave_set();
3106 #endif // USE_OCTAVE
3107 nodedistdrive_set();
3108 minmaxdrive_set();
3109 #endif // STATIC_MODULES
3110 }
3111
3112 void
DestroyDriveCallerData(void)3113 DestroyDriveCallerData(void)
3114 {
3115 if (::dc_done == 0) {
3116 silent_cerr("DestroyDriveCallerData() called once too many" << std::endl);
3117 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
3118 }
3119
3120 if (--::dc_done > 0) {
3121 return;
3122 }
3123
3124 /* free stuff */
3125 for (DriveCallerFuncMapType::iterator i = DriveCallerFuncMap.begin(); i != DriveCallerFuncMap.end(); ++i) {
3126 delete i->second;
3127 }
3128 DriveCallerFuncMap.clear();
3129 }
3130