00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #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
00053 }
00054
00055
00056 HystereticEnergy::~HystereticEnergy()
00057 {
00058
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
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
00094 TCyclicDmg = CCyclicDmg + CExcurDmg - CExcurDmg * CCyclicDmg;
00095
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
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
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
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
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 }