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