MembranePlateFiberSection.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:34 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/material/section/MembranePlateFiberSection.cpp,v $
00024 
00025 // Ed "C++" Love
00026 //
00027 //  Generic Plate Section with membrane
00028 //
00029 
00030 
00031 #include <MembranePlateFiberSection.h>
00032 #include <Channel.h>
00033 #include <FEM_ObjectBroker.h>
00034 
00035 
00036 //parameters
00037 const double MembranePlateFiberSection::root56 = sqrt(5.0/6.0) ; //shear correction
00038 
00039 //static vector and matrices
00040 Vector  MembranePlateFiberSection::stressResultant(8) ;
00041 Matrix  MembranePlateFiberSection::tangent(8,8) ;
00042 ID      MembranePlateFiberSection::array(8) ;
00043 
00044 
00045 const double  MembranePlateFiberSection::sg[] = { -1, 
00046                                                   -0.65465367, 
00047                                                    0, 
00048                                                    0.65465367, 
00049                                                    1 } ;
00050  
00051 const double  MembranePlateFiberSection::wg[] = { 0.1, 
00052                                                   0.5444444444, 
00053                                                   0.7111111111, 
00054                                                   0.5444444444, 
00055                                                   0.1  };
00056 
00057 /*      from Ham-O
00058         case 5:
00059          xi(0,0) = -1.;
00060          xi(1,0) = -0.65465367;
00061          xi(2,0) =  0.;
00062          xi(3,0) =  0.65465367;
00063          xi(4,0) =  1.;
00064       
00065          w(0) =  0.1;
00066          w(1) =  0.5444444444;
00067          w(2) =  0.7111111111;
00068          w(3) =  0.5444444444;
00069          w(4) =  0.1;
00070       break;
00071 */
00072 
00073 
00074 //null constructor
00075 MembranePlateFiberSection::MembranePlateFiberSection( ) : 
00076 SectionForceDeformation( 0, SEC_TAG_MembranePlateFiberSection ), 
00077 strainResultant(8) 
00078 { 
00079   for ( int i = 0; i < 5; i++ )
00080       theFibers[i] = 0 ;
00081 }
00082 
00083 
00084 
00085 //full constructor
00086 MembranePlateFiberSection::MembranePlateFiberSection(    
00087                                    int tag, 
00088                                    double thickness, 
00089                                    NDMaterial &Afiber ) :
00090 SectionForceDeformation( tag, SEC_TAG_MembranePlateFiberSection ),
00091 strainResultant(8)
00092 {
00093   this->h  = thickness ;
00094 
00095   int i ;
00096   for ( i = 0; i < 5; i++ )
00097       theFibers[i] = Afiber.getCopy( "PlateFiber" ) ;
00098 
00099 }
00100 
00101 
00102 
00103 //destructor
00104 MembranePlateFiberSection::~MembranePlateFiberSection( ) 
00105 { 
00106   int i ;
00107   for ( i = 0; i < 5; i++ )
00108      delete theFibers[i] ; 
00109 } 
00110 
00111 
00112 
00113 //make a clone of this material
00114 SectionForceDeformation  *MembranePlateFiberSection::getCopy( ) 
00115 {
00116   MembranePlateFiberSection *clone ;   //new instance of this class
00117 
00118   clone = new MembranePlateFiberSection( this->getTag(), 
00119                                          this->h,
00120                                          *theFibers[0] ) ; //make the copy
00121   return clone ;
00122 }
00123 
00124 
00125 
00126 //send back order of strainResultant in vector form
00127 int MembranePlateFiberSection::getOrder( ) const
00128 {
00129   return 8 ;
00130 }
00131 
00132 
00133 //send back order of strainResultant in vector form
00134 const ID& MembranePlateFiberSection::getType( ) 
00135 {
00136   return array ;
00137 }
00138 
00139 
00140 
00141 //swap history variables
00142 int MembranePlateFiberSection::commitState( ) 
00143 {
00144   int success = 0 ;
00145 
00146   int i ;
00147   for ( i = 0; i < 5; i++ )
00148     success += theFibers[i]->commitState( ) ;
00149 
00150   return success ;
00151 }
00152 
00153 
00154 
00155 //revert to last saved state
00156 int MembranePlateFiberSection::revertToLastCommit( )
00157 {
00158   int success = 0 ;
00159 
00160   int i ;
00161   for ( i = 0; i < 5; i++ )
00162     success += theFibers[i]->revertToLastCommit( ) ;
00163 
00164   return success ;
00165 }
00166 
00167 //revert to start
00168 int MembranePlateFiberSection::revertToStart( )
00169 {
00170   int success = 0 ;
00171 
00172   int i ;
00173   for ( i = 0; i < 5; i++ )
00174     success += theFibers[i]->revertToStart( ) ;
00175 
00176   return success ;
00177 }
00178 
00179 
00180 //mass per unit area
00181 double
00182 MembranePlateFiberSection::getRho( )
00183 {
00184 
00185   double weight ;
00186 
00187   double rhoH = 0.0 ;
00188 
00189   for ( int i = 0; i < 5; i++ ) {
00190     
00191     weight = ( 0.5*h ) * wg[i] ;
00192 
00193     rhoH += ( theFibers[i]->getRho() ) * weight ;
00194 
00195   }
00196 
00197   return rhoH ;
00198 
00199 }
00200 
00201 
00202 //receive the strainResultant 
00203 int MembranePlateFiberSection ::
00204 setTrialSectionDeformation( const Vector &strainResultant_from_element)
00205 {
00206   this->strainResultant = strainResultant_from_element ;
00207 
00208   static Vector strain(5) ;
00209 
00210   int success = 0 ;
00211 
00212   int i ;
00213 
00214   double z ;
00215 
00216   for ( i = 0; i < 5; i++ ) {
00217 
00218       z = ( 0.5*h ) * sg[i] ;
00219   
00220       strain(0) =  strainResultant(0)  - z*strainResultant(3) ;
00221 
00222       strain(1) =  strainResultant(1)  - z*strainResultant(4) ;
00223 
00224       strain(2) =  strainResultant(2)  - z*strainResultant(5) ;
00225 
00226       strain(3) =  root56*strainResultant(6) ;
00227 
00228       strain(4) =  root56*strainResultant(7) ;
00229   
00230       success += theFibers[i]->setTrialStrain( strain ) ;
00231 
00232   } //end for i
00233 
00234   return success ;
00235 }
00236 
00237 
00238 //send back the strainResultant
00239 const Vector& MembranePlateFiberSection::getSectionDeformation( )
00240 {
00241   return this->strainResultant ;
00242 }
00243 
00244 
00245 //send back the stressResultant 
00246 const Vector&  MembranePlateFiberSection::getStressResultant( )
00247 {
00248 
00249   static Vector stress(5) ;
00250 
00251   int i ;
00252 
00253   double z, weight ;
00254 
00255   stressResultant.Zero( ) ;
00256 
00257   for ( i = 0; i < 5; i++ ) {
00258 
00259       z = ( 0.5*h ) * sg[i] ;
00260 
00261       weight = ( 0.5*h ) * wg[i] ;
00262 
00263       stress = theFibers[i]->getStress( ) ;
00264   
00265       //membrane
00266       stressResultant(0)  +=  stress(0)*weight ;
00267 
00268       stressResultant(1)  +=  stress(1)*weight ;
00269 
00270       stressResultant(2)  +=  stress(2)*weight ;
00271 
00272       //bending moments
00273       stressResultant(3)  +=  ( z*stress(0) ) * weight ;
00274 
00275       stressResultant(4)  +=  ( z*stress(1) ) * weight ;
00276 
00277       stressResultant(5)  +=  ( z*stress(2) ) * weight ;
00278 
00279       //shear
00280       stressResultant(6)  += stress(3)*weight ;
00281 
00282       stressResultant(7)  += stress(4)*weight ;
00283   
00284   } //end for i
00285 
00286    //modify shear 
00287    stressResultant(6) *= root56 ;  
00288    stressResultant(7) *= root56 ;
00289 
00290    return this->stressResultant ;
00291 }
00292 
00293 
00294 //send back the tangent 
00295 const Matrix&  MembranePlateFiberSection::getSectionTangent( )
00296 {
00297   static Matrix dd(5,5) ;
00298 
00299   static Matrix Aeps(5,8) ;
00300 
00301   static Matrix Asig(8,5) ;
00302 
00303   int i ;
00304 
00305   double z, weight ;
00306 
00307   tangent.Zero( ) ;
00308 
00309   for ( i = 0; i < 5; i++ ) {
00310 
00311       z = ( 0.5*h ) * sg[i] ;
00312 
00313       weight = (0.5*h) * wg[i] ;
00314 
00315 /*      //compute Aeps
00316 
00317       Aeps.Zero( ) ;
00318 
00319       Aeps(0,0) = 1.0 ;
00320       Aeps(0,3) = -z ;
00321 
00322       Aeps(1,1) = 1.0 ;
00323       Aeps(1,4) = -z ;
00324 
00325       Aeps(2,2) = 1.0 ;
00326       Aeps(2,5) = -z ;
00327 
00328       Aeps(3,6) = root56 ;
00329       Aeps(4,7) = root56 ;
00330 
00331       //compute Asig
00332 
00333       Asig.Zero( ) ;
00334 
00335       Asig(0,0) = 1.0 ;
00336       Asig(3,0) = z ;
00337 
00338       Asig(1,1) = 1.0 ;
00339       Asig(4,1) = z ;
00340 
00341       Asig(2,2) = 1.0 ;
00342       Asig(5,2) = z ;
00343 
00344       Asig(6,3) = root56 ;
00345       Asig(7,4) = root56 ;
00346 */
00347 
00348       //compute the tangent
00349 
00350       dd = theFibers[i]->getTangent( ) ;
00351 
00352       dd *= weight ;
00353 
00354       //tangent +=  ( Asig * dd * Aeps ) ;   
00355 
00356 //from MATLAB : tangent = 
00357 //[      d11,           d12,           d13,        -z*d11,        -z*d12,        -z*d13,    d14*root56,    d15*root56]
00358 //[      d21,           d22,           d23,        -z*d21,        -z*d22,        -z*d23,    d24*root56,    d25*root56]
00359 //[      d31,           d32,           d33,        -z*d31,        -z*d32,        -z*d33,    d34*root56,    d35*root56]
00360 //[     z*d11,         z*d12,         z*d13,      -z^2*d11,      -z^2*d12,      -z^2*d13,  z*d14*root56,  z*d15*root56]
00361 //[     z*d21,         z*d22,         z*d23,      -z^2*d21,      -z^2*d22,      -z^2*d23,  z*d24*root56,  z*d25*root56]
00362 //[     z*d31,         z*d32,         z*d33,      -z^2*d31,      -z^2*d32,      -z^2*d33,  z*d34*root56,  z*d35*root56]
00363 //[  root56*d41,    root56*d42,    root56*d43, -root56*d41*z, -root56*d42*z, -root56*d43*z,  root56^2*d44,  root56^2*d45]
00364 //[  root56*d51,    root56*d52,    root56*d53, -root56*d51*z, -root56*d52*z, -root56*d53*z,  root56^2*d54,  root56^2*d55]
00365  
00366       //row 1
00367 //[      d11,           d12,           d13,        -z*d11,        -z*d12,        -z*d13,    d14*root56,    d15*root56]
00368       tangent(0,0) +=  dd(0,0) ;
00369       tangent(0,1) +=  dd(0,1) ;
00370       tangent(0,2) +=  dd(0,2) ;      
00371       tangent(0,3) +=  -z*dd(0,0) ;      
00372       tangent(0,3) +=  -z*dd(0,1) ;
00373       tangent(0,5) +=  -z*dd(0,2) ;
00374       tangent(0,6) +=  root56*dd(0,3) ;
00375       tangent(0,7) +=  root56*dd(0,4) ;
00376 
00377       //row 2
00378 //[      d21,           d22,           d23,        -z*d21,        -z*d22,        -z*d23,    d24*root56,    d25*root56]
00379       tangent(1,0) +=  dd(1,0) ;
00380       tangent(1,1) +=  dd(1,1) ;
00381       tangent(1,2) +=  dd(1,2) ;      
00382       tangent(1,3) +=  -z*dd(1,0) ;      
00383       tangent(1,4) +=  -z*dd(1,1) ;
00384       tangent(1,5) +=  -z*dd(1,2) ;
00385       tangent(1,6) +=  root56*dd(1,3) ;
00386       tangent(1,7) +=  root56*dd(1,4) ;
00387 
00388       //row 3
00389 //[      d31,           d32,           d33,        -z*d31,        -z*d32,        -z*d33,    d34*root56,    d35*root56]
00390       tangent(2,0) +=  dd(2,0) ;
00391       tangent(2,1) +=  dd(2,1) ;
00392       tangent(2,2) +=  dd(2,2) ;      
00393       tangent(2,3) +=  -z*dd(2,0) ;      
00394       tangent(2,4) +=  -z*dd(2,1) ;
00395       tangent(2,5) +=  -z*dd(2,2) ;
00396       tangent(2,6) +=  root56*dd(2,3) ;
00397       tangent(2,7) +=  root56*dd(2,4) ;
00398 
00399       //row 4
00400 //[     z*d11,         z*d12,         z*d13,      -z^2*d11,      -z^2*d12,      -z^2*d13,  z*d14*root56,  z*d15*root56]
00401       tangent(3,0) +=  z*dd(0,0) ;
00402       tangent(3,1) +=  z*dd(0,1) ;
00403       tangent(3,2) +=  z*dd(0,2) ;      
00404       tangent(3,3) +=  -z*z*dd(0,0) ;      
00405       tangent(3,4) +=  -z*z*dd(0,1) ;
00406       tangent(3,5) +=  -z*z*dd(0,2) ;
00407       tangent(3,6) +=  z*root56*dd(0,3) ;
00408       tangent(3,7) +=  z*root56*dd(0,4) ;
00409 
00410       //row 5
00411 //[     z*d21,         z*d22,         z*d23,      -z^2*d21,      -z^2*d22,      -z^2*d23,  z*d24*root56,  z*d25*root56]
00412       tangent(4,0) +=  z*dd(1,0) ;
00413       tangent(4,1) +=  z*dd(1,1) ;
00414       tangent(4,2) +=  z*dd(1,2) ;      
00415       tangent(4,3) +=  -z*z*dd(1,0) ;      
00416       tangent(4,4) +=  -z*z*dd(1,1) ;
00417       tangent(4,5) +=  -z*z*dd(1,2) ;
00418       tangent(4,6) +=  z*root56*dd(1,3) ;
00419       tangent(4,7) +=  z*root56*dd(1,4) ;
00420 
00421       //row 6
00422 //[     z*d31,         z*d32,         z*d33,      -z^2*d31,      -z^2*d32,      -z^2*d33,  z*d34*root56,  z*d35*root56]
00423       tangent(5,0) +=  z*dd(2,0) ;
00424       tangent(5,1) +=  z*dd(2,1) ;
00425       tangent(5,2) +=  z*dd(2,2) ;      
00426       tangent(5,3) +=  -z*z*dd(2,0) ;      
00427       tangent(5,4) +=  -z*z*dd(2,1) ;
00428       tangent(5,5) +=  -z*z*dd(2,2) ;
00429       tangent(5,6) +=  z*root56*dd(2,3) ;
00430       tangent(5,7) +=  z*root56*dd(2,4) ;
00431 
00432       //row 7
00433 //[  root56*d41,    root56*d42,    root56*d43, -root56*d41*z, -root56*d42*z, -root56*d43*z,  root56^2*d44,  root56^2*d45]
00434       tangent(6,0) +=  root56*dd(3,0) ;
00435       tangent(6,1) +=  root56*dd(3,1) ;
00436       tangent(6,2) +=  root56*dd(3,2) ;      
00437       tangent(6,3) +=  -root56*z*dd(3,0) ;      
00438       tangent(6,4) +=  -root56*z*dd(3,1) ;
00439       tangent(6,5) +=  -root56*z*dd(3,2) ;
00440       tangent(6,6) +=  root56*root56*dd(3,3) ;
00441       tangent(6,7) +=  root56*root56*dd(3,4) ;
00442 
00443       //row 8 
00444 //[  root56*d51,    root56*d52,    root56*d53, -root56*d51*z, -root56*d52*z, -root56*d53*z,  root56^2*d54,  root56^2*d55]
00445       tangent(7,0) +=  root56*dd(4,0) ;
00446       tangent(7,1) +=  root56*dd(4,1) ;
00447       tangent(7,2) +=  root56*dd(4,2) ;      
00448       tangent(7,3) +=  -root56*z*dd(4,0) ;      
00449       tangent(7,4) +=  -root56*z*dd(4,1) ;
00450       tangent(7,5) +=  -root56*z*dd(4,2) ;
00451       tangent(7,6) +=  root56*root56*dd(4,3) ;
00452       tangent(7,7) +=  root56*root56*dd(4,4) ;
00453 
00454   } //end for i
00455 
00456   return this->tangent ;
00457 }
00458 
00459 
00460 //print out data
00461 void  MembranePlateFiberSection::Print( OPS_Stream &s, int flag )
00462 {
00463   s << "MembranePlateFiberSection: \n " ;
00464   s <<  "  Thickness h = "        <<  h  <<  endln ;
00465 
00466   theFibers[0]->Print( s, flag ) ;
00467 
00468   return ;
00469 }
00470 
00471 int 
00472 MembranePlateFiberSection::sendSelf(int commitTag, Channel &theChannel) 
00473 {
00474   int res = 0;
00475 
00476   // note: we don't check for dataTag == 0 for Element
00477   // objects as that is taken care of in a commit by the Domain
00478   // object - don't want to have to do the check if sending data
00479   int dataTag = this->getDbTag();
00480   
00481 
00482   // Now quad sends the ids of its materials
00483   int matDbTag;
00484   
00485   static ID idData(11);
00486   
00487   int i;
00488   for (i = 0; i < 5; i++) {
00489     idData(i) = theFibers[i]->getClassTag();
00490     matDbTag = theFibers[i]->getDbTag();
00491     // NOTE: we do have to ensure that the material has a database
00492     // tag if we are sending to a database channel.
00493     if (matDbTag == 0) {
00494       matDbTag = theChannel.getDbTag();
00495                         if (matDbTag != 0)
00496                           theFibers[i]->setDbTag(matDbTag);
00497     }
00498     idData(i+5) = matDbTag;
00499   }
00500   
00501   idData(10) = this->getTag();
00502 
00503   res += theChannel.sendID(dataTag, commitTag, idData);
00504   if (res < 0) {
00505     opserr << "WARNING MembranePlateFiberSection::sendSelf() - " << this->getTag() << " failed to send ID\n";
00506                             
00507     return res;
00508   }
00509 
00510   // Finally, quad asks its material objects to send themselves
00511   for (i = 0; i < 5; i++) {
00512     res += theFibers[i]->sendSelf(commitTag, theChannel);
00513     if (res < 0) {
00514       opserr << "WARNING MembranePlateFiberSection::sendSelf() - " << this->getTag() << " failed to send its Material\n";
00515       return res;
00516     }
00517   }
00518   
00519   return res;
00520 }
00521 
00522 
00523 int 
00524 MembranePlateFiberSection::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00525 {
00526   int res = 0;
00527   
00528   int dataTag = this->getDbTag();
00529 
00530   static ID idData(11);
00531   // Quad now receives the tags of its four external nodes
00532   res += theChannel.recvID(dataTag, commitTag, idData);
00533   if (res < 0) {
00534     opserr << "WARNING MembranePlateFiberSection::recvSelf() - " << this->getTag() << " failed to receive ID\n";
00535     return res;
00536   }
00537 
00538   this->setTag(idData(11));
00539 
00540   int i;
00541 
00542   if (theFibers[0] == 0) {
00543     for (i = 0; i < 5; i++) {
00544       int matClassTag = idData(i);
00545       int matDbTag = idData(i+5);
00546       // Allocate new material with the sent class tag
00547       theFibers[i] = theBroker.getNewNDMaterial(matClassTag);
00548       if (theFibers[i] == 0) {
00549         opserr << "MembranePlateFiberSection::recvSelf() - " <<
00550           "Broker could not create NDMaterial of class type " << matClassTag << endln;
00551         return -1;
00552       }
00553       // Now receive materials into the newly allocated space
00554       theFibers[i]->setDbTag(matDbTag);
00555       res += theFibers[i]->recvSelf(commitTag, theChannel, theBroker);
00556       if (res < 0) {
00557         opserr << "NLBeamColumn3d::recvSelf() - material " << 
00558           i << "failed to recv itself\n";
00559         return res;
00560       }
00561     }
00562   }
00563   // Number of materials is the same, receive materials into current space
00564   else {
00565     for (i = 0; i < 5; i++) {
00566       int matClassTag = idData(i);
00567       int matDbTag = idData(i+5);
00568       // Check that material is of the right type; if not,
00569       // delete it and create a new one of the right type
00570       if (theFibers[i]->getClassTag() != matClassTag) {
00571         delete theFibers[i];
00572         theFibers[i] = theBroker.getNewNDMaterial(matClassTag);
00573         if (theFibers[i] == 0) {
00574           opserr << "MembranePlateFiberSection::recvSelf() - " << 
00575             "Broker could not create NDMaterial of class type" << matClassTag << endln;
00576           exit(-1);
00577         }
00578       }
00579       // Receive the material
00580       theFibers[i]->setDbTag(matDbTag);
00581       res += theFibers[i]->recvSelf(commitTag, theChannel, theBroker);
00582       if (res < 0) {
00583         opserr << "MembranePlateFiberSection::recvSelf() - material " << 
00584           i << ", failed to recv itself\n";
00585         return res;
00586       }
00587     }
00588   }
00589   
00590   return res;
00591 }
00592  
00593 
00594 

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