1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/mbdyn/base/tpldrive_impl.cc,v 1.27 2017/01/12 14:46:11 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 "myassert.h"
35 #include "mynewmem.h"
36
37 #include "dataman.h"
38 #include "tpldrive_impl.h"
39 #include "reffrm.h"
40
41 /* ZeroTplDriveCaller<T> defined in "tpldrive_impl.h",
42 * which includes "tpldrive.h" */
43
44 template <class T>
45 class NullTDCR : public TplDriveCallerRead<T> {
46 public:
47 virtual TplDriveCaller<T> *
Read(const DataManager * pDM,MBDynParser & HP)48 Read(const DataManager* pDM, MBDynParser& HP) {
49 TplDriveCaller<T>* pTplDC = 0;
50
51 SAFENEW(pTplDC, ZeroTplDriveCaller<T>);
52
53 return pTplDC;
54 };
55 };
56
57 template <class T>
58 class ZeroTDCR : public NullTDCR<T> {
59 public:
60 virtual TplDriveCaller<T> *
Read(const DataManager * pDM,MBDynParser & HP)61 Read(const DataManager* pDM, MBDynParser& HP) {
62 silent_cerr("\"zero\" template drive caller "
63 "at line " << HP.GetLineData() << " is deprecated; "
64 "use \"null\" instead" << std::endl);
65
66 return NullTDCR<T>::Read(pDM, HP);
67 };
68 };
69
70 /* ZeroTplDriveCaller - end */
71
72
73 /* SingleTplDriveCaller - begin */
74
75 template <class T>
76 class SingleTDCR : public TplDriveCallerRead<T> {
77 public:
78 virtual TplDriveCaller<T> *
Read(const DataManager * pDM,MBDynParser & HP)79 Read(const DataManager* pDM, MBDynParser& HP) {
80 T t(mb_zero<T>());
81
82 t = GetT(HP, t);
83
84 DriveCaller* pDC = HP.GetDriveCaller();
85
86 TplDriveCaller<T>* pTplDC = 0;
87
88 SAFENEWWITHCONSTRUCTOR(pTplDC,
89 SingleTplDriveCaller<T>,
90 SingleTplDriveCaller<T>(pDC, t));
91
92 return pTplDC;
93 };
94 };
95
96 /* SingleTplDriveCaller - end */
97
98
99 /* CompTplDriveCaller - begin */
100
101 template <class T>
102 class CompTplDriveCaller : public TplDriveCaller<T>, public DriveOwner {
103 protected:
104 std::vector<DriveCaller *> m_dc;
105
106 public:
CompTplDriveCaller(std::vector<DriveCaller * > & dc)107 CompTplDriveCaller(std::vector<DriveCaller *>& dc)
108 : m_dc(dc)
109 {
110 if (typeid(T) == typeid(Vec3)) {
111 if (dc.size() != 3) {
112 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
113 }
114
115 } else if (typeid(T) == typeid(Vec6)) {
116 if (dc.size() != 6) {
117 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
118 }
119
120 } else {
121 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
122 }
123 };
124
~CompTplDriveCaller(void)125 ~CompTplDriveCaller(void) {
126 for (unsigned i = 0; i < m_dc.size(); i++) {
127 delete m_dc[i];
128 }
129 };
130
131 /* copia */
pCopy(void) const132 virtual TplDriveCaller<T>* pCopy(void) const {
133 typedef CompTplDriveCaller<T> dc;
134 TplDriveCaller<T>* pDC = 0;
135
136 std::vector<DriveCaller *> tmpdc(m_dc.size());
137
138 for (unsigned i = 0; i < m_dc.size(); i++) {
139 tmpdc[i] = m_dc[i]->pCopy();
140 }
141
142 SAFENEWWITHCONSTRUCTOR(pDC, dc, dc(tmpdc));
143
144 return pDC;
145 };
146
147 /* Scrive il contributo del DriveCaller al file di restart */
Restart(std::ostream & out) const148 virtual std::ostream& Restart(std::ostream& out) const {
149 out << "component";
150
151 for (unsigned i = 0; i < m_dc.size(); i++) {
152 out << ", ", m_dc[i]->Restart(out);
153 }
154
155 return out;
156 };
157
Restart_int(std::ostream & out) const158 virtual std::ostream& Restart_int(std::ostream& out) const {
159 for (unsigned i = 0; i < m_dc.size(); i++) {
160 out << ", ", m_dc[i]->Restart(out);
161 }
162
163 return out;
164 };
165
Get(const doublereal & dVar) const166 inline T Get(const doublereal& dVar) const {
167 T t;
168
169 for (unsigned i = 0; i < m_dc.size(); i++) {
170 t(i + 1) = m_dc[i]->dGet(dVar);
171 }
172
173 return t;
174 };
175
Get(void) const176 inline T Get(void) const {
177 T t;
178
179 for (unsigned i = 0; i < m_dc.size(); i++) {
180 t(i + 1) = m_dc[i]->dGet();
181 }
182
183 return t;
184 };
185
186 /* this is about drives that are differentiable */
bIsDifferentiable(void) const187 inline bool bIsDifferentiable(void) const {
188 for (unsigned i = 0; i < m_dc.size(); i++) {
189 if (!m_dc[i]->bIsDifferentiable()) {
190 return false;
191 }
192 }
193
194 return true;
195 };
196
GetP(void) const197 inline T GetP(void) const {
198 T t;
199
200 for (unsigned i = 0; i < m_dc.size(); i++) {
201 t(i + 1) = m_dc[i]->dGetP();
202 }
203
204 return t;
205 };
206
getNDrives(void) const207 inline int getNDrives(void) const {
208 return m_dc.size();
209 };
210 };
211
212 template <>
213 class CompTplDriveCaller<Mat3x3> : public TplDriveCaller<Mat3x3>, public DriveOwner {
214 protected:
215 std::vector<DriveCaller *> m_dc;
216
217 public:
CompTplDriveCaller(std::vector<DriveCaller * > & dc)218 CompTplDriveCaller(std::vector<DriveCaller *>& dc)
219 : m_dc(dc)
220 {
221 if (dc.size() != 9) {
222 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
223 }
224 };
225
~CompTplDriveCaller(void)226 ~CompTplDriveCaller(void) {
227 for (unsigned i = 0; i < m_dc.size(); i++) {
228 delete m_dc[i];
229 }
230 };
231
232 /* copia */
pCopy(void) const233 virtual TplDriveCaller<Mat3x3>* pCopy(void) const {
234 typedef CompTplDriveCaller<Mat3x3> dc;
235 TplDriveCaller<Mat3x3>* pDC = 0;
236
237 std::vector<DriveCaller *> tmpdc(m_dc.size());
238
239 for (unsigned i = 0; i < m_dc.size(); i++) {
240 tmpdc[i] = m_dc[i]->pCopy();
241 }
242
243 SAFENEWWITHCONSTRUCTOR(pDC, dc, dc(tmpdc));
244
245 return pDC;
246 };
247
248 /* Scrive il contributo del DriveCaller al file di restart */
Restart(std::ostream & out) const249 virtual std::ostream& Restart(std::ostream& out) const {
250 out << "component";
251
252 for (unsigned i = 0; i < m_dc.size(); i++) {
253 out << ", ", m_dc[i]->Restart(out);
254 }
255
256 return out;
257 };
258
Restart_int(std::ostream & out) const259 virtual std::ostream& Restart_int(std::ostream& out) const {
260 for (unsigned i = 0; i < m_dc.size(); i++) {
261 out << ", ", m_dc[i]->Restart(out);
262 }
263
264 return out;
265 };
266
Get(const doublereal & dVar) const267 inline Mat3x3 Get(const doublereal& dVar) const {
268 Mat3x3 t;
269
270 for (unsigned i = 0; i < m_dc.size(); i++) {
271 t(i/3 + 1, i%3 + 1) = m_dc[i]->dGet(dVar);
272 }
273
274 return t;
275 };
276
Get(void) const277 inline Mat3x3 Get(void) const {
278 Mat3x3 t;
279
280 for (unsigned i = 0; i < m_dc.size(); i++) {
281 t(i/3 + 1, i%3 + 1) = m_dc[i]->dGet();
282 }
283
284 return t;
285 };
286
287 /* this is about drives that are differentiable */
bIsDifferentiable(void) const288 inline bool bIsDifferentiable(void) const {
289 for (unsigned i = 0; i < m_dc.size(); i++) {
290 if (!m_dc[i]->bIsDifferentiable()) {
291 return false;
292 }
293 }
294
295 return true;
296 };
297
GetP(void) const298 inline Mat3x3 GetP(void) const {
299 Mat3x3 t;
300
301 for (unsigned i = 0; i < m_dc.size(); i++) {
302 t(i/3 + 1, i%3 + 1) = m_dc[i]->dGetP();
303 }
304
305 return t;
306 };
307
getNDrives(void) const308 inline int getNDrives(void) const {
309 return m_dc.size();
310 };
311 };
312
313 template <>
314 class CompTplDriveCaller<Mat6x6> : public TplDriveCaller<Mat6x6>, public DriveOwner {
315 protected:
316 std::vector<DriveCaller *> m_dc;
317
318 public:
CompTplDriveCaller(std::vector<DriveCaller * > & dc)319 CompTplDriveCaller(std::vector<DriveCaller *>& dc)
320 : m_dc(dc)
321 {
322 if (dc.size() != 36) {
323 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
324 }
325 };
326
~CompTplDriveCaller(void)327 ~CompTplDriveCaller(void) {
328 for (unsigned i = 0; i < m_dc.size(); i++) {
329 delete m_dc[i];
330 }
331 };
332
333 /* copia */
pCopy(void) const334 virtual TplDriveCaller<Mat6x6>* pCopy(void) const {
335 typedef CompTplDriveCaller<Mat6x6> dc;
336 TplDriveCaller<Mat6x6>* pDC = 0;
337
338 std::vector<DriveCaller *> tmpdc(m_dc.size());
339
340 for (unsigned i = 0; i < m_dc.size(); i++) {
341 tmpdc[i] = m_dc[i]->pCopy();
342 }
343
344 SAFENEWWITHCONSTRUCTOR(pDC, dc, dc(tmpdc));
345
346 return pDC;
347 };
348
349 /* Scrive il contributo del DriveCaller al file di restart */
Restart(std::ostream & out) const350 virtual std::ostream& Restart(std::ostream& out) const {
351 out << "component";
352
353 for (unsigned i = 0; i < m_dc.size(); i++) {
354 out << ", ", m_dc[i]->Restart(out);
355 }
356
357 return out;
358 };
359
Restart_int(std::ostream & out) const360 virtual std::ostream& Restart_int(std::ostream& out) const {
361 for (unsigned i = 0; i < m_dc.size(); i++) {
362 out << ", ", m_dc[i]->Restart(out);
363 }
364
365 return out;
366 };
367
Get(const doublereal & dVar) const368 inline Mat6x6 Get(const doublereal& dVar) const {
369 Mat6x6 t;
370
371 for (unsigned i = 0; i < m_dc.size(); i++) {
372 t(i/6 + 1, i%6 + 1) = m_dc[i]->dGet(dVar);
373 }
374
375 return t;
376 };
377
Get(void) const378 inline Mat6x6 Get(void) const {
379 Mat6x6 t;
380
381 for (unsigned i = 0; i < m_dc.size(); i++) {
382 t(i/6 + 1, i%6 + 1) = m_dc[i]->dGet();
383 }
384
385 return t;
386 };
387
388 /* this is about drives that are differentiable */
bIsDifferentiable(void) const389 inline bool bIsDifferentiable(void) const {
390 for (unsigned i = 0; i < m_dc.size(); i++) {
391 if (!m_dc[i]->bIsDifferentiable()) {
392 return false;
393 }
394 }
395
396 return true;
397 };
398
GetP(void) const399 inline Mat6x6 GetP(void) const {
400 Mat6x6 t;
401
402 for (unsigned i = 0; i < m_dc.size(); i++) {
403 t(i/6 + 1, i%6 + 1) = m_dc[i]->dGetP();
404 }
405
406 return t;
407 };
408
getNDrives(void) const409 inline int getNDrives(void) const {
410 return m_dc.size();
411 };
412 };
413
414 template <class T>
415 class CompTDCR : public TplDriveCallerRead<T> {
416 public:
417 virtual TplDriveCaller<T> *
Read(const DataManager * pDM,MBDynParser & HP)418 Read(const DataManager* pDM, MBDynParser& HP) {
419 std::vector<DriveCaller *> dc;
420 unsigned nr = 0, nc = 1;
421 if (typeid(T) == typeid(Vec3)) {
422 nr = 3;
423
424 } else if (typeid(T) == typeid(Vec6)) {
425 nr = 6;
426
427 } else if (typeid(T) == typeid(Mat3x3)) {
428 nr = 3;
429 nc = 3;
430
431 } else if (typeid(T) == typeid(Mat6x6)) {
432 nr = 6;
433 nc = 6;
434
435 } else {
436 silent_cerr("component template drive used with unknown type" << std::endl);
437 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
438 }
439
440 dc.resize(nr*nc);
441
442 if (nc > 1 && HP.IsKeyWord("sym")) {
443 for (unsigned ir = 0; ir < nr; ir++) {
444 for (unsigned ic = ir; ic < nc; ic++) {
445 if (HP.IsKeyWord("inactive")) {
446 dc[nc*ir + ic] = 0;
447 SAFENEW(dc[nc*ir + ic], NullDriveCaller);
448
449 } else {
450 dc[nc*ir + ic] = HP.GetDriveCaller();
451 }
452
453 if (ic > ir) {
454 dc[nc*ic + ir] = dc[nc*ir + ic]->pCopy();
455 }
456 }
457 }
458
459 } else if (nc > 1 && HP.IsKeyWord("diag")) {
460 for (unsigned ir = 0; ir < nr; ir++) {
461 if (HP.IsKeyWord("inactive")) {
462 dc[nc*ir + ir] = 0;
463 SAFENEW(dc[nc*ir + ir], NullDriveCaller);
464
465 } else {
466 dc[nc*ir + ir] = HP.GetDriveCaller();
467 }
468
469 for (unsigned ic = ir + 1; ic < nc; ic++) {
470 dc[nc*ir + ic] = 0;
471 SAFENEW(dc[nc*ir + ic], NullDriveCaller);
472 dc[nc*ic + ir] = dc[nc*ir + ic]->pCopy();
473 }
474 }
475
476 } else {
477 for (unsigned i = 0; i < dc.size(); i++) {
478 if (HP.IsKeyWord("inactive")) {
479 dc[i] = 0;
480 SAFENEW(dc[i], NullDriveCaller);
481
482 } else {
483 dc[i] = HP.GetDriveCaller();
484 }
485 }
486 }
487
488 TplDriveCaller<T>* pTplDC = 0;
489
490 SAFENEWWITHCONSTRUCTOR(pTplDC,
491 CompTplDriveCaller<T>,
492 CompTplDriveCaller<T>(dc));
493
494 return pTplDC;
495 };
496 };
497
498 /* CompTplDriveCaller - end */
499
500 /* ArrayTplDriveCaller - begin */
501
502 template <class T>
503 struct DrivesArray {
504 DriveCaller* pDriveCaller;
505 T t;
DrivesArrayDrivesArray506 DrivesArray(void) : pDriveCaller(0), t() {};
507 };
508
509 template <class T>
510 class ArrayTplDriveCaller : public TplDriveCaller<T> {
511 protected:
512 std::vector<DrivesArray<T> > m_dc;
513
514 public:
ArrayTplDriveCaller(std::vector<DrivesArray<T>> & dc)515 ArrayTplDriveCaller(std::vector<DrivesArray<T> >& dc)
516 : m_dc(dc) {
517 ASSERT(!dc.empty());
518 };
519
~ArrayTplDriveCaller(void)520 ~ArrayTplDriveCaller(void) {
521 for (unsigned i = 0; i < m_dc.size(); i++) {
522 SAFEDELETE(m_dc[i].pDriveCaller);
523 }
524 };
525
526 /* copia */
pCopy(void) const527 virtual TplDriveCaller<T>* pCopy(void) const {
528 std::vector<DrivesArray<T> > dc(m_dc.size());
529 for (unsigned i = 0; i < m_dc.size(); i++) {
530 dc[i].pDriveCaller = m_dc[i].pDriveCaller->pCopy();
531 dc[i].t = m_dc[i].t;
532 }
533
534 typedef ArrayTplDriveCaller<T> dc_t;
535 TplDriveCaller<T>* pDC = 0;
536
537 SAFENEWWITHCONSTRUCTOR(pDC, dc_t, dc_t(dc));
538
539 return pDC;
540 };
541
542 /* Scrive il contributo del DriveCaller al file di restart */
Restart(std::ostream & out) const543 virtual std::ostream& Restart(std::ostream& out) const {
544 out << "array, " << m_dc.size();
545 for (unsigned i = 0; i < m_dc.size(); i++) {
546 out << ", ",
547 Write(out, m_dc[i].t, ", ") << ", ",
548 m_dc[i].pDriveCaller->Restart(out);
549 }
550 return out;
551 };
552
Restart_int(std::ostream & out) const553 virtual std::ostream& Restart_int(std::ostream& out) const {
554 for (unsigned i = 0; i < m_dc.size(); i++) {
555 out << ", ",
556 Write(out, m_dc[i].t, ", ") << ", ",
557 m_dc[i].pDriveCaller->Restart(out);
558 }
559 return out;
560 };
561
Get(const doublereal & dVar) const562 inline T Get(const doublereal& dVar) const {
563 T v = mb_zero<T>();
564 for (unsigned i = 0; i < m_dc.size(); i++) {
565 v += (m_dc[i].t)*(m_dc[i].pDriveCaller->dGet(dVar));
566 }
567 return v;
568 };
569
Get(void) const570 inline T Get(void) const {
571 T v = mb_zero<T>();
572 for (unsigned i = 0; i < m_dc.size(); i++) {
573 v += (m_dc[i].t)*(m_dc[i].pDriveCaller->dGet());
574 }
575 return v;
576 };
577
bIsDifferentiable(void) const578 inline bool bIsDifferentiable(void) const {
579 for (unsigned i = 0; i < m_dc.size(); i++) {
580 if (!m_dc[i].pDriveCaller->bIsDifferentiable()) {
581 return false;
582 }
583 }
584 return true;
585 };
586
GetP(void) const587 inline T GetP(void) const {
588 T v = mb_zero<T>();
589 for (unsigned i = 0; i < m_dc.size(); i++) {
590 v += (m_dc[i].t)*(m_dc[i].pDriveCaller->dGetP());
591 }
592 return v;
593 };
594
getNDrives(void) const595 inline int getNDrives(void) const {
596 return m_dc.size();
597 };
598 };
599
600 template<>
601 class ArrayTplDriveCaller<doublereal> : public TplDriveCaller<doublereal> {
602 protected:
603 std::vector<DrivesArray<doublereal> > m_dc;
604
605 public:
ArrayTplDriveCaller(std::vector<DrivesArray<doublereal>> dc)606 ArrayTplDriveCaller(std::vector<DrivesArray<doublereal> > dc)
607 : m_dc(dc) {
608 ASSERT(!m_dc.empty());
609 };
610
~ArrayTplDriveCaller(void)611 virtual ~ArrayTplDriveCaller(void) {
612 for (unsigned i = 0; i < m_dc.size(); i++) {
613 SAFEDELETE(m_dc[i].pDriveCaller);
614 }
615 };
616
617 /* copia */
pCopy(void) const618 virtual TplDriveCaller<doublereal>* pCopy(void) const {
619 std::vector<DrivesArray<doublereal> > dc(m_dc.size());
620 for (unsigned i = 0; i < m_dc.size(); i++) {
621 dc[i].pDriveCaller = m_dc[i].pDriveCaller->pCopy();
622 dc[i].t = m_dc[i].t;
623 }
624
625 typedef ArrayTplDriveCaller<doublereal> dc_t;
626 TplDriveCaller<doublereal>* pDC = 0;
627
628 SAFENEWWITHCONSTRUCTOR(pDC, dc_t, dc_t(dc));
629
630 return pDC;
631 };
632
633 /* Scrive il contributo del DriveCaller al file di restart */
Restart(std::ostream & out) const634 virtual std::ostream& Restart(std::ostream& out) const {
635 out << "array, " << m_dc.size();
636 for (unsigned i = 0; i < m_dc.size(); i++) {
637 out << ", ", m_dc[i].pDriveCaller->Restart(out);
638 }
639 return out;
640 };
641
Restart_int(std::ostream & out) const642 virtual std::ostream& Restart_int(std::ostream& out) const {
643 for (unsigned i = 0; i < m_dc.size(); i++) {
644 out << ", ", m_dc[i].pDriveCaller->Restart(out);
645 }
646 return out;
647 };
648
Get(const doublereal & dVar) const649 inline doublereal Get(const doublereal& dVar) const {
650 doublereal v = 0.;
651 for (unsigned i = 0; i < m_dc.size(); i++) {
652 v += m_dc[i].pDriveCaller->dGet(dVar);
653 }
654 return v;
655 };
656
Get(void) const657 inline doublereal Get(void) const {
658 doublereal v = 0.;
659 for (unsigned i = 0; i < m_dc.size(); i++) {
660 v += m_dc[i].pDriveCaller->dGet();
661 }
662 return v;
663 };
664
getNDrives(void) const665 inline int getNDrives(void) const {
666 return m_dc.size();
667 };
668 };
669
670 /* Nota: di questa classe non viene scritta esplicitamente la versione
671 * per reali in quanto il coefficiente moltiplicativo
672 * puo' essere usato per un'ulteriore pesatura del drive */
673
674 template <class T>
675 class ArrayTDCR : public SingleTDCR<T> {
676 public:
677 virtual TplDriveCaller<T> *
Read(const DataManager * pDM,MBDynParser & HP)678 Read(const DataManager* pDM, MBDynParser& HP) {
679 unsigned short int iNumDr = HP.GetInt();
680 if (iNumDr == 0) {
681 silent_cerr("At least one drive is required "
682 "in array template drive" << std::endl);
683 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
684
685 } else if (iNumDr == 1) {
686 return SingleTDCR<T>::Read(pDM, HP);
687 } /* else */
688
689 std::vector<DrivesArray<T> > dc(iNumDr);
690
691 for (unsigned short int i = 0; i < iNumDr; i++) {
692 T t(mb_zero<T>());
693 dc[i].t = GetT(HP, t);
694 dc[i].pDriveCaller = HP.GetDriveCaller();
695 }
696
697 TplDriveCaller<T>* pTplDC = 0;
698
699 SAFENEWWITHCONSTRUCTOR(pTplDC,
700 ArrayTplDriveCaller<T>,
701 ArrayTplDriveCaller<T>(dc));
702
703 return pTplDC;
704 };
705 };
706
707 /* ArrayTplDriveCaller - end */
708
709
710 extern doublereal GetT(MBDynParser& HP, const doublereal& t);
711
GetT(MBDynParser & HP,const T & t)712 template <class T> T GetT(MBDynParser& HP, const T& t)
713 {
714 return HP.Get(t);
715 }
716
717 /* template drive caller containers */
718 typedef std::map<std::string, TplDriveCallerRead<doublereal> *, ltstrcase> DC1DFuncMapType;
719 typedef std::map<std::string, TplDriveCallerRead<Vec3> *, ltstrcase> DC3DFuncMapType;
720 typedef std::map<std::string, TplDriveCallerRead<Vec6> *, ltstrcase> DC6DFuncMapType;
721
722 typedef std::map<std::string, TplDriveCallerRead<Mat3x3> *, ltstrcase> DC3x3DFuncMapType;
723 typedef std::map<std::string, TplDriveCallerRead<Mat6x6> *, ltstrcase> DC6x6DFuncMapType;
724
725 static DC1DFuncMapType DC1DFuncMap;
726 static DC3DFuncMapType DC3DFuncMap;
727 static DC6DFuncMapType DC6DFuncMap;
728
729 static DC3x3DFuncMapType DC3x3DFuncMap;
730 static DC6x6DFuncMapType DC6x6DFuncMap;
731
732 struct DC1DWordSetType : public HighParser::WordSet {
IsWordDC1DWordSetType733 bool IsWord(const std::string& s) const {
734 return ::DC1DFuncMap.find(std::string(s)) != ::DC1DFuncMap.end();
735 };
736 };
737
738 struct DC3DWordSetType : public HighParser::WordSet {
IsWordDC3DWordSetType739 bool IsWord(const std::string& s) const {
740 return ::DC3DFuncMap.find(std::string(s)) != ::DC3DFuncMap.end();
741 };
742 };
743
744 struct DC6DWordSetType : public HighParser::WordSet {
IsWordDC6DWordSetType745 bool IsWord(const std::string& s) const {
746 return ::DC6DFuncMap.find(std::string(s)) != ::DC6DFuncMap.end();
747 };
748 };
749
750 struct DC3x3DWordSetType : public HighParser::WordSet {
IsWordDC3x3DWordSetType751 bool IsWord(const std::string& s) const {
752 return ::DC3x3DFuncMap.find(std::string(s)) != ::DC3x3DFuncMap.end();
753 };
754 };
755
756 struct DC6x6DWordSetType : public HighParser::WordSet {
IsWordDC6x6DWordSetType757 bool IsWord(const std::string& s) const {
758 return ::DC6x6DFuncMap.find(std::string(s)) != ::DC6x6DFuncMap.end();
759 };
760 };
761
762 static DC1DWordSetType DC1DWordSet;
763 static DC3DWordSetType DC3DWordSet;
764 static DC6DWordSetType DC6DWordSet;
765
766 static DC3x3DWordSetType DC3x3DWordSet;
767 static DC6x6DWordSetType DC6x6DWordSet;
768
769 /* template drive caller registration functions: call to register one */
770 bool
SetDC1D(const char * name,TplDriveCallerRead<doublereal> * rf)771 SetDC1D(const char *name, TplDriveCallerRead<doublereal> *rf)
772 {
773 pedantic_cout("registering template drive caller 1D \"" << name << "\""
774 << std::endl );
775 return DC1DFuncMap.insert(DC1DFuncMapType::value_type(name, rf)).second;
776 }
777
778 bool
SetDC3D(const char * name,TplDriveCallerRead<Vec3> * rf)779 SetDC3D(const char *name, TplDriveCallerRead<Vec3> *rf)
780 {
781 pedantic_cout("registering template drive caller 3D \"" << name << "\""
782 << std::endl );
783 return DC3DFuncMap.insert(DC3DFuncMapType::value_type(name, rf)).second;
784 }
785
786 bool
SetDC6D(const char * name,TplDriveCallerRead<Vec6> * rf)787 SetDC6D(const char *name, TplDriveCallerRead<Vec6> *rf)
788 {
789 pedantic_cout("registering template drive caller 6D \"" << name << "\""
790 << std::endl );
791 return DC6DFuncMap.insert(DC6DFuncMapType::value_type(name, rf)).second;
792 }
793
794 bool
SetDC3x3D(const char * name,TplDriveCallerRead<Mat3x3> * rf)795 SetDC3x3D(const char *name, TplDriveCallerRead<Mat3x3> *rf)
796 {
797 pedantic_cout("registering template drive caller 3x3D \"" << name << "\""
798 << std::endl );
799 return DC3x3DFuncMap.insert(DC3x3DFuncMapType::value_type(name, rf)).second;
800 }
801
802 bool
SetDC6x6D(const char * name,TplDriveCallerRead<Mat6x6> * rf)803 SetDC6x6D(const char *name, TplDriveCallerRead<Mat6x6> *rf)
804 {
805 pedantic_cout("registering template drive caller 6x6D \"" << name << "\""
806 << std::endl );
807 return DC6x6DFuncMap.insert(DC6x6DFuncMapType::value_type(name, rf)).second;
808 }
809
810 /* functions that read a template drive caller */
811 TplDriveCaller<doublereal> *
ReadDC1D(const DataManager * pDM,MBDynParser & HP)812 ReadDC1D(const DataManager* pDM, MBDynParser& HP)
813 {
814 const char *s = HP.IsWord(DC1DWordSet);
815 if (s == 0) {
816 s = "single";
817 }
818
819 DC1DFuncMapType::iterator func = DC1DFuncMap.find(std::string(s));
820 if (func == DC1DFuncMap.end()) {
821 silent_cerr("unknown template drive caller 1D type \"" << s << "\" "
822 "at line " << HP.GetLineData() << std::endl);
823 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
824 }
825
826 return func->second->Read(pDM, HP);
827 }
828
829 TplDriveCaller<Vec3> *
ReadDC3D(const DataManager * pDM,MBDynParser & HP)830 ReadDC3D(const DataManager* pDM, MBDynParser& HP)
831 {
832 const char *s = HP.IsWord(DC3DWordSet);
833 if (s == 0) {
834 s = "single";
835 }
836
837 DC3DFuncMapType::iterator func = DC3DFuncMap.find(std::string(s));
838 if (func == DC3DFuncMap.end()) {
839 silent_cerr("unknown template drive caller 3D type \"" << s << "\" "
840 "at line " << HP.GetLineData() << std::endl);
841 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
842 }
843
844 return func->second->Read(pDM, HP);
845 }
846
847 TplDriveCaller<Vec6> *
ReadDC6D(const DataManager * pDM,MBDynParser & HP)848 ReadDC6D(const DataManager* pDM, MBDynParser& HP)
849 {
850 const char *s = HP.IsWord(DC6DWordSet);
851 if (s == 0) {
852 s = "single";
853 }
854
855 DC6DFuncMapType::iterator func = DC6DFuncMap.find(std::string(s));
856 if (func == DC6DFuncMap.end()) {
857 silent_cerr("unknown template drive caller 6D type \"" << s << "\" "
858 "at line " << HP.GetLineData() << std::endl);
859 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
860 }
861
862 return func->second->Read(pDM, HP);
863 }
864
865 TplDriveCaller<Mat3x3> *
ReadDC3x3D(const DataManager * pDM,MBDynParser & HP)866 ReadDC3x3D(const DataManager* pDM, MBDynParser& HP)
867 {
868 const char *s = HP.IsWord(DC3x3DWordSet);
869 if (s == 0) {
870 s = "single";
871 }
872
873 DC3x3DFuncMapType::iterator func = DC3x3DFuncMap.find(std::string(s));
874 if (func == DC3x3DFuncMap.end()) {
875 silent_cerr("unknown template drive caller 3x3D type \"" << s << "\" "
876 "at line " << HP.GetLineData() << std::endl);
877 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
878 }
879
880 return func->second->Read(pDM, HP);
881 }
882
883 TplDriveCaller<Mat6x6> *
ReadDC6x6D(const DataManager * pDM,MBDynParser & HP)884 ReadDC6x6D(const DataManager* pDM, MBDynParser& HP)
885 {
886 const char *s = HP.IsWord(DC6x6DWordSet);
887 if (s == 0) {
888 s = "single";
889 }
890
891 DC6x6DFuncMapType::iterator func = DC6x6DFuncMap.find(std::string(s));
892 if (func == DC6x6DFuncMap.end()) {
893 silent_cerr("unknown template drive caller 6x6D type \"" << s << "\" "
894 "at line " << HP.GetLineData() << std::endl);
895 throw DataManager::ErrGeneric(MBDYN_EXCEPT_ARGS);
896 }
897
898 return func->second->Read(pDM, HP);
899 }
900
901 template <class VM>
902 static TplDriveCaller<Vec3> *
ReadDCVec(const DataManager * pDM,MBDynParser & HP,const ReferenceFrame & rf)903 ReadDCVec(const DataManager* pDM, MBDynParser& HP, const ReferenceFrame& rf)
904 {
905 VM manip(HP, rf);
906
907 HP.PushManip(&manip);
908 TplDriveCaller<Vec3>* pDC = HP.GetTplDriveCaller<Vec3>();
909 if (HP.GetManip() == &manip) {
910 HP.PopManip();
911 }
912
913 return pDC;
914 }
915
916 TplDriveCaller<Vec3> *
ReadDCVecRel(const DataManager * pDM,MBDynParser & HP,const ReferenceFrame & rf)917 ReadDCVecRel(const DataManager* pDM, MBDynParser& HP, const ReferenceFrame& rf)
918 {
919 return ReadDCVec<MBDynParser::VecRelManip>(pDM, HP, rf);
920 }
921
922 TplDriveCaller<Vec3> *
ReadDCVecAbs(const DataManager * pDM,MBDynParser & HP,const ReferenceFrame & rf)923 ReadDCVecAbs(const DataManager* pDM, MBDynParser& HP, const ReferenceFrame& rf)
924 {
925 return ReadDCVec<MBDynParser::VecAbsManip>(pDM, HP, rf);
926 }
927
928 static unsigned done;
929
930 void
InitTplDC(void)931 InitTplDC(void)
932 {
933 if (::done++ > 0) {
934 return;
935 }
936
937 /* null */
938 SetDC1D("null", new NullTDCR<doublereal>);
939 SetDC3D("null", new NullTDCR<Vec3>);
940 SetDC6D("null", new NullTDCR<Vec6>);
941
942 SetDC3x3D("null", new NullTDCR<Mat3x3>);
943 SetDC6x6D("null", new NullTDCR<Mat6x6>);
944
945 /* zero (deprecated) */
946 SetDC1D("zero", new ZeroTDCR<doublereal>);
947 SetDC3D("zero", new ZeroTDCR<Vec3>);
948 SetDC6D("zero", new ZeroTDCR<Vec6>);
949
950 SetDC3x3D("zero", new ZeroTDCR<Mat3x3>);
951 SetDC6x6D("zero", new ZeroTDCR<Mat6x6>);
952
953 /* single */
954 SetDC1D("single", new SingleTDCR<doublereal>);
955 SetDC3D("single", new SingleTDCR<Vec3>);
956 SetDC6D("single", new SingleTDCR<Vec6>);
957
958 SetDC3x3D("single", new SingleTDCR<Mat3x3>);
959 SetDC6x6D("single", new SingleTDCR<Mat6x6>);
960
961 /* component */
962 /* in the scalar case, "single" and "component" are identical */
963 SetDC1D("component", new SingleTDCR<doublereal>);
964 SetDC3D("component", new CompTDCR<Vec3>);
965 SetDC6D("component", new CompTDCR<Vec6>);
966
967 SetDC3x3D("component", new CompTDCR<Mat3x3>);
968 SetDC6x6D("component", new CompTDCR<Mat6x6>);
969
970 /* array */
971 SetDC1D("array", new ArrayTDCR<doublereal>);
972 SetDC3D("array", new ArrayTDCR<Vec3>);
973 SetDC6D("array", new ArrayTDCR<Vec6>);
974
975 SetDC3x3D("array", new ArrayTDCR<Mat3x3>);
976 SetDC6x6D("array", new ArrayTDCR<Mat6x6>);
977 }
978
979 void
DestroyTplDC(void)980 DestroyTplDC(void)
981 {
982 if (::done == 0) {
983 silent_cerr("DestroyTplDC() called once too many" << std::endl);
984 throw ErrGeneric(MBDYN_EXCEPT_ARGS);
985 }
986
987 if (--::done > 0) {
988 return;
989 }
990
991 /* free stuff */
992 for (DC1DFuncMapType::iterator i = DC1DFuncMap.begin(); i != DC1DFuncMap.end(); ++i) {
993 delete i->second;
994 }
995 DC1DFuncMap.clear();
996
997 for (DC3DFuncMapType::iterator i = DC3DFuncMap.begin(); i != DC3DFuncMap.end(); ++i) {
998 delete i->second;
999 }
1000 DC3DFuncMap.clear();
1001
1002 for (DC6DFuncMapType::iterator i = DC6DFuncMap.begin(); i != DC6DFuncMap.end(); ++i) {
1003 delete i->second;
1004 }
1005 DC6DFuncMap.clear();
1006
1007 for (DC3x3DFuncMapType::iterator i = DC3x3DFuncMap.begin(); i != DC3x3DFuncMap.end(); ++i) {
1008 delete i->second;
1009 }
1010 DC3x3DFuncMap.clear();
1011
1012 for (DC6x6DFuncMapType::iterator i = DC6x6DFuncMap.begin(); i != DC6x6DFuncMap.end(); ++i) {
1013 delete i->second;
1014 }
1015 DC6x6DFuncMap.clear();
1016 }
1017
1018