MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
body.cc
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/mbdyn/struct/body.cc,v 1.90 2016/08/08 15:03:40 masarati Exp $ */
2 /*
3  * MBDyn (C) is a multibody analysis code.
4  * http://www.mbdyn.org
5  *
6  * Copyright (C) 1996-2005
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 /* elementi di massa */
33 
34 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
35 
36 #include <limits>
37 
38 #include "body.h"
39 #include "body_vm.h"
40 #include "dataman.h"
41 
42 /* Mass - begin */
43 
44 Mass::Mass(unsigned int uL,
45  const StructDispNode *pNode,
46  doublereal dMass,
47  flag fOut)
48 : Elem(uL, fOut),
49 ElemGravityOwner(uL, fOut),
50 InitialAssemblyElem(uL, fOut),
51 pNode(pNode),
52 dMass(dMass)
53 {
54  ASSERT(pNode != NULL);
55  ASSERT(pNode->GetNodeType() == Node::STRUCTURAL);
56  ASSERT(dMass > 0.);
57 }
58 
59 
60 /* distruttore */
62 {
63  NO_OP;
64 }
65 
66 
67 /* momento statico */
68 Vec3
69 Mass::GetS_int(void) const
70 {
71  return pNode->GetXCurr()*dMass;
72 }
73 
74 
75 /* momento d'inerzia */
76 Mat3x3
77 Mass::GetJ_int(void) const
78 {
79  const Vec3& x = pNode->GetXCurr();
80 
81  return Mat3x3(MatCrossCross, x, x*(-dMass));
82 }
83 
84 
85 /* Scrive il contributo dell'elemento al file di restart */
86 std::ostream&
87 Mass::Restart(std::ostream& out) const
88 {
89  out << " body: " << GetLabel() << ", "
90  << pNode->GetLabel() << ", " << dMass << ';' << std::endl;
91 
92  return out;
93 }
94 
95 
96 /* massa totale */
98 Mass::dGetM(void) const
99 {
100  return dMass;
101 }
102 
103 /* momento statico */
104 Vec3
105 Mass::GetS(void) const
106 {
107  return GetS_int();
108 }
109 
110 /* momento d'inerzia */
111 Mat3x3
112 Mass::GetJ(void) const
113 {
114  return GetJ_int();
115 }
116 
117 /* nodo */
118 const StructDispNode *
119 Mass::pGetNode(void) const
120 {
121  return pNode;
122 }
123 
124 /* Accesso ai dati privati */
125 unsigned int
127 {
128  return 3;
129 }
130 
131 unsigned int
132 Mass::iGetPrivDataIdx(const char *s) const
133 {
134  if (s[1] == '\0') {
135  switch (s[0]) {
136  case 'E':
137  // kinetic energy
138  return 1;
139 
140  case 'V':
141  // potential energy
142  return 2;
143 
144  case 'm':
145  return 3;
146  }
147  }
148 
149  return 0;
150 }
151 
153 Mass::dGetPrivData(unsigned int i) const
154 {
155  switch (i) {
156  case 1: {
157  // kinetic energy
158  const Vec3& Vn = pNode->GetVCurr();
159 
160  return Vn.Dot()*dMass;
161  }
162 
163  case 2: {
164  // potential energy
165  const Vec3& Xn = pNode->GetXCurr();
166 
167  Vec3 GravityAcceleration;
168  if (GravityOwner::bGetGravity(Xn, GravityAcceleration)) {
169  return -Xn.Dot(GravityAcceleration)*dMass;
170  }
171  break;
172  }
173 
174  case 3:
175  // mass
176  return dMass;
177  }
178 
179  return 0.;
180 }
181 
182 void
184 {
185  const RigidBodyKinematics *pRBK = pNode->pGetRBK();
186 
187  Vec3 s0;
188 
189  integer iIdx = 0;
190  if (dynamic_cast<DynamicMass *>(this)) {
191  iIdx = 3;
192  }
193 
194  s0 = pNode->GetXCurr()*dMass;
195 
196  // force
197  Vec3 f;
198  f = pRBK->GetXPP()*dMass;
199 
200  WorkVec.Sub(iIdx + 1, f);
201 }
202 
203 void
207  const doublereal& dCoef)
208 {
209  const RigidBodyKinematics *pRBK = pNode->pGetRBK();
210 
211  integer iIdx = 0;
212  if (dynamic_cast<DynamicMass *>(this)) {
213  iIdx = 3;
214  }
215 
216  // f: delta x
217  Mat3x3 MTmp(MatCross, pRBK->GetWP());
218  MTmp += Mat3x3(MatCrossCross, pRBK->GetW(), pRBK->GetW());
219 
220  WMA.Add(iIdx + 1, 1, MTmp*(dMass*dCoef));
221 }
222 
223 /* Mass - end */
224 
225 
226 /* DynamicMass - begin */
227 
228 DynamicMass::DynamicMass(unsigned int uL,
229  const DynamicStructDispNode* pNode,
230  doublereal dMass,
231  flag fOut)
232 : Elem(uL, fOut),
233 Mass(uL, pNode, dMass, fOut)
234 {
235  NO_OP;
236 }
237 
238 
239 /* distruttore */
241 {
242  NO_OP;
243 }
244 
245 
248  doublereal dCoef,
249  const VectorHandler& XCurr,
250  const VectorHandler& XPrimeCurr)
251 {
252  DEBUGCOUTFNAME("DynamicMass::AssJac");
253 
254  /* Casting di WorkMat */
255  FullSubMatrixHandler& WM = WorkMat.SetFull();
256 
257  Vec3 GravityAcceleration;
259  GravityAcceleration);
260 
261  integer iNumRows = 3;
262  if (pNode->pGetRBK()) {
263  iNumRows = 6;
264  }
265 
266  /* Dimensiona e resetta la matrice di lavoro */
267  WM.ResizeReset(iNumRows, 3);
268 
269  /* Setta gli indici della matrice - le incognite sono ordinate come:
270  * - posizione (3)
271  * - parametri di rotazione (3)
272  * - quantita' di moto (3)
273  * - momento della quantita' di moto
274  * e gli indici sono consecutivi. La funzione pGetFirstPositionIndex()
275  * ritorna il valore del primo indice -1, in modo che l'indice i-esimo
276  * e' dato da iGetFirstPositionIndex()+i */
277  integer iFirstPositionIndex = pNode->iGetFirstPositionIndex();
278  for (integer iCnt = 1; iCnt <= 3; iCnt++) {
279  WM.PutRowIndex(iCnt, iFirstPositionIndex + iCnt);
280  WM.PutColIndex(iCnt, iFirstPositionIndex + iCnt);
281  }
282 
283  if (iNumRows == 6) {
284  integer iFirstMomentumIndex = pNode->iGetFirstMomentumIndex();
285  for (integer iCnt = 1; iCnt <= 3; iCnt++) {
286  WM.PutRowIndex(3 + iCnt, iFirstMomentumIndex + iCnt);
287  }
288  }
289 
290  AssMats(WM, WM, dCoef, g, GravityAcceleration);
291 
292  return WorkMat;
293 }
294 
295 
296 void
298  VariableSubMatrixHandler& WorkMatB,
299  const VectorHandler& XCurr,
300  const VectorHandler& XPrimeCurr)
301 {
302  DEBUGCOUTFNAME("DynamicMass::AssMats");
303 
304  /* Casting di WorkMat */
305  FullSubMatrixHandler& WMA = WorkMatA.SetFull();
306  FullSubMatrixHandler& WMB = WorkMatB.SetFull();
307 
308  Vec3 GravityAcceleration;
310  GravityAcceleration);
311 
312  integer iNumRows = 3;
313  if (g) {
314  iNumRows = 6;
315  }
316 
317  /* Dimensiona e resetta la matrice di lavoro */
318  WMA.ResizeReset(iNumRows, 3);
319  WMB.ResizeReset(3, 3);
320 
321  /* Setta gli indici della matrice - le incognite sono ordinate come:
322  * - posizione (3)
323  * - parametri di rotazione (3)
324  * - quantita' di moto (3)
325  * - momento della quantita' di moto
326  * e gli indici sono consecutivi. La funzione pGetFirstPositionIndex()
327  * ritorna il valore del primo indice -1, in modo che l'indice i-esimo
328  * e' dato da iGetFirstPositionIndex()+i */
329  integer iFirstPositionIndex = pNode->iGetFirstPositionIndex();
330  for (integer iCnt = 1; iCnt <= 3; iCnt++) {
331  WMA.PutRowIndex(iCnt, iFirstPositionIndex + iCnt);
332  WMA.PutColIndex(iCnt, iFirstPositionIndex + iCnt);
333 
334  WMB.PutRowIndex(iCnt, iFirstPositionIndex + iCnt);
335  WMB.PutColIndex(iCnt, iFirstPositionIndex + iCnt);
336  }
337 
338  if (g) {
339  integer iFirstMomentumIndex = pNode->iGetFirstMomentumIndex();
340  for (integer iCnt = 1; iCnt <= 3; iCnt++) {
341  WMA.PutRowIndex(3 + iCnt, iFirstMomentumIndex + iCnt);
342  }
343  }
344 
345  AssMats(WMA, WMB, 1., g, GravityAcceleration);
346 }
347 
348 
349 void
352  doublereal dCoef,
353  bool bGravity,
354  const Vec3& GravityAcceleration)
355 {
356  DEBUGCOUTFNAME("DynamicMass::AssMats");
357 
358  /*
359  * momentum:
360  *
361  * m * I DeltaV - S /\ DeltagP + ( S /\ W ) /\ Deltag
362  */
363  WMB.IncCoef(1, 1, dMass);
364  WMB.IncCoef(2, 2, dMass);
365  WMB.IncCoef(3, 3, dMass);
366 
367  const RigidBodyKinematics *pRBK = pNode->pGetRBK();
368  if (pRBK) {
369  AssMatsRBK_int(WMA, WMB, dCoef);
370  }
371 }
372 
373 
376  doublereal /* dCoef */ ,
377  const VectorHandler& /* XCurr */ ,
378  const VectorHandler& /* XPrimeCurr */ )
379 {
380  DEBUGCOUTFNAME("DynamicMass::AssRes");
381 
382  /* Se e' definita l'accelerazione di gravita',
383  * la aggiunge (solo al residuo) */
384  Vec3 GravityAcceleration;
386  GravityAcceleration);
387 
388  const RigidBodyKinematics *pRBK = pNode->pGetRBK();
389 
390  integer iNumRows = 3;
391  if (g || pRBK) {
392  iNumRows = 6;
393  }
394 
395  WorkVec.ResizeReset(iNumRows);
396 
397  integer iFirstPositionIndex = pNode->iGetFirstPositionIndex();
398  for (integer iCnt = 1; iCnt <= iNumRows; iCnt++) {
399  WorkVec.PutRowIndex(iCnt, iFirstPositionIndex + iCnt);
400  }
401 
402  const Vec3& V(pNode->GetVCurr());
403 
404  /* Quantita' di moto: R[1] = Q */
405  WorkVec.Sub(1, V*dMass);
406 
407  if (g) {
408  WorkVec.Add(3 + 1, GravityAcceleration*dMass);
409  }
410 
411  if (pRBK) {
412  AssVecRBK_int(WorkVec);
413  }
414 
415  const DynamicStructDispNode *pDN = dynamic_cast<const DynamicStructDispNode *>(pNode);
416  ASSERT(pDN != 0);
417 
418  pDN->AddInertia(dMass);
419 
420  return WorkVec;
421 }
422 
423 
424 /* Contributo allo jacobiano durante l'assemblaggio iniziale */
427  const VectorHandler& /* XCurr */ )
428 {
429  DEBUGCOUTFNAME("DynamicMass::InitialAssJac");
430 
431  /* Casting di WorkMat */
432  WorkMat.SetNullMatrix();
433 
434  return WorkMat;
435 }
436 
437 
438 /* Contributo al residuo durante l'assemblaggio iniziale */
441  const VectorHandler& /* XCurr */ )
442 {
443  DEBUGCOUTFNAME("DynamicMass::InitialAssRes");
444 
445  WorkVec.Resize(0);
446 
447  return WorkVec;
448 }
449 
450 
451 /* Usata per inizializzare la quantita' di moto */
452 void
454  VectorHandler& X, VectorHandler& /* XP */ ,
456 {
457  integer iFirstIndex = pNode->iGetFirstMomentumIndex();
458 
459  const Vec3& V(pNode->GetVCurr());
460  X.Add(iFirstIndex + 1, V*dMass);
461 }
462 
463 /* momentum */
464 Vec3
466 {
467  const Vec3& V(pNode->GetVCurr());
468 
469  return V*dMass;
470 }
471 
472 /* DynamicMass - end */
473 
474 
475 /* StaticMass - begin */
476 
477 StaticMass::StaticMass(unsigned int uL,
478  const StaticStructDispNode* pNode,
479  doublereal dMass,
480  flag fOut)
481 : Elem(uL, fOut),
482 Mass(uL, pNode, dMass, fOut)
483 {
484  NO_OP;
485 }
486 
487 
488 /* distruttore */
490 {
491  NO_OP;
492 }
493 
494 
497  doublereal dCoef,
498  const VectorHandler& XCurr,
499  const VectorHandler& XPrimeCurr)
500 {
501  DEBUGCOUTFNAME("StaticMass::AssJac");
502 
503  /* Casting di WorkMat */
504  FullSubMatrixHandler& WM = WorkMat.SetFull();
505 
506  /* Dimensiona e resetta la matrice di lavoro */
507  WM.ResizeReset(6, 6);
508 
509  /* Setta gli indici della matrice - le incognite sono ordinate come:
510  * - posizione (3)
511  * - parametri di rotazione (3)
512  * - quantita' di moto (3)
513  * - momento della quantita' di moto
514  * e gli indici sono consecutivi. La funzione pGetFirstPositionIndex()
515  * ritorna il valore del primo indice -1, in modo che l'indice i-esimo
516  * e' dato da iGetFirstPositionIndex() + i */
517  integer iFirstPositionIndex = pNode->iGetFirstPositionIndex();
518  integer iFirstMomentumIndex = pNode->iGetFirstMomentumIndex();
519  for (integer iCnt = 1; iCnt <= 6; iCnt++) {
520  WM.PutRowIndex(iCnt, iFirstMomentumIndex + iCnt);
521  WM.PutColIndex(iCnt, iFirstPositionIndex + iCnt);
522  }
523 
524  if (AssMats(WM, WM, dCoef)) {
525  WorkMat.SetNullMatrix();
526  }
527 
528  return WorkMat;
529 }
530 
531 
532 void
534  VariableSubMatrixHandler& WorkMatB,
535  const VectorHandler& XCurr,
536  const VectorHandler& XPrimeCurr)
537 {
538  DEBUGCOUTFNAME("StaticMass::AssMats");
539 
540  /* Casting di WorkMat */
541  FullSubMatrixHandler& WMA = WorkMatA.SetFull();
542  FullSubMatrixHandler& WMB = WorkMatB.SetFull();
543 
544  /* Dimensiona e resetta la matrice di lavoro */
545  WMA.ResizeReset(6, 6);
546  WMB.ResizeReset(6, 6);
547 
548  /* Setta gli indici della matrice - le incognite sono ordinate come:
549  * - posizione (3)
550  * - parametri di rotazione (3)
551  * - quantita' di moto (3)
552  * - momento della quantita' di moto
553  * e gli indici sono consecutivi. La funzione pGetFirstPositionIndex()
554  * ritorna il valore del primo indice -1, in modo che l'indice i-esimo
555  * e' dato da iGetFirstPositionIndex() + i */
556  integer iFirstPositionIndex = pNode->iGetFirstPositionIndex();
557  integer iFirstMomentumIndex = pNode->iGetFirstMomentumIndex();
558  for (integer iCnt = 1; iCnt <= 6; iCnt++) {
559  WMA.PutRowIndex(iCnt, iFirstMomentumIndex + iCnt);
560  WMA.PutColIndex(iCnt, iFirstPositionIndex + iCnt);
561 
562  WMB.PutRowIndex(iCnt, iFirstMomentumIndex + iCnt);
563  WMB.PutColIndex(iCnt, iFirstPositionIndex + iCnt);
564  }
565 
566  if (AssMats(WMA, WMB, 1.)) {
567  WorkMatA.SetNullMatrix();
568  WorkMatB.SetNullMatrix();
569  }
570 }
571 
572 
573 bool
576  doublereal dCoef)
577 {
578  DEBUGCOUTFNAME("StaticMass::AssMats");
579 
580  /* Se e' definita l'accelerazione di gravita',
581  * la aggiunge (solo al residuo) */
582  Vec3 Acceleration(Zero3);
583  bool g = GravityOwner::bGetGravity(pNode->GetXCurr(), Acceleration);
584 
585  const RigidBodyKinematics *pRBK = pNode->pGetRBK();
586 
587  if (!g && !pRBK) {
588  /* Caller will set WMA & WMB to null matrix */
589  return true;
590  }
591 
592  if (pRBK) {
593  AssMatsRBK_int(WMA, WMB, dCoef);
594  }
595 
596  return false;
597 }
598 
599 
602  doublereal /* dCoef */ ,
603  const VectorHandler& /* XCurr */ ,
604  const VectorHandler& /* XPrimeCurr */ )
605 {
606  DEBUGCOUTFNAME("StaticMass::AssRes");
607 
608  /* Se e' definita l'accelerazione di gravita',
609  * la aggiunge (solo al residuo) */
610  Vec3 Acceleration(Zero3);
611  bool g = GravityOwner::bGetGravity(pNode->GetXCurr(), Acceleration);
612 
613  /* W is uninitialized because its use is conditioned by w */
614  const RigidBodyKinematics *pRBK = pNode->pGetRBK();
615 
616  if (!g && !pRBK) {
617  WorkVec.Resize(0);
618  return WorkVec;
619  }
620 
621  WorkVec.ResizeReset(3);
622 
623  integer iFirstMomentumIndex = pNode->iGetFirstMomentumIndex();
624  for (integer iCnt = 1; iCnt <= 3; iCnt++) {
625  WorkVec.PutRowIndex(iCnt, iFirstMomentumIndex + iCnt);
626  }
627 
628  if (g) {
629  WorkVec.Add(1, Acceleration*dMass);
630  }
631 
632  if (pRBK) {
633  AssVecRBK_int(WorkVec);
634  }
635 
636  return WorkVec;
637 }
638 
639 
640 /* inverse dynamics capable element */
641 bool
643 {
644  return true;
645 }
646 
647 
650  const VectorHandler& /* XCurr */ ,
651  const VectorHandler& /* XPrimeCurr */ ,
652  const VectorHandler& /* XPrimePrimeCurr */ ,
653  InverseDynamics::Order iOrder)
654 {
655  DEBUGCOUTFNAME("DynamicMass::AssRes");
656 
658 
659  /* Se e' definita l'accelerazione di gravita', la aggiunge */
660  Vec3 GravityAcceleration;
662  GravityAcceleration);
663 
664  WorkVec.ResizeReset(3);
665 
666  integer iFirstPositionIndex = pNode->iGetFirstPositionIndex();
667  for (integer iCnt = 1; iCnt <= 3; iCnt++) {
668  WorkVec.PutRowIndex(iCnt, iFirstPositionIndex + iCnt);
669  }
670 
671  Vec3 Acceleration = pNode->GetXPPCurr();
672  if (g) {
673  Acceleration -= GravityAcceleration;
674  }
675 
676  WorkVec.Sub(1, Acceleration*dMass);
677 
678  return WorkVec;
679 }
680 
681 
682 /* Contributo allo jacobiano durante l'assemblaggio iniziale */
685  const VectorHandler& /* XCurr */ )
686 {
687  DEBUGCOUTFNAME("StaticMass::InitialAssJac");
688 
689  WorkMat.SetNullMatrix();
690 
691  return WorkMat;
692 }
693 
694 
695 /* Contributo al residuo durante l'assemblaggio iniziale */
698  const VectorHandler& /* XCurr */ )
699 {
700  DEBUGCOUTFNAME("StaticMass::InitialAssRes");
701 
702  WorkVec.Resize(0);
703 
704  return WorkVec;
705 }
706 
707 
708 /* Usata per inizializzare la quantita' di moto */
709 void
711  VectorHandler& X, VectorHandler& /* XP */ ,
713 {
714  NO_OP;
715 }
716 
717 /* StaticMass - end */
718 
719 
720 /* Body - begin */
721 
722 Body::Body(unsigned int uL,
723  const StructNode *pNode,
724  doublereal dMass,
725  const Vec3& Xgc,
726  const Mat3x3& J,
727  flag fOut)
728 : Elem(uL, fOut),
729 ElemGravityOwner(uL, fOut),
730 InitialAssemblyElem(uL, fOut),
731 pNode(pNode),
732 dMass(dMass),
733 Xgc(Xgc),
734 S0(Xgc*dMass),
735 J0(J)
736 {
737  ASSERT(pNode != NULL);
738  ASSERT(pNode->GetNodeType() == Node::STRUCTURAL);
739  ASSERT(dMass > 0.);
740 }
741 
742 
743 /* distruttore */
745 {
746  NO_OP;
747 }
748 
749 
750 /* momento statico */
751 Vec3
752 Body::GetS_int(void) const
753 {
754  return pNode->GetXCurr()*dMass + pNode->GetRCurr()*S0;
755 }
756 
757 
758 /* momento d'inerzia */
759 Mat3x3
760 Body::GetJ_int(void) const
761 {
762  Vec3 s = pNode->GetRCurr()*S0;
763  const Vec3& x = pNode->GetXCurr();
764 
765  return pNode->GetRCurr()*J0.MulMT(pNode->GetRCurr())
766  - Mat3x3(MatCrossCross, x, x*dMass)
767  - Mat3x3(MatCrossCross, s, x)
768  - Mat3x3(MatCrossCross, x, s);
769 }
770 
771 
772 /* Scrive il contributo dell'elemento al file di restart */
773 std::ostream&
774 Body::Restart(std::ostream& out) const
775 {
776  out << " body: " << GetLabel() << ", "
777  << pNode->GetLabel() << ", " << dMass << ", "
778  << "reference, node, ", Xgc.Write(out, ", ") << ", "
779  << "reference, node, ", (J0 + Mat3x3(MatCrossCross, S0, Xgc)).Write(out, ", ")
780  << ";" << std::endl;
781 
782  return out;
783 }
784 
785 
786 void
788 {
789  const Mat3x3& R = pNode->GetRRef();
790 
791  STmp = R*S0;
792  JTmp = R*J0.MulMT(R);
793 }
794 
795 /* massa totale */
797 Body::dGetM(void) const
798 {
799  return dMass;
800 }
801 
802 /* momento statico */
803 Vec3
804 Body::GetS(void) const
805 {
806  return GetS_int();
807 }
808 
809 /* momento d'inerzia */
810 Mat3x3
811 Body::GetJ(void) const
812 {
813  return GetJ_int();
814 }
815 
816 /* nodo */
817 const StructNode *
818 Body::pGetNode(void) const
819 {
820  return pNode;
821 }
822 
823 /* Accesso ai dati privati */
824 unsigned int
826 {
827  return 3;
828 }
829 
830 unsigned int
831 Body::iGetPrivDataIdx(const char *s) const
832 {
833  if (s[1] == '\0') {
834  switch (s[0]) {
835  case 'E':
836  // kinetic energy
837  return 1;
838 
839  case 'V':
840  // potential energy
841  return 2;
842 
843  case 'm':
844  return 3;
845  }
846  }
847 
848  return 0;
849 }
850 
852 Body::dGetPrivData(unsigned int i) const
853 {
854  switch (i) {
855  case 1: {
856  // kinetic energy
857  const Mat3x3& Rn = pNode->GetRCurr();
858  const Vec3& Vn = pNode->GetVCurr();
859  const Vec3& Wn = pNode->GetWCurr();
860 
861  Vec3 X = Rn*Xgc;
862  Vec3 V = Vn + Wn.Cross(X);
863  Vec3 W = Rn.MulTV(Wn);
864 
865  Mat3x3 Jgc = J0 + Mat3x3(MatCrossCross, Xgc, Xgc*dMass);
866 
867  return ((V*V)*dMass + W*(Jgc*W))/2.;
868  }
869 
870  case 2: {
871  // potential energy
872  Vec3 X(pNode->GetXCurr() + pNode->GetRCurr()*Xgc);
873  Vec3 GravityAcceleration;
874  if (GravityOwner::bGetGravity(X, GravityAcceleration)) {
875  return -X.Dot(GravityAcceleration)*dMass;
876  }
877  break;
878  }
879 
880  case 3:
881  return dMass;
882  }
883 
884  return 0.;
885 }
886 
887 void
889 {
890  const RigidBodyKinematics *pRBK = pNode->pGetRBK();
891 
892  Vec3 s0;
893 
894  integer iIdx = 0;
895  if (dynamic_cast<DynamicBody *>(this)) {
896  iIdx = 6;
897  }
898 
899  s0 = pNode->GetXCurr()*dMass + STmp;
900 
901  // force
902  Vec3 f;
903  f = pRBK->GetXPP()*dMass;
904  f += pRBK->GetWP().Cross(s0);
905  f += pRBK->GetW().Cross(pRBK->GetW().Cross(s0));
906 
907  WorkVec.Sub(iIdx + 1, f);
908 
909  // moment
910  Vec3 a;
911  a = pRBK->GetXPP();
912  a += pRBK->GetWP().Cross(pNode->GetXCurr());
913  a += pRBK->GetW().Cross(pRBK->GetW().Cross(pNode->GetXCurr()));
914  a += pRBK->GetW().Cross(pNode->GetVCurr());
915 
916  Vec3 m;
917  m = STmp.Cross(a);
918  m += pRBK->GetW().Cross(JTmp*pRBK->GetW());
919  m += JTmp*pRBK->GetWP();
920  m += pNode->GetWCurr().Cross(JTmp*pRBK->GetW());
921  m -= JTmp*(pNode->GetWCurr().Cross(pRBK->GetW()));
922  m += pNode->GetVCurr().Cross(pRBK->GetW().Cross(STmp));
923 
924  WorkVec.Sub(iIdx + 3 + 1, m);
925 }
926 
927 void
931  const doublereal& dCoef,
932  const Vec3& Sc)
933 {
934  const RigidBodyKinematics *pRBK = pNode->pGetRBK();
935 
936  Mat3x3 MTmp;
937  Vec3 VTmp;
938 
939  integer iIdx = 0;
940  if (dynamic_cast<DynamicBody *>(this)) {
941  iIdx = 6;
942  }
943 
944  // f: delta x
945  MTmp = Mat3x3(MatCross, pRBK->GetWP());
946  MTmp += Mat3x3(MatCrossCross, pRBK->GetW(), pRBK->GetW());
947 
948  WMA.Add(iIdx + 1, 1, MTmp*(dMass*dCoef));
949 
950 
951  // f: theta delta
952 
953  WMA.Sub(iIdx + 1, 3 + 1, MTmp*Mat3x3(MatCross, Sc));
954 
955 
956  // m: delta x
957  MTmp = Mat3x3(MatCrossCross, Sc, pRBK->GetWP());
958  MTmp += Sc.Cross(Mat3x3(MatCrossCross, pRBK->GetW(), pRBK->GetW()));
959 
960  WMA.Add(iIdx + 3 + 1, 1, MTmp);
961 
962 
963  // m: theta delta
964 
965  VTmp = pRBK->GetXPP();
966  VTmp += pRBK->GetWP().Cross(pNode->GetXCurr());
967  VTmp += pRBK->GetW().Cross(pRBK->GetW().Cross(pNode->GetXCurr()));
968  VTmp += pRBK->GetW().Cross(pNode->GetVCurr());
969 
970  MTmp = Mat3x3(MatCrossCross, VTmp, Sc);
971 
972  VTmp = (pRBK->GetW() + pNode->GetWCurr())*dCoef;
973 
974  Mat3x3 MTmp2(JTmp*Mat3x3(MatCross, pRBK->GetW()) - Mat3x3(MatCross, JTmp*pRBK->GetW()));
975  MTmp += VTmp.Cross(MTmp2);
976 
977  VTmp = (pRBK->GetWP() + pRBK->GetW().Cross(pNode->GetWCurr()))*dCoef;
978 
979  MTmp += JTmp*Mat3x3(MatCross, VTmp);
980  MTmp -= Mat3x3(MatCross, JTmp*VTmp);
981 
982  MTmp -= pNode->GetVCurr().Cross(Mat3x3(MatCrossCross, pRBK->GetW(), Sc));
983 
984  WMA.Add(iIdx + 3 + 1, 3 + 1, MTmp);
985 
986 
987  // m: delta dot x
988  MTmp = Mat3x3(MatCrossCross, STmp, pRBK->GetW());
989  MTmp -= Mat3x3(MatCross, pRBK->GetW().Cross(STmp));
990 
991  WMB.Add(iIdx + 3 + 1, 1, MTmp);
992 
993  // m: delta omega
994  WMB.Add(iIdx + 3 + 1, 3 + 1, MTmp2);
995 }
996 
997 /* Body - end */
998 
999 
1000 /* DynamicBody - begin */
1001 
1003  const DynamicStructNode* pNode,
1004  doublereal dMass,
1005  const Vec3& Xgc,
1006  const Mat3x3& J,
1007  flag fOut)
1008 : Elem(uL, fOut),
1009 Body(uL, pNode, dMass, Xgc, J, fOut)
1010 {
1011  NO_OP;
1012 }
1013 
1014 
1015 /* distruttore */
1017 {
1018  NO_OP;
1019 }
1020 
1021 void
1022 DynamicBody::WorkSpaceDim(integer* piNumRows, integer* piNumCols) const
1023 {
1024  *piNumRows = 12;
1025  *piNumCols = 6;
1026 }
1027 
1028 void
1029 DynamicBody::InitialWorkSpaceDim(integer* piNumRows, integer* piNumCols) const
1030 {
1031  *piNumRows = 12;
1032  *piNumCols = 6;
1033 }
1034 
1037  doublereal dCoef,
1038  const VectorHandler& XCurr,
1039  const VectorHandler& XPrimeCurr)
1040 {
1041  DEBUGCOUTFNAME("DynamicBody::AssJac");
1042 
1043  /* Casting di WorkMat */
1044  FullSubMatrixHandler& WM = WorkMat.SetFull();
1045 
1046  Vec3 GravityAcceleration;
1048  GravityAcceleration);
1049 
1050  integer iNumRows = 6;
1051  if (g || pNode->pGetRBK()) {
1052  iNumRows = 12;
1053  }
1054 
1055  /* Dimensiona e resetta la matrice di lavoro */
1056  WM.ResizeReset(iNumRows, 6);
1057 
1058  /* Setta gli indici della matrice - le incognite sono ordinate come:
1059  * - posizione (3)
1060  * - parametri di rotazione (3)
1061  * - quantita' di moto (3)
1062  * - momento della quantita' di moto
1063  * e gli indici sono consecutivi. La funzione pGetFirstPositionIndex()
1064  * ritorna il valore del primo indice -1, in modo che l'indice i-esimo
1065  * e' dato da iGetFirstPositionIndex()+i */
1066  integer iFirstPositionIndex = pNode->iGetFirstPositionIndex();
1067  for (integer iCnt = 1; iCnt <= 6; iCnt++) {
1068  WM.PutRowIndex(iCnt, iFirstPositionIndex + iCnt);
1069  WM.PutColIndex(iCnt, iFirstPositionIndex + iCnt);
1070  }
1071 
1072  if (iNumRows == 12) {
1073  integer iFirstMomentumIndex = pNode->iGetFirstMomentumIndex();
1074  for (integer iCnt = 1; iCnt <= 6; iCnt++) {
1075  WM.PutRowIndex(6 + iCnt, iFirstMomentumIndex + iCnt);
1076  }
1077  }
1078 
1079  AssMats(WM, WM, dCoef, g, GravityAcceleration);
1080 
1081  return WorkMat;
1082 }
1083 
1084 
1085 void
1087  VariableSubMatrixHandler& WorkMatB,
1088  const VectorHandler& XCurr,
1089  const VectorHandler& XPrimeCurr)
1090 {
1091  DEBUGCOUTFNAME("DynamicBody::AssMats");
1092 
1093  /* Casting di WorkMat */
1094  FullSubMatrixHandler& WMA = WorkMatA.SetFull();
1095  FullSubMatrixHandler& WMB = WorkMatB.SetFull();
1096 
1097  Vec3 GravityAcceleration;
1099  GravityAcceleration);
1100 
1101  integer iNumRows = 6;
1102  if (g) {
1103  iNumRows = 12;
1104  }
1105 
1106  /* Dimensiona e resetta la matrice di lavoro */
1107  WMA.ResizeReset(iNumRows, 6);
1108  WMB.ResizeReset(6, 6);
1109 
1110  /* Setta gli indici della matrice - le incognite sono ordinate come:
1111  * - posizione (3)
1112  * - parametri di rotazione (3)
1113  * - quantita' di moto (3)
1114  * - momento della quantita' di moto
1115  * e gli indici sono consecutivi. La funzione pGetFirstPositionIndex()
1116  * ritorna il valore del primo indice -1, in modo che l'indice i-esimo
1117  * e' dato da iGetFirstPositionIndex()+i */
1118  integer iFirstPositionIndex = pNode->iGetFirstPositionIndex();
1119  for (integer iCnt = 1; iCnt <= 6; iCnt++) {
1120  WMA.PutRowIndex(iCnt, iFirstPositionIndex + iCnt);
1121  WMA.PutColIndex(iCnt, iFirstPositionIndex + iCnt);
1122 
1123  WMB.PutRowIndex(iCnt, iFirstPositionIndex + iCnt);
1124  WMB.PutColIndex(iCnt, iFirstPositionIndex + iCnt);
1125  }
1126 
1127  if (g) {
1128  integer iFirstMomentumIndex = pNode->iGetFirstMomentumIndex();
1129  for (integer iCnt = 1; iCnt <= 6; iCnt++) {
1130  WMA.PutRowIndex(6 + iCnt, iFirstMomentumIndex + iCnt);
1131  }
1132  }
1133 
1134  AssMats(WMA, WMB, 1., g, GravityAcceleration);
1135 }
1136 
1137 
1138 void
1140  FullSubMatrixHandler& WMB,
1141  doublereal dCoef,
1142  bool bGravity,
1143  const Vec3& GravityAcceleration)
1144 {
1145  DEBUGCOUTFNAME("DynamicBody::AssMats");
1146 
1147  const Vec3& V(pNode->GetVCurr());
1148  const Vec3& W(pNode->GetWCurr());
1149 
1150  // STmp, JTmp computed by AssRes()
1151  // const Mat3x3& R(pNode->GetRCurr());
1152  // STmp = R*S0;
1153  // JTmp = R*J0.MulMT(R);
1154 
1155  Mat3x3 SWedge(MatCross, STmp); /* S /\ */
1156  Vec3 Sc(STmp*dCoef);
1157 
1158  /*
1159  * momentum:
1160  *
1161  * m * I DeltaV - S /\ DeltagP + ( S /\ W ) /\ Deltag
1162  */
1163  WMB.IncCoef(1, 1, dMass);
1164  WMB.IncCoef(2, 2, dMass);
1165  WMB.IncCoef(3, 3, dMass);
1166 
1167  WMB.Sub(1, 3 + 1, SWedge);
1168  WMA.Add(1, 3 + 1, Mat3x3(MatCross, Sc.Cross(W)));
1169 
1170  /*
1171  * momenta moment:
1172  *
1173  * S /\ DeltaV + J DeltagP + ( V /\ S /\ - ( J * W ) /\ ) Deltag
1174  */
1175  WMB.Add(3 + 1, 1, SWedge);
1176 
1177  WMB.Add(3 + 1, 3 + 1, JTmp);
1178  WMA.Add(3 + 1, 3 + 1, Mat3x3(MatCrossCross, V, Sc) - Mat3x3(MatCross, JTmp*(W*dCoef)));
1179 
1180  if (bGravity) {
1181  WMA.Sub(9 + 1, 3 + 1, Mat3x3(MatCrossCross, GravityAcceleration, Sc));
1182  }
1183 
1184  const RigidBodyKinematics *pRBK = pNode->pGetRBK();
1185  if (pRBK) {
1186  AssMatsRBK_int(WMA, WMB, dCoef, Sc);
1187  }
1188 }
1189 
1190 
1193  doublereal /* dCoef */ ,
1194  const VectorHandler& /* XCurr */ ,
1195  const VectorHandler& /* XPrimeCurr */ )
1196 {
1197  DEBUGCOUTFNAME("DynamicBody::AssRes");
1198 
1199  /* Se e' definita l'accelerazione di gravita',
1200  * la aggiunge (solo al residuo) */
1201  Vec3 GravityAcceleration;
1203  GravityAcceleration);
1204 
1205  const RigidBodyKinematics *pRBK = pNode->pGetRBK();
1206 
1207  integer iNumRows = 6;
1208  if (g || pRBK) {
1209  iNumRows = 12;
1210  }
1211 
1212  WorkVec.ResizeReset(iNumRows);
1213 
1214  integer iFirstPositionIndex = pNode->iGetFirstPositionIndex();
1215  for (integer iCnt = 1; iCnt <= iNumRows; iCnt++) {
1216  WorkVec.PutRowIndex(iCnt, iFirstPositionIndex + iCnt);
1217  }
1218 
1219  const Vec3& V(pNode->GetVCurr());
1220  const Vec3& W(pNode->GetWCurr());
1221 
1222  /* Aggiorna i suoi dati (saranno pronti anche per AssJac) */
1223  const Mat3x3& R(pNode->GetRCurr());
1224  STmp = R*S0;
1225  JTmp = R*J0.MulMT(R);
1226 
1227  /* Quantita' di moto: R[1] = Q - M * V - W /\ S */
1228  WorkVec.Sub(1, V*dMass + W.Cross(STmp));
1229 
1230  /* Momento della quantita' di moto: R[2] = G - S /\ V - J * W */
1231  WorkVec.Sub(3 + 1, JTmp*W + STmp.Cross(V));
1232 
1233  if (g) {
1234  WorkVec.Add(6 + 1, GravityAcceleration*dMass);
1235  /* FIXME: this should go into Jacobian matrix
1236  * as Gravity /\ S /\ Delta g */
1237  WorkVec.Add(9 + 1, STmp.Cross(GravityAcceleration));
1238  }
1239 
1240  if (pRBK) {
1241  AssVecRBK_int(WorkVec);
1242  }
1243 
1244  const DynamicStructNode *pDN = dynamic_cast<const DynamicStructNode *>(pNode);
1245  ASSERT(pDN != 0);
1246 
1247  pDN->AddInertia(dMass, STmp, JTmp);
1248 
1249  return WorkVec;
1250 }
1251 
1252 
1253 /* Contributo allo jacobiano durante l'assemblaggio iniziale */
1256  const VectorHandler& /* XCurr */ )
1257 {
1258  DEBUGCOUTFNAME("DynamicBody::InitialAssJac");
1259 
1260  /* Casting di WorkMat */
1261  FullSubMatrixHandler& WM = WorkMat.SetFull();
1262 
1263  /* Dimensiona e resetta la matrice di lavoro */
1264  integer iNumRows = 0;
1265  integer iNumCols = 0;
1266  InitialWorkSpaceDim(&iNumRows, &iNumCols);
1267  WM.ResizeReset(iNumRows, iNumCols);
1268 
1269  /* Setta gli indici della matrice - le incognite sono ordinate come:
1270  * - posizione (3)
1271  * - parametri di rotazione (3)
1272  * - quantita' di moto (3)
1273  * - momento della quantita' di moto
1274  * e gli indici sono consecutivi. La funzione pGetFirstPositionIndex()
1275  * ritorna il valore del primo indice -1, in modo che l'indice i-esimo
1276  * e' dato da iGetFirstPositionIndex()+i */
1277  integer iFirstPositionIndex = pNode->iGetFirstPositionIndex();
1278  integer iFirstVelocityIndex = iFirstPositionIndex+6;
1279  for (integer iCnt = 1; iCnt <= 6; iCnt++) {
1280  WM.PutRowIndex(iCnt, iFirstPositionIndex+iCnt);
1281  WM.PutRowIndex(6+iCnt, iFirstVelocityIndex+iCnt);
1282  WM.PutColIndex(iCnt, iFirstPositionIndex+iCnt);
1283  }
1284 
1285  /* Prepara matrici e vettori */
1286 
1287  /* Velocita' angolare corrente */
1288  const Vec3& W(pNode->GetWRef());
1289 
1290  Vec3 SWedgeW(STmp.Cross(W));
1291  Mat3x3 WWedgeSWedge(MatCrossCross, -W, STmp);
1292  Mat3x3 WWedge(MatCross, W);
1293  Mat3x3 WWedgeWWedgeSWedge(W.Cross(WWedgeSWedge));
1294  Mat3x3 FDeltaW(Mat3x3(MatCross, SWedgeW) + WWedgeSWedge);
1295 
1296  // STmp, JTmp computed by InitialAssRes()
1297  Vec3 JW(JTmp*W);
1298  Mat3x3 JWWedge(MatCross, JW);
1299  Mat3x3 MDeltag(W.Cross(JTmp*WWedge - JWWedge));
1300  Mat3x3 MDeltaW(W.Cross(JTmp) - JWWedge);
1301 
1302  /* Forza */
1303  WM.Add(1, 1, WWedgeWWedgeSWedge);
1304  WM.Add(1, 4, FDeltaW);
1305 
1306  /* Momento */
1307  WM.Add(4, 1, MDeltag);
1308  WM.Add(4, 4, MDeltaW);
1309 
1310  /* Derivata forza */
1311  WM.Add(7, 1, Mat3x3(MatCross, W.Cross(SWedgeW)) + W.Cross(FDeltaW));
1312  WM.Add(7, 4, W.Cross(WWedgeWWedgeSWedge));
1313 
1314  /* Derivata Momento */
1315  WM.Add(4, 1, W.Cross(MDeltag));
1316  WM.Add(4, 4, W.Cross(MDeltaW) - Mat3x3(MatCross, W.Cross(JW)));
1317 
1318  return WorkMat;
1319 }
1320 
1321 
1322 /* Contributo al residuo durante l'assemblaggio iniziale */
1325  const VectorHandler& /* XCurr */ )
1326 {
1327  DEBUGCOUTFNAME("DynamicBody::InitialAssRes");
1328 
1329  integer iNumRows;
1330  integer iNumCols;
1331  InitialWorkSpaceDim(&iNumRows, &iNumCols);
1332  WorkVec.ResizeReset(iNumRows);
1333 
1334  integer iFirstPositionIndex = pNode->iGetFirstPositionIndex();
1335  for (integer iCnt = 1; iCnt <= 12; iCnt++) {
1336  WorkVec.PutRowIndex(iCnt, iFirstPositionIndex+iCnt);
1337  }
1338 
1339  const Vec3& X(pNode->GetXCurr());
1340  const Vec3& W(pNode->GetWCurr());
1341 
1342  // Aggiorna i suoi dati (saranno pronti anche per InitialAssJac)
1343  const Mat3x3& R(pNode->GetRCurr());
1344  STmp = R*S0;
1345  JTmp = R*J0.MulMT(R);
1346 
1347  Vec3 FC(-W.Cross(W.Cross(STmp)));
1348  Vec3 MC(-W.Cross(JTmp*W));
1349 
1350  /* Forza */
1351  WorkVec.Add(1, FC);
1352 
1353  /* Momento */
1354  WorkVec.Add(4, MC);
1355 
1356  /* Derivata forza */
1357  WorkVec.Add(7, W.Cross(FC));
1358 
1359  /* Derivata momento */
1360  WorkVec.Add(10, W.Cross(MC));
1361 
1362  /* Se e' definita l'accelerazione di gravita',
1363  * la aggiunge (solo al residuo) */
1364  Vec3 GravityAcceleration;
1365  if (GravityOwner::bGetGravity(X, GravityAcceleration)) {
1366  WorkVec.Add(1, GravityAcceleration*dMass);
1367  WorkVec.Add(3 + 1, STmp.Cross(GravityAcceleration));
1368  WorkVec.Add(9 + 1, (W.Cross(STmp)).Cross(GravityAcceleration));
1369  }
1370 
1371  return WorkVec;
1372 }
1373 
1374 
1375 /* Usata per inizializzare la quantita' di moto */
1376 void
1378  VectorHandler& X, VectorHandler& /* XP */ ,
1380 {
1381  integer iFirstIndex = pNode->iGetFirstMomentumIndex();
1382 
1383  // TODO: make configurable
1384  const Vec3& V(pNode->GetVCurr());
1385  const Vec3& W(pNode->GetWCurr());
1386  const Mat3x3& R(pNode->GetRCurr());
1387  STmp = R*S0;
1388  JTmp = R*J0.MulMT(R);
1389  X.Add(iFirstIndex + 1, V*dMass + W.Cross(STmp));
1390  X.Add(iFirstIndex + 4, STmp.Cross(V) + JTmp*W);
1391 }
1392 
1393 /* momentum */
1394 Vec3
1396 {
1397  const Vec3& V(pNode->GetVCurr());
1398  const Vec3& W(pNode->GetWCurr());
1399  const Mat3x3& R(pNode->GetRCurr());
1400 
1401  return V*dMass + W.Cross(R*S0);
1402 }
1403 
1404 
1405 /* momenta moment */
1406 Vec3
1408 {
1409  const Vec3& X(pNode->GetXCurr());
1410  const Mat3x3& R(pNode->GetRCurr());
1411  const Vec3& V(pNode->GetVCurr());
1412  const Vec3& W(pNode->GetWCurr());
1413 
1414  Vec3 STmp(R*S0);
1415 
1416  // NOTE: with respect to the origin of the global reference frame!
1417  return (STmp + X*dMass).Cross(V) + R*(J0*(R.MulTV(W)))
1418  - X.Cross(STmp.Cross(W));
1419 }
1420 
1421 
1422 /* DynamicBody - end */
1423 
1424 
1425 /* ModalBody - begin */
1426 
1427 ModalBody::ModalBody(unsigned int uL,
1428  const ModalNode* pNode,
1429  doublereal dMass,
1430  const Vec3& Xgc,
1431  const Mat3x3& J,
1432  flag fOut)
1433 : Elem(uL, fOut),
1434 DynamicBody(uL, pNode, dMass, Xgc, J, fOut),
1435 XPP(::Zero3), WP(::Zero3)
1436 {
1437  NO_OP;
1438 }
1439 
1440 /* distruttore */
1442 {
1443  NO_OP;
1444 }
1445 
1446 void
1447 ModalBody::WorkSpaceDim(integer* piNumRows, integer* piNumCols) const
1448 {
1449  *piNumRows = 12;
1450  *piNumCols = 12;
1451 }
1452 
1455  doublereal dCoef,
1456  const VectorHandler& XCurr,
1457  const VectorHandler& XPrimeCurr)
1458 {
1459  DEBUGCOUTFNAME("ModalBody::AssJac");
1460 
1461  /* Casting di WorkMat */
1462  FullSubMatrixHandler& WM = WorkMat.SetFull();
1463 
1464  Vec3 GravityAcceleration;
1466  GravityAcceleration);
1467 
1468  const integer iNumRows = 12;
1469 
1470  /* Dimensiona e resetta la matrice di lavoro */
1471  WM.ResizeReset(iNumRows, 12);
1472 
1473  /* Setta gli indici della matrice - le incognite sono ordinate come:
1474  * - posizione (3)
1475  * - parametri di rotazione (3)
1476  * - quantita' di moto (3)
1477  * - momento della quantita' di moto
1478  * e gli indici sono consecutivi. La funzione pGetFirstPositionIndex()
1479  * ritorna il valore del primo indice -1, in modo che l'indice i-esimo
1480  * e' dato da iGetFirstPositionIndex()+i */
1481  const integer iFirstIndexModal = pNode->iGetFirstIndex();
1482  for (integer iCnt = 1; iCnt <= 12; iCnt++) {
1483  WM.PutRowIndex(iCnt, iFirstIndexModal + iCnt);
1484  }
1485 
1486  for (integer iCnt = 1; iCnt <= 12; ++iCnt) {
1487  WM.PutColIndex(iCnt, iFirstIndexModal + iCnt);
1488  }
1489 
1490  AssMats(WM, WM, dCoef, XCurr, XPrimeCurr, g, GravityAcceleration);
1491 
1492  return WorkMat;
1493 }
1494 
1495 
1496 void
1498  VariableSubMatrixHandler& WorkMatB,
1499  const VectorHandler& XCurr,
1500  const VectorHandler& XPrimeCurr)
1501 {
1502  DEBUGCOUTFNAME("ModalBody::AssMats");
1503 
1504  /* Casting di WorkMat */
1505  FullSubMatrixHandler& WMA = WorkMatA.SetFull();
1506  FullSubMatrixHandler& WMB = WorkMatB.SetFull();
1507 
1508  Vec3 GravityAcceleration;
1510  GravityAcceleration);
1511 
1512  const integer iNumRows = 12;
1513 
1514  /* Dimensiona e resetta la matrice di lavoro */
1515  WMA.ResizeReset(iNumRows, 12);
1516  WMB.ResizeReset(iNumRows, 12);
1517 
1518  /* Setta gli indici della matrice - le incognite sono ordinate come:
1519  * - posizione (3)
1520  * - parametri di rotazione (3)
1521  * - quantita' di moto (3)
1522  * - momento della quantita' di moto
1523  * e gli indici sono consecutivi. La funzione pGetFirstPositionIndex()
1524  * ritorna il valore del primo indice -1, in modo che l'indice i-esimo
1525  * e' dato da iGetFirstPositionIndex()+i */
1526  integer iFirstIndexModal = pNode->iGetFirstIndex();
1527  for (integer iCnt = 1; iCnt <= 12; iCnt++) {
1528  WMA.PutRowIndex(iCnt, iFirstIndexModal + iCnt);
1529  WMA.PutColIndex(iCnt, iFirstIndexModal + iCnt);
1530 
1531  WMB.PutRowIndex(iCnt, iFirstIndexModal + iCnt);
1532  WMB.PutColIndex(iCnt, iFirstIndexModal + iCnt);
1533  }
1534 
1535  AssMats(WMA, WMB, 1., XCurr, XPrimeCurr, g, GravityAcceleration);
1536 }
1537 
1538 
1539 void
1541  FullSubMatrixHandler& WMB,
1542  doublereal dCoef,
1543  const VectorHandler& XCurr,
1544  const VectorHandler& XPrimeCurr,
1545  bool bGravity,
1546  const Vec3& GravityAcceleration)
1547 {
1548  DEBUGCOUTFNAME("ModalBody::AssMats");
1549 
1550  const Vec3& W(pNode->GetWCurr());
1551 
1552  Vec3 Sc(STmp*dCoef);
1553 
1554  const Mat3x3& RRef = pNode->GetRRef();
1555  const Mat3x3& RCurr = pNode->GetRCurr();
1556 
1557  const Mat3x3 J12A = (Mat3x3(MatCross, WP) + Mat3x3(MatCrossCross, W, W)).MulVCross(RRef * S0 * (-dCoef));
1558  const Mat3x3 J13B(Mat3x3DEye, dMass);
1559  const Mat3x3 J14A = (Mat3x3(MatCrossCross, W, STmp) + Mat3x3(MatCross, W.Cross(STmp))) * (-dCoef);
1560  const Mat3x3 J14B(MatCross, -STmp);
1561  const Mat3x3 J22A = (Mat3x3(MatCrossCross, W, RRef * J0 * RCurr.MulTV(W))
1562  - Mat3x3(MatCrossCross, XPP, RRef * S0)
1563  - W.Cross(RCurr * J0 * RRef.MulTVCross(W))
1564  + Mat3x3(MatCross, RRef * J0 * RCurr.MulTV(WP))
1565  - RCurr * J0 * RRef.MulTVCross(WP))* (-dCoef);
1566  const Mat3x3 J23B(MatCross, STmp);
1567  const Mat3x3 J24A = (Mat3x3(MatCross, JTmp * W) - W.Cross(JTmp)) * (-dCoef);
1568  const Mat3x3 J24B = JTmp;
1569 
1570  WMA.Add(6 + 1, 3 + 1, J12A);
1571  WMB.Add(6 + 1, 6 + 1, J13B);
1572  WMA.Add(6 + 1, 9 + 1, J14A);
1573  WMB.Add(6 + 1, 9 + 1, J14B);
1574  WMA.Add(9 + 1, 3 + 1, J22A);
1575  WMB.Add(9 + 1, 6 + 1, J23B);
1576  WMA.Add(9 + 1, 9 + 1, J24A);
1577  WMB.Add(9 + 1, 9 + 1, J24B);
1578 
1579  if (bGravity) {
1580  WMA.Sub(9 + 1, 3 + 1, Mat3x3(MatCrossCross, GravityAcceleration, Sc));
1581  }
1582 
1583  const RigidBodyKinematics *pRBK = pNode->pGetRBK();
1584  if (pRBK) {
1585  AssMatsRBK_int(WMA, WMB, dCoef, Sc);
1586  }
1587 }
1588 
1589 
1592  doublereal dCoef,
1593  const VectorHandler& XCurr,
1594  const VectorHandler& XPrimeCurr)
1595 {
1596  DEBUGCOUTFNAME("ModalBody::AssRes");
1597 
1598  /* Se e' definita l'accelerazione di gravita',
1599  * la aggiunge (solo al residuo) */
1600  Vec3 GravityAcceleration;
1602  GravityAcceleration);
1603 
1604  const RigidBodyKinematics *pRBK = pNode->pGetRBK();
1605 
1606  const integer iNumRows = 12;
1607 
1608  WorkVec.ResizeReset(iNumRows);
1609 
1610  integer iFirstPositionIndex = pNode->iGetFirstPositionIndex();
1611  for (integer iCnt = 1; iCnt <= iNumRows; iCnt++) {
1612  WorkVec.PutRowIndex(iCnt, iFirstPositionIndex + iCnt);
1613  }
1614 
1615  const Vec3& W(pNode->GetWCurr());
1616 
1617  /* Aggiorna i suoi dati (saranno pronti anche per AssJac) */
1618  const Mat3x3& R(pNode->GetRCurr());
1619  STmp = R*S0;
1620  JTmp = R*J0.MulMT(R);
1621 
1622  const integer iFirstIndexModal = pNode->iGetFirstIndex();
1623 
1624  for (integer i = 1; i <= 3; ++i) {
1625  XPP(i) = XPrimeCurr.dGetCoef(iFirstIndexModal + i + 6);
1626  WP(i) = XPrimeCurr.dGetCoef(iFirstIndexModal + i + 9);
1627  }
1628 
1629  const Vec3 F = XPP * -dMass - WP.Cross(STmp) - W.Cross(W.Cross(STmp));
1630  const Vec3 M = -STmp.Cross(XPP) - W.Cross(JTmp * W) - JTmp * WP;
1631 
1632  WorkVec.Add(6 + 1, F);
1633  WorkVec.Add(9 + 1, M);
1634 
1635  if (g) {
1636  WorkVec.Add(6 + 1, GravityAcceleration*dMass);
1637  /* FIXME: this should go into Jacobian matrix
1638  * as Gravity /\ S /\ Delta g */
1639  WorkVec.Add(9 + 1, STmp.Cross(GravityAcceleration));
1640  }
1641 
1642  if (pRBK) {
1643  AssVecRBK_int(WorkVec);
1644  }
1645 
1646  const DynamicStructNode *pDN = dynamic_cast<const DynamicStructNode *>(pNode);
1647  ASSERT(pDN != 0);
1648 
1649  pDN->AddInertia(dMass, STmp, JTmp);
1650 
1651  return WorkVec;
1652 }
1653 
1654 /* ModalBody - end */
1655 
1656 
1657 /* StaticBody - begin */
1658 
1659 StaticBody::StaticBody(unsigned int uL,
1660  const StaticStructNode* pNode,
1661  doublereal dMass,
1662  const Vec3& Xgc,
1663  const Mat3x3& J,
1664  flag fOut)
1665 : Elem(uL, fOut),
1666 Body(uL, pNode, dMass, Xgc, J, fOut)
1667 {
1668  NO_OP;
1669 }
1670 
1671 
1672 /* distruttore */
1674 {
1675  NO_OP;
1676 }
1677 
1678 
1681  doublereal dCoef,
1682  const VectorHandler& XCurr,
1683  const VectorHandler& XPrimeCurr)
1684 {
1685  DEBUGCOUTFNAME("StaticBody::AssJac");
1686 
1687  /* Casting di WorkMat */
1688  FullSubMatrixHandler& WM = WorkMat.SetFull();
1689 
1690  /* Dimensiona e resetta la matrice di lavoro */
1691  WM.ResizeReset(6, 6);
1692 
1693  /* Setta gli indici della matrice - le incognite sono ordinate come:
1694  * - posizione (3)
1695  * - parametri di rotazione (3)
1696  * - quantita' di moto (3)
1697  * - momento della quantita' di moto
1698  * e gli indici sono consecutivi. La funzione pGetFirstPositionIndex()
1699  * ritorna il valore del primo indice -1, in modo che l'indice i-esimo
1700  * e' dato da iGetFirstPositionIndex() + i */
1701  integer iFirstPositionIndex = pNode->iGetFirstPositionIndex();
1702  integer iFirstMomentumIndex = pNode->iGetFirstMomentumIndex();
1703  for (integer iCnt = 1; iCnt <= 6; iCnt++) {
1704  WM.PutRowIndex(iCnt, iFirstMomentumIndex + iCnt);
1705  WM.PutColIndex(iCnt, iFirstPositionIndex + iCnt);
1706  }
1707 
1708  if (AssMats(WM, WM, dCoef)) {
1709  WorkMat.SetNullMatrix();
1710  }
1711 
1712  return WorkMat;
1713 }
1714 
1715 
1716 void
1718  VariableSubMatrixHandler& WorkMatB,
1719  const VectorHandler& XCurr,
1720  const VectorHandler& XPrimeCurr)
1721 {
1722  DEBUGCOUTFNAME("StaticBody::AssMats");
1723 
1724  /* Casting di WorkMat */
1725  FullSubMatrixHandler& WMA = WorkMatA.SetFull();
1726  FullSubMatrixHandler& WMB = WorkMatB.SetFull();
1727 
1728  /* Dimensiona e resetta la matrice di lavoro */
1729  WMA.ResizeReset(6, 6);
1730  WMB.ResizeReset(6, 6);
1731 
1732  /* Setta gli indici della matrice - le incognite sono ordinate come:
1733  * - posizione (3)
1734  * - parametri di rotazione (3)
1735  * - quantita' di moto (3)
1736  * - momento della quantita' di moto
1737  * e gli indici sono consecutivi. La funzione pGetFirstPositionIndex()
1738  * ritorna il valore del primo indice -1, in modo che l'indice i-esimo
1739  * e' dato da iGetFirstPositionIndex() + i */
1740  integer iFirstPositionIndex = pNode->iGetFirstPositionIndex();
1741  integer iFirstMomentumIndex = pNode->iGetFirstMomentumIndex();
1742  for (integer iCnt = 1; iCnt <= 6; iCnt++) {
1743  WMA.PutRowIndex(iCnt, iFirstMomentumIndex + iCnt);
1744  WMA.PutColIndex(iCnt, iFirstPositionIndex + iCnt);
1745 
1746  WMB.PutRowIndex(iCnt, iFirstMomentumIndex + iCnt);
1747  WMB.PutColIndex(iCnt, iFirstPositionIndex + iCnt);
1748  }
1749 
1750  if (AssMats(WMA, WMB, 1.)) {
1751  WorkMatA.SetNullMatrix();
1752  WorkMatB.SetNullMatrix();
1753  }
1754 }
1755 
1756 
1757 bool
1759  FullSubMatrixHandler& WMB,
1760  doublereal dCoef)
1761 {
1762  DEBUGCOUTFNAME("StaticBody::AssMats");
1763 
1764  /* Se e' definita l'accelerazione di gravita',
1765  * la aggiunge (solo al residuo) */
1766  Vec3 Acceleration(Zero3);
1767  bool g = GravityOwner::bGetGravity(pNode->GetXCurr(), Acceleration);
1768 
1769  /* TODO: reference */
1770  Vec3 W(Zero3);
1771 
1772  const RigidBodyKinematics *pRBK = pNode->pGetRBK();
1773 
1774  if (!g && !pRBK) {
1775  /* Caller will set WMA & WMB to null matrix */
1776  return true;
1777  }
1778 
1779  Vec3 Sc(STmp*dCoef);
1780 
1781  if (g) {
1782  WMA.Add(3 + 1, 3 + 1, Mat3x3(MatCrossCross, Acceleration, Sc));
1783  }
1784 
1785  if (pRBK) {
1786  AssMatsRBK_int(WMA, WMB, dCoef, Sc);
1787  }
1788 
1789  return false;
1790 }
1791 
1792 
1795  doublereal /* dCoef */ ,
1796  const VectorHandler& /* XCurr */ ,
1797  const VectorHandler& /* XPrimeCurr */ )
1798 {
1799  DEBUGCOUTFNAME("StaticBody::AssRes");
1800 
1801  /* Se e' definita l'accelerazione di gravita',
1802  * la aggiunge (solo al residuo) */
1803  Vec3 Acceleration(Zero3);
1804  bool g = GravityOwner::bGetGravity(pNode->GetXCurr(), Acceleration);
1805 
1806  /* W is uninitialized because its use is conditioned by w */
1807  const RigidBodyKinematics *pRBK = pNode->pGetRBK();
1808 
1809  if (!g && !pRBK) {
1810  WorkVec.Resize(0);
1811  return WorkVec;
1812  }
1813 
1814  WorkVec.ResizeReset(6);
1815 
1816  integer iFirstMomentumIndex = pNode->iGetFirstMomentumIndex();
1817  for (integer iCnt = 1; iCnt <= 6; iCnt++) {
1818  WorkVec.PutRowIndex(iCnt, iFirstMomentumIndex + iCnt);
1819  }
1820 
1821  /* Aggiorna i suoi dati (saranno pronti anche per AssJac) */
1822  const Mat3x3& R(pNode->GetRCurr());
1823  STmp = R*S0;
1824  JTmp = R*J0.MulMT(R);
1825 
1826  if (g) {
1827  WorkVec.Add(1, Acceleration*dMass);
1828  WorkVec.Add(3 + 1, STmp.Cross(Acceleration));
1829  }
1830 
1831  if (pRBK) {
1832  AssVecRBK_int(WorkVec);
1833  }
1834 
1835  return WorkVec;
1836 }
1837 
1838 
1839 /* inverse dynamics capable element */
1840 bool
1842 {
1843  return true;
1844 }
1845 
1846 
1849  const VectorHandler& /* XCurr */ ,
1850  const VectorHandler& /* XPrimeCurr */ ,
1851  const VectorHandler& /* XPrimePrimeCurr */ ,
1852  InverseDynamics::Order iOrder)
1853 {
1854  DEBUGCOUTFNAME("StaticBody::AssRes");
1855 
1857 
1858  /* Se e' definita l'accelerazione di gravita', la aggiunge */
1859  Vec3 GravityAcceleration;
1861  GravityAcceleration);
1862 
1863  WorkVec.ResizeReset(6);
1864 
1865  integer iFirstPositionIndex = pNode->iGetFirstPositionIndex();
1866  for (integer iCnt = 1; iCnt <= 6; iCnt++) {
1867  WorkVec.PutRowIndex(iCnt, iFirstPositionIndex + iCnt);
1868  }
1869 
1870  const Mat3x3& R(pNode->GetRCurr());
1871  Vec3 XgcTmp = R*Xgc;
1872  STmp = R*S0;
1873  JTmp = R*J0.MulMT(R);
1874 
1875  Vec3 Acceleration = pNode->GetXPPCurr()
1876  + pNode->GetWPCurr().Cross(XgcTmp)
1877  + pNode->GetWCurr().Cross(pNode->GetWCurr().Cross(XgcTmp));
1878  if (g) {
1879  Acceleration -= GravityAcceleration;
1880  }
1881 
1882  WorkVec.Sub(1, Acceleration*dMass);
1883 
1884  Vec3 M = JTmp*pNode->GetWPCurr()
1885  + STmp.Cross(pNode->GetXPPCurr())
1886  + STmp.Cross(pNode->GetWCurr().Cross(pNode->GetWCurr().Cross(XgcTmp)));
1887  if (g) {
1888  M -= STmp.Cross(GravityAcceleration);
1889  }
1890 
1891  WorkVec.Sub(4, M);
1892 
1893  return WorkVec;
1894 }
1895 
1896 
1897 /* Contributo allo jacobiano durante l'assemblaggio iniziale */
1900  const VectorHandler& /* XCurr */ )
1901 {
1902  DEBUGCOUTFNAME("StaticBody::InitialAssJac");
1903 
1904  WorkMat.SetNullMatrix();
1905 
1906  return WorkMat;
1907 }
1908 
1909 
1910 /* Contributo al residuo durante l'assemblaggio iniziale */
1913  const VectorHandler& /* XCurr */ )
1914 {
1915  DEBUGCOUTFNAME("StaticBody::InitialAssRes");
1916 
1917  WorkVec.ResizeReset(0);
1918 
1919  return WorkVec;
1920 }
1921 
1922 
1923 /* Usata per inizializzare la quantita' di moto */
1924 void
1926  VectorHandler& X, VectorHandler& /* XP */ ,
1928 {
1929  NO_OP;
1930 }
1931 
1932 /* StaticBody - end */
1933 
1934 
1935 /* Legge un corpo rigido */
1936 Elem*
1937 ReadBody(DataManager* pDM, MBDynParser& HP, unsigned int uLabel)
1938 {
1939  DEBUGCOUTFNAME("ReadBody");
1940 
1941  const char* sKeyWords[] = {
1942  NULL
1943  };
1944 
1945  /* enum delle parole chiave */
1946  enum KeyWords {
1947  UNKNOWN = -1,
1948  LASTKEYWORD = 0
1949  };
1950 
1951  /* tabella delle parole chiave */
1952  KeyTable K(HP, sKeyWords);
1953 
1954  /* nodo collegato */
1955  const StructDispNode *pStrDispNode = pDM->ReadNode<const StructDispNode, Node::STRUCTURAL>(HP);
1956  const StructNode *pStrNode = dynamic_cast<const StructNode *>(pStrDispNode);
1957 
1958  /* may be determined by a special DataManager parameter... */
1959  bool bStaticModel = pDM->bIsStaticModel();
1960  bool bInverseDynamics = pDM->bIsInverseDynamics();
1961 
1962  if (HP.IsKeyWord("variable" "mass")) {
1963  return ReadVariableBody(pDM, HP, uLabel, pStrNode);
1964  }
1965 
1966  integer iNumMasses = 1;
1967  if (HP.IsKeyWord("condense")) {
1968  iNumMasses = HP.GetInt();
1969  if (iNumMasses < 1) {
1970  silent_cerr("Body(" << uLabel << "): "
1971  "at least one mass is required in \"condense\" "
1972  "at line " << HP.GetLineData() << std::endl);
1974  }
1976  iNumMasses << " masses will be condensed" << std::endl);
1977 
1978  /* The inertia is calculated as follows:
1979  *
1980  * dm = Sum(dm_i)
1981  *
1982  * Xgc = Sum(Xgc_i*dm_i)/Sum(dm_i)
1983  *
1984  * J = Sum(J_i)-Sum(dm_i*(Xgc_i-Xgc)/\(Xgc_i-Xgc)/\)
1985  *
1986  * and it can be accomplished by accumulating:
1987  *
1988  * dm = Sum(dm_i)
1989  *
1990  * ~S = Sum(Xgc_i*dm_i)
1991  *
1992  * ~J = Sum(J_i)-Sum(dm_i*Xgc_i/\*Xgc_i/\)
1993  *
1994  * then calculating
1995  *
1996  * Xgc = S/dm
1997  *
1998  * and finally:
1999  *
2000  * J = ~J-Xgc/\(dm*Xgc/\-2*~S)
2001  *
2002  */
2003  }
2004 
2005  doublereal dm = 0.;
2006  ReferenceFrame RF(pStrDispNode);
2007  Vec3 Xgc(::Zero3);
2008  Vec3 STmp(::Zero3);
2009  Mat3x3 J(::Zero3x3);
2010  bool bNegative(false);
2011 
2012  if (HP.IsKeyWord("allow" "negative" "mass")) {
2013  bNegative = true;
2014  }
2015 
2016  for (int iCnt = 1; iCnt <= iNumMasses; iCnt++) {
2017  /* massa */
2018  doublereal dMTmp = HP.GetReal();
2019  if (!bNegative && dMTmp < 0.) {
2020  silent_cerr("Body(" << uLabel << "): "
2021  "negative mass is not allowed at line "
2022  << HP.GetLineData() << std::endl);
2024  }
2025 
2026  DEBUGLCOUT(MYDEBUG_INPUT, "Mass(" << iCnt << ") = " << dMTmp << std::endl);
2027  dm += dMTmp;
2028 
2029  if (pStrNode) {
2030  /* posiz. c.g. */
2031  Vec3 XgcTmp(HP.GetPosRel(RF));
2032  if (iNumMasses == 1) {
2033  Xgc = XgcTmp;
2034 
2035  } else {
2036  STmp += XgcTmp*dMTmp;
2037  }
2038 
2039  DEBUGLCOUT(MYDEBUG_INPUT, "position of mass(" << iCnt
2040  << ") center of gravity = " << XgcTmp << std::endl);
2041 
2042  /*
2043  * matrice del mom. d'inerzia
2044  *
2045  * Usa la funzione che legge una matrice qualsiasi con parole chiave
2046  * per forme abbreviate:
2047  * - null: matrice vuota
2048  * - eye: matrice identita'
2049  * - diag: matrice diagonale, seguita da 3 reali
2050  * - sym: matrice simmetrica, seguita da 6 reali,
2051  * letta come triangolare superiore ordinata per righe:
2052  * m11, m12, m13, m22, m23, m33
2053  * - matrice generica, costituita da 9 reali, letta per righe:
2054  * m11, m12, m13, m21, m22, m23, m31, m32, m33
2055  *
2056  * Si assume inoltre che la matrice dei momenti di inerzia
2057  * sia espressa nel centro di massa del corpo, quindi viene
2058  * corretta per l'eventuale offset rispetto al nodo
2059  */
2060  Mat3x3 JTmp(HP.GetMatRel(RF));
2061  DEBUGLCOUT(MYDEBUG_INPUT, "Inertia matrix of mass(" << iCnt
2062  << ") =" << std::endl << JTmp << std::endl);
2063  if (!JTmp.IsSymmetric()) {
2064  silent_cerr("Body(" << uLabel << "): "
2065  "warning, non-symmetric inertia tensor at line " << HP.GetLineData() << std::endl);
2066  }
2067 
2068  if (HP.IsKeyWord("inertial")) {
2070  "supplied in inertial reference frame" << std::endl);
2071  if (HP.IsKeyWord("node")) {
2072  NO_OP;
2073  } else {
2074  Mat3x3 RTmp(HP.GetRotRel(RF));
2075  JTmp = RTmp*JTmp.MulMT(RTmp);
2076  }
2078  "Inertia matrix of mass(" << iCnt << ") "
2079  "in current frame =" << JTmp << std::endl);
2080  }
2081 
2082  J += JTmp - Mat3x3(MatCrossCross, XgcTmp, XgcTmp*dMTmp);
2083  }
2084  }
2085 
2086  if (!bNegative && dm < 0.) {
2087  silent_cerr("Body(" << uLabel << "): "
2088  "negative mass is not allowed at line "
2089  << HP.GetLineData() << std::endl);
2091  }
2092 
2093  if (iNumMasses > 1 && pStrNode) {
2094  if (dm < std::numeric_limits<doublereal>::epsilon()) {
2095  silent_cerr("Body(" << uLabel << "): "
2096  "mass value " << dm << " is too small at line "
2097  << HP.GetLineData() << std::endl);
2099  }
2100 
2101  Xgc = STmp/dm;
2102  }
2103 
2104  DEBUGLCOUT(MYDEBUG_INPUT, "Total mass: " << dm << std::endl
2105  << "Center of mass: " << Xgc << std::endl
2106  << "Inertia matrix:" << std::endl << J << std::endl);
2107 
2108  const DynamicStructDispNode* pDynamicDispNode = 0;
2109  const StaticStructDispNode* pStaticDispNode = 0;
2110  const char *sElemName;
2111  const char *sNodeName;
2112  if (pStrNode) {
2113  sElemName = "Body";
2114  sNodeName = "StructNode";
2115  } else {
2116  sElemName = "Mass";
2117  sNodeName = "StructDispNode";
2118  }
2119 
2120  if (bStaticModel || bInverseDynamics) {
2121  /* static */
2122  pStaticDispNode = dynamic_cast<const StaticStructDispNode *>(pStrDispNode);
2123  if (pStaticDispNode == 0 || pStaticDispNode->GetStructDispNodeType() != StructDispNode::STATIC) {
2124  silent_cerr(sElemName << "(" << uLabel << "): "
2125  "illegal structural node type "
2126  "for " << sNodeName << "(" << pStrDispNode->GetLabel() << ") "
2127  "in " << (bStaticModel ? "static model" : "inverse dynamics") << " analysis "
2128  "at line " << HP.GetLineData() << std::endl);
2130  }
2131 
2132  } else {
2133  pDynamicDispNode = dynamic_cast<const DynamicStructDispNode*>(pStrDispNode);
2134  if (pDynamicDispNode == 0 || pDynamicDispNode->GetStructDispNodeType() != StructDispNode::DYNAMIC) {
2135  silent_cerr(sElemName << "(" << uLabel << "): "
2136  "illegal structural node type "
2137  "for " << sNodeName << "(" << pStrDispNode->GetLabel() << ") "
2138  "at line " << HP.GetLineData() << std::endl);
2140  }
2141  }
2142 
2143  flag fOut = pDM->fReadOutput(HP, Elem::BODY);
2144 
2145  /* Allocazione e costruzione */
2146  Elem* pEl = NULL;
2147  if (bStaticModel || bInverseDynamics) {
2148  StaticBody *pSB = 0;
2149  StaticMass *pSM = 0;
2150 
2151  /* static */
2152  if (pStrNode) {
2154  StaticBody(uLabel, dynamic_cast<const StaticStructNode *>(pStaticDispNode),
2155  dm, Xgc, J, fOut));
2156  pEl = pSB;
2157 
2158  } else {
2160  StaticMass(uLabel, pStaticDispNode,
2161  dm, fOut));
2162  pEl = pSM;
2163  }
2164 
2165  if (bInverseDynamics) {
2166  bool bIsRightHandSide(true);
2167  bool bIsErgonomy(true);
2168 
2169  if (HP.IsKeyWord("inverse" "dynamics")) {
2170  bIsRightHandSide = false;
2171  if (HP.IsKeyWord("right" "hand" "side")) {
2172  bIsRightHandSide = HP.GetYesNoOrBool(bIsRightHandSide);
2173  }
2174 
2175  bIsErgonomy = false;
2176  if (HP.IsKeyWord("ergonomy")) {
2177  bIsErgonomy = HP.GetYesNoOrBool(bIsErgonomy);
2178  }
2179  }
2180 
2181  unsigned flags = 0;
2182 
2183  if (bIsRightHandSide) {
2185  }
2186 
2187  if (bIsErgonomy) {
2188  flags |= InverseDynamics::ERGONOMY;
2189  }
2190 
2191  if (pSB) {
2192  pSB->SetInverseDynamicsFlags(flags);
2193 
2194  } else {
2195  pSM->SetInverseDynamicsFlags(flags);
2196  }
2197  }
2198 
2199  } else {
2200  if (pStrNode) {
2201  const DynamicStructNode* pDynamicStructNode = dynamic_cast<const DynamicStructNode*>(pDynamicDispNode);
2202  const ModalNode* pModalNode = dynamic_cast<const ModalNode*>(pDynamicDispNode);
2203  const RigidBodyKinematics* pRBK = pDynamicStructNode->pGetRBK();
2204 
2205  if (pModalNode && pRBK) {
2206  silent_cerr("Body(" << uLabel << ") "
2207  "is connected to ModalNode(" << pModalNode->GetLabel() << ") "
2208  "which uses rigid body kinematics "
2209  "at line " << HP.GetLineData() << std::endl);
2211  }
2212 
2213  if (pModalNode) {
2215  ModalBody(uLabel, pModalNode, dm, Xgc, J, fOut));
2216 
2217  } else {
2219  DynamicBody(uLabel, pDynamicStructNode, dm, Xgc, J, fOut));
2220  }
2221  } else {
2223  DynamicMass(uLabel, pDynamicDispNode,
2224  dm, fOut));
2225  }
2226  }
2227 
2228  pDM->GetLogFile()
2229  << "body: " << uLabel
2230  << ' ' << pStrDispNode->GetLabel()
2231  << ' ' << dm
2232  << ' ' << Xgc
2233  << ' ' << J
2234  << std::endl;
2235 
2236  /* Se non c'e' il punto e virgola finale */
2237  if (HP.IsArg()) {
2238  silent_cerr("semicolon expected "
2239  "at line " << HP.GetLineData() << std::endl);
2241  }
2242 
2243  return pEl;
2244 } /* End of ReadBody() */
2245 
flag fReadOutput(MBDynParser &HP, const T &t) const
Definition: dataman.h:1064
Mat3x3 GetRotRel(const ReferenceFrame &rf)
Definition: mbpar.cc:1795
virtual std::ostream & Restart(std::ostream &out) const
Definition: body.cc:774
virtual StructDispNode::Type GetStructDispNodeType(void) const
Definition: strnode.cc:1101
void PutColIndex(integer iSubCol, integer iCol)
Definition: submat.h:325
virtual void SetValue(DataManager *pDM, VectorHandler &X, VectorHandler &XP, SimulationEntity::Hints *ph=0)
Definition: body.cc:1377
virtual VariableSubMatrixHandler & InitialAssJac(VariableSubMatrixHandler &WorkMat, const VectorHandler &XCurr)
Definition: body.cc:684
const Vec3 Zero3(0., 0., 0.)
Vec3 Cross(const Vec3 &v) const
Definition: matvec3.h:218
void AssVecRBK_int(SubVectorHandler &WorkVec)
Definition: body.cc:183
virtual void SetValue(DataManager *pDM, VectorHandler &X, VectorHandler &XP, SimulationEntity::Hints *ph=0)
Definition: body.cc:1925
std::ostream & Write(std::ostream &out, const char *sFill=" ") const
Definition: matvec3.cc:738
long int flag
Definition: mbdyn.h:43
virtual const Mat3x3 & GetRRef(void) const
Definition: strnode.h:1006
#define MBDYN_EXCEPT_ARGS
Definition: except.h:63
Definition: body.h:270
Definition: matvec3.h:98
#define DEBUGCOUTFNAME(fname)
Definition: myassert.h:256
virtual void SetValue(DataManager *pDM, VectorHandler &X, VectorHandler &XP, SimulationEntity::Hints *ph=0)
Definition: body.cc:710
virtual void ResizeReset(integer)
Definition: vh.cc:55
virtual integer GetInt(integer iDefval=0)
Definition: parser.cc:1050
const MatCross_Manip MatCross
Definition: matvec3.cc:639
FullSubMatrixHandler & SetFull(void)
Definition: submat.h:1168
virtual const Mat3x3 & GetRCurr(void) const
Definition: strnode.h:1012
virtual Node::Type GetNodeType(void) const
Definition: strnode.cc:145
virtual SubVectorHandler & AssRes(SubVectorHandler &WorkVec, doublereal dCoef, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
Definition: body.cc:1192
void AssMats(FullSubMatrixHandler &WorkMatA, FullSubMatrixHandler &WorkMatB, doublereal dCoef, bool bGravity, const Vec3 &GravityAcceleration)
Definition: body.cc:1139
doublereal Dot(const Vec3 &v) const
Definition: matvec3.h:243
void Add(integer iRow, integer iCol, const Vec3 &v)
Definition: submat.cc:209
virtual VariableSubMatrixHandler & AssJac(VariableSubMatrixHandler &WorkMat, doublereal dCoef, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
Definition: body.cc:496
Vec3 STmp
Definition: body.h:279
std::ostream & Write(std::ostream &out, const FullMatrixHandler &m, const char *s, const char *s2)
Definition: fullmh.cc:376
virtual ~StaticMass(void)
Definition: body.cc:489
virtual ~Body(void)
Definition: body.cc:744
Vec3 GetG_int(void) const
Definition: body.cc:1407
virtual void Sub(integer iRow, const Vec3 &v)
Definition: vh.cc:78
virtual unsigned int iGetPrivDataIdx(const char *s) const
Definition: body.cc:831
const StructNode * pGetNode(void) const
Definition: body.cc:818
virtual SubVectorHandler & AssRes(SubVectorHandler &WorkVec, doublereal dCoef, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
Definition: body.cc:375
DynamicBody(unsigned int uL, const DynamicStructNode *pNodeTmp, doublereal dMassTmp, const Vec3 &XgcTmp, const Mat3x3 &JTmp, flag fOut)
Definition: body.cc:1002
virtual SubVectorHandler & AssRes(SubVectorHandler &WorkVec, doublereal dCoef, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
Definition: body.cc:1591
virtual const Vec3 & GetXPP(void) const =0
doublereal dGetM(void) const
Definition: body.cc:98
Vec3 GetS(void) const
Definition: body.cc:804
virtual ~DynamicMass(void)
Definition: body.cc:240
virtual bool bGetGravity(const Vec3 &X, Vec3 &Acc) const
Definition: gravity.cc:208
StaticMass(unsigned int uL, const StaticStructDispNode *pNode, doublereal dMass, flag fOut)
Definition: body.cc:477
void AssVecRBK_int(SubVectorHandler &WorkVec)
Definition: body.cc:888
virtual VariableSubMatrixHandler & AssJac(VariableSubMatrixHandler &WorkMat, doublereal dCoef, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
Definition: body.cc:247
virtual const doublereal & dGetCoef(integer iRow) const =0
bool AssMats(FullSubMatrixHandler &WorkMatA, FullSubMatrixHandler &WorkMatB, doublereal dCoef)
Definition: body.cc:1758
virtual const Vec3 & GetWRef(void) const
Definition: strnode.h:1024
#define NO_OP
Definition: myassert.h:74
Mat3x3 GetJ_int(void) const
Definition: body.cc:77
virtual StructDispNode::Type GetStructDispNodeType(void) const
Definition: strnode.cc:1429
virtual void WorkSpaceDim(integer *piNumRows, integer *piNumCols) const
Definition: body.cc:1022
std::vector< Hint * > Hints
Definition: simentity.h:89
virtual SubVectorHandler & InitialAssRes(SubVectorHandler &WorkVec, const VectorHandler &XCurr)
Definition: body.cc:1324
bool bIsStaticModel(void) const
Definition: dataman.h:482
void SetInverseDynamicsFlags(unsigned uIDF)
Definition: elem.cc:71
Mat3x3 J0
Definition: body.h:277
void IncCoef(integer iRow, integer iCol, const doublereal &dCoef)
Definition: submat.h:683
virtual SubVectorHandler & InitialAssRes(SubVectorHandler &WorkVec, const VectorHandler &XCurr)
Definition: body.cc:440
virtual void AfterPredict(VectorHandler &X, VectorHandler &XP)
Definition: body.cc:787
virtual void InitialWorkSpaceDim(integer *piNumRows, integer *piNumCols) const
Definition: body.cc:1029
const Mat3x3DEye_Manip Mat3x3DEye
Definition: matvec3.cc:637
virtual bool GetYesNoOrBool(bool bDefval=false)
Definition: parser.cc:1038
Vec3 GetB_int(void) const
Definition: body.cc:1395
virtual void SetValue(DataManager *pDM, VectorHandler &X, VectorHandler &XP, SimulationEntity::Hints *ph=0)
Definition: body.cc:453
Vec3 MulTV(const Vec3 &v) const
Definition: matvec3.cc:482
Elem * ReadBody(DataManager *pDM, MBDynParser &HP, unsigned int uLabel)
Definition: body.cc:1937
StaticBody(unsigned int uL, const StaticStructNode *pNode, doublereal dMass, const Vec3 &Xgc, const Mat3x3 &J, flag fOut)
Definition: body.cc:1659
virtual void PutRowIndex(integer iSubRow, integer iRow)=0
const Mat3x3 Zero3x3(0., 0., 0., 0., 0., 0., 0., 0., 0.)
virtual VariableSubMatrixHandler & InitialAssJac(VariableSubMatrixHandler &WorkMat, const VectorHandler &XCurr)
Definition: body.cc:1899
virtual ~ModalBody(void)
Definition: body.cc:1441
Mat3x3 MulTVCross(const Vec3 &v) const
Definition: matvec3.cc:596
Vec3 GetPosRel(const ReferenceFrame &rf)
Definition: mbpar.cc:1331
bool AssMats(FullSubMatrixHandler &WorkMatA, FullSubMatrixHandler &WorkMatB, doublereal dCoef)
Definition: body.cc:574
virtual std::ostream & Restart(std::ostream &out) const
Definition: body.cc:87
virtual unsigned int iGetNumPrivData(void) const
Definition: body.cc:126
void SetNullMatrix(void)
Definition: submat.h:1159
virtual bool IsKeyWord(const char *sKeyWord)
Definition: parser.cc:910
ModalBody(unsigned int uL, const ModalNode *pNodeTmp, doublereal dMassTmp, const Vec3 &XgcTmp, const Mat3x3 &JTmp, flag fOut)
Definition: body.cc:1427
Mat3x3 GetMatRel(const ReferenceFrame &rf)
Definition: mbpar.cc:1737
const StructDispNode * pNode
Definition: body.h:48
Vec3 GetS(void) const
Definition: body.cc:105
virtual ~DynamicBody(void)
Definition: body.cc:1016
doublereal dMass
Definition: body.h:49
virtual integer iGetFirstMomentumIndex(void) const =0
virtual integer iGetFirstPositionIndex(void) const
Definition: strnode.h:452
doublereal dMass
Definition: body.h:274
virtual const Vec3 & GetWCurr(void) const
Definition: strnode.h:1030
virtual ~Mass(void)
Definition: body.cc:61
doublereal dGetM(void) const
Definition: body.cc:797
void AssMatsRBK_int(FullSubMatrixHandler &WMA, FullSubMatrixHandler &WMB, const doublereal &dCoef, const Vec3 &Sc)
Definition: body.cc:928
virtual VariableSubMatrixHandler & InitialAssJac(VariableSubMatrixHandler &WorkMat, const VectorHandler &XCurr)
Definition: body.cc:426
virtual SubVectorHandler & AssRes(SubVectorHandler &WorkVec, doublereal dCoef, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
Definition: body.cc:601
virtual const Vec3 & GetWPCurr(void) const
Definition: strnode.h:1042
#define ASSERT(expression)
Definition: colamd.c:977
const RigidBodyKinematics * pGetRBK(void) const
Definition: strnode.cc:152
virtual VariableSubMatrixHandler & AssJac(VariableSubMatrixHandler &WorkMat, doublereal dCoef, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
Definition: body.cc:1454
DynamicMass(unsigned int uL, const DynamicStructDispNode *pNode, doublereal dMassTmp, flag fOut)
Definition: body.cc:228
KeyWords
Definition: dataman4.cc:94
Vec3 WP
Definition: body.h:428
VectorExpression< VectorCrossExpr< VectorLhsExpr, VectorRhsExpr >, 3 > Cross(const VectorExpression< VectorLhsExpr, 3 > &u, const VectorExpression< VectorRhsExpr, 3 > &v)
Definition: matvec.h:3248
#define SAFENEWWITHCONSTRUCTOR(pnt, item, constructor)
Definition: mynewmem.h:698
virtual const Vec3 & GetXCurr(void) const
Definition: strnode.h:310
Definition: body.h:45
virtual void Add(integer iRow, const Vec3 &v)
Definition: vh.cc:63
virtual VariableSubMatrixHandler & InitialAssJac(VariableSubMatrixHandler &WorkMat, const VectorHandler &XCurr)
Definition: body.cc:1255
Mat3x3 JTmp
Definition: body.h:280
virtual SubVectorHandler & InitialAssRes(SubVectorHandler &WorkVec, const VectorHandler &XCurr)
Definition: body.cc:697
Vec3 GetB_int(void) const
Definition: body.cc:465
virtual doublereal dGetPrivData(unsigned int i) const
Definition: body.cc:153
virtual void ResizeReset(integer, integer)
Definition: submat.cc:182
virtual const Vec3 & GetWP(void) const =0
const StructDispNode * pGetNode(void) const
Definition: body.cc:119
virtual bool bInverseDynamics(void) const
Definition: body.cc:1841
void AssMats(FullSubMatrixHandler &WorkMatA, FullSubMatrixHandler &WorkMatB, doublereal dCoef, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr, bool bGravity, const Vec3 &GravityAcceleration)
Definition: body.cc:1540
const MatCrossCross_Manip MatCrossCross
Definition: matvec3.cc:640
virtual bool IsArg(void)
Definition: parser.cc:807
virtual ~StaticBody(void)
Definition: body.cc:1673
Definition: elem.h:75
virtual const Vec3 & GetW(void) const =0
virtual unsigned int iGetPrivDataIdx(const char *s) const
Definition: body.cc:132
void PutRowIndex(integer iSubRow, integer iRow)
Definition: submat.h:311
std::ostream & GetLogFile(void) const
Definition: dataman.h:326
virtual VariableSubMatrixHandler & AssJac(VariableSubMatrixHandler &WorkMat, doublereal dCoef, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
Definition: body.cc:1036
Mat3x3 GetJ_int(void) const
Definition: body.cc:760
void AssMats(FullSubMatrixHandler &WorkMatA, FullSubMatrixHandler &WorkMatB, doublereal dCoef, bool bGravity, const Vec3 &GravityAcceleration)
Definition: body.cc:350
Elem * ReadVariableBody(DataManager *pDM, MBDynParser &HP, unsigned int uLabel, const StructNode *pStrNode)
Definition: body_vm.cc:1022
virtual unsigned int iGetNumPrivData(void) const
Definition: body.cc:825
Vec3 GetS_int(void) const
Definition: body.cc:752
Vec3 S0
Definition: body.h:276
virtual const Vec3 & GetVCurr(void) const
Definition: strnode.h:322
void Sub(integer iRow, integer iCol, const Vec3 &v)
Definition: submat.cc:215
virtual bool bInverseDynamics(void) const
Definition: body.cc:642
void AssMatsRBK_int(FullSubMatrixHandler &WMA, FullSubMatrixHandler &WMB, const doublereal &dCoef)
Definition: body.cc:204
Mass(unsigned int uL, const StructDispNode *pNode, doublereal dMassTmp, flag fOut)
Definition: body.cc:44
static const doublereal a
Definition: hfluid_.h:289
virtual SubVectorHandler & InitialAssRes(SubVectorHandler &WorkVec, const VectorHandler &XCurr)
Definition: body.cc:1912
Mat3x3 MulMT(const Mat3x3 &m) const
Definition: matvec3.cc:444
virtual const Vec3 & GetXPPCurr(void) const
Definition: strnode.h:334
virtual integer iGetFirstIndex(void) const
Definition: dofown.h:127
virtual VariableSubMatrixHandler & AssJac(VariableSubMatrixHandler &WorkMat, doublereal dCoef, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
Definition: body.cc:1680
double doublereal
Definition: colamd.c:52
long int integer
Definition: colamd.c:51
virtual doublereal dGetPrivData(unsigned int i) const
Definition: body.cc:852
virtual void AddInertia(const doublereal &dm) const
Definition: strnode.cc:1244
virtual HighParser::ErrOut GetLineData(void) const
Definition: parsinc.cc:697
const StructNode * pNode
Definition: body.h:273
virtual SubVectorHandler & AssRes(SubVectorHandler &WorkVec, doublereal dCoef, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
Definition: body.cc:1794
unsigned int GetLabel(void) const
Definition: withlab.cc:62
Node * ReadNode(MBDynParser &HP, Node::Type type) const
Definition: dataman3.cc:2309
Mat3x3 GetJ(void) const
Definition: body.cc:112
#define DEBUGLCOUT(level, msg)
Definition: myassert.h:244
Mat3x3 GetJ(void) const
Definition: body.cc:811
Vec3 XPP
Definition: body.h:428
virtual void Resize(integer iNewSize)=0
Vec3 Xgc
Definition: body.h:275
Mat3x3 R
Vec3 GetS_int(void) const
Definition: body.cc:69
void WorkSpaceDim(integer *piNumRows, integer *piNumCols) const
Definition: body.cc:1447
virtual void AddInertia(const doublereal &dm, const Vec3 &dS, const Mat3x3 &dJ) const
Definition: strnode.cc:3092
bool bIsInverseDynamics(void) const
Definition: dataman.h:493
Body(unsigned int uL, const StructNode *pNode, doublereal dMassTmp, const Vec3 &XgcTmp, const Mat3x3 &JTmp, flag fOut)
Definition: body.cc:722
virtual doublereal GetReal(const doublereal &dDefval=0.0)
Definition: parser.cc:1056