CyclicModel.cpp

Go to the documentation of this file.
00001 #include "CyclicModel.h"
00002 #include <math.h>
00003 
00004 const int    CyclicModel::Loading(1);
00005 const int    CyclicModel::Unloading(2);
00006 const int    CyclicModel::Crossover(3);
00007 const double CyclicModel::Tol(1e-10);
00008 const double CyclicModel::delK(0.85);
00009 
00010 CyclicModel::CyclicModel(int tag, int clasTag)
00011 :TaggedObject(tag), MovableObject(clasTag),
00012  resFactor(1.0),
00013  cycFactor(1.0), cycFactor_hist(1.0),
00014  f_hist(0.0), d_hist(0.0), f_curr(0.0), d_curr(0.0),
00015  f_bgn(0.0), d_bgn(0.0), f_end(0.0), d_end(0.0),
00016  initFpos(0.0),initDpos(0.0),initFneg(0.0),initDneg(0.0),
00017  initFMag(0.0),initDMag(0.0),
00018  k_init(0.0),
00019  delT_curr(0.0), delT_hist(0.0),
00020  k_hist(0.0), k_curr(0.0),
00021  initYieldPos(false), initYieldNeg(false), 
00022  initCyc(false), yielding(false), yielding_hist(false),
00023  fpeakPos(0.0), dpeakPos(0.0),fpeakNeg(0.0),dpeakNeg(0.0),
00024  state_hist(Loading), state_curr(Loading)
00025 {
00026 
00027 }
00028 
00029 
00030 CyclicModel::~CyclicModel()
00031 {
00032   // does nothing
00033 }
00034 
00035 
00036 double CyclicModel::getFactor()
00037 {
00038         if(cycFactor < 0.05)
00039                 cycFactor = 0.05;
00040 
00041         if(state_curr == Unloading && state_hist == Loading)
00042                 cycFactor = resFactor;
00043                 
00044         return cycFactor;
00045 }
00046 
00047 void CyclicModel::update(double f, double d, bool yield)
00048 {
00049         if( yield && (!initYieldPos &&  !initYieldNeg))
00050         {
00051                 initDMag = d;
00052                 initFMag = f;
00053         }
00054         if( !yield && (!initYieldPos &&  !initYieldNeg))
00055         {
00056                 initDMag = d;
00057                 initFMag = f;
00058         }
00059 
00060         // non-dimentionalize d_curr and f_curr
00061         d_curr = d/initDMag;
00062         f_curr = f/initFMag;
00063 
00064         yielding = yield;
00065 
00066 // check state
00067         if(fabs(f_curr) < fabs(f_hist) &&
00068            fabs(d_curr) < fabs(d_hist) &&
00069            dir(f_curr)== dir(f_hist)
00070           )
00071                 state_curr = Unloading;
00072         else
00073                 state_curr = Loading;
00074 
00075         if(f_curr*f_hist < 0)
00076                 state_curr = Crossover;
00077 }
00078 
00079 int CyclicModel::commitState(double newRes)
00080 {
00081 //      d_curr = d;
00082 //      f_curr = f;
00083 
00084 // first make sure we don't encounter any divide by 0 errors
00085         if (fabs(d_curr - d_hist) > Tol)
00086                 k_curr = fabs((f_curr - f_hist)/(d_curr - d_hist));
00087 
00088         // check if the yield-point has been found
00089         if(!initYieldPos && yielding && d_curr > 0.0)
00090         {
00091                 initDpos = d_curr;
00092                 initFpos = f_curr;
00093                 initYieldPos = true;
00094                 if(!initYieldNeg)
00095                         k_init = f_curr/d_curr;
00096         }
00097 
00098         if(!initYieldNeg && yielding && d_curr < 0.0)
00099         {
00100                 initDneg = d_curr;
00101                 initFneg = f_curr;
00102                 initYieldNeg = true;
00103                 if(!initYieldPos)
00104                         k_init = f_curr/d_curr;
00105         }
00106 
00107 
00108 // Temp approx. init values
00109         if(initYieldPos && !initYieldNeg)
00110         {
00111                 initDneg = -1*initDpos;
00112                 initFneg = -1*initFpos;
00113         }
00114         if(initYieldNeg && !initYieldPos)
00115         {
00116                 initDpos = -1*initDneg;
00117                 initFpos = -1*initFneg;
00118         }
00119 
00120 // now update the commit values
00121 
00122         if(d_curr > dpeakPos)
00123         {
00124                 dpeakPos = d_curr;
00125                 fpeakPos = f_curr;
00126         }
00127 
00128         if(d_curr < 0 && fabs(d_curr) > fabs(dpeakNeg))
00129         {
00130                 dpeakNeg = d_curr;
00131                 fpeakNeg = f_curr;
00132         }
00133 
00134         setCurrent(f_curr, d_curr);
00135         //cout << *this;
00136 
00137         k_hist = k_curr;
00138         f_hist = f_curr;
00139         d_hist = d_curr;
00140         cycFactor_hist = cycFactor;
00141         resFactor = newRes;
00142 
00143         // opserr << " Resfactor = " << newRes << endln;
00144         
00145         state_hist = state_curr;
00146         yielding_hist = yielding;
00147 
00148         delT_hist = delT_curr;
00149 
00150         return 0;
00151 }
00152 
00153 int CyclicModel::setCurrent(double f, double d)
00154 {
00155         // check if initially yielded
00156         if(d_curr > 0 && !initYieldPos ||
00157        d_curr < 0 && !initYieldNeg
00158           )
00159         {
00160                 cycFactor = 1.0; // resFactor; - not yielded yet
00161                 // return cycFactor;
00162                 return 0;
00163         }
00164 
00165         if (fabs(d - d_hist) < Tol)
00166         {
00167                 state_curr = Loading;
00168                 // opserr << "CYC1 \n"; -> don't remove
00169                 cycFactor = cycFactor_hist;
00170                 return 0;
00171         }
00172 
00173         // check if new full-cycle task needs to be created
00174         if(state_curr == Unloading && state_hist == Loading && f_curr*f_hist > 0)
00175         {
00176                 if (createFullCycleTask() < 0)
00177                 {
00178                         opserr << "WARNING - CyclicModel::getFactor(), createFullCycleTask failed\n";
00179                         cycFactor = resFactor;
00180                 }
00181                 else
00182                         cycFactor = getTaskFactor();
00183                 // opserr << *this;
00184 
00185                 // return cycFactor;
00186                 return 0;
00187         }
00188 
00189         // else check the status of the current task
00190         int res = taskStatus();
00191         if(res < 0) // task aborted, create new (half-cycle)
00192         {
00193                 opserr << "Task aborted, creating new half-cycle task\n";
00194                 //cout <<"BEFORE\n" << *this;
00195 
00196                 if (createHalfCycleTask() < 0)
00197                 {
00198                         opserr << "WARNING - CyclicModel::getFactor(), createHalfCycleTask failed\n";
00199                         cycFactor = resFactor;
00200                 }
00201                 else
00202                         cycFactor = getTaskFactor();
00203                 // opserr <<"AFTER\n" << *this;
00204                 // opserr << "\a";
00205 
00206         }
00207         else if (res > 0) // existing task continuing
00208         {
00209                 // opserr << "Task continuing\n";
00210                 cycFactor = getTaskFactor();
00211         }
00212         else if (res == 0)
00213         {
00214                 // opserr << "Task does not exit (or completed)\n";
00215                 // cycFactor = resFactor or cyc_hist?
00216                 cycFactor = cycFactor_hist;
00217         }
00218         else
00219         {
00220                 opserr << "FATAL: CyclicModel::getFactor() - nan \n";
00221                 opserr << "CYC3 \n";
00222                 cycFactor = 1.0;
00223         }
00224 
00225         if(cycFactor > (1.001))
00226         {
00227                 // opserr << "WARNING - cyc > Ko\n";
00228                 // opserr << *this;
00229                 // opserr << "\a";
00230                 // opserr << "CYC4 \n";
00231                 cycFactor = 1.0;
00232         }
00233 
00234         // return cycFactor;
00235         return 0;
00236 }
00237 
00238 int CyclicModel::createHalfCycleTask()
00239 {
00240         int res =  initNewTask();
00241         delT_hist = fabs(d_hist - d_end);
00242         delT_curr = fabs(d_curr - d_end);
00243         return res;
00244 }
00245 
00246 int CyclicModel::createFullCycleTask()
00247 {
00248         opserr << "Creating new full-cycle task\n";
00249         // opserr << *this;
00250     // opserr << "\a";
00251     
00252         initCyc = true;
00253         int res =  initNewTask();
00254         delT_hist = fabs(d_hist - d_end);
00255         delT_curr = fabs(d_curr - d_end);
00256         return res;
00257 }
00258 
00259 // start-point should be f_hist, d_hist
00260 // end-point is fpeak (corresponding to dpeak)
00261 // direction is diven by (d_curr - d_hist)
00262 int CyclicModel::initNewTask()
00263 {
00264         f_bgn = f_hist;
00265         d_bgn = d_hist;
00266 
00267         double sgn = d_curr - d_hist;
00268 
00269         if(sgn > 0)
00270         {
00271                 f_end = fpeakPos;
00272                 d_end = dpeakPos;
00273 
00274                 if(!initYieldPos)
00275                 {
00276                         f_end = initFpos;
00277                         d_end = initDpos;
00278                 }
00279         }
00280         else
00281         {
00282                 f_end = fpeakNeg;
00283                 d_end = dpeakNeg;
00284 
00285                 if(!initYieldNeg)
00286                 {
00287                         f_end = initFneg;
00288                         d_end = initDneg;
00289                 }
00290         }
00291 
00292         return 0;
00293 }
00294 
00295 int CyclicModel::taskStatus()
00296 {
00297         if(!initCyc)
00298                 return 0; // task does not exist
00299 
00300         delT_curr = fabs(d_curr - d_end);
00301 
00302         if(fabs(d_curr) >= fabs(d_end) && dir(d_curr)==dir(d_end))
00303         {
00304                 initCyc = false;
00305                 return 0; // task completed
00306         }
00307 
00308 int status = -1; // aborted
00309         if( delT_curr <= delT_hist)
00310                 status = 1; // task continuing
00311 
00312         return status;
00313 }
00314 
00315 
00316 double CyclicModel::rationalize(double x1, double y1, double x2, double y2)
00317 {
00318         double tangent = fabs((y2-y1)/(x2-x1));
00319         double tang0   = k_init; // = 1.0
00320 
00321         return (tangent/tang0);
00322 }
00323 
00324 bool CyclicModel::contains(double x1, double x2, double x)
00325 {
00326 bool res = false;
00327         if( (x >= x1 && x <= x2) || (x <= x1 && x >= x2))
00328                 res = true;
00329         return res;
00330 }
00331 
00332 int CyclicModel::dir(double x)
00333 {
00334 int sgn;
00335         (x>0)?sgn=1:sgn=-1;
00336         return sgn;
00337 }
00338 
00339 void CyclicModel::Print (OPS_Stream &s, int flag)
00340 {
00341         s << "+CyclicModel, Tag: " << getTag() << endln;
00342         s << "|  f curr  = " << f_curr << ", d curr  = " << d_curr << endln;
00343         s << "|  f commit = " << f_hist  << ", d commit = " << d_hist  << endln;
00344         s << "|  state = " << state_curr << endln;
00345         s << "|  (1: loading, 2:unloading, 3: cross-over)\n";
00346         s << "|  Yielding: "; (yielding)? s << "TRUE\n" : s << "FALSE" << endln;
00347         s << "|  " << endln;
00348         s << "|  d_bgn = " << d_bgn << ", f_bgn = " << f_bgn << endln;
00349         s << "|  d_end = " << d_end << ", f_end = " << f_end << endln;
00350         s << "|  " << endln;            
00351         s << "|  delT curr = " << delT_curr << ", delT_hist = " << delT_hist << endln;
00352         s << "|  initFpos: " << initFpos << ", initDpos: " << initDpos << endln;
00353         s << "|  initFneg: " << initFneg << ", initDneg: " << initDneg << endln;
00354         s << "|  k_init  : " << k_init << endln;
00355         s << "|  dpeakPos: " << dpeakPos << ", fpeakPos: " << fpeakPos << endln;
00356         s << "|  dpeakNeg: " << dpeakNeg << ", fpeakNeg: " << fpeakNeg << endln;
00357         s << "|  " << endln;
00358         s << "|  resFactor  -> " << resFactor << endln;
00359         s << "|  realFactor -> " << getFactor() << endln;
00360 }
00361 
00362 

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