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 <FourNodeQuad.h>
00032 #include <Node.h>
00033 #include <NDMaterial.h>
00034 #include <Matrix.h>
00035 #include <Vector.h>
00036 #include <ID.h>
00037 #include <Renderer.h>
00038 #include <Domain.h>
00039 #include <string.h>
00040 #include <Information.h>
00041 #include <Parameter.h>
00042 #include <Channel.h>
00043 #include <FEM_ObjectBroker.h>
00044 #include <ElementResponse.h>
00045
00046
00047 double FourNodeQuad::matrixData[64];
00048 Matrix FourNodeQuad::K(matrixData, 8, 8);
00049 Vector FourNodeQuad::P(8);
00050 double FourNodeQuad::shp[3][4];
00051 double FourNodeQuad::pts[4][2];
00052 double FourNodeQuad::wts[4];
00053
00054 FourNodeQuad::FourNodeQuad(int tag, int nd1, int nd2, int nd3, int nd4,
00055 NDMaterial &m, const char *type, double t,
00056 double p, double r, double b1, double b2)
00057 :Element (tag, ELE_TAG_FourNodeQuad),
00058 theMaterial(0), connectedExternalNodes(4),
00059 Q(8), pressureLoad(8), thickness(t), rho(r), pressure(p), Ki(0)
00060 {
00061 pts[0][0] = -0.5773502691896258;
00062 pts[0][1] = -0.5773502691896258;
00063 pts[1][0] = 0.5773502691896258;
00064 pts[1][1] = -0.5773502691896258;
00065 pts[2][0] = 0.5773502691896258;
00066 pts[2][1] = 0.5773502691896258;
00067 pts[3][0] = -0.5773502691896258;
00068 pts[3][1] = 0.5773502691896258;
00069
00070 wts[0] = 1.0;
00071 wts[1] = 1.0;
00072 wts[2] = 1.0;
00073 wts[3] = 1.0;
00074
00075 if (strcmp(type,"PlaneStrain") != 0 && strcmp(type,"PlaneStress") != 0
00076 && strcmp(type,"PlaneStrain2D") != 0 && strcmp(type,"PlaneStress2D") != 0) {
00077 opserr << "FourNodeQuad::FourNodeQuad -- improper material type: " << type << "for FourNodeQuad\n";
00078 exit(-1);
00079 }
00080
00081
00082 b[0] = b1;
00083 b[1] = b2;
00084
00085
00086 theMaterial = new NDMaterial *[4];
00087
00088 if (theMaterial == 0) {
00089 opserr << "FourNodeQuad::FourNodeQuad - failed allocate material model pointer\n";
00090 exit(-1);
00091 }
00092
00093 int i;
00094 for (i = 0; i < 4; i++) {
00095
00096
00097 theMaterial[i] = m.getCopy(type);
00098
00099
00100 if (theMaterial[i] == 0) {
00101 opserr << "FourNodeQuad::FourNodeQuad -- failed to get a copy of material model\n";
00102 exit(-1);
00103 }
00104 }
00105
00106
00107 connectedExternalNodes(0) = nd1;
00108 connectedExternalNodes(1) = nd2;
00109 connectedExternalNodes(2) = nd3;
00110 connectedExternalNodes(3) = nd4;
00111
00112 for (i=0; i<4; i++)
00113 theNodes[i] = 0;
00114 }
00115
00116 FourNodeQuad::FourNodeQuad()
00117 :Element (0,ELE_TAG_FourNodeQuad),
00118 theMaterial(0), connectedExternalNodes(4),
00119 Q(8), pressureLoad(8), thickness(0.0), rho(0.0), pressure(0.0), Ki(0)
00120 {
00121 pts[0][0] = -0.577350269189626;
00122 pts[0][1] = -0.577350269189626;
00123 pts[1][0] = 0.577350269189626;
00124 pts[1][1] = -0.577350269189626;
00125 pts[2][0] = 0.577350269189626;
00126 pts[2][1] = 0.577350269189626;
00127 pts[3][0] = -0.577350269189626;
00128 pts[3][1] = 0.577350269189626;
00129
00130 wts[0] = 1.0;
00131 wts[1] = 1.0;
00132 wts[2] = 1.0;
00133 wts[3] = 1.0;
00134
00135 for (int i=0; i<4; i++)
00136 theNodes[i] = 0;
00137 }
00138
00139 FourNodeQuad::~FourNodeQuad()
00140 {
00141 for (int i = 0; i < 4; i++) {
00142 if (theMaterial[i])
00143 delete theMaterial[i];
00144 }
00145
00146
00147 if (theMaterial)
00148 delete [] theMaterial;
00149
00150 if (Ki != 0)
00151 delete Ki;
00152 }
00153
00154 int
00155 FourNodeQuad::getNumExternalNodes() const
00156 {
00157 return 4;
00158 }
00159
00160 const ID&
00161 FourNodeQuad::getExternalNodes()
00162 {
00163 return connectedExternalNodes;
00164 }
00165
00166
00167 Node **
00168 FourNodeQuad::getNodePtrs(void)
00169 {
00170 return theNodes;
00171 }
00172
00173 int
00174 FourNodeQuad::getNumDOF()
00175 {
00176 return 8;
00177 }
00178
00179 void
00180 FourNodeQuad::setDomain(Domain *theDomain)
00181 {
00182
00183 if (theDomain == 0) {
00184 theNodes[0] = 0;
00185 theNodes[1] = 0;
00186 theNodes[2] = 0;
00187 theNodes[3] = 0;
00188 return;
00189 }
00190
00191 int Nd1 = connectedExternalNodes(0);
00192 int Nd2 = connectedExternalNodes(1);
00193 int Nd3 = connectedExternalNodes(2);
00194 int Nd4 = connectedExternalNodes(3);
00195
00196 theNodes[0] = theDomain->getNode(Nd1);
00197 theNodes[1] = theDomain->getNode(Nd2);
00198 theNodes[2] = theDomain->getNode(Nd3);
00199 theNodes[3] = theDomain->getNode(Nd4);
00200
00201 if (theNodes[0] == 0 || theNodes[1] == 0 || theNodes[2] == 0 || theNodes[3] == 0) {
00202
00203
00204
00205 return;
00206 }
00207
00208 int dofNd1 = theNodes[0]->getNumberDOF();
00209 int dofNd2 = theNodes[1]->getNumberDOF();
00210 int dofNd3 = theNodes[2]->getNumberDOF();
00211 int dofNd4 = theNodes[3]->getNumberDOF();
00212
00213 if (dofNd1 != 2 || dofNd2 != 2 || dofNd3 != 2 || dofNd4 != 2) {
00214
00215
00216
00217 return;
00218 }
00219 this->DomainComponent::setDomain(theDomain);
00220
00221
00222 this->setPressureLoadAtNodes();
00223 }
00224
00225 int
00226 FourNodeQuad::commitState()
00227 {
00228 int retVal = 0;
00229
00230
00231 if ((retVal = this->Element::commitState()) != 0) {
00232 opserr << "FourNodeQuad::commitState () - failed in base class";
00233 }
00234
00235
00236 for (int i = 0; i < 4; i++)
00237 retVal += theMaterial[i]->commitState();
00238
00239 return retVal;
00240 }
00241
00242 int
00243 FourNodeQuad::revertToLastCommit()
00244 {
00245 int retVal = 0;
00246
00247
00248 for (int i = 0; i < 4; i++)
00249 retVal += theMaterial[i]->revertToLastCommit();
00250
00251 return retVal;
00252 }
00253
00254 int
00255 FourNodeQuad::revertToStart()
00256 {
00257 int retVal = 0;
00258
00259
00260 for (int i = 0; i < 4; i++)
00261 retVal += theMaterial[i]->revertToStart();
00262
00263 return retVal;
00264 }
00265
00266
00267 int
00268 FourNodeQuad::update()
00269 {
00270 const Vector &disp1 = theNodes[0]->getTrialDisp();
00271 const Vector &disp2 = theNodes[1]->getTrialDisp();
00272 const Vector &disp3 = theNodes[2]->getTrialDisp();
00273 const Vector &disp4 = theNodes[3]->getTrialDisp();
00274
00275 static double u[2][4];
00276
00277 u[0][0] = disp1(0);
00278 u[1][0] = disp1(1);
00279 u[0][1] = disp2(0);
00280 u[1][1] = disp2(1);
00281 u[0][2] = disp3(0);
00282 u[1][2] = disp3(1);
00283 u[0][3] = disp4(0);
00284 u[1][3] = disp4(1);
00285
00286 static Vector eps(3);
00287
00288 int ret = 0;
00289
00290
00291 for (int i = 0; i < 4; i++) {
00292
00293
00294 this->shapeFunction(pts[i][0], pts[i][1]);
00295
00296
00297
00298
00299 eps.Zero();
00300 for (int beta = 0; beta < 4; beta++) {
00301 eps(0) += shp[0][beta]*u[0][beta];
00302 eps(1) += shp[1][beta]*u[1][beta];
00303 eps(2) += shp[0][beta]*u[1][beta] + shp[1][beta]*u[0][beta];
00304 }
00305
00306
00307 ret += theMaterial[i]->setTrialStrain(eps);
00308 }
00309
00310 return ret;
00311 }
00312
00313
00314 const Matrix&
00315 FourNodeQuad::getTangentStiff()
00316 {
00317
00318 K.Zero();
00319
00320 double dvol;
00321 double DB[3][2];
00322
00323
00324 for (int i = 0; i < 4; i++) {
00325
00326
00327 dvol = this->shapeFunction(pts[i][0], pts[i][1]);
00328 dvol *= (thickness*wts[i]);
00329
00330
00331 const Matrix &D = theMaterial[i]->getTangent();
00332
00333
00334
00335
00336
00337 double D00 = D(0,0); double D01 = D(0,1); double D02 = D(0,2);
00338 double D10 = D(1,0); double D11 = D(1,1); double D12 = D(1,2);
00339 double D20 = D(2,0); double D21 = D(2,1); double D22 = D(2,2);
00340
00341
00342
00343
00344
00345 for (int alpha = 0, ia = 0; alpha < 4; alpha++, ia += 2) {
00346 for (int beta = 0, ib = 0; beta < 4; beta++, ib += 2) {
00347
00348 DB[0][0] = dvol * (D00 * shp[0][beta] + D02 * shp[1][beta]);
00349 DB[1][0] = dvol * (D10 * shp[0][beta] + D12 * shp[1][beta]);
00350 DB[2][0] = dvol * (D20 * shp[0][beta] + D22 * shp[1][beta]);
00351 DB[0][1] = dvol * (D01 * shp[1][beta] + D02 * shp[0][beta]);
00352 DB[1][1] = dvol * (D11 * shp[1][beta] + D12 * shp[0][beta]);
00353 DB[2][1] = dvol * (D21 * shp[1][beta] + D22 * shp[0][beta]);
00354
00355
00356 K(ia,ib) += shp[0][alpha]*DB[0][0] + shp[1][alpha]*DB[2][0];
00357 K(ia,ib+1) += shp[0][alpha]*DB[0][1] + shp[1][alpha]*DB[2][1];
00358 K(ia+1,ib) += shp[1][alpha]*DB[1][0] + shp[0][alpha]*DB[2][0];
00359 K(ia+1,ib+1) += shp[1][alpha]*DB[1][1] + shp[0][alpha]*DB[2][1];
00360
00361
00362
00363
00364
00365 }
00366 }
00367 }
00368
00369 return K;
00370 }
00371
00372
00373 const Matrix&
00374 FourNodeQuad::getInitialStiff()
00375 {
00376 if (Ki != 0)
00377 return *Ki;
00378
00379 K.Zero();
00380
00381 double dvol;
00382 double DB[3][2];
00383
00384
00385 for (int i = 0; i < 4; i++) {
00386
00387
00388 dvol = this->shapeFunction(pts[i][0], pts[i][1]);
00389 dvol *= (thickness*wts[i]);
00390
00391
00392 const Matrix &D = theMaterial[i]->getInitialTangent();
00393
00394 double D00 = D(0,0); double D01 = D(0,1); double D02 = D(0,2);
00395 double D10 = D(1,0); double D11 = D(1,1); double D12 = D(1,2);
00396 double D20 = D(2,0); double D21 = D(2,1); double D22 = D(2,2);
00397
00398
00399
00400
00401 for (int beta = 0, ib = 0, colIb =0, colIbP1 = 8;
00402 beta < 4;
00403 beta++, ib += 2, colIb += 16, colIbP1 += 16) {
00404
00405 for (int alpha = 0, ia = 0; alpha < 4; alpha++, ia += 2) {
00406
00407 DB[0][0] = dvol * (D00 * shp[0][beta] + D02 * shp[1][beta]);
00408 DB[1][0] = dvol * (D10 * shp[0][beta] + D12 * shp[1][beta]);
00409 DB[2][0] = dvol * (D20 * shp[0][beta] + D22 * shp[1][beta]);
00410 DB[0][1] = dvol * (D01 * shp[1][beta] + D02 * shp[0][beta]);
00411 DB[1][1] = dvol * (D11 * shp[1][beta] + D12 * shp[0][beta]);
00412 DB[2][1] = dvol * (D21 * shp[1][beta] + D22 * shp[0][beta]);
00413
00414 matrixData[colIb + ia] += shp[0][alpha]*DB[0][0] + shp[1][alpha]*DB[2][0];
00415 matrixData[colIbP1 + ia] += shp[0][alpha]*DB[0][1] + shp[1][alpha]*DB[2][1];
00416 matrixData[colIb + ia+1] += shp[1][alpha]*DB[1][0] + shp[0][alpha]*DB[2][0];
00417 matrixData[colIbP1 + ia+1] += shp[1][alpha]*DB[1][1] + shp[0][alpha]*DB[2][1];
00418 }
00419 }
00420 }
00421
00422 Ki = new Matrix(K);
00423 return K;
00424 }
00425
00426 const Matrix&
00427 FourNodeQuad::getMass()
00428 {
00429 K.Zero();
00430
00431 int i;
00432 static double rhoi[4];
00433 double sum = this->rho;
00434 for (i = 0; i < 4; i++) {
00435 rhoi[i] = theMaterial[i]->getRho();
00436 sum += rhoi[i];
00437 }
00438
00439 if (sum == 0.0)
00440 return K;
00441
00442 double rhodvol, Nrho;
00443
00444
00445 for (i = 0; i < 4; i++) {
00446
00447
00448 rhodvol = this->shapeFunction(pts[i][0], pts[i][1]);
00449
00450
00451 double tmp = rho + rhoi[i];
00452 rhodvol *= (tmp*thickness*wts[i]);
00453
00454 for (int alpha = 0, ia = 0; alpha < 4; alpha++, ia++) {
00455 Nrho = shp[2][alpha]*rhodvol;
00456 K(ia,ia) += Nrho;
00457 ia++;
00458 K(ia,ia) += Nrho;
00459 }
00460 }
00461
00462 return K;
00463 }
00464
00465 void
00466 FourNodeQuad::zeroLoad(void)
00467 {
00468 Q.Zero();
00469 return;
00470 }
00471
00472 int
00473 FourNodeQuad::addLoad(ElementalLoad *theLoad, double loadFactor)
00474 {
00475 opserr << "FourNodeQuad::addLoad - load type unknown for ele with tag: " << this->getTag() << endln;
00476 return -1;
00477 }
00478
00479 int
00480 FourNodeQuad::addInertiaLoadToUnbalance(const Vector &accel)
00481 {
00482 int i;
00483 static double rhoi[4];
00484 double sum = this->rho;
00485 for (i = 0; i < 4; i++) {
00486 rhoi[i] = theMaterial[i]->getRho();
00487 sum += rhoi[i];
00488 }
00489
00490 if (sum == 0.0)
00491 return 0;
00492
00493
00494 const Vector &Raccel1 = theNodes[0]->getRV(accel);
00495 const Vector &Raccel2 = theNodes[1]->getRV(accel);
00496 const Vector &Raccel3 = theNodes[2]->getRV(accel);
00497 const Vector &Raccel4 = theNodes[3]->getRV(accel);
00498
00499 if (2 != Raccel1.Size() || 2 != Raccel2.Size() || 2 != Raccel3.Size() ||
00500 2 != Raccel4.Size()) {
00501 opserr << "FourNodeQuad::addInertiaLoadToUnbalance matrix and vector sizes are incompatable\n";
00502 return -1;
00503 }
00504
00505 static double ra[8];
00506
00507 ra[0] = Raccel1(0);
00508 ra[1] = Raccel1(1);
00509 ra[2] = Raccel2(0);
00510 ra[3] = Raccel2(1);
00511 ra[4] = Raccel3(0);
00512 ra[5] = Raccel3(1);
00513 ra[6] = Raccel4(0);
00514 ra[7] = Raccel4(1);
00515
00516
00517 this->getMass();
00518
00519
00520
00521 for (i = 0; i < 8; i++)
00522 Q(i) += -K(i,i)*ra[i];
00523
00524 return 0;
00525 }
00526
00527 const Vector&
00528 FourNodeQuad::getResistingForce()
00529 {
00530 P.Zero();
00531
00532 double dvol;
00533
00534
00535 for (int i = 0; i < 4; i++) {
00536
00537
00538 dvol = this->shapeFunction(pts[i][0], pts[i][1]);
00539 dvol *= (thickness*wts[i]);
00540
00541
00542 const Vector &sigma = theMaterial[i]->getStress();
00543
00544
00545
00546
00547 for (int alpha = 0, ia = 0; alpha < 4; alpha++, ia += 2) {
00548
00549 P(ia) += dvol*(shp[0][alpha]*sigma(0) + shp[1][alpha]*sigma(2));
00550
00551 P(ia+1) += dvol*(shp[1][alpha]*sigma(1) + shp[0][alpha]*sigma(2));
00552
00553
00554
00555
00556 P(ia) -= dvol*(shp[2][alpha]*b[0]);
00557 P(ia+1) -= dvol*(shp[2][alpha]*b[1]);
00558 }
00559 }
00560
00561
00562 if (pressure != 0.0) {
00563
00564 P.addVector(1.0, pressureLoad, -1.0);
00565 }
00566
00567
00568
00569 P.addVector(1.0, Q, -1.0);
00570
00571 return P;
00572 }
00573
00574 const Vector&
00575 FourNodeQuad::getResistingForceIncInertia()
00576 {
00577 int i;
00578 static double rhoi[4];
00579 double sum = this->rho;
00580 for (i = 0; i < 4; i++) {
00581 rhoi[i] = theMaterial[i]->getRho();
00582 sum += rhoi[i];
00583 }
00584
00585
00586 if (sum == 0.0) {
00587 this->getResistingForce();
00588
00589
00590 if (betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
00591 P += this->getRayleighDampingForces();
00592
00593 return P;
00594 }
00595
00596 const Vector &accel1 = theNodes[0]->getTrialAccel();
00597 const Vector &accel2 = theNodes[1]->getTrialAccel();
00598 const Vector &accel3 = theNodes[2]->getTrialAccel();
00599 const Vector &accel4 = theNodes[3]->getTrialAccel();
00600
00601 static double a[8];
00602
00603 a[0] = accel1(0);
00604 a[1] = accel1(1);
00605 a[2] = accel2(0);
00606 a[3] = accel2(1);
00607 a[4] = accel3(0);
00608 a[5] = accel3(1);
00609 a[6] = accel4(0);
00610 a[7] = accel4(1);
00611
00612
00613 this->getResistingForce();
00614
00615
00616 this->getMass();
00617
00618
00619 for (i = 0; i < 8; i++)
00620 P(i) += K(i,i)*a[i];
00621
00622
00623 if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
00624 P += this->getRayleighDampingForces();
00625
00626 return P;
00627 }
00628
00629 int
00630 FourNodeQuad::sendSelf(int commitTag, Channel &theChannel)
00631 {
00632 int res = 0;
00633
00634
00635
00636
00637 int dataTag = this->getDbTag();
00638
00639
00640
00641 static Vector data(6);
00642 data(0) = this->getTag();
00643 data(1) = thickness;
00644 data(2) = rho;
00645 data(3) = b[0];
00646 data(4) = b[1];
00647 data(5) = pressure;
00648
00649 res += theChannel.sendVector(dataTag, commitTag, data);
00650 if (res < 0) {
00651 opserr << "WARNING FourNodeQuad::sendSelf() - " << this->getTag() << " failed to send Vector\n";
00652 return res;
00653 }
00654
00655
00656
00657 int matDbTag;
00658
00659 static ID idData(12);
00660
00661 int i;
00662 for (i = 0; i < 4; i++) {
00663 idData(i) = theMaterial[i]->getClassTag();
00664 matDbTag = theMaterial[i]->getDbTag();
00665
00666
00667 if (matDbTag == 0) {
00668 matDbTag = theChannel.getDbTag();
00669 if (matDbTag != 0)
00670 theMaterial[i]->setDbTag(matDbTag);
00671 }
00672 idData(i+4) = matDbTag;
00673 }
00674
00675 idData(8) = connectedExternalNodes(0);
00676 idData(9) = connectedExternalNodes(1);
00677 idData(10) = connectedExternalNodes(2);
00678 idData(11) = connectedExternalNodes(3);
00679
00680 res += theChannel.sendID(dataTag, commitTag, idData);
00681 if (res < 0) {
00682 opserr << "WARNING FourNodeQuad::sendSelf() - " << this->getTag() << " failed to send ID\n";
00683 return res;
00684 }
00685
00686
00687 for (i = 0; i < 4; i++) {
00688 res += theMaterial[i]->sendSelf(commitTag, theChannel);
00689 if (res < 0) {
00690 opserr << "WARNING FourNodeQuad::sendSelf() - " << this->getTag() << " failed to send its Material\n";
00691 return res;
00692 }
00693 }
00694
00695 return res;
00696 }
00697
00698 int
00699 FourNodeQuad::recvSelf(int commitTag, Channel &theChannel,
00700 FEM_ObjectBroker &theBroker)
00701 {
00702 int res = 0;
00703
00704 int dataTag = this->getDbTag();
00705
00706
00707
00708 static Vector data(6);
00709 res += theChannel.recvVector(dataTag, commitTag, data);
00710 if (res < 0) {
00711 opserr << "WARNING FourNodeQuad::recvSelf() - failed to receive Vector\n";
00712 return res;
00713 }
00714
00715 this->setTag((int)data(0));
00716 thickness = data(1);
00717 rho = data(2);
00718 b[0] = data(3);
00719 b[1] = data(4);
00720 pressure = data(5);
00721
00722 static ID idData(12);
00723
00724 res += theChannel.recvID(dataTag, commitTag, idData);
00725 if (res < 0) {
00726 opserr << "WARNING FourNodeQuad::recvSelf() - " << this->getTag() << " failed to receive ID\n";
00727 return res;
00728 }
00729
00730 connectedExternalNodes(0) = idData(8);
00731 connectedExternalNodes(1) = idData(9);
00732 connectedExternalNodes(2) = idData(10);
00733 connectedExternalNodes(3) = idData(11);
00734
00735
00736 if (theMaterial == 0) {
00737
00738 theMaterial = new NDMaterial *[4];
00739 if (theMaterial == 0) {
00740 opserr << "FourNodeQuad::recvSelf() - Could not allocate NDMaterial* array\n";
00741 return -1;
00742 }
00743 for (int i = 0; i < 4; i++) {
00744 int matClassTag = idData(i);
00745 int matDbTag = idData(i+4);
00746
00747 theMaterial[i] = theBroker.getNewNDMaterial(matClassTag);
00748 if (theMaterial[i] == 0) {
00749 opserr << "FourNodeQuad::recvSelf() - Broker could not create NDMaterial of class type " << matClassTag << endln;
00750 return -1;
00751 }
00752
00753 theMaterial[i]->setDbTag(matDbTag);
00754 res += theMaterial[i]->recvSelf(commitTag, theChannel, theBroker);
00755 if (res < 0) {
00756 opserr << "NLBeamColumn3d::recvSelf() - material " << i << "failed to recv itself\n";
00757 return res;
00758 }
00759 }
00760 }
00761
00762
00763 else {
00764 for (int i = 0; i < 4; i++) {
00765 int matClassTag = idData(i);
00766 int matDbTag = idData(i+4);
00767
00768
00769 if (theMaterial[i]->getClassTag() != matClassTag) {
00770 delete theMaterial[i];
00771 theMaterial[i] = theBroker.getNewNDMaterial(matClassTag);
00772 if (theMaterial[i] == 0) {
00773 opserr << "NLBeamColumn3d::recvSelf() - material " << i << "failed to create\n";
00774
00775 return -1;
00776 }
00777 }
00778
00779 theMaterial[i]->setDbTag(matDbTag);
00780 res += theMaterial[i]->recvSelf(commitTag, theChannel, theBroker);
00781 if (res < 0) {
00782 opserr << "NLBeamColumn3d::recvSelf() - material " << i << "failed to recv itself\n";
00783 return res;
00784 }
00785 }
00786 }
00787
00788 return res;
00789 }
00790
00791 void
00792 FourNodeQuad::Print(OPS_Stream &s, int flag)
00793 {
00794 if (flag == 2) {
00795
00796 s << "#FourNodeQuad\n";
00797
00798 int i;
00799 const int numNodes = 4;
00800 const int nstress = 3 ;
00801
00802 for (i=0; i<numNodes; i++) {
00803 const Vector &nodeCrd = theNodes[i]->getCrds();
00804 const Vector &nodeDisp = theNodes[i]->getDisp();
00805 s << "#NODE " << nodeCrd(0) << " " << nodeCrd(1) << " " << endln;
00806 }
00807
00808
00809 const int numMaterials = 4;
00810
00811 static Vector avgStress(nstress);
00812 static Vector avgStrain(nstress);
00813 avgStress.Zero();
00814 avgStrain.Zero();
00815 for (i=0; i<numMaterials; i++) {
00816 avgStress += theMaterial[i]->getCommittedStress();
00817 avgStrain += theMaterial[i]->getCommittedStrain();
00818 }
00819 avgStress /= numMaterials;
00820 avgStrain /= numMaterials;
00821
00822 s << "#AVERAGE_STRESS ";
00823 for (i=0; i<nstress; i++)
00824 s << avgStress(i) << " " ;
00825 s << endln;
00826
00827 s << "#AVERAGE_STRAIN ";
00828 for (i=0; i<nstress; i++)
00829 s << avgStrain(i) << " " ;
00830 s << endln;
00831
00832 } else {
00833 s << "\nFourNodeQuad, element id: " << this->getTag() << endln;
00834 s << "\tConnected external nodes: " << connectedExternalNodes;
00835 s << "\tthickness: " << thickness << endln;
00836 s << "\tmass density: " << rho << endln;
00837 s << "\tsurface pressure: " << pressure << endln;
00838 s << "\tbody forces: " << b[0] << " " << b[1] << endln;
00839 theMaterial[0]->Print(s,flag);
00840 s << "\tStress (xx yy xy)" << endln;
00841 for (int i = 0; i < 4; i++)
00842 s << "\t\tGauss point " << i+1 << ": " << theMaterial[i]->getStress();
00843 }
00844 }
00845
00846 int
00847 FourNodeQuad::displaySelf(Renderer &theViewer, int displayMode, float fact)
00848 {
00849
00850
00851
00852
00853 static Vector values(4);
00854
00855 for (int j=0; j<4; j++)
00856 values(j) = 0.0;
00857
00858 if (displayMode < 4 && displayMode > 0) {
00859 for (int i=0; i<4; i++) {
00860 const Vector &stress = theMaterial[i]->getStress();
00861 values(i) = stress(displayMode-1);
00862 }
00863 }
00864
00865
00866
00867
00868 const Vector &end1Crd = theNodes[0]->getCrds();
00869 const Vector &end2Crd = theNodes[1]->getCrds();
00870 const Vector &end3Crd = theNodes[2]->getCrds();
00871 const Vector &end4Crd = theNodes[3]->getCrds();
00872
00873 static Matrix coords(4,3);
00874
00875 if (displayMode >= 0) {
00876
00877 const Vector &end1Disp = theNodes[0]->getDisp();
00878 const Vector &end2Disp = theNodes[1]->getDisp();
00879 const Vector &end3Disp = theNodes[2]->getDisp();
00880 const Vector &end4Disp = theNodes[3]->getDisp();
00881
00882 for (int i = 0; i < 2; i++) {
00883 coords(0,i) = end1Crd(i) + end1Disp(i)*fact;
00884 coords(1,i) = end2Crd(i) + end2Disp(i)*fact;
00885 coords(2,i) = end3Crd(i) + end3Disp(i)*fact;
00886 coords(3,i) = end4Crd(i) + end4Disp(i)*fact;
00887 }
00888 } else {
00889 int mode = displayMode * -1;
00890 const Matrix &eigen1 = theNodes[0]->getEigenvectors();
00891 const Matrix &eigen2 = theNodes[1]->getEigenvectors();
00892 const Matrix &eigen3 = theNodes[2]->getEigenvectors();
00893 const Matrix &eigen4 = theNodes[3]->getEigenvectors();
00894 if (eigen1.noCols() >= mode) {
00895 for (int i = 0; i < 2; i++) {
00896 coords(0,i) = end1Crd(i) + eigen1(i,mode-1)*fact;
00897 coords(1,i) = end2Crd(i) + eigen2(i,mode-1)*fact;
00898 coords(2,i) = end3Crd(i) + eigen3(i,mode-1)*fact;
00899 coords(3,i) = end4Crd(i) + eigen4(i,mode-1)*fact;
00900 }
00901 } else {
00902 for (int i = 0; i < 2; i++) {
00903 coords(0,i) = end1Crd(i);
00904 coords(1,i) = end2Crd(i);
00905 coords(2,i) = end3Crd(i);
00906 coords(3,i) = end4Crd(i);
00907 }
00908 }
00909 }
00910
00911 int error = 0;
00912
00913
00914 error += theViewer.drawPolygon (coords, values);
00915
00916 return error;
00917 }
00918
00919 Response*
00920 FourNodeQuad::setResponse(const char **argv, int argc,
00921 Information &eleInfo, OPS_Stream &output)
00922 {
00923 Response *theResponse =0;
00924
00925 output.tag("ElementOutput");
00926 output.attr("eleType","FourNodeQuad");
00927 output.attr("eleTag",this->getTag());
00928 output.attr("node1",connectedExternalNodes[0]);
00929 output.attr("node2",connectedExternalNodes[1]);
00930 output.attr("node3",connectedExternalNodes[2]);
00931 output.attr("node4",connectedExternalNodes[3]);
00932
00933 char dataOut[10];
00934 if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0) {
00935
00936 for (int i=1; i<=4; i++) {
00937 sprintf(dataOut,"P1_%d",i);
00938 output.tag("ResponseType",dataOut);
00939 sprintf(dataOut,"P2_%d",i);
00940 output.tag("ResponseType",dataOut);
00941 }
00942
00943 theResponse = new ElementResponse(this, 1, P);
00944 } else if (strcmp(argv[0],"material") == 0 || strcmp(argv[0],"integrPoint") == 0) {
00945 int pointNum = atoi(argv[1]);
00946 if (pointNum > 0 && pointNum <= 4) {
00947
00948 output.tag("GaussPoint");
00949 output.attr("number",pointNum);
00950 output.attr("eta",pts[pointNum-1][0]);
00951 output.attr("neta",pts[pointNum-1][1]);
00952
00953 theResponse = theMaterial[pointNum-1]->setResponse(&argv[2], argc-2, eleInfo, output);
00954
00955 output.endTag();
00956
00957 } else if (strcmp(argv[0],"stresses") ==0) {
00958
00959 for (int i=0; i<4; i++) {
00960 output.tag("GaussPoint");
00961 output.attr("number",i+1);
00962 output.attr("eta",pts[i][0]);
00963 output.attr("neta",pts[i][1]);
00964
00965 output.tag("NdMaterialOutput");
00966 output.attr("classType", theMaterial[i]->getClassTag());
00967 output.attr("tag", theMaterial[i]->getTag());
00968
00969 output.tag("ResponseType","sigma11");
00970 output.tag("ResponseType","sigma22");
00971 output.tag("ResponseType","sigma12");
00972
00973 output.endTag();
00974 output.endTag();
00975 }
00976
00977 theResponse = new ElementResponse(this, 3, Vector(12));
00978 }
00979 }
00980
00981 output.endTag();
00982
00983 return theResponse;
00984 }
00985
00986 int
00987 FourNodeQuad::getResponse(int responseID, Information &eleInfo)
00988 {
00989 if (responseID == 1) {
00990
00991 return eleInfo.setVector(this->getResistingForce());
00992
00993 } else if (responseID == 3) {
00994
00995
00996 static Vector stresses(12);
00997 int cnt = 0;
00998 for (int i = 0; i < 4; i++) {
00999
01000
01001 const Vector &sigma = theMaterial[i]->getStress();
01002 stresses(cnt) = sigma(0);
01003 stresses(cnt+1) = sigma(1);
01004 stresses(cnt+2) = sigma(2);
01005 cnt += 3;
01006 }
01007 return eleInfo.setVector(stresses);
01008
01009 } else
01010
01011 return -1;
01012 }
01013
01014 int
01015 FourNodeQuad::setParameter(const char **argv, int argc, Parameter ¶m)
01016 {
01017 if (argc < 1)
01018 return -1;
01019
01020
01021 if (strcmp(argv[0],"rho") == 0)
01022 return param.addObject(1, this);
01023
01024
01025 if (strcmp(argv[0],"pressure") == 0)
01026 return param.addObject(2, this);
01027
01028
01029 else if (strstr(argv[0],"material") != 0) {
01030
01031 if (argc < 3)
01032 return -1;
01033
01034 int pointNum = atoi(argv[1]);
01035 if (pointNum > 0 && pointNum <= 4)
01036 return theMaterial[pointNum-1]->setParameter(&argv[2], argc-2, param);
01037 else
01038 return -1;
01039 }
01040
01041
01042 else
01043 return -1;
01044 }
01045
01046 int
01047 FourNodeQuad::updateParameter(int parameterID, Information &info)
01048 {
01049 switch (parameterID) {
01050 case -1:
01051 return -1;
01052
01053 case 1:
01054 rho = info.theDouble;
01055 this->getMass();
01056 return 0;
01057 case 2:
01058 pressure = info.theDouble;
01059 this->setPressureLoadAtNodes();
01060 return 0;
01061 default:
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071 return -1;
01072 }
01073 }
01074
01075 double FourNodeQuad::shapeFunction(double xi, double eta)
01076 {
01077 const Vector &nd1Crds = theNodes[0]->getCrds();
01078 const Vector &nd2Crds = theNodes[1]->getCrds();
01079 const Vector &nd3Crds = theNodes[2]->getCrds();
01080 const Vector &nd4Crds = theNodes[3]->getCrds();
01081
01082 double oneMinuseta = 1.0-eta;
01083 double onePluseta = 1.0+eta;
01084 double oneMinusxi = 1.0-xi;
01085 double onePlusxi = 1.0+xi;
01086
01087 shp[2][0] = 0.25*oneMinusxi*oneMinuseta;
01088 shp[2][1] = 0.25*onePlusxi*oneMinuseta;
01089 shp[2][2] = 0.25*onePlusxi*onePluseta;
01090 shp[2][3] = 0.25*oneMinusxi*onePluseta;
01091
01092 double J[2][2];
01093
01094 J[0][0] = 0.25 * (-nd1Crds(0)*oneMinuseta + nd2Crds(0)*oneMinuseta +
01095 nd3Crds(0)*(onePluseta) - nd4Crds(0)*(onePluseta));
01096
01097 J[0][1] = 0.25 * (-nd1Crds(0)*oneMinusxi - nd2Crds(0)*onePlusxi +
01098 nd3Crds(0)*onePlusxi + nd4Crds(0)*oneMinusxi);
01099
01100 J[1][0] = 0.25 * (-nd1Crds(1)*oneMinuseta + nd2Crds(1)*oneMinuseta +
01101 nd3Crds(1)*onePluseta - nd4Crds(1)*onePluseta);
01102
01103 J[1][1] = 0.25 * (-nd1Crds(1)*oneMinusxi - nd2Crds(1)*onePlusxi +
01104 nd3Crds(1)*onePlusxi + nd4Crds(1)*oneMinusxi);
01105
01106 double detJ = J[0][0]*J[1][1] - J[0][1]*J[1][0];
01107 double oneOverdetJ = 1.0/detJ;
01108 double L[2][2];
01109
01110
01111 L[0][0] = J[1][1]*oneOverdetJ;
01112 L[1][0] = -J[0][1]*oneOverdetJ;
01113 L[0][1] = -J[1][0]*oneOverdetJ;
01114 L[1][1] = J[0][0]*oneOverdetJ;
01115
01116 double L00 = 0.25*L[0][0];
01117 double L10 = 0.25*L[1][0];
01118 double L01 = 0.25*L[0][1];
01119 double L11 = 0.25*L[1][1];
01120
01121 double L00oneMinuseta = L00*oneMinuseta;
01122 double L00onePluseta = L00*onePluseta;
01123 double L01oneMinusxi = L01*oneMinusxi;
01124 double L01onePlusxi = L01*onePlusxi;
01125
01126 double L10oneMinuseta = L10*oneMinuseta;
01127 double L10onePluseta = L10*onePluseta;
01128 double L11oneMinusxi = L11*oneMinusxi;
01129 double L11onePlusxi = L11*onePlusxi;
01130
01131
01132 shp[0][0] = -L00oneMinuseta - L01oneMinusxi;
01133 shp[0][1] = L00oneMinuseta - L01onePlusxi;
01134 shp[0][2] = L00onePluseta + L01onePlusxi;
01135 shp[0][3] = -L00onePluseta + L01oneMinusxi;
01136
01137 shp[1][0] = -L10oneMinuseta - L11oneMinusxi;
01138 shp[1][1] = L10oneMinuseta - L11onePlusxi;
01139 shp[1][2] = L10onePluseta + L11onePlusxi;
01140 shp[1][3] = -L10onePluseta + L11oneMinusxi;
01141
01142 return detJ;
01143 }
01144
01145 void
01146 FourNodeQuad::setPressureLoadAtNodes(void)
01147 {
01148 pressureLoad.Zero();
01149
01150 if (pressure == 0.0)
01151 return;
01152
01153 const Vector &node1 = theNodes[0]->getCrds();
01154 const Vector &node2 = theNodes[1]->getCrds();
01155 const Vector &node3 = theNodes[2]->getCrds();
01156 const Vector &node4 = theNodes[3]->getCrds();
01157
01158 double x1 = node1(0);
01159 double y1 = node1(1);
01160 double x2 = node2(0);
01161 double y2 = node2(1);
01162 double x3 = node3(0);
01163 double y3 = node3(1);
01164 double x4 = node4(0);
01165 double y4 = node4(1);
01166
01167 double dx12 = x2-x1;
01168 double dy12 = y2-y1;
01169 double dx23 = x3-x2;
01170 double dy23 = y3-y2;
01171 double dx34 = x4-x3;
01172 double dy34 = y4-y3;
01173 double dx41 = x1-x4;
01174 double dy41 = y1-y4;
01175
01176 double pressureOver2 = pressure/2.0;
01177
01178
01179 pressureLoad(0) += pressureOver2*dy12;
01180 pressureLoad(2) += pressureOver2*dy12;
01181 pressureLoad(1) += pressureOver2*-dx12;
01182 pressureLoad(3) += pressureOver2*-dx12;
01183
01184
01185 pressureLoad(2) += pressureOver2*dy23;
01186 pressureLoad(4) += pressureOver2*dy23;
01187 pressureLoad(3) += pressureOver2*-dx23;
01188 pressureLoad(5) += pressureOver2*-dx23;
01189
01190
01191 pressureLoad(4) += pressureOver2*dy34;
01192 pressureLoad(6) += pressureOver2*dy34;
01193 pressureLoad(5) += pressureOver2*-dx34;
01194 pressureLoad(7) += pressureOver2*-dx34;
01195
01196
01197 pressureLoad(6) += pressureOver2*dy41;
01198 pressureLoad(0) += pressureOver2*dy41;
01199 pressureLoad(7) += pressureOver2*-dx41;
01200 pressureLoad(1) += pressureOver2*-dx41;
01201
01202
01203 }
01204
01205
01206
01207
01208
01209
01210
01211