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