106 #include "mbconfig.h"
109 #define MODAL_USE_GRAVITY
114 #include <sys/stat.h>
134 const std::vector<unsigned int>& uModeNumber,
138 const std::vector<std::string>& IdFEMNodes,
140 const std::vector<Modal::StrNodeData>& snd,
156 Joint(uL, pDO, fOut),
158 iRigidOffset(pModalNode ? 12 : 0),
165 IdFEMNodes(IdFEMNodes),
170 uModeNumber(uModeNumber),
171 pModalMass(pGenMass),
172 pModalStiff(pGenStiff),
173 pModalDamp(pGenDamp),
176 pModeShapest(pModeShapest),
177 pModeShapesr(pModeShapesr),
195 Inv5jaPj(NModes, 0.),
202 aPrime(NModes, 0.), aPrime0(*bb),
270 return out <<
"modal; # not implemented yet" << std::endl;
288 << prefix << iModalIndex + 1 <<
"->" << iModalIndex +
NModes
289 <<
": modal displacements [q(1.." <<
NModes <<
")]" << std::endl
290 << prefix << iModalIndex +
NModes + 1 <<
"->" << iModalIndex + 2*
NModes
291 <<
": modal velocities [qP(1.." <<
NModes <<
")]" << std::endl;
293 for (
unsigned iStrNodem1 = 0; iStrNodem1 <
NStrNodes; iStrNodem1++, iModalIndex += 6) {
295 << prefix << iModalIndex + 1 <<
"->" << iModalIndex + 3 <<
": "
296 "StructNode(" <<
SND[iStrNodem1].pNode->GetLabel() <<
") "
297 "reaction forces [Fx,Fy,Fz]" << std::endl
298 << prefix << iModalIndex + 4 <<
"->" << iModalIndex + 6 <<
": "
299 "StructNode(" <<
SND[iStrNodem1].pNode->GetLabel() <<
") "
300 "reaction couples [Mx,My,Mz]" << std::endl;
304 << prefix << iModalIndex + 1 <<
"->" << iModalIndex + 3 <<
": "
305 "StructNode(" <<
SND[iStrNodem1].pNode->GetLabel() <<
") "
306 "reaction force derivatives [FPx,FPy,FPz]" << std::endl
307 << prefix << iModalIndex + 4 <<
"->" << iModalIndex + 6 <<
": "
308 "StructNode(" <<
SND[iStrNodem1].pNode->GetLabel() <<
") "
309 "reaction couple derivatives [MPx,MPy,MPz]" << std::endl;
316 static const char xyz[] =
"xyz";
318 "modal displacement q",
324 "reaction force derivative FP",
325 "reaction couple derivative MP"
327 static const char *
meq[] = {
328 "modal velocity definition q",
329 "modal equilibrium equation f"
331 static const char *
req[] = {
332 "position constraint P",
333 "orientation constraint g",
334 "velocity constraint v",
335 "angular velocity constraint w"
355 std::ostringstream os;
356 os <<
"Modal(" <<
GetLabel() <<
")";
362 }
else if (i == -1) {
363 std::string name(os.str());
365 for (
unsigned i = 0; i < 2*
NModes; i++) {
367 os.seekp(0, std::ios_base::end);
368 os <<
": " <<
mdof[i/
NModes] <<
"(" << i%NModes + 1 <<
")";
372 for (
unsigned i = 0; i < modulo*
NStrNodes; i++) {
374 os.seekp(0, std::ios_base::end);
375 os <<
": StructNode(" <<
SND[i/modulo].pNode->GetLabel() <<
") "
376 <<
rdof[(i/3)%(modulo/3)] <<
xyz[i%3];
377 desc[2*NModes + i] = os.str();
381 if (
unsigned(i) < 2*
NModes) {
394 os <<
": StructNode(" <<
SND[i/modulo].pNode->GetLabel() <<
") "
395 <<
rdof[(i/3)%(modulo/3)] <<
xyz[i%3];
407 << prefix << iModalIndex + 1 <<
"->" << iModalIndex +
NModes
408 <<
": modal velocity definitions [q(1.." <<
NModes <<
")=qP(1.." <<
NModes <<
")]" << std::endl
409 << prefix << iModalIndex +
NModes + 1 <<
"->" << iModalIndex + 2*
NModes
410 <<
": modal equilibrium equations [1.." <<
NModes <<
"]" << std::endl;
412 for (
unsigned iStrNodem1 = 0; iStrNodem1 <
NStrNodes; iStrNodem1++, iModalIndex += 6) {
414 << prefix << iModalIndex + 1 <<
"->" << iModalIndex + 3 <<
": "
415 "StructNode(" <<
SND[iStrNodem1].pNode->GetLabel() <<
") "
416 "position constraints [Px=PxN,Py=PyN,Pz=PzN]" << std::endl
417 << prefix << iModalIndex + 4 <<
"->" << iModalIndex + 6 <<
": "
418 "StructNode(" <<
SND[iStrNodem1].pNode->GetLabel() <<
") "
419 "orientation constraints [gx=gxN,gy=gyN,gz=gzN]" << std::endl;
423 << prefix << iModalIndex + 1 <<
"->" << iModalIndex + 3 <<
": "
424 "StructNode(" <<
SND[iStrNodem1].pNode->GetLabel() <<
") "
425 "velocity constraints [vx=vxN,vy=vyN,vz=vzN]" << std::endl
426 << prefix << iModalIndex + 4 <<
"->" << iModalIndex + 6 <<
": "
427 "StructNode(" <<
SND[iStrNodem1].pNode->GetLabel() <<
") "
428 "angular velocity constraints [wx=wxN,wy=wyN,wz=wzN]" << std::endl;
452 std::ostringstream os;
453 os <<
"Modal(" <<
GetLabel() <<
")";
459 }
else if (i == -1) {
460 std::string name(os.str());
462 for (
unsigned i = 0; i < 2*
NModes; i++) {
464 os.seekp(0, std::ios_base::end);
465 os <<
": " <<
meq[i/
NModes] <<
"(" << i%NModes + 1 <<
")";
469 for (
unsigned i = 0; i < modulo*
NStrNodes; i++) {
471 os.seekp(0, std::ios_base::end);
472 os <<
": StructNode(" <<
SND[i/modulo].pNode->GetLabel() <<
") "
473 <<
req[(i/3)%(modulo/3)] <<
xyz[i%3];
474 desc[2*NModes + i] = os.str();
478 if (
unsigned(i) < 2*
NModes) {
491 os <<
": StructNode(" <<
SND[i/modulo].pNode->GetLabel() <<
") "
492 <<
req[(i/3)%(modulo/3)] <<
xyz[i%3];
531 #if USE_AUTODIFF && MODAL_USE_AUTODIFF && !MODAL_DEBUG_AUTODIFF
534 *piNumRows = -iNumRows;
535 *piNumCols = iNumCols;
548 DEBUGCOUT(
"Entering Modal::AssJac()" << std::endl);
549 #if USE_AUTODIFF && MODAL_USE_AUTODIFF && !MODAL_DEBUG_AUTODIFF
579 for (
unsigned int iCnt = 1; iCnt <=
iRigidOffset; iCnt++) {
589 for (
unsigned int iCnt = 1; iCnt <= iNumDof; iCnt++) {
595 for (
unsigned int iStrNodem1 = 0; iStrNodem1 <
NStrNodes; iStrNodem1++) {
597 SND[iStrNodem1].pNode->iGetFirstMomentumIndex();
599 SND[iStrNodem1].pNode->iGetFirstPositionIndex();
602 for (
integer iCnt = 1; iCnt <= 6; iCnt++) {
603 WM.
PutRowIndex(iOffset + iCnt, iNodeFirstMomIndex + iCnt);
604 WM.
PutColIndex(iOffset + iCnt, iNodeFirstPosIndex + iCnt);
631 for (
int iCnt = 6 + 1; iCnt <= 6 + 3; iCnt++) {
648 for (
int iCnt = 1; iCnt <= 6; iCnt++) {
650 WM.
DecCoef(iCnt, 6 + iCnt, dCoef);
662 for (
unsigned int iCnt = 1; iCnt <=
NModes; iCnt++) {
667 for (
unsigned int jCnt = 1; jCnt <=
NModes; jCnt++) {
697 WM.
Sub(6 + 1, 9 + 1, Inv3jaPjWedge);
724 WM.
Add(9 + 1, 9 + 1,
R*(JTmp*(
RT*(2.*dCoef))));
734 Jac13.LeftMult(wrWedge*
R*2*dCoef, *
pInv3);
748 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
752 unsigned int jOffset = (jMode - 1)*3 + 1;
756 for (
unsigned int kModem1 = 0; kModem1 <
NModes; kModem1++) {
758 integer iOffset = (jMode - 1)*3*NModes + kModem1*3 + 1;
762 for (
int iCnt = 1; iCnt <= 3; iCnt++) {
764 for (
int jCnt = 1; jCnt<=3; jCnt++) {
766 temp1 += -2*wr.
dGet(jCnt)*(
R*(Inv8jTranspose - Inv9jkak)*
RT).dGet(iCnt, jCnt);
768 temp1 += -2*wr.
dGet(jCnt)*(
R*(Inv8jTranspose)*
RT).dGet(iCnt, jCnt);
770 temp2 += -(
R*(Inv4j + VInv5jaj)).dGet(jCnt)*wrWedge.dGet(iCnt, jCnt);
773 dCoef*(temp1 + temp2));
775 for (
int iCnt = 1; iCnt<=3; iCnt++) {
777 for (
int jCnt = 1; jCnt<=3; jCnt++) {
778 temp1 += (
R*VInv5jaPj*2).dGet(jCnt);
788 for (
unsigned int iStrNode = 1; iStrNode <=
NStrNodes; iStrNode++) {
789 unsigned int iStrNodem1 = iStrNode - 1;
793 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
794 integer iOffset = (jMode - 1)*NStrNodes + iStrNode;
801 PHItT.Transpose(PHIt);
823 for (
int iCnt = 1; iCnt <= 3; iCnt++) {
825 WM.
DecCoef(iStrNodeIndex + iCnt, iReactionIndex + iCnt, 1.);
828 WM.
DecCoef(iReactionIndex + iCnt, iStrNodeIndex + iCnt, 1.);
832 for (
int iCnt = 1; iCnt <= 3; iCnt++) {
834 WM.
IncCoef(6 + iCnt, iReactionIndex + iCnt, 1.);
837 WM.
IncCoef(iReactionIndex + iCnt, iCnt, 1.);
844 WM.
Add(9 + 1, iReactionIndex + 1, dTmp1Wedge);
847 WM.
Add(9 + 1, 3 + 1, FTmpWedge*dTmp1Wedge);
850 WM.
Sub(iReactionIndex + 1, 3 + 1, dTmp1Wedge);
856 SubMat1.LeftMult(FTmpWedge, PHItR);
865 WM.
Sub(iStrNodeIndex + 3 + 1, iReactionIndex + 1, dTmp2Wedge);
868 WM.
Sub(iStrNodeIndex + 3 + 1, iStrNodeIndex + 3 + 1,
869 FTmpWedge*dTmp2Wedge);
878 WM.
Add(iReactionIndex + 1, iStrNodeIndex + 3 + 1, dTmp2Wedge);
885 Vec3 MTmp =
SND[iStrNodem1].R2*(
SND[iStrNodem1].M*dCoef);
890 WM.
Sub(9 + 1, iStrNodeIndex + 3 + 1, MTmpWedge);
892 WM.
Add(iStrNodeIndex + 3 + 1, iStrNodeIndex + 3 + 1, MTmpWedge);
903 WM.
AddT(iReactionIndex + 3 + 1, 3 + 1,
SND[iStrNodem1].R2);
904 WM.
Add(9 + 1, iReactionIndex + 3 + 1,
SND[iStrNodem1].R2);
906 WM.
SubT(iReactionIndex + 3 + 1, iStrNodeIndex + 3 + 1,
SND[iStrNodem1].R2);
907 WM.
Sub(iStrNodeIndex + 3 + 1, iReactionIndex + 3 + 1,
SND[iStrNodem1].R2);
912 for (
unsigned iMode = 1; iMode <=
NModes; iMode++) {
913 for (
unsigned jIdx = 1; jIdx <= 3; jIdx++) {
915 SubMat3(iMode, jIdx));
929 DEBUGCOUT(
"Entering Modal::AssRes()" << std::endl);
930 #if USE_AUTODIFF && MODAL_USE_AUTODIFF && !MODAL_DEBUG_AUTODIFF
944 #if USE_AUTODIFF && MODAL_USE_AUTODIFF && MODAL_DEBUG_AUTODIFF
946 silent_cerr(
"Residual: #" << ++iResidual << std::endl);
949 WorkVecAD.
Resize(iNumRows);
982 for (
unsigned int iCnt = 1; iCnt <= iNumDof; iCnt++) {
988 for (
unsigned iStrNodem1 = 0; iStrNodem1 <
NStrNodes; iStrNodem1++) {
990 SND[iStrNodem1].pNode->iGetFirstMomentumIndex();
992 for (
unsigned int iCnt = 1; iCnt <= 6; iCnt++) {
994 iNodeFirstMomIndex + iCnt);
1000 a.
Copy(XCurr, iModalIndex + 1);
1015 std::cerr <<
"### Stiff" << std::endl;
1016 for (
unsigned int i = 1; i <=
NModes; i++) {
1017 for (
unsigned int j = 1; j <=
NModes; j++) {
1018 std::cerr << std::setw(2) << i <<
", "
1019 << std::setw(2) << j <<
" "
1020 << std::setw(20) << (*pModalStiff)(i,j)
1025 std::cerr <<
"### Damp" << std::endl;
1026 for (
unsigned int i = 1; i <=
NModes; i++) {
1027 for (
unsigned int j = 1; j <=
NModes; j++) {
1028 std::cerr << std::setw(2) << i <<
", "
1029 << std::setw(2) << j <<
" "
1030 << std::setw(20) << (*pModalDamp)(i,j)
1034 std::cerr <<
"### Mass" << std::endl;
1035 for (
unsigned int i = 1; i <=
NModes; i++) {
1036 for (
unsigned int j = 1; j <=
NModes; j++) {
1037 std::cerr << std::setw(2) << i <<
", "
1038 << std::setw(2) << j <<
" "
1039 << std::setw(20) << (*pModalMass)(i,j)
1043 std::cerr <<
"### a" << std::endl;
1044 for (
unsigned int i = 1; i <=
NModes; i++) {
1045 std::cerr << std::setw(2) << i <<
" "
1046 << std::setw(20) <<
a(i) << std::endl;
1048 std::cerr <<
"### b" << std::endl;
1049 for (
unsigned int i = 1; i <=
NModes; i++) {
1050 std::cerr << std::setw(2) << i <<
" "
1051 << std::setw(20) <<
b(i) << std::endl;
1053 std::cerr <<
"### bP" << std::endl;
1054 for (
unsigned int i = 1; i <=
NModes; i++) {
1055 std::cerr << std::setw(2) << i <<
" "
1056 << std::setw(20) <<
bPrime(i) << std::endl;
1086 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
1091 for (
unsigned int kMode = 1; kMode <=
NModes; kMode++) {
1102 for (
unsigned int jCnt = 1; jCnt <= 3; jCnt++) {
1103 unsigned int iMjC = (jMode - 1)*3 + jCnt;
1108 Inv8jaj += Inv8jajTmp * a_jMode;
1118 for (
unsigned int kMode = 1; kMode <=
NModes; kMode++) {
1121 unsigned int iOffset = (jMode - 1)*3*
NModes + (kMode - 1)*3 + 1;
1131 for (
unsigned int jCnt = 1; jCnt <= 3; jCnt++) {
1132 unsigned int iMjC = (jMode - 1)*3 + jCnt;
1138 Inv10jaPj += Inv10jaPjTmp;
1143 #ifdef MODAL_USE_GRAVITY
1157 for (
unsigned int iCnt = 1; iCnt <=
iRigidOffset; iCnt++) {
1170 Vec3 v(XCurr, iRigidIndex + 6 + 1);
1171 w =
Vec3(XCurr, iRigidIndex + 9 + 1);
1198 FTmp +=
R*Inv3jaPPj + (w.Cross(
R*
Inv3jaPj))*2.;
1200 WorkVec.
Sub(6 + 1, FTmp);
1202 std::cerr <<
"m=" <<
dMass <<
"; S=" << S
1203 <<
"; a=" <<
a <<
"; aPrime =" <<
aPrime
1204 <<
"; b=" <<
b <<
"; bPrime= " <<
bPrime
1206 + (w.Cross(
R*
Inv3jaPj))*2 +
R*Inv3jaPPj << std::endl;
1218 MTmp += Inv5jajCurr*
bPrime;
1225 MTmp +=
R*Tmp*(RTw*2.);
1235 WorkVec.
Sub(9 + 1, MTmp);
1237 #ifdef MODAL_USE_GRAVITY
1240 WorkVec.
Add(6 + 1, GravityAcceleration*
dMass);
1241 WorkVec.
Add(9 + 1, S.
Cross(GravityAcceleration));
1246 WorkVec.
Add(1, v - xP);
1252 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
1253 unsigned int jOffset = (jMode - 1)*3 + 1;
1254 doublereal d = - MaPP(jMode) - CaP(jMode) - Ka(jMode);
1259 d -= (
R*Inv3j).
Dot(vP);
1261 #ifdef MODAL_USE_GRAVITY
1265 (
R*Inv3j).
Dot(GravityAcceleration));
1278 d -= (
R*Inv4j).
Dot(wP);
1287 for (
unsigned int kModem1 = 0; kModem1 <
NModes; kModem1++) {
1289 integer kOffset = (jMode - 1)*3*NModes + kModem1*3 + 1;
1300 d += w.
Dot(
R*(MTmp*RTw));
1306 std::cerr <<
"(R*Inv3j).Dot(vP)=" << (
R*Inv3j).
Dot(vP)
1308 <<
"(R*(Inv4j + VInv5jaj)).Dot(wP)="
1309 << (
R*(Inv4j + VInv5jaj)).Dot(wP) << std::endl
1310 <<
"w.Dot(R*((Inv8jTranspose + Inv10j)*RTw))"
1311 << w.
Dot(
R*((Inv8jTranspose + Inv10j)*RTw)) << std::endl
1312 <<
" -(R*VInv5jaPj).Dot(w)*2."
1313 << -(
R*VInv5jaPj).
Dot(w)*2.<< std::endl
1314 <<
" -CaP.dGet(jMode)" << -CaP.dGet(jMode)<< std::endl
1315 <<
"-Ka.dGet(jMode) "
1316 << -CaP.dGet(jMode) - Ka.dGet(jMode) << std::endl;
1321 for (
unsigned int iCnt = 1; iCnt <=
NModes; iCnt++) {
1326 for (
unsigned int iStrNode = 1; iStrNode <=
NStrNodes; iStrNode++) {
1327 unsigned int iStrNodem1 = iStrNode - 1;
1334 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
1335 integer iOffset = (jMode - 1)*NStrNodes + iStrNode;
1345 SND[iStrNodem1].d1tot =
R*(
SND[iStrNodem1].OffsetFEM + PHIt*
a);
1349 SND[iStrNodem1].F =
Vec3(XCurr,
1350 iModalIndex + 2*
NModes + 6*iStrNodem1 + 1);
1351 const Vec3& x2 =
SND[iStrNodem1].pNode->GetXCurr();
1354 SND[iStrNodem1].R2 =
SND[iStrNodem1].pNode->GetRCurr();
1357 Vec3 dTmp1(
SND[iStrNodem1].d1tot);
1358 Vec3 dTmp2(
SND[iStrNodem1].R2*
SND[iStrNodem1].OffsetMB);
1362 WorkVec.
Sub(6 + 1,
SND[iStrNodem1].F);
1363 WorkVec.
Sub(9 + 1, dTmp1.
Cross(
SND[iStrNodem1].F));
1369 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
1372 PHIt.GetVec(jMode)*vtemp);
1376 WorkVec.
Add(iStrNodeIndex + 1,
SND[iStrNodem1].F);
1377 WorkVec.
Add(iStrNodeIndex + 3 + 1, dTmp2.
Cross(
SND[iStrNodem1].F));
1381 WorkVec.
Add(iReactionIndex + 1, (x2 + dTmp2 -
x - dTmp1)/dCoef);
1384 SND[iStrNodem1].M =
Vec3(XCurr,
1385 iModalIndex + 2*
NModes + 6*iStrNodem1 + 3 + 1);
1389 Vec3 MTmp =
SND[iStrNodem1].R2*
SND[iStrNodem1].M;
1393 WorkVec.
Sub(9 + 1, MTmp);
1397 WorkVec.
Add(iStrNodeIndex + 3 + 1, MTmp);
1401 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
1404 PHIr.
GetVec(jMode)*vtemp);
1410 WorkVec.
Sub(iReactionIndex + 3 + 1, ThetaCurr/dCoef);
1414 std::cerr <<
"###" << std::endl;
1415 for (
int i = 1; i <= WorkVec.
iGetSize(); i++) {
1416 std::cerr << std::setw(2) << i <<
"("
1418 << std::setw(20) << WorkVec(i) << std::endl;
1423 #if USE_AUTODIFF && MODAL_USE_AUTODIFF && MODAL_DEBUG_AUTODIFF
1430 dTol *=
sqrt(std::numeric_limits<doublereal>::epsilon());
1443 if (
fabs(dVal - dValAD) > dTol) {
1444 silent_cerr(
"\tRowIndex: " << iRow <<
" WorkVec(" << i <<
")=" << dVal <<
", WorkVecAD(" << i <<
")=" << dValAD << std::endl);
1449 silent_cerr(
"Residual #" << iResidual <<
": NOK" << std::endl);
1456 #if USE_AUTODIFF && MODAL_USE_AUTODIFF
1465 using namespace grad;
1468 oNode.
d1tot(i) = d1tot(i);
1475 oNode.
R1tot(i, j) = R1tot(i, j);
1476 oNode.
R2(i, j) = R2(i, j);
1485 using namespace grad;
1493 R(i, j) = RTmp(i, j);
1504 using namespace grad;
1511 aPrime(i) = aPrimeTmp(i);
1519 bPrime(i) = bPrimeTmp(i);
1528 using namespace grad;
1536 Inv8jaj(i, j) = Inv8jajTmp(i, j);
1547 template <
typename T>
1555 using namespace grad;
1567 XCurr.dGetCoef(iModalIndex + i,
a(i), dCoef, &dofMap);
1568 XPrimeCurr.dGetCoef(iModalIndex + i,
aPrime(i), 1., &dofMap);
1572 XCurr.dGetCoef(iModalIndex +
NModes + i,
b(i), dCoef, &dofMap);
1573 XPrimeCurr.dGetCoef(iModalIndex +
NModes + i,
bPrime(i), 1., &dofMap);
1595 const T& a_jMode =
a(jMode);
1596 const T& aP_jMode =
b(jMode);
1602 Inv5jaj(i, kMode) += v_i * a_jMode;
1603 Inv5jaPj(i, kMode) += v_i * aP_jMode;
1609 for (
index_type jCnt = 1; jCnt <= 3; jCnt++) {
1610 const index_type iMjC = (jMode - 1) * 3 + jCnt;
1612 Inv8jaj(i, jCnt) += (*pInv8)(i, iMjC) * a_jMode;
1613 Inv8jaPj(i, jCnt) += (*pInv8)(i, iMjC) * aP_jMode;
1619 const T& a_kMode =
a(kMode);
1620 const T& aP_kMode =
b(kMode);
1625 Inv9jkajak(i, j) += (*pInv9)(i, iOffset + j) * a_jMode * a_kMode;
1626 Inv9jkajaPk(i, j) += (*pInv9)(i, iOffset + j) * a_jMode * aP_kMode;
1634 for (
index_type jCnt = 1; jCnt <= 3; jCnt++) {
1635 const index_type iMjC = (jMode - 1) * 3 + jCnt;
1638 Inv10jaPj(i, jCnt) += (*pInv10)(i, iMjC) * aP_jMode;
1645 #ifdef MODAL_USE_GRAVITY
1654 Vec3 x(this->
x), vP, wP, w, RTw;
1670 XCurr.dGetCoef(iRigidIndex + 6 + i, v(i), dCoef, &dofMap);
1671 XCurr.dGetCoef(iRigidIndex + 9 + i, w(i), dCoef, &dofMap);
1695 const Vec3 S =
R * STmp;
1703 #ifdef MODAL_USE_GRAVITY
1705 FTmp += GravityAcceleration *
dMass;
1724 MTmp -=
R *
Vec3(Tmp * RTw * 2.);
1735 #ifdef MODAL_USE_GRAVITY
1737 MTmp +=
Cross(S, GravityAcceleration);
1740 const Vec3 f1 = v - xP;
1743 WorkVec.AddItem(iRigidIndex + 1, f1);
1744 WorkVec.AddItem(iRigidIndex + 4, f2);
1749 T d = -MaPP(jMode) - CaP(jMode) - Ka(jMode);
1754 d -=
Dot(RInv3j, vP);
1756 #ifdef MODAL_USE_GRAVITY
1758 d +=
Dot(RInv3j, GravityAcceleration);
1766 Inv4j +=
Inv5jaj.GetCol(jMode);
1770 d -=
Dot(
R * Inv4j, wP);
1779 MatTmp(j, i) += (*pInv8)(i, jOffset + j - 1);
1784 const T& a_kMode =
a(kModem1 + 1);
1785 const index_type kOffset = (jMode - 1) * 3 * NModes + kModem1 * 3 + 1;
1789 MatTmp(i, j) -= (*pInv9)(i, kOffset + j - 1) * a_kMode;
1799 MatTmp(i, j) += (*pInv10)(i, jOffset + j - 1);
1804 d +=
Dot(w,
R *
Vec3(MatTmp * RTw));
1807 WorkVec.AddItem(iModalIndex + NModes + jMode, d);
1811 WorkVec.AddItem(iModalIndex + iCnt,
b(iCnt) -
aPrime(iCnt));
1816 const integer iNodeFirstMomIndex =
SND[iStrNodem1].pNode->iGetFirstMomentumIndex();
1823 PHIta(i) += (*pPHIt)(i, iOffset) *
a(jMode);
1824 PHIra(i) += (*pPHIr)(i, iOffset) *
a(jMode);
1828 const Vec3 d1tot =
R *
Vec3(PHIta +
SND[iStrNodem1].OffsetFEM);
1834 XCurr.dGetCoef(iModalIndex + 2 * NModes + 6 * iStrNodem1 + i, F(i), 1., &dofMap);
1839 SND[iStrNodem1].pNode->GetXCurr(x2, dCoef, func, &dofMap);
1843 SND[iStrNodem1].pNode->GetRCurr(R2, dCoef, func, &dofMap);
1845 Vec3 dTmp2(R2 *
SND[iStrNodem1].OffsetMB);
1849 MTmp -=
Cross(d1tot, F);
1857 WorkVec.AddItem(iModalIndex + NModes + jMode, d);
1864 XCurr.dGetCoef(iModalIndex + 2 * NModes + 6 * iStrNodem1 + 3 + i, M(i), 1., &dofMap);
1869 const Vec3 R2_M = R2 * M;
1882 WorkVec.AddItem(iModalIndex + NModes + jMode, d);
1887 const Vec3 f1 = (x2 + dTmp2 -
x - d1tot) / dCoef;
1888 const Vec3 f2 = ThetaCurr / -dCoef;
1890 WorkVec.AddItem(iModalIndex + 2 * NModes + 6 * iStrNodem1 + 1, f1);
1891 WorkVec.AddItem(iModalIndex + 2 * NModes + 6 * iStrNodem1 + 4, f2);
1893 WorkVec.AddItem(iNodeFirstMomIndex + 1, F);
1894 WorkVec.AddItem(iNodeFirstMomIndex + 4, MTmp2);
1896 UpdateStrNodeData(
SND[iStrNodem1], d1tot, R1tot, F, M, R2);
1900 WorkVec.AddItem(iRigidIndex + 7, FTmp);
1901 WorkVec.AddItem(iRigidIndex + 10, MTmp);
1905 UpdateModalNode(
x,
R);
1918 std::ostream& out = OH.
Modal();
1920 for (
unsigned int iCnt = 1; iCnt <=
NModes; iCnt++) {
1928 std::vector<StrNodeData>::const_iterator i =
SND.begin();
1929 std::vector<StrNodeData>::const_iterator end =
SND.end();
1930 for (; i != end; ++i) {
1932 out << std::setw(8) <<
GetLabel() <<
"@" << i->pNode->GetLabel()
1933 <<
" ", i->F.Write(out,
" ")
1934 <<
" ", i->M.Write(out,
" ")
1958 DEBUGCOUT(
"Entering Modal::InitialAssJac()" << std::endl);
1969 for (
unsigned int iCnt = 1; iCnt <=
iRigidOffset; iCnt++) {
1982 for (
unsigned iStrNodem1 = 0; iStrNodem1 <
NStrNodes; iStrNodem1++) {
1984 SND[iStrNodem1].pNode->iGetFirstPositionIndex();
1985 integer iNodeFirstVelIndex = iNodeFirstPosIndex + 6;
1988 for (
unsigned int iCnt = 1; iCnt <= 6; iCnt++) {
1990 iNodeFirstPosIndex + iCnt);
1992 iNodeFirstPosIndex + iCnt);
1994 iNodeFirstVelIndex + iCnt);
1996 iNodeFirstVelIndex + iCnt);
2006 WM.
PutCoef(iCnt, iCnt, 1.e-12);
2010 for (
unsigned int iCnt = 1; iCnt <=
NModes; iCnt++) {
2011 for (
unsigned int jCnt = 1; jCnt <=
NModes; jCnt++) {
2022 for (
unsigned int iStrNode = 1; iStrNode <=
NStrNodes; iStrNode++) {
2023 unsigned int iStrNodem1 = iStrNode - 1;
2026 const Mat3x3& R2(
SND[iStrNodem1].pNode->GetRRef());
2031 const Vec3& Omega2(
SND[iStrNodem1].pNode->GetWRef());
2032 Vec3 F(XCurr, iFlexIndex + 2*NModes + 12*iStrNodem1 + 1);
2033 Vec3 FPrime(XCurr, iFlexIndex + 2*NModes + 12*iStrNodem1 + 6 + 1);
2035 Mat3xN PHIt(NModes, 0), PHIr(NModes, 0);
2036 MatNx3 PHItT(NModes, 0), PHIrT(NModes, 0);
2038 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
2039 PHIt.PutVec(jMode,
pPHIt->
GetVec((jMode - 1)*NStrNodes + iStrNode));
2043 PHItT.Transpose(PHIt);
2046 Vec3 d1tot =
R*(
SND[iStrNodem1].OffsetFEM + PHIt*
a);
2048 Mat3xN SubMat1(NModes, 0.);
2049 MatNx3 SubMat2(NModes, 0.);
2054 for (
unsigned int iCnt = 1; iCnt <= 3; iCnt++) {
2057 WM.
IncCoef(iCnt, iOffset1 + iCnt, 1.);
2061 WM.
IncCoef(6 + iCnt, iOffset1 + 6 + iCnt, 1.);
2064 WM.
DecCoef(iOffset1 + iCnt, iCnt, 1.);
2067 WM.
DecCoef(iOffset1 + 6 + iCnt, 6 + iCnt, 1.);
2071 for (
unsigned int iCnt = 1; iCnt <= 3; iCnt++) {
2073 WM.
IncCoef(iOffset1 + iCnt, iOffset2 + iCnt, 1.);
2076 WM.
IncCoef(iOffset1 + 6 + iCnt, iOffset2 + 6 + iCnt, 1.);
2080 WM.
DecCoef(iOffset2 + iCnt, iOffset1 + iCnt, 1.);
2084 WM.
DecCoef(iOffset2 + 6 + iCnt, iOffset1 + 6 + iCnt, 1.);
2088 const Vec3& d1Tmp(d1tot);
2089 Vec3 d2Tmp(R2*
SND[iStrNodem1].OffsetMB);
2097 Mat3x3 O1Wedged1Wedge(
MatCross, Omega1.Cross(d1Tmp));
2102 R1PHIt.LeftMult(
R, PHIt);
2103 Vec3 d1Prime(Omega1.Cross(d1Tmp) + R1PHIt*
b);
2108 WM.
Add(3 + 1, 3 + 1, FWedged1Wedge);
2109 WM.
Add(3 + 1, iOffset1 + 1, Mat3x3(
MatCross, d1Tmp));
2121 WM.
Sub(iOffset2 + 3 + 1,iOffset2 + 3 + 1, FWedged2Wedge);
2122 WM.
Sub(iOffset2 + 3 + 1,iOffset1 + 1, Mat3x3(
MatCross, d2Tmp));
2130 WM.
Add(9 + 1, 3 + 1,
2133 WM.
Add(9 + 1, 9 + 1, FWedged1Wedge);
2134 WM.
Add(9 + 1, iOffset1 + 1, O1Wedged1Wedge + Mat3x3(
MatCross,
R*(PHIt*b)));
2135 WM.
Add(9 + 1, iOffset1 + 6 + 1, Mat3x3(
MatCross, d1Tmp));
2154 WM.
Sub(iOffset2 + 9 + 1, iOffset2 + 3 + 1,
2157 WM.
Sub(iOffset2 + 9 + 1, iOffset2 + 9 + 1, FWedged2Wedge);
2158 WM.
Add(iOffset2 + 9 + 1, iOffset1 + 1, O2Wedged2Wedge);
2159 WM.
Sub(iOffset2 + 9 + 1, iOffset1 + 6 + 1, Mat3x3(
MatCross, d2Tmp));
2163 WM.
Add(iOffset1 + 1, 3 + 1, Mat3x3(
MatCross, d1Tmp));
2165 WM.
Sub(iOffset1 + 1, iOffset2 + 3 + 1, Mat3x3(
MatCross, d2Tmp));
2173 WM.
Add(iOffset1 + 6 + 1, 3 + 1, O1Wedged1Wedge + Mat3x3(
MatCross,
R*(PHIt*
b)));
2174 WM.
Add(iOffset1 + 6 + 1, 9 + 1, Mat3x3(
MatCross, d1Tmp));
2176 WM.
Add(iOffset1 + 6 + 1, iOffset2 + 3 + 1, O2Wedged2Wedge);
2177 WM.
Sub(iOffset1 + 6 + 1, iOffset2 + 9 + 1, Mat3x3(
MatCross, d2Tmp));
2180 SubMat1.
LeftMult(Omega1.Cross(
R), PHIt);
2186 Vec3 M(XCurr, iFlexIndex + 2*NModes + 12*iStrNodem1 + 3 + 1);
2187 Vec3 MPrime(XCurr, iFlexIndex + 2*NModes + 12*iStrNodem1 + 9 + 1);
2188 Vec3 e1tota(R1tot.GetVec(1));
2189 Vec3 e2tota(R1tot.GetVec(2));
2190 Vec3 e3tota(R1tot.GetVec(3));
2202 WM.
Add(3 + 1, 3 + 1, MWedge);
2203 WM.
SubT(3 + 1, iOffset2 + 3 + 1, MWedge);
2205 WM.
AddT(iOffset2 + 3 + 1, 3 + 1, MWedge);
2207 WM.
Sub(iOffset2 + 3 + 1, iOffset2 + 3 + 1, MWedge);
2225 SubMat2.
RightMult(PHIrT, R1tot.MulTM(MWedge));
2228 SubMat2.
RightMult(PHIrT, R1tot.MulTMT(MWedge));
2231 Vec3 MA(Mat3x3(e2tota.Cross(e3b), e3tota.Cross(e1b),
2232 e1tota.Cross(e2b))*M);
2239 SubMat1.
LeftMult(R1TMAWedge, PHIr);
2242 SubMat3.
LeftMult(R1tot.MulTM(M1Wedge), PHIr);
2244 SubMat4.
Mult(PHIrT, SubMat1);
2245 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
2246 for (
unsigned int kMode = 1; kMode <=
NModes; kMode++) {
2248 SubMat4(jMode, kMode));
2254 WM.
Add(9 + 1, 9 + 1, MWedge);
2255 WM.
SubT(9 + 1, iOffset2 + 9 + 1, MWedge);
2257 WM.
AddT(iOffset2 + 9 + 1, 9 + 1, MWedge);
2259 WM.
Sub(iOffset2 + 9 + 1, iOffset2 + 9 + 1, MWedge);
2269 WM.
Add(9 + 1, 3 + 1, MWedge);
2270 WM.
Sub(iOffset2 + 9 + 1, 3 + 1, MWedge);
2281 WM.
Sub(9 + 1, iOffset2 + 3 + 1, MWedge);
2283 WM.
Add(iOffset2 + 9 + 1, iOffset2 + 3 + 1, MWedge);
2292 Vec3 v1(e2tota.Cross(e3b));
2293 Vec3 v2(e3tota.Cross(e1b));
2294 Vec3 v3(e1tota.Cross(e2b));
2298 if (v1.Dot() < std::numeric_limits<doublereal>::epsilon()
2299 || v2.Dot() < std::numeric_limits<doublereal>::epsilon()
2300 || v3.Dot() < std::numeric_limits<doublereal>::epsilon())
2302 silent_cerr(
"Modal(" <<
GetLabel() <<
"):"
2303 <<
"warning, first node hinge axis "
2304 "and second node hinge axis "
2305 "are (nearly) orthogonal; aborting..."
2310 MWedge = Mat3x3(v1, v2, v3);
2314 WM.
Add(3 + 1, iOffset1 + 3 + 1, MWedge);
2316 WM.
Sub(iOffset2 + 3 + 1, iOffset1 + 3 + 1, MWedge);
2318 SubMat2.
RightMult(PHIrT, R1tot.MulTM(MWedge));
2323 WM.
Add(9 + 1, iOffset1 + 9 + 1, MWedge);
2325 WM.
Sub(iOffset2 + 9 + 1, iOffset1 + 9 + 1, MWedge);
2331 WM.
AddT(iOffset1 + 3 + 1, 3 + 1, MWedge);
2333 WM.
SubT(iOffset1 + 3 + 1, iOffset2 + 3 + 1, MWedge);
2337 Vec3 u1(e2ra.Cross(e3b));
2338 Vec3 u2(e3ra.Cross(e1b));
2339 Vec3 u3(e1ra.Cross(e2b));
2341 M1Wedge = (Mat3x3(u1, u2, u3)).
Transpose();
2347 WM.
AddT(iOffset1 + 9 + 1, 9 + 1, MWedge);
2349 WM.
SubT(iOffset1 + 9 + 1, iOffset2 + 9 + 1, MWedge);
2351 v1 = e3b.Cross(e2tota.Cross(Omega1))
2352 + e2tota.Cross(Omega2.Cross(e3b));
2353 v2 = e1b.Cross(e3tota.Cross(Omega1))
2354 + e3tota.Cross(Omega2.Cross(e1b));
2355 v3 = e2b.Cross(e1tota.Cross(Omega1))
2356 + e1tota.Cross(Omega2.Cross(e2b));
2358 MWedge = Mat3x3(v1, v2, v3);
2362 WM.
Add(9 + 1, iOffset1 + 3 + 1, MWedge);
2364 WM.
Sub(iOffset2 + 9 + 1, iOffset1 + 3 + 1, MWedge);
2367 Omega1 = Omega1 - Omega2;
2369 v1 = e2tota.Cross(e3b.Cross(Omega1));
2370 Vec3 v1p(e3b.Cross(Omega1.Cross(e2tota)));
2371 v2 = e3tota.Cross(e1b.Cross(Omega1));
2372 Vec3 v2p(e1b.Cross(Omega1.Cross(e3tota)));
2373 v3 = e1tota.Cross(e2b.Cross(Omega1));
2374 Vec3 v3p(e2b.Cross(Omega1.Cross(e1tota)));
2377 for (
unsigned int iCnt = 1; iCnt <= 3; iCnt++) {
2381 WM.
IncCoef(iOffset1 + 9 + 1, 3 + iCnt, d);
2384 WM.
IncCoef(iOffset1 + 9 + 2, 3 + iCnt, d);
2387 WM.
IncCoef(iOffset1 + 9 + 3, 3 + iCnt, d);
2391 for (
unsigned int iCnt = 1; iCnt <= 3; iCnt++) {
2395 WM.
IncCoef(iOffset1 + 9 + 1, iOffset2 + 3 + iCnt, d);
2398 WM.
IncCoef(iOffset1 + 9 + 2, iOffset2 + 3 + iCnt, d);
2401 WM.
IncCoef(iOffset1 + 9 + 3, iOffset2 + 3 + iCnt, d);
2414 DEBUGCOUT(
"Entering Modal::InitialAssRes()" << std::endl);
2426 for (
unsigned int iCnt = 1; iCnt <=
iRigidOffset; iCnt++) {
2437 for (
unsigned iStrNodem1 = 0; iStrNodem1 <
NStrNodes; iStrNodem1++) {
2439 SND[iStrNodem1].pNode->iGetFirstPositionIndex();
2440 integer iNodeFirstVelIndex = iNodeFirstPosIndex + 6;
2443 for (
unsigned int iCnt = 1; iCnt <= 6; iCnt++) {
2445 iNodeFirstPosIndex + iCnt);
2447 iNodeFirstVelIndex + iCnt);
2452 for (
unsigned int iCnt = 1; iCnt <=
NModes; iCnt++) {
2453 a.
Put(iCnt, XCurr(iFlexIndex + iCnt));
2454 b.
Put(iCnt, XCurr(iFlexIndex + NModes + iCnt));
2458 for (
unsigned int iCnt = 1; iCnt <=
NModes; iCnt++) {
2461 for (
unsigned int jCnt = 1; jCnt <=
NModes; jCnt++) {
2485 for (
unsigned int iStrNode = 1; iStrNode <=
NStrNodes; iStrNode++) {
2486 unsigned int iStrNodem1 = iStrNode - 1;
2487 Mat3xN PHIt(NModes,0), PHIr(NModes,0);
2492 for (
unsigned int iCnt = 1; iCnt <= 3; iCnt++) {
2493 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
2494 PHIt.Put(iCnt, jMode,
pPHIt->
dGet(iCnt, (jMode - 1)*NStrNodes + iStrNode));
2495 PHIr.
Put(iCnt, jMode,
pPHIr->
dGet(iCnt, (jMode - 1)*NStrNodes + iStrNode));
2499 MatNx3 PHItT(NModes), PHIrT(NModes);
2500 PHItT.Transpose(PHIt);
2503 Vec3 d1tot =
R*(
SND[iStrNodem1].OffsetFEM + PHIt*
a);
2506 const Vec3& x2(
SND[iStrNodem1].pNode->GetXCurr());
2507 const Vec3& v2(
SND[iStrNodem1].pNode->GetVCurr());
2508 const Mat3x3& R2(
SND[iStrNodem1].pNode->GetRCurr());
2509 const Vec3& Omega2(
SND[iStrNodem1].pNode->GetWCurr());
2510 Vec3 F(XCurr, iFlexIndex + 2*NModes + 12*iStrNodem1 + 1);
2511 Vec3 FPrime(XCurr, iFlexIndex + 2*NModes + 12*iStrNodem1 + 6 + 1);
2516 const Vec3& d1Tmp(d1tot);
2517 Vec3 d2Tmp(R2*
SND[iStrNodem1].OffsetMB);
2521 Vec3 O2Wedged2(Omega2.Cross(d2Tmp));
2525 R1PHIt.LeftMult(
R, PHIt);
2526 Vec3 d1Prime(O1Wedged1 + R1PHIt*
b);
2531 WorkVec.
Add(3 + 1, F.Cross(d1Tmp));
2535 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
2537 for (
unsigned int iCnt = 1; iCnt <= 3; iCnt++) {
2538 temp += PHIt(iCnt, jMode)*(
RT*F).dGet(iCnt);
2545 WorkVec.
Sub(6 + 1, FPrime);
2552 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
2555 for (
unsigned int iCnt = 1; iCnt <= 3; iCnt++) {
2556 temp += PHItTR1T(jMode, iCnt)*(Omega1.
Cross(F) - FPrime).dGet(iCnt);
2562 WorkVec.
Add(iOffset2 + 1, F);
2563 WorkVec.
Add(iOffset2 + 3 + 1, d2Tmp.
Cross(F));
2566 WorkVec.
Add(iOffset2 + 6 + 1, FPrime);
2567 WorkVec.
Add(iOffset2 + 9 + 1, d2Tmp.
Cross(FPrime) + O2Wedged2.
Cross(F));
2570 WorkVec.
Add(iOffset1 + 1,
x + d1Tmp - x2 - d2Tmp);
2573 WorkVec.
Add(iOffset1 + 6 + 1, v1 + d1Prime - v2 - O2Wedged2);
2576 Vec3 M(XCurr, iFlexIndex + 2*NModes + 12*iStrNodem1 + 3 + 1);
2577 Vec3 MPrime(XCurr, iFlexIndex + 2*NModes + 12*iStrNodem1 + 9 + 1);
2579 Vec3 e1a(R1tot.GetVec(1));
2580 Vec3 e2a(R1tot.GetVec(2));
2581 Vec3 e3a(R1tot.GetVec(3));
2586 Vec3 MTmp(e2a.Cross(e3b*M(1))
2587 + e3a.Cross(e1b*M(2))
2588 + e1a.Cross(e2b*M(3)));
2592 WorkVec.
Sub(3 + 1, MTmp);
2596 WorkVec.
Add(iOffset2 + 3 + 1, MTmp);
2599 Vec3 MTmpRel(R1tot.MulTV(MTmp));
2600 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
2605 Mat3x3 Tmp =
R*Mat3x3(
MatCross, PHIr*b);
2612 (e2a.Cross(Omega2.Cross(e3b)) - e3b.Cross(e2aPrime))*M(1)
2613 + (e3a.Cross(Omega2.Cross(e1b)) - e1b.Cross(e3aPrime))*M(2)
2614 + (e1a.Cross(Omega2.Cross(e2b)) - e2b.Cross(e1aPrime))*M(3)
2615 + e2a.
Cross(e3b*MPrime(1))
2616 + e3a.
Cross(e1b*MPrime(2))
2617 + e1a.
Cross(e2b*MPrime(3));
2621 WorkVec.
Sub(9 + 1, MTmpPrime);
2625 WorkVec.
Add(iOffset2 + 9 + 1, MTmpPrime);
2632 Vec3 T1 = MTmpPrime - Omega1.
Cross(MTmp);
2635 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
2638 for (
unsigned int iCnt = 1; iCnt <= 3; iCnt++) {
2639 temp += SubMat1(jMode, iCnt)*T1(iCnt)
2640 - PHIrT(jMode, iCnt)*T2(iCnt);
2646 WorkVec.
DecCoef(iOffset1 + 3 + 1, e3b.Dot(e2a));
2647 WorkVec.
DecCoef(iOffset1 + 3 + 2, e1b.Dot(e3a));
2648 WorkVec.
DecCoef(iOffset1 + 3 + 3, e2b.Dot(e1a));
2651 WorkVec.
IncCoef(iOffset1 + 9 + 1,
2652 e3b.Dot(Omega2.Cross(e2a) - e2aPrime));
2653 WorkVec.
IncCoef(iOffset1 + 9 + 2,
2654 e1b.Dot(Omega2.Cross(e3a) - e3aPrime));
2655 WorkVec.
IncCoef(iOffset1 + 9 + 3,
2656 e2b.Dot(Omega2.Cross(e1a) - e1aPrime));
2670 for (
unsigned int iCnt = 1; iCnt <=
NModes; iCnt++) {
2672 X.
PutCoef(iFlexIndex + iCnt,
a(iCnt));
2675 X.
PutCoef(iFlexIndex + NModes + iCnt,
b(iCnt));
2697 for (
unsigned int iCnt = 1; iCnt <=
NModes; iCnt++) {
2699 X.
PutCoef(iFlexIndex + iCnt,
a(iCnt));
2702 X.
PutCoef(iFlexIndex + NModes + iCnt,
b(iCnt));
2703 XP.
PutCoef(iFlexIndex + iCnt,
b(iCnt));
2725 for (
unsigned int iCnt = 1; iCnt <=
NModes; iCnt++) {
2783 while ((++s)[0] ==
'P') {
2797 const char *end = std::strchr(s,
']');
2798 if (end == 0 || end[1] !=
'\0') {
2811 char buf[
sizeof(
"18446744073709551615") + 1];
2812 size_t len = end - s;
2816 strncpy(
buf, s, len);
2820 if (
buf[0] ==
'-') {
2826 unsigned long n = strtoul(
buf, &next, 10);
2827 int save_errno = errno;
2832 }
else if (end[0] !=
'\0') {
2835 }
else if (save_errno == ERANGE) {
2836 silent_cerr(
"Modal(" <<
GetLabel() <<
"): "
2837 "warning, private data mode index "
2838 << std::string(
buf, end -
buf)
2839 <<
" overflows" << std::endl);
2849 std::vector<unsigned int>::const_iterator iv
2858 return p*NModes + n;
2861 end = std::strchr(s,
',');
2866 std::string FEMLabel(s, end - s);
2869 if (end[0] ==
'-') {
2875 unsigned int index = strtoul(end, &next, 10);
2876 int save_errno = errno;
2877 if (next == end || next[0] !=
']') {
2880 }
else if (save_errno == ERANGE) {
2881 silent_cerr(
"Modal(" <<
GetLabel() <<
"): "
2882 "warning, private data FEM node component "
2883 << std::string(end, next - end)
2884 <<
" overflows" << std::endl);
2888 if (index == 0 || index > 3) {
2892 std::vector<std::string>::const_iterator ii = find(
IdFEMNodes.begin(),
IdFEMNodes.end(), FEMLabel);
2898 return 3*NModes + 18*i + (what ==
'w' ? 3 : 0) + 6*p + index;
2922 unsigned int n = (i - 1) / 18;
2923 unsigned int index = (i - 1) % 18 + 1;
2924 unsigned int p = (index - 1) / 6;
2925 unsigned int c = (index - 1) % 6 + 1;
2926 unsigned int w = (c - 1) / 3;
2944 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
2960 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
2977 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
2999 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
3020 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
3030 XPP += W0.
Cross(
R*(XPn*2.));
3057 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
3058 for (
unsigned int iNode = 1; iNode <=
NFEMNodes; iNode++) {
3059 for (
unsigned int iCnt = 1; iCnt <= 3; iCnt++) {
3067 for (
unsigned int iNode = 1; iNode <=
NFEMNodes; iNode++) {
3068 for (
unsigned int iCnt = 1; iCnt <= 3; iCnt++) {
3095 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
3096 for (
unsigned int iNode = 1; iNode <=
NFEMNodes; iNode++) {
3097 for (
unsigned int iCnt = 1; iCnt <= 3; iCnt++) {
3100 CurrXYZTmp.
Add(iCnt, iNode,d *
b(jMode) );
3106 for (
unsigned int iNode = 1; iNode <=
NFEMNodes; iNode++) {
3107 for (
unsigned int iCnt = 1; iCnt <= 3; iCnt++) {
3108 pCurrXYZVel->
Add(iCnt, iNode, CurrXYZTmp(iCnt, iNode) + v(iCnt));
3216 unsigned int uNode = HP.
GetInt();
3218 DEBUGCOUT(
"Linked to Modal Node: " << uNode << std::endl);
3223 if (pTmpNode == 0) {
3224 silent_cerr(
"Modal(" << uLabel <<
"): "
3225 "StructuralNode(" << uNode <<
") "
3227 <<
" not defined" << std::endl);
3232 silent_cerr(
"Modal(" << uLabel <<
"): "
3234 "StructuralNode(" << uNode <<
") "
3239 pModalNode =
dynamic_cast<const ModalNode *
>(pTmpNode);
3242 if (pModalNode->
pGetRBK() != 0) {
3243 silent_cerr(
"Modal(" << uLabel
3244 <<
"): StructuralNode(" << uNode
3245 <<
") uses rigid body kinematics at line "
3259 int tmpNModes = HP.
GetInt();
3260 if (tmpNModes <= 0) {
3261 silent_cerr(
"Modal(" << uLabel <<
"): "
3262 "illegal number of modes " << tmpNModes <<
" at line "
3266 unsigned int NModes = (
unsigned int)tmpNModes;
3267 unsigned int uLargestMode(0);
3271 for (
unsigned int iCnt = 0; iCnt <
NModes; iCnt++) {
3275 silent_cerr(
"Modal(" << uLabel <<
"): "
3276 "illegal mode number "
3277 "for mode #" << iCnt + 1
3283 std::vector<unsigned int>::const_iterator
3284 iv = std::find(uModeNumber.begin(),
3285 uModeNumber.end(), (
unsigned int)n);
3286 if (iv != uModeNumber.end()) {
3287 silent_cerr(
"Modal(" << uLabel <<
"): "
3288 "mode #" << iCnt + 1
3289 <<
" already defined "
3295 if ((
unsigned int)n > uLargestMode) {
3296 uLargestMode = (
unsigned int)n;
3299 uModeNumber[iCnt] = n;
3303 for (
unsigned int iCnt = 1; iCnt <=
NModes; iCnt++) {
3304 uModeNumber[iCnt - 1] = iCnt;
3309 std::vector<doublereal> InitialValues(NModes, 0.);
3310 std::vector<doublereal> InitialValuesP(NModes, 0.);
3311 bool bInitialValues(
false);
3313 bInitialValues =
true;
3321 silent_cerr(
"Modal(" << uLabel <<
"): "
3322 "illegal mode number "
3323 "for initial value #" << iCnt + 1
3329 std::vector<unsigned int>::const_iterator
3330 iv = std::find(uModeNumber.begin(),
3331 uModeNumber.end(), (
unsigned int)n);
3332 if (iv == uModeNumber.end()) {
3333 silent_cerr(
"Modal(" << uLabel <<
"): "
3334 "mode " << n <<
" not defined "
3340 unsigned iIdx = iv - uModeNumber.begin();
3341 InitialValues[iIdx] = HP.
GetReal();
3342 InitialValuesP[iIdx] = HP.
GetReal();
3348 for (
unsigned int iCnt = 0; iCnt <
NModes; iCnt++) {
3349 InitialValues[0] = HP.
GetReal();
3350 InitialValuesP[0] = HP.
GetReal();
3358 int tmpNFEMNodes = HP.
GetInt();
3359 if (tmpNFEMNodes <= 0) {
3360 silent_cerr(
"Modal(" << uLabel <<
"): "
3361 "illegal number of FEM nodes " << tmpNFEMNodes
3365 NFEMNodes = unsigned(tmpNFEMNodes);
3368 #ifdef MODAL_SCALE_DATA
3385 scaleinertia = scalemasses*(scalemodes*scalemodes);
3390 DAMPING_FROM_FILE = 0,
3394 DAMPING_SINGLE_FACTOR,
3396 } eDamp(DAMPING_FROM_FILE);
3397 const char *sDamp[] = {
3398 "damping from file",
3402 "single factor damping",
3407 doublereal damp_factor(0.), damp_coef_M(0.), damp_coef_K(0.);
3408 std::vector<doublereal> DampRatios;
3413 }
else if (HP.
IsKeyWord(
"rayleigh" "damping")) {
3414 eDamp = DAMPING_RAYLEIGH;
3416 if (damp_coef_M < 0.) {
3417 silent_cerr(
"Modal(" << uLabel <<
"): "
3418 "warning, negative mass damping coefficient for \"Rayleigh damping\" "
3422 if (damp_coef_K < 0.) {
3423 silent_cerr(
"Modal(" << uLabel <<
"): "
3424 "warning, negative stiffness damping coefficient for \"Rayleigh damping\" "
3428 }
else if (HP.
IsKeyWord(
"single" "factor" "damping")) {
3429 eDamp = DAMPING_SINGLE_FACTOR;
3431 if (damp_factor < 0.) {
3432 silent_cerr(
"Modal(" << uLabel <<
"): "
3433 "warning, negative damping factor for \"single factor damping\" "
3437 }
else if (HP.
IsKeyWord(
"proportional" "damping")) {
3438 silent_cerr(
"Modal(" << uLabel <<
"): "
3439 "warning, \"proportional damping\" is deprecated; "
3440 "use \"single factor damping\" with the desired damping factor instead "
3443 eDamp = DAMPING_SINGLE_FACTOR;
3445 if (damp_factor < 0.) {
3446 silent_cerr(
"Modal(" << uLabel <<
"): "
3447 "warning, negative damping factor for \"proportional damping\" "
3451 }
else if (HP.
IsKeyWord(
"diag" "damping")) {
3452 eDamp = DAMPING_DIAG;
3453 DampRatios.resize(NModes);
3454 fill(DampRatios.begin(), DampRatios.end(), 0.);
3457 for (
unsigned int iCnt = 0; iCnt <
NModes; iCnt ++) {
3459 if (damp_factor < 0.) {
3460 silent_cerr(
"Modal(" << uLabel <<
"): "
3461 "warning, negative damping factor for \"diag damping\" "
3462 "of mode " << (iCnt + 1 ) <<
" "
3465 DampRatios[iCnt] = damp_factor;
3470 if (iDM <= 0 ||
unsigned(iDM) > NModes) {
3471 silent_cerr(
"invalid number of damped modes "
3476 std::vector<bool> gotit(NModes,
false);
3478 for (
unsigned int iCnt = 1; iCnt <= unsigned(iDM); iCnt ++) {
3480 if (iDampedMode <= 0 ||
unsigned(iDampedMode) > NModes) {
3481 silent_cerr(
"invalid index " << iDampedMode
3482 <<
" for damped mode #" << iCnt
3488 if (gotit[iDampedMode - 1]) {
3489 silent_cerr(
"damping already provided for mode " << iDampedMode
3490 <<
" (damped mode #" << iCnt
3496 gotit[iDampedMode - 1] =
true;
3498 if (damp_factor < 0.) {
3499 silent_cerr(
"Modal(" << uLabel <<
"): "
3500 "warning, negative damping factor for \"diag damping\" "
3501 "of mode " << iDampedMode <<
" "
3504 DampRatios[iDampedMode - 1] = damp_factor;
3507 }
else if (HP.
IsKeyWord(
"damping" "from" "file")) {
3508 eDamp = DAMPING_FROM_FILE;
3510 silent_cout(
"Modal(" << uLabel <<
"): "
3511 "no damping is assumed at line "
3516 DEBUGCOUT(
"Number of Modes Imported : " << NModes << std::endl);
3517 DEBUGCOUT(
"Number of FEM Nodes Imported : " << NFEMNodes << std::endl);
3518 DEBUGCOUT(
"Origin of FEM Model : " << X0 << std::endl);
3519 DEBUGCOUT(
"Orientation of FEM Model : " << R << std::endl);
3527 std::vector<doublereal> FEMMass;
3528 std::vector<Vec3> FEMJ;
3532 Mat3xN PHIti(NModes, 0.);
3533 Mat3xN PHIri(NModes, 0.);
3555 silent_cerr(
"Modal(" << uLabel <<
"): unable to get "
3556 "modal data file name at line " << HP.
GetLineData()
3561 std::string sFileFEM(s);
3568 dStiffnessThreshold = HP.
GetReal();
3569 if (dStiffnessThreshold < 0.) {
3570 silent_cerr(
"Modal(" << uLabel <<
"): "
3571 "invalid threshold " << dStiffnessThreshold
3576 dMassThreshold = dDampingThreshold = dStiffnessThreshold;
3578 }
else if (HP.
IsKeyWord(
"mass" "threshold")) {
3579 dMassThreshold = HP.
GetReal();
3580 if (dMassThreshold < 0.) {
3581 silent_cerr(
"Modal(" << uLabel <<
"): "
3582 "invalid mass threshold " << dMassThreshold
3588 }
else if (HP.
IsKeyWord(
"damping" "threshold")) {
3589 dDampingThreshold = HP.
GetReal();
3590 if (dDampingThreshold < 0.) {
3591 silent_cerr(
"Modal(" << uLabel <<
"): "
3592 "invalid damping threshold " << dDampingThreshold
3598 }
else if (HP.
IsKeyWord(
"stiffness" "threshold")) {
3599 dStiffnessThreshold = HP.
GetReal();
3600 if (dStiffnessThreshold < 0.) {
3601 silent_cerr(
"Modal(" << uLabel <<
"): "
3602 "invalid stiffness threshold " << dStiffnessThreshold
3614 bool bCreateBinary =
false;
3615 bool bUseBinary =
false;
3616 bool bUpdateBinary =
false;
3619 bCreateBinary =
true;
3621 }
else if (HP.
IsKeyWord(
"use" "binary")) {
3624 }
else if (HP.
IsKeyWord(
"update" "binary")) {
3625 bUpdateBinary =
true;
3632 std::string sEchoFileName;
3633 int iEchoPrecision(13);
3637 silent_cerr(
"Modal(" << uLabel <<
"): "
3638 "unable to parse echo file name at line " << HP.
GetLineData()
3645 iEchoPrecision = HP.
GetInt();
3646 if (iEchoPrecision <= 0) {
3647 silent_cerr(
"Modal(" << uLabel <<
"): "
3656 std::string sBinFileFEM;
3657 struct stat stFEM, stBIN;
3658 bool bReadFEM =
true,
3662 if (stat(sFileFEM.c_str(), &stFEM) == -1) {
3663 int save_errno = errno;
3664 char *errmsg = strerror(save_errno);
3666 silent_cerr(
"Modal(" << uLabel <<
"): "
3667 "unable to stat(\"" << sFileFEM <<
"\") "
3668 "(" << save_errno <<
": " << errmsg <<
")"
3673 if (bUseBinary || bCreateBinary || bUpdateBinary) {
3674 sBinFileFEM = sFileFEM +
".bin";
3676 if (stat(sBinFileFEM.c_str(), &stBIN) == -1) {
3677 int save_errno = errno;
3678 char *errmsg = strerror(save_errno);
3680 if (save_errno == ENOENT && (bCreateBinary || bUpdateBinary)) {
3681 silent_cerr(
"Modal(" << uLabel <<
"): "
3682 "creating binary file "
3683 "\"" << sBinFileFEM <<
"\" "
3685 "\"" << sFileFEM <<
"\""
3689 silent_cerr(
"Modal(" << uLabel <<
"): "
3690 "unable to stat(\"" << sBinFileFEM <<
"\") "
3691 "(" << save_errno <<
": " << errmsg <<
")"
3702 if (bUseBinary && bCheckBIN) {
3704 if (stBIN.st_mtime > stFEM.st_mtime) {
3709 if (bUpdateBinary) {
3712 silent_cout(
"Modal(" << uLabel <<
"): "
3713 "binary database file \"" << sBinFileFEM <<
"\" "
3714 "older than text database file \"" << sFileFEM <<
"\"; "
3719 silent_cerr(
"Modal(" << uLabel <<
"): "
3720 "warning, binary database file \"" << sBinFileFEM <<
"\" "
3721 "older than text database file \"" << sFileFEM <<
"\"; "
3722 "using text database file "
3723 "(enable \"update binary\" to refresh binary database file)"
3728 }
else if (bCreateBinary || bUpdateBinary) {
3746 std::vector<bool> bActiveModes;
3749 MODAL_VERSION_UNKNOWN = 0,
3751 MODAL_VERSION_1 = 1,
3752 MODAL_VERSION_2 = 2,
3753 MODAL_VERSION_3 = 3,
3754 MODAL_VERSION_4 = 4,
3760 const char magic[5] =
"bmod";
3761 const uint32_t BinVersion = MODAL_VERSION_4;
3763 uint32_t currBinVersion = MODAL_VERSION_UNKNOWN;
3765 uint32_t NFEMNodesFEM = 0, NModesFEM = 0;
3767 bool bBuildInvariants =
false;
3780 MODAL_RECORD_10 = 10,
3781 MODAL_RECORD_11 = 11,
3782 MODAL_RECORD_12 = 12,
3783 MODAL_RECORD_13 = 13,
3789 MODAL_END_OF_FILE = char(-1)
3793 bool bRecordGroup[MODAL_LAST_RECORD] = {
false };
3812 std::ifstream fdat(sFileFEM.c_str());
3814 silent_cerr(
"Modal(" << uLabel <<
"): "
3815 "unable to open file \"" << sFileFEM <<
"\""
3825 fbin.open(sBinFileFEM.c_str(), std::ios::binary | std::ios::trunc);
3827 silent_cerr(
"Modal(" << uLabel <<
"): "
3828 "unable to open file \"" << sBinFileFEM <<
"\""
3833 fbin.write(&magic[0],
sizeof(4));
3834 currBinVersion = BinVersion;
3835 fbin.write((
const char *)&currBinVersion,
sizeof(currBinVersion));
3843 unsigned int NRejModes = 0;
3846 while (fdat && !fdat.eof()) {
3847 fdat.getline(str,
sizeof(str));
3849 if (strncmp(
"** END OF FILE", str,
STRLENOF(
"** END OF FILE")) == 0) {
3854 if (strncmp(
"** RECORD GROUP ", str,
3855 STRLENOF(
"** RECORD GROUP ")) != 0) {
3860 long rg = std::strtol(&str[
STRLENOF(
"** RECORD GROUP ")], &next, 10);
3861 if (next == &str[
STRLENOF(
"** RECORD GROUP ")]) {
3862 silent_cerr(
"file=\"" << sFileFEM <<
"\": "
3863 "unable to parse \"RECORD GROUP\" number <" << &str[
STRLENOF(
"** RECORD GROUP ")] <<
">"
3868 if (!bRecordGroup[MODAL_RECORD_1] && rg != MODAL_RECORD_1) {
3869 silent_cerr(
"file=\"" << sFileFEM <<
"\": "
3870 "\"RECORD GROUP 1\" not parsed yet; cannot parse \"RECORD GROUP " << rg <<
"\""
3876 case MODAL_RECORD_1: {
3877 if (bRecordGroup[MODAL_RECORD_1]) {
3878 silent_cerr(
"file=\"" << sFileFEM <<
"\": "
3879 "\"RECORD GROUP 1\" already parsed"
3884 fdat.getline(str,
sizeof(str));
3890 fdat >> NFEMNodesFEM;
3903 NModesFEM -= NRejModes;
3906 if (NFEMNodes ==
unsigned(-1)) {
3907 NFEMNodes = NFEMNodesFEM;
3909 }
else if (NFEMNodes != NFEMNodesFEM) {
3910 silent_cerr(
"Modal(" << uLabel <<
"), "
3911 "file \"" << sFileFEM <<
"\": "
3912 "FEM nodes number " << NFEMNodes
3913 <<
" does not match node number "
3919 if (NModes > NModesFEM) {
3920 silent_cerr(
"Modal(" << uLabel <<
"), "
3921 "file '" << sFileFEM <<
"': "
3922 "number of requested modes "
3923 "(" << NModes <<
") "
3924 "exceeds number of available "
3925 "modes (" << NModesFEM <<
")"
3931 if (NModes < NModesFEM) {
3932 silent_cout(
"Modal(" << uLabel <<
"), "
3933 "file '" << sFileFEM <<
"': "
3935 <<
" of " << NModesFEM
3936 <<
" available modes"
3940 if (uLargestMode > NModesFEM) {
3941 silent_cerr(
"Modal(" << uLabel <<
"), "
3942 "file '" << sFileFEM <<
"': "
3943 "largest requested mode "
3944 "(" << uLargestMode <<
") "
3945 "exceeds available modes "
3946 "(" << NModesFEM <<
")"
3951 if (!bActiveModes.empty()) {
3955 IdFEMNodes.resize(NFEMNodes);
3961 bActiveModes.resize(NModesFEM + 1,
false);
3963 for (
unsigned int iCnt = 0; iCnt <
NModes; iCnt++) {
3964 if (uModeNumber[iCnt] > NModesFEM) {
3965 silent_cerr(
"Modal(" << uLabel <<
"): "
3966 "mode " << uModeNumber[iCnt]
3967 <<
" is not available (max = "
3972 bActiveModes[uModeNumber[iCnt]] =
true;
3976 checkPoint = MODAL_RECORD_1;
3977 fbin.write(&checkPoint,
sizeof(checkPoint));
3978 fbin.write((
const char *)&NFEMNodesFEM,
sizeof(NFEMNodesFEM));
3979 fbin.write((
const char *)&NModesFEM,
sizeof(NModesFEM));
3982 bRecordGroup[MODAL_RECORD_1] =
true;
3985 case MODAL_RECORD_2: {
3987 if (bRecordGroup[MODAL_RECORD_2]) {
3988 silent_cerr(
"file=\"" << sFileFEM <<
"\": "
3989 "\"RECORD GROUP 2\" already parsed"
3994 for (
unsigned int iNode = 0; iNode <
NFEMNodes; iNode++) {
3997 fdat >> IdFEMNodes[iNode];
4001 checkPoint = MODAL_RECORD_2;
4002 fbin.write(&checkPoint,
sizeof(checkPoint));
4003 for (
unsigned int iNode = 0; iNode <
NFEMNodes; iNode++) {
4004 uint32_t len = IdFEMNodes[iNode].size();
4005 fbin.write((
const char *)&len,
sizeof(len));
4006 fbin.write((
const char *)IdFEMNodes[iNode].c_str(), len);
4010 bRecordGroup[2] =
true;
4013 case MODAL_RECORD_3: {
4015 if (bRecordGroup[MODAL_RECORD_3]) {
4016 silent_cerr(
"file=\"" << sFileFEM <<
"\": "
4017 "\"RECORD GROUP 3\" already parsed"
4022 unsigned int iCnt = 1;
4024 if (bActiveModes.empty()) {
4025 silent_cerr(
"Modal(" << uLabel <<
"): "
4026 "input file \"" << sFileFEM <<
"\" "
4027 "is bogus (RECORD GROUP 3)"
4033 checkPoint = MODAL_RECORD_3;
4034 fbin.write(&checkPoint,
sizeof(checkPoint));
4037 for (
unsigned int jMode = 1; jMode <= NModesFEM; jMode++) {
4041 fbin.write((
const char *)&d,
sizeof(d));
4044 if (!bActiveModes[jMode]) {
4051 bRecordGroup[MODAL_RECORD_3] =
true;
4054 case MODAL_RECORD_4: {
4056 if (bRecordGroup[MODAL_RECORD_4]) {
4057 silent_cerr(
"file=\"" << sFileFEM <<
"\": "
4058 "\"RECORD GROUP 4\" already parsed"
4063 unsigned int iCnt = 1;
4065 if (bActiveModes.empty()) {
4066 silent_cerr(
"Modal(" << uLabel <<
"): "
4067 "input file \"" << sFileFEM <<
"\" "
4068 "is bogus (RECORD GROUP 4)"
4074 checkPoint = MODAL_RECORD_4;
4075 fbin.write(&checkPoint,
sizeof(checkPoint));
4078 for (
unsigned int jMode = 1; jMode <= NModesFEM; jMode++) {
4082 fbin.write((
const char *)&d,
sizeof(d));
4085 if (!bActiveModes[jMode]) {
4092 bRecordGroup[MODAL_RECORD_4] =
true;
4095 case MODAL_RECORD_5: {
4097 if (bRecordGroup[MODAL_RECORD_5]) {
4098 silent_cerr(
"file=\"" << sFileFEM <<
"\": "
4099 "\"RECORD GROUP 5\" already parsed"
4105 checkPoint = MODAL_RECORD_5;
4106 fbin.write(&checkPoint,
sizeof(checkPoint));
4109 for (
unsigned int iNode = 1; iNode <=
NFEMNodes; iNode++) {
4113 fbin.write((
const char *)&d,
sizeof(d));
4116 #ifdef MODAL_SCALE_DATA
4119 pXYZFEMNodes->
Put(1, iNode, d);
4122 bRecordGroup[MODAL_RECORD_5] =
true;
4125 case MODAL_RECORD_6: {
4127 if (bRecordGroup[MODAL_RECORD_6]) {
4128 silent_cerr(
"file=\"" << sFileFEM <<
"\": "
4129 "\"RECORD GROUP 6\" already parsed"
4135 checkPoint = MODAL_RECORD_6;
4136 fbin.write(&checkPoint,
sizeof(checkPoint));
4139 for (
unsigned int iNode = 1; iNode <=
NFEMNodes; iNode++) {
4143 fbin.write((
const char *)&d,
sizeof(d));
4146 #ifdef MODAL_SCALE_DATA
4149 pXYZFEMNodes->
Put(2, iNode, d);
4152 bRecordGroup[MODAL_RECORD_6] =
true;
4155 case MODAL_RECORD_7: {
4157 if (bRecordGroup[MODAL_RECORD_7]) {
4158 silent_cerr(
"file=\"" << sFileFEM <<
"\": "
4159 "\"RECORD GROUP 7\" already parsed"
4165 checkPoint = MODAL_RECORD_7;
4166 fbin.write(&checkPoint,
sizeof(checkPoint));
4169 for (
unsigned int iNode = 1; iNode <=
NFEMNodes; iNode++) {
4173 fbin.write((
const char *)&d,
sizeof(d));
4176 #ifdef MODAL_SCALE_DATA
4179 pXYZFEMNodes->
Put(3, iNode, d);
4182 bRecordGroup[MODAL_RECORD_7] =
true;
4185 case MODAL_RECORD_8: {
4187 if (bRecordGroup[MODAL_RECORD_8]) {
4188 silent_cerr(
"file=\"" << sFileFEM <<
"\": "
4189 "\"RECORD GROUP 8\" already parsed"
4195 checkPoint = MODAL_RECORD_8;
4196 fbin.write(&checkPoint,
sizeof(checkPoint));
4200 for (
unsigned int jMode = 1; jMode <= NRejModes; jMode++) {
4202 fdat.getline(str,
sizeof(str));
4204 silent_cout(
"Modal(" << uLabel <<
"): rejecting mode #" << jMode
4205 <<
" (" << str <<
")" << std::endl);
4208 for (
unsigned int iNode = 1; iNode <=
NFEMNodes; iNode++) {
4211 fdat >> n[0] >> n[1] >> n[2]
4212 >> n[3] >> n[4] >> n[5];
4217 fdat.getline(str,
sizeof(str));
4220 if (bActiveModes.empty()) {
4221 silent_cerr(
"Modal(" << uLabel <<
"): "
4222 "input file \"" << sFileFEM <<
"\" "
4223 "is bogus (RECORD GROUP 8)"
4228 unsigned int iCnt = 1;
4229 for (
unsigned int jMode = 1; jMode <= NModesFEM; jMode++) {
4230 fdat.getline(str,
sizeof(str));
4231 if (str[0] !=
'\0' && strncmp(
"**", str,
STRLENOF(
"**")) != 0)
4234 silent_cerr(
"Modal(" << uLabel <<
"): "
4235 "input file \"" << sFileFEM <<
"\""
4236 "is bogus (\"**\" expected before mode #" << jMode
4237 <<
" of " << NModesFEM <<
"; "
4238 "#" << jMode + NRejModes
4239 <<
" of " << NModesFEM + NRejModes
4240 <<
" including rejected)"
4243 silent_cerr(
"Modal(" << uLabel <<
"): "
4244 "input file \"" << sFileFEM <<
"\""
4245 "is bogus (\"**\" expected before mode #" << jMode
4246 <<
" of " << NModesFEM <<
")"
4252 for (
unsigned int iNode = 1; iNode <=
NFEMNodes; iNode++) {
4255 fdat >> n[0] >> n[1] >> n[2]
4256 >> n[3] >> n[4] >> n[5];
4259 fbin.write((
const char *)n,
sizeof(n));
4262 if (!bActiveModes[jMode]) {
4266 #ifdef MODAL_SCALE_DATA
4271 pModeShapest->
PutVec((iCnt - 1)*NFEMNodes + iNode,
Vec3(&n[0]));
4272 pModeShapesr->
PutVec((iCnt - 1)*NFEMNodes + iNode,
Vec3(&n[3]));
4275 if (bActiveModes[jMode]) {
4278 fdat.getline(str,
sizeof(str));
4281 bRecordGroup[MODAL_RECORD_8] =
true;
4284 case MODAL_RECORD_9: {
4286 if (bRecordGroup[MODAL_RECORD_9]) {
4287 silent_cerr(
"file=\"" << sFileFEM <<
"\": "
4288 "\"RECORD GROUP 9\" already parsed"
4293 if (bActiveModes.empty()) {
4294 silent_cerr(
"Modal(" << uLabel <<
"): "
4295 "input file \"" << sFileFEM <<
"\" "
4296 "is bogus (RECORD GROUP 9)"
4302 checkPoint = MODAL_RECORD_9;
4303 fbin.write(&checkPoint,
sizeof(checkPoint));
4306 unsigned int iCnt = 1;
4307 for (
unsigned int jMode = 1; jMode <= NModesFEM; jMode++) {
4308 unsigned int jCnt = 1;
4310 for (
unsigned int kMode = 1; kMode <= NModesFEM; kMode++) {
4313 if (dMassThreshold > 0.0 &&
fabs(d) < dMassThreshold) {
4318 fbin.write((
const char *)&d,
sizeof(d));
4321 if (!bActiveModes[jMode] || !bActiveModes[kMode]) {
4324 pGenMass->
Put(iCnt, jCnt, d);
4328 if (bActiveModes[jMode]) {
4333 bRecordGroup[MODAL_RECORD_9] =
true;
4336 case MODAL_RECORD_10: {
4338 if (bRecordGroup[MODAL_RECORD_10]) {
4339 silent_cerr(
"file=\"" << sFileFEM <<
"\": "
4340 "\"RECORD GROUP 10\" already parsed"
4345 if (bActiveModes.empty()) {
4346 silent_cerr(
"Modal(" << uLabel <<
"): "
4347 "input file \"" << sFileFEM <<
"\" "
4348 "is bogus (RECORD GROUP 10)"
4354 checkPoint = MODAL_RECORD_10;
4355 fbin.write(&checkPoint,
sizeof(checkPoint));
4358 unsigned int iCnt = 1;
4359 for (
unsigned int jMode = 1; jMode <= NModesFEM; jMode++) {
4360 unsigned int jCnt = 1;
4362 for (
unsigned int kMode = 1; kMode <= NModesFEM; kMode++) {
4365 if (dStiffnessThreshold > 0.0 &&
fabs(d) < dStiffnessThreshold) {
4370 fbin.write((
const char *)&d,
sizeof(d));
4373 if (!bActiveModes[jMode] || !bActiveModes[kMode]) {
4376 pGenStiff->
Put(iCnt, jCnt, d);
4380 if (bActiveModes[jMode]) {
4385 bRecordGroup[MODAL_RECORD_10] =
true;
4388 case MODAL_RECORD_11: {
4390 if (bRecordGroup[MODAL_RECORD_11]) {
4391 silent_cerr(
"file=\"" << sFileFEM <<
"\": "
4392 "\"RECORD GROUP 11\" already parsed"
4398 checkPoint = MODAL_RECORD_11;
4399 fbin.write(&checkPoint,
sizeof(checkPoint));
4402 FEMMass.resize(NFEMNodes);
4403 FEMJ.resize(NFEMNodes);
4405 for (
unsigned int iNode = 1; iNode <=
NFEMNodes; iNode++) {
4407 for (
unsigned int jCnt = 1; jCnt <= 6; jCnt++) {
4411 fbin.write((
const char *)&d,
sizeof(d));
4417 #ifdef MODAL_SCALE_DATA
4420 FEMMass[iNode - 1] = d;
4426 silent_cout(
"Warning: component(" << jCnt <<
") "
4427 "of FEM node(" << iNode <<
") mass "
4428 "differs from component(1)=" << tmpmass << std::endl);
4435 #ifdef MODAL_SCALE_DATA
4438 FEMJ[iNode - 1](jCnt - 3) = d;
4444 bBuildInvariants =
true;
4446 bRecordGroup[MODAL_RECORD_11] =
true;
4449 case MODAL_RECORD_12: {
4451 if (bRecordGroup[MODAL_RECORD_12]) {
4452 silent_cerr(
"file=\"" << sFileFEM <<
"\": "
4453 "\"RECORD GROUP 12\" already parsed"
4459 checkPoint = MODAL_RECORD_12;
4460 fbin.write(&checkPoint,
sizeof(checkPoint));
4466 fbin.write((
const char *)&d,
sizeof(d));
4473 for (
int iRow = 1; iRow <= 3; iRow++) {
4477 fbin.write((
const char *)&d,
sizeof(d));
4484 for (
int iRow = 1; iRow <= 3; iRow++) {
4485 for (
int iCol = 1; iCol <= 3; iCol++) {
4489 fbin.write((
const char *)&d,
sizeof(d));
4492 JTmpIn(iRow, iCol) = d;
4496 bRecordGroup[MODAL_RECORD_12] =
true;
4499 case MODAL_RECORD_13: {
4501 if (bRecordGroup[MODAL_RECORD_13]) {
4502 silent_cerr(
"file=\"" << sFileFEM <<
"\": "
4503 "\"RECORD GROUP 13\" already parsed"
4508 if (bActiveModes.empty()) {
4509 silent_cerr(
"Modal(" << uLabel <<
"): "
4510 "input file \"" << sFileFEM <<
"\" "
4511 "is bogus (RECORD GROUP 13)"
4517 checkPoint = MODAL_RECORD_13;
4518 fbin.write(&checkPoint,
sizeof(checkPoint));
4521 unsigned int iCnt = 1;
4522 for (
unsigned int jMode = 1; jMode <= NModesFEM; jMode++) {
4523 unsigned int jCnt = 1;
4525 for (
unsigned int kMode = 1; kMode <= NModesFEM; kMode++) {
4528 if (dDampingThreshold > 0.0 &&
fabs(d) < dDampingThreshold) {
4533 fbin.write((
const char *)&d,
sizeof(d));
4536 if (!bActiveModes[jMode] || !bActiveModes[kMode]) {
4540 if (eDamp == DAMPING_FROM_FILE) {
4541 pGenDamp->
Put(iCnt, jCnt, d);
4547 if (bActiveModes[jMode]) {
4552 bRecordGroup[MODAL_RECORD_13] =
true;
4556 silent_cerr(
"file=\"" << sFileFEM <<
"\": "
4557 "\"RECORD GROUP " << rg <<
"\" unhandled"
4565 checkPoint = MODAL_END_OF_FILE;
4566 fbin.write(&checkPoint,
sizeof(checkPoint));
4575 (void)unlink(sBinFileFEM.c_str());
4583 std::ifstream fbin(sBinFileFEM.c_str(), std::ios::binary);
4585 silent_cerr(
"Modal(" << uLabel <<
"): "
4586 "unable to open file \"" << sBinFileFEM <<
"\""
4590 silent_cout(
"Modal(" << uLabel <<
"): "
4591 "reading flexible body data from file "
4592 "\"" << sBinFileFEM <<
"\"" << std::endl);
4617 char currMagic[5] = { 0 };
4618 fbin.read((
char *)&currMagic,
sizeof(4));
4619 if (memcmp(magic, currMagic, 4) != 0) {
4620 silent_cerr(
"Modal(" << uLabel <<
"): "
4621 "file \"" << sBinFileFEM <<
"\" "
4622 "unexpected signature" << std::endl);
4626 fbin.read((
char *)&currBinVersion,
sizeof(currBinVersion));
4627 if (currBinVersion > BinVersion) {
4628 silent_cerr(
"Modal(" << uLabel <<
"): "
4629 "file \"" << sBinFileFEM <<
"\" "
4630 "version " << currBinVersion <<
" unsupported" << std::endl);
4633 }
else if (currBinVersion < BinVersion) {
4634 silent_cout(
"Modal(" << uLabel <<
"): "
4635 "file \"" << sBinFileFEM <<
"\" "
4636 "version " << currBinVersion <<
" is outdated; "
4637 "trying to read anyway..." << std::endl);
4640 pedantic_cout(
"Modal(" << uLabel <<
"): "
4641 "binary version " << currBinVersion << std::endl);
4649 fbin.read(&checkPoint,
sizeof(checkPoint));
4650 if (checkPoint != MODAL_RECORD_1) {
4651 silent_cerr(
"Modal(" << uLabel <<
"): "
4652 "file \"" << sBinFileFEM <<
"\" "
4653 "looks broken (expecting checkpoint 1)"
4658 pedantic_cout(
"Modal(" << uLabel <<
"): "
4659 "reading block " <<
unsigned(checkPoint) << std::endl);
4661 fbin.read((
char *)&NFEMNodesFEM,
sizeof(NFEMNodesFEM));
4662 fbin.read((
char *)&NModesFEM,
sizeof(NModesFEM));
4665 if (NFEMNodes ==
unsigned(-1)) {
4666 NFEMNodes = NFEMNodesFEM;
4668 }
else if (NFEMNodes != NFEMNodesFEM) {
4669 silent_cerr(
"Modal(" << uLabel <<
"), "
4670 "file \"" << sFileFEM <<
"\": "
4671 "FEM nodes number " << NFEMNodes
4672 <<
" does not match node number "
4678 if (NModes != NModesFEM) {
4679 silent_cout(
"Modal(" << uLabel
4680 <<
"), file '" << sFileFEM
4681 <<
"': using " << NModes
4682 <<
" of " << NModesFEM
4683 <<
" modes" << std::endl);
4686 if (!bActiveModes.empty()) {
4690 IdFEMNodes.resize(NFEMNodes);
4696 bActiveModes.resize(NModesFEM + 1,
false);
4698 for (
unsigned int iCnt = 0; iCnt <
NModes; iCnt++) {
4699 if (uModeNumber[iCnt] > NModesFEM) {
4700 silent_cerr(
"Modal(" << uLabel <<
"): "
4701 "mode " << uModeNumber[iCnt]
4702 <<
" is not available (max = "
4707 bActiveModes[uModeNumber[iCnt]] =
true;
4710 bRecordGroup[1] =
true;
4713 fbin.read(&checkPoint,
sizeof(checkPoint));
4715 if (checkPoint == MODAL_END_OF_FILE) {
4716 pedantic_cout(
"Modal(" << uLabel <<
"): "
4717 "end of binary file \"" << sBinFileFEM <<
"\""
4723 if (checkPoint < MODAL_RECORD_1 || checkPoint >= MODAL_LAST_RECORD) {
4724 silent_cerr(
"Modal(" << uLabel <<
"): "
4725 "file \"" << sBinFileFEM <<
"\" "
4726 "looks broken (unknown block " <<
unsigned(checkPoint) <<
")"
4731 if (bRecordGroup[
unsigned(checkPoint)]) {
4732 silent_cerr(
"Modal(" << uLabel <<
"): "
4733 "file \"" << sBinFileFEM <<
"\" "
4734 "looks broken (block " <<
unsigned(checkPoint) <<
" already parsed)"
4739 pedantic_cout(
"Modal(" << uLabel <<
"): "
4740 "reading block " <<
unsigned(checkPoint)
4741 <<
" from file \"" << sBinFileFEM <<
"\"" << std::endl);
4743 switch (checkPoint) {
4744 case MODAL_RECORD_2:
4746 for (
unsigned int iNode = 0; iNode <
NFEMNodes; iNode++) {
4748 fbin.read((
char *)&len,
sizeof(len));
4750 IdFEMNodes[iNode].resize(len);
4751 fbin.read((
char *)IdFEMNodes[iNode].c_str(), len);
4755 case MODAL_RECORD_3:
4757 for (
unsigned int iCnt = 1, jMode = 1; jMode <= NModesFEM; jMode++) {
4760 fbin.read((
char *)&d,
sizeof(d));
4762 if (!bActiveModes[jMode]) {
4771 case MODAL_RECORD_4:
4773 for (
unsigned int iCnt = 1, jMode = 1; jMode <= NModesFEM; jMode++) {
4776 fbin.read((
char *)&d,
sizeof(d));
4778 if (!bActiveModes[jMode]) {
4787 case MODAL_RECORD_5:
4789 for (
unsigned int iNode = 1; iNode <=
NFEMNodes; iNode++) {
4792 fbin.read((
char *)&d,
sizeof(d));
4794 #ifdef MODAL_SCALE_DATA
4798 pXYZFEMNodes->
Put(1, iNode, d);
4802 case MODAL_RECORD_6:
4804 for (
unsigned int iNode = 1; iNode <=
NFEMNodes; iNode++) {
4807 fbin.read((
char *)&d,
sizeof(d));
4809 #ifdef MODAL_SCALE_DATA
4813 pXYZFEMNodes->
Put(2, iNode, d);
4817 case MODAL_RECORD_7:
4819 for (
unsigned int iNode = 1; iNode <=
NFEMNodes; iNode++) {
4822 fbin.read((
char *)&d,
sizeof(d));
4824 #ifdef MODAL_SCALE_DATA
4828 pXYZFEMNodes->
Put(3, iNode, d);
4832 case MODAL_RECORD_8:
4834 for (
unsigned int iCnt = 1, jMode = 1; jMode <= NModesFEM; jMode++) {
4835 for (
unsigned int iNode = 1; iNode <=
NFEMNodes; iNode++) {
4838 fbin.read((
char *)n,
sizeof(n));
4840 if (!bActiveModes[jMode]) {
4844 #ifdef MODAL_SCALE_DATA
4849 pModeShapest->
PutVec((iCnt - 1)*NFEMNodes + iNode,
Vec3(&n[0]));
4850 pModeShapesr->
PutVec((iCnt - 1)*NFEMNodes + iNode,
Vec3(&n[3]));
4853 if (bActiveModes[jMode]) {
4859 case MODAL_RECORD_9:
4861 for (
unsigned int iCnt = 1, jMode = 1; jMode <= NModesFEM; jMode++) {
4862 unsigned int jCnt = 1;
4864 for (
unsigned int kMode = 1; kMode <= NModesFEM; kMode++) {
4867 fbin.read((
char *)&d,
sizeof(d));
4869 if (!bActiveModes[jMode] || !bActiveModes[kMode]) {
4872 pGenMass->
Put(iCnt, jCnt, d);
4876 if (bActiveModes[jMode]) {
4882 case MODAL_RECORD_10:
4884 for (
unsigned int iCnt = 1, jMode = 1; jMode <= NModesFEM; jMode++) {
4885 unsigned int jCnt = 1;
4887 for (
unsigned int kMode = 1; kMode <= NModesFEM; kMode++) {
4890 fbin.read((
char *)&d,
sizeof(d));
4892 if (!bActiveModes[jMode] || !bActiveModes[kMode]) {
4895 pGenStiff->
Put(iCnt, jCnt, d);
4899 if (bActiveModes[jMode]) {
4905 case MODAL_RECORD_11:
4907 FEMMass.resize(NFEMNodes);
4908 FEMJ.resize(NFEMNodes);
4910 for (
unsigned int iNode = 1; iNode <=
NFEMNodes; iNode++) {
4911 for (
unsigned int jCnt = 1; jCnt <= 6; jCnt++) {
4914 fbin.read((
char *)&d,
sizeof(d));
4918 #ifdef MODAL_SCALE_DATA
4921 FEMMass[iNode - 1] = d;
4927 #ifdef MODAL_SCALE_DATA
4930 FEMJ[iNode - 1](jCnt - 3) = d;
4936 bBuildInvariants =
true;
4939 case MODAL_RECORD_12: {
4941 fbin.read((
char *)&d,
sizeof(d));
4946 for (
int iRow = 1; iRow <= 3; iRow++) {
4947 fbin.read((
char *)&d,
sizeof(d));
4953 for (
int iRow = 1; iRow <= 3; iRow++) {
4954 for (
int iCol = 1; iCol <= 3; iCol++) {
4955 fbin.read((
char *)&d,
sizeof(d));
4957 JTmpIn(iRow, iCol) = d;
4962 case MODAL_RECORD_13:
4963 for (
unsigned int iCnt = 1, jMode = 1; jMode <= NModesFEM; jMode++) {
4964 unsigned int jCnt = 1;
4966 for (
unsigned int kMode = 1; kMode <= NModesFEM; kMode++) {
4969 fbin.read((
char *)&d,
sizeof(d));
4971 if (!bActiveModes[jMode] || !bActiveModes[kMode]) {
4975 if (eDamp == DAMPING_FROM_FILE) {
4976 pGenDamp->
Put(iCnt, jCnt, d);
4982 if (bActiveModes[jMode]) {
4989 silent_cerr(
"Modal(" << uLabel <<
"): "
4990 "file \"" << sBinFileFEM <<
"\" "
4991 "looks broken (unknown block " <<
unsigned(checkPoint) <<
")"
4996 bRecordGroup[unsigned(checkPoint)] =
true;
4999 fname = sBinFileFEM;
5002 unsigned reqMR[] = {
5013 bool bBailOut(
false);
5014 for (
unsigned iCnt = 0; iCnt <
sizeof(reqMR)/
sizeof(
unsigned); iCnt++) {
5015 if (!bRecordGroup[reqMR[iCnt]]) {
5016 silent_cerr(
"Modal(" << uLabel <<
"): "
5017 "incomplete input file \"" << fname <<
"\", "
5018 "record group " << reqMR[iCnt] <<
" missing "
5031 if (!sEchoFileName.empty()) {
5032 std::ofstream fecho(sEchoFileName.c_str());
5034 fecho.setf(std::ios::scientific);
5035 fecho.precision(iEchoPrecision);
5041 <<
"** echo of file \"" << fname <<
"\" generated " << ctime(&t)
5042 <<
"** RECORD GROUP 1, HEADER" << std::endl
5043 <<
"** REVISION. NODES. NORMAL, ATTACHMENT, CONSTRAINT, REJECTED MODES." << std::endl
5044 <<
"VER" << currBinVersion <<
" " << NFEMNodes <<
" " << NModes <<
" 0 0 0" << std::endl
5045 <<
"**" << std::endl
5046 <<
"** RECORD GROUP 2, FINITE ELEMENT NODE LIST" << std::endl;
5047 for (
unsigned r = 0; r <= (IdFEMNodes.size() - 1)/6; r++) {
5048 for (
unsigned c = 0;
c < std::min(6U,
unsigned(IdFEMNodes.size() - 6*r));
c++) {
5049 fecho << IdFEMNodes[6*r +
c] <<
" ";
5055 <<
"**" << std::endl
5056 <<
"** RECORD GROUP 3, INITIAL MODAL DISPLACEMENTS"<< std::endl;
5058 fecho << (*a)(r) << std::endl;
5062 <<
"**" << std::endl
5063 <<
"** RECORD GROUP 4, INITIAL MODAL VELOCITIES"<< std::endl;
5065 fecho << (*aP)(r) << std::endl;
5069 <<
"**" << std::endl
5070 <<
"** RECORD GROUP 5, NODAL X COORDINATES" << std::endl;
5071 for (
int r = 1; r <= pXYZFEMNodes->
iGetNumCols(); r++) {
5072 fecho << (*pXYZFEMNodes)(1, r) << std::endl;
5076 <<
"**" << std::endl
5077 <<
"** RECORD GROUP 6, NODAL Y COORDINATES" << std::endl;
5078 for (
int r = 1; r <= pXYZFEMNodes->
iGetNumCols(); r++) {
5079 fecho << (*pXYZFEMNodes)(2, r) << std::endl;
5083 <<
"**" << std::endl
5084 <<
"** RECORD GROUP 7, NODAL Z COORDINATES" << std::endl;
5085 for (
int r = 1; r <= pXYZFEMNodes->
iGetNumCols(); r++) {
5086 fecho << (*pXYZFEMNodes)(3, r) << std::endl;
5090 <<
"**" << std::endl
5091 <<
"** RECORD GROUP 8, NON-ORTHOGONALIZED MODE SHAPES" << std::endl;
5092 for (
unsigned m = 0; m <
NModes; m++) {
5094 <<
"** NORMAL MODE SHAPE # " << uModeNumber[m] << std::endl;
5095 for (
unsigned n = 1; n <=
NFEMNodes; n++) {
5097 << (*pModeShapest)(1, m*NFEMNodes + n) <<
" "
5098 << (*pModeShapest)(2, m*NFEMNodes + n) <<
" "
5099 << (*pModeShapest)(3, m*NFEMNodes + n) <<
" "
5100 << (*pModeShapesr)(1, m*NFEMNodes + n) <<
" "
5101 << (*pModeShapesr)(2, m*NFEMNodes + n) <<
" "
5102 << (*pModeShapesr)(3, m*NFEMNodes + n) << std::endl;
5107 <<
"**" << std::endl
5108 <<
"** RECORD GROUP 9, MODAL MASS MATRIX. COLUMN-MAJOR FORM" << std::endl;
5109 for (
unsigned r = 1; r <=
NModes; r++) {
5110 for (
unsigned c = 1;
c <=
NModes;
c++) {
5111 fecho << (*pGenMass)(r,
c) <<
" ";
5117 <<
"**" << std::endl
5118 <<
"** RECORD GROUP 10, MODAL STIFFNESS MATRIX. COLUMN-MAJOR FORM" << std::endl;
5119 for (
unsigned r = 1; r <=
NModes; r++) {
5120 for (
unsigned c = 1;
c <=
NModes;
c++) {
5121 fecho << (*pGenStiff)(r,
c) <<
" ";
5126 if (bBuildInvariants) {
5128 <<
"**" << std::endl
5129 <<
"** RECORD GROUP 11, DIAGONAL OF LUMPED MASS MATRIX" << std::endl;
5130 for (
unsigned r = 0; r < FEMMass.size(); r++) {
5132 << FEMMass[r] <<
" " << FEMMass[r] <<
" " << FEMMass[r] <<
" "
5133 << FEMJ[r] << std::endl;
5137 if (bRecordGroup[MODAL_RECORD_12]) {
5139 <<
"**" << std::endl
5140 <<
"** RECORD GROUP 12, GLOBAL INERTIA" << std::endl
5141 << dMass << std::endl
5142 << XTmpIn << std::endl,
5143 JTmpIn.
Write(fecho,
" ",
"\n") << std::endl;
5146 if (bRecordGroup[MODAL_RECORD_13]) {
5148 <<
"**" << std::endl
5149 <<
"** RECORD GROUP 13, MODAL DAMPING MATRIX. COLUMN-MAJOR FORM" << std::endl;
5150 for (
unsigned r = 1; r <=
NModes; r++) {
5151 for (
unsigned c = 1;
c <=
NModes;
c++) {
5152 fecho << (*pGenDamp)(r,
c) <<
" ";
5166 Mat3xN* pPHItStrNode = 0;
5167 Mat3xN* pPHIrStrNode = 0;
5171 bool bOrigin(
false);
5175 std::string FEMOriginNode;
5180 pedantic_cerr(
"Modal(" << uLabel <<
"): "
5181 "origin node expected as string with delimiters"
5187 for (iNode = 0; iNode <
NFEMNodes; iNode++) {
5188 if (FEMOriginNode == IdFEMNodes[iNode]) {
5193 if (iNode == NFEMNodes) {
5194 silent_cerr(
"Modal(" << uLabel <<
"): "
5195 "FEM node \"" << FEMOriginNode <<
"\""
5197 <<
" not defined " << std::endl);
5202 Origin = pXYZFEMNodes->
GetVec(iNode);
5204 pedantic_cout(
"Modal(" << uLabel <<
"): origin x={" << Origin <<
"}" << std::endl);
5207 }
else if (HP.
IsKeyWord(
"origin" "position")) {
5213 for (
unsigned int iStrNode = 1; iStrNode <=
NFEMNodes; iStrNode++) {
5214 pXYZFEMNodes->
SubVec(iStrNode, Origin);
5217 if (!bBuildInvariants) {
5219 JTmp = JTmpIn - Mat3x3(
MatCrossCross, XTmpIn, XTmpIn*dMass);
5225 DEBUGCOUT(
"Number of Interface Nodes : " << NStrNodes << std::endl);
5228 Mat3xN(NStrNodes*NModes, 0.));
5230 Mat3xN(NStrNodes*NModes, 0.));
5232 std::vector<Modal::StrNodeData>
SND(NStrNodes);
5239 for (
unsigned int iStrNode = 1; iStrNode <=
NStrNodes; iStrNode++) {
5246 if (Node1.find(
' ') != std::string::npos ) {
5247 silent_cout(
"Modal(" << uLabel <<
"): "
5248 "FEM node \"" << Node1 <<
"\""
5250 <<
" contains a blank" << std::endl);
5253 DEBUGCOUT(
"Linked to FEM Node " << Node1 << std::endl);
5257 for (iNode = 0; iNode <
NFEMNodes; iNode++) {
5258 if (Node1 == IdFEMNodes[iNode]) {
5263 if (iNode == NFEMNodes) {
5264 silent_cerr(
"Modal(" << uLabel <<
"): "
5265 "FEM node \"" << Node1 <<
"\""
5267 <<
" not defined " << std::endl);
5273 int iNodeCurr = iNode;
5282 SND[iStrNode-1].OffsetFEM = pXYZFEMNodes->
GetVec(iNodeCurr);
5286 for (
unsigned int jMode = 0; jMode <
NModes; jMode++) {
5287 pPHItStrNode->
PutVec(jMode*NStrNodes + iStrNode,
5288 pModeShapest->
GetVec(jMode*NFEMNodes + iNodeCurr));
5289 pPHIrStrNode->
PutVec(jMode*NStrNodes + iStrNode,
5290 pModeShapesr->
GetVec(jMode*NFEMNodes + iNodeCurr));
5294 unsigned int uNode2 = (
unsigned int)HP.
GetInt();
5295 DEBUGCOUT(
"Linked to Multi-Body Node " << uNode2 << std::endl);
5299 if (SND[iStrNode - 1].pNode == 0) {
5300 silent_cerr(
"Modal(" << uLabel <<
"): "
5301 "StructuralNode(" << uNode2 <<
") "
5303 <<
" not defined" << std::endl);
5315 SND[iStrNode - 1].OffsetMB = d2;
5316 SND[iStrNode - 1].RotMB = R2;
5318 DEBUGCOUT(
"Multibody Node reference frame d2: " << std::endl
5319 << d2 << std::endl);
5323 SND[iStrNode - 1].FEMNode = Node1;
5329 const Vec3& xMB(SND[iStrNode - 1].pNode->GetXCurr());
5330 pedantic_cout(
"Interface node " << iStrNode <<
":" << std::endl
5331 <<
" MB node " << uNode2 <<
" x={" << xMB <<
"}" << std::endl);
5332 Vec3 xFEMRel(pXYZFEMNodes->
GetVec(iNodeCurr));
5333 Vec3 xFEM(X0 + R*xFEMRel);
5334 pedantic_cout(
" FEM node \"" << Node1 <<
"\" x={" << xFEM <<
"} "
5335 "xrel={" << xFEMRel <<
"}" << std::endl);
5336 pedantic_cout(
" offset={" << xFEM - xMB <<
"}" << std::endl);
5340 std::vector<Modal::StrNodeData>::iterator i = SND.begin();
5341 std::vector<Modal::StrNodeData>::iterator end = SND.end();
5342 for (; i != end; ++i) {
5356 if (bBuildInvariants) {
5361 MatNxN GenMass(NModes, 0.);
5377 if (HP.
IsKeyWord(
"use" "invariant" "9")) {
5386 for (
unsigned int iNode = 1; iNode <=
NFEMNodes; iNode++) {
5398 JiNodeTmp(1, 1) = FEMJ[iNode - 1](1);
5399 JiNodeTmp(2, 2) = FEMJ[iNode - 1](2);
5400 JiNodeTmp(3, 3) = FEMJ[iNode - 1](3);
5406 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
5407 unsigned int iOffset = (jMode - 1)*NFEMNodes + iNode;
5415 Mat3xN Inv3Tmp(NModes, 0.);
5416 Mat3xN Inv4Tmp(NModes, 0.);
5417 Mat3xN Inv4JTmp(NModes, 0.);
5418 Inv3Tmp.
Copy(PHIti);
5424 Inv4Tmp.
LeftMult(uiWedge*mi, PHIti);
5425 Inv4JTmp.
LeftMult(JiNodeTmp, PHIri);
5426 Inv4Tmp += Inv4JTmp;
5429 *pInv11 += Inv4JTmp;
5432 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
5436 Mat3x3 PHItijvett_mi(
MatCross, PHItij*mi);
5437 Mat3xN Inv5jTmp(NModes, 0);
5441 Inv5jTmp.
LeftMult(PHItijvett_mi, PHIti);
5442 for (
unsigned int kMode = 1; kMode <=
NModes; kMode++) {
5443 pInv5->
AddVec((jMode - 1)*NModes + kMode,
5449 GenMass(jMode, kMode) += (PHItij*PHIti.
GetVec(kMode))*mi
5450 + PHIrij*(JiNodeTmp*PHIri.
GetVec(kMode));
5455 Mat3x3 Inv8jTmp = -uiWedge*PHItijvett_mi;
5456 pInv8->
AddMat3x3((jMode - 1)*3 + 1, Inv8jTmp);
5461 for (
unsigned int kMode = 1; kMode <=
NModes; kMode++) {
5463 Mat3x3 Inv9jkTmp = PHItijvett_mi*PHItikvett;
5465 pInv9->
AddMat3x3((jMode - 1)*3*NModes + (kMode - 1)*3 + 1, Inv9jkTmp);
5471 Mat3x3 Inv10jTmp = PHIrij.
Cross(JiNodeTmp);
5472 pInv10->
AddMat3x3((jMode - 1)*3 + 1, Inv10jTmp);
5476 if (bRecordGroup[12]) {
5477 Mat3x3 DJ = JTmp - JTmpInv;
5478 pedantic_cerr(
" Rigid-body mass: "
5479 "input - computed" << std::endl
5480 <<
" " << dMass - dMassInv << std::endl);
5481 pedantic_cerr(
" Rigid-body CM location: "
5482 "input - computed" << std::endl
5483 <<
" " << XTmpIn - STmpInv/dMassInv << std::endl);
5484 pedantic_cerr(
" Rigid-body inertia: "
5485 "input - computed" << std::endl
5486 <<
" " << DJ.
GetVec(1) << std::endl
5487 <<
" " << DJ.
GetVec(2) << std::endl
5488 <<
" " << DJ.
GetVec(3) << std::endl);
5494 pedantic_cerr(
" Generalized mass: input - computed" << std:: endl);
5495 for (
unsigned int jMode = 1; jMode <=
NModes; jMode++) {
5497 for (
unsigned int kMode = 1; kMode <=
NModes; kMode++) {
5498 pedantic_cerr(
" " << pGenMass->
dGet(jMode, kMode) - GenMass(jMode, kMode));
5500 pedantic_cerr(std::endl);
5505 if (!bRecordGroup[12]) {
5513 if (bRecordGroup[12]) {
5515 STmp = XTmpIn*
dMass;
5523 bool bIsMSym =
true;
5524 bool bIsMDiag =
true;
5525 for (
unsigned iRow = 2; iRow <=
NModes; iRow++) {
5526 for (
unsigned iCol = 1; iCol < iRow; iCol++) {
5531 silent_cerr(
"Modal(" << uLabel <<
"): mass matrix is not symmetric: (at least) "
5532 "M(" << iRow <<
", " << iCol <<
")=" << mrc <<
" "
5534 "M(" << iCol <<
", " << iRow <<
")=" << mcr <<
" "
5540 if (mrc != 0. || mcr != 0.) {
5542 silent_cerr(
"Modal(" << uLabel <<
"): mass matrix is not diagonal: (at least) "
5543 "M(" << iRow <<
", " << iCol <<
")=" << mrc <<
" "
5545 "M(" << iCol <<
", " << iRow <<
")=" << mcr <<
" "
5554 bool bIsKSym =
true;
5555 bool bIsKDiag =
true;
5556 for (
unsigned iRow = 2; iRow <=
NModes; iRow++) {
5557 for (
unsigned iCol = 1; iCol < iRow; iCol++) {
5562 silent_cerr(
"Modal(" << uLabel <<
"): stiffness matrix is not symmetric: (at least) "
5563 "K(" << iRow <<
", " << iCol <<
")=" << mrc <<
" "