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