00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <TransformationDOF_Group.h>
00039 #include <stdlib.h>
00040
00041 #include <Domain.h>
00042 #include <Node.h>
00043 #include <Vector.h>
00044 #include <Matrix.h>
00045 #include <TransientIntegrator.h>
00046 #include <MP_Constraint.h>
00047 #include <SP_Constraint.h>
00048 #include <SP_ConstraintIter.h>
00049
00050 #define MAX_NUM_DOF 16
00051
00052
00053
00054 Matrix **TransformationDOF_Group::modMatrices;
00055 Vector **TransformationDOF_Group::modVectors;
00056 int TransformationDOF_Group::numTransDOFs(0);
00057
00058 TransformationDOF_Group::TransformationDOF_Group(int tag, Node *node,
00059 MP_Constraint *mp)
00060 :DOF_Group(tag,node),
00061 theMP(mp),Trans(0),modTangent(0),modUnbalance(0),modID(0),theSPs(0)
00062 {
00063
00064 int numNodalDOF = node->getNumberDOF();
00065 const ID &retainedDOF = mp->getRetainedDOFs();
00066 const ID &constrainedDOF = mp->getConstrainedDOFs();
00067 int numNodalDOFConstrained = constrainedDOF.Size();
00068 int numConstrainedNodeRetainedDOF = numNodalDOF - numNodalDOFConstrained;
00069 int numRetainedNodeDOF = retainedDOF.Size();
00070
00071 modNumDOF = numConstrainedNodeRetainedDOF + numRetainedNodeDOF;
00072
00073
00074 theSPs = new SP_Constraint *[numNodalDOF];
00075 for (int ii=0; ii<numNodalDOF; ii++)
00076 theSPs[ii] = 0;
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 modID = new ID(modNumDOF);
00098 Trans = new Matrix(numNodalDOF, modNumDOF);
00099
00100 if (modID == 0 || modID->Size() == 0 ||
00101 Trans == 0 || Trans->noRows() == 0) {
00102
00103 cerr << "FATAL TransformationDOF_Group::TransformationDOF_Group() -";
00104 cerr << " ran out of memory for size: " << modNumDOF << endl;
00105 exit(-1);
00106 }
00107
00108
00109 for (int i=0; i<numConstrainedNodeRetainedDOF; i++)
00110 (*modID)(i) = -2;
00111
00112
00113 for (int j=numConstrainedNodeRetainedDOF; j<modNumDOF; j++)
00114 (*modID)(j) = -1;
00115
00116
00117
00118 for (int k=numConstrainedNodeRetainedDOF; k<modNumDOF; k++)
00119 (*modID)(k) = -1;
00120
00121
00122
00123
00124 if (numTransDOFs == 0) {
00125 modMatrices = new Matrix *[MAX_NUM_DOF+1];
00126 modVectors = new Vector *[MAX_NUM_DOF+1];
00127
00128 if (modMatrices == 0 || modVectors == 0) {
00129 cerr << "TransformationDOF_Group::TransformationDOF_Group(Node *) ";
00130 cerr << " ran out of memory";
00131 }
00132 for (int i=0; i<MAX_NUM_DOF; i++) {
00133 modMatrices[i] = 0;
00134 modVectors[i] = 0;
00135 }
00136 }
00137
00138
00139 if (modNumDOF <= MAX_NUM_DOF) {
00140
00141 if (modVectors[modNumDOF] == 0) {
00142
00143 modVectors[modNumDOF] = new Vector(modNumDOF);
00144 modMatrices[modNumDOF] = new Matrix(modNumDOF,modNumDOF);
00145 modUnbalance = modVectors[modNumDOF];
00146 modTangent = modMatrices[modNumDOF];
00147 if (modUnbalance == 0 || modUnbalance->Size() != modNumDOF ||
00148 modTangent == 0 || modTangent->noCols() != modNumDOF) {
00149 cerr << "TransformationDOF_Group::TransformationDOF_Group(Node *) ";
00150 cerr << " ran out of memory for vector/Matrix of size :";
00151 cerr << modNumDOF << endl;
00152 exit(-1);
00153 }
00154 } else {
00155 modUnbalance = modVectors[modNumDOF];
00156 modTangent = modMatrices[modNumDOF];
00157 }
00158 } else {
00159
00160 modUnbalance = new Vector(modNumDOF);
00161 modTangent = new Matrix(modNumDOF, modNumDOF);
00162 if (modUnbalance == 0 || modTangent ==0 ||
00163 modTangent ==0 || modTangent->noRows() ==0) {
00164
00165 cerr << "TransformationDOF_Group::TransformationDOF_Group(Node *) ";
00166 cerr << " ran out of memory for vector/Matrix of size :";
00167 cerr << modNumDOF << endl;
00168 exit(-1);
00169 }
00170 }
00171
00172 numTransDOFs++;
00173 }
00174
00175 void
00176 TransformationDOF_Group::setID(int dof, int value)
00177 {
00178 if (theMP == 0)
00179 this->DOF_Group::setID(dof,value);
00180 else
00181 (*modID)(dof) = value;
00182 }
00183
00184
00185 TransformationDOF_Group::TransformationDOF_Group(int tag, Node *node)
00186 :DOF_Group(tag,node),
00187 theMP(0),Trans(0),modTangent(0),modUnbalance(0),modID(0),theSPs(0)
00188 {
00189 modNumDOF = node->getNumberDOF();
00190
00191
00192 theSPs = new SP_Constraint *[modNumDOF];
00193 for (int i=0; i<modNumDOF; i++)
00194 theSPs[i] = 0;
00195
00196
00197 Domain *theDomain=node->getDomain();
00198 int nodeTag = node->getTag();
00199 SP_ConstraintIter &theSPIter = theDomain->getSPs();
00200 SP_Constraint *sp;
00201 while ((sp = theSPIter()) != 0) {
00202 if (sp->getNodeTag() == nodeTag) {
00203 int dof = sp->getDOF_Number();
00204 theSPs[dof] = sp;
00205 }
00206 }
00207
00208
00209
00210
00211 if (numTransDOFs == 0) {
00212 modMatrices = new Matrix *[MAX_NUM_DOF+1];
00213 modVectors = new Vector *[MAX_NUM_DOF+1];
00214
00215 if (modMatrices == 0 || modVectors == 0) {
00216 cerr << "TransformationDOF_Group::TransformationDOF_Group(Node *) ";
00217 cerr << " ran out of memory";
00218 }
00219 for (int i=0; i<MAX_NUM_DOF; i++) {
00220 modMatrices[i] = 0;
00221 modVectors[i] = 0;
00222 }
00223 }
00224
00225 numTransDOFs++;
00226 }
00227
00228
00229
00230
00231
00232 TransformationDOF_Group::~TransformationDOF_Group()
00233 {
00234 numTransDOFs--;
00235
00236
00237 if (modNumDOF > MAX_NUM_DOF) {
00238 if (modTangent != 0) delete modTangent;
00239 if (modUnbalance != 0) delete modUnbalance;
00240 }
00241
00242 if (modID != 0) delete modID;
00243 if (Trans != 0) delete Trans;
00244 if (theSPs != 0) delete [] theSPs;
00245
00246
00247
00248 if (numTransDOFs == 0) {
00249 for (int i=0; i<MAX_NUM_DOF; i++) {
00250 if (modVectors[i] != 0)
00251 delete modVectors[i];
00252 if (modMatrices[i] != 0)
00253 delete modMatrices[i];
00254 }
00255 delete [] modMatrices;
00256 delete [] modVectors;
00257 }
00258 }
00259
00260
00261 const ID &
00262 TransformationDOF_Group::getID(void) const
00263 {
00264 if (modID != 0)
00265 return *modID;
00266 else
00267 return this->DOF_Group::getID();
00268 }
00269
00270 int
00271 TransformationDOF_Group::getNumDOF(void) const
00272 {
00273 return modNumDOF;
00274 }
00275
00276
00277 int
00278 TransformationDOF_Group::getNumFreeDOF(void) const
00279 {
00280 if (modID != 0) {
00281 int numFreeDOF = modNumDOF;
00282 for (int i=0; i<modNumDOF; i++)
00283 if ((*modID)(i) < 0)
00284 numFreeDOF--;
00285 return numFreeDOF;
00286 } else
00287 return this->DOF_Group::getNumFreeDOF();
00288 }
00289
00290 int
00291 TransformationDOF_Group::getNumConstrainedDOF(void) const
00292 {
00293 if (modID != 0) {
00294 int numConstr = 0;
00295 for (int i=0; i<modNumDOF; i++)
00296 if ((*modID)(i) < 0)
00297 numConstr++;
00298
00299 return numConstr;
00300 } else
00301 return this->DOF_Group::getNumConstrainedDOF();
00302 }
00303
00304
00305
00306 const Matrix &
00307 TransformationDOF_Group::getTangent(Integrator *theIntegrator)
00308 {
00309 const Matrix &unmodTangent = this->DOF_Group::getTangent(theIntegrator);
00310 Matrix *T = this->getT();
00311 if (T != 0) {
00312 *modTangent = (*T) ^ unmodTangent * (*T);
00313 return *modTangent;
00314
00315 } else
00316 return unmodTangent;
00317 }
00318
00319 const Vector &
00320 TransformationDOF_Group::getUnbalance(Integrator *theIntegrator)
00321 {
00322 const Vector &unmodUnbalance =
00323 this->DOF_Group::getUnbalance(theIntegrator);
00324
00325 Matrix *T = this->getT();
00326 if (T != 0) {
00327 *modUnbalance = (*T) ^ unmodUnbalance;
00328 return *modUnbalance;
00329 } else
00330 return unmodUnbalance;
00331 }
00332
00333
00334 const Vector &
00335 TransformationDOF_Group::getCommittedDisp(void)
00336 {
00337 const Vector &responseC = myNode->getDisp();
00338
00339 if (theMP == 0)
00340 return responseC;
00341 else {
00342 int retainedNode = theMP->getNodeRetained();
00343 Domain *theDomain = myNode->getDomain();
00344 Node *retainedNodePtr = theDomain->getNode(retainedNode);
00345 const Vector &responseR = retainedNodePtr->getDisp();
00346 const ID &retainedDOF = theMP->getRetainedDOFs();
00347 const ID &constrainedDOF = theMP->getConstrainedDOFs();
00348 int numCNodeDOF = myNode->getNumberDOF();
00349 int numRetainedNodeDOF = retainedDOF.Size();
00350
00351 int loc = 0;
00352 for (int i=0; i<numCNodeDOF; i++) {
00353 if (constrainedDOF.getLocation(i) < 0) {
00354 (*modUnbalance)(loc) = responseC(i);
00355 loc++;
00356 }
00357 }
00358 for (int j=0; j<numRetainedNodeDOF; j++) {
00359 int dof = retainedDOF(j);
00360 (*modUnbalance)(loc) = responseR(dof);
00361 loc++;
00362 }
00363
00364 return *modUnbalance;
00365 }
00366 }
00367
00368 const Vector &
00369 TransformationDOF_Group::getCommittedVel(void)
00370 {
00371 const Vector &responseC = myNode->getVel();
00372
00373 if (theMP == 0)
00374 return responseC;
00375 else {
00376 int retainedNode = theMP->getNodeRetained();
00377 Domain *theDomain = myNode->getDomain();
00378 Node *retainedNodePtr = theDomain->getNode(retainedNode);
00379 const Vector &responseR = retainedNodePtr->getVel();
00380 const ID &retainedDOF = theMP->getRetainedDOFs();
00381 const ID &constrainedDOF = theMP->getConstrainedDOFs();
00382 int numCNodeDOF = myNode->getNumberDOF();
00383 int numRetainedNodeDOF = retainedDOF.Size();
00384
00385 int loc = 0;
00386 for (int i=0; i<numCNodeDOF; i++) {
00387 if (constrainedDOF.getLocation(i) < 0) {
00388 (*modUnbalance)(loc) = responseC(i);
00389 loc++;
00390 }
00391 }
00392 for (int j=0; j<numRetainedNodeDOF; j++) {
00393 int dof = retainedDOF(j);
00394 (*modUnbalance)(loc) = responseR(dof);
00395 loc++;
00396 }
00397
00398 return *modUnbalance;
00399 }
00400 }
00401
00402
00403 const Vector &
00404 TransformationDOF_Group::getCommittedAccel(void)
00405 {
00406 const Vector &responseC = myNode->getAccel();
00407
00408 if (theMP == 0)
00409 return responseC;
00410 else {
00411 int retainedNode = theMP->getNodeRetained();
00412 Domain *theDomain = myNode->getDomain();
00413 Node *retainedNodePtr = theDomain->getNode(retainedNode);
00414 const Vector &responseR = retainedNodePtr->getAccel();
00415 const ID &retainedDOF = theMP->getRetainedDOFs();
00416 const ID &constrainedDOF = theMP->getConstrainedDOFs();
00417 int numCNodeDOF = myNode->getNumberDOF();
00418 int numRetainedNodeDOF = retainedDOF.Size();
00419
00420 int loc = 0;
00421 for (int i=0; i<numCNodeDOF; i++) {
00422 if (constrainedDOF.getLocation(i) < 0) {
00423 (*modUnbalance)(loc) = responseC(i);
00424 loc++;
00425 }
00426 }
00427 for (int j=0; j<numRetainedNodeDOF; j++) {
00428 int dof = retainedDOF(j);
00429 (*modUnbalance)(loc) = responseR(dof);
00430 loc++;
00431 }
00432
00433 return *modUnbalance;
00434 }
00435 }
00436
00437
00438
00439
00440
00441 void
00442 TransformationDOF_Group::setNodeDisp(const Vector &u)
00443 {
00444
00445 if (theMP == 0) {
00446 this->DOF_Group::setNodeDisp(u);
00447 return;
00448 }
00449
00450 const ID &theID = this->getID();
00451 for (int i=0; i<modNumDOF; i++) {
00452 int loc = theID(i);
00453 if (loc >= 0)
00454 (*modUnbalance)(i) = u(loc);
00455
00456 }
00457 Matrix *T = this->getT();
00458 if (T != 0) {
00459 *unbalance = (*T) * (*modUnbalance);
00460 myNode->setTrialDisp(*unbalance);
00461 } else
00462 myNode->setTrialDisp(*modUnbalance);
00463 }
00464
00465 void
00466 TransformationDOF_Group::setNodeVel(const Vector &u)
00467 {
00468
00469 if (theMP == 0) {
00470 this->DOF_Group::setNodeVel(u);
00471 return;
00472 }
00473
00474 const ID &theID = this->getID();
00475 for (int i=0; i<modNumDOF; i++) {
00476 int loc = theID(i);
00477 if (loc >= 0)
00478 (*modUnbalance)(i) = u(loc);
00479 else
00480 (*modUnbalance)(i) = 0.0;
00481
00482 }
00483 Matrix *T = this->getT();
00484 if (T != 0) {
00485 *unbalance = (*T) * (*modUnbalance);
00486 myNode->setTrialVel(*unbalance);
00487 } else
00488 myNode->setTrialVel(*modUnbalance);
00489 }
00490
00491
00492 void
00493 TransformationDOF_Group::setNodeAccel(const Vector &u)
00494 {
00495
00496 if (theMP == 0) {
00497 this->DOF_Group::setNodeAccel(u);
00498 return;
00499 }
00500
00501 const ID &theID = this->getID();
00502 for (int i=0; i<modNumDOF; i++) {
00503 int loc = theID(i);
00504 if (loc >= 0)
00505 (*modUnbalance)(i) = u(loc);
00506 else
00507 (*modUnbalance)(i) = 0.0;
00508
00509 }
00510 Matrix *T = this->getT();
00511 if (T != 0) {
00512 *unbalance = (*T) * (*modUnbalance);
00513 myNode->setTrialAccel(*unbalance);
00514 } else
00515 myNode->setTrialAccel(*modUnbalance);
00516 }
00517
00518
00519
00520
00521
00522
00523 void
00524 TransformationDOF_Group::incrNodeDisp(const Vector &u)
00525 {
00526
00527 if (theMP == 0) {
00528 this->DOF_Group::incrNodeDisp(u);
00529 return;
00530 }
00531
00532 const ID &theID = this->getID();
00533
00534 for (int i=0; i<modNumDOF; i++) {
00535 int loc = theID(i);
00536 if (loc >= 0)
00537 (*modUnbalance)(i) = u(loc);
00538 else
00539 (*modUnbalance)(i) = 0.0;
00540 }
00541
00542 Matrix *T = this->getT();
00543 if (T != 0) {
00544 *unbalance = (*T) * (*modUnbalance);
00545 myNode->incrTrialDisp(*unbalance);
00546 } else
00547 myNode->incrTrialDisp(*modUnbalance);
00548 }
00549
00550
00551 void
00552 TransformationDOF_Group::incrNodeVel(const Vector &u)
00553 {
00554
00555 if (theMP == 0) {
00556 this->DOF_Group::incrNodeVel(u);
00557 return;
00558 }
00559
00560 const ID &theID = this->getID();
00561 for (int i=0; i<modNumDOF; i++) {
00562 int loc = theID(i);
00563 if (loc >= 0)
00564 (*modUnbalance)(i) = u(loc);
00565 else
00566 (*modUnbalance)(i) = 0.0;
00567 }
00568 Matrix *T = this->getT();
00569 if (T != 0) {
00570 *unbalance = (*T) * (*modUnbalance);
00571 myNode->incrTrialVel(*unbalance);
00572 } else
00573 myNode->incrTrialVel(*modUnbalance);
00574 }
00575
00576
00577 void
00578 TransformationDOF_Group::incrNodeAccel(const Vector &u)
00579 {
00580
00581 if (theMP == 0) {
00582 this->DOF_Group::incrNodeAccel(u);
00583 return;
00584 }
00585
00586 const ID &theID = this->getID();
00587 for (int i=0; i<modNumDOF; i++) {
00588 int loc = theID(i);
00589 if (loc >= 0)
00590 (*modUnbalance)(i) = u(loc);
00591 else
00592 (*modUnbalance)(i) = 0.0;
00593 }
00594 Matrix *T = this->getT();
00595 if (T != 0) {
00596 *unbalance = (*T) * (*modUnbalance);
00597 myNode->incrTrialAccel(*unbalance);
00598 } else
00599 myNode->incrTrialAccel(*modUnbalance);
00600 }
00601
00602
00603 void
00604 TransformationDOF_Group::setEigenvector(int mode, const Vector &u)
00605 {
00606
00607 if (theMP == 0) {
00608 this->DOF_Group::setNodeDisp(u);
00609 return;
00610 }
00611
00612 const ID &theID = this->getID();
00613 for (int i=0; i<modNumDOF; i++) {
00614 int loc = theID(i);
00615 if (loc >= 0)
00616 (*modUnbalance)(i) = u(loc);
00617
00618 }
00619 Matrix *T = this->getT();
00620 if (T != 0) {
00621 *unbalance = (*T) * (*modUnbalance);
00622 myNode->setEigenvector(mode, *unbalance);
00623 } else
00624 myNode->setEigenvector(mode, *modUnbalance);
00625 }
00626
00627
00628 Matrix *
00629 TransformationDOF_Group::getT(void)
00630 {
00631 if (theMP == 0)
00632 return 0;
00633
00634 if (theMP->isTimeVarying() == false) {
00635 return Trans;
00636 }
00637
00638 int numNodalDOF = this->DOF_Group::getNumDOF();
00639
00640 const ID &constrainedDOF = theMP->getConstrainedDOFs();
00641 int numNodalDOFConstrained = constrainedDOF.Size();
00642 int numRetainedDOF = numNodalDOF - numNodalDOFConstrained;
00643
00644
00645 Trans->Zero();
00646 const Matrix &Ccr = theMP->getConstraint();
00647 int col = 0;
00648 for (int i=0; i<numNodalDOF; i++) {
00649 int loc = constrainedDOF.getLocation(i);
00650 if (loc < 0) {
00651 (*Trans)(i,col) = 1.0;
00652 col++;
00653 } else {
00654 for (int j=0; j<numRetainedDOF; j++)
00655 (*Trans)(i,j+numRetainedDOF) = Ccr(loc,j);
00656 }
00657 }
00658 return Trans;
00659 }
00660
00661
00662 int
00663 TransformationDOF_Group::doneID(void)
00664 {
00665
00666 if (theMP == 0)
00667 return 0;
00668
00669
00670 int numNodalDOF = this->getNumDOF();
00671 const ID &retainedDOF = theMP->getRetainedDOFs();
00672 const ID &constrainedDOF = theMP->getConstrainedDOFs();
00673 int numNodalDOFConstrained = constrainedDOF.Size();
00674 int numRetainedDOF = numNodalDOF - numNodalDOFConstrained;
00675 int numRetainedNodeDOF = retainedDOF.Size();
00676
00677 int retainedNode = theMP->getNodeRetained();
00678 Domain *theDomain = myNode->getDomain();
00679 Node *retainedNodePtr = theDomain->getNode(retainedNode);
00680 DOF_Group *retainedGroup = retainedNodePtr->getDOF_GroupPtr();
00681 const ID &otherID = retainedGroup->getID();
00682
00683
00684 for (int i=0; i<numRetainedNodeDOF; i++) {
00685 int dof = retainedDOF(i);
00686 int id = otherID(dof);
00687 (*modID)(i+numRetainedDOF) = id;
00688 }
00689
00690
00691 if (theMP->isTimeVarying() == false) {
00692 Trans->Zero();
00693 const Matrix &Ccr = theMP->getConstraint();
00694 int col = 0;
00695 for (int i=0; i<numNodalDOF; i++) {
00696 int loc = constrainedDOF.getLocation(i);
00697 if (loc < 0) {
00698 (*Trans)(i,col) = 1.0;
00699 col++;
00700 } else {
00701 for (int j=0; j<numRetainedNodeDOF; j++)
00702 (*Trans)(i,j+numRetainedDOF) = Ccr(loc,j);
00703 }
00704 }
00705 }
00706
00707
00708 if (modNumDOF <= MAX_NUM_DOF) {
00709
00710 if (modVectors[modNumDOF] == 0) {
00711
00712 modVectors[modNumDOF] = new Vector(modNumDOF);
00713 modMatrices[modNumDOF] = new Matrix(modNumDOF,modNumDOF);
00714 modUnbalance = modVectors[modNumDOF];
00715 modTangent = modMatrices[modNumDOF];
00716 if (modUnbalance == 0 || modUnbalance->Size() != modNumDOF ||
00717 modTangent == 0 || modTangent->noCols() != modNumDOF) {
00718 cerr << "DOF_Group::DOF_Group(Node *) ";
00719 cerr << " ran out of memory for vector/Matrix of size :";
00720 cerr << modNumDOF << endl;
00721 exit(-1);
00722 }
00723 } else {
00724 modUnbalance = modVectors[modNumDOF];
00725 modTangent = modMatrices[modNumDOF];
00726 }
00727 } else {
00728
00729 modUnbalance = new Vector(modNumDOF);
00730 modTangent = new Matrix(modNumDOF, modNumDOF);
00731 if (modUnbalance == 0 || modUnbalance->Size() ==0 ||
00732 modTangent ==0 || modTangent->noRows() ==0) {
00733
00734 cerr << "DOF_Group::DOF_Group(Node *) ";
00735 cerr << " ran out of memory for vector/Matrix of size :";
00736 cerr << modNumDOF << endl;
00737 exit(-1);
00738 }
00739 }
00740 return 0;
00741 }
00742
00743 int
00744 TransformationDOF_Group::addSP_Constraint(SP_Constraint &theSP)
00745 {
00746
00747 int dof = theSP.getDOF_Number();
00748 theSPs[dof] = &theSP;
00749
00750
00751 if (theMP == 0)
00752 this->setID(dof,-1);
00753 else {
00754 const ID &constrainedDOF = theMP->getConstrainedDOFs();
00755 int loc = 0;
00756 for (int i=0; i<dof; i++)
00757 if (constrainedDOF.getLocation(i) < 0)
00758 loc++;
00759 this->setID(loc,-1);
00760 }
00761 return 0;
00762 }
00763
00764 int
00765 TransformationDOF_Group::enforceSPs(void)
00766 {
00767 Vector trialDisp(myNode->getTrialDisp());
00768 int numDof = myNode->getNumberDOF();
00769 for (int i=0; i<numDof; i++)
00770 if (theSPs[i] != 0) {
00771 double value = theSPs[i]->getValue();
00772 trialDisp(i) = value;
00773 }
00774 myNode->setTrialDisp(trialDisp);
00775
00776 return 0;
00777 }
00778
00779 void
00780 TransformationDOF_Group::addM_Force(const Vector &Udotdot, double fact)
00781 {
00782
00783 if (theMP == 0 || modID == 0) {
00784 this->DOF_Group::addM_Force(Udotdot, fact);
00785 return;
00786 }
00787
00788 for (int i=0; i<modNumDOF; i++) {
00789 int loc = (*modID)(i);
00790 if (loc >= 0)
00791 (*modUnbalance)(i) = Udotdot(loc);
00792 else
00793 (*modUnbalance)(i) = 0.0;
00794 }
00795
00796 Vector unmod(Trans->noRows());
00797 unmod = (*Trans) * (*modUnbalance);
00798 this->addLocalM_Force(unmod,fact);
00799 }