HystereticEnergy.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.1 $
00022 // $Date: 2004/09/01 03:54:28 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/damage/HystereticEnergy.cpp,v $
00024 
00025 // Written: Arash Altoontash, Gregory Deierlein 
00026 // Created: 06/03
00027 // Revision: AA
00028 //
00029 // Description: This file contains the class implementation for HystereticEnergy 
00030 // damage model. HystereticEnergy damage model calculates the damage index based on
00031 // last half cycle energy and the cumulative energy. If an unloading stiffness is
00032 // introduced, the calculation would be based on plastic energy
00033 //
00034 
00035 #include <HystereticEnergy.h>
00036 #include <DamageResponse.h>
00037 
00038 
00039 HystereticEnergy::HystereticEnergy (int tag, double Etot , double Cpow)
00040 :DamageModel(tag,DMG_TAG_HystereticEnergy),
00041 Etotal( Etot ) , Cpower( Cpow )
00042 {
00043   if ( Etot <= 0 || Cpow <= 0 )
00044     opserr << "DamageModel::DamageModel : Incorrect arguments for the damage model";
00045   
00046   this->revertToStart();
00047 }
00048 
00049 HystereticEnergy::HystereticEnergy()
00050 :DamageModel(0,DMG_TAG_HystereticEnergy)
00051 {
00052         // Does nothing
00053 }
00054 
00055 
00056 HystereticEnergy::~HystereticEnergy()
00057 {
00058   // Does nothing
00059 }
00060 
00061 
00062 int
00063 HystereticEnergy::setTrial ( Vector trialVector )
00064 {       
00065   double TDisp, TForce, TKunload, TEnrgTot, TEnrgc, TExcurDmg, TCyclicDmg;
00066   double CDisp, CForce, CKunload, CEnrgTot, CEnrgc, CExcurDmg, CCyclicDmg;
00067   
00068   // retrieve history data
00069   CDisp         = CommitInfo[0];
00070   CForce                = CommitInfo[1];
00071   CKunload      = CommitInfo[2];
00072   CEnrgTot      = CommitInfo[3];
00073   CEnrgc                = CommitInfo[4];
00074   CExcurDmg     = CommitInfo[5];
00075   CCyclicDmg    = CommitInfo[6];
00076   
00077   if ( trialVector.Size() < 3 ) {
00078     opserr << "WARNING: HystereticEnergy::setTrial Wrong vector size for trial data" << endln;
00079     return -1;
00080   }
00081   
00082   TDisp         = trialVector[0];
00083   TForce                = trialVector[1];
00084   TKunload      = trialVector[2];
00085   
00086   if ( TKunload < 0.0 ) {
00087     opserr << "WARNING: HystereticEnergy::setTrial negative unloading stiffness specified" << endln;
00088     return -1;
00089   }
00090   
00091   if ( TForce == 0.0 )
00092     {
00093       // submitt the cyclic damage
00094       TCyclicDmg = CCyclicDmg + CExcurDmg - CExcurDmg * CCyclicDmg;
00095       // a new excursion just started
00096       TEnrgc = 0.0;
00097       TEnrgTot = CEnrgTot;
00098     } 
00099   else 
00100     if ( CForce * TForce < 0.0 )
00101       {
00102         double ZeroForceDisp;
00103         if ( fabs( CForce + TForce ) < 1.0e-6 )
00104           {
00105             ZeroForceDisp = 0.5 * ( TDisp + CDisp );
00106           }
00107         else
00108           {
00109             ZeroForceDisp = ( CForce * TDisp + TForce * CDisp ) / (CForce + TForce );
00110           }
00111         
00112         // calculate the energies to the end of last cycle
00113         TEnrgc = CEnrgc + 0.5 * CForce * ( ZeroForceDisp - CDisp );
00114         TEnrgTot = CEnrgTot + 0.5 * CForce * ( ZeroForceDisp - CDisp );
00115         TExcurDmg = pow( TEnrgc / ( Etotal - TEnrgTot) , Cpower );
00116         TCyclicDmg = CCyclicDmg + TExcurDmg - TExcurDmg * CCyclicDmg;
00117         
00118         // then add the new cycle
00119         TEnrgc = 0.5 * TForce * ( TDisp - ZeroForceDisp );
00120         TEnrgTot = CEnrgTot + 0.5 * TForce * ( TDisp - ZeroForceDisp );
00121         
00122       } else {
00123         TEnrgc = CEnrgc + 0.5 * ( TForce + CForce ) * ( TDisp - CDisp );
00124         TEnrgTot = CEnrgTot + 0.5 * ( TForce + CForce ) * ( TDisp - CDisp );
00125         TCyclicDmg = CCyclicDmg;
00126       }
00127   
00128   double RSE = 0.0 ;
00129   if ( TKunload != 0.0 )
00130     {
00131       // Calculate and deduct the elastic energy from the total energy
00132       RSE =  0.5 * TForce * TForce / TKunload;  
00133       if ( (TEnrgc - RSE) < 0.0 ) RSE = 0.0;
00134       if ( (TEnrgTot -RSE) < 0.0 ) RSE = 0.0;
00135     }
00136   
00137   TExcurDmg = pow( (TEnrgc -RSE) / ( (Etotal -RSE) - (TEnrgTot -RSE) ) , Cpower );
00138   
00139   
00140   TrialInfo[0] = TDisp;
00141   TrialInfo[1] = TForce;
00142   TrialInfo[2] = TKunload;
00143   TrialInfo[3] = TEnrgTot;
00144   TrialInfo[4] = TEnrgc;
00145   TrialInfo[5] = TExcurDmg;
00146   TrialInfo[6] = TCyclicDmg;
00147   return 0;
00148 }
00149 
00150 
00151 int
00152 HystereticEnergy::setTrial ()
00153 {
00154   opserr << "WARNING: HystereticEnergy::setTrial Wrong Method called" << endln;
00155   opserr << "HystereticEnergy Model uses vector based setTrial method" << endln;
00156   return -1;
00157 }
00158 
00159 
00160 double
00161 HystereticEnergy::getDamage (void)
00162 {
00163   TrialInfo[7] =  CommitInfo[6] + TrialInfo[5] - TrialInfo[5] * CommitInfo[6];
00164   if ( TrialInfo[7] < CommitInfo[7] ) TrialInfo[7] = CommitInfo[7];
00165   return TrialInfo[7];
00166 }
00167 
00168 
00169 double HystereticEnergy::getPosDamage (void)
00170 {
00171   return this->getDamage();
00172 }
00173 
00174 
00175 double HystereticEnergy::getNegDamage (void)
00176 {
00177         return this->getDamage();
00178 }
00179 
00180 
00181 int
00182 HystereticEnergy::commitState (void)
00183 {
00184         for ( int i=0 ; i<8 ; i++ )
00185         {
00186                 LastCommitInfo[i] = CommitInfo[i];
00187                 CommitInfo[i] = TrialInfo[i];
00188         }
00189 
00190         return 0;
00191 }
00192 
00193 
00194 int
00195 HystereticEnergy::revertToLastCommit (void)
00196 {
00197         for ( int i=0 ; i<8 ; i++ )
00198         {
00199                 CommitInfo[i] = LastCommitInfo[i];
00200         }
00201 
00202         return 0;
00203 }
00204 
00205 
00206 int
00207 HystereticEnergy::revertToStart (void)
00208 {
00209         for ( int i = 0 ; i< 8 ; i++ ){
00210                 TrialInfo[i] = 0.0;
00211                 CommitInfo[i] = 0.0;
00212                 LastCommitInfo[i] = 0.0;
00213         }
00214 
00215         return 0;
00216 }
00217 
00218 
00219 DamageModel*
00220 HystereticEnergy::getCopy (void)
00221 {
00222         HystereticEnergy *theCopy = new HystereticEnergy(this->getTag(), Etotal , Cpower);
00223  
00224         for ( int i=0 ; i<8 ; i++ )
00225         {
00226                 theCopy->TrialInfo[i] = TrialInfo[i];
00227                 theCopy->CommitInfo[i] = CommitInfo[i];
00228                 theCopy->LastCommitInfo[i] = LastCommitInfo[i];
00229         }
00230 
00231         return theCopy;
00232 }
00233 
00234 
00235 int
00236 HystereticEnergy::setVariable(const char *argv)
00237 {
00238         return -1;
00239 }
00240 
00241 
00242 int
00243 HystereticEnergy::getVariable(int variableID, double &info)
00244 {
00245         return -1;
00246 }
00247 
00248 
00249 int
00250 HystereticEnergy::setParameter(char **argv, int argc, Information &eleInformation)
00251 {
00252     return -1;
00253 }
00254 
00255 
00256 int
00257 HystereticEnergy::updateParameter(int responseID, Information &eleInformation)
00258 {
00259     return -1;
00260 }
00261 
00262 
00263 Response*
00264 HystereticEnergy::setResponse(char **argv, int argc, Information &info)
00265 {
00266 //
00267 // we compare argv[0] for known response types for the Truss
00268 //
00269 
00270         if ( strcmp(argv[0],"damage") == 0 || strcmp(argv[0],"damageindex") == 0 )
00271     return new DamageResponse( this , 1 , 0.0 );
00272 
00273         else if (strcmp(argv[0],"trial") == 0 || strcmp(argv[0],"trialinfo") == 0 )
00274     return new DamageResponse( this , 2 , Vector(7) );
00275 
00276         else 
00277                 return 0;
00278 
00279 }
00280 
00281 
00282 int 
00283 HystereticEnergy::getResponse(int responseID, Information &info)
00284 {
00285         switch (responseID) {
00286         case -1:
00287                 return -1;
00288         
00289         case 1:
00290                 return info.setDouble( this->getDamage() );
00291 
00292         case 2:
00293                 if(info.theVector!=0)
00294                 {
00295                         for (int i = 0 ; i < 8 ; i++ ) (*(info.theVector))(i) = TrialInfo[i];
00296                 }
00297                 return 0;
00298 
00299         default:
00300                 return -1;
00301         }
00302 }
00303 
00304 
00305 int
00306 HystereticEnergy::sendSelf(int commitTag, Channel &theChannel)
00307 {
00308         return 0;
00309 }
00310 
00311 
00312 int
00313 HystereticEnergy::recvSelf(int commitTag, Channel &theChannel,
00314                                                                 FEM_ObjectBroker &theBroker)
00315 {
00316         return 0;
00317 }
00318 
00319 
00320 void
00321 HystereticEnergy::Print(OPS_Stream &s, int flag )
00322 {
00323     s << "HystereticEnergy tag: " << this->getTag() << endln;
00324     s << "  Etotal: " << Etotal << " Cpower: " << Cpower << endln;
00325 }
00326 
00327 
00328 
00329 int HystereticEnergy::setInputResponse ( Element *elem , const char **argv , int argc, int ndof )
00330 {
00331         return -1;
00332 }

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