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 #include <DispBeamColumn3d.h>
00031 #include <Node.h>
00032 #include <SectionForceDeformation.h>
00033 #include <GaussQuadRule1d01.h>
00034 #include <CrdTransf3d.h>
00035 #include <Matrix.h>
00036 #include <Vector.h>
00037 #include <ID.h>
00038 #include <Renderer.h>
00039 #include <Domain.h>
00040 #include <string.h>
00041 #include <Information.h>
00042 #include <Channel.h>
00043 #include <FEM_ObjectBroker.h>
00044 #include <ElementResponse.h>
00045
00046 #include <G3Globals.h>
00047
00048 Matrix DispBeamColumn3d::K(12,12);
00049 Vector DispBeamColumn3d::P(12);
00050 double DispBeamColumn3d::workArea[200];
00051
00052 DispBeamColumn3d::DispBeamColumn3d(int tag, int nd1, int nd2,
00053 int numSec, SectionForceDeformation &s,
00054 CrdTransf3d &coordTransf, double r)
00055 :Element (tag, ELE_TAG_DispBeamColumn3d), rho(r),
00056 Q(12), q(6), connectedExternalNodes(2), L(0.0),
00057 numSections(numSec), theSections(0), crdTransf(0)
00058 {
00059
00060 theSections = new SectionForceDeformation *[numSections];
00061
00062 if (theSections == 0)
00063 g3ErrorHandler->fatal("%s - failed to allocate section model pointer",
00064 "DispBeamColumn3d::DispBeamColumn3d");
00065
00066 for (int i = 0; i < numSections; i++) {
00067
00068
00069 theSections[i] = s.getCopy();
00070
00071
00072 if (theSections[i] == 0)
00073 g3ErrorHandler->fatal("%s -- failed to get a copy of section model",
00074 "DispBeamColumn3d::DispBeamColumn3d");
00075 }
00076
00077 crdTransf = coordTransf.getCopy();
00078
00079 if (crdTransf == 0)
00080 g3ErrorHandler->fatal("%s - failed to copy coordinate transformation",
00081 "DispBeamColumn3d::DispBeamColumn3d");
00082
00083
00084 connectedExternalNodes(0) = nd1;
00085 connectedExternalNodes(1) = nd2;
00086 }
00087
00088 DispBeamColumn3d::DispBeamColumn3d()
00089 :Element (0, ELE_TAG_DispBeamColumn3d), rho(0.0),
00090 Q(12), q(6), connectedExternalNodes(2), L(0.0),
00091 numSections(0), theSections(0), crdTransf(0)
00092 {
00093
00094 }
00095
00096 DispBeamColumn3d::~DispBeamColumn3d()
00097 {
00098 for (int i = 0; i < numSections; i++) {
00099 if (theSections[i])
00100 delete theSections[i];
00101 }
00102
00103
00104 if (theSections)
00105 delete [] theSections;
00106 }
00107
00108 int
00109 DispBeamColumn3d::getNumExternalNodes() const
00110 {
00111 return 2;
00112 }
00113
00114 const ID&
00115 DispBeamColumn3d::getExternalNodes()
00116 {
00117 return connectedExternalNodes;
00118 }
00119
00120 int
00121 DispBeamColumn3d::getNumDOF()
00122 {
00123 return 12;
00124 }
00125
00126 void
00127 DispBeamColumn3d::setDomain(Domain *theDomain)
00128 {
00129
00130 if (theDomain == 0) {
00131 nd1Ptr = 0;
00132 nd2Ptr = 0;
00133 return;
00134 }
00135
00136 int Nd1 = connectedExternalNodes(0);
00137 int Nd2 = connectedExternalNodes(1);
00138
00139 nd1Ptr = theDomain->getNode(Nd1);
00140 nd2Ptr = theDomain->getNode(Nd2);
00141
00142 if (nd1Ptr == 0 || nd2Ptr == 0) {
00143
00144
00145
00146 return;
00147 }
00148
00149 int dofNd1 = nd1Ptr->getNumberDOF();
00150 int dofNd2 = nd2Ptr->getNumberDOF();
00151
00152 if (dofNd1 != 6 || dofNd2 != 6) {
00153
00154
00155
00156 return;
00157 }
00158
00159 if (crdTransf->initialize(nd1Ptr, nd2Ptr)) {
00160
00161 }
00162
00163 L = crdTransf->getInitialLength();
00164
00165 if (L == 0.0) {
00166
00167 }
00168
00169 this->DomainComponent::setDomain(theDomain);
00170
00171 this->update();
00172 }
00173
00174 int
00175 DispBeamColumn3d::commitState()
00176 {
00177 int retVal = 0;
00178
00179
00180 for (int i = 0; i < numSections; i++)
00181 retVal += theSections[i]->commitState();
00182
00183 retVal += crdTransf->commitState();
00184
00185 return retVal;
00186 }
00187
00188 int
00189 DispBeamColumn3d::revertToLastCommit()
00190 {
00191 int retVal = 0;
00192
00193
00194 for (int i = 0; i < numSections; i++)
00195 retVal += theSections[i]->revertToLastCommit();
00196
00197 retVal += crdTransf->revertToLastCommit();
00198
00199 return retVal;
00200 }
00201
00202 int
00203 DispBeamColumn3d::revertToStart()
00204 {
00205 int retVal = 0;
00206
00207
00208 for (int i = 0; i < numSections; i++)
00209 retVal += theSections[i]->revertToStart();
00210
00211 retVal += crdTransf->revertToStart();
00212
00213 return retVal;
00214 }
00215
00216 int
00217 DispBeamColumn3d::update(void)
00218 {
00219
00220 crdTransf->update();
00221
00222
00223 static Vector v(6);
00224 v = crdTransf->getBasicTrialDisp();
00225
00226 double oneOverL = 1.0/L;
00227 GaussQuadRule1d01 quadrat(numSections);
00228 const Matrix &pts = quadrat.getIntegrPointCoords();
00229 const Vector &wts = quadrat.getIntegrPointWeights();
00230
00231
00232
00233 int order = theSections[0]->getOrder();
00234 const ID &code = theSections[0]->getType();
00235 Vector e(workArea, order);
00236
00237
00238 for (int i = 0; i < numSections; i++) {
00239
00240 double xi6 = 6.0*pts(i,0);
00241
00242 int j;
00243 for (j = 0; j < order; j++) {
00244 switch(code(j)) {
00245 case SECTION_RESPONSE_P:
00246 e(j) = oneOverL*v(0); break;
00247 case SECTION_RESPONSE_MZ:
00248 e(j) = oneOverL*((xi6-4.0)*v(1) + (xi6-2.0)*v(2)); break;
00249 case SECTION_RESPONSE_MY:
00250 e(j) = oneOverL*((xi6-4.0)*v(3) + (xi6-2.0)*v(4)); break;
00251 case SECTION_RESPONSE_T:
00252 e(j) = oneOverL*v(5); break;
00253 default:
00254 e(j) = 0.0; break;
00255 }
00256 }
00257
00258
00259 theSections[i]->setTrialSectionDeformation(e);
00260 }
00261
00262 return 0;
00263 }
00264
00265 const Matrix&
00266 DispBeamColumn3d::getTangentStiff()
00267 {
00268 static Matrix kb(6,6);
00269
00270
00271 kb.Zero();
00272 q.Zero();
00273
00274 GaussQuadRule1d01 quadrat(numSections);
00275 const Matrix &pts = quadrat.getIntegrPointCoords();
00276 const Vector &wts = quadrat.getIntegrPointWeights();
00277
00278
00279
00280 int order = theSections[0]->getOrder();
00281 const ID &code = theSections[0]->getType();
00282
00283 double oneOverL = 1.0/L;
00284 Matrix ka(workArea, order, 6);
00285
00286
00287 for (int i = 0; i < numSections; i++) {
00288
00289
00290 const Matrix &ks = theSections[i]->getSectionTangent();
00291 const Vector &s = theSections[i]->getStressResultant();
00292
00293 double xi6 = 6.0*pts(i,0);
00294 ka.Zero();
00295
00296
00297
00298 double wti = wts(i)*oneOverL;
00299 double tmp;
00300 int j, k;
00301 for (j = 0; j < order; j++) {
00302 switch(code(j)) {
00303 case SECTION_RESPONSE_P:
00304 for (k = 0; k < order; k++)
00305 ka(k,0) += ks(k,j)*wti;
00306 break;
00307 case SECTION_RESPONSE_MZ:
00308 for (k = 0; k < order; k++) {
00309 tmp = ks(k,j)*wti;
00310 ka(k,1) += (xi6-4.0)*tmp;
00311 ka(k,2) += (xi6-2.0)*tmp;
00312 }
00313 break;
00314 case SECTION_RESPONSE_MY:
00315 for (k = 0; k < order; k++) {
00316 tmp = ks(k,j)*wti;
00317 ka(k,3) += (xi6-4.0)*tmp;
00318 ka(k,4) += (xi6-2.0)*tmp;
00319 }
00320 break;
00321 case SECTION_RESPONSE_T:
00322 for (k = 0; k < order; k++)
00323 ka(k,5) += ks(k,j)*wti;
00324 break;
00325 default:
00326 break;
00327 }
00328 }
00329 for (j = 0; j < order; j++) {
00330 switch (code(j)) {
00331 case SECTION_RESPONSE_P:
00332 for (k = 0; k < 6; k++)
00333 kb(0,k) += ka(j,k);
00334 break;
00335 case SECTION_RESPONSE_MZ:
00336 for (k = 0; k < 6; k++) {
00337 tmp = ka(j,k);
00338 kb(1,k) += (xi6-4.0)*tmp;
00339 kb(2,k) += (xi6-2.0)*tmp;
00340 }
00341 break;
00342 case SECTION_RESPONSE_MY:
00343 for (k = 0; k < 6; k++) {
00344 tmp = ka(j,k);
00345 kb(3,k) += (xi6-4.0)*tmp;
00346 kb(4,k) += (xi6-2.0)*tmp;
00347 }
00348 break;
00349 case SECTION_RESPONSE_T:
00350 for (k = 0; k < 6; k++)
00351 kb(5,k) += ka(j,k);
00352 break;
00353 default:
00354 break;
00355 }
00356 }
00357
00358
00359 double si;
00360 for (j = 0; j < order; j++) {
00361 si = s(j)*wts(i);
00362 switch(code(j)) {
00363 case SECTION_RESPONSE_P:
00364 q(0) += si; break;
00365 case SECTION_RESPONSE_MZ:
00366 q(1) += (xi6-4.0)*si; q(2) += (xi6-2.0)*si; break;
00367 case SECTION_RESPONSE_MY:
00368 q(3) += (xi6-4.0)*si; q(4) += (xi6-2.0)*si; break;
00369 case SECTION_RESPONSE_T:
00370 q(5) += si; break;
00371 default:
00372 break;
00373 }
00374 }
00375
00376 }
00377
00378
00379 K = crdTransf->getGlobalStiffMatrix(kb, q);
00380
00381 return K;
00382 }
00383
00384 const Matrix&
00385 DispBeamColumn3d::getSecantStiff()
00386 {
00387 return this->getTangentStiff();
00388 }
00389
00390 const Matrix&
00391 DispBeamColumn3d::getDamp()
00392 {
00393 K.Zero();
00394
00395 return K;
00396 }
00397
00398 const Matrix&
00399 DispBeamColumn3d::getMass()
00400 {
00401 K.Zero();
00402
00403 if (rho == 0.0)
00404 return K;
00405
00406 double m = 0.5*rho*L;
00407
00408 K(0,0) = K(1,1) = K(2,2) = K(6,6) = K(7,7) = K(8,8) = m;
00409
00410 return K;
00411 }
00412
00413 void
00414 DispBeamColumn3d::zeroLoad(void)
00415 {
00416 Q.Zero();
00417
00418 return;
00419 }
00420
00421 int
00422 DispBeamColumn3d::addLoad(const Vector &addLoad)
00423 {
00424 if (addLoad.Size() != 12) {
00425 g3ErrorHandler->warning("DispBeamColumn3d::addLoad %s\n",
00426 "Vector not of correct size");
00427 return -1;
00428 }
00429
00430
00431 Q.addVector(1.0, addLoad, 1.0);
00432
00433 return 0;
00434 }
00435
00436 int
00437 DispBeamColumn3d::addInertiaLoadToUnbalance(const Vector &accel)
00438 {
00439
00440 if (rho == 0.0)
00441 return 0;
00442
00443
00444 const Vector &Raccel1 = nd1Ptr->getRV(accel);
00445 const Vector &Raccel2 = nd2Ptr->getRV(accel);
00446
00447 if (6 != Raccel1.Size() || 6 != Raccel2.Size()) {
00448 g3ErrorHandler->warning("DispBeamColumn3d::addInertiaLoadToUnbalance %s\n",
00449 "matrix and vector sizes are incompatable");
00450 return -1;
00451 }
00452
00453 double m = 0.5*rho*L;
00454
00455
00456
00457 Q(0) -= m*Raccel1(0);
00458 Q(1) -= m*Raccel1(1);
00459 Q(2) -= m*Raccel1(2);
00460 Q(6) -= m*Raccel2(0);
00461 Q(7) -= m*Raccel2(1);
00462 Q(8) -= m*Raccel2(2);
00463
00464 return 0;
00465 }
00466
00467 const Vector&
00468 DispBeamColumn3d::getResistingForce()
00469 {
00470 GaussQuadRule1d01 quadrat(numSections);
00471 const Matrix &pts = quadrat.getIntegrPointCoords();
00472 const Vector &wts = quadrat.getIntegrPointWeights();
00473
00474
00475
00476 int order = theSections[0]->getOrder();
00477 const ID &code = theSections[0]->getType();
00478
00479
00480 q.Zero();
00481
00482
00483 for (int i = 0; i < numSections; i++) {
00484
00485 double xi6 = 6.0*pts(i,0);
00486
00487
00488 const Vector &s = theSections[i]->getStressResultant();
00489
00490
00491
00492
00493 double si;
00494 for (int j = 0; j < order; j++) {
00495 si = s(j)*wts(i);
00496 switch(code(j)) {
00497 case SECTION_RESPONSE_P:
00498 q(0) += si; break;
00499 case SECTION_RESPONSE_MZ:
00500 q(1) += (xi6-4.0)*si; q(2) += (xi6-2.0)*si; break;
00501 case SECTION_RESPONSE_MY:
00502 q(3) += (xi6-4.0)*si; q(4) += (xi6-2.0)*si; break;
00503 case SECTION_RESPONSE_T:
00504 q(5) += si; break;
00505 default:
00506 break;
00507 }
00508 }
00509
00510 }
00511
00512
00513 static Vector dummy(3);
00514 P = crdTransf->getGlobalResistingForce(q,dummy);
00515
00516
00517 P.addVector(1.0, Q, -1.0);
00518
00519 return P;
00520 }
00521
00522 const Vector&
00523 DispBeamColumn3d::getResistingForceIncInertia()
00524 {
00525
00526 if (rho == 0.0)
00527 return this->getResistingForce();
00528
00529 const Vector &accel1 = nd1Ptr->getTrialAccel();
00530 const Vector &accel2 = nd2Ptr->getTrialAccel();
00531
00532
00533 this->getResistingForce();
00534
00535 double m = 0.5*rho*L;
00536
00537 P(0) += m*accel1(0);
00538 P(1) += m*accel1(1);
00539 P(2) += m*accel1(2);
00540 P(6) += m*accel2(0);
00541 P(7) += m*accel2(1);
00542 P(8) += m*accel2(2);
00543
00544 return P;
00545 }
00546
00547 int
00548 DispBeamColumn3d::sendSelf(int commitTag, Channel &theChannel)
00549 {
00550 return -1;
00551 }
00552
00553 int
00554 DispBeamColumn3d::recvSelf(int commitTag, Channel &theChannel,
00555 FEM_ObjectBroker &theBroker)
00556 {
00557 return -1;
00558 }
00559
00560 void
00561 DispBeamColumn3d::Print(ostream &s, int flag)
00562 {
00563 s << "\nDispBeamColumn3d, element id: " << this->getTag() << endl;
00564 s << "\tConnected external nodes: " << connectedExternalNodes;
00565 s << "\tmass density: " << rho << endl;
00566 theSections[0]->Print(s,flag);
00567 }
00568
00569
00570 int
00571 DispBeamColumn3d::displaySelf(Renderer &theViewer, int displayMode, float fact)
00572 {
00573
00574
00575 const Vector &end1Crd = nd1Ptr->getCrds();
00576 const Vector &end2Crd = nd2Ptr->getCrds();
00577
00578 const Vector &end1Disp = nd1Ptr->getDisp();
00579 const Vector &end2Disp = nd2Ptr->getDisp();
00580
00581 static Vector v1(3);
00582 static Vector v2(3);
00583
00584 for (int i = 0; i < 3; i++) {
00585 v1(i) = end1Crd(i) + end1Disp(i)*fact;
00586 v2(i) = end2Crd(i) + end2Disp(i)*fact;
00587 }
00588
00589 return theViewer.drawLine (v1, v2, 1.0, 1.0);
00590 }
00591
00592 Response*
00593 DispBeamColumn3d::setResponse(char **argv, int argc, Information &eleInfo)
00594 {
00595
00596 if (strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"force") == 0
00597 || strcmp(argv[0],"globalForce") == 0 || strcmp(argv[0],"globalForces") == 0)
00598 return new ElementResponse(this, 1, P);
00599
00600
00601 else if (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0)
00602 return new ElementResponse(this, 2, P);
00603
00604
00605 else if (strcmp(argv[0],"section") ==0) {
00606 if (argc <= 2)
00607 return 0;
00608
00609 int sectionNum = atoi(argv[1]);
00610 if (sectionNum > 0 && sectionNum <= numSections)
00611 return theSections[sectionNum-1]->setResponse(&argv[2], argc-2, eleInfo);
00612 else
00613 return 0;
00614 }
00615
00616 else
00617 return 0;
00618 }
00619
00620 int
00621 DispBeamColumn3d::getResponse(int responseID, Information &eleInfo)
00622 {
00623 double V;
00624
00625 switch (responseID) {
00626 case 1:
00627 return eleInfo.setVector(P);
00628
00629 case 2:
00630
00631 P(6) = q(0);
00632 P(0) = -q(0);
00633
00634
00635 P(11) = q(5);
00636 P(5) = -q(5);
00637
00638
00639 P(2) = q(1);
00640 P(8) = q(2);
00641 V = (q(1)+q(2))/L;
00642 P(1) = V;
00643 P(7) = -V;
00644
00645
00646 P(4) = q(3);
00647 P(10) = q(4);
00648 V = (q(3)+q(4))/L;
00649 P(3) = -V;
00650 P(9) = V;
00651 return eleInfo.setVector(P);
00652
00653 default:
00654 return -1;
00655 }
00656 }