BoucWenMaterial.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 2001, 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 ** Reliability module developed by:                                   **
00020 **   Terje Haukaas (haukaas@ce.berkeley.edu)                          **
00021 **   Armen Der Kiureghian (adk@ce.berkeley.edu)                       **
00022 **                                                                    **
00023 ** ****************************************************************** */
00024                                                                         
00025 // $Revision: 1.2 $
00026 // $Date: 2006/09/05 22:14:06 $
00027 // $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/BoucWenMaterial.cpp,v $
00028 
00029 
00030 //
00031 // Written by Terje Haukaas (haukaas@ce.berkeley.edu) 
00032 //
00033 
00034 #include <BoucWenMaterial.h>
00035 #include <Vector.h>
00036 #include <Channel.h>
00037 #include <math.h>
00038 #include <Matrix.h>
00039 #include <Information.h>
00040 #include <Parameter.h>
00041 
00042 BoucWenMaterial::BoucWenMaterial(int tag, 
00043                                         double p_alpha,
00044                                         double p_ko,
00045                                         double p_n,
00046                                         double p_gamma,
00047                                         double p_beta,
00048                                         double p_Ao,
00049                                         double p_deltaA,
00050                                         double p_deltaNu,
00051                                         double p_deltaEta,
00052                                         double ptolerance,
00053                                         int pMaxNumIter)
00054 :UniaxialMaterial(tag,MAT_TAG_BoucWen),
00055 alpha(p_alpha), ko(p_ko), n(p_n), gamma(p_gamma), beta(p_beta), Ao(p_Ao), 
00056 deltaA(p_deltaA), deltaNu(p_deltaNu), deltaEta(p_deltaEta), tolerance(ptolerance),
00057 maxNumIter(pMaxNumIter)
00058 {
00059         parameterID = 0;
00060         SHVs = 0;
00061 
00062         // Initialize variables
00063     this->revertToStart();
00064 }
00065 
00066 
00067 BoucWenMaterial::~BoucWenMaterial()
00068 {
00069         if (SHVs != 0) 
00070                 delete SHVs;
00071 }
00072 
00073 
00074 
00075 
00076 double 
00077 BoucWenMaterial::signum(double value)
00078 {
00079         if (value > 0.0) {
00080                 return 1.0;
00081         }
00082         else {
00083                 return -1.0;
00084         }
00085 }
00086 
00087 
00088 
00089 
00090 int 
00091 BoucWenMaterial::setTrialStrain (double strain, double strainRate)
00092 {
00093         // Set trial strain and compute strain increment
00094         Tstrain = strain;
00095         double dStrain = Tstrain - Cstrain;
00096 
00097 
00098 
00099         // Initial declarations (make sure not to declare class variables here!)
00100         double TA, Tnu, Teta, Psi, Phi, f, Te_, TA_, Tnu_;
00101         double Teta_, Phi_, f_, Tznew, Tzold, sign;
00102 
00103 
00104         // Newton-Raphson scheme to solve for z_{i+1} := z1
00105         int count = 0;
00106         double startPoint = 0.01;
00107         Tz = startPoint;
00108         Tzold = startPoint;
00109         Tznew = 1.0;  
00110         while ( ( fabs(Tzold-Tznew) > tolerance ) && count<maxNumIter) {
00111 
00112                 Te = Ce + (1-alpha)*ko*dStrain*Tz;
00113                 TA = Ao - deltaA*Te;
00114                 Tnu = 1.0 + deltaNu*Te;
00115                 Teta = 1.0 + deltaEta*Te;
00116                 sign = signum(dStrain*Tz);
00117                 Psi = gamma + beta*sign;
00118                 Phi = TA - pow(fabs(Tz),n)*Psi*Tnu;
00119                 f = Tz - Cz - Phi/Teta*dStrain;
00120 
00121 
00122                 // Evaluate function derivative f' (underscore:=prime)
00123                 Te_ = (1.0-alpha)*ko*dStrain;
00124                 TA_ = -deltaA*Te_;
00125                 Tnu_ = deltaNu*Te_;
00126                 Teta_ = deltaEta*Te_;
00127                 sign = signum(Tz);
00128                 double pow1;
00129                 double pow2;
00130                 if (Tz == 0.0) {
00131                         pow1 = 0.0;
00132                         pow2 = 0.0;
00133                 }
00134                 else {
00135                         pow1 = pow(fabs(Tz),(n-1));
00136                         pow2 = pow(fabs(Tz),n);
00137                 }
00138                 Phi_ = TA_ - n*pow1*sign*Psi*Tnu - pow2*Psi*Tnu_;
00139                 f_ = 1.0 - (Phi_*Teta-Phi*Teta_)/pow(Teta,2.0)*dStrain;
00140 
00141 
00142                 // Issue warning if derivative is zero
00143                 if ( fabs(f_)<1.0e-10 ) {
00144                         opserr << "WARNING: BoucWenMaterial::setTrialStrain() -- zero derivative " << endln
00145                                 << " in Newton-Raphson scheme" << endln;
00146                 }
00147 
00148                 // Take a Newton step
00149                 Tznew = Tz - f/f_;
00150 
00151 
00152                 // Update the root (but the keep the old for convergence check)
00153                 Tzold = Tz; 
00154                 Tz = Tznew;
00155 
00156                 // Update counter
00157                 count++;
00158 
00159 
00160                 // Issue warning if we didn't converge
00161                 if (count == maxNumIter) {
00162 
00163                         opserr << "WARNING: BoucWenMaterial::setTrialStrain() -- did not" << endln
00164                                 << " find the root z_{i+1}, after " << maxNumIter << " iterations" << endln
00165                                 << " and norm: " << fabs(Tzold-Tznew) << endln;
00166                 }
00167 
00168                 // Compute stress
00169                 Tstress = alpha*ko*Tstrain + (1-alpha)*ko*Tz;
00170 
00171 
00172                 // Compute deterioration parameters
00173                 Te = Ce + (1-alpha)*ko*dStrain*Tz;
00174                 TA = Ao - deltaA*Te;
00175                 Tnu = 1.0 + deltaNu*Te;
00176                 Teta = 1.0 + deltaEta*Te;
00177 
00178 
00179                 // Compute tangent
00180                 if (Tz != 0.0) {
00181                         Psi = gamma + beta*signum(dStrain*Tz);
00182                         Phi = TA - pow(fabs(Tz),n)*Psi*Tnu;
00183                         double b1, b2, b3, b4, b5;
00184                         b1  = (1-alpha)*ko*Tz;
00185                         b2  = (1-alpha)*ko*dStrain;
00186                         b3  = dStrain/Teta;
00187                         b4  = -b3*deltaA*b1 - b3*pow(fabs(Tz),n)*Psi*deltaNu*b1 
00188                                 - Phi/(Teta*Teta)*dStrain*deltaEta*b1 + Phi/Teta;
00189                         b5  = 1.0 + b3*deltaA*b2 + b3*n*pow(fabs(Tz),(n-1))*signum(Tz)*Psi*Tnu
00190                                 + b3*pow(fabs(Tz),n)*Psi*deltaNu*b2
00191                                 + Phi/(Teta*Teta)*dStrain*deltaEta*b2;
00192                         double DzDeps = b4/b5;
00193                         Ttangent = alpha*ko + (1-alpha)*ko*DzDeps;
00194                 }
00195                 else {
00196                         Ttangent = alpha*ko + (1-alpha)*ko;
00197                 }
00198 
00199         }
00200 
00201     return 0;
00202 }
00203 
00204 double 
00205 BoucWenMaterial::getStress(void)
00206 {
00207     return Tstress;
00208 }
00209 
00210 double 
00211 BoucWenMaterial::getInitialTangent(void)
00212 {
00213     return ( alpha*ko + (1-alpha)*ko*Ao );
00214 }
00215 
00216 double 
00217 BoucWenMaterial::getTangent(void)
00218 {
00219     return Ttangent;
00220 }
00221 
00222 double 
00223 BoucWenMaterial::getStrain(void)
00224 {
00225     return Tstrain;
00226 }
00227 
00228 int 
00229 BoucWenMaterial::commitState(void)
00230 {
00231     // Commit trial history variables
00232     Cstrain = Tstrain;
00233         Cz = Tz;
00234         Ce = Te;
00235 
00236     return 0;
00237 }
00238 
00239 int 
00240 BoucWenMaterial::revertToLastCommit(void)
00241 {
00242         // Nothing to do here
00243     return 0;
00244 }
00245 
00246 int 
00247 BoucWenMaterial::revertToStart(void)
00248 {
00249     Tstrain = 0.0;
00250         Cstrain = 0.0;
00251         Tz = 0.0;
00252         Cz = 0.0;
00253         Te = 0.0;
00254         Ce = 0.0;
00255         Tstress = 0.0;
00256         Ttangent = alpha*ko + (1-alpha)*ko*Ao;
00257 
00258         if (SHVs != 0) 
00259                 SHVs->Zero();
00260 
00261     return 0;
00262 }
00263 
00264 UniaxialMaterial *
00265 BoucWenMaterial::getCopy(void)
00266 {
00267     BoucWenMaterial *theCopy =
00268         new BoucWenMaterial(this->getTag(), alpha, ko, n, gamma,
00269                                                 beta, Ao, deltaA, deltaNu, deltaEta,tolerance,maxNumIter);
00270         
00271     theCopy->Tstrain = Tstrain;
00272     theCopy->Cstrain = Cstrain;
00273     theCopy->Tz = Tz;
00274     theCopy->Cz = Cz;
00275     theCopy->Te = Te;
00276     theCopy->Ce = Ce;
00277     theCopy->Tstress = Tstress;
00278     theCopy->Ttangent = Ttangent;
00279 
00280     return theCopy;
00281 }
00282 
00283 int 
00284 BoucWenMaterial::sendSelf(int cTag, Channel &theChannel)
00285 {
00286   return 0;
00287 }
00288 
00289 int 
00290 BoucWenMaterial::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00291 {
00292   return 0;
00293 }
00294 
00295 void 
00296 BoucWenMaterial::Print(OPS_Stream &s, int flag)
00297 {
00298     s << "BoucWenMaterial, tag: " << this->getTag() << endln;
00299     s << "  alpha: " << alpha << endln;
00300     s << "  ko: " << ko << endln;
00301     s << "  n: " << n << endln;
00302     s << "  gamma: " << gamma << endln;
00303     s << "  beta: " << beta << endln;
00304     s << "  Ao: " << Ao << endln;
00305     s << "  deltaA: " << deltaA << endln;
00306     s << "  deltaNu: " << deltaNu << endln;
00307     s << "  deltaEta: " << deltaEta << endln;
00308 }
00309 
00310 
00311 int
00312 BoucWenMaterial::setParameter(const char **argv, int argc, Parameter &param)
00313 {
00314         if (argc < 1)
00315                 return 0;
00316 
00317         if (strcmp(argv[0],"alpha") == 0)
00318           return param.addObject(1, this);
00319 
00320         if (strcmp(argv[0],"ko") == 0)
00321           return param.addObject(2, this);
00322 
00323         if (strcmp(argv[0],"n") == 0)
00324           return param.addObject(3, this);
00325 
00326         if (strcmp(argv[0],"gamma") == 0)
00327           return param.addObject(4, this);
00328 
00329         if (strcmp(argv[0],"beta") == 0)
00330           return param.addObject(5, this);
00331 
00332         if (strcmp(argv[0],"Ao") == 0)
00333           return param.addObject(6, this);
00334 
00335         if (strcmp(argv[0],"deltaA") == 0)
00336           return param.addObject(7, this);
00337 
00338         if (strcmp(argv[0],"deltaNu") == 0)
00339           return param.addObject(8, this);
00340 
00341         if (strcmp(argv[0],"deltaEta") == 0)
00342           return param.addObject(9, this);
00343 
00344         else
00345                 opserr << "WARNING: Could not set parameter in BoucWenMaterial. " << endln;
00346                 
00347         return -1;
00348 }
00349 
00350 int
00351 BoucWenMaterial::updateParameter(int parameterID, Information &info)
00352 {
00353         switch (parameterID) {
00354         case 1:
00355                 this->alpha = info.theDouble;
00356                 return 0;
00357         case 2:
00358                 this->ko = info.theDouble;
00359                 return 0;
00360         case 3:
00361                 this->n = info.theDouble;
00362                 return 0;
00363         case 4:
00364                 this->gamma = info.theDouble;
00365                 return 0;
00366         case 5:
00367                 this->beta = info.theDouble;
00368                 return 0;
00369         case 6:
00370                 this->Ao = info.theDouble;
00371                 return 0;
00372         case 7:
00373                 this->deltaA = info.theDouble;
00374                 return 0;
00375         case 8:
00376                 this->deltaNu = info.theDouble;
00377                 return 0;
00378         case 9:
00379                 this->deltaEta = info.theDouble;
00380                 return 0;
00381         default:
00382                 return -1;
00383         }
00384 }
00385 
00386 
00387 
00388 int
00389 BoucWenMaterial::activateParameter(int passedParameterID)
00390 {
00391         parameterID = passedParameterID;
00392 
00393         return 0;
00394 }
00395 
00396 
00397 
00398 
00399 double
00400 BoucWenMaterial::getStressSensitivity(int gradNumber, bool conditional)
00401 {
00402 
00403         // Declare output variable
00404         double sensitivity = 0.0;
00405 
00406 
00407         // Issue warning if response is zero (then an error will occur)
00408         if (Tz == 0.0)  {
00409                 opserr << "ERROR: BoucWenMaterial::getStressSensitivity() is called " << endln
00410                         << " is called with zero hysteretic deformation Tz." << endln;
00411         }
00412 
00413         // First set values depending on what is random
00414         double Dalpha = 0.0;
00415         double Dko = 0.0;
00416         double Dn = 0.0;
00417         double Dgamma = 0.0;
00418         double Dbeta = 0.0;
00419         double DAo = 0.0;
00420         double DdeltaA = 0.0;
00421         double DdeltaNu = 0.0;
00422         double DdeltaEta = 0.0;
00423 
00424         if (parameterID == 0) { }
00425         else if (parameterID == 1) {Dalpha=1.0;}
00426         else if (parameterID == 2) {Dko=1.0;}
00427         else if (parameterID == 3) {Dn=1.0;}
00428         else if (parameterID == 4) {Dgamma=1.0;}
00429         else if (parameterID == 5) {Dbeta=1.0;}
00430         else if (parameterID == 6) {DAo=1.0;}
00431         else if (parameterID == 7) {DdeltaA=1.0;}
00432         else if (parameterID == 8) {DdeltaNu=1.0;}
00433         else if (parameterID == 9) {DdeltaEta=1.0;}
00434 
00435 
00436         // Pick up sensitivity history variables for this gradient number
00437         double DCz = 0.0;
00438         double DCe = 0.0;
00439         double DCstrain = 0.0;
00440         if (SHVs != 0) {
00441                 DCz              = (*SHVs)(0,(gradNumber-1));
00442                 DCe              = (*SHVs)(1,(gradNumber-1));
00443                 DCstrain = (*SHVs)(2,(gradNumber-1));
00444         }
00445 
00446         
00447         // Compute sensitivity of z_{i+1} 
00448         // (use same equations as for the unconditional 
00449         // sensitivities, just set DTstrain=0.0)
00450         double c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11;
00451         double DTstrain = 0.0; 
00452         double dStrain = Tstrain-Cstrain;
00453         double TA, Tnu, Teta, DTz, Psi, Phi, DPsi;
00454 
00455         c1  = DCe 
00456                 - Dalpha*ko*dStrain*Tz
00457                 + (1-alpha)*Dko*dStrain*Tz
00458                 + (1-alpha)*ko*(DTstrain-DCstrain)*Tz;
00459         c2  = (1-alpha)*ko*dStrain;
00460         c3  = DAo - DdeltaA*Te - deltaA*c1;
00461         c4  = -deltaA*c2;
00462         c5  = DdeltaNu*Te + deltaNu*c1;
00463         c6  = deltaNu*c2;
00464         c7  = DdeltaEta*Te + deltaEta*c1;
00465         c8  = deltaEta*c2;
00466         TA = Ao - deltaA*Te;
00467         Tnu = 1.0 + deltaNu*Te;
00468         Teta = 1.0 + deltaEta*Te;
00469         Psi = gamma + beta*signum(dStrain*Tz);
00470         DPsi= Dgamma + Dbeta*signum(dStrain*Tz);
00471         Phi = TA - pow(fabs(Tz),n)*Psi*Tnu;
00472         c9  = dStrain/Teta;
00473         c10 = DCz + c9*c3 - c9*pow(fabs(Tz),n)*Dn*log(fabs(Tz))*Psi*Tnu
00474                 - c9*pow(fabs(Tz),n)*DPsi*Tnu - c9*pow(fabs(Tz),n)*Psi*c5
00475                 - Phi/(Teta*Teta)*c7*dStrain + Phi/Teta*(DTstrain-DCstrain);
00476         c11 = 1.0 - c9*c4 + c9*pow(fabs(Tz),n)*Psi*c6
00477                 + c9*pow(fabs(Tz),n)*n/fabs(Tz)*signum(Tz)*Psi*Tnu
00478                 + Phi/(Teta*Teta)*c8*dStrain;
00479 
00480         DTz = c10/c11;
00481 
00482         sensitivity = Dalpha*ko*Tstrain
00483                         + alpha*Dko*Tstrain
00484                                 - Dalpha*ko*Tz
00485                                 + (1-alpha)*Dko*Tz
00486                                 + (1-alpha)*ko*DTz;
00487 
00488         return sensitivity;
00489 }
00490 
00491 
00492 
00493 double
00494 BoucWenMaterial::getTangentSensitivity(int gradNumber)
00495 {
00496         return 0.0;
00497 }
00498 
00499 double
00500 BoucWenMaterial::getDampTangentSensitivity(int gradNumber)
00501 {
00502         return 0.0;
00503 }
00504 
00505 double
00506 BoucWenMaterial::getStrainSensitivity(int gradNumber)
00507 {
00508         return 0.0;
00509 }
00510 
00511 double
00512 BoucWenMaterial::getRhoSensitivity(int gradNumber)
00513 {
00514         return 0.0;
00515 }
00516 
00517 
00518 int
00519 BoucWenMaterial::commitSensitivity(double TstrainSensitivity, int gradNumber, int numGrads)
00520 {
00521         if (SHVs == 0) {
00522                 SHVs = new Matrix(3,numGrads);
00523         }
00524 
00525         // First set values depending on what is random
00526         double Dalpha = 0.0;
00527         double Dko = 0.0;
00528         double Dn = 0.0;
00529         double Dgamma = 0.0;
00530         double Dbeta = 0.0;
00531         double DAo = 0.0;
00532         double DdeltaA = 0.0;
00533         double DdeltaNu = 0.0;
00534         double DdeltaEta = 0.0;
00535 
00536         if (parameterID == 1) {Dalpha=1.0;}
00537         else if (parameterID == 2) {Dko=1.0;}
00538         else if (parameterID == 3) {Dn=1.0;}
00539         else if (parameterID == 4) {Dgamma=1.0;}
00540         else if (parameterID == 5) {Dbeta=1.0;}
00541         else if (parameterID == 6) {DAo=1.0;}
00542         else if (parameterID == 7) {DdeltaA=1.0;}
00543         else if (parameterID == 8) {DdeltaNu=1.0;}
00544         else if (parameterID == 9) {DdeltaEta=1.0;}
00545 
00546 
00547         // Pick up sensitivity history variables for this gradient number
00548         double DCz = 0.0;
00549         double DCe = 0.0;
00550         double DCstrain = 0.0;
00551         if (SHVs != 0) {
00552                 DCz              = (*SHVs)(0,(gradNumber-1));
00553                 DCe              = (*SHVs)(1,(gradNumber-1));
00554                 DCstrain = (*SHVs)(2,(gradNumber-1));
00555         }
00556 
00557         
00558         // Compute sensitivity of z_{i+1} 
00559         // (use same equations as for the unconditional 
00560         // sensitivities, just set DTstrain=0.0)
00561         double c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11;
00562         double DTstrain = TstrainSensitivity; 
00563         double dStrain = Tstrain-Cstrain;
00564         double TA, Tnu, Teta, DTz, Psi, Phi, DPsi, DTe;
00565 
00566         c1  = DCe 
00567                 - Dalpha*ko*dStrain*Tz
00568                 + (1-alpha)*Dko*dStrain*Tz
00569                 + (1-alpha)*ko*(DTstrain-DCstrain)*Tz;
00570         c2  = (1-alpha)*ko*dStrain;
00571         c3  = DAo - DdeltaA*Te - deltaA*c1;
00572         c4  = -deltaA*c2;
00573         c5  = DdeltaNu*Te + deltaNu*c1;
00574         c6  = deltaNu*c2;
00575         c7  = DdeltaEta*Te + deltaEta*c1;
00576         c8  = deltaEta*c2;
00577         TA = Ao - deltaA*Te;
00578         Tnu = 1.0 + deltaNu*Te;
00579         Teta = 1.0 + deltaEta*Te;
00580         Psi = gamma + beta*signum(dStrain*Tz);
00581         DPsi= Dgamma + Dbeta*signum(dStrain*Tz);
00582         Phi = TA - pow(fabs(Tz),n)*Psi*Tnu;
00583         c9  = dStrain/Teta;
00584         c10 = DCz + c9*c3 - c9*pow(fabs(Tz),n)*Dn*log(fabs(Tz))*Psi*Tnu
00585                 - c9*pow(fabs(Tz),n)*DPsi*Tnu - c9*pow(fabs(Tz),n)*Psi*c5
00586                 - Phi/(Teta*Teta)*c7*dStrain + Phi/Teta*(DTstrain-DCstrain);
00587         c11 = 1.0 - c9*c4 + c9*pow(fabs(Tz),n)*Psi*c6
00588                 + c9*pow(fabs(Tz),n)*n/fabs(Tz)*signum(Tz)*Psi*Tnu
00589                 + Phi/(Teta*Teta)*c8*dStrain;
00590 
00591         DTz = c10/c11;
00592 
00593         DTe = DCe - Dalpha*ko*dStrain*Tz
00594                 + (1-alpha)*Dko*dStrain*Tz
00595                 + (1-alpha)*ko*(DTstrain-DCstrain)*Tz
00596                 + (1-alpha)*ko*dStrain*DTz;
00597 
00598 
00599         // Save sensitivity history variables
00600         (*SHVs)(0,(gradNumber-1)) = DTz;
00601         (*SHVs)(1,(gradNumber-1)) = DTe;
00602         (*SHVs)(2,(gradNumber-1)) = DTstrain;
00603 
00604         return 0;
00605 }
00606 
00607 

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