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 #include <stdlib.h>
00037
00038 #include "Element.h"
00039 #include "ElementResponse.h"
00040 #include <Renderer.h>
00041 #include <Vector.h>
00042 #include <Matrix.h>
00043 #include <Node.h>
00044 #include <Domain.h>
00045
00046 Matrix **Element::theMatrices;
00047 Vector **Element::theVectors1;
00048 Vector **Element::theVectors2;
00049 int Element::numMatrices(0);
00050
00051
00052
00053
00054
00055 Element::Element(int tag, int cTag)
00056 :DomainComponent(tag, cTag), alphaM(0.0),
00057 betaK(0.0), betaK0(0.0), betaKc(0.0),
00058 Kc(0), index(-1), nodeIndex(-1)
00059 {
00060
00061 }
00062
00063
00064 Element::~Element()
00065 {
00066 if (Kc != 0)
00067 delete Kc;
00068 }
00069
00070 int
00071 Element::commitState(void)
00072 {
00073 if (Kc != 0)
00074 *Kc = this->getTangentStiff();
00075
00076 return 0;
00077 }
00078
00079 int
00080 Element::update(void)
00081 {
00082 return 0;
00083 }
00084
00085 int
00086 Element::revertToStart(void)
00087 {
00088 return 0;
00089 }
00090
00091
00092 int
00093 Element::setRayleighDampingFactors(double alpham, double betak, double betak0, double betakc)
00094 {
00095 alphaM = alpham;
00096 betaK = betak;
00097 betaK0 = betak0;
00098 betaKc = betakc;
00099
00100
00101
00102 if (index == -1) {
00103 int numDOF = this->getNumDOF();
00104
00105 for (int i=0; i<numMatrices; i++) {
00106 Matrix *aMatrix = theMatrices[i];
00107 if (aMatrix->noRows() == numDOF) {
00108 index = i;
00109 i = numMatrices;
00110 }
00111 }
00112 if (index == -1) {
00113 Matrix **nextMatrices = new Matrix *[numMatrices+1];
00114 if (nextMatrices == 0) {
00115 opserr << "Element::getTheMatrix - out of memory\n";
00116 }
00117 int j;
00118 for (j=0; j<numMatrices; j++)
00119 nextMatrices[j] = theMatrices[j];
00120 Matrix *theMatrix = new Matrix(numDOF, numDOF);
00121 if (theMatrix == 0) {
00122 opserr << "Element::getTheMatrix - out of memory\n";
00123 exit(-1);
00124 }
00125 nextMatrices[numMatrices] = theMatrix;
00126
00127 Vector **nextVectors1 = new Vector *[numMatrices+1];
00128 Vector **nextVectors2 = new Vector *[numMatrices+1];
00129 if (nextVectors1 == 0 || nextVectors2 == 0) {
00130 opserr << "Element::getTheVector - out of memory\n";
00131 exit(-1);
00132 }
00133
00134 for (j=0; j<numMatrices; j++) {
00135 nextVectors1[j] = theVectors1[j];
00136 nextVectors2[j] = theVectors2[j];
00137 }
00138
00139 Vector *theVector1 = new Vector(numDOF);
00140 Vector *theVector2 = new Vector(numDOF);
00141 if (theVector1 == 0 || theVector2 == 0) {
00142 opserr << "Element::getTheVector - out of memory\n";
00143 exit(-1);
00144 }
00145
00146 nextVectors1[numMatrices] = theVector1;
00147 nextVectors2[numMatrices] = theVector2;
00148
00149 if (numMatrices != 0) {
00150 delete [] theMatrices;
00151 delete [] theVectors1;
00152 delete [] theVectors2;
00153 }
00154 index = numMatrices;
00155 numMatrices++;
00156 theMatrices = nextMatrices;
00157 theVectors1 = nextVectors1;
00158 theVectors2 = nextVectors2;
00159 }
00160 }
00161
00162
00163 if (betaKc != 0.0) {
00164 if (Kc == 0)
00165 Kc = new Matrix(this->getTangentStiff());
00166 if (Kc == 0) {
00167 opserr << "WARNING - ELEMENT::setRayleighDampingFactors - out of memory\n";
00168 betaKc = 0.0;
00169 }
00170
00171
00172 } else if (Kc != 0) {
00173 delete Kc;
00174 Kc = 0;
00175 }
00176
00177 return 0;
00178 }
00179
00180 const Matrix &
00181 Element::getDamp(void)
00182 {
00183 if (index == -1) {
00184 this->setRayleighDampingFactors(0.0, 0.0, 0.0, 0.0);
00185 }
00186
00187
00188 Matrix *theMatrix = theMatrices[index];
00189 theMatrix->Zero();
00190 if (alphaM != 0.0)
00191 theMatrix->addMatrix(0.0, this->getMass(), alphaM);
00192 if (betaK != 0.0)
00193 theMatrix->addMatrix(1.0, this->getTangentStiff(), betaK);
00194 if (betaK0 != 0.0)
00195 theMatrix->addMatrix(1.0, this->getInitialStiff(), betaK0);
00196 if (betaKc != 0.0)
00197 theMatrix->addMatrix(1.0, *Kc, betaKc);
00198
00199
00200 return *theMatrix;
00201 }
00202
00203
00204
00205 const Matrix &
00206 Element::getMass(void)
00207 {
00208 if (index == -1) {
00209 this->setRayleighDampingFactors(0.0, 0.0, 0.0, 0.0);
00210 }
00211
00212
00213 Matrix *theMatrix = theMatrices[index];
00214 theMatrix->Zero();
00215 return *theMatrix;
00216 }
00217
00218 const Vector &
00219 Element::getResistingForceIncInertia(void)
00220 {
00221 if (index == -1) {
00222 this->setRayleighDampingFactors(0.0, 0.0, 0.0, 0.0);
00223 }
00224
00225 Matrix *theMatrix = theMatrices[index];
00226 Vector *theVector = theVectors2[index];
00227 Vector *theVector2 = theVectors1[index];
00228
00229
00230
00231
00232
00233 (*theVector) = this->getResistingForce();
00234
00235
00236
00237
00238
00239 int loc = 0;
00240 Node **theNodes = this->getNodePtrs();
00241 int numNodes = this->getNumExternalNodes();
00242
00243 int i;
00244 for (i=0; i<numNodes; i++) {
00245 const Vector &acc = theNodes[i]->getAccel();
00246 for (int i=0; i<acc.Size(); i++) {
00247 (*theVector2)(loc++) = acc(i);
00248 }
00249 }
00250 theVector->addMatrixVector(1.0, this->getMass(), *theVector2, +1.0);
00251
00252
00253
00254
00255
00256
00257
00258 loc = 0;
00259 for (i=0; i<numNodes; i++) {
00260 const Vector &vel = theNodes[i]->getTrialVel();
00261 for (int i=0; i<vel.Size(); i++) {
00262 (*theVector2)(loc++) = vel[i];
00263 }
00264 }
00265
00266
00267 theMatrix->Zero();
00268 if (alphaM != 0.0)
00269 theMatrix->addMatrix(0.0, this->getMass(), alphaM);
00270 if (betaK != 0.0)
00271 theMatrix->addMatrix(1.0, this->getTangentStiff(), betaK);
00272 if (betaK0 != 0.0)
00273 theMatrix->addMatrix(1.0, this->getInitialStiff(), betaK0);
00274 if (betaKc != 0.0)
00275 theMatrix->addMatrix(1.0, *Kc, betaKc);
00276
00277
00278 theVector->addMatrixVector(1.0, *theMatrix, *theVector2, 1.0);
00279
00280 return *theVector;
00281 }
00282
00283
00284 const Vector &
00285 Element::getRayleighDampingForces(void)
00286 {
00287
00288 if (index == -1) {
00289 this->setRayleighDampingFactors(0.0, 0.0, 0.0, 0.0);
00290 }
00291
00292 Matrix *theMatrix = theMatrices[index];
00293 Vector *theVector = theVectors2[index];
00294 Vector *theVector2 = theVectors1[index];
00295
00296
00297
00298
00299
00300
00301
00302 Node **theNodes = this->getNodePtrs();
00303 int numNodes = this->getNumExternalNodes();
00304 int loc = 0;
00305 for (int i=0; i<numNodes; i++) {
00306 const Vector &vel = theNodes[i]->getTrialVel();
00307 for (int i=0; i<vel.Size(); i++) {
00308 (*theVector2)(loc++) = vel[i];
00309 }
00310 }
00311
00312
00313 theMatrix->Zero();
00314 if (alphaM != 0.0)
00315 theMatrix->addMatrix(0.0, this->getMass(), alphaM);
00316 if (betaK != 0.0)
00317 theMatrix->addMatrix(1.0, this->getTangentStiff(), betaK);
00318 if (betaK0 != 0.0)
00319 theMatrix->addMatrix(1.0, this->getInitialStiff(), betaK0);
00320 if (betaKc != 0.0)
00321 theMatrix->addMatrix(1.0, *Kc, betaKc);
00322
00323
00324 theVector->addMatrixVector(0.0, *theMatrix, *theVector2, 1.0);
00325
00326 return *theVector;
00327 }
00328
00329 int
00330 Element::addLoad(ElementalLoad *theLoad, double loadFactor) {
00331 return 0;
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 bool
00378 Element::isSubdomain(void)
00379 {
00380 return false;
00381 }
00382
00383 Response*
00384 Element::setResponse(const char **argv, int argc, Information &eleInfo, OPS_Stream &output)
00385 {
00386 Response *theResponse = 0;
00387
00388 output.tag("ElementOutput");
00389 output.attr("eleType",this->getClassType());
00390 output.attr("eleTag",this->getTag());
00391 int numNodes = this->getNumExternalNodes();
00392 const ID &nodes = this->getExternalNodes();
00393 static char nodeData[32];
00394
00395 for (int i=0; i<numNodes; i++) {
00396 sprintf(nodeData,"node%d",i+1);
00397 output.attr(nodeData,nodes(i));
00398 }
00399
00400 if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0 ||
00401 strcmp(argv[0],"globalForce") == 0 || strcmp(argv[0],"globalForces") == 0) {
00402 const Vector &force = this->getResistingForce();
00403 int size = force.Size();
00404 for (int i=0; i<size; i++) {
00405 sprintf(nodeData,"P%d",i+1);
00406 output.tag("ResponseType",nodeData);
00407 }
00408 theResponse = new ElementResponse(this, 1, this->getResistingForce());
00409 }
00410 output.endTag();
00411 return theResponse;
00412 }
00413
00414 int
00415 Element::getResponse(int responseID, Information &eleInfo)
00416 {
00417 switch (responseID) {
00418 case 1:
00419 return eleInfo.setVector(this->getResistingForce());
00420 default:
00421 return -1;
00422 }
00423 }
00424
00425 int
00426 Element::getResponseSensitivity(int responseID, int gradNumber,
00427 Information &eleInfo)
00428 {
00429 return -1;
00430 }
00431
00432
00433 const Vector &
00434 Element::getResistingForceSensitivity(int gradNumber)
00435 {
00436 static Vector dummy(1);
00437 return dummy;
00438 }
00439
00440 const Matrix &
00441 Element::getInitialStiffSensitivity(int gradNumber)
00442 {
00443 static Matrix dummy(1,1);
00444 return dummy;
00445 }
00446
00447 const Matrix &
00448 Element::getMassSensitivity(int gradNumber)
00449 {
00450 static Matrix dummy(1,1);
00451 return dummy;
00452 }
00453
00454 int
00455 Element::commitSensitivity(int gradNumber, int numGrads)
00456 {
00457 return -1;
00458 }
00459
00460 int
00461 Element::addInertiaLoadSensitivityToUnbalance(const Vector &accel, bool tag)
00462 {
00463 return -1;
00464 }
00465
00466
00467
00468
00469
00470
00471 const Matrix &
00472 Element::getDampSensitivity(int gradNumber)
00473 {
00474 if (index == -1) {
00475 this->setRayleighDampingFactors(0.0, 0.0, 0.0, 0.0);
00476 }
00477
00478
00479 Matrix *theMatrix = theMatrices[index];
00480 theMatrix->Zero();
00481 if (alphaM != 0.0) {
00482 theMatrix->addMatrix(0.0, this->getMassSensitivity(gradNumber), alphaM);
00483 }
00484 if (betaK != 0.0) {
00485 theMatrix->addMatrix(1.0, this->getTangentStiff(), 0.0);
00486 opserr << "Rayleigh damping with non-zero betaCurrentTangent is not compatible with DDM sensitivity analysis" << endln;
00487 }
00488 if (betaK0 != 0.0) {
00489 theMatrix->addMatrix(1.0, this->getInitialStiffSensitivity(gradNumber), betaK0);
00490 }
00491 if (betaKc != 0.0) {
00492 theMatrix->addMatrix(1.0, *Kc, 0.0);
00493 opserr << "Rayleigh damping with non-zero betaCommittedTangent is not compatible with DDM sensitivity analysis" << endln;
00494 }
00495
00496
00497 return *theMatrix;
00498 }
00499
00500
00501
00502 int
00503 Element::addResistingForceToNodalReaction(bool inclInertia)
00504 {
00505 int result = 0;
00506 int numNodes = this->getNumExternalNodes();
00507 Node **theNodes = this->getNodePtrs();
00508
00509
00510
00511
00512
00513
00514 if (nodeIndex == -1) {
00515 int numLastDOF = -1;
00516 for (int i=0; i<numNodes; i++) {
00517 int numNodalDOF = theNodes[i]->getNumberDOF();
00518
00519 if (numNodalDOF != 0 && numNodalDOF != numLastDOF) {
00520
00521 int j;
00522 for (j=0; j<numMatrices; j++) {
00523 if (theVectors1[j]->Size() == numNodalDOF)
00524 nodeIndex = j;
00525 j = numMatrices+2;
00526 }
00527
00528
00529 if (j != (numMatrices+2)) {
00530 Matrix **nextMatrices = new Matrix *[numMatrices+1];
00531 if (nextMatrices == 0) {
00532 opserr << "Element::addResistingForceToNodalReaction - out of memory\n";
00533 }
00534 int j;
00535 for (j=0; j<numMatrices; j++)
00536 nextMatrices[j] = theMatrices[j];
00537 Matrix *theMatrix = new Matrix(numNodalDOF, numNodalDOF);
00538 if (theMatrix == 0) {
00539 opserr << "Element::addResistingForceToNodalReaction - out of memory\n";
00540 exit(-1);
00541 }
00542 nextMatrices[numMatrices] = theMatrix;
00543
00544 Vector **nextVectors1 = new Vector *[numMatrices+1];
00545 Vector **nextVectors2 = new Vector *[numMatrices+1];
00546 if (nextVectors1 == 0 || nextVectors2 == 0) {
00547 opserr << "Element::addResistingForceToNodalReaction - out of memory\n";
00548 exit(-1);
00549 }
00550
00551 for (j=0; j<numMatrices; j++) {
00552 nextVectors1[j] = theVectors1[j];
00553 nextVectors2[j] = theVectors2[j];
00554 }
00555
00556 Vector *theVector1 = new Vector(numNodalDOF);
00557 Vector *theVector2 = new Vector(numNodalDOF);
00558 if (theVector1 == 0 || theVector2 == 0) {
00559 opserr << "Element::addResistingForceToNodalReaction - out of memory\n";
00560 exit(-1);
00561 }
00562
00563 nextVectors1[numMatrices] = theVector1;
00564 nextVectors2[numMatrices] = theVector2;
00565
00566 if (numMatrices != 0) {
00567 delete [] theMatrices;
00568 delete [] theVectors1;
00569 delete [] theVectors2;
00570 }
00571 nodeIndex = numMatrices;
00572 numMatrices++;
00573 theMatrices = nextMatrices;
00574 theVectors1 = nextVectors1;
00575 theVectors2 = nextVectors2;
00576 }
00577 }
00578 numLastDOF = numNodalDOF;
00579 }
00580 }
00581
00582
00583
00584
00585
00586 const Vector *theResistingForce;
00587 if (inclInertia == 0)
00588 theResistingForce = &(this->getResistingForce());
00589 else
00590 theResistingForce = &(this->getResistingForceIncInertia());
00591
00592 if (nodeIndex == -1) {
00593 opserr << "LOGIC ERROR Element::addResistingForceToNodalReaction() -HUH!\n";
00594 return -1;
00595 }
00596
00597
00598
00599
00600
00601 int nodalDOFCount = 0;
00602
00603 for (int i=0; i<numNodes; i++) {
00604 Node *theNode = theNodes[i];
00605
00606 int numNodalDOF = theNode->getNumberDOF();
00607 Vector *theVector = theVectors1[nodeIndex];
00608 if (theVector->Size() != numNodalDOF) {
00609 for (int j=0; j<numMatrices; j++)
00610 if (theVectors1[j]->Size() == numNodalDOF) {
00611 j = numMatrices;
00612 theVector = theVectors1[j];
00613 }
00614 }
00615 for (int j=0; j<numNodalDOF; j++) {
00616 (*theVector)(j) = (*theResistingForce)(nodalDOFCount);
00617 nodalDOFCount++;
00618 }
00619 result +=theNode->addReactionForce(*theVector, 1.0);
00620 }
00621
00622 return result;
00623 }