FatigueMaterial.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.4 $
00022 // $Date: 2006/08/18 23:00:31 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/FatigueMaterial.cpp,v $
00024 
00025 // Written: Patxi 
00026 // Created: Aug 2003
00027 //
00028 // Description: This file contains the class definition for 
00029 // FatigueMaterial.  FatigueMaterial wraps a UniaxialMaterial
00030 // and imposes fatigue limits. More information about this material can
00031 // be found in the doctoral dissertation of Patxi Uriz:
00032 //
00033 //   Uriz, Patxi, "Towards Earthquake Resistant Design of 
00034 //      Concentrically Braced Steel Frames," Ph.D. Dissertation, 
00035 //      Structural Engineering, Mechanics, and Materials, Civil 
00036 //      and Envrironmental Engineering, University of California, 
00037 //      Berkeley, December 2005
00038 //
00039 // Modifications to the code have been added by Kevin Mackie, Ph.D., as
00040 // shown below.
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; //Damage index
00062   X   = 0; //Range in consideration
00063   Y   = 0; //Previous Adjacent Range
00064   A   = 0; //Peak or valley 1
00065   B   = 0; //Peak or valley 2
00066   C   = 0; //Peak or valley 2
00067   D   = 0; //Peak or valley 4
00068   PCC = 0; /*Previous Cycle counter flag if >1 then previous 'n' 
00069              cycles did not flag a complete cycle */
00070   R1F = 0; //Flag for first  peak count
00071   R2F = 0; //Flag for second peak count
00072   CS  = 0; //Current Slope
00073   PS  = 0; //Previous slope
00074   EP  = 0; //Previous Strain
00075   SF  = 0; /*Start Flag = 0 if very first strain, (i.e. when initializing)
00076              = 1 otherwise */
00077   DL  = 0; //Damage if current strain was last peak.
00078   
00079   // added 6/9/2006
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; //Damage index
00114   X   = 0; //Range in consideration
00115   Y   = 0; //Previous Adjacent Range
00116   A   = 0; //Peak or valley 1
00117   B   = 0; //Peak or valley 2
00118   C   = 0; //Peak or valley 2
00119   D   = 0; //Peak or valley 4
00120   PCC = 0; /*Previous Cycle counter flag if >1 then previous 'n' 
00121              cycles did not flag a complete cycle */
00122   R1F = 0; //Flag for first  peak count
00123   R2F = 0; //Flag for second peak count
00124   CS  = 0; //Current Slope
00125   PS  = 0; //Previous slope
00126   EP  = 0; //Previous Strain
00127   SF  = 0; /*Start Flag = 0 if very first strain, (i.e. when initializing)
00128              = 1 otherwise */
00129   DL  = 0; //Damage if current strain was last peak.
00130   
00131   Dmax    = 0;
00132   E0      = 0; 
00133   m       = 0;
00134   minStrain    = 0;
00135   maxStrain    = 0;
00136   
00137   // added 6/9/2006
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     // return 0;
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     // Reduce stress to 0.0 
00183     return theMaterial->getStress()*1.0e-8;
00184   
00185   /*
00186   // This portion of the code was added by Kevin Mackie, Ph.D.
00187   //  This is appropriate for steel material.  Uncomment to use.
00188   else if ( damageloc <= 0.9 )
00189   modifier = 1.0-725.0/2937.0*pow(damageloc,2);
00190   else 
00191   modifier = 8.0*(1.0-damageloc);
00192   
00193   if (modifier <= 0)
00194     modifier = 1.0e-8;
00195   
00196   else
00197     return theMaterial->getStress()*modifier;
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     // Reduce tangent to 0.0 
00211     return 1.0e-8*theMaterial->getInitialTangent();
00212   
00213   /* 
00214   // This portion of the code was added by Kevin Mackie, Ph.D.
00215   //  This is appropriate for steel material.  Uncomment to use.
00216   else if ( damageloc <= 0.9 )
00217   modifier = 1.0-725.0/2937.0*pow(damageloc,2);
00218   else
00219   modifier = 8.0*(1.0-damageloc);
00220   
00221   if (modifier <= 0)
00222   // modifier = 1.0e-8;
00223   modifier = 1.0e-3;
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   // NOTE: Do not accumulate damage if peaks are too small (e.g. if X < 1e-10)
00258   // may get floating point errors.  This is essentially a filter for 
00259   // strain cycles smaller than 1e-10 strain.  
00260   //  THIS FATIGE MATERIAL CODE WAS NOT INTENDED FOR HIGH CYCLE FATIGUE, 
00261   //  THE LINEAR ACCUMULATION OF DAMAGE IS NOT AS APPROPRIATE FOR HIGH
00262   //  CYCLE FATIGUE. 
00263 
00264   //added 6/9/2006
00265   // for recorder
00266   SR1 = 0;
00267   NC1 = 0;
00268 
00269 
00270   // No need to continue if the uniaxial material copy 
00271   // has already failed.
00272   if (Cfailed) {
00273     return 0;
00274   }
00275 
00276   //Simple check to see if we reached max strain capacities
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   //Initialize the fatigue parameters if they have 
00286   // not been initialized yet
00287   if (SF == 0) {
00288 
00289     A   = trialStrain;
00290     SF  = 1  ;
00291     EP  = trialStrain;
00292     // Initialize other params if not done so already
00293     PCC = 0;
00294     B   = 0;
00295     C   = 0;
00296     D   = 0;
00297 
00298   }
00299 
00300   /* Now we need to determine if we are at a peak or not 
00301      If we are, then we need to do some calcs to determine
00302      the amount of damage suffered. If we are not at a peak, we need to
00303      pretend like we are at a peak, so that we can calculate the damage
00304      as if it WERE a peak.   
00305   */
00306 
00307   // Determine the slope of the strain hysteresis
00308   if ( EP == trialStrain ) {
00309     CS = PS;         // No real slope here....
00310   } else {
00311     CS = trialStrain - EP;   // Determine Current Slope
00312   }
00313 
00314 
00315   // If we are at a peak or a valley, then check for damage
00316   if (sign(PS) != sign(CS) && sign(PS) != 0 ) {
00317 
00318     if ( R1F == 0 )  {    // mark second peak
00319 
00320       B = EP; 
00321       Y = fabs(B-A);
00322       R1F = 1;
00323 
00324     } else {   // start at least the third peak
00325 
00326       // begin modified Rainflow cycle counting
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           // Count X = |D-C| as a 1.0 cycle
00347           DI = DI + 1.0 / fabs(pow( (X/E0) , 1/m )) ;
00348           //added 6/9/2006
00349           SR1 = X;
00350           NC1 = 1.0;
00351           // Reset parameters
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           // Count Y = |C-B| as a 1.0 cycle
00364           DI = DI + 1.0 / fabs(pow( (Y/E0) , 1/m ));
00365           //added 6/9/2006
00366           SR1 = Y;
00367           NC1 = 1.0;
00368 
00369           // Reset parameters
00370           B = D;
00371           C = 0;
00372           D = 0;
00373           Y = fabs(B-A);
00374           PCC = 0;
00375 
00376 
00377 
00378         } else {
00379           
00380           // Count Y = |A-B| as a 0.5 cycle
00381           DI = DI + 0.5 / fabs(pow( (Y/E0), 1/m ));
00382 
00383           //added 6/9/2006
00384           // For recorder
00385           SR1 = Y;
00386           NC1 = 0.5;
00387 
00388           // Reset parameters
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     // Flag failure if we have reached that point
00404     if (DI >= Dmax )  {
00405       // Most likely will not fail at this point, more 
00406       // likely at the psuedo peak. But this step is
00407       // is important for accumulating damage
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     // Modified by Patxi 3/5/2006
00417   // } else {
00418   }
00419   if (Cfailed == false) {
00420     
00421     // Now check for damage, although we may not be at a peak at all.
00422     // Store temporary damage only as if it were the last peak: DL
00423     // Commit to DI only if failure occurs.
00424     if (B == 0 && C == 0 &&  D == 0) {
00425       
00426       // If we have not yet found the second peak
00427       X = fabs(trialStrain - A);
00428 
00429       if (fabs(X) < 1e-10) {
00430         DL = DI ;
00431         // added 6/9/2006
00432         //values for recorder
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         // added 6/9/2006
00440         //values for recorder
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       // On our way to find point C. Range Y defined, no X yet
00450       X = fabs(trialStrain - B);
00451       
00452       if (fabs(X) < 1e-10) {
00453         DL = DI;
00454         // added 6/9/2006
00455         //values for recorder
00456         SR2 = 0.0;
00457         NC2 = 0.0;
00458       } else {
00459         DL = DI +  0.5 / fabs(pow( (X/E0) , 1/m ));
00460         // added 6/9/2006
00461         //values for recorder
00462         SR2 = X;
00463         NC2 = 0.5;
00464       } 
00465       
00466       if (fabs(Y) < 1e-10) {
00467         DL = DL;
00468         // added 6/9/2006
00469         //values for recorder
00470         SR3 = 0.0;
00471         NC3 = 0.0;
00472       } else {
00473         DL = DL +  0.5 / fabs(pow( (Y/E0) , 1/m ));
00474         // added 6/9/2006
00475         //values for recorder
00476         SR3 = Y;
00477         NC3 = 0.5;
00478       }
00479       
00480     } else if (B != 0 && C != 0 &&  D == 0) {
00481       
00482       // Two ranges stored, but no cycles for either stored
00483       // There are two scenarios that can result:
00484       // 1.)  |A-D| is the predominate 1/2 cycle, 
00485       //      and |B-C| is a small full cycle.
00486       //
00487       // 2.)  One full cylce at |D-C|, 1/2 cycle at |A-B|
00488 
00489       if (fabs(A-trialStrain)> fabs(A-B)) {
00490         
00491         //   count 1/2 cycle at |D-A|, and one full cycle at |B-C|.
00492         X = fabs(trialStrain-A);
00493         
00494         if (fabs(Y) < 1e-10) {
00495           DL = DI;
00496           // added 6/9/2006
00497           //values for recorder
00498           SR3 = 0.0;
00499           NC3 = 0.0;
00500         } else {
00501           DL = DI +  1.0 / fabs(pow( (Y/E0) , 1/m ));
00502           // added 6/9/2006
00503           //values for recorder
00504           SR3 = Y;
00505           NC3 = 1.0;
00506         } 
00507       
00508         if (fabs(X) < 1e-10) {
00509           DL = DL;
00510           // added 6/9/2006
00511           //values for recorder
00512           SR2 = 0.0;
00513           NC2 = 0.0;
00514         } else {
00515           DL = DL +  0.5 / fabs(pow( (X/E0) , 1/m ));
00516           // added 6/9/2006
00517           //values for recorder
00518           SR2 = X;
00519           NC2 = 0.5;
00520         }
00521 
00522       } else {
00523         
00524         // One full cycle of |C-D| and 1/2 cyle of |A-B|
00525         
00526         if (fabs(C-trialStrain) < 1e-10) {
00527           DL = DI;
00528           // added 6/9/2006
00529           //values for recorder
00530           SR3 = 0.0;
00531           NC3 = 0.0;
00532         } else {
00533           DL = DI +  1.0 / fabs(pow( ( fabs(C-trialStrain)/E0 ) , 1/m ));
00534           // added 6/9/2006
00535           //values for recorder
00536           SR3 = fabs(C-trialStrain);
00537           NC3 = 1.0;
00538         } 
00539       
00540         if (fabs(A-B) < 1e-10) {
00541           DL = DL;
00542           // added 6/9/2006
00543           //values for recorder
00544           SR2 = 0.0;
00545           NC2 = 0.0;
00546         } else {
00547           DL = DL +  0.5 / fabs(pow( (fabs(A-B) /E0) , 1/m ));
00548           // added 6/9/2006
00549           //values for recorder
00550           SR2 = fabs(A-B);
00551           NC2 = 0.5;
00552         }
00553       }
00554     }
00555     
00556     // Did we fail before a peak?
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;            // Previous Slope
00569   EP = trialStrain;   // Keep track of previous strain
00570   
00571   // Check if failed at current step
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   // Check if failed at last step
00585   if (Cfailed)
00586     return 0;
00587   else
00588     return theMaterial->revertToLastCommit();
00589 }
00590 
00591 // Kevin Mackie, Ph.D. is responsible for the addition of 
00592 // revertToStart, sendSelf, recvSelf.  Thanks to Kevin for making this
00593 // code more user friendly!
00594 
00595 int 
00596 FatigueMaterial::revertToStart(void)
00597 {
00598 
00599   Cfailed = false;
00600   DI  = 0; //Damage index
00601   X   = 0; //Range in consideration
00602   Y   = 0; //Previous Adjacent Range
00603   A   = 0; //Peak or valley 1
00604   B   = 0; //Peak or valley 2
00605   C   = 0; //Peak or valley 2
00606   D   = 0; //Peak or valley 4
00607   PCC = 0; /*Previous Cycle counter flag if >1 then previous 'n' 
00608              cycles did not flag a complete cycle */
00609   R1F = 0; //Flag for first  peak count
00610   R2F = 0; //Flag for second peak count
00611   CS  = 0; //Current Slope
00612   PS  = 0; //Previous slope
00613   EP  = 0; //Previous Strain
00614   SF  = 0; /*Start Flag = 0 if very first strain, (i.e. when initializing)
00615              = 1 otherwise */
00616   DL  = 0; //Damage if current strain was last peak.
00617 
00618   Dmax    = 0;
00619   E0      = 0; 
00620   m       = 0;
00621   minStrain    = 0;
00622   maxStrain    = 0;
00623 
00624   // added 6/9/2006
00625   //values for recorder
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   // as no way to change material, don't have to check classTag of the material 
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 //Printing of current damage.  NOTE:  The damage that is returned
00772 //  is damage at the psuedo peak, DL, ( if not at a peak when the 
00773 //  print function  is called). The generic print will print both 
00774 //  the damage recorded at the last peak, along with current damage
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   // stress
00805   if (strcmp(argv[0],"stress") == 0) {
00806     theOutput.tag("ResponseType", "sigma11");
00807     theResponse =  new MaterialResponse(this, 1, this->getStress());
00808   }  
00809   // tangent
00810   else if (strcmp(argv[0],"tangent") == 0) {
00811     theOutput.tag("ResponseType", "C11");
00812     theResponse =  new MaterialResponse(this, 2, this->getTangent());
00813   }
00814 
00815   // strain
00816   else if (strcmp(argv[0],"strain") == 0) {
00817     theOutput.tag("ResponseType", "eps11");
00818     theResponse =  new MaterialResponse(this, 3, this->getStrain());
00819   }
00820 
00821   // strain
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  // damage 
00830   else if (strcmp(argv[0],"damage") == 0) {
00831     theResponse =  new MaterialResponse(this, 5, DI);
00832     theOutput.tag("ResponseType", "DI");
00833     // added 6/9/2006
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   // end add
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   // each subclass must implement its own stuff    
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 

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