Bidirectional.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.6 $
00022 // $Date: 2003/02/14 23:01:33 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/material/section/Bidirectional.cpp,v $
00024 
00025 #include <Bidirectional.h>           
00026 #include <Channel.h>
00027 
00028 Vector Bidirectional::s(2);
00029 Matrix Bidirectional::ks(2,2);
00030 ID Bidirectional::code(2);
00031 
00032 Bidirectional::Bidirectional
00033 (int tag, double e, double sy, double Hi, double Hk) :
00034  SectionForceDeformation(tag, SEC_TAG_Bidirectional),
00035          E(e), sigY(sy), Hiso(Hi), Hkin(Hk)
00036 {
00037         for (int i = 0; i < 2; i++) {
00038                 eP_n[i]  = 0.0;
00039                 eP_n1[i] = 0.0;
00040                 q_n[i]  = 0.0;
00041                 q_n1[i] = 0.0;
00042         }
00043 
00044         alpha_n  = 0.0;
00045         alpha_n1 = 0.0;
00046 
00047         code(0) = SECTION_RESPONSE_VY;
00048         code(1) = SECTION_RESPONSE_P;
00049 }
00050 
00051 Bidirectional::Bidirectional():
00052  SectionForceDeformation(0, SEC_TAG_Bidirectional),
00053          E(0.0), sigY(0.0), Hiso(0.0), Hkin(0.0)
00054 {
00055         for (int i = 0; i < 2; i++) {
00056                 eP_n[i]  = 0.0;
00057                 eP_n1[i] = 0.0;
00058                 q_n[i]  = 0.0;
00059                 q_n1[i] = 0.0;
00060         }
00061 
00062         alpha_n  = 0.0;
00063         alpha_n1 = 0.0;
00064 
00065         code(0) = SECTION_RESPONSE_VY;
00066         code(1) = SECTION_RESPONSE_P;
00067 }
00068 
00069 Bidirectional::~Bidirectional()
00070 {
00071         // Nothing to do here
00072 }
00073 
00074 int
00075 Bidirectional::setTrialSectionDeformation(const Vector &e)
00076 {
00077         e_n1[0] = e(0);
00078         e_n1[1] = e(1);
00079 
00080         return 0;
00081 }
00082 
00083 const Matrix&
00084 Bidirectional::getSectionTangent(void)
00085 {
00086         // Compute trial stress using elastic tangent
00087         s(0) = E*(e_n1[0]-eP_n[0]);
00088         s(1) = E*(e_n1[1]-eP_n[1]);
00089 
00090         static Vector xsi(2);
00091 
00092         // Predicted stress minus back stress
00093         xsi(0) = s(0) - q_n[0];
00094         xsi(1) = s(1) - q_n[1];
00095 
00096         double normxsi = xsi.Norm();
00097 
00098         // Current yield stress
00099         double sigY_n = sigY + alpha_n*Hiso;
00100 
00101         // Yield function
00102         double f_n1 = normxsi - sigY_n;
00103 
00104         // Elastic step
00105         if (f_n1 < 0.0) {
00106                 ks(0,0) = ks(1,1) = E;
00107                 ks(0,1) = ks(1,0) = 0.0;
00108         }
00109 
00110         // Plastic step
00111         else {
00112                 // Consistency parameter
00113                 double dlam = f_n1/(E+Hkin+Hiso);
00114 
00115                 double n_n1[2];
00116 
00117                 // Normal vector
00118                 n_n1[0] = xsi(0)/normxsi;
00119                 n_n1[1] = xsi(1)/normxsi;
00120 
00121                 double A = E*(E/(Hiso+Hkin+E));
00122                 double B = E*(E*dlam/normxsi);
00123 
00124                 //ks(0,0) = E - A*n_n1[0]*n_n1[0] - B*(1.0 - n_n1[0]*n_n1[0]);
00125                 //ks(1,1) = E - A*n_n1[1]*n_n1[1] - B*(1.0 - n_n1[1]*n_n1[1]);
00126                 //ks(0,1) = -A*n_n1[0]*n_n1[1] - B*(-n_n1[0]*n_n1[1]);
00127                 //ks(1,0) = ks(0,1);
00128 
00129                 double EB = E-B;
00130                 double BA = B-A;
00131 
00132                 ks(0,0) = EB + BA*n_n1[0]*n_n1[0];
00133                 ks(1,1) = EB + BA*n_n1[1]*n_n1[1];
00134                 ks(0,1) = BA*n_n1[0]*n_n1[1];
00135                 ks(1,0) = ks(0,1);
00136 
00137                 //n_n1[0] *= dlam;
00138                 //n_n1[1] *= dlam;
00139 
00140                 // Update plastic strains
00141                 //eP_n1[0] = eP_n[0] + n_n1[0];
00142                 //eP_n1[1] = eP_n[1] + n_n1[1];
00143 
00144                 // Update back stress
00145                 //q_n1[0] = q_n[0] + Hkin*n_n1[0];
00146                 //q_n1[1] = q_n[1] + Hkin*n_n1[1];
00147 
00148                 // Update effective plastic strain
00149                 //alpha_n1 = alpha_n + dlam;
00150         }
00151 
00152         return ks;
00153 }
00154 
00155 const Matrix&
00156 Bidirectional::getInitialTangent(void)
00157 {
00158   ks(0,0) = ks(1,1) = E;
00159   ks(0,1) = ks(1,0) = 0.0;
00160 
00161   return ks;
00162 }
00163 
00164 const Vector&
00165 Bidirectional::getStressResultant(void)
00166 {
00167         // Compute trial stress using elastic tangent
00168         s(0) = E*(e_n1[0]-eP_n[0]);
00169         s(1) = E*(e_n1[1]-eP_n[1]);
00170 
00171         static Vector xsi(2);
00172 
00173         // Predicted stress minus back stress
00174         xsi(0) = s(0) - q_n[0];
00175         xsi(1) = s(1) - q_n[1];
00176 
00177         double normxsi = xsi.Norm();
00178 
00179         // Current yield stress
00180         double sigY_n = sigY + alpha_n*Hiso;
00181 
00182         // Yield function
00183         double f_n1 = normxsi - sigY_n;
00184 
00185         // Elastic step
00186         if (f_n1 < 0.0) {
00187                 // do nothing
00188         }
00189 
00190         // Plastic step
00191         else {
00192                 // Consistency parameter
00193                 double dlam = f_n1/(E+Hkin+Hiso);
00194 
00195                 double n_n1[2];
00196 
00197                 // Normal vector
00198                 n_n1[0] = xsi(0)/normxsi;
00199                 n_n1[1] = xsi(1)/normxsi;
00200 
00201                 n_n1[0] *= dlam;
00202                 n_n1[1] *= dlam;
00203 
00204                 // Return stresses to yield surface
00205                 s(0) -= E*n_n1[0];
00206                 s(1) -= E*n_n1[1];
00207 
00208                 // Update plastic strains
00209                 eP_n1[0] = eP_n[0] + n_n1[0];
00210                 eP_n1[1] = eP_n[1] + n_n1[1];
00211 
00212                 // Update back stress
00213                 q_n1[0] = q_n[0] + Hkin*n_n1[0];
00214                 q_n1[1] = q_n[1] + Hkin*n_n1[1];
00215 
00216                 // Update effective plastic strain
00217                 alpha_n1 = alpha_n + dlam;
00218         }
00219 
00220         return s;
00221 }
00222 
00223 const Vector&
00224 Bidirectional::getSectionDeformation(void)
00225 {
00226         // Write to static variable for return
00227         s(0) = e_n1[0];
00228         s(1) = e_n1[1];
00229 
00230         return s;
00231 }
00232 
00233 int
00234 Bidirectional::commitState(void)
00235 {
00236         eP_n[0] = eP_n1[0];
00237         eP_n[1] = eP_n1[1];
00238 
00239         q_n[0] = q_n1[0];
00240         q_n[1] = q_n1[1];
00241 
00242         alpha_n = alpha_n1;
00243 
00244         return 0;
00245 }
00246 
00247 int
00248 Bidirectional::revertToLastCommit(void)
00249 {
00250         return 0;
00251 }
00252 
00253 int
00254 Bidirectional::revertToStart(void)
00255 {
00256         for (int i = 0; i < 2; i++) {
00257                 eP_n[i]  = 0.0;
00258                 eP_n1[i] = 0.0;
00259                 q_n[i]  = 0.0;
00260                 q_n1[i] = 0.0;
00261         }
00262 
00263         alpha_n  = 0.0;
00264         alpha_n1 = 0.0;
00265 
00266         return 0;
00267 }
00268 
00269 SectionForceDeformation*
00270 Bidirectional::getCopy(void)
00271 {
00272         Bidirectional *theCopy =
00273                 new Bidirectional (this->getTag(), E, sigY, Hiso, Hkin);
00274 
00275         for (int i = 0; i < 2; i++) {
00276                 theCopy->eP_n[i]  = eP_n[i];
00277                 theCopy->eP_n1[i] = eP_n1[i];
00278                 theCopy->q_n[i]  = q_n[i];
00279                 theCopy->q_n1[i] = q_n1[i];
00280         }
00281 
00282         theCopy->alpha_n  = alpha_n;
00283         theCopy->alpha_n1 = alpha_n1;
00284 
00285         return theCopy;
00286 }
00287 
00288 const ID&
00289 Bidirectional::getType(void)
00290 {
00291         return code;
00292 }
00293 
00294 int
00295 Bidirectional::getOrder(void) const
00296 {
00297         return 2;
00298 }
00299 
00300 int 
00301 Bidirectional::sendSelf(int cTag, Channel &theChannel)
00302 {
00303   int res = 0;
00304   
00305   static Vector data(10);
00306   
00307   data(0) = this->getTag();
00308   data(1) = E;
00309   data(2) = sigY;
00310   data(3) = Hiso;
00311   data(4) = Hkin;
00312   data(5) = eP_n[0];
00313   data(6) = eP_n[1];
00314   data(7) = q_n[0];
00315   data(8) = q_n[1];
00316   data(9) = alpha_n;
00317 
00318   res = theChannel.sendVector(this->getDbTag(), cTag, data);
00319   if (res < 0) 
00320     opserr << "Bidirectional::sendSelf() - failed to send data\n";
00321 
00322   return res;
00323 }
00324 
00325 int 
00326 Bidirectional::recvSelf(int cTag, Channel &theChannel, 
00327                                FEM_ObjectBroker &theBroker)
00328 {
00329   int res = 0;
00330   
00331   static Vector data(10);
00332   res = theChannel.recvVector(this->getDbTag(), cTag, data);
00333   
00334   if (res < 0) {
00335       opserr << "Bidirectional::recvSelf() - failed to receive data\n";
00336       E = 0; 
00337       this->setTag(0);      
00338   }
00339   else {
00340     this->setTag((int)data(0));
00341         E = data(1);
00342         sigY = data(2);
00343         Hiso = data(3);
00344         Hkin = data(4);
00345         eP_n[0] = data(5);
00346         eP_n[1] = data(6);
00347         q_n[0]  = data(7);
00348         q_n[1]  = data(8);
00349         alpha_n = data(9);
00350 
00351     // Set the trial state variables
00352     revertToLastCommit();
00353   }
00354     
00355   return res;
00356 }
00357 
00358 void
00359 Bidirectional::Print(OPS_Stream &s, int flag)
00360 {
00361         s << "Bidirectional, tag: " << this->getTag() << endln;
00362         s << "\tE:    " << E << endln;
00363         s << "\tsigY: " << sigY<< endln;
00364         s << "\tHiso: " << Hiso << endln;
00365         s << "\tHkin: " << Hkin << endln;
00366 }

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