Steel01.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.16 $
00022 // $Date: 2006/09/05 22:27:12 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/Steel01.cpp,v $
00024                                                                         
00025 // Written: MHS 
00026 // Created: 06/99
00027 // Revision: A
00028 //
00029 // Description: This file contains the class implementation for 
00030 // Steel01. 
00031 //
00032 // What: "@(#) Steel01.C, revA"
00033 
00034 
00035 #include <Steel01.h>
00036 #include <Vector.h>
00037 #include <Matrix.h>
00038 #include <Channel.h>
00039 #include <Information.h>
00040 #include <Parameter.h>
00041 
00042 #include <math.h>
00043 #include <float.h>
00044 
00045 Steel01::Steel01
00046 (int tag, double FY, double E, double B,
00047  double A1, double A2, double A3, double A4):
00048    UniaxialMaterial(tag,MAT_TAG_Steel01),
00049    fy(FY), E0(E), b(B), a1(A1), a2(A2), a3(A3), a4(A4)
00050 {
00051    // Sets all history and state variables to initial values
00052    // History variables
00053    CminStrain = 0.0;
00054    CmaxStrain = 0.0;
00055    CshiftP = 1.0;
00056    CshiftN = 1.0;
00057    Cloading = 0;
00058 
00059    TminStrain = 0.0;
00060    TmaxStrain = 0.0;
00061    TshiftP = 1.0;
00062    TshiftN = 1.0;
00063    Tloading = 0;
00064 
00065    // State variables
00066    Cstrain = 0.0;
00067    Cstress = 0.0;
00068    Ctangent = E0;
00069 
00070    Tstrain = 0.0;
00071    Tstress = 0.0;
00072    Ttangent = E0;
00073 
00074 // AddingSensitivity:BEGIN /////////////////////////////////////
00075         parameterID = 0;
00076         SHVs = 0;
00077 // AddingSensitivity:END //////////////////////////////////////
00078 }
00079 
00080 Steel01::Steel01():UniaxialMaterial(0,MAT_TAG_Steel01),
00081  fy(0.0), E0(0.0), b(0.0), a1(0.0), a2(0.0), a3(0.0), a4(0.0)
00082 {
00083 
00084 // AddingSensitivity:BEGIN /////////////////////////////////////
00085         parameterID = 0;
00086         SHVs = 0;
00087 // AddingSensitivity:END //////////////////////////////////////
00088 
00089 }
00090 
00091 Steel01::~Steel01 ()
00092 {
00093 // AddingSensitivity:BEGIN /////////////////////////////////////
00094         if (SHVs != 0) 
00095                 delete SHVs;
00096 // AddingSensitivity:END //////////////////////////////////////
00097 }
00098 
00099 int Steel01::setTrialStrain (double strain, double strainRate)
00100 {
00101    // Reset history variables to last converged state
00102    TminStrain = CminStrain;
00103    TmaxStrain = CmaxStrain;
00104    TshiftP = CshiftP;
00105    TshiftN = CshiftN;
00106    Tloading = Cloading;
00107    Tstrain = Cstrain;
00108    Tstress = Cstress;
00109    Ttangent = Ctangent;
00110 
00111    // Determine change in strain from last converged state
00112    double dStrain = strain - Cstrain;
00113 
00114    if (fabs(dStrain) > DBL_EPSILON) {
00115      // Set trial strain
00116      Tstrain = strain;
00117 
00118      // Calculate the trial state given the trial strain
00119      determineTrialState (dStrain);
00120 
00121    }
00122 
00123    return 0;
00124 }
00125 
00126 int Steel01::setTrial (double strain, double &stress, double &tangent, double strainRate)
00127 {
00128    // Reset history variables to last converged state
00129    TminStrain = CminStrain;
00130    TmaxStrain = CmaxStrain;
00131    TshiftP = CshiftP;
00132    TshiftN = CshiftN;
00133    Tloading = Cloading;
00134    Tstrain = Cstrain;
00135    Tstress = Cstress;
00136    Ttangent = Ctangent;
00137 
00138    // Determine change in strain from last converged state
00139    double dStrain = strain - Cstrain;
00140 
00141    if (fabs(dStrain) > DBL_EPSILON) {
00142      // Set trial strain
00143      Tstrain = strain;
00144 
00145      // Calculate the trial state given the trial strain
00146      determineTrialState (dStrain);
00147 
00148    }
00149 
00150    stress = Tstress;
00151    tangent = Ttangent;
00152 
00153    return 0;
00154 }
00155 
00156 void Steel01::determineTrialState (double dStrain)
00157 {
00158       double fyOneMinusB = fy * (1.0 - b);
00159 
00160       double Esh = b*E0;
00161       double epsy = fy/E0;
00162       
00163       double c1 = Esh*Tstrain;
00164       
00165       double c2 = TshiftN*fyOneMinusB;
00166 
00167       double c3 = TshiftP*fyOneMinusB;
00168 
00169       double c = Cstress + E0*dStrain;
00170 
00171       /**********************************************************
00172          removal of the following lines due to problems with
00173          optimization may be required (e.g. on gnucc compiler
00174          with optimization turned on & -ffloat-store option not
00175          used) .. replace them with line that follows but which 
00176          now requires 2 function calls to achieve same result !!
00177       ************************************************************/
00178 
00179       double c1c3 = c1 + c3;
00180 
00181       if (c1c3 < c)
00182         Tstress = c1c3;
00183       else
00184         Tstress = c;
00185 
00186       double c1c2 = c1-c2;
00187 
00188       if (c1c2 > Tstress)
00189         Tstress = c1c2;
00190 
00191       /* ***********************************************************
00192       and replace them with:
00193 
00194       Tstress = fmax((c1-c2), fmin((c1+c3),c));
00195       **************************************************************/
00196 
00197       if (fabs(Tstress-c) < DBL_EPSILON)
00198           Ttangent = E0;
00199       else
00200         Ttangent = Esh;
00201 
00202       //
00203       // Determine if a load reversal has occurred due to the trial strain
00204       //
00205 
00206       // Determine initial loading condition
00207       if (Tloading == 0 && dStrain != 0.0) {
00208           if (dStrain > 0.0)
00209             Tloading = 1;
00210           else
00211             Tloading = -1;
00212       }
00213 
00214       // Transition from loading to unloading, i.e. positive strain increment
00215       // to negative strain increment
00216       if (Tloading == 1 && dStrain < 0.0) {
00217           Tloading = -1;
00218           if (Cstrain > TmaxStrain)
00219             TmaxStrain = Cstrain;
00220           TshiftN = 1 + a1*pow((TmaxStrain-TminStrain)/(2.0*a2*epsy),0.8);
00221       }
00222 
00223       // Transition from unloading to loading, i.e. negative strain increment
00224       // to positive strain increment
00225       if (Tloading == -1 && dStrain > 0.0) {
00226           Tloading = 1;
00227           if (Cstrain < TminStrain)
00228             TminStrain = Cstrain;
00229           TshiftP = 1 + a3*pow((TmaxStrain-TminStrain)/(2.0*a4*epsy),0.8);
00230       }
00231 }
00232 
00233 void Steel01::detectLoadReversal (double dStrain)
00234 {
00235    // Determine initial loading condition
00236    if (Tloading == 0 && dStrain != 0.0)
00237    {
00238       if (dStrain > 0.0)
00239          Tloading = 1;
00240       else
00241          Tloading = -1;
00242    }
00243 
00244    double epsy = fy/E0;
00245 
00246    // Transition from loading to unloading, i.e. positive strain increment
00247    // to negative strain increment
00248    if (Tloading == 1 && dStrain < 0.0)
00249    {
00250       Tloading = -1;
00251       if (Cstrain > TmaxStrain)
00252          TmaxStrain = Cstrain;
00253       TshiftN = 1 + a1*pow((TmaxStrain-TminStrain)/(2.0*a2*epsy),0.8);
00254    }
00255 
00256    // Transition from unloading to loading, i.e. negative strain increment
00257    // to positive strain increment
00258    if (Tloading == -1 && dStrain > 0.0)
00259    {
00260       Tloading = 1;
00261       if (Cstrain < TminStrain)
00262          TminStrain = Cstrain;
00263       TshiftP = 1 + a3*pow((TmaxStrain-TminStrain)/(2.0*a4*epsy),0.8);
00264    }
00265 }
00266 
00267 double Steel01::getStrain ()
00268 {
00269    return Tstrain;
00270 }
00271 
00272 double Steel01::getStress ()
00273 {
00274    return Tstress;
00275 }
00276 
00277 double Steel01::getTangent ()
00278 {
00279    return Ttangent;
00280 }
00281 
00282 int Steel01::commitState ()
00283 {
00284    // History variables
00285    CminStrain = TminStrain;
00286    CmaxStrain = TmaxStrain;
00287    CshiftP = TshiftP;
00288    CshiftN = TshiftN;
00289    Cloading = Tloading;
00290 
00291    // State variables
00292    Cstrain = Tstrain;
00293    Cstress = Tstress;
00294    Ctangent = Ttangent;
00295 
00296    return 0;
00297 }
00298 
00299 int Steel01::revertToLastCommit ()
00300 {
00301    // Reset trial history variables to last committed state
00302    TminStrain = CminStrain;
00303    TmaxStrain = CmaxStrain;
00304    TshiftP = CshiftP;
00305    TshiftN = CshiftN;
00306    Tloading = Cloading;
00307 
00308    // Reset trial state variables to last committed state
00309    Tstrain = Cstrain;
00310    Tstress = Cstress;
00311    Ttangent = Ctangent;
00312 
00313    return 0;
00314 }
00315 
00316 int Steel01::revertToStart ()
00317 {
00318    // History variables
00319    CminStrain = 0.0;
00320    CmaxStrain = 0.0;
00321    CshiftP = 1.0;
00322    CshiftN = 1.0;
00323    Cloading = 0;
00324 
00325    TminStrain = 0.0;
00326    TmaxStrain = 0.0;
00327    TshiftP = 1.0;
00328    TshiftN = 1.0;
00329    Tloading = 0;
00330 
00331    // State variables
00332    Cstrain = 0.0;
00333    Cstress = 0.0;
00334    Ctangent = E0;
00335 
00336    Tstrain = 0.0;
00337    Tstress = 0.0;
00338    Ttangent = E0;
00339 
00340 // AddingSensitivity:BEGIN /////////////////////////////////
00341         if (SHVs != 0) 
00342                 SHVs->Zero();
00343 // AddingSensitivity:END //////////////////////////////////
00344 
00345    return 0;
00346 }
00347 
00348 UniaxialMaterial* Steel01::getCopy ()
00349 {
00350    Steel01* theCopy = new Steel01(this->getTag(), fy, E0, b,
00351                                   a1, a2, a3, a4);
00352 
00353    // Converged history variables
00354    theCopy->CminStrain = CminStrain;
00355    theCopy->CmaxStrain = CmaxStrain;
00356    theCopy->CshiftP = CshiftP;
00357    theCopy->CshiftN = CshiftN;
00358    theCopy->Cloading = Cloading;
00359 
00360    // Trial history variables
00361    theCopy->TminStrain = TminStrain;
00362    theCopy->TmaxStrain = TmaxStrain;
00363    theCopy->TshiftP = TshiftP;
00364    theCopy->TshiftN = TshiftN;
00365    theCopy->Tloading = Tloading;
00366 
00367    // Converged state variables
00368    theCopy->Cstrain = Cstrain;
00369    theCopy->Cstress = Cstress;
00370    theCopy->Ctangent = Ctangent;
00371 
00372    // Trial state variables
00373    theCopy->Tstrain = Tstrain;
00374    theCopy->Tstress = Tstress;
00375    theCopy->Ttangent = Ttangent;
00376 
00377    return theCopy;
00378 }
00379 
00380 int Steel01::sendSelf (int commitTag, Channel& theChannel)
00381 {
00382    int res = 0;
00383    static Vector data(16);
00384    data(0) = this->getTag();
00385 
00386    // Material properties
00387    data(1) = fy;
00388    data(2) = E0;
00389    data(3) = b;
00390    data(4) = a1;
00391    data(5) = a2;
00392    data(6) = a3;
00393    data(7) = a4;
00394 
00395    // History variables from last converged state
00396    data(8) = CminStrain;
00397    data(9) = CmaxStrain;
00398    data(10) = CshiftP;
00399    data(11) = CshiftN;
00400    data(12) = Cloading;
00401 
00402    // State variables from last converged state
00403    data(13) = Cstrain;
00404    data(14) = Cstress;
00405    data(15) = Ctangent;
00406 
00407    // Data is only sent after convergence, so no trial variables
00408    // need to be sent through data vector
00409 
00410    res = theChannel.sendVector(this->getDbTag(), commitTag, data);
00411    if (res < 0) 
00412       opserr << "Steel01::sendSelf() - failed to send data\n";
00413 
00414    return res;
00415 }
00416 
00417 int Steel01::recvSelf (int commitTag, Channel& theChannel,
00418                                 FEM_ObjectBroker& theBroker)
00419 {
00420    int res = 0;
00421    static Vector data(16);
00422    res = theChannel.recvVector(this->getDbTag(), commitTag, data);
00423   
00424    if (res < 0) {
00425       opserr << "Steel01::recvSelf() - failed to receive data\n";
00426       this->setTag(0);      
00427    }
00428    else {
00429       this->setTag(int(data(0)));
00430 
00431       // Material properties
00432       fy = data(1);
00433       E0 = data(2);
00434       b = data(3);
00435       a1 = data(4);
00436       a2 = data(5);
00437       a3 = data(6);
00438       a4 = data(7);
00439 
00440       // History variables from last converged state
00441       CminStrain = data(8);
00442       CmaxStrain = data(9);
00443       CshiftP = data(10);
00444       CshiftN = data(11);
00445       Cloading = int(data(12));
00446 
00447       // Copy converged history values into trial values since data is only
00448       // sent (received) after convergence
00449       TminStrain = CminStrain;
00450       TmaxStrain = CmaxStrain;
00451       TshiftP = CshiftP;
00452       TshiftN = CshiftN;
00453       Tloading = Cloading;
00454 
00455       // State variables from last converged state
00456       Cstrain = data(13);
00457       Cstress = data(14);
00458       Ctangent = data(15);      
00459 
00460       // Copy converged state values into trial values
00461       Tstrain = Cstrain;
00462       Tstress = Cstress;
00463       Ttangent = Ctangent;
00464    }
00465     
00466    return res;
00467 }
00468 
00469 void Steel01::Print (OPS_Stream& s, int flag)
00470 {
00471    s << "Steel01 tag: " << this->getTag() << endln;
00472    s << "  fy: " << fy << " ";
00473    s << "  E0: " << E0 << " ";
00474    s << "  b:  " << b << " ";
00475    s << "  a1: " << a1 << " ";
00476    s << "  a2: " << a2 << " ";
00477    s << "  a3: " << a3 << " ";
00478    s << "  a4: " << a4 << " ";
00479 }
00480 
00481 
00482 
00483 
00484 // AddingSensitivity:BEGIN ///////////////////////////////////
00485 int
00486 Steel01::setParameter(const char **argv, int argc, Parameter &param)
00487 {
00488   if (argc < 1)
00489     return 0;
00490 
00491   if (strcmp(argv[0],"sigmaY") == 0 || strcmp(argv[0],"fy") == 0)
00492     return param.addObject(1, this);
00493 
00494   if (strcmp(argv[0],"E") == 0)
00495     return param.addObject(2, this);
00496 
00497   if (strcmp(argv[0],"b") == 0)
00498     return param.addObject(3, this);
00499 
00500   if (strcmp(argv[0],"a1") == 0)
00501     return param.addObject(4, this);
00502 
00503   if (strcmp(argv[0],"a2") == 0)
00504     return param.addObject(5, this);
00505 
00506   if (strcmp(argv[0],"a3") == 0)
00507     return param.addObject(6, this);
00508 
00509   if (strcmp(argv[0],"a4") == 0)
00510     return param.addObject(7, this);
00511 
00512   else
00513     opserr << "WARNING: Could not set parameter in Steel01. " << endln;
00514   
00515   return 0;
00516 }
00517 
00518 
00519 
00520 int
00521 Steel01::updateParameter(int parameterID, Information &info)
00522 {
00523         switch (parameterID) {
00524         case -1:
00525                 return -1;
00526         case 1:
00527                 this->fy = info.theDouble;
00528                 break;
00529         case 2:
00530                 this->E0 = info.theDouble;
00531                 break;
00532         case 3:
00533                 this->b = info.theDouble;
00534                 break;
00535         case 4:
00536                 this->a1 = info.theDouble;
00537                 break;
00538         case 5:
00539                 this->a2 = info.theDouble;
00540                 break;
00541         case 6:
00542                 this->a3 = info.theDouble;
00543                 break;
00544         case 7:
00545                 this->a4 = info.theDouble;
00546                 break;
00547         default:
00548                 return -1;
00549         }
00550 
00551         Ttangent = E0;          // Initial stiffness
00552 
00553         return 0;
00554 }
00555 
00556 
00557 
00558 
00559 int
00560 Steel01::activateParameter(int passedParameterID)
00561 {
00562         parameterID = passedParameterID;
00563 
00564         return 0;
00565 }
00566 
00567 
00568 
00569 double
00570 Steel01::getStressSensitivity(int gradNumber, bool conditional)
00571 {
00572         // Initialize return value
00573         double gradient = 0.0;
00574 
00575 
00576         // Pick up sensitivity history variables
00577         double CstrainSensitivity = 0.0;
00578         double CstressSensitivity = 0.0;
00579         if (SHVs != 0) {
00580                 CstrainSensitivity = (*SHVs)(0,(gradNumber-1));
00581                 CstressSensitivity = (*SHVs)(1,(gradNumber-1));
00582         }
00583 
00584 
00585         // Assign values to parameter derivatives (depending on what's random)
00586         double fySensitivity = 0.0;
00587         double E0Sensitivity = 0.0;
00588         double bSensitivity = 0.0;
00589         if (parameterID == 1) {
00590                 fySensitivity = 1.0;
00591         }
00592         else if (parameterID == 2) {
00593                 E0Sensitivity = 1.0;
00594         }
00595         else if (parameterID == 3) {
00596                 bSensitivity = 1.0;
00597         }
00598 
00599 
00600         // Compute min and max stress
00601         double Tstress;
00602         double dStrain = Tstrain-Cstrain;
00603         double sigmaElastic = Cstress + E0*dStrain;
00604         double fyOneMinusB = fy * (1.0 - b);
00605         double Esh = b*E0;
00606         double c1 = Esh*Tstrain;
00607         double c2 = TshiftN*fyOneMinusB;
00608         double c3 = TshiftP*fyOneMinusB;
00609         double sigmaMax = c1+c3;
00610         double sigmaMin = c1-c2;
00611 
00612 
00613         // Evaluate stress sensitivity 
00614         if ( (sigmaMax < sigmaElastic) && (fabs(sigmaMax-sigmaElastic)>1e-5) ) {
00615                 Tstress = sigmaMax;
00616                 gradient = E0Sensitivity*b*Tstrain 
00617                                  + E0*bSensitivity*Tstrain
00618                                  + TshiftP*(fySensitivity*(1-b)-fy*bSensitivity);
00619         }
00620         else {
00621                 Tstress = sigmaElastic;
00622                 gradient = CstressSensitivity 
00623                              + E0Sensitivity*(Tstrain-Cstrain)
00624                                  - E0*CstrainSensitivity;
00625         }
00626         if (sigmaMin > Tstress) {
00627                 gradient = E0Sensitivity*b*Tstrain
00628                              + E0*bSensitivity*Tstrain
00629                                  - TshiftN*(fySensitivity*(1-b)-fy*bSensitivity);
00630         }
00631 
00632         return gradient;
00633 }
00634 
00635 
00636 
00637 
00638 double
00639 Steel01::getInitialTangentSensitivity(int gradNumber)
00640 {
00641         // For now, assume that this is only called for initial stiffness 
00642         if (parameterID == 2) {
00643                 return 1.0; 
00644         }
00645         else {
00646                 return 0.0;
00647         }
00648 }
00649 
00650 
00651 int
00652 Steel01::commitSensitivity(double TstrainSensitivity, int gradNumber, int numGrads)
00653 {
00654         if (SHVs == 0) {
00655                 SHVs = new Matrix(2,numGrads);
00656         }
00657 
00658 
00659         // Initialize unconditaional stress sensitivity
00660         double gradient = 0.0;
00661 
00662 
00663         // Pick up sensitivity history variables
00664         double CstrainSensitivity = 0.0;
00665         double CstressSensitivity        = 0.0;
00666         if (SHVs != 0) {
00667                 CstrainSensitivity = (*SHVs)(0,(gradNumber-1));
00668                 CstressSensitivity = (*SHVs)(1,(gradNumber-1));
00669         }
00670 
00671 
00672         // Assign values to parameter derivatives (depending on what's random)
00673         double fySensitivity = 0.0;
00674         double E0Sensitivity = 0.0;
00675         double bSensitivity = 0.0;
00676         if (parameterID == 1) {
00677                 fySensitivity = 1.0;
00678         }
00679         else if (parameterID == 2) {
00680                 E0Sensitivity = 1.0;
00681         }
00682         else if (parameterID == 3) {
00683                 bSensitivity = 1.0;
00684         }
00685 
00686 
00687         // Compute min and max stress
00688         double Tstress;
00689         double dStrain = Tstrain-Cstrain;
00690         double sigmaElastic = Cstress + E0*dStrain;
00691         double fyOneMinusB = fy * (1.0 - b);
00692         double Esh = b*E0;
00693         double c1 = Esh*Tstrain;
00694         double c2 = TshiftN*fyOneMinusB;
00695         double c3 = TshiftP*fyOneMinusB;
00696         double sigmaMax = c1+c3;
00697         double sigmaMin = c1-c2;
00698 
00699 
00700         // Evaluate stress sensitivity ('gradient')
00701         if ( (sigmaMax < sigmaElastic) && (fabs(sigmaMax-sigmaElastic)>1e-5) ) {
00702                 Tstress = sigmaMax;
00703                 gradient = E0Sensitivity*b*Tstrain 
00704                                  + E0*bSensitivity*Tstrain
00705                                  + E0*b*TstrainSensitivity
00706                                  + TshiftP*(fySensitivity*(1-b)-fy*bSensitivity);
00707         }
00708         else {
00709                 Tstress = sigmaElastic;
00710                 gradient = CstressSensitivity 
00711                              + E0Sensitivity*(Tstrain-Cstrain)
00712                                  + E0*(TstrainSensitivity-CstrainSensitivity);
00713         }
00714         if (sigmaMin > Tstress) {
00715                 gradient = E0Sensitivity*b*Tstrain
00716                              + E0*bSensitivity*Tstrain
00717                              + E0*b*TstrainSensitivity
00718                                  - TshiftN*(fySensitivity*(1-b)-fy*bSensitivity);
00719         }
00720 
00721 
00722         // Commit history variables
00723         (*SHVs)(0,(gradNumber-1)) = TstrainSensitivity;
00724         (*SHVs)(1,(gradNumber-1)) = gradient;
00725 
00726         return 0;
00727 }
00728 
00729 // AddingSensitivity:END /////////////////////////////////////////////
00730 

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