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 #include <BeamWithHinges2d.h>
00026 #include <Element.h>
00027 #include <Domain.h>
00028 #include <Channel.h>
00029 #include <FEM_ObjectBroker.h>
00030 #include <Matrix.h>
00031 #include <Vector.h>
00032 #include <Node.h>
00033 #include <MatrixUtil.h>
00034 #include <math.h>
00035 #include <stdlib.h>
00036 #include <string.h>
00037 #include <stdio.h>
00038
00039 #include <SectionForceDeformation.h>
00040 #include <CrdTransf2d.h>
00041 #include <ElementalLoad.h>
00042
00043 #include <Information.h>
00044 #include <ElementResponse.h>
00045 #include <Renderer.h>
00046
00047 Matrix BeamWithHinges2d::theMatrix(6,6);
00048 Vector BeamWithHinges2d::theVector(6);
00049 double BeamWithHinges2d::workArea[100];
00050
00051 BeamWithHinges2d::BeamWithHinges2d(void)
00052 :Element(0, ELE_TAG_BeamWithHinges2d),
00053 E(0.0), A(0.0), I(0.0),
00054 beta1(0.0), beta2(0.0), rho(0.0),
00055 theCoordTransf(0),
00056 connectedExternalNodes(2),
00057 kb(3,3), q(3), load(6),
00058 kbCommit(3,3), qCommit(3),
00059 initialFlag(0), maxIter(0), tolerance(0.0), sp(0)
00060 {
00061 section[0] = 0;
00062 section[1] = 0;
00063
00064 p0[0] = 0.0;
00065 p0[1] = 0.0;
00066 p0[2] = 0.0;
00067
00068 v0[0] = 0.0;
00069 v0[1] = 0.0;
00070 v0[2] = 0.0;
00071
00072 theNodes[0] = 0;
00073 theNodes[1] = 0;
00074 }
00075
00076 BeamWithHinges2d::BeamWithHinges2d(int tag, int nodeI, int nodeJ,
00077 double e, double a, double i,
00078 SectionForceDeformation §ionRefI, double lpi,
00079 SectionForceDeformation §ionRefJ, double lpj,
00080 CrdTransf2d &coordTransf,
00081 double r, int max, double tol)
00082 :Element(tag, ELE_TAG_BeamWithHinges2d),
00083 E(e), A(a), I(i),
00084 beta1(lpi), beta2(lpj), rho(r),
00085 theCoordTransf(0),
00086 connectedExternalNodes(2),
00087 kb(3,3), q(3), load(6),
00088 kbCommit(3,3), qCommit(3),
00089 initialFlag(0), maxIter(max), tolerance(tol), sp(0)
00090 {
00091 if (E <= 0.0) {
00092 opserr << "BeamWithHinges2d::BeamWithHinges2d -- input parameter E is <= 0.0\n";
00093 exit(-1);
00094 }
00095
00096 if (I <= 0.0) {
00097 opserr << "BeamWithHinges2d::BeamWithHinges2d -- input parameter I is <= 0.0\n";
00098 exit(-1);
00099 }
00100
00101 if (A <= 0.0) {
00102 opserr << "BeamWithHinges2d::BeamWithHinges2d -- input parameter A is <= 0.0\n";
00103 exit(-1);
00104 }
00105
00106
00107 section[0] = sectionRefI.getCopy();
00108
00109 if (section[0] == 0) {
00110 opserr << "BeamWithHinges2d::BeamWithHinges2d -- failed to get copy of section I\n";
00111 exit(-1);
00112 }
00113
00114 section[1] = sectionRefJ.getCopy();
00115
00116 if (section[1] == 0) {
00117 opserr << "BeamWithHinges2d::BeamWithHinges2d -- failed to get copy of section J\n";
00118 exit(-1);
00119 }
00120
00121 theCoordTransf = coordTransf.getCopy();
00122
00123 if (theCoordTransf == 0) {
00124 opserr << "BeamWithHinges2d::BeamWithHinges2d -- failed to get copy of coordinate transformation\n";
00125 exit(-1);
00126 }
00127
00128 connectedExternalNodes(0) = nodeI;
00129 connectedExternalNodes(1) = nodeJ;
00130
00131 theNodes[0] = 0;
00132 theNodes[1] = 0;
00133
00134
00135 this->setHinges();
00136
00137 p0[0] = 0.0;
00138 p0[1] = 0.0;
00139 p0[2] = 0.0;
00140
00141 v0[0] = 0.0;
00142 v0[1] = 0.0;
00143 v0[2] = 0.0;
00144 }
00145
00146 BeamWithHinges2d::~BeamWithHinges2d(void)
00147 {
00148 for (int i = 0; i < 2; i++)
00149 if (section[i] != 0)
00150 delete section[i];
00151
00152 if (theCoordTransf)
00153 delete theCoordTransf;
00154
00155 if (sp != 0)
00156 delete sp;
00157 }
00158
00159 int
00160 BeamWithHinges2d::getNumExternalNodes(void) const
00161 {
00162 return 2;
00163 }
00164
00165 const ID &
00166 BeamWithHinges2d::getExternalNodes(void)
00167 {
00168 return connectedExternalNodes;
00169 }
00170
00171 Node **
00172 BeamWithHinges2d::getNodePtrs()
00173 {
00174 return theNodes;
00175 }
00176
00177 int
00178 BeamWithHinges2d::getNumDOF(void)
00179 {
00180 return 6;
00181 }
00182
00183 void
00184 BeamWithHinges2d::setDomain(Domain *theDomain)
00185 {
00186
00187
00188
00189 if(theDomain == 0) {
00190 theNodes[0] = 0;
00191 theNodes[1] = 0;
00192 return;
00193 }
00194
00195
00196 this->setNodePtrs(theDomain);
00197
00198
00199 this->DomainComponent::setDomain(theDomain);
00200
00201 if (theCoordTransf->initialize(theNodes[0], theNodes[1]) != 0) {
00202 opserr << "BeamWithHinges2d::setDomain() -- failed to initialize coordinate transformation\n";
00203 exit(-1);
00204 }
00205
00206
00207 double L = theCoordTransf->getInitialLength();
00208 if (L == 0.0) {
00209 opserr << "BeamWithHinges2d::setDomain() -- element has zero length\n";
00210 exit(-1);
00211 }
00212
00213 if (initialFlag == 2)
00214 theCoordTransf->update();
00215 else
00216 this->update();
00217 }
00218
00219 int
00220 BeamWithHinges2d::commitState(void)
00221 {
00222 int err = 0;
00223
00224
00225 if ((err = this->Element::commitState()) != 0) {
00226 opserr << "BeamWithHinges2d::commitState () - failed in base class";
00227 }
00228
00229 for (int i = 0; i < 2; i++) {
00230 if (section[i] != 0)
00231 err += section[i]->commitState();
00232 }
00233
00234 err += theCoordTransf->commitState();
00235
00236 kbCommit = kb;
00237 qCommit = q;
00238
00239
00240 eCommit[0] = e[0];
00241 eCommit[1] = e[1];
00242
00243
00244
00245 return err;
00246 }
00247
00248 int
00249 BeamWithHinges2d::revertToLastCommit(void)
00250 {
00251 int err = 0;
00252
00253
00254
00255 for (int i = 0; i < 2; i++) {
00256 if (section[i] != 0) {
00257 err += section[i]->revertToLastCommit();
00258 section[i]->setTrialSectionDeformation(eCommit[i]);
00259
00260 e[i] = eCommit[i];
00261 sr[i] = section[i]->getStressResultant();
00262 fs[i] = section[i]->getSectionFlexibility();
00263 }
00264 }
00265
00266
00267 err += theCoordTransf->revertToLastCommit();
00268
00269 kb = kbCommit;
00270 q = qCommit;
00271
00272 initialFlag = 0;
00273
00274
00275 return err;
00276 }
00277
00278 int
00279 BeamWithHinges2d::revertToStart(void)
00280 {
00281 int err = 0;
00282
00283 for (int i = 0; i < 2; i++) {
00284 if (section[i] != 0) {
00285 err += section[i]->revertToStart();
00286 fs[i].Zero();
00287 e[i].Zero();
00288 sr[i].Zero();
00289 eCommit[i].Zero();
00290 }
00291 }
00292
00293 err += theCoordTransf->revertToStart();
00294
00295 kb.Zero();
00296 q.Zero();
00297
00298 initialFlag = 0;
00299
00300
00301 return err;
00302 }
00303
00304 const Matrix &
00305 BeamWithHinges2d::getTangentStiff(void)
00306 {
00307 return theCoordTransf->getGlobalStiffMatrix(kb, q);
00308 }
00309
00310
00311 const Matrix &
00312 BeamWithHinges2d::getInitialStiff(void)
00313 {
00314 double L = theCoordTransf->getInitialLength();
00315 double oneOverL = 1.0/L;
00316
00317
00318 double xi[2];
00319
00320
00321 double lp[2];
00322
00323 lp[0] = beta1*L;
00324 lp[1] = beta2*L;
00325
00326 xi[0] = 0.5*lp[0];
00327 xi[1] = L-0.5*lp[1];
00328
00329
00330 static Matrix f(3,3);
00331 static Vector vr(3);
00332
00333 static Matrix Iden(3,3);
00334 Iden.Zero();
00335 int i;
00336 for (i = 0; i < 3; i++)
00337 Iden(i,i) = 1.0;
00338
00339
00340 double Le = L-lp[0]-lp[1];
00341 double LoverEA = Le/(E*A);
00342 double Lover3EI = Le/(3*E*I);
00343 double Lover6EI = 0.5*Lover3EI;
00344
00345
00346 static Matrix fe(2,2);
00347 fe(0,0) = fe(1,1) = Lover3EI;
00348 fe(0,1) = fe(1,0) = -Lover6EI;
00349
00350
00351 static Matrix B(2,2);
00352 B(0,0) = 1.0 - beta1;
00353 B(1,1) = 1.0 - beta2;
00354 B(0,1) = -beta1;
00355 B(1,0) = -beta2;
00356
00357
00358
00359 static Matrix fElastic(2,2);
00360 fElastic.addMatrixTripleProduct(0.0, B, fe, 1.0);
00361
00362
00363 f(0,0) = LoverEA;
00364 f(1,1) = fElastic(0,0);
00365 f(2,2) = fElastic(1,1);
00366 f(1,2) = fElastic(0,1);
00367 f(2,1) = fElastic(1,0);
00368 f(0,1) = f(1,0) = f(0,2) = f(2,0) = 0.0;
00369
00370 for (i = 0; i < 2; i++) {
00371
00372 if (section[i] == 0 || lp[i] <= 0.0)
00373 continue;
00374
00375
00376 int order = section[i]->getOrder();
00377 const ID &code = section[i]->getType();
00378
00379 Vector s(workArea, order);
00380 Vector ds(&workArea[order], order);
00381 Vector de(&workArea[2*order], order);
00382
00383 Matrix fb(&workArea[3*order], order, 3);
00384
00385 double x = xi[i];
00386 double xL = x*oneOverL;
00387 double xL1 = xL-1.0;
00388
00389
00390 const Matrix &fSec = section[i]->getInitialFlexibility();
00391
00392
00393
00394
00395 int ii, jj;
00396 fb.Zero();
00397 double tmp;
00398 for (ii = 0; ii < order; ii++) {
00399 switch(code(ii)) {
00400 case SECTION_RESPONSE_P:
00401 for (jj = 0; jj < order; jj++)
00402 fb(jj,0) += fSec(jj,ii)*lp[i];
00403 break;
00404 case SECTION_RESPONSE_MZ:
00405 for (jj = 0; jj < order; jj++) {
00406 tmp = fSec(jj,ii)*lp[i];
00407 fb(jj,1) += xL1*tmp;
00408 fb(jj,2) += xL*tmp;
00409 }
00410 break;
00411 case SECTION_RESPONSE_VY:
00412 for (jj = 0; jj < order; jj++) {
00413
00414 tmp = fSec(jj,ii);
00415 fb(jj,1) += tmp;
00416 fb(jj,2) += tmp;
00417 }
00418 break;
00419 default:
00420 break;
00421 }
00422 }
00423 for (ii = 0; ii < order; ii++) {
00424 switch (code(ii)) {
00425 case SECTION_RESPONSE_P:
00426 for (jj = 0; jj < 3; jj++)
00427 f(0,jj) += fb(ii,jj);
00428 break;
00429 case SECTION_RESPONSE_MZ:
00430 for (jj = 0; jj < 3; jj++) {
00431 tmp = fb(ii,jj);
00432 f(1,jj) += xL1*tmp;
00433 f(2,jj) += xL*tmp;
00434 }
00435 break;
00436 case SECTION_RESPONSE_VY:
00437 for (jj = 0; jj < 3; jj++) {
00438 tmp = oneOverL*fb(ii,jj);
00439 f(1,jj) += tmp;
00440 f(2,jj) += tmp;
00441 }
00442 break;
00443 default:
00444 break;
00445 }
00446 }
00447 }
00448
00449
00450
00451 static Matrix kbInit(3,3);
00452 if (f.Solve(Iden,kbInit) < 0)
00453 opserr << "BeamWithHinges2d::update() -- could not invert flexibility\n";
00454
00455 return theCoordTransf->getInitialGlobalStiffMatrix(kbInit);
00456 }
00457
00458
00459 const Matrix &
00460 BeamWithHinges2d::getMass(void)
00461 {
00462 theMatrix.Zero();
00463
00464 if (rho != 0.0) {
00465 double L = theCoordTransf->getInitialLength();
00466 theMatrix(0,0) = theMatrix(1,1) = theMatrix(3,3) = theMatrix(4,4) = 0.5*L*rho;
00467 }
00468
00469 return theMatrix;
00470 }
00471
00472 void
00473 BeamWithHinges2d::zeroLoad(void)
00474 {
00475 if (sp != 0)
00476 sp->Zero();
00477
00478 p0[0] = 0.0;
00479 p0[1] = 0.0;
00480 p0[2] = 0.0;
00481
00482 v0[0] = 0.0;
00483 v0[1] = 0.0;
00484 v0[2] = 0.0;
00485
00486 load.Zero();
00487 }
00488
00489 int
00490 BeamWithHinges2d::addLoad(ElementalLoad *theLoad, double loadFactor)
00491 {
00492 int type;
00493 const Vector &data = theLoad->getData(type, loadFactor);
00494
00495 if (sp == 0) {
00496 sp = new Matrix(3,2);
00497 if (sp == 0) {
00498 opserr << "BeamWithHinges2d::addLoad -- out of memory\n";
00499 exit(-1);
00500 }
00501 }
00502
00503 double L = theCoordTransf->getInitialLength();
00504 double oneOverL = 1.0/L;
00505
00506 double lp1 = beta1*L;
00507 double lp2 = beta2*L;
00508 double Le = L-lp1-lp2;
00509
00510
00511 double xi[2];
00512 xi[0] = 0.5*lp1;
00513 xi[1] = L-0.5*lp2;
00514
00515 if (type == LOAD_TAG_Beam2dUniformLoad) {
00516 double wa = data(1)*loadFactor;
00517 double wy = data(0)*loadFactor;
00518
00519 Matrix &s_p = *sp;
00520
00521
00522 for (int i = 0; i < 2; i++) {
00523 double x = xi[i];
00524
00525 s_p(0,i) += wa*(L-x);
00526
00527 s_p(1,i) += wy*0.5*x*(x-L);
00528
00529 s_p(2,i) += wy*(x-0.5*L);
00530 }
00531
00532
00533 p0[0] -= wa*L;
00534 double V = 0.5*wy*L;
00535 p0[1] -= V;
00536 p0[2] -= V;
00537
00538
00539 if (Le == 0.0)
00540 return 0;
00541
00542
00543
00544 v0[0] += wa*0.5*(L-lp1+lp2)/(E*A)*Le;
00545
00546
00547
00548 double x1 = lp1 + 0.5*Le*(1.0-1.0/sqrt(3.0));
00549 double x2 = lp1 + 0.5*Le*(1.0+1.0/sqrt(3.0));
00550
00551 double M1 = 0.5*wy*x1*(x1-L);
00552 double M2 = 0.5*wy*x2*(x2-L);
00553
00554 double b1, b2;
00555 double Le2EI = Le/(2*E*I);
00556 b1 = x1*oneOverL;
00557 b2 = x2*oneOverL;
00558 v0[2] += Le2EI*(b1*M1+b2*M2);
00559
00560 b1 -= 1.0;
00561 b2 -= 1.0;
00562 v0[1] += Le2EI*(b1*M1+b2*M2);
00563 }
00564
00565 else if (type == LOAD_TAG_Beam2dPointLoad) {
00566 double P = data(0)*loadFactor;
00567 double N = data(1)*loadFactor;
00568 double aOverL = data(2);
00569 double a = aOverL*L;
00570
00571 double V1 = P*(1.0-aOverL);
00572 double V2 = P*aOverL;
00573
00574 Matrix &s_p = *sp;
00575
00576
00577 for (int i = 0; i < 2; i++) {
00578 double x = xi[i];
00579 if (x <= a) {
00580 s_p(0,i) += N;
00581 s_p(1,i) -= x*V1;
00582 s_p(2,i) -= V1;
00583 }
00584 else {
00585 s_p(1,i) -= (L-x)*V2;
00586 s_p(2,i) += V2;
00587 }
00588 }
00589
00590
00591 p0[0] -= N;
00592 p0[1] -= V1;
00593 p0[2] -= V2;
00594
00595
00596 if (Le == 0.0)
00597 return 0;
00598
00599
00600 double M1, M2, M3;
00601 double b1, b2, b3;
00602
00603
00604 if (a < lp1) {
00605 M1 = (lp1-L)*V2;
00606 M2 = -lp2*V2;
00607
00608 double Le_6EI = Le/(6*E*I);
00609
00610 b1 = lp1*oneOverL;
00611 b2 = 1.0-lp2*oneOverL;
00612 v0[2] += Le_6EI*(M1*(2*b1+b2)+M2*(b1+2*b2));
00613
00614 b1 -= 1.0;
00615 b2 -= 1.0;
00616 v0[1] += Le_6EI*(M1*(2*b1+b2)+M2*(b1+2*b2));
00617
00618
00619
00620 }
00621
00622 else if (a > L-lp2) {
00623 M1 = -lp1*V1;
00624 M2 = (lp2-L)*V1;
00625
00626 double Le_6EI = Le/(6*E*I);
00627
00628 b1 = lp1*oneOverL;
00629 b2 = 1.0-lp2*oneOverL;
00630 v0[2] += Le_6EI*(M1*(2*b1+b2)+M2*(b1+2*b2));
00631
00632 b1 -= 1.0;
00633 b2 -= 1.0;
00634 v0[1] += Le_6EI*(M1*(2*b1+b2)+M2*(b1+2*b2));
00635
00636 v0[0] += N*Le/(E*A);
00637 }
00638
00639 else {
00640 M1 = -lp1*V1;
00641 M2 = -lp2*V2;
00642 M3 = -a*V1;
00643
00644 double L1_6EI = (a-lp1)/(6*E*I);
00645 double L2_6EI = (Le-a+lp1)/(6*E*I);
00646
00647 b1 = lp1*oneOverL;
00648 b2 = 1.0-lp2*oneOverL;
00649 b3 = a*oneOverL;
00650 v0[2] += L1_6EI*(M1*(2*b1+b3)+M3*(b1+2*b3));
00651 v0[2] += L2_6EI*(M2*(2*b2+b3)+M3*(b2+2*b3));
00652
00653 b1 -= 1.0;
00654 b2 -= 1.0;
00655 b3 -= 1.0;
00656 v0[1] += L1_6EI*(M1*(2*b1+b3)+M3*(b1+2*b3));
00657 v0[1] += L2_6EI*(M2*(2*b2+b3)+M3*(b2+2*b3));
00658
00659 v0[0] += N*(a-lp1)/(E*A);
00660 }
00661 }
00662
00663 else {
00664 opserr << "BeamWithHinges2d::addLoad() -- load type unknown for element with tag: " << this->getTag() << endln;
00665 return -1;
00666 }
00667
00668 return 0;
00669 }
00670
00671 int
00672 BeamWithHinges2d::addInertiaLoadToUnbalance(const Vector &accel)
00673 {
00674 if (rho == 0.0)
00675 return 0;
00676
00677 const Vector &Raccel1 = theNodes[0]->getRV(accel);
00678 const Vector &Raccel2 = theNodes[1]->getRV(accel);
00679
00680 double L = theCoordTransf->getInitialLength();
00681 double mass = 0.5*L*rho;
00682
00683 int i,j;
00684 for (i = 0, j = 3; i < 2; i++, j++) {
00685 load(i) += mass*Raccel1(i);
00686 load(j) += mass*Raccel2(i);
00687 }
00688
00689 return 0;
00690 }
00691
00692 const Vector &
00693 BeamWithHinges2d::getResistingForce(void)
00694 {
00695 Vector p0Vec(p0, 3);
00696
00697 return theCoordTransf->getGlobalResistingForce(q, p0Vec);
00698 }
00699
00700 const Vector &
00701 BeamWithHinges2d::getResistingForceIncInertia(void)
00702 {
00703 theVector = this->getResistingForce();
00704
00705 if (rho != 0.0) {
00706
00707 double ag[6];
00708
00709 const Vector &accel1 = theNodes[0]->getTrialAccel();
00710 const Vector &accel2 = theNodes[1]->getTrialAccel();
00711
00712 ag[0] = accel1(0);
00713 ag[1] = accel1(1);
00714
00715 ag[3] = accel2(0);
00716 ag[4] = accel2(1);
00717
00718
00719 theVector = this->getResistingForce();
00720
00721 double L = theCoordTransf->getInitialLength();
00722 double mass = 0.5*L*rho;
00723
00724 int i,j;
00725 for (i = 0, j = 3; i < 2; i++, j++) {
00726 theVector(i) += mass*ag[i];
00727 theVector(j) += mass*ag[j];
00728 }
00729
00730
00731 if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
00732 theVector += this->getRayleighDampingForces();
00733
00734 } else {
00735
00736
00737 if (betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
00738 theVector += this->getRayleighDampingForces();
00739 }
00740
00741 return theVector;
00742 }
00743
00744 int
00745 BeamWithHinges2d::sendSelf(int commitTag, Channel &theChannel)
00746 {
00747
00748 int dbTag = this->getDbTag();
00749 int i, j , k;
00750 int loc = 0;
00751
00752 static ID idData(11);
00753 idData(0) = this->getTag();
00754 idData(1) = connectedExternalNodes(0);
00755 idData(2) = connectedExternalNodes(1);
00756 idData(3) = theCoordTransf->getClassTag();
00757 int theCoordTransfDbTag = theCoordTransf->getDbTag();
00758 if (theCoordTransfDbTag == 0) {
00759 theCoordTransfDbTag = theChannel.getDbTag();
00760 if (theCoordTransfDbTag != 0)
00761 theCoordTransf->setDbTag(theCoordTransfDbTag);
00762 }
00763 idData(4) = theCoordTransfDbTag;
00764
00765 idData(5) = initialFlag;
00766 idData(6) = maxIter;
00767
00768 loc = 5;
00769 for (i = 0; i<2; i++) {
00770 int sectClassTag = section[i]->getClassTag();
00771 int sectDbTag = section[i]->getDbTag();
00772 if (sectDbTag == 0) {
00773 sectDbTag = theChannel.getDbTag();
00774 section[i]->setDbTag(sectDbTag);
00775 }
00776
00777 idData(loc) = sectClassTag;
00778 idData(loc+1) = sectDbTag;
00779 loc += 2;
00780 }
00781
00782 if (theChannel.sendID(dbTag, commitTag, idData) < 0) {
00783 opserr << "NLBeamColumn2d::sendSelf() - failed to send ID data\n";
00784 return -1;
00785 }
00786
00787
00788
00789 if (theCoordTransf->sendSelf(commitTag, theChannel) < 0) {
00790 opserr << "NLBeamColumn2d::sendSelf() - failed to send crdTranf\n";
00791 return -1;
00792 }
00793
00794
00795
00796
00797
00798 for (j = 0; j<2; j++) {
00799 if (section[j]->sendSelf(commitTag, theChannel) < 0) {
00800 opserr << "NLBeamColumn2d::sendSelf() - section " << j << "failed to send itself\n";
00801 return -1;
00802 }
00803 }
00804
00805
00806 int secDefSize = 0;
00807 for (i = 0; i < 2; i++)
00808 {
00809 int size = section[i]->getOrder();
00810 secDefSize += size;
00811 }
00812
00813 Vector dData(7+3+9+secDefSize);
00814 loc = 0;
00815
00816
00817 dData(loc++) = E;
00818 dData(loc++) = A;
00819 dData(loc++) = I;
00820 dData(loc++) = beta1;
00821 dData(loc++) = beta2;
00822 dData(loc++) = rho;
00823 dData(loc++) = tolerance;
00824
00825
00826
00827
00828
00829
00830 for (i=0; i<3; i++)
00831 dData(loc++) = qCommit(i);
00832
00833
00834 for (i=0; i<3; i++)
00835 for (j=0; j<3; j++)
00836 dData(loc++) = kbCommit(i,j);
00837
00838
00839 for (k=0; k<2; k++)
00840 for (i=0; i<section[k]->getOrder(); i++)
00841 dData(loc++) = (eCommit[k])(i);
00842
00843 if (theChannel.sendVector(dbTag, commitTag, dData) < 0) {
00844 opserr << "NLBeamColumn2d::sendSelf() - failed to send Vector data\n";
00845 return -1;
00846 }
00847
00848 return 0;
00849 }
00850
00851 int
00852 BeamWithHinges2d::recvSelf(int commitTag, Channel &theChannel,
00853 FEM_ObjectBroker &theBroker)
00854 {
00855
00856 int dbTag = this->getDbTag();
00857 int i, j , k;
00858 int loc = 0;
00859
00860 static ID idData(11);
00861
00862 if (theChannel.recvID(dbTag, commitTag, idData) < 0) {
00863 opserr << "NLBeamColumn2d::recvSelf() - failed to recv ID data\n";
00864 return -1;
00865 }
00866
00867 this->setTag(idData(0));
00868 connectedExternalNodes(0) = idData(1);
00869 connectedExternalNodes(1) = idData(2);
00870
00871 maxIter = idData(5);
00872 initialFlag = idData(6);
00873
00874 int crdTransfClassTag = idData(3);
00875 int crdTransfDbTag = idData(4);
00876
00877
00878 if (theCoordTransf == 0 || theCoordTransf->getClassTag() != crdTransfClassTag) {
00879 if (theCoordTransf != 0)
00880 delete theCoordTransf;
00881
00882 theCoordTransf = theBroker.getNewCrdTransf2d(crdTransfClassTag);
00883
00884 if (theCoordTransf == 0) {
00885 opserr << "NLBeamColumn2d::recvSelf() - " <<
00886 "failed to obtain a CrdTrans object with classTag" << crdTransfClassTag << endln;
00887 return -2;
00888 }
00889 }
00890
00891 theCoordTransf->setDbTag(crdTransfDbTag);
00892
00893
00894 if (theCoordTransf->recvSelf(commitTag, theChannel, theBroker) < 0)
00895 {
00896 opserr << "NLBeamColumn2d::sendSelf() - failed to recv crdTranf\n";
00897 return -3;
00898 }
00899
00900
00901
00902
00903
00904 loc = 5;
00905 if (section[0] == 0) {
00906
00907
00908 for (i=0; i<2; i++) {
00909 int sectClassTag = idData(loc);
00910 int sectDbTag = idData(loc+1);
00911 loc += 2;
00912 section[i] = theBroker.getNewSection(sectClassTag);
00913 if (section[i] == 0) {
00914 opserr << "NLBeamColumn2d::recvSelf() - " <<
00915 "Broker could not create Section of class type" << sectClassTag << endln;
00916 exit(-1);
00917 }
00918 section[i]->setDbTag(sectDbTag);
00919 if (section[i]->recvSelf(commitTag, theChannel, theBroker) < 0) {
00920 opserr << "NLBeamColumn2d::recvSelf() - section " << i << "failed to recv itself\n";
00921 return -1;
00922 }
00923 }
00924
00925 this->setHinges();
00926
00927 } else {
00928
00929
00930 for (i=0; i<2; i++) {
00931
00932 int sectClassTag = idData(loc);
00933 int sectDbTag = idData(loc+1);
00934 loc += 2;
00935
00936
00937 if (section[i]->getClassTag() != sectClassTag) {
00938
00939 delete section[i];
00940 section[i] = theBroker.getNewSection(sectClassTag);
00941 if (section[i] == 0) {
00942 opserr << "NLBeamColumn2d::recvSelf() - " <<
00943 "Broker could not create Section of class type" << sectClassTag << endln;
00944 exit(-1);
00945 }
00946 }
00947
00948
00949 section[i]->setDbTag(sectDbTag);
00950 if (section[i]->recvSelf(commitTag, theChannel, theBroker) < 0) {
00951 opserr << "NLBeamColumn2d::recvSelf() - section " << i << "failed to recv itself\n";
00952 return -1;
00953 }
00954 }
00955 }
00956
00957
00958 int secDefSize = 0;
00959 for (i = 0; i < 2; i++)
00960 {
00961 int size = section[i]->getOrder();
00962 secDefSize += size;
00963 }
00964
00965 Vector dData(7+3+9+secDefSize);
00966 loc = 0;
00967
00968 if (theChannel.recvVector(dbTag, commitTag, dData) < 0) {
00969 opserr << "NLBeamColumn2d::sendSelf() - failed to send Vector data\n";
00970 return -1;
00971 }
00972
00973
00974 E = dData(loc++);
00975 A = dData(loc++);
00976 I = dData(loc++);
00977 beta1 = dData(loc++);
00978 beta2 = dData(loc++);
00979 rho = dData(loc++);
00980 tolerance = dData(loc++);
00981
00982
00983 for (i=0; i<3; i++)
00984 qCommit(i) = dData(loc++);
00985
00986
00987 for (i=0; i<3; i++)
00988 for (j=0; j<3; j++)
00989 kbCommit(i,j) = dData(loc++);;
00990
00991
00992 for (k=0; k<2; k++)
00993 for (i=0; i<section[k]->getOrder(); i++)
00994 (eCommit[k])(i) = dData(loc++);
00995
00996 initialFlag = 2;
00997
00998 return 0;
00999 }
01000
01001 void
01002 BeamWithHinges2d::Print(OPS_Stream &s, int flag)
01003 {
01004 s << "\nBeamWithHinges2d, tag: " << this->getTag() << endln;
01005 s << "\tConnected Nodes: " << connectedExternalNodes;
01006 s << "\tE: " << E << endln;
01007 s << "\tA: " << A << endln;
01008 s << "\tI: " << I << endln;
01009
01010 double P, V, M1, M2;
01011 double L = theCoordTransf->getInitialLength();
01012 P = qCommit(0);
01013 M1 = qCommit(1);
01014 M2 = qCommit(2);
01015 V = (M1+M2)/L;
01016
01017 s << "\tEnd 1 Forces (P V M): "
01018 << -P+p0[0] << ' ' << V+p0[1] << ' ' << M1 << endln;
01019 s << "\tEnd 2 Forces (P V M): "
01020 << P << ' ' << -V+p0[2] << ' ' << M2 << endln;
01021
01022 if (section[0] != 0) {
01023 s << "Hinge 1, section tag: " << section[0]->getTag() <<
01024 ", length: " << beta1*L << endln;
01025 section[0]->Print(s,flag);
01026 }
01027
01028 if (section[1] != 0) {
01029 s << "Hinge 2, section tag: " << section[2]->getTag() <<
01030 ", length: " << beta2*L << endln;
01031 section[1]->Print(s,flag);
01032 }
01033 }
01034
01036
01037
01038 void
01039 BeamWithHinges2d::setNodePtrs(Domain *theDomain)
01040 {
01041 theNodes[0] = theDomain->getNode(connectedExternalNodes(0));
01042 theNodes[1] = theDomain->getNode(connectedExternalNodes(1));
01043
01044 if(theNodes[0] == 0) {
01045 opserr << "BeamWithHinges2d::setNodePtrs() -- node 1 does not exist\n";
01046 exit(-1);
01047 }
01048
01049 if(theNodes[1] == 0) {
01050 opserr << "BeamWithHinges2d::setNodePtrs() -- node 2 does not exist\n";
01051 exit(-1);
01052 }
01053
01054
01055 int dofNd1 = theNodes[0]->getNumberDOF();
01056 int dofNd2 = theNodes[1]->getNumberDOF();
01057 if ((dofNd1 != 3) || (dofNd2 != 3)) {
01058 opserr << "BeamWithHinges2d::setNodePtrs() -- nodal dof is not three";
01059 exit(-1);
01060 }
01061 }
01062
01063 int
01064 BeamWithHinges2d::update(void)
01065 {
01066
01067
01068 if (initialFlag == 2)
01069 this->revertToLastCommit();
01070
01071
01072 theCoordTransf->update();
01073
01074
01075 static Vector v(3);
01076 v = theCoordTransf->getBasicTrialDisp();
01077
01078 static Vector dv(3);
01079 dv = theCoordTransf->getBasicIncrDeltaDisp();
01080
01081 double L = theCoordTransf->getInitialLength();
01082 double oneOverL = 1.0/L;
01083
01084
01085 double xi[2];
01086
01087
01088 double lp[2];
01089
01090 lp[0] = beta1*L;
01091 lp[1] = beta2*L;
01092
01093 xi[0] = 0.5*lp[0];
01094 xi[1] = L-0.5*lp[1];
01095
01096
01097 static Matrix f(3,3);
01098 static Vector vr(3);
01099
01100 static Matrix Iden(3,3);
01101 Iden.Zero();
01102 for (int i = 0; i < 3; i++)
01103 Iden(i,i) = 1.0;
01104
01105
01106 double Le = L-lp[0]-lp[1];
01107 double LoverEA = Le/(E*A);
01108 double Lover3EI = Le/(3*E*I);
01109 double Lover6EI = 0.5*Lover3EI;
01110
01111
01112 static Matrix fe(2,2);
01113 fe(0,0) = fe(1,1) = Lover3EI;
01114 fe(0,1) = fe(1,0) = -Lover6EI;
01115
01116
01117 static Matrix B(2,2);
01118 B(0,0) = 1.0 - beta1;
01119 B(1,1) = 1.0 - beta2;
01120 B(0,1) = -beta1;
01121 B(1,0) = -beta2;
01122
01123
01124
01125 static Matrix fElastic(2,2);
01126 fElastic.addMatrixTripleProduct(0.0, B, fe, 1.0);
01127
01128
01129 static Vector dq(3);
01130
01131 dq.addMatrixVector(0.0, kb, dv, 1.0);
01132
01133 int converged = 0;
01134
01135 for (int j = 0; j < maxIter; j++) {
01136
01137
01138 q.addVector(1.0, dq, 1.0);
01139
01140
01141 f(0,0) = LoverEA;
01142 f(1,1) = fElastic(0,0);
01143 f(2,2) = fElastic(1,1);
01144 f(1,2) = fElastic(0,1);
01145 f(2,1) = fElastic(1,0);
01146 f(0,1) = f(1,0) = f(0,2) = f(2,0) = 0.0;
01147
01148
01149 vr(0) = LoverEA*q(0) + v0[0];
01150 vr(1) = fElastic(0,0)*q(1) + fElastic(0,1)*q(2) + v0[1];
01151 vr(2) = fElastic(1,0)*q(1) + fElastic(1,1)*q(2) + v0[2];
01152
01153 for (int i = 0; i < 2; i++) {
01154
01155 if (section[i] == 0 || lp[i] <= 0.0)
01156 continue;
01157
01158
01159 int order = section[i]->getOrder();
01160 const ID &code = section[i]->getType();
01161
01162 Vector s(workArea, order);
01163 Vector ds(&workArea[order], order);
01164 Vector de(&workArea[2*order], order);
01165
01166 Matrix fb(&workArea[3*order], order, 3);
01167
01168 double x = xi[i];
01169 double xL = x*oneOverL;
01170 double xL1 = xL-1.0;
01171
01172 int ii;
01173
01174
01175
01176
01177 for (ii = 0; ii < order; ii++) {
01178 switch(code(ii)) {
01179 case SECTION_RESPONSE_P:
01180 s(ii) = q(0);
01181 break;
01182 case SECTION_RESPONSE_MZ:
01183 s(ii) = xL1*q(1) + xL*q(2);
01184 break;
01185 case SECTION_RESPONSE_VY:
01186 s(ii) = oneOverL*(q(1)+q(2));
01187 break;
01188 default:
01189 s(ii) = 0.0;
01190 break;
01191 }
01192 }
01193
01194
01195 if (sp != 0) {
01196 const Matrix &s_p = *sp;
01197 for (ii = 0; ii < order; ii++) {
01198 switch(code(ii)) {
01199 case SECTION_RESPONSE_P:
01200 s(ii) += s_p(0,i);
01201 break;
01202 case SECTION_RESPONSE_MZ:
01203 s(ii) += s_p(1,i);
01204 break;
01205 case SECTION_RESPONSE_VY:
01206 s(ii) += s_p(2,i);
01207 break;
01208 default:
01209 break;
01210 }
01211 }
01212 }
01213
01214
01215
01216 ds = s;
01217 ds.addVector(1.0, sr[i], -1.0);
01218
01219
01220
01221 de.addMatrixVector(0.0, fs[i], ds, 1.0);
01222 if (initialFlag != 0)
01223 e[i].addVector(1.0, de, 1.0);
01224
01225
01226 section[i]->setTrialSectionDeformation(e[i]);
01227
01228
01229 sr[i] = section[i]->getStressResultant();
01230
01231
01232 fs[i] = section[i]->getSectionFlexibility();
01233
01234
01235 ds = s;
01236 ds.addVector(1.0, sr[i], -1.0);
01237
01238 de.addMatrixVector(0.0, fs[i], ds, 1.0);
01239
01240
01241
01242
01243 int jj;
01244 fb.Zero();
01245 double tmp;
01246 const Matrix &fSec = fs[i];
01247 for (ii = 0; ii < order; ii++) {
01248 switch(code(ii)) {
01249 case SECTION_RESPONSE_P:
01250 for (jj = 0; jj < order; jj++)
01251 fb(jj,0) += fSec(jj,ii)*lp[i];
01252 break;
01253 case SECTION_RESPONSE_MZ:
01254 for (jj = 0; jj < order; jj++) {
01255 tmp = fSec(jj,ii)*lp[i];
01256 fb(jj,1) += xL1*tmp;
01257 fb(jj,2) += xL*tmp;
01258 }
01259 break;
01260 case SECTION_RESPONSE_VY:
01261 for (jj = 0; jj < order; jj++) {
01262
01263 tmp = fSec(jj,ii);
01264 fb(jj,1) += tmp;
01265 fb(jj,2) += tmp;
01266 }
01267 break;
01268 default:
01269 break;
01270 }
01271 }
01272 for (ii = 0; ii < order; ii++) {
01273 switch (code(ii)) {
01274 case SECTION_RESPONSE_P:
01275 for (jj = 0; jj < 3; jj++)
01276 f(0,jj) += fb(ii,jj);
01277 break;
01278 case SECTION_RESPONSE_MZ:
01279 for (jj = 0; jj < 3; jj++) {
01280 tmp = fb(ii,jj);
01281 f(1,jj) += xL1*tmp;
01282 f(2,jj) += xL*tmp;
01283 }
01284 break;
01285 case SECTION_RESPONSE_VY:
01286 for (jj = 0; jj < 3; jj++) {
01287 tmp = oneOverL*fb(ii,jj);
01288 f(1,jj) += tmp;
01289 f(2,jj) += tmp;
01290 }
01291 break;
01292 default:
01293 break;
01294 }
01295 }
01296
01297
01298
01299
01300
01301 de.addVector(1.0, e[i], 1.0);
01302
01303 for (ii = 0; ii < order; ii++) {
01304 switch(code(ii)) {
01305 case SECTION_RESPONSE_P:
01306 vr(0) += de(ii)*lp[i]; break;
01307 case SECTION_RESPONSE_MZ:
01308 tmp = de(ii)*lp[i];
01309 vr(1) += xL1*tmp; vr(2) += xL*tmp; break;
01310 case SECTION_RESPONSE_VY:
01311
01312 tmp = de(ii);
01313 vr(1) += tmp; vr(2) += tmp; break;
01314 default:
01315 break;
01316 }
01317 }
01318 }
01319
01320
01321
01322 if (f.Solve(Iden,kb) < 0)
01323 opserr << "BeamWithHinges2d::update() -- could not invert flexibility\n";
01324
01325
01326
01327 dv = v;
01328 dv.addVector(1.0, vr, -1.0);
01329
01330
01331
01332
01333 dq.addMatrixVector(0.0, kb, dv, 1.0);
01334
01335 double dW = dv^ dq;
01336
01337 if (fabs(dW) < tolerance)
01338 break;
01339
01340 if ((maxIter != 1) && (j == (maxIter - 1))) {
01341 converged = -1;
01342 }
01343 }
01344
01345
01346 q.addVector(1.0, dq, 1.0);
01347
01348 initialFlag = 1;
01349
01350 return 0;
01351 }
01352
01353 void
01354 BeamWithHinges2d::setHinges(void)
01355 {
01356 for (int i = 0; i < 2; i++) {
01357 if (section[i] == 0)
01358 continue;
01359
01360
01361 int order = section[i]->getOrder();
01362
01363 fs[i] = Matrix(order,order);
01364 e[i] = Vector(order);
01365 sr[i] = Vector(order);
01366 eCommit[i] = Vector(order);
01367 }
01368 }
01369
01370 void
01371 BeamWithHinges2d::getForceInterpMatrix(Matrix &b, double x, const ID &code)
01372 {
01373 b.Zero();
01374
01375 double L = theCoordTransf->getInitialLength();
01376 double xi = x/L;
01377
01378 for (int i = 0; i < code.Size(); i++) {
01379 switch (code(i)) {
01380 case SECTION_RESPONSE_MZ:
01381 b(i,1) = xi - 1.0;
01382 b(i,2) = xi;
01383 break;
01384 case SECTION_RESPONSE_P:
01385 b(i,0) = 1.0;
01386 break;
01387 case SECTION_RESPONSE_VY:
01388 b(i,1) = b(i,2) = 1.0/L;
01389 break;
01390 default:
01391 break;
01392 }
01393 }
01394 }
01395
01396 void
01397 BeamWithHinges2d::getDistrLoadInterpMatrix(Matrix &bp, double x, const ID & code)
01398 {
01399 bp.Zero();
01400
01401 double L = theCoordTransf->getInitialLength();
01402 double xi = x/L;
01403
01404 for (int i = 0; i < code.Size(); i++) {
01405 switch (code(i)) {
01406 case SECTION_RESPONSE_MZ:
01407 bp(i,1) = 0.5*xi*(xi-1);
01408 break;
01409 case SECTION_RESPONSE_P:
01410 bp(i,0) = 1.0-xi;
01411 break;
01412 case SECTION_RESPONSE_VY:
01413 bp(i,1) = xi-0.5;
01414 break;
01415 default:
01416 break;
01417 }
01418 }
01419 }
01420
01421 Response*
01422 BeamWithHinges2d::setResponse(const char **argv, int argc, Information &info)
01423 {
01424
01425 if (strcmp(argv[0],"plasticDeformation") == 0 ||
01426 strcmp(argv[0],"plasticRotation") == 0)
01427 return new ElementResponse(this, 1, Vector(3));
01428
01429
01430 else if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0 ||
01431 strcmp(argv[0],"globalForce") == 0 || strcmp(argv[0],"globalForces") == 0)
01432 return new ElementResponse(this, 2, theVector);
01433
01434
01435 else if (strcmp(argv[0],"stiffness") == 0)
01436 return new ElementResponse(this, 3, theMatrix);
01437
01438
01439 else if (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0)
01440 return new ElementResponse(this, 4, theVector);
01441
01442
01443 else if (strcmp(argv[0],"section") == 0) {
01444 int sectionNum = atoi(argv[1]) - 1;
01445
01446 if (sectionNum >= 0 && sectionNum < 2)
01447 if (section[sectionNum] != 0)
01448 return section[sectionNum]->setResponse(&argv[2], argc-2, info);
01449 return 0;
01450 }
01451 else
01452 return 0;
01453 }
01454
01455 int
01456 BeamWithHinges2d::getResponse(int responseID, Information &eleInfo)
01457 {
01458 double V;
01459 double L = theCoordTransf->getInitialLength();
01460 static Vector force(6);
01461 static Vector def(3);
01462
01463 switch (responseID) {
01464 case 1: {
01465 const Vector &v = theCoordTransf->getBasicTrialDisp();
01466 double LoverEA = L/(E*A);
01467 double Lover3EI = L/(3*E*I);
01468 double Lover6EI = 0.5*Lover3EI;
01469
01470 double q1 = qCommit(1);
01471 double q2 = qCommit(2);
01472
01473 def(0) = v(0) - LoverEA*qCommit(0);
01474 def(1) = v(1) - Lover3EI*q1 + Lover6EI*q2;
01475 def(2) = v(2) + Lover6EI*q1 - Lover3EI*q2;
01476
01477 return eleInfo.setVector(def);
01478 }
01479
01480 case 2:
01481 return eleInfo.setVector(this->getResistingForce());
01482
01483 case 3:
01484 return eleInfo.setMatrix(this->getTangentStiff());
01485
01486 case 4:
01487
01488 force(3) = q(0);
01489 force(0) = -q(0)+p0[0];
01490
01491 force(2) = q(1);
01492 force(5) = q(2);
01493
01494 V = (q(1)+q(2))/L;
01495 force(1) = V+p0[1];
01496 force(4) = -V+p0[2];
01497 return eleInfo.setVector(force);
01498
01499 default:
01500 return -1;
01501 }
01502 }
01503
01504 int
01505 BeamWithHinges2d::displaySelf(Renderer &theViewer, int displayMode, float fact)
01506 {
01507
01508
01509 const Vector &end1Crd = theNodes[0]->getCrds();
01510 const Vector &end2Crd = theNodes[1]->getCrds();
01511
01512 const Vector &end1Disp = theNodes[0]->getDisp();
01513 const Vector &end2Disp = theNodes[1]->getDisp();
01514
01515 static Vector v1(3);
01516 static Vector v2(3);
01517
01518 for (int i = 0; i < 2; i++) {
01519 v1(i) = end1Crd(i) + end1Disp(i)*fact;
01520 v2(i) = end2Crd(i) + end2Disp(i)*fact;
01521 }
01522
01523 return theViewer.drawLine (v1, v2, 1.0, 1.0);
01524 }
01525
01526 int
01527 BeamWithHinges2d::setParameter(const char **argv, int argc, Information &info)
01528 {
01529
01530 if (strcmp(argv[0],"E") == 0) {
01531 info.theType = DoubleType;
01532 return 1;
01533 }
01534
01535
01536 else if (strcmp(argv[0],"A") == 0) {
01537 info.theType = DoubleType;
01538 return 3;
01539 }
01540
01541
01542 else if (strcmp(argv[0],"I") == 0) {
01543 info.theType = DoubleType;
01544 return 4;
01545 }
01546
01547
01548 else if (strcmp(argv[0],"section") ==0) {
01549 if (argc <= 2)
01550 return -1;
01551
01552 int sectionNum = atoi(argv[1]);
01553
01554 int ok = -1;
01555
01556 if (sectionNum == 1)
01557 ok = section[0]->setParameter (&argv[2], argc-2, info);
01558 if (sectionNum == 2)
01559 ok = section[1]->setParameter (&argv[2], argc-2, info);
01560
01561 if (ok < 0)
01562 return -1;
01563 else if (ok < 100)
01564 return sectionNum*100 + ok;
01565 else
01566 return -1;
01567 }
01568
01569
01570 else
01571 return -1;
01572 }
01573
01574 int
01575 BeamWithHinges2d::updateParameter(int parameterID, Information &info)
01576 {
01577 switch (parameterID) {
01578 case 1:
01579 this->E = info.theDouble;
01580 return 0;
01581 case 3:
01582 this->A = info.theDouble;
01583 return 0;
01584 case 4:
01585 this->I = info.theDouble;
01586 return 0;
01587 default:
01588 if (parameterID >= 100) {
01589 int sectionNum = parameterID/100;
01590 if (sectionNum == 1)
01591 return section[0]->updateParameter (parameterID-100, info);
01592 if (sectionNum == 2)
01593 return section[1]->updateParameter (parameterID-2*100, info);
01594 else
01595 return -1;
01596 }
01597 else
01598 return -1;
01599 }
01600 }