TotalLagrangianFD20NodeBrick.cpp

Go to the documentation of this file.
00001 //===============================================================================
00002 //# COPYRIGHT (C): Woody's license (by BJ):
00003 //                 ``This    source  code is Copyrighted in
00004 //                 U.S.,  for  an  indefinite  period,  and anybody
00005 //                 caught  using it without our permission, will be
00006 //                 mighty good friends of ourn, cause we don't give
00007 //                 a  darn.  Hack it. Compile it. Debug it. Run it.
00008 //                 Yodel  it.  Enjoy it. We wrote it, that's all we
00009 //                 wanted to do.''
00010 //
00011 //# PROJECT:           Object Oriented Finite Element Program
00012 //# PURPOSE:           Finite Deformation Hyper-Elastic classes
00013 //# CLASS:
00014 //#
00015 //# VERSION:           0.6_(1803398874989) (golden section)
00016 //# LANGUAGE:          C++
00017 //# TARGET OS:         all...
00018 //# DESIGN:            Zhao Cheng, Boris Jeremic (jeremic@ucdavis.edu)
00019 //# PROGRAMMER(S):     Zhao Cheng, Boris Jeremic
00020 //#
00021 //#
00022 //# DATE:              Sept2003
00023 //# UPDATE HISTORY:    28May2004, Zhao put all Ks & Rs in the integration cycle and
00024 //#                          and use minor symmetries to make concise and efficient
00025 //#                    April2005 Zhao adds new output options
00026 //#                    Sept2005  Zhao shortens the codes
00027 //===============================================================================
00028 #ifndef TOTALLAGRANGIANFD20NODEBRICK_CPP
00029 #define TOTALLAGRANGIANFD20NODEBRICK_CPP
00030 
00031 #include <TotalLagrangianFD20NodeBrick.h>
00032 
00033 const int TotalLagrangianFD20NodeBrick::NumIntegrationPts = 3;
00034 const int TotalLagrangianFD20NodeBrick::NumTotalGaussPts = 27;
00035 const int TotalLagrangianFD20NodeBrick::NumNodes = 20;
00036 const int TotalLagrangianFD20NodeBrick::NumDof = 3;
00037 const int TotalLagrangianFD20NodeBrick::NumElemDof = NumNodes*NumDof;
00038 
00039 Matrix TotalLagrangianFD20NodeBrick::K(NumElemDof, NumElemDof);
00040 Matrix TotalLagrangianFD20NodeBrick::M(NumElemDof, NumElemDof);
00041 Vector TotalLagrangianFD20NodeBrick::P(NumElemDof);
00042 const double TotalLagrangianFD20NodeBrick::pts[3] = {-0.774596669241483, 0.0, +0.774596669241483};
00043 const double TotalLagrangianFD20NodeBrick::wts[3] = {+0.55555555555555556, +0.88888888888888889, +0.55555555555555556};
00044 
00045 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00046 
00047 TotalLagrangianFD20NodeBrick::TotalLagrangianFD20NodeBrick(int tag,
00048 int node_numb_1,  int node_numb_2,  int node_numb_3,  int node_numb_4,
00049 int node_numb_5,  int node_numb_6,  int node_numb_7,  int node_numb_8,
00050 int node_numb_9,  int node_numb_10, int node_numb_11, int node_numb_12,
00051 int node_numb_13, int node_numb_14, int node_numb_15, int node_numb_16,
00052 int node_numb_17, int node_numb_18, int node_numb_19, int node_numb_20,
00053 NDMaterial &m, double b1, double b2, double b3)
00054 :Element(tag, ELE_TAG_TotalLagrangianFD20NodeBrick ),
00055  theMaterial(0), connectedExternalNodes(NumNodes), Q(0), bf(NumDof), Ki(0)
00056 {
00057       connectedExternalNodes( 0) = node_numb_1;
00058       connectedExternalNodes( 1) = node_numb_2;
00059       connectedExternalNodes( 2) = node_numb_3;
00060       connectedExternalNodes( 3) = node_numb_4;
00061       connectedExternalNodes( 4) = node_numb_5;
00062       connectedExternalNodes( 5) = node_numb_6;
00063       connectedExternalNodes( 6) = node_numb_7;
00064       connectedExternalNodes( 7) = node_numb_8;
00065       connectedExternalNodes( 8) = node_numb_9;
00066       connectedExternalNodes( 9) = node_numb_10;
00067       connectedExternalNodes(10) = node_numb_11;
00068       connectedExternalNodes(11) = node_numb_12;
00069       connectedExternalNodes(12) = node_numb_13;
00070       connectedExternalNodes(13) = node_numb_14;
00071       connectedExternalNodes(14) = node_numb_15;
00072       connectedExternalNodes(15) = node_numb_16;
00073       connectedExternalNodes(16) = node_numb_17;
00074       connectedExternalNodes(17) = node_numb_18;
00075       connectedExternalNodes(18) = node_numb_19;
00076       connectedExternalNodes(19) = node_numb_20;
00077 
00078       bf(0) = b1;
00079       bf(1) = b2;
00080       bf(2) = b3;
00081 
00082       theMaterial = new NDMaterial *[NumTotalGaussPts];
00083 
00084       if (theMaterial == 0) {
00085        opserr<<"FiniteDeformationElastic3D::FiniteDeformationElastic3D -- failed allocate material model pointer\n";
00086        exit(-1);
00087       }
00088       
00089       int i;
00090       for (i=0; i<NumTotalGaussPts; i++) {
00091        theMaterial[i] = m.getCopy();
00092        if (theMaterial[i] == 0)
00093        {
00094         opserr<<"FiniteDeformationElastic3D::FiniteDeformationElastic3D -- failed allocate material model pointer\n";
00095         exit(-1);
00096        }
00097       }
00098 
00099       rho = m.getRho();
00100 
00101       for (i=0; i<NumNodes; i++) 
00102         theNodes[i] = 0;
00103 }
00104 
00105 //-------------------------------------------------------------------------------------------
00106 TotalLagrangianFD20NodeBrick::TotalLagrangianFD20NodeBrick ()
00107 :Element(0, ELE_TAG_TotalLagrangianFD20NodeBrick ),
00108  theMaterial(0), connectedExternalNodes(NumNodes), Q(0), bf(NumDof), Ki(0)
00109 {    
00110      int  i;
00111      for (i=0; i<NumNodes; i++)  
00112        theNodes[i] = 0;
00113 
00114      bf(0) = 0.0;
00115      bf(1) = 0.0;
00116      bf(2) = 0.0;
00117 
00118      rho = 0.0;
00119 }
00120 
00121 //-------------------------------------------------------------------------------------------------
00122 TotalLagrangianFD20NodeBrick::~TotalLagrangianFD20NodeBrick ()
00123 {
00124     int i;
00125     for (i=0; i<NumTotalGaussPts; i++) {
00126       if (theMaterial[i]) 
00127         delete theMaterial[i];
00128     }
00129 
00130     if(theMaterial) 
00131       delete [] theMaterial;
00132 
00133     if(Ki) delete Ki;
00134 
00135 }
00136 
00137 
00138 //=============================================================================
00139 int TotalLagrangianFD20NodeBrick::getNumExternalNodes () const
00140 {
00141     return NumNodes;
00142 }
00143 
00144 //=============================================================================
00145 const ID& TotalLagrangianFD20NodeBrick::getExternalNodes ()
00146 {
00147     return connectedExternalNodes;
00148 }
00149 
00150 //=============================================================================
00151 Node **TotalLagrangianFD20NodeBrick::getNodePtrs(void)
00152 {
00153     return theNodes;
00154 }
00155 
00156 //=============================================================================
00157 int TotalLagrangianFD20NodeBrick::getNumDOF ()
00158 {
00159     return NumElemDof;
00160 }
00161 
00162 //=============================================================================
00163 void TotalLagrangianFD20NodeBrick::setDomain (Domain *theDomain)
00164 {
00165     int i;
00166 
00167     // Check Domain is not null - invoked when object removed from a domain
00168     if (theDomain == 0) {
00169       for (i=0; i<NumNodes; i++) {
00170         theNodes[i] = 0; 
00171       }
00172       return;
00173     }
00174     
00175     for (i=0; i<NumNodes; i++) {
00176       theNodes[i] = theDomain->getNode(connectedExternalNodes(i));
00177       if ( theNodes[i]==0 ) {
00178         opserr << "FATAL ERROR TotalLagrangianFD8NodeBrick (tag: " << this->getTag() <<
00179         " ), node not found in domain\n";
00180         exit(-1);
00181       }    
00182     }
00183 
00184     this->DomainComponent::setDomain(theDomain);  // Very Important!!
00185 
00186     for (i=0; i<NumNodes; i++) {
00187       if ( theNodes[i]->getNumberDOF() != NumDof ) {
00188         opserr << "FATAL ERROR TotalLagrangianFD8NodeBrick (tag: " << this->getTag() <<
00189         "), has differing number of DOFs at its nodes\n";
00190         exit(-1);
00191       }       
00192     }
00193 
00194 }
00195 
00196 //=============================================================================
00197 int TotalLagrangianFD20NodeBrick::commitState ()
00198 {
00199     int retVal = 0;
00200 
00201     if ((retVal = this->Element::commitState()) != 0)
00202       opserr << "TotalLagrangianFD20NodeBrick::commitState () - failed in base class";
00203     
00204     int i;
00205     for (i = 0; i < NumTotalGaussPts ; i++)
00206       retVal += theMaterial[i]->commitState();
00207 
00208     return retVal;
00209 }
00210 
00211 //=============================================================================
00212 int TotalLagrangianFD20NodeBrick::revertToLastCommit ()
00213 {
00214     int retVal = 0;
00215     
00216     int i;
00217     for (i=0; i<NumTotalGaussPts; i++)
00218        retVal += theMaterial[i]->revertToLastCommit();
00219 
00220     return retVal;
00221 }
00222 
00223 //=============================================================================
00224 int TotalLagrangianFD20NodeBrick::revertToStart ()
00225 {
00226     int retVal = 0;
00227     
00228     int i;
00229     for (i=0; i<NumTotalGaussPts; i++)
00230        retVal += theMaterial[i]->revertToStart();
00231 
00232     return retVal;
00233 
00234 }
00235 
00236 //=============================================================================
00237 int TotalLagrangianFD20NodeBrick::update ()
00238 {
00239     int ret = 0;
00240     tensor dh;
00241     tensor dH_dX;
00242     int where = 0;
00243     int GP_c_r, GP_c_s, GP_c_t;
00244     double r = 0.0;
00245     double s = 0.0;
00246     double t = 0.0;
00247     tensor I_ij("I", 2, def_dim_2);
00248     tensor currentF;
00249     tensor updatedF;
00250 
00251     tensor InitialNodesCrds = this->getNodesCrds();
00252     tensor CurrentNodesDisp = this->getNodesDisp();
00253 
00254     for( GP_c_r = 0 ; GP_c_r < NumIntegrationPts ; GP_c_r++ ) {
00255       r = pts[GP_c_r ];
00256       for( GP_c_s = 0 ; GP_c_s < NumIntegrationPts ; GP_c_s++ ) {
00257         s = pts[GP_c_s ];
00258         for( GP_c_t = 0 ; GP_c_t < NumIntegrationPts ; GP_c_t++ ) {
00259           t = pts[GP_c_t ];
00260           where =(GP_c_r * NumIntegrationPts + GP_c_s) * NumIntegrationPts + GP_c_t;
00261           //dh = shapeFunctionDerivative(r,s,t);
00262           dH_dX = this->dh_Global(r,s,t);
00263           currentF = CurrentNodesDisp("Ia") * dH_dX("Ib");
00264             currentF.null_indices();
00265           updatedF = currentF + I_ij;
00266           ret += theMaterial[where]->setTrialF(updatedF);
00267         }
00268       }
00269     }
00270     return ret;
00271 }
00272 
00273 //======================================================================
00274 tensor TotalLagrangianFD20NodeBrick::Jacobian_3D(double x, double y, double z)
00275 {
00276      tensor N_C = this->getNodesCrds();
00277      tensor dh = this->shapeFunctionDerivative(x, y, z);
00278      
00279      tensor J3D = N_C("ki") * dh("kj");
00280        J3D.null_indices();
00281      return J3D;
00282 }
00283 
00284 //======================================================================
00285 tensor TotalLagrangianFD20NodeBrick::Jacobian_3Dinv(double x, double y, double z)
00286 {
00287      tensor J = this->Jacobian_3D(x,y,z);
00288      return J.inverse();
00289 }
00290 
00291 //======================================================================
00292 tensor TotalLagrangianFD20NodeBrick::dh_Global(double x, double y, double z)
00293 {
00294      tensor JacobianINV0 = this->Jacobian_3Dinv(x, y, z);
00295      tensor dh = this->shapeFunctionDerivative(x, y, z);
00296      tensor  dhGlobal = dh("ik") * JacobianINV0("kj");
00297        dhGlobal.null_indices();
00298      return dhGlobal;}
00299 
00300 //======================================================================
00301 tensor TotalLagrangianFD20NodeBrick::getStiffnessTensor(void)
00302 {
00303     tensor tI2("I", 2, def_dim_2);
00304           
00305         int K_dim[] = {NumNodes, NumDof, NumDof, NumNodes};
00306     tensor Kk(4,K_dim,0.0);
00307 
00308     double r  = 0.0;
00309     double rw = 0.0;
00310     double s  = 0.0;
00311     double sw = 0.0;
00312     double t  = 0.0;
00313     double tw = 0.0;
00314    
00315     int where = 0;
00316     int GP_c_r, GP_c_s, GP_c_t;
00317     double weight = 0.0;
00318 
00319     int dh_dim[] = {NumNodes, NumDof};
00320     tensor dh(2, dh_dim, 0.0);
00321     stresstensor PK2Stress;
00322     tensor L2;
00323 
00324     double det_of_Jacobian = 0.0;
00325 
00326     tensor Jacobian;
00327     tensor dhGlobal;
00328     tensor nodesDisp;
00329     tensor F;
00330     //tensor temp01;
00331     tensor temp02;
00332     tensor temp03;
00333     tensor temp04; 
00334     tensor temp05;
00335     tensor temp06;
00336 
00337     nodesDisp = this->getNodesDisp( );
00338 
00339     for( GP_c_r = 0 ; GP_c_r < NumIntegrationPts ; GP_c_r++ ) {
00340       r = pts[GP_c_r ];
00341       rw = wts[GP_c_r ];
00342       for( GP_c_s = 0 ; GP_c_s < NumIntegrationPts ; GP_c_s++ ) {
00343         s = pts[GP_c_s ];
00344         sw = wts[GP_c_s ];
00345         for( GP_c_t = 0 ; GP_c_t < NumIntegrationPts ; GP_c_t++ ) {
00346           t = pts[GP_c_t ];
00347           tw = wts[GP_c_t ];
00348           where =(GP_c_r * NumIntegrationPts + GP_c_s) * NumIntegrationPts + GP_c_t;
00349           //dh = shapeFunctionDerivative(r,s,t);
00350           Jacobian = this->Jacobian_3D(r,s,t);
00351           det_of_Jacobian  = Jacobian.determinant();
00352           dhGlobal = this->dh_Global(r,s,t);
00353           weight = rw * sw * tw * det_of_Jacobian;
00354           PK2Stress = theMaterial[where]->getStressTensor();
00355           L2 = theMaterial[where]->getTangentTensor();
00356           F = theMaterial[where]->getF();
00357                         
00358           //K1
00359           temp04 = dhGlobal("Pb") * tI2("mn");
00360             temp04.null_indices(); 
00361           temp02 = PK2Stress("bd") * dhGlobal("Qd");   
00362             temp02.null_indices();
00363           temp06 = temp04("Pbmn") * temp02("bQ") * weight;
00364             temp06.null_indices(); 
00365           Kk += temp06;
00366                         
00367           //K2
00368           temp03 =  dhGlobal("Pb") * F("ma");
00369             temp03.null_indices(); 
00370           temp04 = F("nc") * L2("abcd");
00371             temp04.null_indices(); 
00372           temp05 = temp04("nabd") * dhGlobal("Qd"); 
00373             temp05.null_indices(); 
00374           temp06 = temp03("Pbma") * temp05("nabQ") * weight;
00375             temp06.null_indices(); 
00376           Kk += temp06;
00377         }
00378       }
00379     }
00380 
00381     return Kk;
00382 }
00383 
00384 //======================================================================
00385 tensor TotalLagrangianFD20NodeBrick::getRtensor(void)
00386 {
00387     int R_dim[] = {NumNodes, NumDof};
00388     tensor Rr(2,R_dim,0.0);
00389 
00390     double r  = 0.0;
00391     double rw = 0.0;
00392     double s  = 0.0;
00393     double sw = 0.0;
00394     double t  = 0.0;
00395     double tw = 0.0;
00396 
00397     int where = 0;
00398     int GP_c_r, GP_c_s, GP_c_t;
00399     double weight = 0.0;
00400 
00401     int dh_dim[] = {NumNodes,NumDof};
00402     tensor dh(2, dh_dim, 0.0);
00403 
00404     double det_of_Jacobian = 0.0;
00405 
00406     tensor Jacobian;
00407     tensor JacobianINV;
00408     tensor dhGlobal;
00409     tensor currentF;
00410     tensor nodesDisp;
00411     //stresstensor PK2Stress;
00412     tensor temp01;
00413     tensor temp02;
00414     tensor F;
00415 
00416     nodesDisp = this->getNodesDisp( );
00417 
00418     for( GP_c_r = 0 ; GP_c_r < NumIntegrationPts ; GP_c_r++ ) {
00419           r = pts[GP_c_r ];
00420       rw = wts[GP_c_r ];
00421       for( GP_c_s = 0 ; GP_c_s < NumIntegrationPts ; GP_c_s++ ) {
00422         s = pts[GP_c_s ];
00423         sw = wts[GP_c_s ];
00424         for( GP_c_t = 0 ; GP_c_t < NumIntegrationPts ; GP_c_t++ ) {
00425           t = pts[GP_c_t ];
00426           tw = wts[GP_c_t ];
00427           where =(GP_c_r * NumIntegrationPts + GP_c_s) * NumIntegrationPts + GP_c_t;
00428           //dh = shapeFunctionDerivative(r,s,t);
00429           Jacobian = this->Jacobian_3D(r,s,t);
00430           det_of_Jacobian  = Jacobian.determinant();
00431           dhGlobal = this->dh_Global(r,s,t);
00432           weight = rw * sw * tw * det_of_Jacobian;
00433           //PK2Stress = theMaterial[where]->getStressTensor();
00434           //F = theMaterial[where]->getF();
00435           //temp01 = PK2Stress("ik") * F("jk");
00436           //  temp01.null_indices();
00437           temp01 = theMaterial[where]->getPK1StressTensor();
00438           temp02 = dhGlobal("PJ") * temp01("iJ") * weight;
00439             temp02.null_indices(); 
00440           Rr += temp02;
00441         }
00442       }
00443     }
00444 
00445     return Rr;
00446 }
00447 
00448 //======================================================================
00449 tensor TotalLagrangianFD20NodeBrick::getBodyForce(void)
00450 {
00451     int B_dim[] = {NumNodes, NumDof};
00452     tensor Bb(2,B_dim,0.0);
00453 
00454     double r  = 0.0;
00455     double rw = 0.0;
00456     double s  = 0.0;
00457     double sw = 0.0;
00458     double t  = 0.0;
00459     double tw = 0.0;
00460 
00461     int where = 0;
00462     int GP_c_r, GP_c_s, GP_c_t;
00463     double weight = 0.0;
00464 
00465     int h_dim[] = {20};
00466     tensor h(1, h_dim, 0.0);
00467     int dh_dim[] = {NumNodes,NumDof};
00468     tensor dh(2, dh_dim, 0.0);
00469     int bodyforce_dim[] = {3};
00470     tensor bodyforce(1, bodyforce_dim, 0.0);
00471 
00472     double det_of_Jacobian = 0.0;
00473 
00474     tensor Jacobian;
00475     tensor JacobianINV;
00476 
00477     bodyforce.val(1) = bf(0);
00478     bodyforce.val(2) = bf(1);
00479     bodyforce.val(3) = bf(2);
00480 
00481     for( GP_c_r = 0 ; GP_c_r < NumIntegrationPts ; GP_c_r++ ) {
00482       r = pts[GP_c_r ];
00483       rw = wts[GP_c_r ];
00484       for( GP_c_s = 0 ; GP_c_s < NumIntegrationPts ; GP_c_s++ ) {
00485         s = pts[GP_c_s ];
00486         sw = wts[GP_c_s ];
00487         for( GP_c_t = 0 ; GP_c_t < NumIntegrationPts ; GP_c_t++ ) {
00488           t = pts[GP_c_t ];
00489           tw = wts[GP_c_t ];
00490           where =(GP_c_r * NumIntegrationPts + GP_c_s) * NumIntegrationPts + GP_c_t;
00491           h = shapeFunction(r,s,t);
00492           //dh = shapeFunctionDerivative(r,s,t);
00493           Jacobian = this->Jacobian_3D(r,s,t);
00494           det_of_Jacobian  = Jacobian.determinant();
00495           weight = rw * sw * tw * det_of_Jacobian;
00496           Bb = Bb +  h("P") * bodyforce("i") * rho *weight;
00497             Bb.null_indices();
00498         }
00499       }
00500     }
00501     return Bb;
00502 }
00503 
00504 //======================================================================
00505 tensor TotalLagrangianFD20NodeBrick::getSurfaceForce(void)
00506 {
00507     int S_dim[] = {NumNodes, NumDof};
00508     tensor Ss(2,S_dim,0.0);
00509     // Need Work Here!
00510 
00511     return Ss;
00512 }
00513 
00514 //============================================================================
00515 tensor TotalLagrangianFD20NodeBrick::getForces(void)
00516 {
00517     int F_dim[] = {NumNodes,NumDof};
00518     tensor Ff(2,F_dim,0.0);
00519 
00520     Ff = this->getBodyForce( ) + this->getSurfaceForce( );
00521 
00522     return Ff;
00523 }
00524 
00525 //=============================================================================
00526 const Matrix &TotalLagrangianFD20NodeBrick::getTangentStiff ()
00527 {
00528      K.Zero();
00529 
00530      tensor stifftensor = this->getStiffnessTensor();
00531 
00532      int kki=0;
00533      int kkj=0;
00534      
00535      int i, j, k, l;
00536      for (i=1 ; i<=NumNodes ; i++ ) {
00537         for (j=1 ; j<=NumNodes ; j++ ) {
00538            for (k=1 ; k<=NumDof ; k++ ) {
00539               for (l=1 ; l<=NumDof ; l++ ) {
00540                  kki = k + NumDof*(i-1);
00541                  kkj = l + NumDof*(j-1);
00542                  K(kki-1 , kkj-1) = stifftensor.cval(i,k,l,j); 
00543               }
00544            }
00545         }
00546      }
00547 
00548      return K;
00549 }
00550 
00551 //=============================================================================
00552 const Matrix &TotalLagrangianFD20NodeBrick::getInitialStiff ()
00553 {
00554     if (Ki != 0) return *Ki;
00555 
00556     K.Zero();
00557     K = this->getTangentStiff ();
00558 
00559     Ki = new Matrix(K);
00560 
00561     return K;
00562 }
00563 
00564 //=============================================================================
00565 const Matrix &TotalLagrangianFD20NodeBrick::getMass ()
00566 {
00567     // Need Work Here
00568     M.Zero();
00569     return M;
00570 }
00571 
00572 //======================================================================
00573 tensor TotalLagrangianFD20NodeBrick::getNodesCrds(void)
00574 {
00575     const int dimensions[] = {NumNodes, NumDof};
00576     tensor N_coord(2, dimensions, 0.0);
00577 
00578     int i, j;
00579     for (i=0; i<NumNodes; i++) {
00580           const Vector &TNodesCrds = theNodes[i]->getCrds();
00581       for (j=0; j<NumDof; j++) {
00582         N_coord.val(i+1, j+1) = TNodesCrds(j);
00583           }                 
00584     }
00585     
00586     return N_coord;
00587 }
00588 
00589 //=============================================================================================
00590 tensor TotalLagrangianFD20NodeBrick::getNodesDisp(void)
00591 {
00592     int i, j;
00593     int dimU[] = {NumNodes, NumDof};
00594     tensor total_disp(2, dimU, 0.0);
00595 
00596     for (i=0; i<NumNodes; i++) {
00597       const Vector &TNodesDisp = theNodes[i]->getTrialDisp();
00598       for (j=0; j<NumDof; j++) {
00599         total_disp.val(i+1, j+1) = TNodesDisp(j);
00600       }
00601     }
00602 
00603     return total_disp;
00604 }
00605 
00606 //=============================================================================
00607 void TotalLagrangianFD20NodeBrick::zeroLoad(void)
00608 {
00609    if ( Q != 0 )
00610      Q->Zero();
00611     
00612    return;
00613 }
00614 
00615 
00616 //=============================================================================
00617 int
00618 TotalLagrangianFD20NodeBrick::addLoad(ElementalLoad *theLoad, double loadFactor)
00619 {
00620     opserr<<"TotalLagrangianFD20NodeBrick::addLoad - load type unknown for ele with tag: "<<this->getTag();          
00621     return -1;
00622 }
00623 
00624 //=============================================================================
00625 int TotalLagrangianFD20NodeBrick::addInertiaLoadToUnbalance(const Vector &accel)
00626 {
00627     // Check for a quick return
00628     if (rho == 0.0) return 0;
00629 
00630     static Vector ra(NumElemDof);
00631     int i, j;
00632 
00633     for (i=0; i<NumNodes; i++) {
00634       const Vector &RA = theNodes[i]->getRV(accel);
00635       if ( RA.Size() != NumDof ) {
00636         opserr << "TotalLagrangianFD20NodeBrick::addInertiaLoadToUnbalance(): matrix and vector sizes are incompatable \n";
00637         return (-1);
00638       }
00639       
00640       for (j=0; j<NumDof; j++) {
00641         ra(i*NumDof +j) = RA(j);
00642       }
00643 
00644     }
00645 
00646     this->getMass();
00647 
00648     if (Q == 0)  
00649       Q = new Vector(NumElemDof);
00650 
00651     Q->addMatrixVector(1.0, M, ra, -1.0);
00652 
00653     return 0;  
00654     
00655 }
00656 
00657 
00658 //=============================================================================
00659 const Vector &TotalLagrangianFD20NodeBrick::getResistingForce ()
00660 {
00661         int i, j;
00662     int f_dim[] = {NumNodes, NumDof};
00663     tensor NodalForces_in(2, f_dim, 0.0);
00664     NodalForces_in = this->getRtensor() - this->getForces();
00665     
00666     for (i=0; i<NumNodes; i++) {
00667       for (j=0; j<NumDof; j++) {
00668          P(i*NumDof +j) = NodalForces_in.cval(i+1, j+1);
00669       }
00670     }
00671     
00672     if (Q != 0)
00673       P.addVector(1.0, *Q, -1.0);
00674     
00675     return P;
00676 }
00677 
00678 //=============================================================================
00679 const Vector &TotalLagrangianFD20NodeBrick::getResistingForceIncInertia ()
00680 {
00681     int i, j;
00682     Vector a(NumElemDof);
00683   
00684     this->getResistingForce();
00685 
00686     if (rho != 0.0)
00687     {
00688       for (i=0; i<NumNodes; i++) {
00689         const Vector &acc = theNodes[i]->getTrialAccel();
00690         if ( acc.Size() != NumDof ) {
00691           opserr << "TotalLagrangianFD20NodeBrick::getResistingForceIncInertia matrix and vector sizes are incompatable \n";
00692           exit(-1);
00693         }
00694        for (j=0; j<NumDof; j++) {
00695          a(i*NumDof +j) = acc(j);
00696       }
00697     }
00698 
00699     this->getMass();
00700     P.addMatrixVector(1.0, M, a, 1.0);
00701 
00702   }
00703 
00704   return P;
00705 }
00706 
00707 //=============================================================================
00708 int TotalLagrangianFD20NodeBrick::sendSelf (int commitTag, Channel &theChannel)
00709 {
00710      // Not implemtented yet
00711      return 0;
00712 }
00713 
00714 //=============================================================================
00715 int TotalLagrangianFD20NodeBrick::recvSelf (int commitTag, Channel &theChannel,
00716 FEM_ObjectBroker &theBroker)
00717 {
00718      // Not implemtented yet
00719      return 0;
00720 }
00721 
00722 
00723 //=============================================================================
00724 int TotalLagrangianFD20NodeBrick::displaySelf (Renderer &theViewer, int displayMode, float fact)
00725 {
00726      // Not implemtented yet
00727      return 0;
00728 }
00729 
00730 //=============================================================================
00731 void TotalLagrangianFD20NodeBrick::Print(OPS_Stream &s, int flag)
00732 {
00733     s << "\nTotalLagrangianFD20NodeBrick, element id:  " << this->getTag() << endln;
00734     s << "\nConnected external nodes:  " << connectedExternalNodes;
00735     s << "\nBody forces:  " << bf(0) << " " << bf(1) << " " << bf(2) << endln;
00736 
00737     theMaterial[0]->Print(s,flag);
00738 
00739     tensor sigma;
00740     Vector P00(6);
00741     
00742     int i;
00743     for (i=0; i<NumTotalGaussPts; i++)
00744     {
00745       sigma = theMaterial[i]->getCauchyStressTensor();
00746       P00(0) = sigma.val(1,1);
00747       P00(1) = sigma.val(2,2);
00748       P00(2) = sigma.val(3,3);
00749       P00(3) = sigma.val(2,3);
00750       P00(4) = sigma.val(3,1);
00751       P00(5) = sigma.val(1,2);
00752 
00753       s << "\n where = " << i << endln;
00754       s << " Stress (Cauchy): xx yy zz yz zx xy) " << P00 << endln;
00755     }
00756 }
00757 
00758 //=============================================================================
00759 Response * TotalLagrangianFD20NodeBrick::setResponse (const char **argv, int argc, Information &eleInfo, OPS_Stream &output)
00760 {
00761   Response *theResponse = 0;
00762 
00763   char outputData[32];
00764 
00765   output.tag("ElementOutput");
00766   output.attr("eleType","TotalLagrangianFD8NodeBrick");
00767   output.attr("eleTag",this->getTag());
00768   for (int i=1; i<=NumNodes; i++) {
00769     sprintf(outputData,"node%d",i);
00770     output.attr(outputData,connectedExternalNodes[i-1]);
00771   }
00772 
00773   if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0) {
00774     for (int i=1; i<=NumNodes; i++)
00775       for (int j=1; j<=NumDof; j++) {
00776         sprintf(outputData,"P%d_%d",j,i);
00777         output.tag("ResponseType",outputData);
00778       }
00779     
00780     theResponse = new ElementResponse(this, 1, this->getResistingForce());
00781     
00782   } else if (strcmp(argv[0],"CauchyStress") == 0 || strcmp(argv[0],"stress") == 0)
00783       theResponse = new ElementResponse(this, 3, Vector(NumTotalGaussPts*6));
00784     
00785     else if (strcmp(argv[0],"PK2Stress") == 0 || strcmp(argv[0],"PK2stress") == 0)
00786       theResponse = new ElementResponse(this, 4, Vector(NumTotalGaussPts*6));
00787 
00788     else if (strcmp(argv[0],"EulerianStrain") == 0 || strcmp(argv[0],"strain") == 0)
00789       theResponse = new ElementResponse(this, 5, Vector(NumTotalGaussPts*6));
00790     
00791     else if (strcmp(argv[0],"LagrangianStrain") == 0 || strcmp(argv[0],"iniStrain") == 0)
00792       theResponse = new ElementResponse(this, 6, Vector(NumTotalGaussPts*6));
00793 
00794     output.endTag(); // ElementOutput
00795 
00796   return theResponse; 
00797 }
00798 
00799 //=============================================================================
00800 int TotalLagrangianFD20NodeBrick::getResponse (int responseID, Information &eleInfo)
00801 {    
00802          int i;
00803      static Vector P0(NumTotalGaussPts*6);
00804      
00805      switch (responseID) {
00806      
00807      case 1:
00808           return eleInfo.setVector(this->getResistingForce() );
00809 
00810      case 3: { 
00811         Vector P0(NumTotalGaussPts*6);
00812         tensor sigma; 
00813         for (i=0; i<NumTotalGaussPts; i++) {
00814           sigma = theMaterial[i]->getCauchyStressTensor();
00815           P0(i*6 +0 ) = sigma.val(1,1);
00816           P0(i*6 +1 ) = sigma.val(2,2);
00817           P0(i*6 +2 ) = sigma.val(3,3);
00818           P0(i*6 +3 ) = sigma.val(2,3);
00819           P0(i*6 +4 ) = sigma.val(3,1);
00820           P0(i*6 +5 ) = sigma.val(1,2);
00821         }
00822         return eleInfo.setVector(P0);
00823      }
00824 
00825      case 4: { 
00826         Vector P0(NumTotalGaussPts*6);
00827         tensor sigma; 
00828         for (i=0; i<NumTotalGaussPts; i++) {
00829           sigma = theMaterial[i]->getStressTensor();
00830           P0(i*6 +0 ) = sigma.val(1,1);
00831           P0(i*6 +1 ) = sigma.val(2,2);
00832           P0(i*6 +2 ) = sigma.val(3,3);
00833           P0(i*6 +3 ) = sigma.val(2,3);
00834           P0(i*6 +4 ) = sigma.val(3,1);
00835           P0(i*6 +5 ) = sigma.val(1,2);
00836         }
00837         return eleInfo.setVector(P0);
00838      }
00839 
00840      case 5: { 
00841         Vector P0(NumTotalGaussPts*6);
00842         tensor e;
00843         tensor E;
00844         tensor F;
00845         tensor tI2("I", 2, def_dim_2); 
00846         for (i=0; i<NumTotalGaussPts; i++) {
00847           E = theMaterial[i]->getStrainTensor();
00848           F = theMaterial[i]->getF();
00849           F = F.inverse();
00850           e = F("ki")*F("kj"); e.null_indices();
00851           e = (tI2-e) *0.5;
00852           P0(i*6 +0 ) = e.val(1,1);
00853           P0(i*6 +1 ) = e.val(2,2);
00854           P0(i*6 +2 ) = e.val(3,3);
00855           P0(i*6 +3 ) = e.val(2,3);
00856           P0(i*6 +4 ) = e.val(3,1);
00857           P0(i*6 +5 ) = e.val(1,2);
00858         }
00859         return eleInfo.setVector(P0);
00860      }
00861 
00862      case 6: { 
00863         Vector P0(NumTotalGaussPts*6);
00864         tensor E; 
00865         for (i=0; i<NumTotalGaussPts; i++) {
00866           E = theMaterial[i]->getStrainTensor();
00867           P0(i*6 +0 ) = E.val(1,1);
00868           P0(i*6 +1 ) = E.val(2,2);
00869           P0(i*6 +2 ) = E.val(3,3);
00870           P0(i*6 +3 ) = E.val(2,3);
00871           P0(i*6 +4 ) = E.val(3,1);
00872           P0(i*6 +5 ) = E.val(1,2);
00873         }
00874         return eleInfo.setVector(P0);
00875      }
00876     
00877      default:
00878      return -1;
00879 
00880    }    
00881 }
00882 
00883 
00884 //#############################################################################
00885 //===================================================================
00886 tensor TotalLagrangianFD20NodeBrick::shapeFunction(double r1, double r2, double r3)
00887 {
00888 
00889     int dimension[] = {NumNodes};
00890     tensor h(1, dimension, 0.0);
00891 
00892     // influence of the node number 20
00893         h.val(20)=(1.0+r1)*(1.0-r2)*(1.0-r3*r3)*0.25;
00894     // influence of the node number 19
00895         h.val(19)=(1.0-r1)*(1.0-r2)*(1.0-r3*r3)*0.25;
00896     // influence of the node number 18
00897         h.val(18)=(1.0-r1)*(1.0+r2)*(1.0-r3*r3)*0.25;
00898     // influence of the node number 17
00899         h.val(17)=(1.0+r1)*(1.0+r2)*(1.0-r3*r3)*0.25;
00900 
00901     // influence of the node number 16
00902         h.val(16)=(1.0+r1)*(1.0-r2*r2)*(1.0-r3)*0.25;
00903     // influence of the node number 15
00904         h.val(15)=(1.0-r1*r1)*(1.0-r2)*(1.0-r3)*0.25;
00905     // influence of the node number 14
00906         h.val(14)=(1.0-r1)*(1.0-r2*r2)*(1.0-r3)*0.25;
00907     // influence of the node number 13
00908         h.val(13)=(1.0-r1*r1)*(1.0+r2)*(1.0-r3)*0.25;
00909 
00910     // influence of the node number 12
00911         h.val(12)=(1.0+r1)*(1.0-r2*r2)*(1.0+r3)*0.25;
00912     // influence of the node number 11
00913         h.val(11)=(1.0-r1*r1)*(1.0-r2)*(1.0+r3)*0.25;
00914     // influence of the node number 10
00915         h.val(10)=(1.0-r1)*(1.0-r2*r2)*(1.0+r3)*0.25;
00916     // influence of the node number 9
00917         h.val( 9)=(1.0-r1*r1)*(1.0+r2)*(1.0+r3)*0.25;
00918 
00919       // influence of the node number 8
00920     h.val(8)=(1.0+r1)*(1.0-r2)*(1.0-r3)*0.125 - (h.val(15)+h.val(16)+h.val(20))*0.5;
00921       // influence of the node number 7
00922     h.val(7)=(1.0-r1)*(1.0-r2)*(1.0-r3)*0.125 - (h.val(14)+h.val(15)+h.val(19))*0.5;
00923       // influence of the node number 6
00924     h.val(6)=(1.0-r1)*(1.0+r2)*(1.0-r3)*0.125 - (h.val(13)+h.val(14)+h.val(18))*0.5;
00925       // influence of the node number 5
00926     h.val(5)=(1.0+r1)*(1.0+r2)*(1.0-r3)*0.125 - (h.val(13)+h.val(16)+h.val(17))*0.5;
00927 
00928       // influence of the node number 4
00929     h.val(4)=(1.0+r1)*(1.0-r2)*(1.0+r3)*0.125 - (h.val(11)+h.val(12)+h.val(20))*0.5;
00930       // influence of the node number 3
00931     h.val(3)=(1.0-r1)*(1.0-r2)*(1.0+r3)*0.125 - (h.val(10)+h.val(11)+h.val(19))*0.5;
00932       // influence of the node number 2
00933     h.val(2)=(1.0-r1)*(1.0+r2)*(1.0+r3)*0.125 - (h.val(10)+h.val(18)+h.val( 9))*0.5;
00934       // influence of the node number 1
00935     h.val(1)=(1.0+r1)*(1.0+r2)*(1.0+r3)*0.125 - (h.val(12)+h.val(17)+h.val( 9))*0.5;
00936 
00937     return h;
00938 }
00939 
00940 
00941 //==============================================================
00942 tensor TotalLagrangianFD20NodeBrick::shapeFunctionDerivative(double r1, double r2, double r3)
00943 {
00944 
00945     int dimensions[] = {NumNodes, NumDof};
00946     tensor dh(2, dimensions, 0.0);
00947 
00948     // influence of the node number 20
00949         dh.val(20,1) =   (1.0-r2)*(1.0-r3*r3)*0.25;
00950         dh.val(20,2) = - (1.0+r1)*(1.0-r3*r3)*0.25;
00951         dh.val(20,3) = - (1.0+r1)*(1.0-r2)*r3*0.50;
00952     // influence of the node number 19
00953         dh.val(19,1) = - (1.0-r2)*(1.0-r3*r3)*0.25;
00954         dh.val(19,2) = - (1.0-r1)*(1.0-r3*r3)*0.25;
00955         dh.val(19,3) = - (1.0-r1)*(1.0-r2)*r3*0.50;
00956     // influence of the node number 18
00957         dh.val(18,1) = - (1.0+r2)*(1.0-r3*r3)*0.25;
00958         dh.val(18,2) =   (1.0-r1)*(1.0-r3*r3)*0.25;
00959         dh.val(18,3) = - (1.0-r1)*(1.0+r2)*r3*0.50;
00960     // influence of the node number 17
00961         dh.val(17,1) =   (1.0+r2)*(1.0-r3*r3)*0.25;
00962         dh.val(17,2) =   (1.0+r1)*(1.0-r3*r3)*0.25;
00963         dh.val(17,3) = - (1.0+r1)*(1.0+r2)*r3*0.50;
00964 
00965     // influence of the node number 16
00966         dh.val(16,1) =   (1.0-r2*r2)*(1.0-r3)*0.25;
00967         dh.val(16,2) = - (1.0+r1)*r2*(1.0-r3)*0.50;
00968         dh.val(16,3) = - (1.0+r1)*(1.0-r2*r2)*0.25;
00969     // influnce of the node number 15
00970         dh.val(15,1) = - r1*(1.0-r2)*(1.0-r3)*0.50;
00971         dh.val(15,2) = - (1.0-r1*r1)*(1.0-r3)*0.25;
00972         dh.val(15,3) = - (1.0-r1*r1)*(1.0-r2)*0.25;
00973     // influence of the node number 14
00974         dh.val(14,1) = - (1.0-r2*r2)*(1.0-r3)*0.25;
00975         dh.val(14,2) = - (1.0-r1)*r2*(1.0-r3)*0.50;
00976         dh.val(14,3) = - (1.0-r1)*(1.0-r2*r2)*0.25;
00977     // influence of the node number 13
00978         dh.val(13,1) = - r1*(1.0+r2)*(1.0-r3)*0.50;
00979         dh.val(13,2) =   (1.0-r1*r1)*(1.0-r3)*0.25;
00980         dh.val(13,3) = - (1.0-r1*r1)*(1.0+r2)*0.25;
00981 
00982     // influence of the node number 12
00983         dh.val(12,1) =   (1.0-r2*r2)*(1.0+r3)*0.25;
00984         dh.val(12,2) = - (1.0+r1)*r2*(1.0+r3)*0.50;
00985         dh.val(12,3) =   (1.0+r1)*(1.0-r2*r2)*0.25;
00986     // influence of the node number 11
00987         dh.val(11,1) = - r1*(1.0-r2)*(1.0+r3)*0.50;
00988         dh.val(11,2) = - (1.0-r1*r1)*(1.0+r3)*0.25;
00989         dh.val(11,3) =   (1.0-r1*r1)*(1.0-r2)*0.25;
00990     // influence of the node number 10
00991         dh.val(10,1) = - (1.0-r2*r2)*(1.0+r3)*0.25;
00992         dh.val(10,2) = - (1.0-r1)*r2*(1.0+r3)*0.50;
00993         dh.val(10,3) =   (1.0-r1)*(1.0-r2*r2)*0.25;
00994     // influence of the node number 9
00995         dh.val(9,1)  = - r1*(1.0+r2)*(1.0+r3)*0.50;
00996         dh.val(9,2)  =   (1.0-r1*r1)*(1.0+r3)*0.25;
00997         dh.val(9,3)  =   (1.0-r1*r1)*(1.0+r2)*0.25;
00998 
00999       // influence of the node number 8
01000     dh.val(8,1)= (1.0-r2)*(1.0-r3)*0.125 - (dh.val(15,1)+dh.val(16,1)+dh.val(20,1))*0.5;
01001     dh.val(8,2)=-(1.0+r1)*(1.0-r3)*0.125 - (dh.val(15,2)+dh.val(16,2)+dh.val(20,2))*0.5;
01002     dh.val(8,3)=-(1.0+r1)*(1.0-r2)*0.125 - (dh.val(15,3)+dh.val(16,3)+dh.val(20,3))*0.5;
01003       // influence of the node number 7
01004     dh.val(7,1)=-(1.0-r2)*(1.0-r3)*0.125 - (dh.val(14,1)+dh.val(15,1)+dh.val(19,1))*0.5;
01005     dh.val(7,2)=-(1.0-r1)*(1.0-r3)*0.125 - (dh.val(14,2)+dh.val(15,2)+dh.val(19,2))*0.5;
01006     dh.val(7,3)=-(1.0-r1)*(1.0-r2)*0.125 - (dh.val(14,3)+dh.val(15,3)+dh.val(19,3))*0.5;
01007       // influence of the node number 6
01008     dh.val(6,1)=-(1.0+r2)*(1.0-r3)*0.125 - (dh.val(13,1)+dh.val(14,1)+dh.val(18,1))*0.5;
01009     dh.val(6,2)= (1.0-r1)*(1.0-r3)*0.125 - (dh.val(13,2)+dh.val(14,2)+dh.val(18,2))*0.5;
01010     dh.val(6,3)=-(1.0-r1)*(1.0+r2)*0.125 - (dh.val(13,3)+dh.val(14,3)+dh.val(18,3))*0.5;
01011       // influence of the node number 5
01012     dh.val(5,1)= (1.0+r2)*(1.0-r3)*0.125 - (dh.val(13,1)+dh.val(16,1)+dh.val(17,1))*0.5;
01013     dh.val(5,2)= (1.0+r1)*(1.0-r3)*0.125 - (dh.val(13,2)+dh.val(16,2)+dh.val(17,2))*0.5;
01014     dh.val(5,3)=-(1.0+r1)*(1.0+r2)*0.125 - (dh.val(13,3)+dh.val(16,3)+dh.val(17,3))*0.5;
01015 
01016       // influence of the node number 4
01017     dh.val(4,1)= (1.0-r2)*(1.0+r3)*0.125 - (dh.val(11,1)+dh.val(12,1)+dh.val(20,1))*0.5;
01018     dh.val(4,2)=-(1.0+r1)*(1.0+r3)*0.125 - (dh.val(11,2)+dh.val(12,2)+dh.val(20,2))*0.5;
01019     dh.val(4,3)= (1.0+r1)*(1.0-r2)*0.125 - (dh.val(11,3)+dh.val(12,3)+dh.val(20,3))*0.5;
01020       // influence of the node number 3
01021     dh.val(3,1)=-(1.0-r2)*(1.0+r3)*0.125 - (dh.val(10,1)+dh.val(11,1)+dh.val(19,1))*0.5;
01022     dh.val(3,2)=-(1.0-r1)*(1.0+r3)*0.125 - (dh.val(10,2)+dh.val(11,2)+dh.val(19,2))*0.5;
01023     dh.val(3,3)= (1.0-r1)*(1.0-r2)*0.125 - (dh.val(10,3)+dh.val(11,3)+dh.val(19,3))*0.5;
01024       // influence of the node number 2
01025     dh.val(2,1)=-(1.0+r2)*(1.0+r3)*0.125 - (dh.val(10,1)+dh.val(18,1)+dh.val( 9,1))*0.5;
01026     dh.val(2,2)= (1.0-r1)*(1.0+r3)*0.125 - (dh.val(10,2)+dh.val(18,2)+dh.val( 9,2))*0.5;
01027     dh.val(2,3)= (1.0-r1)*(1.0+r2)*0.125 - (dh.val(10,3)+dh.val(18,3)+dh.val( 9,3))*0.5;
01028       // influence of the node number 1
01029     dh.val(1,1)= (1.0+r2)*(1.0+r3)*0.125 - (dh.val(12,1)+dh.val(17,1)+dh.val( 9,1))*0.5;
01030     dh.val(1,2)= (1.0+r1)*(1.0+r3)*0.125 - (dh.val(12,2)+dh.val(17,2)+dh.val( 9,2))*0.5;
01031     dh.val(1,3)= (1.0+r1)*(1.0+r2)*0.125 - (dh.val(12,3)+dh.val(17,3)+dh.val( 9,3))*0.5;
01032 
01033     return dh;
01034 }
01035 
01036 
01037 #endif
01038 

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