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 #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
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
00094 Tstrain = strain;
00095 double dStrain = Tstrain - Cstrain;
00096
00097
00098
00099
00100 double TA, Tnu, Teta, Psi, Phi, f, Te_, TA_, Tnu_;
00101 double Teta_, Phi_, f_, Tznew, Tzold, sign;
00102
00103
00104
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
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
00143 if ( fabs(f_)<1.0e-10 ) {
00144 opserr << "WARNING: BoucWenMaterial::setTrialStrain() -- zero derivative " << endln
00145 << " in Newton-Raphson scheme" << endln;
00146 }
00147
00148
00149 Tznew = Tz - f/f_;
00150
00151
00152
00153 Tzold = Tz;
00154 Tz = Tznew;
00155
00156
00157 count++;
00158
00159
00160
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
00169 Tstress = alpha*ko*Tstrain + (1-alpha)*ko*Tz;
00170
00171
00172
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
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
00232 Cstrain = Tstrain;
00233 Cz = Tz;
00234 Ce = Te;
00235
00236 return 0;
00237 }
00238
00239 int
00240 BoucWenMaterial::revertToLastCommit(void)
00241 {
00242
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 ¶m)
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
00404 double sensitivity = 0.0;
00405
00406
00407
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
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
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
00448
00449
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
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
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
00559
00560
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
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