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
00036
00037
00038
00039
00040
00041
00042 #include <stdlib.h>
00043 #include <MaterialResponse.h>
00044 #include <Information.h>
00045
00046
00047 #include <FatigueMaterial.h>
00048 #include <ID.h>
00049 #include <Channel.h>
00050 #include <FEM_ObjectBroker.h>
00051
00052 #include <OPS_Globals.h>
00053 #include <OPS_Stream.h>
00054
00055 FatigueMaterial::FatigueMaterial(int tag, UniaxialMaterial &material,
00056 double dmax, double E_0, double slope_m,
00057 double epsmin, double epsmax )
00058 :UniaxialMaterial(tag,MAT_TAG_Fatigue), theMaterial(0),
00059 Cfailed(false), trialStrain(0)
00060 {
00061 DI = 0;
00062 X = 0;
00063 Y = 0;
00064 A = 0;
00065 B = 0;
00066 C = 0;
00067 D = 0;
00068 PCC = 0;
00069
00070 R1F = 0;
00071 R2F = 0;
00072 CS = 0;
00073 PS = 0;
00074 EP = 0;
00075 SF = 0;
00076
00077 DL = 0;
00078
00079
00080 SR1 = 0;
00081 NC1= 0;
00082 SR2 = 0;
00083 NC2 = 0;
00084 SR3 = 0;
00085 NC3 = 0;
00086
00087
00088 if ( dmax > 1.0 || dmax < 0.0 ) {
00089 opserr << "FatigueMaterial::FatigueMaterial " <<
00090 "- Dmax must be between 0 and 1, assuming Dmax = 1\n" ;
00091 Dmax = 1;
00092 } else
00093 Dmax = dmax;
00094
00095 E0 = E_0;
00096 m = slope_m;
00097 minStrain = epsmin;
00098 maxStrain = epsmax;
00099
00100 theMaterial = material.getCopy();
00101
00102 if (theMaterial == 0) {
00103 opserr << "FatigueMaterial::FatigueMaterial " <<
00104 " -- failed to get copy of material\n" ;
00105 exit(-1);
00106 }
00107 }
00108
00109 FatigueMaterial::FatigueMaterial()
00110 :UniaxialMaterial(0,MAT_TAG_Fatigue), theMaterial(0),
00111 Cfailed(false), trialStrain(0)
00112 {
00113 DI = 0;
00114 X = 0;
00115 Y = 0;
00116 A = 0;
00117 B = 0;
00118 C = 0;
00119 D = 0;
00120 PCC = 0;
00121
00122 R1F = 0;
00123 R2F = 0;
00124 CS = 0;
00125 PS = 0;
00126 EP = 0;
00127 SF = 0;
00128
00129 DL = 0;
00130
00131 Dmax = 0;
00132 E0 = 0;
00133 m = 0;
00134 minStrain = 0;
00135 maxStrain = 0;
00136
00137
00138 SR1 = 0;
00139 NC1 = 0;
00140 SR2 = 0;
00141 NC2 = 0;
00142 SR3 = 0;
00143 NC3 = 0;
00144
00145 }
00146
00147 FatigueMaterial::~FatigueMaterial()
00148 {
00149 if (theMaterial)
00150 delete theMaterial;
00151 }
00152
00153 static int sign(double a) {
00154 if (a < 0)
00155 return -1;
00156 else if (a == 0)
00157 return 0;
00158 else
00159 return 1;
00160 }
00161
00162 int
00163 FatigueMaterial::setTrialStrain(double strain, double strainRate)
00164 {
00165 if (Cfailed) {
00166 trialStrain = strain;
00167
00168 return theMaterial->setTrialStrain(strain, strainRate);
00169 } else {
00170 Cfailed = false;
00171 trialStrain = strain;
00172 return theMaterial->setTrialStrain(strain, strainRate);
00173 }
00174 }
00175
00176 double
00177 FatigueMaterial::getStress(void)
00178 {
00179 double modifier = 1.0;
00180 double damageloc = 1.0-Dmax+DL;
00181 if (Cfailed)
00182
00183 return theMaterial->getStress()*1.0e-8;
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 else
00201 return theMaterial -> getStress();
00202 }
00203
00204 double
00205 FatigueMaterial::getTangent(void)
00206 {
00207 double modifier = 1.0;
00208 double damageloc = 1.0-Dmax+DL;
00209 if (Cfailed)
00210
00211 return 1.0e-8*theMaterial->getInitialTangent();
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 else
00227 return theMaterial->getTangent()*modifier;
00228 }
00229
00230 double
00231 FatigueMaterial::getDampTangent(void)
00232 {
00233 if (Cfailed)
00234 return 0.0;
00235 else
00236 return theMaterial->getDampTangent();
00237 }
00238
00239
00240
00241 double
00242 FatigueMaterial::getStrain(void)
00243 {
00244 return theMaterial->getStrain();
00245 }
00246
00247 double
00248 FatigueMaterial::getStrainRate(void)
00249 {
00250 return theMaterial->getStrainRate();
00251 }
00252
00253 int
00254 FatigueMaterial::commitState(void)
00255 {
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 SR1 = 0;
00267 NC1 = 0;
00268
00269
00270
00271
00272 if (Cfailed) {
00273 return 0;
00274 }
00275
00276
00277 if (trialStrain >= maxStrain || trialStrain <= minStrain) {
00278 Cfailed = true;
00279 opserr << "FatigueMaterial: material tag " << this->getTag() << " failed from excessive strain\n";
00280 DI = Dmax;
00281 DL = Dmax;
00282 return 0;
00283 }
00284
00285
00286
00287 if (SF == 0) {
00288
00289 A = trialStrain;
00290 SF = 1 ;
00291 EP = trialStrain;
00292
00293 PCC = 0;
00294 B = 0;
00295 C = 0;
00296 D = 0;
00297
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 if ( EP == trialStrain ) {
00309 CS = PS;
00310 } else {
00311 CS = trialStrain - EP;
00312 }
00313
00314
00315
00316 if (sign(PS) != sign(CS) && sign(PS) != 0 ) {
00317
00318 if ( R1F == 0 ) {
00319
00320 B = EP;
00321 Y = fabs(B-A);
00322 R1F = 1;
00323
00324 } else {
00325
00326
00327 if (PCC == 1) {
00328
00329 D = EP;
00330 X = fabs(D-C);
00331
00332 } else {
00333
00334 C = EP;
00335 X = fabs(C-B);
00336
00337 }
00338
00339 if (X < Y) {
00340
00341 PCC = PCC + 1;
00342
00343 if (PCC == 1) {
00344 Y = fabs(C-B);
00345 } else if (PCC == 2 ) {
00346
00347 DI = DI + 1.0 / fabs(pow( (X/E0) , 1/m )) ;
00348
00349 SR1 = X;
00350 NC1 = 1.0;
00351
00352 D = 0;
00353 C = 0;
00354 Y = fabs(B-A);
00355 PCC = 0;
00356
00357 }
00358
00359 } else {
00360
00361 if (PCC == 1 ) {
00362
00363
00364 DI = DI + 1.0 / fabs(pow( (Y/E0) , 1/m ));
00365
00366 SR1 = Y;
00367 NC1 = 1.0;
00368
00369
00370 B = D;
00371 C = 0;
00372 D = 0;
00373 Y = fabs(B-A);
00374 PCC = 0;
00375
00376
00377
00378 } else {
00379
00380
00381 DI = DI + 0.5 / fabs(pow( (Y/E0), 1/m ));
00382
00383
00384
00385 SR1 = Y;
00386 NC1 = 0.5;
00387
00388
00389 A = B;
00390 B = C;
00391 C = 0;
00392 D = 0;
00393 Y = X;
00394 PCC = 0;
00395
00396
00397 }
00398
00399 }
00400
00401 }
00402
00403
00404 if (DI >= Dmax ) {
00405
00406
00407
00408 Cfailed = true;
00409 opserr << "FatigueMaterial: material tag " << this->getTag() << " failed at peak\n";
00410 DL=DI;
00411 } else {
00412 Cfailed = false;
00413 DL=DI;
00414 }
00415
00416
00417
00418 }
00419 if (Cfailed == false) {
00420
00421
00422
00423
00424 if (B == 0 && C == 0 && D == 0) {
00425
00426
00427 X = fabs(trialStrain - A);
00428
00429 if (fabs(X) < 1e-10) {
00430 DL = DI ;
00431
00432
00433 SR2 = 0.0;
00434 NC2 = 0.0;
00435 SR3 = 0.0;
00436 NC3 = 0.0;
00437 } else {
00438 DL = DI + 0.5 / fabs(pow( (X/E0), 1/m ));
00439
00440
00441 SR2 = X;
00442 NC2 = 0.5;
00443 SR3 = 0.0;
00444 NC3 = 0.0;
00445 }
00446
00447 } else if (B != 0 && C == 0 && D == 0) {
00448
00449
00450 X = fabs(trialStrain - B);
00451
00452 if (fabs(X) < 1e-10) {
00453 DL = DI;
00454
00455
00456 SR2 = 0.0;
00457 NC2 = 0.0;
00458 } else {
00459 DL = DI + 0.5 / fabs(pow( (X/E0) , 1/m ));
00460
00461
00462 SR2 = X;
00463 NC2 = 0.5;
00464 }
00465
00466 if (fabs(Y) < 1e-10) {
00467 DL = DL;
00468
00469
00470 SR3 = 0.0;
00471 NC3 = 0.0;
00472 } else {
00473 DL = DL + 0.5 / fabs(pow( (Y/E0) , 1/m ));
00474
00475
00476 SR3 = Y;
00477 NC3 = 0.5;
00478 }
00479
00480 } else if (B != 0 && C != 0 && D == 0) {
00481
00482
00483
00484
00485
00486
00487
00488
00489 if (fabs(A-trialStrain)> fabs(A-B)) {
00490
00491
00492 X = fabs(trialStrain-A);
00493
00494 if (fabs(Y) < 1e-10) {
00495 DL = DI;
00496
00497
00498 SR3 = 0.0;
00499 NC3 = 0.0;
00500 } else {
00501 DL = DI + 1.0 / fabs(pow( (Y/E0) , 1/m ));
00502
00503
00504 SR3 = Y;
00505 NC3 = 1.0;
00506 }
00507
00508 if (fabs(X) < 1e-10) {
00509 DL = DL;
00510
00511
00512 SR2 = 0.0;
00513 NC2 = 0.0;
00514 } else {
00515 DL = DL + 0.5 / fabs(pow( (X/E0) , 1/m ));
00516
00517
00518 SR2 = X;
00519 NC2 = 0.5;
00520 }
00521
00522 } else {
00523
00524
00525
00526 if (fabs(C-trialStrain) < 1e-10) {
00527 DL = DI;
00528
00529
00530 SR3 = 0.0;
00531 NC3 = 0.0;
00532 } else {
00533 DL = DI + 1.0 / fabs(pow( ( fabs(C-trialStrain)/E0 ) , 1/m ));
00534
00535
00536 SR3 = fabs(C-trialStrain);
00537 NC3 = 1.0;
00538 }
00539
00540 if (fabs(A-B) < 1e-10) {
00541 DL = DL;
00542
00543
00544 SR2 = 0.0;
00545 NC2 = 0.0;
00546 } else {
00547 DL = DL + 0.5 / fabs(pow( (fabs(A-B) /E0) , 1/m ));
00548
00549
00550 SR2 = fabs(A-B);
00551 NC2 = 0.5;
00552 }
00553 }
00554 }
00555
00556
00557 double mStress = theMaterial->getStress();
00558 if (DL > Dmax && mStress > 0.0 ) {
00559 DI = DL;
00560 Cfailed = true;
00561 opserr << "FatigueMaterial: material tag " << this->getTag() << " failed at pseudo peak\n";
00562 } else {
00563 Cfailed = false;
00564 }
00565
00566 }
00567
00568 PS = CS;
00569 EP = trialStrain;
00570
00571
00572 if (Cfailed) {
00573 return 0;
00574 }
00575 else
00576 return theMaterial->commitState();
00577
00578 }
00579
00580
00581 int
00582 FatigueMaterial::revertToLastCommit(void)
00583 {
00584
00585 if (Cfailed)
00586 return 0;
00587 else
00588 return theMaterial->revertToLastCommit();
00589 }
00590
00591
00592
00593
00594
00595 int
00596 FatigueMaterial::revertToStart(void)
00597 {
00598
00599 Cfailed = false;
00600 DI = 0;
00601 X = 0;
00602 Y = 0;
00603 A = 0;
00604 B = 0;
00605 C = 0;
00606 D = 0;
00607 PCC = 0;
00608
00609 R1F = 0;
00610 R2F = 0;
00611 CS = 0;
00612 PS = 0;
00613 EP = 0;
00614 SF = 0;
00615
00616 DL = 0;
00617
00618 Dmax = 0;
00619 E0 = 0;
00620 m = 0;
00621 minStrain = 0;
00622 maxStrain = 0;
00623
00624
00625
00626 SR1 = 0;
00627 NC1 = 0;
00628 SR2 = 0;
00629 NC2 = 0;
00630 SR3 = 0;
00631 NC3 = 0;
00632
00633 return theMaterial->revertToStart();
00634 }
00635
00636 UniaxialMaterial *
00637 FatigueMaterial::getCopy(void)
00638 {
00639 FatigueMaterial *theCopy =
00640 new FatigueMaterial(this->getTag(), *theMaterial, Dmax, E0, m ,minStrain, maxStrain);
00641
00642 theCopy->Cfailed = Cfailed;
00643 theCopy->trialStrain = trialStrain;
00644
00645 return theCopy;
00646 }
00647
00648 int
00649 FatigueMaterial::sendSelf(int cTag, Channel &theChannel)
00650 {
00651 int dbTag = this->getDbTag();
00652
00653 static ID dataID(3);
00654 dataID(0) = this->getTag();
00655 dataID(1) = theMaterial->getClassTag();
00656 int matDbTag = theMaterial->getDbTag();
00657 if ( matDbTag == 0) {
00658 matDbTag = theChannel.getDbTag();
00659 theMaterial->setDbTag(matDbTag);
00660 }
00661 dataID(2) = matDbTag;
00662 if (theChannel.sendID(dbTag, cTag, dataID) < 0) {
00663 opserr << "FatigueMaterial::sendSelf() - failed to send the ID\n";
00664 return -1;
00665 }
00666
00667 static Vector dataVec(21);
00668 dataVec(0) = DI;
00669 dataVec(1) = X;
00670 dataVec(2) = Y;
00671 dataVec(3) = A;
00672 dataVec(4) = B;
00673 dataVec(5) = C;
00674 dataVec(6) = D;
00675 dataVec(7) = PCC;
00676 dataVec(8) = R1F;
00677 dataVec(9) = R2F;
00678 dataVec(10) = CS;
00679 dataVec(11) = PS;
00680 dataVec(12) = EP;
00681 dataVec(13) = SF;
00682 dataVec(14) = DL;
00683 dataVec(15) = Dmax;
00684 dataVec(16) = E0;
00685 dataVec(17) = m;
00686 dataVec(18) = minStrain;
00687 dataVec(19) = maxStrain;
00688
00689 if (Cfailed == true)
00690 dataVec(20) = 1.0;
00691 else
00692 dataVec(20) = 0.0;
00693
00694 if (theChannel.sendVector(dbTag, cTag, dataVec) < 0) {
00695 opserr << "FatigueMaterial::sendSelf() - failed to send the Vector\n";
00696 return -2;
00697 }
00698
00699 if (theMaterial->sendSelf(cTag, theChannel) < 0) {
00700 opserr << "FatigueMaterial::sendSelf() - failed to send the Material\n";
00701 return -3;
00702 }
00703
00704 return 0;
00705 }
00706
00707 int
00708 FatigueMaterial::recvSelf(int cTag, Channel &theChannel,
00709 FEM_ObjectBroker &theBroker)
00710 {
00711 int dbTag = this->getDbTag();
00712
00713 static ID dataID(3);
00714 if (theChannel.recvID(dbTag, cTag, dataID) < 0) {
00715 opserr << "FatigueMaterial::recvSelf() - failed to get the ID\n";
00716 return -1;
00717 }
00718 this->setTag(int(dataID(0)));
00719
00720
00721 if (theMaterial == 0) {
00722 int matClassTag = int(dataID(1));
00723 theMaterial = theBroker.getNewUniaxialMaterial(matClassTag);
00724 if (theMaterial == 0) {
00725 opserr << "FatigueMaterial::recvSelf() - failed to create Material with classTag "
00726 << dataID(0) << endln;
00727 return -2;
00728 }
00729 }
00730 theMaterial->setDbTag(dataID(2));
00731
00732 static Vector dataVec(21);
00733 if (theChannel.recvVector(dbTag, cTag, dataVec) < 0) {
00734 opserr << "FatigueMaterial::recvSelf() - failed to get the Vector\n";
00735 return -3;
00736 }
00737
00738 DI = dataVec(0);
00739 X = dataVec(1);
00740 Y = dataVec(2);
00741 A = dataVec(3);
00742 B = dataVec(4);
00743 C = dataVec(5);
00744 D = dataVec(6);
00745 PCC = int(dataVec(7));
00746 R1F = int(dataVec(8));
00747 R2F = int(dataVec(9));
00748 CS = dataVec(10);
00749 PS = dataVec(11);
00750 EP = dataVec(12);
00751 SF = int(dataVec(13));
00752 DL = dataVec(14);
00753 Dmax = dataVec(15);
00754 E0 = dataVec(16);
00755 m = dataVec(17);
00756 minStrain = dataVec(18);
00757 maxStrain = dataVec(19);
00758
00759 if (dataVec(20) == 1.0)
00760 Cfailed = true;
00761 else
00762 Cfailed = false;
00763
00764 if (theMaterial->recvSelf(cTag, theChannel, theBroker) < 0) {
00765 opserr << "FatigueMaterial::recvSelf() - failed to get the Material\n";
00766 return -4;
00767 }
00768 return 0;
00769 }
00770
00771
00772
00773
00774
00775
00776 void
00777 FatigueMaterial::Print(OPS_Stream &s, int flag)
00778 {
00779 if (flag == 100) {
00780 s << DL << endln;
00781 } else {
00782 s << "FatigueMaterial tag: " << this->getTag() << endln;
00783 s << "\tMaterial: " << theMaterial->getTag() << endln;
00784 s << "\tDI: " << DI << " Dmax: " << Dmax << endln;
00785 s << "\tE0: " << E0 << " m: " << m << endln;
00786 s << "\tDL: " << DL << endln;
00787
00788 }
00789 }
00790
00791 Response*
00792 FatigueMaterial::setResponse(const char **argv, int argc, Information &matInfo, OPS_Stream &theOutput)
00793 {
00794 if (argc == 0)
00795 return 0;
00796
00797 Response *theResponse = 0;
00798
00799 theOutput.tag("UniaxialMaterialOutput");
00800 theOutput.attr("matType", this->getClassType());
00801 theOutput.attr("matTag", this->getTag());
00802
00803
00804
00805 if (strcmp(argv[0],"stress") == 0) {
00806 theOutput.tag("ResponseType", "sigma11");
00807 theResponse = new MaterialResponse(this, 1, this->getStress());
00808 }
00809
00810 else if (strcmp(argv[0],"tangent") == 0) {
00811 theOutput.tag("ResponseType", "C11");
00812 theResponse = new MaterialResponse(this, 2, this->getTangent());
00813 }
00814
00815
00816 else if (strcmp(argv[0],"strain") == 0) {
00817 theOutput.tag("ResponseType", "eps11");
00818 theResponse = new MaterialResponse(this, 3, this->getStrain());
00819 }
00820
00821
00822 else if ((strcmp(argv[0],"stressStrain") == 0) ||
00823 (strcmp(argv[0],"stressANDstrain") == 0)) {
00824 theOutput.tag("ResponseType", "sig11");
00825 theOutput.tag("ResponseType", "eps11");
00826 theResponse = new MaterialResponse(this, 4, Vector(2));
00827 }
00828
00829
00830 else if (strcmp(argv[0],"damage") == 0) {
00831 theResponse = new MaterialResponse(this, 5, DI);
00832 theOutput.tag("ResponseType", "DI");
00833
00834 } else if (strcmp(argv[0],"cyclesAndRange") == 0) {
00835 theOutput.tag("ResponseType", "UnknownResponse");
00836 theOutput.tag("ResponseType", "UnknownResponse");
00837 theOutput.tag("ResponseType", "UnknownResponse");
00838 theOutput.tag("ResponseType", "UnknownResponse");
00839 theOutput.tag("ResponseType", "UnknownResponse");
00840 theOutput.tag("ResponseType", "UnknownResponse");
00841 theResponse = new MaterialResponse(this, 6, Vector(6));
00842 }
00843
00844
00845
00846 theOutput.endTag();
00847 return theResponse;
00848 }
00849
00850 int
00851 FatigueMaterial::getResponse(int responseID, Information &matInfo)
00852 {
00853 static Vector stressStrain(2);
00854 static Vector cyclesAndRange(6);
00855
00856
00857 switch (responseID) {
00858 case 1:
00859 matInfo.setDouble(this->getStress());
00860 return 0;
00861
00862 case 2:
00863 matInfo.setDouble(this->getTangent());
00864 return 0;
00865
00866 case 3:
00867 matInfo.setDouble(this->getStrain());
00868 return 0;
00869
00870 case 4:
00871 stressStrain(0) = this->getStress();
00872 stressStrain(1) = this->getStrain();
00873 matInfo.setVector(stressStrain);
00874 return 0;
00875
00876 case 5:
00877 matInfo.setDouble(DI);
00878 return 0;
00879
00880 case 6:
00881 cyclesAndRange(0) = NC1;
00882 cyclesAndRange(1) = SR1;
00883 cyclesAndRange(2) = NC2;
00884 cyclesAndRange(3) = SR2;
00885 cyclesAndRange(4) = NC3;
00886 cyclesAndRange(5) = SR3;
00887 matInfo.setVector(cyclesAndRange);
00888 return 0;
00889
00890 default:
00891 return -1;
00892
00893 }
00894 }
00895
00896