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 #include <Isolator2spring.h>
00036 #include <Channel.h>
00037 #include <Matrix.h>
00038 #include <Vector.h>
00039
00040 Vector Isolator2spring::s(2);
00041 Vector Isolator2spring::s3(3);
00042 Vector Isolator2spring::f0(5);
00043 Matrix Isolator2spring::df(5,5);
00044 ID Isolator2spring::code(3);
00045
00046 Isolator2spring::Isolator2spring
00047 (int tag, double tol_in, double k1_in, double Fy_in, double kb_in, double kvo_in, double hb_in, double Pe_in,
00048 double po_in) :
00049 SectionForceDeformation(tag, SEC_TAG_Isolator2spring),
00050 tol(tol_in), k1(k1_in), Fyo(Fy_in), kbo(kb_in), kvo(kvo_in), h(hb_in), Pe(Pe_in), po(po_in), x0(5), ks(3,3)
00051 {
00052
00053 this->revertToStart();
00054
00055 pcr = sqrt(Pe*kbo*h);
00056 H = k1*kbo/(k1 - kbo);
00057
00058 code(0) = SECTION_RESPONSE_P;
00059 code(1) = SECTION_RESPONSE_VY;
00060 code(2) = SECTION_RESPONSE_MZ;
00061
00062 }
00063
00064 Isolator2spring::Isolator2spring():
00065 SectionForceDeformation(0, SEC_TAG_Isolator2spring),
00066 tol(1.0e-12), k1(0.0), Fyo(0.0), kbo(0.0), kvo(0.0), h(0.0), Pe(0.0), po(0.0)
00067 {
00068
00069 this->revertToStart();
00070
00071 pcr = sqrt(Pe*kbo*h);
00072 H = k1*kbo/(k1 - kbo);
00073
00074 code(0) = SECTION_RESPONSE_P;
00075 code(1) = SECTION_RESPONSE_VY;
00076 code(2) = SECTION_RESPONSE_MZ;
00077 }
00078
00079 Isolator2spring::~Isolator2spring()
00080 {
00081
00082 }
00083
00084 int
00085 Isolator2spring::setTrialSectionDeformation(const Vector &e)
00086 {
00087 utpt[0] = e(0);
00088 utpt[1] = e(1);
00089 return 0;
00090 }
00091
00092 const Matrix&
00093 Isolator2spring::getSectionTangent(void)
00094 {
00095
00096
00097 return ks;
00098 }
00099
00100 const Matrix&
00101 Isolator2spring::getInitialTangent(void)
00102 {
00103
00104 ks(0,0) = k1;
00105 ks(1,1) = kvo;
00106 ks(0,1) = ks(1,0) = 0.0;
00107 ks(0,2) = ks(1,2) = ks(2,2) = ks(2,1) = ks(2,0) = 0.0;
00108
00109 return ks;
00110 }
00111
00112 const Vector&
00113 Isolator2spring::getStressResultant(void)
00114 {
00115
00116 double Fy;
00117 if (po < 1.0e-10) {
00118
00119 Fy = Fyo;
00120 } else {
00121
00122 double p2 = x0(1)/po;
00123 if (p2<0) {
00124 p2 = 0.0;
00125 }
00126 Fy = Fyo*(1-exp(-p2));
00127 }
00128
00129
00130
00131
00132
00133 double fb_try = k1*(x0(2)-sP_n);
00134 double xi_try = fb_try - q_n;
00135
00136
00137 double Phi_try = fabs(xi_try) - Fy;
00138
00139 double fspr;
00140 double dfsds;
00141 double del_gam;
00142 int sign;
00143
00144
00145 if (Phi_try <= 0.0) {
00146
00147
00148 fspr = fb_try;
00149 dfsds = k1;
00150 sP_n1 = sP_n;
00151 q_n1 = q_n;
00152 }
00153
00154
00155 else {
00156
00157 del_gam = Phi_try/(k1+H);
00158
00159 sign = (xi_try < 0) ? -1 : 1;
00160
00161 fspr = fb_try - del_gam*k1*sign;
00162 dfsds = kbo;
00163
00164 sP_n1 = sP_n + del_gam*sign;
00165 q_n1 = q_n + del_gam*H*sign;
00166 }
00167
00168
00169
00170 f0(0) = x0(0) - fspr + x0(1)*x0(3);
00171 f0(1) = x0(0)*h - Pe*h*x0(3) + x0(1)*(x0(2)+h*x0(3));
00172 f0(2) = x0(1) - kvo*x0(4);
00173 f0(3) = utpt[0] - x0(2) - h*x0(3);
00174 f0(4) = -utpt[1] - x0(2)*x0(3) - h/2.0*x0(3)*x0(3) - x0(4);
00175
00176 int iter = 0;
00177 double normf0 = f0.Norm();
00178 static Matrix dfinverse(5,5);
00179
00180
00181 while (normf0 > tol) {
00182
00183 iter += 1;
00184
00185
00186 df(0,0) = 1.0;
00187 df(0,1) = x0(3);
00188 df(0,2) = -dfsds;
00189 df(0,3) = x0(1);
00190 df(0,4) = 0.0;
00191
00192 df(1,0) = h;
00193 df(1,1) = x0(2) + h*x0(3);
00194 df(1,2) = x0(1);
00195 df(1,3) = (x0(1) - Pe)*h;
00196 df(1,4) = 0.0;
00197
00198 df(2,0) = 0.0;
00199 df(2,1) = 1.0;
00200 df(2,2) = 0.0;
00201 df(2,3) = 0.0;
00202 df(2,4) = -kvo;
00203
00204 df(3,0) = 0.0;
00205 df(3,1) = 0.0;
00206 df(3,2) = -1.0;
00207 df(3,3) = -h;
00208 df(3,4) = 0.0;
00209
00210 df(4,0) = 0.0;
00211 df(4,1) = 0.0;
00212 df(4,2) = -x0(3);
00213 df(4,3) = -(x0(2) + h*x0(3));
00214 df(4,4) = -1.0;
00215
00216 df.Invert(dfinverse);
00217
00218 x0 -= dfinverse*f0;
00219
00220
00221 if (po > 1.0e-10) {
00222
00223 double p2 = x0(1)/po;
00224 if (p2<0) {
00225 p2 = 0.0;
00226 }
00227 Fy = Fyo*(1-exp(-p2));
00228 }
00229
00230
00231
00232 fb_try = k1*(x0(2) - sP_n);
00233 xi_try = fb_try - q_n;
00234
00235 Phi_try = fabs(xi_try) - Fy;
00236
00237
00238 if (Phi_try <= 0.0) {
00239
00240 fspr = fb_try;
00241 dfsds = k1;
00242 sP_n1 = sP_n;
00243 q_n1 = q_n;
00244 }
00245
00246
00247 else {
00248 del_gam = Phi_try/(k1+H);
00249 sign = (xi_try < 0) ? -1 : 1;
00250 fspr = fb_try - del_gam*k1*sign;
00251 dfsds = kbo;
00252 sP_n1 = sP_n + del_gam*sign;
00253 q_n1 = q_n + del_gam*H*sign;
00254 }
00255
00256
00257 f0(0) = x0(0) - fspr + x0(1)*x0(3);
00258 f0(1) = x0(0)*h - Pe*h*x0(3) + x0(1)*(x0(2)+h*x0(3));
00259 f0(2) = x0(1) - kvo*x0(4);
00260 f0(3) = utpt[0] - x0(2) - h*x0(3);
00261 f0(4) = -utpt[1] - x0(2)*x0(3) - h/2.0*x0(3)*x0(3) - x0(4);
00262
00263 normf0 = f0.Norm();
00264
00265 if (iter > 19) {
00266 opserr << "WARNING! Iso2spring: Newton iteration failed. Norm Resid: " << normf0 << endln;
00267 break;
00268 }
00269 }
00270
00271
00272 double denom = h*dfsds*(Pe - x0(1)) - x0(1)*x0(1);
00273 static Matrix fkin(3,2);
00274 fkin(0,0) = 1.0;
00275 fkin(1,0) = h;
00276 fkin(2,0) = 0.0;
00277 fkin(0,1) = -x0(3);
00278 fkin(1,1) = -(x0(2) + h*x0(3));
00279 fkin(2,1) = -1.0;
00280
00281 static Matrix feq(3,3);
00282 feq(0,0) = (Pe-x0(1))*h/denom;
00283 feq(0,1) = feq(1,0) = x0(1)/denom;
00284 feq(1,1) = dfsds/denom;
00285 feq(0,2) = feq(1,2) = feq(2,0) = feq(2,1) = 0.0;
00286 feq(2,2) = 1.0/kvo;
00287
00288 static Matrix ftot(2,2);
00289 static Matrix ktot(2,2);
00290 ftot.Zero();
00291 ftot.addMatrixTripleProduct(0.0,fkin,feq,1.0);
00292 ftot.Invert(ktot);
00293
00294 ks(0,0) = ktot(0,0);
00295 ks(1,0) = ktot(1,0);
00296 ks(0,1) = ktot(0,1);
00297 ks(1,1) = ktot(1,1);
00298 ks(0,2) = ks(1,2) = ks(2,2) = ks(2,1) = ks(2,0) = 0.0;
00299
00300
00301
00302 s3(0) = x0(0);
00303 s3(1) = -x0(1);
00304 s3(2) = (x0(1)*utpt[0] + x0(0)*h)/2.0;
00305 return s3;
00306 }
00307
00308 const Vector&
00309 Isolator2spring::getSectionDeformation(void)
00310 {
00311
00312 s(0) = utpt[0];
00313 s(1) = utpt[1];
00314
00315 return s;
00316 }
00317
00318 int
00319 Isolator2spring::commitState(void)
00320 {
00321 sP_n = sP_n1;
00322 q_n = q_n1;
00323
00324 return 0;
00325 }
00326
00327 int
00328 Isolator2spring::revertToLastCommit(void)
00329 {
00330 return 0;
00331 }
00332
00333 int
00334 Isolator2spring::revertToStart(void)
00335 {
00336 for (int i = 0; i < 2; i++) {
00337 utpt[i] = 0.0;
00338 }
00339
00340 sP_n = 0.0;
00341 sP_n1 = 0.0;
00342 q_n = 0.0;
00343 q_n1 = 0.0;
00344
00345 x0.Zero();
00346 ks.Zero();
00347
00348 return 0;
00349 }
00350
00351 SectionForceDeformation*
00352 Isolator2spring::getCopy(void)
00353 {
00354 Isolator2spring *theCopy =
00355 new Isolator2spring (this->getTag(), tol, k1, Fyo, kbo, kvo, h, Pe, po);
00356
00357 for (int i = 0; i < 2; i++) {
00358 theCopy->utpt[i] = utpt[i];
00359 }
00360
00361 theCopy->sP_n = sP_n;
00362 theCopy->sP_n1 = sP_n1;
00363 theCopy->q_n = q_n;
00364 theCopy->q_n1 = q_n1;
00365 theCopy->pcr = pcr;
00366 theCopy->H = H;
00367
00368 theCopy->x0 = x0;
00369 theCopy->ks = ks;
00370
00371 return theCopy;
00372 }
00373
00374 const ID&
00375 Isolator2spring::getType(void)
00376 {
00377 return code;
00378 }
00379
00380 int
00381 Isolator2spring::getOrder(void) const
00382 {
00383 return 3;
00384 }
00385
00386 int
00387 Isolator2spring::sendSelf(int cTag, Channel &theChannel)
00388 {
00389 int res = 0;
00390
00391 static Vector data(13);
00392
00393 data(0) = this->getTag();
00394 data(1) = tol;
00395 data(2) = k1;
00396 data(3) = Fyo;
00397 data(4) = kbo;
00398 data(5) = kvo;
00399 data(6) = h;
00400 data(7) = Pe;
00401 data(8) = po;
00402 data(9) = sP_n;
00403 data(10) = q_n;
00404 data(11) = H;
00405 data(12) = pcr;
00406
00407 res = theChannel.sendVector(this->getDbTag(), cTag, data);
00408 if (res < 0)
00409 opserr << "Isolator2spring::sendSelf() - failed to send data\n";
00410 return res;
00411 }
00412
00413 int
00414 Isolator2spring::recvSelf(int cTag, Channel &theChannel,
00415 FEM_ObjectBroker &theBroker)
00416 {
00417 int res = 0;
00418
00419 static Vector data(13);
00420 res = theChannel.recvVector(this->getDbTag(), cTag, data);
00421
00422 if (res < 0) {
00423 opserr << "Isolator2spring::recvSelf() - failed to receive data\n";
00424 this->setTag(0);
00425 }
00426 else {
00427 this->setTag((int)data(0));
00428 tol = data(1);
00429 k1 = data(2);
00430 Fyo = data(3);
00431 kbo = data(4);
00432 kvo = data(5);
00433 h = data(6);
00434 Pe = data(7);
00435 po = data(8);
00436 sP_n = data(9);
00437 q_n = data(10);
00438 H = data(11);
00439 pcr = data(12);
00440
00441
00442 revertToLastCommit();
00443 }
00444
00445 return res;
00446 }
00447
00448 void
00449 Isolator2spring::Print(OPS_Stream &s, int flag)
00450 {
00451
00452 s << "Isolator2spring, tag: " << this->getTag() << endln;
00453 s << "\tol: " << tol << endln;
00454 s << "\tk1: " << k1 << endln;
00455 s << "\tFy: " << Fyo << endln;
00456 s << "\tk2: " << kbo << endln;
00457 s << "\tkv: " << kvo << endln;
00458 s << "\th: " << h << endln;
00459 s << "\tPe: " << Pe << endln;
00460 s << "\tPo: " << po << endln;
00461 }