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 #include <TransformationDOF_Group.h>
00036 #include <stdlib.h>
00037
00038 #include <Domain.h>
00039 #include <Node.h>
00040 #include <Vector.h>
00041 #include <Matrix.h>
00042 #include <TransientIntegrator.h>
00043 #include <MP_Constraint.h>
00044 #include <SP_Constraint.h>
00045 #include <SP_ConstraintIter.h>
00046 #include <TransformationConstraintHandler.h>
00047
00048 #define MAX_NUM_DOF 16
00049
00050
00051 Matrix **TransformationDOF_Group::modMatrices;
00052 Vector **TransformationDOF_Group::modVectors;
00053 int TransformationDOF_Group::numTransDOFs(0);
00054 TransformationConstraintHandler *TransformationDOF_Group::theHandler = 0;
00055
00056 TransformationDOF_Group::TransformationDOF_Group(int tag, Node *node,
00057 MP_Constraint *mp,
00058 TransformationConstraintHandler *theTHandler)
00059 :DOF_Group(tag,node),
00060 theMP(mp),Trans(0),modTangent(0),modUnbalance(0),modID(0),theSPs(0)
00061 {
00062
00063 int numNodalDOF = node->getNumberDOF();
00064 const ID &retainedDOF = mp->getRetainedDOFs();
00065 const ID &constrainedDOF = mp->getConstrainedDOFs();
00066 int numNodalDOFConstrained = constrainedDOF.Size();
00067 int numConstrainedNodeRetainedDOF = numNodalDOF - numNodalDOFConstrained;
00068 int numRetainedNodeDOF = retainedDOF.Size();
00069
00070 modNumDOF = numConstrainedNodeRetainedDOF + numRetainedNodeDOF;
00071
00072
00073 theSPs = new SP_Constraint *[numNodalDOF];
00074 for (int ii=0; ii<numNodalDOF; ii++)
00075 theSPs[ii] = 0;
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 modID = new ID(modNumDOF);
00097 Trans = new Matrix(numNodalDOF, modNumDOF);
00098
00099 if (modID == 0 || modID->Size() == 0 ||
00100 Trans == 0 || Trans->noRows() == 0) {
00101
00102 opserr << "FATAL TransformationDOF_Group::TransformationDOF_Group() -";
00103 opserr << " ran out of memory for size: " << modNumDOF << endln;
00104 exit(-1);
00105 }
00106
00107
00108 for (int i=0; i<numConstrainedNodeRetainedDOF; i++)
00109 (*modID)(i) = -2;
00110
00111
00112 for (int j=numConstrainedNodeRetainedDOF; j<modNumDOF; j++)
00113 (*modID)(j) = -1;
00114
00115
00116
00117 for (int k=numConstrainedNodeRetainedDOF; k<modNumDOF; k++)
00118 (*modID)(k) = -1;
00119
00120
00121
00122
00123 if (numTransDOFs == 0) {
00124 modMatrices = new Matrix *[MAX_NUM_DOF+1];
00125 modVectors = new Vector *[MAX_NUM_DOF+1];
00126
00127 if (modMatrices == 0 || modVectors == 0) {
00128 opserr << "TransformationDOF_Group::TransformationDOF_Group(Node *) ";
00129 opserr << " ran out of memory";
00130 }
00131 for (int i=0; i<MAX_NUM_DOF; i++) {
00132 modMatrices[i] = 0;
00133 modVectors[i] = 0;
00134 }
00135 }
00136
00137
00138 if (modNumDOF <= MAX_NUM_DOF) {
00139
00140 if (modVectors[modNumDOF] == 0) {
00141
00142 modVectors[modNumDOF] = new Vector(modNumDOF);
00143 modMatrices[modNumDOF] = new Matrix(modNumDOF,modNumDOF);
00144 modUnbalance = modVectors[modNumDOF];
00145 modTangent = modMatrices[modNumDOF];
00146 if (modUnbalance == 0 || modUnbalance->Size() != modNumDOF ||
00147 modTangent == 0 || modTangent->noCols() != modNumDOF) {
00148 opserr << "TransformationDOF_Group::TransformationDOF_Group(Node *) ";
00149 opserr << " ran out of memory for vector/Matrix of size :";
00150 opserr << modNumDOF << endln;
00151 exit(-1);
00152 }
00153 } else {
00154 modUnbalance = modVectors[modNumDOF];
00155 modTangent = modMatrices[modNumDOF];
00156 }
00157 } else {
00158
00159 modUnbalance = new Vector(modNumDOF);
00160 modTangent = new Matrix(modNumDOF, modNumDOF);
00161 if (modUnbalance == 0 || modTangent ==0 ||
00162 modTangent ==0 || modTangent->noRows() ==0) {
00163
00164 opserr << "TransformationDOF_Group::TransformationDOF_Group(Node *) ";
00165 opserr << " ran out of memory for vector/Matrix of size :";
00166 opserr << modNumDOF << endln;
00167 exit(-1);
00168 }
00169 }
00170
00171 numTransDOFs++;
00172 theHandler = theTHandler;
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,
00186 Node *node,
00187 TransformationConstraintHandler *theTHandler)
00188 :DOF_Group(tag,node),
00189 theMP(0),Trans(0),modTangent(0),modUnbalance(0),modID(0),theSPs(0)
00190 {
00191 modNumDOF = node->getNumberDOF();
00192
00193 theSPs = new SP_Constraint *[modNumDOF];
00194 for (int i=0; i<modNumDOF; i++)
00195 theSPs[i] = 0;
00196
00197
00198 Domain *theDomain=node->getDomain();
00199 int nodeTag = node->getTag();
00200 SP_ConstraintIter &theSPIter = theDomain->getSPs();
00201 SP_Constraint *sp;
00202 while ((sp = theSPIter()) != 0) {
00203 if (sp->getNodeTag() == nodeTag) {
00204 int dof = sp->getDOF_Number();
00205 theSPs[dof] = sp;
00206 }
00207 }
00208
00209
00210
00211
00212 if (numTransDOFs == 0) {
00213 modMatrices = new Matrix *[MAX_NUM_DOF+1];
00214 modVectors = new Vector *[MAX_NUM_DOF+1];
00215
00216 if (modMatrices == 0 || modVectors == 0) {
00217 opserr << "TransformationDOF_Group::TransformationDOF_Group(Node *) ";
00218 opserr << " ran out of memory";
00219 }
00220 for (int i=0; i<MAX_NUM_DOF; i++) {
00221 modMatrices[i] = 0;
00222 modVectors[i] = 0;
00223 }
00224 }
00225
00226 numTransDOFs++;
00227 theHandler = theTHandler;
00228 }
00229
00230
00231
00232
00233
00234 TransformationDOF_Group::~TransformationDOF_Group()
00235 {
00236 numTransDOFs--;
00237
00238
00239 if (modNumDOF > MAX_NUM_DOF) {
00240 if (modTangent != 0) delete modTangent;
00241 if (modUnbalance != 0) delete modUnbalance;
00242 }
00243
00244 if (modID != 0) delete modID;
00245 if (Trans != 0) delete Trans;
00246 if (theSPs != 0) delete [] theSPs;
00247
00248
00249
00250 if (numTransDOFs == 0) {
00251 for (int i=0; i<MAX_NUM_DOF; i++) {
00252 if (modVectors[i] != 0)
00253 delete modVectors[i];
00254 if (modMatrices[i] != 0)
00255 delete modMatrices[i];
00256 }
00257 delete [] modMatrices;
00258 delete [] modVectors;
00259 }
00260 }
00261
00262
00263 const ID &
00264 TransformationDOF_Group::getID(void) const
00265 {
00266 if (modID != 0)
00267 return *modID;
00268 else
00269 return this->DOF_Group::getID();
00270 }
00271
00272 int
00273 TransformationDOF_Group::getNumDOF(void) const
00274 {
00275 return modNumDOF;
00276 }
00277
00278
00279 int
00280 TransformationDOF_Group::getNumFreeDOF(void) const
00281 {
00282 if (modID != 0) {
00283 int numFreeDOF = modNumDOF;
00284 for (int i=0; i<modNumDOF; i++)
00285 if ((*modID)(i) == -1)
00286 numFreeDOF--;
00287 return numFreeDOF;
00288 } else
00289 return this->DOF_Group::getNumFreeDOF();
00290 }
00291
00292 int
00293 TransformationDOF_Group::getNumConstrainedDOF(void) const
00294 {
00295 if (modID != 0) {
00296 int numConstr = 0;
00297 for (int i=0; i<modNumDOF; i++)
00298 if ((*modID)(i) < 0)
00299 numConstr++;
00300
00301 return numConstr;
00302 } else
00303 return this->DOF_Group::getNumConstrainedDOF();
00304 }
00305
00306
00307
00308 const Matrix &
00309 TransformationDOF_Group::getTangent(Integrator *theIntegrator)
00310 {
00311
00312
00313 const Matrix &unmodTangent = this->DOF_Group::getTangent(theIntegrator);
00314 Matrix *T = this->getT();
00315 if (T != 0) {
00316
00317 modTangent->addMatrixTripleProduct(0.0, *T, unmodTangent, 1.0);
00318 return *modTangent;
00319
00320 } else
00321 return unmodTangent;
00322 }
00323
00324 const Vector &
00325 TransformationDOF_Group::getUnbalance(Integrator *theIntegrator)
00326 {
00327 const Vector &unmodUnbalance =
00328 this->DOF_Group::getUnbalance(theIntegrator);
00329
00330 Matrix *T = this->getT();
00331 if (T != 0) {
00332
00333 modUnbalance->addMatrixTransposeVector(0.0, *T, unmodUnbalance, 1.0);
00334 return *modUnbalance;
00335 } else
00336 return unmodUnbalance;
00337 }
00338
00339
00340 const Vector &
00341 TransformationDOF_Group::getCommittedDisp(void)
00342 {
00343 const Vector &responseC = myNode->getDisp();
00344
00345 if (theMP == 0)
00346 return responseC;
00347 else {
00348 int retainedNode = theMP->getNodeRetained();
00349 Domain *theDomain = myNode->getDomain();
00350 Node *retainedNodePtr = theDomain->getNode(retainedNode);
00351 const Vector &responseR = retainedNodePtr->getDisp();
00352 const ID &retainedDOF = theMP->getRetainedDOFs();
00353 const ID &constrainedDOF = theMP->getConstrainedDOFs();
00354 int numCNodeDOF = myNode->getNumberDOF();
00355 int numRetainedNodeDOF = retainedDOF.Size();
00356
00357 int loc = 0;
00358 for (int i=0; i<numCNodeDOF; i++) {
00359 if (constrainedDOF.getLocation(i) < 0) {
00360 (*modUnbalance)(loc) = responseC(i);
00361 loc++;
00362 }
00363 }
00364 for (int j=0; j<numRetainedNodeDOF; j++) {
00365 int dof = retainedDOF(j);
00366 (*modUnbalance)(loc) = responseR(dof);
00367 loc++;
00368 }
00369
00370 return *modUnbalance;
00371 }
00372 }
00373
00374 const Vector &
00375 TransformationDOF_Group::getCommittedVel(void)
00376 {
00377 const Vector &responseC = myNode->getVel();
00378
00379 if (theMP == 0)
00380 return responseC;
00381 else {
00382 int retainedNode = theMP->getNodeRetained();
00383 Domain *theDomain = myNode->getDomain();
00384 Node *retainedNodePtr = theDomain->getNode(retainedNode);
00385 const Vector &responseR = retainedNodePtr->getVel();
00386 const ID &retainedDOF = theMP->getRetainedDOFs();
00387 const ID &constrainedDOF = theMP->getConstrainedDOFs();
00388 int numCNodeDOF = myNode->getNumberDOF();
00389 int numRetainedNodeDOF = retainedDOF.Size();
00390
00391 int loc = 0;
00392 for (int i=0; i<numCNodeDOF; i++) {
00393 if (constrainedDOF.getLocation(i) < 0) {
00394 (*modUnbalance)(loc) = responseC(i);
00395 loc++;
00396 }
00397 }
00398 for (int j=0; j<numRetainedNodeDOF; j++) {
00399 int dof = retainedDOF(j);
00400 (*modUnbalance)(loc) = responseR(dof);
00401 loc++;
00402 }
00403
00404 return *modUnbalance;
00405 }
00406 }
00407
00408
00409 const Vector &
00410 TransformationDOF_Group::getCommittedAccel(void)
00411 {
00412 const Vector &responseC = myNode->getAccel();
00413
00414 if (theMP == 0)
00415 return responseC;
00416 else {
00417 int retainedNode = theMP->getNodeRetained();
00418 Domain *theDomain = myNode->getDomain();
00419 Node *retainedNodePtr = theDomain->getNode(retainedNode);
00420 const Vector &responseR = retainedNodePtr->getAccel();
00421 const ID &retainedDOF = theMP->getRetainedDOFs();
00422 const ID &constrainedDOF = theMP->getConstrainedDOFs();
00423 int numCNodeDOF = myNode->getNumberDOF();
00424 int numRetainedNodeDOF = retainedDOF.Size();
00425
00426 int loc = 0;
00427 for (int i=0; i<numCNodeDOF; i++) {
00428 if (constrainedDOF.getLocation(i) < 0) {
00429 (*modUnbalance)(loc) = responseC(i);
00430 loc++;
00431 }
00432 }
00433 for (int j=0; j<numRetainedNodeDOF; j++) {
00434 int dof = retainedDOF(j);
00435 (*modUnbalance)(loc) = responseR(dof);
00436 loc++;
00437 }
00438
00439 return *modUnbalance;
00440 }
00441 }
00442
00443
00444
00445
00446
00447 void
00448 TransformationDOF_Group::setNodeDisp(const Vector &u)
00449 {
00450
00451 if (theMP == 0) {
00452 this->DOF_Group::setNodeDisp(u);
00453 return;
00454 }
00455
00456 const ID &theID = this->getID();
00457 for (int i=0; i<modNumDOF; i++) {
00458 int loc = theID(i);
00459 if (loc >= 0)
00460 (*modUnbalance)(i) = u(loc);
00461 else
00462 (*modUnbalance)(i) = 0.0;
00463
00464
00465 }
00466 Matrix *T = this->getT();
00467 if (T != 0) {
00468
00469
00470 unbalance->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00471 myNode->setTrialDisp(*unbalance);
00472
00473 } else
00474 myNode->setTrialDisp(*modUnbalance);
00475 }
00476
00477 void
00478 TransformationDOF_Group::setNodeVel(const Vector &u)
00479 {
00480
00481 if (theMP == 0) {
00482 this->DOF_Group::setNodeVel(u);
00483 return;
00484 }
00485
00486 const ID &theID = this->getID();
00487 for (int i=0; i<modNumDOF; i++) {
00488 int loc = theID(i);
00489 if (loc >= 0)
00490 (*modUnbalance)(i) = u(loc);
00491 else
00492 (*modUnbalance)(i) = 0.0;
00493
00494 }
00495 Matrix *T = this->getT();
00496 if (T != 0) {
00497
00498 unbalance->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00499 myNode->setTrialVel(*unbalance);
00500 } else
00501 myNode->setTrialVel(*modUnbalance);
00502 }
00503
00504
00505 void
00506 TransformationDOF_Group::setNodeAccel(const Vector &u)
00507 {
00508
00509 if (theMP == 0) {
00510 this->DOF_Group::setNodeAccel(u);
00511 return;
00512 }
00513
00514 const ID &theID = this->getID();
00515 for (int i=0; i<modNumDOF; i++) {
00516 int loc = theID(i);
00517 if (loc >= 0)
00518 (*modUnbalance)(i) = u(loc);
00519 else
00520 (*modUnbalance)(i) = 0.0;
00521
00522 }
00523 Matrix *T = this->getT();
00524 if (T != 0) {
00525
00526 unbalance->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00527 myNode->setTrialAccel(*unbalance);
00528 } else
00529 myNode->setTrialAccel(*modUnbalance);
00530 }
00531
00532
00533
00534
00535
00536
00537 void
00538 TransformationDOF_Group::incrNodeDisp(const Vector &u)
00539 {
00540
00541 if (theMP == 0) {
00542 this->DOF_Group::incrNodeDisp(u);
00543 return;
00544 }
00545
00546 const ID &theID = this->getID();
00547
00548 for (int i=0; i<modNumDOF; i++) {
00549 int loc = theID(i);
00550 if (loc >= 0)
00551 (*modUnbalance)(i) = u(loc);
00552 else
00553 (*modUnbalance)(i) = 0.0;
00554 }
00555
00556 Matrix *T = this->getT();
00557 if (T != 0) {
00558
00559 unbalance->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00560 myNode->incrTrialDisp(*unbalance);
00561 } else
00562 myNode->incrTrialDisp(*modUnbalance);
00563 }
00564
00565
00566 void
00567 TransformationDOF_Group::incrNodeVel(const Vector &u)
00568 {
00569
00570 if (theMP == 0) {
00571 this->DOF_Group::incrNodeVel(u);
00572 return;
00573 }
00574
00575 const ID &theID = this->getID();
00576 for (int i=0; i<modNumDOF; i++) {
00577 int loc = theID(i);
00578 if (loc >= 0)
00579 (*modUnbalance)(i) = u(loc);
00580 else
00581 (*modUnbalance)(i) = 0.0;
00582 }
00583 Matrix *T = this->getT();
00584 if (T != 0) {
00585
00586 unbalance->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00587 myNode->incrTrialVel(*unbalance);
00588 } else
00589 myNode->incrTrialVel(*modUnbalance);
00590 }
00591
00592
00593 void
00594 TransformationDOF_Group::incrNodeAccel(const Vector &u)
00595 {
00596
00597 if (theMP == 0) {
00598 this->DOF_Group::incrNodeAccel(u);
00599 return;
00600 }
00601
00602 const ID &theID = this->getID();
00603 for (int i=0; i<modNumDOF; i++) {
00604 int loc = theID(i);
00605 if (loc >= 0)
00606 (*modUnbalance)(i) = u(loc);
00607 else
00608 (*modUnbalance)(i) = 0.0;
00609 }
00610 Matrix *T = this->getT();
00611 if (T != 0) {
00612
00613 unbalance->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00614 myNode->incrTrialAccel(*unbalance);
00615 } else
00616 myNode->incrTrialAccel(*modUnbalance);
00617 }
00618
00619
00620 void
00621 TransformationDOF_Group::setEigenvector(int mode, const Vector &u)
00622 {
00623
00624 if (theMP == 0) {
00625 this->DOF_Group::setEigenvector(mode, u);
00626 return;
00627 }
00628
00629 const ID &theID = this->getID();
00630 for (int i=0; i<modNumDOF; i++) {
00631 int loc = theID(i);
00632 if (loc >= 0)
00633 (*modUnbalance)(i) = u(loc);
00634
00635 }
00636 Matrix *T = this->getT();
00637 if (T != 0) {
00638
00639 unbalance->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00640 myNode->setEigenvector(mode, *unbalance);
00641 } else
00642 myNode->setEigenvector(mode, *modUnbalance);
00643 }
00644
00645
00646 Matrix *
00647 TransformationDOF_Group::getT(void)
00648 {
00649 if (theMP == 0)
00650 return 0;
00651
00652 if (theMP->isTimeVarying() == false) {
00653 return Trans;
00654 }
00655
00656 int numNodalDOF = myNode->getNumberDOF();
00657 const ID &retainedDOF = theMP->getRetainedDOFs();
00658 const ID &constrainedDOF = theMP->getConstrainedDOFs();
00659 int numNodalDOFConstrained = constrainedDOF.Size();
00660 int numRetainedDOF = numNodalDOF - numNodalDOFConstrained;
00661 int numRetainedNodeDOF = retainedDOF.Size();
00662
00663 Trans->Zero();
00664 const Matrix &Ccr = theMP->getConstraint();
00665 int col = 0;
00666 for (int i=0; i<numNodalDOF; i++) {
00667 int loc = constrainedDOF.getLocation(i);
00668 if (loc < 0) {
00669 (*Trans)(i,col) = 1.0;
00670 col++;
00671 } else {
00672 for (int j=0; j<numRetainedNodeDOF; j++)
00673 (*Trans)(i,j+numRetainedDOF) = Ccr(loc,j);
00674 }
00675 }
00676
00677 return Trans;
00678 }
00679
00680
00681 int
00682 TransformationDOF_Group::doneID(void)
00683 {
00684
00685 if (theMP == 0)
00686 return 0;
00687
00688
00689 int numNodalDOF = myNode->getNumberDOF();
00690 const ID &retainedDOF = theMP->getRetainedDOFs();
00691 const ID &constrainedDOF = theMP->getConstrainedDOFs();
00692 int numNodalDOFConstrained = constrainedDOF.Size();
00693 int numRetainedDOF = numNodalDOF - numNodalDOFConstrained;
00694 int numRetainedNodeDOF = retainedDOF.Size();
00695
00696 int retainedNode = theMP->getNodeRetained();
00697 Domain *theDomain = myNode->getDomain();
00698 Node *retainedNodePtr = theDomain->getNode(retainedNode);
00699 DOF_Group *retainedGroup = retainedNodePtr->getDOF_GroupPtr();
00700 const ID &otherID = retainedGroup->getID();
00701
00702
00703 for (int i=0; i<numRetainedNodeDOF; i++) {
00704 int dof = retainedDOF(i);
00705 int id = otherID(dof);
00706 (*modID)(i+numRetainedDOF) = id;
00707 }
00708
00709
00710 if (theMP->isTimeVarying() == false) {
00711 Trans->Zero();
00712 const Matrix &Ccr = theMP->getConstraint();
00713 int col = 0;
00714 for (int i=0; i<numNodalDOF; i++) {
00715 int loc = constrainedDOF.getLocation(i);
00716 if (loc < 0) {
00717 (*Trans)(i,col) = 1.0;
00718 col++;
00719 } else {
00720 for (int j=0; j<numRetainedNodeDOF; j++)
00721 (*Trans)(i,j+numRetainedDOF) = Ccr(loc,j);
00722 }
00723 }
00724 }
00725
00726
00727 if (modNumDOF <= MAX_NUM_DOF) {
00728
00729 if (modVectors[modNumDOF] == 0) {
00730
00731 modVectors[modNumDOF] = new Vector(modNumDOF);
00732 modMatrices[modNumDOF] = new Matrix(modNumDOF,modNumDOF);
00733 modUnbalance = modVectors[modNumDOF];
00734 modTangent = modMatrices[modNumDOF];
00735 if (modUnbalance == 0 || modUnbalance->Size() != modNumDOF ||
00736 modTangent == 0 || modTangent->noCols() != modNumDOF) {
00737 opserr << "DOF_Group::DOF_Group(Node *) ";
00738 opserr << " ran out of memory for vector/Matrix of size :";
00739 opserr << modNumDOF << endln;
00740 exit(-1);
00741 }
00742 } else {
00743 modUnbalance = modVectors[modNumDOF];
00744 modTangent = modMatrices[modNumDOF];
00745 }
00746 } else {
00747
00748 modUnbalance = new Vector(modNumDOF);
00749 modTangent = new Matrix(modNumDOF, modNumDOF);
00750 if (modUnbalance == 0 || modUnbalance->Size() ==0 ||
00751 modTangent ==0 || modTangent->noRows() ==0) {
00752
00753 opserr << "DOF_Group::DOF_Group(Node *) ";
00754 opserr << " ran out of memory for vector/Matrix of size :";
00755 opserr << modNumDOF << endln;
00756 exit(-1);
00757 }
00758 }
00759 return 0;
00760 }
00761
00762 int
00763 TransformationDOF_Group::addSP_Constraint(SP_Constraint &theSP)
00764 {
00765
00766 int dof = theSP.getDOF_Number();
00767 theSPs[dof] = &theSP;
00768
00769
00770 if (theMP == 0)
00771 this->setID(dof,-1);
00772 else {
00773 const ID &constrainedDOF = theMP->getConstrainedDOFs();
00774 int loc = 0;
00775 for (int i=0; i<dof; i++)
00776 if (constrainedDOF.getLocation(i) < 0)
00777 loc++;
00778 this->setID(loc,-1);
00779 }
00780 return 0;
00781 }
00782
00783 int
00784 TransformationDOF_Group::enforceSPs(void)
00785 {
00786 int numDof = myNode->getNumberDOF();
00787 for (int i=0; i<numDof; i++)
00788 if (theSPs[i] != 0) {
00789 double value = theSPs[i]->getValue();
00790 myNode->setTrialDisp(value, i);
00791 }
00792
00793 return 0;
00794 }
00795
00796 void
00797 TransformationDOF_Group::addM_Force(const Vector &Udotdot, double fact)
00798 {
00799
00800 if (theMP == 0 || modID == 0) {
00801 this->DOF_Group::addM_Force(Udotdot, fact);
00802 return;
00803 }
00804
00805 for (int i=0; i<modNumDOF; i++) {
00806 int loc = (*modID)(i);
00807 if (loc >= 0)
00808 (*modUnbalance)(i) = Udotdot(loc);
00809 else
00810 (*modUnbalance)(i) = 0.0;
00811 }
00812
00813 Vector unmod(Trans->noRows());
00814
00815 unmod.addMatrixVector(0.0, *Trans, *modUnbalance, 1.0);
00816 this->addLocalM_Force(unmod, fact);
00817 }
00818
00819
00820 const Vector &
00821 TransformationDOF_Group::getM_Force(const Vector &Udotdot, double fact)
00822 {
00823
00824 if (theMP == 0 || modID == 0) {
00825 return this->DOF_Group::getM_Force(Udotdot, fact);
00826 }
00827
00828 this->DOF_Group::zeroTangent();
00829 this->DOF_Group::addMtoTang();
00830 const Matrix &unmodTangent = this->DOF_Group::getTangent(0);
00831
00832
00833 Vector data(modNumDOF);
00834 for (int i=0; i<modNumDOF; i++) {
00835 int loc = (*modID)(i);
00836 if (loc >= 0)
00837 data(i) = Udotdot(loc);
00838 else
00839 data(i) = 0.0;
00840 }
00841
00842 Matrix *T = this->getT();
00843 if (T != 0) {
00844
00845 modTangent->addMatrixTripleProduct(0.0, *T, unmodTangent, 1.0);
00846 modUnbalance->addMatrixVector(0.0, *modTangent, data, 1.0);
00847
00848 return *modUnbalance;
00849 } else {
00850 modUnbalance->addMatrixVector(0.0, unmodTangent, data, 1.0);
00851 return *modUnbalance;
00852 }
00853 }
00854
00855 const Vector &
00856 TransformationDOF_Group::getC_Force(const Vector &Udotdot, double fact)
00857 {
00858 opserr << "TransformationDOF_Group::getC_Force() - not yet implemented\n";
00859 return *modUnbalance;
00860 }
00861
00862 const Vector &
00863 TransformationDOF_Group::getTangForce(const Vector &Udotdot, double fact)
00864 {
00865 opserr << "TransformationDOF_Group::getTangForce() - not yet implemented\n";
00866 return *modUnbalance;
00867 }
00868
00869
00870
00871
00872 const Vector &
00873 TransformationDOF_Group::getDispSensitivity(int gradNumber)
00874 {
00875 const Vector &result = this->DOF_Group::getDispSensitivity(gradNumber);
00876
00877 Matrix *T = this->getT();
00878 if (T != 0) {
00879
00880 modUnbalance->addMatrixTransposeVector(0.0, *T, result, 1.0);
00881 return *modUnbalance;
00882 } else
00883 return result;
00884
00885 }
00886
00887 const Vector &
00888 TransformationDOF_Group::getVelSensitivity(int gradNumber)
00889 {
00890 const Vector &result = this->DOF_Group::getVelSensitivity(gradNumber);
00891
00892 Matrix *T = this->getT();
00893 if (T != 0) {
00894
00895 modUnbalance->addMatrixTransposeVector(0.0, *T, result, 1.0);
00896 return *modUnbalance;
00897 } else
00898 return result;
00899 }
00900
00901 const Vector &
00902 TransformationDOF_Group::getAccSensitivity(int gradNumber)
00903 {
00904 const Vector &result = this->DOF_Group::getAccSensitivity(gradNumber);
00905
00906 Matrix *T = this->getT();
00907 if (T != 0) {
00908
00909 modUnbalance->addMatrixTransposeVector(0.0, *T, result, 1.0);
00910 return *modUnbalance;
00911 } else
00912 return result;
00913 }
00914
00915
00916
00917 int
00918 TransformationDOF_Group::saveSensitivity(Vector *u,Vector *udot,Vector *udotdot, int gradNum,int numGrads)
00919 {
00920
00921 if (theMP == 0) {
00922 return this->DOF_Group::saveSensitivity(u, udot, udotdot, gradNum, numGrads);
00923 }
00924
00925
00926 Vector *myV = new Vector(modNumDOF);
00927 Vector *myVdot = 0;
00928 Vector *myVdotdot = 0;
00929
00930
00931
00932 const ID &theID = this->getID();
00933 for (int i=0; i<modNumDOF; i++) {
00934 int loc = theID(i);
00935 if (loc >= 0)
00936 (*modUnbalance)(i) = (*u)(loc);
00937
00938 }
00939 Matrix *T = this->getT();
00940 if (T != 0) {
00941
00942
00943 myV->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00944
00945 } else
00946 *myV = *modUnbalance;
00947
00948
00949
00950 if ((udot != 0) && (udotdot != 0)) {
00951 myVdot = new Vector(modNumDOF);
00952 myVdotdot = new Vector(modNumDOF);
00953 for (int i=0; i<modNumDOF; i++) {
00954 int loc = theID(i);
00955 if (loc >= 0)
00956 (*modUnbalance)(i) = (*udot)(loc);
00957
00958 }
00959
00960 if (T != 0) {
00961
00962
00963 myVdot->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00964
00965 } else
00966 *myVdot = *modUnbalance;
00967
00968 for (int j=0; j<modNumDOF; j++) {
00969 int loc = theID(j);
00970 if (loc >= 0)
00971 (*modUnbalance)(j) = (*udotdot)(loc);
00972
00973 }
00974
00975 if (T != 0) {
00976
00977
00978 myVdotdot->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00979
00980 } else
00981 *myVdotdot = *modUnbalance;
00982
00983 }
00984
00985 myNode->saveSensitivity(myV, myVdot, myVdotdot, gradNum, numGrads);
00986
00987 if (myV != 0) delete myV;
00988 if (myVdot != 0) delete myVdot;
00989 if (myVdotdot != 0) delete myVdotdot;
00990
00991 return 0;
00992 }
00993
00994 void
00995 TransformationDOF_Group::addM_ForceSensitivity(const Vector &Udotdot, double fact)
00996 {
00997
00998 if (theMP == 0 || modID == 0) {
00999 this->DOF_Group::addM_ForceSensitivity(Udotdot, fact);
01000 return;
01001 }
01002
01003 for (int i=0; i<modNumDOF; i++) {
01004 int loc = (*modID)(i);
01005 if (loc >= 0)
01006 (*modUnbalance)(i) = Udotdot(loc);
01007 else
01008 (*modUnbalance)(i) = 0.0;
01009 }
01010
01011 Vector unmod(Trans->noRows());
01012
01013 unmod.addMatrixVector(0.0, *Trans, *modUnbalance, 1.0);
01014 this->DOF_Group::addM_ForceSensitivity(unmod, fact);
01015 }
01016
01017 void
01018 TransformationDOF_Group::addD_Force(const Vector &Udot, double fact)
01019 {
01020
01021 if (theMP == 0 || modID == 0) {
01022 this->DOF_Group::addD_Force(Udot, fact);
01023 return;
01024 }
01025
01026 for (int i=0; i<modNumDOF; i++) {
01027 int loc = (*modID)(i);
01028 if (loc >= 0)
01029 (*modUnbalance)(i) = Udot(loc);
01030 else
01031 (*modUnbalance)(i) = 0.0;
01032 }
01033
01034 Vector unmod(Trans->noRows());
01035
01036 unmod.addMatrixVector(0.0, *Trans, *modUnbalance, 1.0);
01037 this->DOF_Group::addD_Force(unmod, fact);
01038 }
01039
01040 void
01041 TransformationDOF_Group::addD_ForceSensitivity(const Vector &Udot, double fact)
01042 {
01043
01044 if (theMP == 0 || modID == 0) {
01045 this->DOF_Group::addD_ForceSensitivity(Udot, fact);
01046 return;
01047 }
01048
01049 for (int i=0; i<modNumDOF; i++) {
01050 int loc = (*modID)(i);
01051 if (loc >= 0)
01052 (*modUnbalance)(i) = Udot(loc);
01053 else
01054 (*modUnbalance)(i) = 0.0;
01055 }
01056
01057 Vector unmod(Trans->noRows());
01058
01059 unmod.addMatrixVector(0.0, *Trans, *modUnbalance, 1.0);
01060 this->DOF_Group::addD_ForceSensitivity(unmod, fact);
01061 }
01062
01063