Isolator2spring.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.1 $
00022 // $Date: 2006/01/17 20:44:32 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/material/section/Isolator2spring.cpp,v $
00024 
00025 // Written: K. Ryan
00026 // Created: September 2003
00027 // Updates: November 2005
00028 //
00029 // Description: This file contains the class implementation for a "two-spring isolator" 
00030 // material.  This material is based on the two-spring model originally developed by 
00031 // Koh and Kelly to represent the buckling behavior of an elastomeric bearing.  The 
00032 // material model has been modified to include material nonlinearity and optional 
00033 // strength degradation.
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         // Nothing to do here
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         // ks is computed in getStressResultant 
00097         return ks;
00098 }
00099 
00100 const Matrix&
00101 Isolator2spring::getInitialTangent(void)
00102 {
00103         // Intial tangent uses nominal properties of the isolator.  
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           // No strength degradation
00119           Fy = Fyo;
00120         } else {
00121           // Strength degradation based on bearing axial load
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         // Material stresses using rate independent plasticity, return mapping algorithm
00131 
00132         // Compute trial stress using elastic tangent
00133         double fb_try = k1*(x0(2)-sP_n);
00134         double xi_try = fb_try - q_n;
00135 
00136         // Yield function
00137         double Phi_try = fabs(xi_try) - Fy;
00138 
00139         double fspr;
00140         double dfsds;
00141         double del_gam;
00142         int sign;
00143 
00144         // Elastic step
00145         if (Phi_try <= 0.0) {
00146                 
00147                 // Stress and tangent, update plastic deformation and back stress
00148                 fspr = fb_try;
00149                 dfsds = k1;
00150                 sP_n1 = sP_n;
00151                 q_n1 = q_n;
00152         }
00153 
00154         // Plastic step
00155         else {
00156                 // Consistency parameter
00157                 del_gam = Phi_try/(k1+H);
00158 
00159                 sign = (xi_try < 0) ? -1 : 1;
00160                 // Return stress to yield surface
00161                 fspr = fb_try - del_gam*k1*sign;
00162                 dfsds = kbo;
00163                 // Update plastic deformation and back stress
00164                 sP_n1 = sP_n + del_gam*sign;
00165                 q_n1 = q_n + del_gam*H*sign;
00166         }
00167 
00168         // Nonlinear equilibrium and kinematic equations; want to find the 
00169         // zeros of these equations.
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         // Solve nonlinear equations using Newton's method
00181         while (normf0 > tol) {
00182 
00183                 iter += 1;
00184                 
00185                 // Formulate Jacobian of nonlinear equations
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                 // Compute improved estimate of solution x0
00218                 x0 -= dfinverse*f0;
00219         
00220                 
00221                 if (po > 1.0e-10) { // Update strength according to axial load
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                 // Apply plasticity theory again, return mapping algorithm 
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                 // Elastic step
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                 // Plastic step
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                 // Estimate the residual
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         // Compute stiffness matrix by three step process
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         // Compute force vector
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         // Write to static variable for return
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           // Set the trial state variables
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 }

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