HystereticMaterial.cpp

Go to the documentation of this file.
00001 /* ****************************************************************** **
00002 **    OpenSees - Open System for Earthquake Engineering Simulation    **
00003 **          Pacific Earthquake Engineering Research Center            **
00004 **                                                                    **
00005 **                                                                    **
00006 ** (C) Copyright 1999, The Regents of the University of California    **
00007 ** All Rights Reserved.                                               **
00008 **                                                                    **
00009 ** Commercial use of this program without express permission of the   **
00010 ** University of California, Berkeley, is strictly prohibited.  See   **
00011 ** file 'COPYRIGHT'  in main directory for information on usage and   **
00012 ** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
00013 **                                                                    **
00014 ** Developed by:                                                      **
00015 **   Frank McKenna (fmckenna@ce.berkeley.edu)                         **
00016 **   Gregory L. Fenves (fenves@ce.berkeley.edu)                       **
00017 **   Filip C. Filippou (filippou@ce.berkeley.edu)                     **
00018 **                                                                    **
00019 ** ****************************************************************** */
00020                                                                         
00021 // $Revision: 1.15 $
00022 // $Date: 2006/10/03 20:37:41 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/HystereticMaterial.cpp,v $
00024 
00025 // Written: MHS
00026 // Created: July 2000
00027 //
00028 // Description: This file contains the implementation of 
00029 // HystereticMaterial.  HystereticMaterial is
00030 // a one-dimensional hysteretic model with pinching of both
00031 // force and deformation, damage due to deformation and energy, and
00032 // degraded unloading stiffness based on maximum ductility.  This
00033 // is a modified implementation of Hyster2.f90 by Filippou.
00034 #include <stdlib.h>
00035 #include <HystereticMaterial.h>
00036 #include <OPS_Globals.h>
00037 #include <math.h>
00038 #include <float.h>
00039 #include <Channel.h>
00040 
00041 HystereticMaterial::HystereticMaterial(int tag,
00042                         double m1p, double r1p, double m2p, double r2p, double m3p, double r3p,
00043                         double m1n, double r1n, double m2n, double r2n, double m3n, double r3n,
00044                         double px, double py, double d1, double d2, double b):
00045 UniaxialMaterial(tag, MAT_TAG_Hysteretic),
00046 pinchX(px), pinchY(py), damfc1(d1), damfc2(d2), beta(b),
00047 mom1p(m1p), rot1p(r1p), mom2p(m2p), rot2p(r2p), mom3p(m3p), rot3p(r3p),
00048 mom1n(m1n), rot1n(r1n), mom2n(m2n), rot2n(r2n), mom3n(m3n), rot3n(r3n)
00049 {
00050         bool error = false;
00051         // Positive backbone parameters
00052         if (rot1p <= 0.0)
00053                 error = true;
00054 
00055         if (rot2p <= rot1p)
00056                 error = true;
00057 
00058         if (rot3p <= rot2p)
00059                 error = true;
00060 
00061         // Negative backbone parameters
00062         if (rot1n >= 0.0)
00063                 error = true;
00064 
00065         if (rot2n >= rot1n)
00066                 error = true;
00067 
00068         if (rot3n >= rot2n)
00069                 error = true;
00070         
00071         if (error) {
00072           opserr << "HystereticMaterial::HystereticMaterial -- input backbone is not unique (one-to-one)\n";
00073           exit(-1);
00074         }               
00075 
00076         energyA = 0.5 * (rot1p*mom1p + (rot2p-rot1p)*(mom2p+mom1p) + (rot3p-rot2p)*(mom3p+mom2p) +
00077                 rot1n*mom1n + (rot2n-rot1n)*(mom2n+mom1n) + (rot3n-rot2n)*(mom3n+mom2n));
00078 
00079         // Set envelope slopes
00080         this->setEnvelope();
00081 
00082         // Initialize history variables
00083         this->revertToStart();
00084         this->revertToLastCommit();
00085 }
00086 
00087 HystereticMaterial::HystereticMaterial(int tag,
00088                         double m1p, double r1p, double m2p, double r2p,
00089                         double m1n, double r1n, double m2n, double r2n,
00090                         double px, double py, double d1, double d2, double b):
00091 UniaxialMaterial(tag, MAT_TAG_Hysteretic),
00092 pinchX(px), pinchY(py), damfc1(d1), damfc2(d2), beta(b),
00093 mom1p(m1p), rot1p(r1p), mom3p(m2p), rot3p(r2p),
00094 mom1n(m1n), rot1n(r1n), mom3n(m2n), rot3n(r2n)
00095 {
00096         bool error = false;
00097         
00098         // Positive backbone parameters
00099         if (rot1p <= 0.0)
00100                 error = true;
00101 
00102         if (rot3p <= rot1p)
00103                 error = true;
00104 
00105         // Negative backbone parameters
00106         if (rot1n >= 0.0)
00107                 error = true;
00108 
00109         if (rot3n >= rot1n)
00110                 error = true;
00111 
00112         if (error) {
00113           opserr << "HystereticMaterial::HystereticMaterial -- input backbone is not unique (one-to-one)\n";
00114           exit(-1);
00115         }
00116 
00117                                       
00118 
00119         energyA = 0.5 * (rot1p*mom1p + (rot3p-rot1p)*(mom3p+mom1p) +
00120                 rot1n*mom1n + (rot3n-rot1n)*(mom3n+mom1n));
00121 
00122         mom2p = 0.5*(mom1p+mom3p);
00123         mom2n = 0.5*(mom1n+mom3n);
00124 
00125         rot2p = 0.5*(rot1p+rot3p);
00126         rot2n = 0.5*(rot1n+rot3n);
00127 
00128         opserr << mom1p << " " << mom2p << " " << mom3p << " " << rot1p << " " << rot2p << " " << rot3p << endln;
00129 
00130         // Set envelope slopes
00131         this->setEnvelope();
00132 
00133         // Initialize history variables
00134         this->revertToStart();
00135         this->revertToLastCommit();
00136 }
00137 
00138 HystereticMaterial::HystereticMaterial():
00139 UniaxialMaterial(0, MAT_TAG_Hysteretic),
00140 pinchX(0.0), pinchY(0.0), damfc1(0.0), damfc2(0.0), beta(0.0),
00141 mom1p(0.0), rot1p(0.0), mom2p(0.0), rot2p(0.0), mom3p(0.0), rot3p(0.0),
00142 mom1n(0.0), rot1n(0.0), mom2n(0.0), rot2n(0.0), mom3n(0.0), rot3n(0.0)
00143 {
00144 
00145 }
00146 
00147 HystereticMaterial::~HystereticMaterial()
00148 {
00149         // Nothing to do
00150 }
00151 
00152 int
00153 HystereticMaterial::setTrialStrain(double strain, double strainRate)
00154 {
00155   if (TloadIndicator == 0 && strain == 0.0)
00156     return 0;
00157 
00158   TrotMax = CrotMax;
00159   TrotMin = CrotMin;
00160   TenergyD = CenergyD;
00161   TrotPu = CrotPu;
00162   TrotNu = CrotNu;
00163 
00164   Tstrain = strain;
00165   double dStrain = Tstrain - Cstrain;
00166   
00167   TloadIndicator = CloadIndicator;
00168   
00169   if (TloadIndicator == 0)
00170     TloadIndicator = (dStrain < 0.0) ? 2 : 1;
00171   
00172   if (Tstrain >= CrotMax) {
00173     TrotMax = Tstrain;
00174     Ttangent = posEnvlpTangent(Tstrain);
00175     Tstress = posEnvlpStress(Tstrain);
00176   }
00177   else if (Tstrain <= CrotMin) {
00178     TrotMin = Tstrain;
00179     Ttangent = negEnvlpTangent(Tstrain);
00180     Tstress = negEnvlpStress(Tstrain);
00181   }
00182   else {
00183     if (dStrain < 0.0)
00184       negativeIncrement(dStrain);
00185     else if (dStrain > 0.0)
00186       positiveIncrement(dStrain);
00187   }
00188   
00189   TenergyD = CenergyD + 0.5*(Cstress+Tstress)*dStrain;
00190   
00191   return 0;
00192 }
00193 
00194 
00195 double
00196 HystereticMaterial::getStrain(void)
00197 {
00198         return Tstrain;
00199 }
00200 
00201 double
00202 HystereticMaterial::getStress(void)
00203 {
00204         return Tstress;
00205 }
00206 
00207 double
00208 HystereticMaterial::getTangent(void)
00209 {
00210         return Ttangent;
00211 }
00212 
00213 void
00214 HystereticMaterial::positiveIncrement(double dStrain)
00215 {
00216         double kn = pow(CrotMin/rot1n,beta);
00217         kn = (kn < 1.0) ? 1.0 : 1.0/kn;
00218         double kp = pow(CrotMax/rot1p,beta);
00219         kp = (kp < 1.0) ? 1.0 : 1.0/kp;
00220 
00221         if (TloadIndicator == 2) {
00222                 TloadIndicator = 1;
00223                 if (Cstress <= 0.0) {
00224                         TrotNu = Cstrain - Cstress/(E1n*kn);
00225                         double energy = CenergyD - 0.5*Cstress/(E1n*kn)*Cstress;
00226                         double damfc = 0.0;
00227                         if (CrotMin < rot1n) {
00228                                 damfc = damfc2*energy/energyA;
00229                                 damfc += damfc1*(CrotMin-rot1n)/rot1n;
00230                         }
00231 
00232                         TrotMax = CrotMax*(1.0+damfc);
00233                 }
00234         }
00235 
00236   TloadIndicator = 1;
00237 
00238         TrotMax = (TrotMax > rot1p) ? TrotMax : rot1p;
00239 
00240         double maxmom = posEnvlpStress(TrotMax);
00241         double rotlim = negEnvlpRotlim(CrotMin);
00242         double rotrel = (rotlim > TrotNu) ? rotlim : TrotNu;
00243 
00244         // rotrel = TrotNu;
00245         // if (negEnvlpStress(CrotMin) >= 0.0)
00246         //    rotrel = rotlim;
00247         
00248         //      double rotmp1 = rotrel + pinchY*(TrotMax-rotrel);
00249 
00250         double rotmp2 = TrotMax - (1.0-pinchY)*maxmom/(E1p*kp);
00251         //double rotmp2 = TrotMax-(1-pinchY)*maxmom/E1p;
00252         //      double rotch = rotmp1 + (rotmp2-rotmp1)*pinchX;
00253         double rotch = rotrel + (rotmp2-rotrel)*pinchX;                   // changed on 7/11/2006
00254 
00255         double tmpmo1;
00256         double tmpmo2;
00257 
00258         if (Tstrain < TrotNu) {
00259                 Ttangent = E1n*kn;
00260                 Tstress = Cstress + Ttangent*dStrain;
00261                 if (Tstress >= 0.0) {
00262                         Tstress = 0.0;
00263                         Ttangent = E1n*1.0e-9;
00264                 }
00265         }
00266 
00267         else if (Tstrain >= TrotNu && Tstrain < rotch) {
00268                 if (Tstrain <= rotrel) {
00269                         Tstress = 0.0;
00270                         Ttangent = E1p*1.0e-9;
00271                 }
00272                 else {
00273                         Ttangent = maxmom*pinchY/(rotch-rotrel);
00274                         tmpmo1 = Cstress + E1p*kp*dStrain;
00275                         tmpmo2 = (Tstrain-rotrel)*Ttangent;
00276                         if (tmpmo1 < tmpmo2) {
00277                                 Tstress = tmpmo1;
00278                                 Ttangent = E1p*kp;
00279                         }
00280                         else
00281                                 Tstress = tmpmo2;
00282                 }
00283         }
00284 
00285         else {
00286                 Ttangent = (1.0-pinchY)*maxmom/(TrotMax-rotch);
00287                 tmpmo1 = Cstress + E1p*kp*dStrain;
00288                 tmpmo2 = pinchY*maxmom + (Tstrain-rotch)*Ttangent;
00289                 if (tmpmo1 < tmpmo2) {
00290                         Tstress = tmpmo1;
00291                         Ttangent = E1p*kp;
00292                 }
00293                 else
00294                         Tstress = tmpmo2;
00295         }
00296 }
00297 
00298 void
00299 HystereticMaterial::negativeIncrement(double dStrain)
00300 {
00301         double kn = pow(CrotMin/rot1n,beta);
00302         kn = (kn < 1.0) ? 1.0 : 1.0/kn;
00303         double kp = pow(CrotMax/rot1p,beta);
00304         kp = (kp < 1.0) ? 1.0 : 1.0/kp;
00305 
00306         if (TloadIndicator == 1) {
00307                 TloadIndicator = 2;
00308                 if (Cstress >= 0.0) {
00309                         TrotPu = Cstrain - Cstress/(E1p*kp);
00310                         double energy = CenergyD - 0.5*Cstress/(E1p*kp)*Cstress;
00311                         double damfc = 0.0;
00312                         if (CrotMax > rot1p) {
00313                                 damfc = damfc2*energy/energyA;
00314                                 damfc += damfc1*(CrotMax-rot1p)/rot1p;
00315                         }
00316 
00317                         TrotMin = CrotMin*(1.0+damfc);
00318                 }
00319         }
00320 
00321   TloadIndicator = 2;
00322 
00323         TrotMin = (TrotMin < rot1n) ? TrotMin : rot1n;
00324 
00325         double minmom = negEnvlpStress(TrotMin);
00326         double rotlim = posEnvlpRotlim(CrotMax);
00327         double rotrel = (rotlim < TrotPu) ? rotlim : TrotPu;
00328 
00329         //rotrel = TrotPu;
00330         //if (posEnvlpStress(CrotMax) <= 0.0)
00331         //  rotrel = rotlim;
00332 
00333         //double rotmp1 = rotrel + pinchY*(TrotMin-rotrel);
00334         double rotmp2 = TrotMin - (1.0-pinchY)*minmom/(E1n*kn);
00335         //double rotmp2 = TrotMin-(1-pinchY)*minmom/E1n;        
00336         //double rotch = rotmp1 + (rotmp2-rotmp1)*pinchX;
00337         double rotch = rotrel + (rotmp2-rotrel)*pinchX;                   // changed on 7/11/2006
00338 
00339         double tmpmo1;
00340         double tmpmo2;
00341 
00342         if (Tstrain > TrotPu) {
00343                 Ttangent = E1p*kp;
00344                 Tstress = Cstress + Ttangent*dStrain;
00345                 if (Tstress <= 0.0) {
00346                         Tstress = 0.0;
00347                         Ttangent = E1p*1.0e-9;
00348                 }
00349         }
00350 
00351         else if (Tstrain <= TrotPu && Tstrain > rotch) {
00352                 if (Tstrain >= rotrel) {
00353                         Tstress = 0.0;
00354                         Ttangent = E1n*1.0e-9;
00355                 }
00356                 else {
00357                         Ttangent = minmom*pinchY/(rotch-rotrel);
00358                         tmpmo1 = Cstress + E1n*kn*dStrain;
00359                         tmpmo2 = (Tstrain-rotrel)*Ttangent;
00360                         if (tmpmo1 > tmpmo2) {
00361                                 Tstress = tmpmo1;
00362                                 Ttangent = E1n*kn;
00363                         }
00364                         else
00365                                 Tstress = tmpmo2;
00366                 }
00367         }
00368 
00369         else {
00370                 Ttangent = (1.0-pinchY)*minmom/(TrotMin-rotch);
00371                 tmpmo1 = Cstress + E1n*kn*dStrain;
00372                 tmpmo2 = pinchY*minmom + (Tstrain-rotch)*Ttangent;
00373                 if (tmpmo1 > tmpmo2) {
00374                         Tstress = tmpmo1;
00375                         Ttangent = E1n*kn;
00376                 }
00377                 else
00378                         Tstress = tmpmo2;
00379         }
00380 }
00381 
00382 int
00383 HystereticMaterial::commitState(void)
00384 {
00385         CrotMax = TrotMax;
00386         CrotMin = TrotMin;
00387         CrotPu = TrotPu;
00388         CrotNu = TrotNu;
00389         CenergyD = TenergyD;
00390         CloadIndicator = TloadIndicator;
00391 
00392         Cstress = Tstress;
00393         Cstrain = Tstrain;
00394         return 0;
00395 }
00396 
00397 int
00398 HystereticMaterial::revertToLastCommit(void)
00399 {
00400         TrotMax = CrotMax;
00401         TrotMin = CrotMin;
00402         TrotPu = CrotPu;
00403         TrotNu = CrotNu;
00404         TenergyD = CenergyD;
00405         TloadIndicator = CloadIndicator;
00406 
00407         Tstress = Cstress;
00408         Tstrain = Cstrain;
00409 
00410         return 0;
00411 }
00412 
00413 int
00414 HystereticMaterial::revertToStart(void)
00415 {
00416         CrotMax = 0.0;
00417         CrotMin = 0.0;
00418         CrotPu = 0.0;
00419         CrotNu = 0.0;
00420         CenergyD = 0.0;
00421         CloadIndicator = 0;
00422 
00423         Cstress = 0.0;
00424         Cstrain = 0.0;
00425 
00426         Tstrain = 0;
00427         Tstress = 0;
00428         Ttangent = E1p;
00429 
00430         return 0;
00431 }
00432 
00433 UniaxialMaterial*
00434 HystereticMaterial::getCopy(void)
00435 {
00436         HystereticMaterial *theCopy = new HystereticMaterial (this->getTag(),
00437                 mom1p, rot1p, mom2p, rot2p, mom3p, rot3p,
00438                 mom1n, rot1n, mom2n, rot2n, mom3n, rot3n,
00439                 pinchX, pinchY, damfc1, damfc2, beta);
00440 
00441         theCopy->CrotMax = CrotMax;
00442         theCopy->CrotMin = CrotMin;
00443         theCopy->CrotPu = CrotPu;
00444         theCopy->CrotNu = CrotNu;
00445         theCopy->CenergyD = CenergyD;
00446         theCopy->CloadIndicator = CloadIndicator;
00447         theCopy->Cstress = Cstress;
00448         theCopy->Cstrain = Cstrain;
00449         theCopy->Ttangent = Ttangent;
00450 
00451         return theCopy;
00452 }
00453 
00454 int
00455 HystereticMaterial::sendSelf(int commitTag, Channel &theChannel)
00456 {
00457   int res = 0;
00458   
00459   static Vector data(27);
00460   
00461   data(0) = this->getTag();
00462   data(1) = mom1p;
00463   data(2) = rot1p;
00464   data(3) = mom2p;
00465   data(4) = rot2p;
00466   data(5) = mom3p;
00467   data(6) = rot3p;
00468   data(7) = mom1n;
00469   data(8) = rot1n;
00470   data(9) = mom2n;
00471   data(10) = rot2n;
00472   data(11) = mom3n;
00473   data(12) = rot3n;
00474   data(13) = pinchX;
00475   data(14) = pinchY;
00476   data(15) = damfc1;
00477   data(16) = damfc2;
00478   data(17) = beta;
00479   data(18) = CrotMax;
00480   data(19) = CrotMin;
00481   data(20) = CrotPu;
00482   data(21) = CrotNu;
00483   data(22) = CenergyD;
00484   data(23) = CloadIndicator;
00485   data(24) = Cstress;
00486   data(25) = Cstrain;
00487   data(26) = Ttangent;
00488 
00489   res = theChannel.sendVector(this->getDbTag(), commitTag, data);
00490   if (res < 0) 
00491     opserr << "HystereticMaterial::sendSelf() - failed to send data\n";
00492 
00493 
00494   return res;
00495 }
00496 
00497 int
00498 HystereticMaterial::recvSelf(int commitTag, Channel &theChannel, 
00499                         FEM_ObjectBroker &theBroker)
00500 {
00501   int res = 0;
00502   
00503   static Vector data(27);
00504   res = theChannel.recvVector(this->getDbTag(), commitTag, data);
00505   
00506   if (res < 0) {
00507       opserr << "HystereticMaterial::recvSelf() - failed to receive data\n";
00508       return res;
00509   }
00510   else {
00511     this->setTag((int)data(0));
00512     mom1p = data(1);
00513     rot1p = data(2);
00514     mom2p = data(3);
00515     rot2p = data(4);
00516     mom3p = data(5);
00517     rot3p = data(6);
00518     mom1n = data(7);
00519     rot1n = data(8);
00520     mom2n = data(9);
00521     rot2n = data(10);
00522     mom3n = data(11);
00523     rot3n = data(12);
00524     pinchX = data(13);
00525     pinchY = data(14);
00526     damfc1 = data(15);
00527     damfc2 = data(16);
00528     beta = data(17);
00529     CrotMax = data(18);
00530     CrotMin = data(19);
00531     CrotPu = data(20);
00532     CrotNu = data(21);
00533     CenergyD = data(22);
00534     CloadIndicator = int(data(23));
00535     Cstress = data(24);
00536     Cstrain = data(25);
00537     Ttangent = data(26);
00538 
00539     // set the trial values
00540     TrotMax = CrotMax;
00541     TrotMin = CrotMin;
00542     TrotPu = CrotPu;
00543     TrotNu = CrotNu;
00544     TenergyD = CenergyD;
00545     TloadIndicator = CloadIndicator;
00546     Tstress = Cstress;
00547     Tstrain = Cstrain;
00548 
00549   }
00550 
00551   return 0;
00552 }
00553     
00554 void
00555 HystereticMaterial::Print(OPS_Stream &s, int flag)
00556 {
00557         s << "Hysteretic Material, tag: " << this->getTag() << endln;
00558         s << "mom1p: " << mom1p << endln;
00559         s << "rot1p: " << rot1p << endln;
00560         s << "E1p: " << E1p << endln;
00561         s << "mom2p: " << mom2p << endln;
00562         s << "rot2p: " << rot2p << endln;
00563         s << "E2p: " << E2p << endln;
00564         s << "mom3p: " << mom3p << endln;
00565         s << "rot3p: " << rot3p << endln;
00566         s << "E3p: " << E3p << endln;
00567 
00568         s << "mom1n: " << mom1n << endln;
00569         s << "rot1n: " << rot1n << endln;
00570         s << "E1n: " << E1n << endln;
00571         s << "mom2n: " << mom2n << endln;
00572         s << "rot2n: " << rot2n << endln;
00573         s << "E2n: " << E2n << endln;
00574         s << "mom3n: " << mom3n << endln;
00575         s << "rot3n: " << rot3n << endln;
00576         s << "E3n: " << E3n << endln;
00577 
00578         s << "pinchX: " << pinchX << endln;
00579         s << "pinchY: " << pinchY << endln;
00580         s << "damfc1: " << damfc1 << endln;
00581         s << "damfc2: " << damfc2 << endln;
00582         s << "energyA: " << energyA << endln;
00583         s << "beta: " << beta << endln;
00584 }
00585 
00586 void
00587 HystereticMaterial::setEnvelope(void)
00588 {
00589         E1p = mom1p/rot1p;
00590         E2p = (mom2p-mom1p)/(rot2p-rot1p);
00591         E3p = (mom3p-mom2p)/(rot3p-rot2p);
00592 
00593         E1n = mom1n/rot1n;
00594         E2n = (mom2n-mom1n)/(rot2n-rot1n);
00595         E3n = (mom3n-mom2n)/(rot3n-rot2n);
00596 }
00597 
00598 double
00599 HystereticMaterial::posEnvlpStress(double strain)
00600 {
00601         if (strain <= 0.0)
00602                 return 0.0;
00603         else if (strain <= rot1p)
00604                 return E1p*strain;
00605         else if (strain <= rot2p)
00606                 return mom1p + E2p*(strain-rot1p);
00607         else if (strain <= rot3p || E3p > 0.0)
00608                 return mom2p + E3p*(strain-rot2p);
00609         else
00610                 return mom3p;
00611 }
00612 
00613 double
00614 HystereticMaterial::negEnvlpStress(double strain)
00615 {
00616         if (strain >= 0.0)
00617                 return 0.0;
00618         else if (strain >= rot1n)
00619                 return E1n*strain;
00620         else if (strain >= rot2n)
00621                 return mom1n + E2n*(strain-rot1n);
00622         else if (strain >= rot3n || E3n > 0.0)
00623                 return mom2n + E3n*(strain-rot2n);
00624         else
00625                 return mom3n;
00626 }
00627 
00628 double
00629 HystereticMaterial::posEnvlpTangent(double strain)
00630 {
00631         if (strain < 0.0)
00632                 return E1p*1.0e-9;
00633         else if (strain <= rot1p)
00634                 return E1p;
00635         else if (strain <= rot2p)
00636                 return E2p;
00637         else if (strain <= rot3p || E3p > 0.0)
00638                 return E3p;
00639         else
00640                 return E1p*1.0e-9;
00641 }
00642 
00643 double
00644 HystereticMaterial::negEnvlpTangent(double strain)
00645 {
00646         if (strain > 0.0)
00647                 return E1n*1.0e-9;
00648         else if (strain >= rot1n)
00649                 return E1n;
00650         else if (strain >= rot2n)
00651                 return E2n;
00652         else if (strain >= rot3n || E3n > 0.0)
00653                 return E3n;
00654         else
00655                 return E1n*1.0e-9;
00656 }
00657 
00658 double
00659 HystereticMaterial::posEnvlpRotlim(double strain)
00660 {
00661   double strainLimit = POS_INF_STRAIN;
00662 
00663   if (strain <= rot1p)
00664     return POS_INF_STRAIN;
00665   if (strain > rot1p && strain <= rot2p && E2p < 0.0)
00666     strainLimit = rot1p - mom1p/E2p;
00667   if (strain > rot2p && E3p < 0.0)
00668     strainLimit = rot2p - mom2p/E3p;
00669 
00670   if (strainLimit == POS_INF_STRAIN)
00671     return POS_INF_STRAIN;
00672   else if (posEnvlpStress(strainLimit) > 0)
00673     return POS_INF_STRAIN;
00674   else
00675     return strainLimit;
00676 }
00677 
00678 double
00679 HystereticMaterial::negEnvlpRotlim(double strain)
00680 {
00681   double strainLimit = NEG_INF_STRAIN;
00682 
00683   if (strain >= rot1n)
00684     return NEG_INF_STRAIN;
00685   if (strain < rot1n && strain >= rot2n && E2n < 0.0)
00686     strainLimit = rot1n - mom1n/E2n;
00687   if (strain < rot2n && E3n < 0.0)
00688     strainLimit = rot2n - mom2n/E3n;
00689 
00690   if (strainLimit == NEG_INF_STRAIN)
00691     return NEG_INF_STRAIN;
00692   else if (negEnvlpStress(strainLimit) < 0)
00693     return NEG_INF_STRAIN;
00694   else
00695     return strainLimit;
00696 }

Generated on Mon Oct 23 15:05:20 2006 for OpenSees by doxygen 1.5.0