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
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
00061 d_curr = d/initDMag;
00062 f_curr = f/initFMag;
00063
00064 yielding = yield;
00065
00066
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
00082
00083
00084
00085 if (fabs(d_curr - d_hist) > Tol)
00086 k_curr = fabs((f_curr - f_hist)/(d_curr - d_hist));
00087
00088
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
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
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
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
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
00156 if(d_curr > 0 && !initYieldPos ||
00157 d_curr < 0 && !initYieldNeg
00158 )
00159 {
00160 cycFactor = 1.0;
00161
00162 return 0;
00163 }
00164
00165 if (fabs(d - d_hist) < Tol)
00166 {
00167 state_curr = Loading;
00168
00169 cycFactor = cycFactor_hist;
00170 return 0;
00171 }
00172
00173
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
00184
00185
00186 return 0;
00187 }
00188
00189
00190 int res = taskStatus();
00191 if(res < 0)
00192 {
00193 opserr << "Task aborted, creating new half-cycle task\n";
00194
00195
00196 if (createHalfCycleTask() < 0)
00197 {
00198 opserr << "WARNING - CyclicModel::getFactor(), createHalfCycleTask failed\n";
00199 cycFactor = resFactor;
00200 }
00201 else
00202 cycFactor = getTaskFactor();
00203
00204
00205
00206 }
00207 else if (res > 0)
00208 {
00209
00210 cycFactor = getTaskFactor();
00211 }
00212 else if (res == 0)
00213 {
00214
00215
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
00228
00229
00230
00231 cycFactor = 1.0;
00232 }
00233
00234
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
00250
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
00260
00261
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;
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;
00306 }
00307
00308 int status = -1;
00309 if( delT_curr <= delT_hist)
00310 status = 1;
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;
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