LimitStateMaterial.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.2 $
00022 // $Date: 2006/09/05 22:32:05 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/limitState/LimitStateMaterial.cpp,v $
00024                                                                         
00025 // Written: KJE
00026 // Created: July 2001
00027 // Modified July 2002
00028 // Based on HystereticMaterial by MHS
00029 //
00030 // Description: This file contains the implementation of 
00031 // LimitStateMaterial.  LimitStateMaterial is
00032 // a one-dimensional hysteretic model with pinching of both
00033 // force and deformation, damage due to deformation and energy, and
00034 // degraded unloading stiffness based on maximum ductility.  Based on 
00035 // HystereticMaterial which is a modified implementation of Hyster2.f90 
00036 // by Filippou.  
00037 //
00038 // Modified July 2002 by KJE to include the use of limitCurve to 
00039 // detect failure in hysteretic material (see commitState).
00040 // Option only available for 3 point specification. Behaves 
00041 // same as HystereticMaterial if no limit curve specified.
00042 //
00043 // All code specific to LimitStateMaterial seperated by ////////////////
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         // Positive backbone parameters
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         // Negative backbone parameters
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 //              this->Print(cout);  // Commented out by Terje
00087                 
00088 //              g3ErrorHandler->fatal("%s -- input backbone is not unique (one-to-one) 3-point backbone",
00089 //              "LimitStateMaterial::LimitStateMaterial");
00090         }
00091 
00092         // Store original input parameters
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         // Set envelope slopes
00115         this->setEnvelope();
00116 
00117         // Initialize history variables
00118         this->revertToStart();
00119         this->revertToLastCommit();
00120         
00122         // not using limit curve option
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         // Positive backbone parameters
00141         if (rot1p <= 0.0)
00142                 error = true;
00143 
00144         if (rot3p <= rot1p)
00145                 error = true;
00146 
00147         // Negative backbone parameters
00148         if (rot1n >= 0.0)
00149                 error = true;
00150 
00151         if (rot3n >= rot1n)
00152                 error = true;
00153 
00154         if (error) {
00155 //              g3ErrorHandler->fatal("%s -- input backbone is not unique (one-to-one) 2-point backbone",
00156 //              "LimitStateMaterial::LimitStateMaterial");
00157         }
00158         
00159         // Store original input parameters
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         // Set envelope slopes
00188         this->setEnvelope();
00189 
00190         // Initialize history variables
00191         this->revertToStart();
00192         this->revertToLastCommit();
00193 
00194         //this->Print(cout);
00195 
00197         // not using limit curve option
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         // Positive backbone parameters
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         // Negative backbone parameters
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 //              this->Print(cout); Commented out by Terje
00241 
00242 //              g3ErrorHandler->fatal("%s -- input backbone is not unique (one-to-one) limit curve option",
00243 //              "LimitStateMaterial::LimitStateMaterial");
00244         }
00245 
00246         // Store original input parameters
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         // get copy of the limit state curve 
00272         //theCurve = curve.getCopy(); Terje Xmas
00273 
00274         if (theCurve == 0) {
00275 //              g3ErrorHandler->fatal("WARNING LimitStateMaterial - could not get copy of limitCurve");
00277         }
00278         
00279         // Set envelope slopes
00280         this->setEnvelope();
00281 
00283         // get elastic slope
00284         Eelasticp = E1p;
00285         Eelasticn = E1n;
00287 
00288         // Initialize history variables
00289         this->revertToStart();
00290         this->revertToLastCommit();
00291 
00292 //      this->Print(cout); // commented out by Terje
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         // Store original input parameters
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         // Return trail strain plus strain due to loss of axial load.
00378         // Ploss will be zero if no axial failure or not using AxialCurve.
00379         // Ploss is always positive.
00380         // E3 set to any number if not using limit curve, 
00381         // otherwise should be negative for axial curve.
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         // Return trail stress minus the loss of axial load.
00404         // Ploss will be zero if no axial failure or not using AxialCurve.
00405         // Ploss is always positive.
00406         // For axial failure Tstress is negative in compression
00407         double stress;
00408 
00409         stress = Tstress + Ploss;
00410 
00411         return stress;
00413 }
00414 
00415 double
00416 LimitStateMaterial::getTangent(void)
00417 {
00419         // If on the limit state surface use degrading slope, 
00420         // but if beyond third corner point use approx zero slope 
00421         // (axial curve only)
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                 // limit TrotMax to maximum strain from opposite direction
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                 // limit TrotMax to maximum strain from opposite direction
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         // check element state if using limit curve option
00653         // and not beyond residual capacity (CstateFlag == 4)
00654         if (curveType != 0 && CstateFlag != 4)
00655         {
00657                 // Check state of element relative to the limit state surface.
00658                 // Note that steps should be kept small to minimize error
00659                 // caused by commited state being far beyond limit state surface
00660                 int stateFlag = theCurve->checkElementState(Cstress);
00661 
00662                 // If beyond limit state surface for first time,
00663                 // get the new final slope and residual capacity 
00664                 // for this LimitState material
00665                 if (stateFlag == 1)
00666                 {
00667 //                      g3ErrorHandler->warning("LimitStateMaterial tag %d - failure detected", this->getTag());
00668 
00669                         // display warning if Cstrain = max strain experienced.
00670                         if (Cstrain != CrotMax && Cstrain != CrotMin) {
00671 //                              g3ErrorHandler->warning("WARNING LimitStateMaterial - failure occured while not at peak in displacement",
00672 //                                              "History variables may not be correct. Need to reset history variables in commitState");
00673                         }
00674 
00675                         result += getNewBackbone(stateFlag); // get backbone in current direction
00676                         
00677                         // if not an axial curve, cause failure in both directions 
00678                         if (curveType != 1) 
00679                                 result += mirrorBackbone(); 
00680 
00681 //                      this->Print(cout); // Commented out by Terje
00682                 }
00683 
00684                 // special functions for axial curve
00685                 if (curveType == 1) {
00686 
00687                         // If on surface, get axial load lost  
00688                         if (stateFlag == 1 || stateFlag == 2 || stateFlag == 4) {
00689                                 Ploss += theCurve->getUnbalanceForce();
00690                                 opserr << "Axial load loss: " << Ploss << endln;
00691                         }
00692 
00693                         // if moving off surface then get new backbone with elastic 3rd slope
00694                         if (CstateFlag == 2 || CstateFlag == 1) {
00695                                 if (stateFlag == 3) {
00696                                         result += getNewBackbone(stateFlag);
00697 //                                      this->Print(cout); // Commented out by Terje
00698                                 }
00699 
00700                         }
00701                         
00702                         // if moving onto surface then get new backbone with degrading slope
00703                         if (CstateFlag == 3) {
00704                                 if (stateFlag == 2) {
00705                                         result += getNewBackbone(stateFlag);
00706 //                                      this->Print(cout); Commented out by Terje
00707                                 }
00708                         }
00709 
00710                         // if forceSurface governed by residual capacity set new flat backbone
00711                         // do not allow backbone to be changed again.
00712                         if (stateFlag == 4) {
00713                                 result += getNewBackbone(stateFlag);
00714 //                              this->Print(cout); commented out by Terje
00715                         }
00716                 }
00717 
00718                 // commit the current state if needed outside commitState 
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         // set commited stateFlag to prior to failure
00761         CstateFlag = 0;
00762         // set axial load loss to zero
00763         Ploss = 0.0;
00765 
00766         // Do the same thin inthe limit curve (done by Terje)
00767         theCurve->revertToStart();
00768 
00769 
00770         // Store original input parameters
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         // Set envelope slopes
00803         this->setEnvelope();
00804 
00805 
00806         Eelasticp = E1p;
00807         Eelasticn = E1n;
00808 
00809 
00810         // Initialize history variables
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     // set the trial values
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         // set backbone with flat slope if at residual capacity
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                 // determine new corner points for post-failure envelope.
01135                 //
01136                 // set point of failure as second corner point
01137                 if (Cstress > 0.0) {
01138                         mom2p = Cstress;
01139                         rot2p = Cstrain;
01140                 } 
01141                 else {
01142                         mom2n = Cstress;
01143                         rot2n = Cstrain;
01144                 }
01145                 // if not yet beyond first corner point,
01146                 // set new first corner point on elastic slope,
01147                 // otherwise leave first corner point as is.
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                 // set new third corner point
01160                 if (flag == 3 && curveType == 1) { //if comming off surface
01161                         if (Cstress > 0.0) {
01162                                 mom3p = 10*mom2p;
01163                                 //rot3p = rot2p + (mom3p-mom2p)/Eelasticp;
01164                                 rot3p = rot2p + (mom3p-mom2p)/(Eelasticp*0.01);
01165                         }
01166                         else {
01167                                 mom3n = 10*mom2n;
01168                                 //rot3n = rot2n + (mom3n-mom2n)/Eelasticn;
01169                                 rot3n = rot2n + (mom3n-mom2n)/(Eelasticn*0.01);
01170                         }
01171                 }
01172                 else {                                                                  //if hitting surface
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         // Check backbone
01185         bool error = false;
01186 
01187         // Positive backbone parameters
01188         if (rot1p <= 0.0)
01189                 error = true;
01190         if (rot2p <= rot1p)
01191                 error = true;
01192         if (rot3p <= rot2p)
01193                 error = true;
01194         // Negative backbone parameters
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 //              this->Print(cout); // Commented out by Terje
01205 //              g3ErrorHandler->fatal("%s -- post-failure backbone is not unique (one-to-one)",
01206 //                      "LimitStateMaterial::getNewBackbone");
01207         }
01208 
01209         // recalculate energy for damfc2 parameter
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 &param)
01265 {
01266   return theCurve->setParameter(argv, argc, param);
01267 }

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