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 <DOF_Group.h>
00039 #include <stdlib.h>
00040
00041 #include <Node.h>
00042 #include <Vector.h>
00043 #include <Matrix.h>
00044 #include <TransientIntegrator.h>
00045
00046 #define MAX_NUM_DOF 256
00047
00048
00049
00050 Matrix DOF_Group::errMatrix(1,1);
00051 Vector DOF_Group::errVect(1);
00052 Matrix **DOF_Group::theMatrices;
00053 Vector **DOF_Group::theVectors;
00054 int DOF_Group::numDOFs(0);
00055
00056
00057
00058
00059
00060 DOF_Group::DOF_Group(int tag, Node *node)
00061 :unbalance(0), tangent(0), myNode(node),
00062 myTag(tag), myID(node->getNumberDOF()),
00063 numDOF(node->getNumberDOF())
00064 {
00065
00066 int numDOF = node->getNumberDOF();
00067 if (numDOF <= 0) {
00068 cerr << "DOF_Group::DOF_Group(Node *) ";
00069 cerr << " node must have at least 1 dof " << *node;
00070 exit(-1);
00071 }
00072
00073
00074 if (myID.Size() != numDOF) {
00075 cerr << "DOF_Group::DOF_Group(Node *) ";
00076 cerr << " ran out of memory creating ID for node " << *node;
00077 exit(-1);
00078 }
00079
00080
00081 for (int i=0; i<numDOF; i++)
00082 myID(i) = -2;
00083
00084
00085
00086
00087 if (numDOFs == 0) {
00088 theMatrices = new Matrix *[MAX_NUM_DOF+1];
00089 theVectors = new Vector *[MAX_NUM_DOF+1];
00090
00091 if (theMatrices == 0 || theVectors == 0) {
00092 cerr << "DOF_Group::DOF_Group(Node *) ";
00093 cerr << " ran out of memory";
00094 }
00095 for (int i=0; i<MAX_NUM_DOF; i++) {
00096 theMatrices[i] = 0;
00097 theVectors[i] = 0;
00098 }
00099 }
00100
00101
00102 if (numDOF <= MAX_NUM_DOF) {
00103
00104 if (theVectors[numDOF] == 0) {
00105
00106 theVectors[numDOF] = new Vector(numDOF);
00107 theMatrices[numDOF] = new Matrix(numDOF,numDOF);
00108 unbalance = theVectors[numDOF];
00109 tangent = theMatrices[numDOF];
00110 if (unbalance == 0 || unbalance->Size() != numDOF ||
00111 tangent == 0 || tangent->noCols() != numDOF) {
00112 cerr << "DOF_Group::DOF_Group(Node *) ";
00113 cerr << " ran out of memory for vector/Matrix of size :";
00114 cerr << numDOF << endl;
00115 exit(-1);
00116 }
00117 } else {
00118 unbalance = theVectors[numDOF];
00119 tangent = theMatrices[numDOF];
00120 }
00121 } else {
00122
00123 unbalance = new Vector(numDOF);
00124 tangent = new Matrix(numDOF, numDOF);
00125 if (unbalance == 0 || unbalance->Size() ==0 ||
00126 tangent ==0 || tangent->noRows() ==0) {
00127
00128 cerr << "DOF_Group::DOF_Group(Node *) ";
00129 cerr << " ran out of memory for vector/Matrix of size :";
00130 cerr << numDOF << endl;
00131 exit(-1);
00132 }
00133 }
00134
00135 numDOFs++;
00136 }
00137
00138
00139 DOF_Group::DOF_Group(int tag, int ndof)
00140 :unbalance(0), tangent(0), myNode(0),
00141 myTag(tag), myID(ndof),
00142 numDOF(ndof)
00143 {
00144
00145 int numDOF = ndof;
00146 if (numDOF <= 0) {
00147 cerr << "DOF_Group::DOF_Group(int, int ndof) ";
00148 cerr << ndof << " ndof specified, there must be at least 1\n";
00149 exit(-1);
00150 }
00151
00152
00153 if (myID.Size() != numDOF) {
00154 cerr << "DOF_Group::DOF_Group(int, int ndof) ";
00155 cerr << " ran out of memory creating ID of size " << ndof << endl;
00156 exit(-1);
00157 }
00158
00159
00160 for (int i=0; i<numDOF; i++)
00161 myID(i) = -2;
00162
00163
00164
00165
00166 if (numDOFs == 0) {
00167 theMatrices = new Matrix *[MAX_NUM_DOF+1];
00168 theVectors = new Vector *[MAX_NUM_DOF+1];
00169
00170 if (theMatrices == 0 || theVectors == 0) {
00171 cerr << "DOF_Group::DOF_Group(int, int ndof) ";
00172 cerr << " ran out of memory";
00173 }
00174 for (int i=0; i<MAX_NUM_DOF; i++) {
00175 theMatrices[i] = 0;
00176 theVectors[i] = 0;
00177 }
00178 }
00179
00180
00181 if (numDOF <= MAX_NUM_DOF) {
00182
00183 if (theVectors[numDOF] == 0) {
00184
00185 theVectors[numDOF] = new Vector(numDOF);
00186 theMatrices[numDOF] = new Matrix(numDOF,numDOF);
00187 unbalance = theVectors[numDOF];
00188 tangent = theMatrices[numDOF];
00189 if (unbalance == 0 || unbalance->Size() != numDOF ||
00190 tangent == 0 || tangent->noCols() != numDOF) {
00191 cerr << "DOF_Group::DOF_Group(int, int ndof) ";
00192 cerr << " ran out of memory for vector/Matrix of size :";
00193 cerr << numDOF << endl;
00194 exit(-1);
00195 }
00196 } else {
00197 unbalance = theVectors[numDOF];
00198 tangent = theMatrices[numDOF];
00199 }
00200 } else {
00201
00202 unbalance = new Vector(numDOF);
00203 tangent = new Matrix(numDOF, numDOF);
00204 if (unbalance == 0 || tangent ==0 ||
00205 tangent ==0 || tangent->noRows() ==0) {
00206
00207 cerr << "DOF_Group::DOF_Group(int, int ndof) ";
00208 cerr << " ran out of memory for vector/Matrix of size :";
00209 cerr << numDOF << endl;
00210 exit(-1);
00211 }
00212 }
00213
00214 numDOFs++;
00215 }
00216
00217
00218
00219
00220 DOF_Group::~DOF_Group()
00221 {
00222 numDOFs--;
00223
00224
00225
00226 if (myNode != 0) {
00227 myNode->setDOF_GroupPtr(0);
00228 }
00229
00230 int numDOF = unbalance->Size();
00231
00232
00233 if (numDOF > MAX_NUM_DOF) {
00234 if (tangent != 0) delete tangent;
00235 if (unbalance != 0) delete unbalance;
00236 }
00237
00238
00239
00240 if (numDOFs == 0) {
00241 for (int i=0; i<MAX_NUM_DOF; i++) {
00242 if (theVectors[i] != 0)
00243 delete theVectors[i];
00244 if (theMatrices[i] != 0)
00245 delete theMatrices[i];
00246 }
00247 delete [] theMatrices;
00248 delete [] theVectors;
00249 }
00250 }
00251
00252
00253
00254
00255 void
00256 DOF_Group::setID(int index, int value)
00257 {
00258 if ((index >= 0) && (index < numDOF))
00259 myID(index) = value;
00260 else {
00261 cerr << "WARNING DOF_Group::setID - invalid location ";
00262 cerr << index << " in ID of size " << numDOF << endl;
00263 }
00264 }
00265
00266
00267
00268
00269 void
00270 DOF_Group::setID(const ID ©)
00271 {
00272 myID = copy;
00273 }
00274
00275
00276
00277
00278
00279 const ID &
00280 DOF_Group::getID(void) const
00281 {
00282 return myID;
00283 }
00284
00285
00286
00287 int
00288 DOF_Group::getNumDOF(void) const
00289 {
00290 return numDOF;
00291 }
00292
00293 int
00294 DOF_Group::getNodeTag(void) const
00295 {
00296 if (myNode != 0)
00297 return myNode->getTag();
00298 else
00299 return -1;
00300 }
00301
00302 int
00303 DOF_Group::getNumFreeDOF(void) const
00304 {
00305 int numFreeDOF = numDOF;
00306 for (int i=0; i<numDOF; i++)
00307 if (myID(i) < 0)
00308 numFreeDOF--;
00309
00310 return numFreeDOF;
00311 }
00312
00313 int
00314 DOF_Group::getNumConstrainedDOF(void) const
00315 {
00316 int numConstr = 0;
00317 for (int i=0; i<numDOF; i++)
00318 if (myID(i) < 0)
00319 numConstr++;
00320
00321 return numConstr;
00322 }
00323
00324
00325
00326 const Matrix &
00327 DOF_Group::getTangent(Integrator *theIntegrator)
00328 {
00329 if (theIntegrator != 0)
00330 theIntegrator->formNodTangent(this);
00331 return *tangent;
00332 }
00333
00334 void
00335 DOF_Group::zeroTangent(void)
00336 {
00337 tangent->Zero();
00338 }
00339
00340
00341 void
00342 DOF_Group::addMtoTang(double fact)
00343 {
00344 if (myNode != 0) {
00345 if (tangent->addMatrix(1.0, myNode->getMass(), fact) < 0) {
00346 cerr << "DOF_Group::addMtoTang(void) ";
00347 cerr << " invoking addMatrix() on the tangent failed\n";
00348 }
00349 }
00350 else {
00351 cerr << "DOF_Group::addMtoTang(void) - no Node associated";
00352 cerr << " subclass should provide the method \n";
00353 }
00354 }
00355
00356
00357
00358 void
00359 DOF_Group::zeroUnbalance(void)
00360 {
00361 unbalance->Zero();
00362 }
00363
00364
00365 const Vector &
00366 DOF_Group::getUnbalance(Integrator *theIntegrator)
00367 {
00368 if (theIntegrator != 0)
00369 theIntegrator->formNodUnbalance(this);
00370
00371 return *unbalance;
00372 }
00373
00374
00375 void
00376 DOF_Group::addPtoUnbalance(double fact)
00377 {
00378 if (myNode != 0) {
00379 if (unbalance->addVector(1.0, myNode->getUnbalancedLoad(), fact) < 0) {
00380 cerr << "DOF_Group::addPIncInertiaToUnbalance() -";
00381 cerr << " invoking addVector() on the unbalance failed\n";
00382 }
00383 }
00384 else {
00385 cerr << "DOF_Group::addPtoUnbalance() - no Node associated";
00386 cerr << " subclass should provide the method \n";
00387 }
00388 }
00389
00390
00391 void
00392 DOF_Group::addPIncInertiaToUnbalance(double fact)
00393 {
00394 if (myNode != 0) {
00395 if (unbalance->addVector(1.0, myNode->getUnbalancedLoadIncInertia(),
00396 fact) < 0) {
00397
00398 cerr << "DOF_Group::addPIncInertiaToUnbalance() - ";
00399 cerr << " invoking addVector() on the unbalance failed\n";
00400 }
00401 }
00402 else {
00403 cerr << "DOF_Group::addPIncInertiaToUnbalance() - no Node associated";
00404 cerr << " subclass should provide the method \n";
00405 }
00406 }
00407
00408
00409 void
00410 DOF_Group::addM_Force(const Vector &Udotdot, double fact)
00411 {
00412 if (myNode == 0) {
00413 cerr << "DOF_Group::addM_Force() - no Node associated";
00414 cerr << " subclass should not call this method \n";
00415 return;
00416 }
00417
00418 Vector accel(numDOF);
00419
00420 for (int i=0; i<numDOF; i++) {
00421 int loc = myID(i);
00422 if (loc >= 0)
00423 accel(i) = Udotdot(loc);
00424 else accel(i) = 0.0;
00425 }
00426
00427 if (unbalance->addMatrixVector(1.0, myNode->getMass(), accel, fact) < 0) {
00428 cerr << "DOF_Group::addM_Force() ";
00429 cerr << " invoking addMatrixVector() on the unbalance failed\n";
00430 }
00431 else {
00432
00433 }
00434 }
00435
00436
00437 const Vector &
00438 DOF_Group::getCommittedDisp(void)
00439 {
00440 if (myNode == 0) {
00441 cerr << "DOF_Group::getCommittedDisp: no associated Node ";
00442 cerr << " returning the error Vector\n";
00443 return errVect;
00444 }
00445 return myNode->getDisp();
00446 }
00447
00448
00449 const Vector &
00450 DOF_Group::getCommittedVel(void)
00451 {
00452 if (myNode == 0) {
00453 cerr << "DOF_Group::getCommittedVel: no associated Node ";
00454 cerr << " returning the error Vector\n";
00455 return errVect;
00456 }
00457 return myNode->getVel();
00458 }
00459
00460
00461 const Vector &
00462 DOF_Group::getCommittedAccel(void)
00463 {
00464 if (myNode == 0) {
00465 cerr << "DOF_Group::getCommittedAccel: no associated Node ";
00466 cerr << " returning the error Vector\n";
00467 return errVect;
00468 }
00469 return myNode->getAccel();
00470 }
00471
00472
00473
00474
00475
00476 void
00477 DOF_Group::setNodeDisp(const Vector &u)
00478 {
00479 if (myNode == 0) {
00480 cerr << "DOF_Group::setNodeDisp: no associated Node\n";
00481 return;
00482 }
00483
00484 Vector &disp = *unbalance;
00485 disp = myNode->getTrialDisp();
00486 int i;
00487
00488
00489 for (i=0; i<numDOF; i++) {
00490 int loc = myID(i);
00491 if (loc >= 0)
00492 disp(i) = u(loc);
00493 }
00494
00495 myNode->setTrialDisp(disp);
00496 }
00497
00498
00499
00500
00501
00502
00503 void
00504 DOF_Group::setNodeVel(const Vector &udot)
00505 {
00506
00507 if (myNode == 0) {
00508 cerr << "DOF_Group::setNodeVel: 0 Node Pointer\n";
00509 return;
00510 }
00511
00512 Vector &vel = *unbalance;
00513 vel = myNode->getTrialVel();
00514 int i;
00515
00516
00517 for (i=0; i<numDOF; i++) {
00518 int loc = myID(i);
00519 if (loc >= 0)
00520 vel(i) = udot(loc);
00521 }
00522
00523 myNode->setTrialVel(vel);
00524
00525 }
00526
00527
00528
00529
00530
00531
00532
00533 void
00534 DOF_Group::setNodeAccel(const Vector &udotdot)
00535 {
00536
00537 if (myNode == 0) {
00538 cerr << "DOF_Group::setNodeAccel: 0 Node Pointer\n";
00539 return;
00540 }
00541
00542 Vector &accel = *unbalance;;
00543 accel = myNode->getTrialAccel();
00544 int i;
00545
00546
00547 for (i=0; i<numDOF; i++) {
00548 int loc = myID(i);
00549 if (loc >= 0)
00550 accel(i) = udotdot(loc);
00551 }
00552
00553 myNode->setTrialAccel(accel);
00554 }
00555
00556
00557
00558
00559
00560
00561 void
00562 DOF_Group::incrNodeDisp(const Vector &u)
00563 {
00564 if (myNode == 0) {
00565 cerr << "DOF_Group::setNodeDisp: 0 Node Pointer\n";
00566 exit(-1);
00567 }
00568
00569 Vector &disp = *unbalance;;
00570
00571 if (disp.Size() == 0) {
00572 cerr << "DOF_Group::setNodeIncrDisp - out of space\n";
00573 return;
00574 }
00575 int i;
00576
00577
00578 for (i=0; i<numDOF; i++) {
00579 int loc = myID(i);
00580 if (loc >= 0)
00581 disp(i) = u(loc);
00582 else disp(i) = 0.0;
00583 }
00584
00585 myNode->incrTrialDisp(disp);
00586
00587 }
00588
00589
00590
00591
00592
00593
00594 void
00595 DOF_Group::incrNodeVel(const Vector &udot)
00596 {
00597
00598 if (myNode == 0) {
00599 cerr << "DOF_Group::setNodeVel: 0 Node Pointer\n";
00600 exit(-1);
00601 }
00602
00603 Vector &vel = *unbalance;
00604 int i;
00605
00606
00607 for (i=0; i<numDOF; i++) {
00608 int loc = myID(i);
00609 if (loc >= 0)
00610 vel(i) = udot(loc);
00611 else vel(i) = 0.0;
00612 }
00613 myNode->incrTrialVel(vel);
00614 }
00615
00616
00617
00618
00619
00620
00621
00622 void
00623 DOF_Group::incrNodeAccel(const Vector &udotdot)
00624 {
00625
00626 if (myNode == 0) {
00627 cerr << "DOF_Group::setNodeAccel: 0 Node Pointer\n";
00628 exit(-1);
00629 }
00630
00631 Vector &accel = *unbalance;
00632 int i;
00633
00634
00635 for (i=0; i<numDOF; i++) {
00636 int loc = myID(i);
00637 if (loc >= 0)
00638 accel(i) = udotdot(loc);
00639 else accel(i) = 0.0;
00640 }
00641 myNode->incrTrialAccel(accel);
00642 }
00643
00644
00645
00646 void
00647 DOF_Group::setEigenvector(int mode, const Vector &theVector)
00648 {
00649
00650 if (myNode == 0) {
00651 cerr << "DOF_Group::setNodeAccel: 0 Node Pointer\n";
00652 exit(-1);
00653 }
00654
00655 Vector &eigenvector = *unbalance;
00656 int i;
00657
00658
00659 for (i=0; i<numDOF; i++) {
00660 int loc = myID(i);
00661 if (loc >= 0)
00662 eigenvector(i) = theVector(loc);
00663 else eigenvector(i) = 0.0;
00664 }
00665 myNode->setEigenvector(mode, eigenvector);
00666 }
00667
00668
00669
00670 int
00671 DOF_Group::getTag(void) const
00672 {
00673 return myTag;
00674 }
00675
00676 Matrix *
00677 DOF_Group::getT(void)
00678 {
00679 return 0;
00680 }
00681
00682
00683
00684 void
00685 DOF_Group::addLocalM_Force(const Vector &accel, double fact)
00686 {
00687 if (myNode != 0) {
00688 if (unbalance->addMatrixVector(1.0, myNode->getMass(), accel, fact) < 0) {
00689
00690 cerr << "DOF_Group::addM_Force() ";
00691 cerr << " invoking addMatrixVector() on the unbalance failed\n";
00692 }
00693 }
00694 else {
00695 cerr << "DOF_Group::addM_Force() - no Node associated";
00696 cerr << " subclass should not call this method \n";
00697 }
00698 }
00699
00700
00701
00702
00703