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
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include <LimitStateMaterial.h>
00046 #include <G3Globals.h>
00047 #include <math.h>
00048 #include <float.h>
00049 #include <Channel.h>
00050 #include <Vector.h>
00051
00052 LimitStateMaterial::LimitStateMaterial(int tag,
00053 double m1p, double r1p, double m2p, double r2p, double m3p, double r3p,
00054 double m1n, double r1n, double m2n, double r2n, double m3n, double r3n,
00055 double px, double py, double d1, double d2, double b):
00056 UniaxialMaterial(tag, MAT_TAG_LimitState),
00057 pinchX(px), pinchY(py), damfc1(d1), damfc2(d2), beta(b),
00058 mom1p(m1p), rot1p(r1p), mom2p(m2p), rot2p(r2p), mom3p(m3p), rot3p(r3p),
00059 mom1n(m1n), rot1n(r1n), mom2n(m2n), rot2n(r2n), mom3n(m3n), rot3n(r3n)
00060 {
00061 constructorType = 1;
00062
00063 bool error = false;
00064
00065
00066 if (rot1p <= 0.0)
00067 error = true;
00068
00069 if (rot2p <= rot1p)
00070 error = true;
00071
00072 if (rot3p <= rot2p)
00073 error = true;
00074
00075
00076 if (rot1n >= 0.0)
00077 error = true;
00078
00079 if (rot2n >= rot1n)
00080 error = true;
00081
00082 if (rot3n >= rot2n)
00083 error = true;
00084
00085 if (error) {
00086
00087
00088
00089
00090 }
00091
00092
00093 pinchX_orig = px;
00094 pinchY_orig = py;
00095 damfc1_orig = d1;
00096 damfc2_orig = d2;
00097 beta_orig = b;
00098 mom1p_orig = m1p;
00099 rot1p_orig = r1p;
00100 mom2p_orig = m2p;
00101 rot2p_orig = r2p;
00102 mom3p_orig = m3p;
00103 rot3p_orig = r3p;
00104 mom1n_orig = m1n;
00105 rot1n_orig = r1n;
00106 mom2n_orig = m2n;
00107 rot2n_orig = r2n;
00108 mom3n_orig = m3n;
00109 rot3n_orig = r3n;
00110
00111 energyA = 0.5 * (rot1p*mom1p + (rot2p-rot1p)*(mom2p+mom1p) + (rot3p-rot2p)*(mom3p+mom2p) +
00112 rot1n*mom1n + (rot2n-rot1n)*(mom2n+mom1n) * (rot3n-rot2n)*(mom3n+mom2n));
00113
00114
00115 this->setEnvelope();
00116
00117
00118 this->revertToStart();
00119 this->revertToLastCommit();
00120
00122
00123 curveType = 0;
00124 degrade = 0;
00126 }
00127
00128 LimitStateMaterial::LimitStateMaterial(int tag,
00129 double m1p, double r1p, double m2p, double r2p,
00130 double m1n, double r1n, double m2n, double r2n,
00131 double px, double py, double d1, double d2, double b):
00132 UniaxialMaterial(tag, MAT_TAG_LimitState),
00133 pinchX(px), pinchY(py), damfc1(d1), damfc2(d2), beta(b),
00134 mom1p(m1p), rot1p(r1p), mom3p(m2p), rot3p(r2p),
00135 mom1n(m1n), rot1n(r1n), mom3n(m2n), rot3n(r2n)
00136 {
00137 constructorType = 2;
00138 bool error = false;
00139
00140
00141 if (rot1p <= 0.0)
00142 error = true;
00143
00144 if (rot3p <= rot1p)
00145 error = true;
00146
00147
00148 if (rot1n >= 0.0)
00149 error = true;
00150
00151 if (rot3n >= rot1n)
00152 error = true;
00153
00154 if (error) {
00155
00156
00157 }
00158
00159
00160 pinchX_orig = px;
00161 pinchY_orig = py;
00162 damfc1_orig = d1;
00163 damfc2_orig = d2;
00164 beta_orig = b;
00165 mom1p_orig = m1p;
00166 rot1p_orig = r1p;
00167 mom2p_orig = m2p;
00168 rot2p_orig = r2p;
00169 mom3p_orig = m2p;
00170 rot3p_orig = r2p;
00171 mom1n_orig = m1n;
00172 rot1n_orig = r1n;
00173 mom2n_orig = m2n;
00174 rot2n_orig = r2n;
00175 mom3n_orig = m2n;
00176 rot3n_orig = r2n;
00177
00178 energyA = 0.5 * (rot1p*mom1p + (rot3p-rot1p)*(mom3p+mom1p) +
00179 rot1n*mom1n + (rot3n-rot1n)*(mom3n+mom1n));
00180
00181 mom2p = 0.5*(mom1p+mom3p);
00182 mom2n = 0.5*(mom1n+mom3n);
00183
00184 rot2p = 0.5*(rot1p+rot3p);
00185 rot2n = 0.5*(rot1n+rot3n);
00186
00187
00188 this->setEnvelope();
00189
00190
00191 this->revertToStart();
00192 this->revertToLastCommit();
00193
00194
00195
00197
00198 curveType = 0;
00199 degrade = 0;
00201 }
00202
00203 LimitStateMaterial::LimitStateMaterial(int tag,
00204 double m1p, double r1p, double m2p, double r2p, double m3p, double r3p,
00205 double m1n, double r1n, double m2n, double r2n, double m3n, double r3n,
00206 double px, double py, double d1, double d2, double b, LimitCurve &curve,
00207 int cType, int deg):
00208 UniaxialMaterial(tag, MAT_TAG_LimitState),
00209 mom1p(m1p), rot1p(r1p), mom2p(m2p), rot2p(r2p), mom3p(m3p), rot3p(r3p),
00210 mom1n(m1n), rot1n(r1n), mom2n(m2n), rot2n(r2n), mom3n(m3n), rot3n(r3n),
00211 pinchX(px), pinchY(py), damfc1(d1), damfc2(d2), beta(b), theCurve(0), curveType(cType),
00212 degrade(deg)
00213 {
00214 constructorType = 3;
00215 theCurve = curve.getCopy();
00216
00217 bool error = false;
00218
00219
00220 if (rot1p <= 0.0)
00221 error = true;
00222
00223 if (rot2p <= rot1p)
00224 error = true;
00225
00226 if (rot3p <= rot2p)
00227 error = true;
00228
00229
00230 if (rot1n >= 0.0)
00231 error = true;
00232
00233 if (rot2n >= rot1n)
00234 error = true;
00235
00236 if (rot3n >= rot2n)
00237 error = true;
00238
00239 if (error) {
00240
00241
00242
00243
00244 }
00245
00246
00247 pinchX_orig = px;
00248 pinchY_orig = py;
00249 damfc1_orig = d1;
00250 damfc2_orig = d2;
00251 beta_orig = b;
00252 mom1p_orig = m1p;
00253 rot1p_orig = r1p;
00254 mom2p_orig = m2p;
00255 rot2p_orig = r2p;
00256 mom3p_orig = m3p;
00257 rot3p_orig = r3p;
00258 mom1n_orig = m1n;
00259 rot1n_orig = r1n;
00260 mom2n_orig = m2n;
00261 rot2n_orig = r2n;
00262 mom3n_orig = m3n;
00263 rot3n_orig = r3n;
00264
00265
00266 energyA = 0.5 * (rot1p*mom1p + (rot2p-rot1p)*(mom2p+mom1p) + (rot3p-rot2p)*(mom3p+mom2p) +
00267 rot1n*mom1n + (rot2n-rot1n)*(mom2n+mom1n) * (rot3n-rot2n)*(mom3n+mom2n));
00268
00269
00271
00272
00273
00274 if (theCurve == 0) {
00275
00277 }
00278
00279
00280 this->setEnvelope();
00281
00283
00284 Eelasticp = E1p;
00285 Eelasticn = E1n;
00287
00288
00289 this->revertToStart();
00290 this->revertToLastCommit();
00291
00292
00293 }
00294
00295 LimitStateMaterial::LimitStateMaterial():
00296 UniaxialMaterial(0, MAT_TAG_LimitState),
00297 pinchX(0.0), pinchY(0.0), damfc1(0.0), damfc2(0.0), beta(0.0),
00298 mom1p(0.0), rot1p(0.0), mom2p(0.0), rot2p(0.0), mom3p(0.0), rot3p(0.0),
00299 mom1n(0.0), rot1n(0.0), mom2n(0.0), rot2n(0.0), mom3n(0.0), rot3n(0.0)
00300 {
00301 constructorType = 4;
00302
00303
00304 pinchX_orig = 0.0;
00305 pinchY_orig = 0.0;
00306 damfc1_orig = 0.0;
00307 damfc2_orig = 0.0;
00308 beta_orig = 0.0;
00309 mom1p_orig = 0.0;
00310 rot1p_orig = 0.0;
00311 mom2p_orig = 0.0;
00312 rot2p_orig = 0.0;
00313 mom3p_orig = 0.0;
00314 rot3p_orig = 0.0;
00315 mom1n_orig = 0.0;
00316 rot1n_orig = 0.0;
00317 mom2n_orig = 0.0;
00318 rot2n_orig = 0.0;
00319 mom3n_orig = 0.0;
00320 rot3n_orig = 0.0;
00321
00322 curveType = 0;
00323 }
00324
00325 LimitStateMaterial::~LimitStateMaterial()
00326 {
00328 if (curveType != 0)
00329 delete theCurve;
00331 }
00332
00333 int
00334 LimitStateMaterial::setTrialStrain(double strain, double strainRate)
00335 {
00336 TrotMax = CrotMax;
00337 TrotMin = CrotMin;
00338 TenergyD = CenergyD;
00339 TrotPu = CrotPu;
00340 TrotNu = CrotNu;
00341
00342 Tstrain = strain;
00343 double dStrain = Tstrain - Cstrain;
00344
00345 TloadIndicator = CloadIndicator;
00346
00347 if (TloadIndicator == 0)
00348 TloadIndicator = (dStrain < 0.0) ? 2 : 1;
00349
00350 if (Tstrain >= CrotMax) {
00351 TrotMax = Tstrain;
00352 Ttangent = posEnvlpTangent(Tstrain);
00353 Tstress = posEnvlpStress(Tstrain);
00354 }
00355 else if (Tstrain <= CrotMin) {
00356 TrotMin = Tstrain;
00357 Ttangent = negEnvlpTangent(Tstrain);
00358 Tstress = negEnvlpStress(Tstrain);
00359 }
00360 else {
00361 if (dStrain < 0.0)
00362 negativeIncrement(dStrain);
00363 else if (dStrain > 0.0)
00364 positiveIncrement(dStrain);
00365 }
00366
00367 TenergyD = CenergyD + 0.5*(Cstress+Tstress)*dStrain;
00368
00369 return 0;
00370 }
00371
00372
00373 double
00374 LimitStateMaterial::getStrain(void)
00375 {
00377
00378
00379
00380
00381
00382 double strain;
00383 double E3;
00384
00385 if (curveType != 0)
00386 E3 = theCurve->getDegSlope();
00387 else
00388 E3 = 1.0;
00389
00390 if (Tstrain < 0.0)
00391 strain = Tstrain + Ploss/E3;
00392 else
00393 strain = Tstrain - Ploss/E3;
00394
00395 return strain;
00397 }
00398
00399 double
00400 LimitStateMaterial::getStress(void)
00401 {
00403
00404
00405
00406
00407 double stress;
00408
00409 stress = Tstress + Ploss;
00410
00411 return stress;
00413 }
00414
00415 double
00416 LimitStateMaterial::getTangent(void)
00417 {
00419
00420
00421
00422 if (curveType == 1)
00423 {
00424 double E3 = theCurve->getDegSlope();
00425
00426 if (CstateFlag == 1 || CstateFlag == 2) {
00427 if (Tstrain > 0.0) {
00428 if (Tstrain > rot3p) {
00429 Ttangent = E1p*1.0e-9;
00430 } else {
00431 Ttangent = E3p;
00432 }
00433 } else {
00434 if (Tstrain < rot3n) {
00435 Ttangent = E1p*1.0e-9;
00436 } else {
00437 Ttangent = E3n;
00438 }
00439 }
00440 }
00441 }
00443
00444 return Ttangent;
00445 }
00446
00447 void
00448 LimitStateMaterial::positiveIncrement(double dStrain)
00449 {
00450 double kn = pow(CrotMin/rot1n,beta);
00451 kn = (kn < 1.0) ? 1.0 : 1.0/kn;
00452 double kp = pow(CrotMax/rot1p,beta);
00453 kp = (kp < 1.0) ? 1.0 : 1.0/kp;
00454
00455 if (TloadIndicator == 2) {
00456 TloadIndicator = 1;
00457 if (Cstress <= 0.0) {
00458 TrotNu = Cstrain - Cstress/(E1n*kn);
00459 double energy = CenergyD - 0.5*Cstress/(E1n*kn)*Cstress;
00460 double damfc = 1.0;
00461 if (CrotMin < rot1n) {
00462 damfc += damfc2*energy/energyA;
00463
00464 if (Cstrain == CrotMin) {
00465 damfc += damfc1*(CrotMax/rot1p-1.0);
00466 }
00467 }
00468
00469 TrotMax = CrotMax * damfc;
00470 }
00471 }
00472
00473 TloadIndicator = 1;
00474
00475 TrotMax = (TrotMax > rot1p) ? TrotMax : rot1p;
00476
00478
00479 if (degrade == 1)
00480 {
00481
00482 if (TrotMax < fabs(CrotMin))
00483 TrotMax = fabs(CrotMin);
00484 }
00486
00487 double maxmom = posEnvlpStress(TrotMax);
00488 double rotlim = negEnvlpRotlim(CrotMin);
00489 double rotrel = (rotlim > TrotNu) ? rotlim : TrotNu;
00490 rotrel = TrotNu;
00491 if (negEnvlpStress(CrotMin) >= 0.0)
00492 rotrel = rotlim;
00493
00494 double rotmp1 = rotrel + pinchY*(TrotMax-rotrel);
00495 double rotmp2 = TrotMax - (1.0-pinchY)*maxmom/(E1p*kp);
00496 double rotch = rotmp1 + (rotmp2-rotmp1)*pinchX;
00497
00498 double tmpmo1;
00499 double tmpmo2;
00500
00501 if (Tstrain < TrotNu) {
00502 Ttangent = E1n*kn;
00503 Tstress = Cstress + Ttangent*dStrain;
00504 if (Tstress >= 0.0) {
00505 Tstress = 0.0;
00506 Ttangent = E1n*1.0e-9;
00507 }
00508 }
00509
00510 else if (Tstrain >= TrotNu && Tstrain < rotch) {
00511 if (Tstrain <= rotrel) {
00512 Tstress = 0.0;
00513 Ttangent = E1p*1.0e-9;
00514 }
00515 else {
00516 Ttangent = maxmom*pinchY/(rotch-rotrel);
00517 tmpmo1 = Cstress + E1p*kp*dStrain;
00518 tmpmo2 = (Tstrain-rotrel)*Ttangent;
00519 if (tmpmo1 < tmpmo2) {
00520 Tstress = tmpmo1;
00521 Ttangent = E1p*kp;
00522 }
00523 else
00524 Tstress = tmpmo2;
00525 }
00526 }
00527
00528 else {
00529 Ttangent = (1.0-pinchY)*maxmom/(TrotMax-rotch);
00530 tmpmo1 = Cstress + E1p*kp*dStrain;
00531 tmpmo2 = pinchY*maxmom + (Tstrain-rotch)*Ttangent;
00532 if (tmpmo1 < tmpmo2) {
00533 Tstress = tmpmo1;
00534 Ttangent = E1p*kp;
00535 }
00536 else
00537 Tstress = tmpmo2;
00538 }
00539 }
00540
00541 void
00542 LimitStateMaterial::negativeIncrement(double dStrain)
00543 {
00544 double kn = pow(CrotMin/rot1n,beta);
00545 kn = (kn < 1.0) ? 1.0 : 1.0/kn;
00546 double kp = pow(CrotMax/rot1p,beta);
00547 kp = (kp < 1.0) ? 1.0 : 1.0/kp;
00548
00549 if (TloadIndicator == 1) {
00550 TloadIndicator = 2;
00551 if (Cstress >= 0.0) {
00552 TrotPu = Cstrain - Cstress/(E1p*kp);
00553 double energy = CenergyD - 0.5*Cstress/(E1p*kp)*Cstress;
00554 double damfc = 1.0;
00555 if (CrotMax > rot1p) {
00556 damfc += damfc2*energy/energyA;
00557
00558 if (Cstrain == CrotMax) {
00559 damfc += damfc1*(CrotMin/rot1n-1.0);
00560 }
00561 }
00562
00563 TrotMin = CrotMin * damfc;
00564 }
00565 }
00566
00567 TloadIndicator = 2;
00568
00569 TrotMin = (TrotMin < rot1n) ? TrotMin : rot1n;
00570
00572 if (degrade == 1)
00573 {
00574
00575 if (TrotMin > -1.0*(CrotMax))
00576 TrotMin = -1.0*(CrotMax);
00577 }
00579
00580 double minmom = negEnvlpStress(TrotMin);
00581 double rotlim = posEnvlpRotlim(CrotMax);
00582 double rotrel = (rotlim < TrotPu) ? rotlim : TrotPu;
00583 rotrel = TrotPu;
00584 if (posEnvlpStress(CrotMax) <= 0.0)
00585 rotrel = rotlim;
00586
00587 double rotmp1 = rotrel + pinchY*(TrotMin-rotrel);
00588 double rotmp2 = TrotMin - (1.0-pinchY)*minmom/(E1n*kn);
00589 double rotch = rotmp1 + (rotmp2-rotmp1)*pinchX;
00590
00591 double tmpmo1;
00592 double tmpmo2;
00593
00594
00595 if (Tstrain > TrotPu) {
00596 Ttangent = E1p*kp;
00597 Tstress = Cstress + Ttangent*dStrain;
00598 if (Tstress <= 0.0) {
00599 Tstress = 0.0;
00600 Ttangent = E1p*1.0e-9;
00601 }
00602 }
00603
00604 else if (Tstrain <= TrotPu && Tstrain > rotch) {
00605
00606 if (Tstrain >= rotrel) {
00607 Tstress = 0.0;
00608 Ttangent = E1n*1.0e-9;
00609 }
00610 else {
00611 Ttangent = minmom*pinchY/(rotch-rotrel);
00612 tmpmo1 = Cstress + E1n*kn*dStrain;
00613 tmpmo2 = (Tstrain-rotrel)*Ttangent;
00614 if (tmpmo1 > tmpmo2) {
00615 Tstress = tmpmo1;
00616 Ttangent = E1n*kn;
00617 }
00618 else
00619 Tstress = tmpmo2;
00620 }
00621 }
00622
00623 else {
00624 Ttangent = (1.0-pinchY)*minmom/(TrotMin-rotch);
00625 tmpmo1 = Cstress + E1n*kn*dStrain;
00626 tmpmo2 = pinchY*minmom + (Tstrain-rotch)*Ttangent;
00627 if (tmpmo1 > tmpmo2) {
00628 Tstress = tmpmo1;
00629 Ttangent = E1n*kn;
00630 }
00631 else
00632 Tstress = tmpmo2;
00633 }
00634 }
00635
00636 int
00637 LimitStateMaterial::commitState(void)
00638 {
00639 CrotMax = TrotMax;
00640 CrotMin = TrotMin;
00641 CrotPu = TrotPu;
00642 CrotNu = TrotNu;
00643 CenergyD = TenergyD;
00644 CloadIndicator = TloadIndicator;
00645
00646 Cstress = Tstress;
00647 Cstrain = Tstrain;
00648
00649 int result = 0;
00650
00652
00653
00654 if (curveType != 0 && CstateFlag != 4)
00655 {
00657
00658
00659
00660 int stateFlag = theCurve->checkElementState(Cstress);
00661
00662
00663
00664
00665 if (stateFlag == 1)
00666 {
00667
00668
00669
00670 if (Cstrain != CrotMax && Cstrain != CrotMin) {
00671
00672
00673 }
00674
00675 result += getNewBackbone(stateFlag);
00676
00677
00678 if (curveType != 1)
00679 result += mirrorBackbone();
00680
00681
00682 }
00683
00684
00685 if (curveType == 1) {
00686
00687
00688 if (stateFlag == 1 || stateFlag == 2 || stateFlag == 4) {
00689 Ploss += theCurve->getUnbalanceForce();
00690 opserr << "Axial load loss: " << Ploss << endln;
00691 }
00692
00693
00694 if (CstateFlag == 2 || CstateFlag == 1) {
00695 if (stateFlag == 3) {
00696 result += getNewBackbone(stateFlag);
00697
00698 }
00699
00700 }
00701
00702
00703 if (CstateFlag == 3) {
00704 if (stateFlag == 2) {
00705 result += getNewBackbone(stateFlag);
00706
00707 }
00708 }
00709
00710
00711
00712 if (stateFlag == 4) {
00713 result += getNewBackbone(stateFlag);
00714
00715 }
00716 }
00717
00718
00719 CstateFlag = stateFlag;
00720
00721 }
00722
00723 return 0;
00724 }
00725
00726 int
00727 LimitStateMaterial::revertToLastCommit(void)
00728 {
00729 TrotMax = CrotMax;
00730 TrotMin = CrotMin;
00731 TrotPu = CrotPu;
00732 TrotNu = CrotNu;
00733 TenergyD = CenergyD;
00734 TloadIndicator = CloadIndicator;
00735
00736 Tstress = Cstress;
00737 Tstrain = Cstrain;
00738
00739 return 0;
00740 }
00741
00742 int
00743 LimitStateMaterial::revertToStart(void)
00744 {
00745 CrotMax = 0.0;
00746 CrotMin = 0.0;
00747 CrotPu = 0.0;
00748 CrotNu = 0.0;
00749 CenergyD = 0.0;
00750 CloadIndicator = 0;
00751
00752 Cstress = 0.0;
00753 Cstrain = 0.0;
00754
00755 Tstrain = 0;
00756 Tstress = 0;
00757 Ttangent = E1p;
00758
00760
00761 CstateFlag = 0;
00762
00763 Ploss = 0.0;
00765
00766
00767 theCurve->revertToStart();
00768
00769
00770
00771 pinchX = pinchX_orig;
00772 pinchY = pinchY_orig;
00773 damfc1 = damfc1_orig;
00774 damfc2 = damfc2_orig;
00775 beta = beta_orig;
00776 mom1p = mom1p_orig;
00777 rot1p = rot1p_orig;
00778 mom2p = mom2p_orig;
00779 rot2p = rot2p_orig;
00780 mom3p = mom3p_orig;
00781 rot3p = rot3p_orig;
00782 mom1n = mom1n_orig;
00783 rot1n = rot1n_orig;
00784 mom2n = mom2n_orig;
00785 rot2n = rot2n_orig;
00786 mom3n = mom3n_orig;
00787 rot3n = rot3n_orig;
00788
00789 energyA = 0.5 * (rot1p*mom1p + (rot2p-rot1p)*(mom2p+mom1p) + (rot3p-rot2p)*(mom3p+mom2p) +
00790 rot1n*mom1n + (rot2n-rot1n)*(mom2n+mom1n) * (rot3n-rot2n)*(mom3n+mom2n));
00791
00792
00793 if (constructorType == 2) {
00794 mom2p = 0.5*(mom1p+mom3p);
00795 mom2n = 0.5*(mom1n+mom3n);
00796
00797 rot2p = 0.5*(rot1p+rot3p);
00798 rot2n = 0.5*(rot1n+rot3n);
00799 }
00800
00801
00802
00803 this->setEnvelope();
00804
00805
00806 Eelasticp = E1p;
00807 Eelasticn = E1n;
00808
00809
00810
00811 this->revertToLastCommit();
00812
00813
00814 return 0;
00815 }
00816
00817 UniaxialMaterial*
00818 LimitStateMaterial::getCopy(void)
00819 {
00821 if (curveType == 0) {
00822 LimitStateMaterial *theCopy = new LimitStateMaterial (this->getTag(),
00823 mom1p, rot1p, mom2p, rot2p, mom3p, rot3p,
00824 mom1n, rot1n, mom2n, rot2n, mom3n, rot3n,
00825 pinchX, pinchY, damfc1, damfc2, beta);
00826
00827 theCopy->CrotMax = CrotMax;
00828 theCopy->CrotMin = CrotMin;
00829 theCopy->CrotPu = CrotPu;
00830 theCopy->CrotNu = CrotNu;
00831 theCopy->CenergyD = CenergyD;
00832 theCopy->CloadIndicator = CloadIndicator;
00833 theCopy->Cstress = Cstress;
00834 theCopy->Cstrain = Cstrain;
00835 theCopy->Ttangent = Ttangent;
00836 theCopy->CstateFlag = CstateFlag;
00837
00838 return theCopy;
00839 }
00840 else {
00841 LimitStateMaterial *theCopy = new LimitStateMaterial (this->getTag(),
00842 mom1p, rot1p, mom2p, rot2p, mom3p, rot3p,
00843 mom1n, rot1n, mom2n, rot2n, mom3n, rot3n,
00844 pinchX, pinchY, damfc1, damfc2, beta, *theCurve, curveType, degrade);
00845
00846 theCopy->CrotMax = CrotMax;
00847 theCopy->CrotMin = CrotMin;
00848 theCopy->CrotPu = CrotPu;
00849 theCopy->CrotNu = CrotNu;
00850 theCopy->CenergyD = CenergyD;
00851 theCopy->CloadIndicator = CloadIndicator;
00852 theCopy->Cstress = Cstress;
00853 theCopy->Cstrain = Cstrain;
00854 theCopy->Ttangent = Ttangent;
00855 theCopy->CstateFlag = CstateFlag;
00856
00857 return theCopy;
00858 }
00860 }
00861
00862 int
00863 LimitStateMaterial::sendSelf(int commitTag, Channel &theChannel)
00864 {
00865 int res = 0;
00866
00867 static Vector data(27);
00868
00869 data(0) = this->getTag();
00870 data(1) = mom1p;
00871 data(2) = rot1p;
00872 data(3) = mom2p;
00873 data(4) = rot2p;
00874 data(5) = mom3p;
00875 data(6) = rot3p;
00876 data(7) = mom1n;
00877 data(8) = rot1n;
00878 data(9) = mom2n;
00879 data(10) = rot2n;
00880 data(11) = mom3n;
00881 data(12) = rot3n;
00882 data(13) = pinchX;
00883 data(14) = pinchY;
00884 data(15) = damfc1;
00885 data(16) = damfc2;
00886 data(17) = beta;
00887 data(18) = CrotMax;
00888 data(19) = CrotMin;
00889 data(20) = CrotPu;
00890 data(21) = CrotNu;
00891 data(22) = CenergyD;
00892 data(23) = CloadIndicator;
00893 data(24) = Cstress;
00894 data(25) = Cstrain;
00895 data(26) = Ttangent;
00896
00897 res = theChannel.sendVector(this->getDbTag(), commitTag, data);
00898 if (res < 0)
00899 opserr << "LimitStateMaterial::sendSelf() - failed to send data\n";
00900
00901
00902 return res;
00903 }
00904
00905 int
00906 LimitStateMaterial::recvSelf(int commitTag, Channel &theChannel,
00907 FEM_ObjectBroker &theBroker)
00908 {
00909 int res = 0;
00910
00911 static Vector data(27);
00912 res = theChannel.recvVector(this->getDbTag(), commitTag, data);
00913
00914 if (res < 0) {
00915 opserr << "LimitStateMaterial::recvSelf() - failed to receive data\n";
00916 return res;
00917 }
00918 else {
00919 this->setTag((int)data(0));
00920 mom1p = data(1);
00921 rot1p = data(2);
00922 mom2p = data(3);
00923 rot2p = data(4);
00924 mom3p = data(5);
00925 rot3p = data(6);
00926 mom1n = data(7);
00927 rot1n = data(8);
00928 mom2n = data(9);
00929 rot2n = data(10);
00930 mom3n = data(11);
00931 rot3n = data(12);
00932 pinchX = data(13);
00933 pinchY = data(14);
00934 damfc1 = data(15);
00935 damfc2 = data(16);
00936 beta = data(17);
00937 CrotMax = data(18);
00938 CrotMin = data(19);
00939 CrotPu = data(20);
00940 CrotNu = data(21);
00941 CenergyD = data(22);
00942 CloadIndicator = int(data(23));
00943 Cstress = data(24);
00944 Cstrain = data(25);
00945 Ttangent = data(26);
00946
00947
00948 TrotMax = CrotMax;
00949 TrotMin = CrotMin;
00950 TrotPu = CrotPu;
00951 TrotNu = CrotNu;
00952 TenergyD = CenergyD;
00953 TloadIndicator = CloadIndicator;
00954 Tstress = Cstress;
00955 Tstrain = Cstrain;
00956
00957 }
00958
00959 return 0;
00960 }
00961
00962 void
00963 LimitStateMaterial::Print(OPS_Stream &s, int flag)
00964 {
00965 s << "LimitState Material, tag: " << this->getTag() << endln;
00966 s << "mom1p: " << mom1p << endln;
00967 s << "rot1p: " << rot1p << endln;
00968 s << "E1p: " << E1p << endln;
00969 s << "mom2p: " << mom2p << endln;
00970 s << "rot2p: " << rot2p << endln;
00971 s << "E2p: " << E2p << endln;
00972 s << "mom3p: " << mom3p << endln;
00973 s << "rot3p: " << rot3p << endln;
00974 s << "E3p: " << E3p << endln;
00975
00976 s << "mom1n: " << mom1n << endln;
00977 s << "rot1n: " << rot1n << endln;
00978 s << "E1n: " << E1n << endln;
00979 s << "mom2n: " << mom2n << endln;
00980 s << "rot2n: " << rot2n << endln;
00981 s << "E2n: " << E2n << endln;
00982 s << "mom3n: " << mom3n << endln;
00983 s << "rot3n: " << rot3n << endln;
00984 s << "E3n: " << E3n << endln;
00985
00986 s << "pinchX: " << pinchX << endln;
00987 s << "pinchY: " << pinchY << endln;
00988 s << "damfc1: " << damfc1 << endln;
00989 s << "damfc2: " << damfc2 << endln;
00990 s << "energyA: " << energyA << endln;
00991 s << "beta: " << beta << endln;
00993 s << "CstateFlag: " << CstateFlag << endln;
00994 s << "Cstress: " << Cstress << endln;
00995 s << "Cstrain: " << Cstrain << endln;
00997 }
00998
00999 void
01000 LimitStateMaterial::setEnvelope(void)
01001 {
01002 E1p = mom1p/rot1p;
01003 E2p = (mom2p-mom1p)/(rot2p-rot1p);
01004 E3p = (mom3p-mom2p)/(rot3p-rot2p);
01005
01006 E1n = mom1n/rot1n;
01007 E2n = (mom2n-mom1n)/(rot2n-rot1n);
01008 E3n = (mom3n-mom2n)/(rot3n-rot2n);
01009 }
01010
01011 double
01012 LimitStateMaterial::posEnvlpStress(double strain)
01013 {
01014 if (strain <= 0.0)
01015 return 0.0;
01016 else if (strain <= rot1p)
01017 return E1p*strain;
01018 else if (strain <= rot2p)
01019 return mom1p + E2p*(strain-rot1p);
01020 else if (strain <= rot3p || E3p > 0.0)
01021 return mom2p + E3p*(strain-rot2p);
01022 else
01023 return mom3p;
01024 }
01025
01026 double
01027 LimitStateMaterial::negEnvlpStress(double strain)
01028 {
01029 if (strain >= 0.0)
01030 return 0.0;
01031 else if (strain >= rot1n)
01032 return E1n*strain;
01033 else if (strain >= rot2n)
01034 return mom1n + E2n*(strain-rot1n);
01035 else if (strain >= rot3n || E3n > 0.0)
01036 return mom2n + E3n*(strain-rot2n);
01037 else
01038 return mom3n;
01039 }
01040
01041 double
01042 LimitStateMaterial::posEnvlpTangent(double strain)
01043 {
01044 if (strain < 0.0)
01045 return E1p*1.0e-9;
01046 else if (strain <= rot1p)
01047 return E1p;
01048 else if (strain <= rot2p)
01049 return E2p;
01050 else if (strain <= rot3p || E3p > 0.0)
01051 return E3p;
01052 else
01053 return E1p*1.0e-9;
01054 }
01055
01056 double
01057 LimitStateMaterial::negEnvlpTangent(double strain)
01058 {
01059 if (strain > 0.0)
01060 return E1n*1.0e-9;
01061 else if (strain >= rot1n)
01062 return E1n;
01063 else if (strain >= rot2n)
01064 return E2n;
01065 else if (strain >= rot3n || E3n > 0.0)
01066 return E3n;
01067 else
01068 return E1n*1.0e-9;
01069 }
01070
01071 double
01072 LimitStateMaterial::posEnvlpRotlim(double strain)
01073 {
01074 double strainLimit = POS_INF_STRAIN;
01075
01076 if (strain <= rot1p)
01077 return POS_INF_STRAIN;
01078 if (strain > rot1p && strain <= rot2p && E2p < 0.0)
01079 strainLimit = rot1p - mom1p/E2p;
01080 if (strain > rot2p && E3p < 0.0)
01081 strainLimit = rot2p - mom2p/E3p;
01082
01083 if (strainLimit == POS_INF_STRAIN)
01084 return POS_INF_STRAIN;
01085 else if (posEnvlpStress(strainLimit) > 0)
01086 return POS_INF_STRAIN;
01087 else
01088 return strainLimit;
01089 }
01090
01091 double
01092 LimitStateMaterial::negEnvlpRotlim(double strain)
01093 {
01094 double strainLimit = NEG_INF_STRAIN;
01095
01096 if (strain >= rot1n)
01097 return NEG_INF_STRAIN;
01098 if (strain < rot1n && strain >= rot2n && E2n < 0.0)
01099 strainLimit = rot1n - mom1n/E2n;
01100 if (strain < rot2n && E3n < 0.0)
01101 strainLimit = rot2n - mom2n/E3n;
01102
01103 if (strainLimit == NEG_INF_STRAIN)
01104 return NEG_INF_STRAIN;
01105 else if (negEnvlpStress(strainLimit) < 0)
01106 return NEG_INF_STRAIN;
01107 else
01108 return strainLimit;
01109 }
01110
01112 int
01113 LimitStateMaterial::getNewBackbone(int flag)
01114 {
01115 double k3 = theCurve->getDegSlope();
01116 double Fr = theCurve->getResForce();
01117
01118
01119 if (flag == 4) {
01120 if (Cstress > 0.0) {
01121 mom3p = Cstress;
01122 rot3p = Cstrain;
01123 rot2p = (rot3p+rot1p)/2;
01124 mom2p = mom3p-(rot3p-rot2p)*(E1p*1.0e-9);
01125 }
01126 else {
01127 mom3n = Cstress;
01128 rot3n = Cstrain;
01129 rot2n = (rot3n+rot1n)/2;
01130 mom2n = mom3n-(rot3n-rot2n)*(E1n*1.0e-9);
01131 }
01132 }
01133 else {
01134
01135
01136
01137 if (Cstress > 0.0) {
01138 mom2p = Cstress;
01139 rot2p = Cstrain;
01140 }
01141 else {
01142 mom2n = Cstress;
01143 rot2n = Cstrain;
01144 }
01145
01146
01147
01148 if (Cstrain <= rot1p && Cstrain >= rot1n) {
01149 if (Cstress > 0.0) {
01150 mom1p = mom2p/2.0;
01151 rot1p = mom1p/Eelasticp;
01152 }
01153 else {
01154 mom1n = mom2n/2.0;
01155 rot1n = mom1n/Eelasticn;
01156 }
01157 }
01158
01159
01160 if (flag == 3 && curveType == 1) {
01161 if (Cstress > 0.0) {
01162 mom3p = 10*mom2p;
01163
01164 rot3p = rot2p + (mom3p-mom2p)/(Eelasticp*0.01);
01165 }
01166 else {
01167 mom3n = 10*mom2n;
01168
01169 rot3n = rot2n + (mom3n-mom2n)/(Eelasticn*0.01);
01170 }
01171 }
01172 else {
01173 if (Cstress > 0.0) {
01174 mom3p = Fr;
01175 rot3p = rot2p + (mom3p-mom2p)/k3;
01176 }
01177 else {
01178 mom3n = -1*Fr;
01179 rot3n = rot2n + (mom3n-mom2n)/k3;
01180 }
01181 }
01182 }
01183
01184
01185 bool error = false;
01186
01187
01188 if (rot1p <= 0.0)
01189 error = true;
01190 if (rot2p <= rot1p)
01191 error = true;
01192 if (rot3p <= rot2p)
01193 error = true;
01194
01195 if (rot1n >= 0.0)
01196 error = true;
01197 if (rot2n >= rot1n)
01198 error = true;
01199 if (rot3n >= rot2n)
01200 error = true;
01201
01202 if (error)
01203 {
01204
01205
01206
01207 }
01208
01209
01210 energyA = 0.5 * (rot1p*mom1p + (rot2p-rot1p)*(mom2p+mom1p) + (rot3p-rot2p)*(mom3p+mom2p) +
01211 rot1n*mom1n + (rot2n-rot1n)*(mom2n+mom1n) * (rot3n-rot2n)*(mom3n+mom2n));
01212
01213 if (Cstress > 0.0) {
01214 E1p = mom1p/rot1p;
01215 E2p = (mom2p-mom1p)/(rot2p-rot1p);
01216 E3p = (mom3p-mom2p)/(rot3p-rot2p);
01217 }
01218 else {
01219 E1n = mom1n/rot1n;
01220 E2n = (mom2n-mom1n)/(rot2n-rot1n);
01221 E3n = (mom3n-mom2n)/(rot3n-rot2n);
01222 }
01223
01224 if (Cstress > 0.0)
01225 return 1;
01226 else
01227 return -1;
01228
01229 }
01230
01231 int
01232 LimitStateMaterial::mirrorBackbone(void)
01233 {
01234 if (Cstress > 0.0) {
01235 E1n = E1p;
01236 E2n = E2p;
01237 E3n = E3p;
01238 mom1n = -mom1p;
01239 mom2n = -mom2p;
01240 mom3n = -mom3p;
01241 rot1n = -rot1p;
01242 rot2n = -rot2p;
01243 rot3n = -rot3p;
01244 }
01245 else {
01246 E1p = E1n;
01247 E2p = E2n;
01248 E3p = E3n;
01249 mom1p = -mom1n;
01250 mom2p = -mom2n;
01251 mom3p = -mom3n;
01252 rot1p = -rot1n;
01253 rot2p = -rot2n;
01254 rot3p = -rot3n;
01255 }
01256 return 0;
01257 }
01259
01260
01261
01262
01263 int
01264 LimitStateMaterial::setParameter(const char **argv, int argc, Parameter ¶m)
01265 {
01266 return theCurve->setParameter(argv, argc, param);
01267 }