FEApp_InitPostOps.cpp

Go to the documentation of this file.
00001 // $Id: FEApp_InitPostOps.cpp,v 1.5.2.2 2007/08/14 00:19:05 etphipp Exp $ 
00002 // $Source: /space/CVS/Trilinos/packages/sacado/example/FEApp/FEApp_InitPostOps.cpp,v $ 
00003 // @HEADER
00004 // ***********************************************************************
00005 // 
00006 //                           Sacado Package
00007 //                 Copyright (2006) Sandia Corporation
00008 // 
00009 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00010 // the U.S. Government retains certain rights in this software.
00011 // 
00012 // This library is free software; you can redistribute it and/or modify
00013 // it under the terms of the GNU Lesser General Public License as
00014 // published by the Free Software Foundation; either version 2.1 of the
00015 // License, or (at your option) any later version.
00016 //  
00017 // This library is distributed in the hope that it will be useful, but
00018 // WITHOUT ANY WARRANTY; without even the implied warranty of
00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020 // Lesser General Public License for more details.
00021 //  
00022 // You should have received a copy of the GNU Lesser General Public
00023 // License along with this library; if not, write to the Free Software
00024 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00025 // USA
00026 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
00027 // (etphipp@sandia.gov).
00028 // 
00029 // ***********************************************************************
00030 // @HEADER
00031 
00032 #include "FEApp_InitPostOps.hpp"
00033 #include "Teuchos_TestForException.hpp"
00034 //#include "Teuchos_Exceptions.hpp"
00035 #include "Epetra_Map.h"
00036 
00037 FEApp::ResidualOp::ResidualOp(
00038         const Teuchos::RCP<const Epetra_Vector>& overlapped_xdot,
00039         const Teuchos::RCP<const Epetra_Vector>& overlapped_x,
00040         const Teuchos::RCP<Epetra_Vector>& overlapped_f) :
00041   xdot(overlapped_xdot),
00042   x(overlapped_x),
00043   f(overlapped_f)
00044 {
00045 }
00046 
00047 FEApp::ResidualOp::~ResidualOp()
00048 {
00049 }
00050 
00051 void
00052 FEApp::ResidualOp::elementInit(const FEApp::AbstractElement& e,
00053              unsigned int neqn,
00054              std::vector<double>* elem_xdot,
00055              std::vector<double>& elem_x)
00056 {
00057   // Global node ID
00058   unsigned int node_GID;
00059 
00060   // Local ID of first DOF
00061   unsigned int firstDOF;
00062 
00063   // Number of nodes
00064   unsigned int nnode = e.numNodes();
00065 
00066   // Copy element solution
00067   for (unsigned int i=0; i<nnode; i++) {
00068     node_GID = e.nodeGID(i);
00069     firstDOF = x->Map().LID(node_GID*neqn);
00070     for (unsigned int j=0; j<neqn; j++) {
00071       elem_x[neqn*i+j] = (*x)[firstDOF+j];
00072       if (elem_xdot != NULL)
00073   (*elem_xdot)[neqn*i+j] = (*xdot)[firstDOF+j];
00074     }
00075   }
00076 }
00077 
00078 void
00079 FEApp::ResidualOp::elementPost(const FEApp::AbstractElement& e,
00080              unsigned int neqn,
00081              std::vector<double>& elem_f)
00082 {
00083   // Number of nodes
00084   unsigned int nnode = e.numNodes();
00085 
00086   // Sum element residual into global residual
00087   int row;
00088   unsigned int lrow;
00089   for (unsigned int node_row=0; node_row<nnode; node_row++) {
00090     for (unsigned int eq_row=0; eq_row<neqn; eq_row++) {
00091       lrow = neqn*node_row+eq_row;
00092       row = static_cast<int>(e.nodeGID(node_row)*neqn + eq_row);
00093       f->SumIntoGlobalValue(row, 0, elem_f[lrow]);
00094     }
00095   }
00096 }
00097 
00098 void
00099 FEApp::ResidualOp::nodeInit(const FEApp::NodeBC& bc,
00100           unsigned int neqn,
00101           std::vector<double>* node_xdot,
00102           std::vector<double>& node_x)
00103 {
00104   // Global node ID
00105   unsigned int node_GID = bc.getNodeGID();
00106 
00107   // Local ID of first DOF
00108   unsigned int firstDOF = x->Map().LID(node_GID*neqn);
00109 
00110   // Copy node solution
00111   for (unsigned int j=0; j<neqn; j++) {
00112     node_x[j] = (*x)[firstDOF+j];
00113     if (node_xdot != NULL)
00114       (*node_xdot)[j] = (*xdot)[firstDOF+j];
00115   }
00116 }
00117 
00118 void
00119 FEApp::ResidualOp::nodePost(const FEApp::NodeBC& bc,
00120           unsigned int neqn,
00121           std::vector<double>& node_f)
00122 {
00123   // Global node ID
00124   unsigned int node_GID = bc.getNodeGID();
00125 
00126   // Global ID of first DOF
00127   unsigned int firstDOF = node_GID*neqn;
00128 
00129   // Residual offsets
00130   const std::vector<unsigned int>& offsets = bc.getOffsets();
00131 
00132   // Replace global residual
00133   for (unsigned int j=0; j<offsets.size(); j++) {
00134     int row = static_cast<int>(firstDOF + offsets[j]);
00135     if (bc.isOwned())
00136       f->ReplaceGlobalValue(row, 0, node_f[offsets[j]]);
00137     else if (bc.isShared())
00138       f->ReplaceGlobalValue(row, 0, 0.0);
00139   }
00140 }
00141 
00142 FEApp::JacobianOp::JacobianOp(
00143              double alpha, double beta,
00144        const Teuchos::RCP<const Epetra_Vector>& overlapped_xdot,
00145        const Teuchos::RCP<const Epetra_Vector>& overlapped_x,
00146        const Teuchos::RCP<Epetra_Vector>& overlapped_f,
00147        const Teuchos::RCP<Epetra_CrsMatrix>& overlapped_jac) :
00148   m_coeff(alpha),
00149   j_coeff(beta),
00150   xdot(overlapped_xdot),
00151   x(overlapped_x),
00152   f(overlapped_f),
00153   jac(overlapped_jac)
00154 {
00155 }
00156 
00157 FEApp::JacobianOp::~JacobianOp()
00158 {
00159 }
00160 
00161 void
00162 FEApp::JacobianOp::elementInit(
00163        const FEApp::AbstractElement& e,
00164        unsigned int neqn,
00165        std::vector< Sacado::Fad::DFad<double> >* elem_xdot,
00166        std::vector< Sacado::Fad::DFad<double> >& elem_x)
00167 {
00168   // Global node ID
00169   unsigned int node_GID;
00170 
00171   // Local ID of first DOF
00172   unsigned int firstDOF;
00173 
00174   // Number of nodes
00175   unsigned int nnode = e.numNodes();
00176 
00177   // Number of dof
00178   unsigned int ndof = nnode*neqn;
00179 
00180   // Copy element solution
00181   for (unsigned int i=0; i<nnode; i++) {
00182     node_GID = e.nodeGID(i);
00183     firstDOF = x->Map().LID(node_GID*neqn);
00184     for (unsigned int j=0; j<neqn; j++) {
00185       elem_x[neqn*i+j] = 
00186   Sacado::Fad::DFad<double>(ndof, (*x)[firstDOF+j]);
00187       elem_x[neqn*i+j].fastAccessDx(neqn*i+j) = j_coeff;
00188       if (elem_xdot != NULL) {
00189   (*elem_xdot)[neqn*i+j] = 
00190     Sacado::Fad::DFad<double>(ndof, (*xdot)[firstDOF+j]);
00191   (*elem_xdot)[neqn*i+j].fastAccessDx(neqn*i+j) = m_coeff;
00192       }
00193   
00194     }
00195   }
00196 }
00197 
00198 void
00199 FEApp::JacobianOp::elementPost(
00200           const FEApp::AbstractElement& e,
00201           unsigned int neqn,
00202           std::vector< Sacado::Fad::DFad<double> >& elem_f)
00203 {
00204   // Number of nodes
00205   unsigned int nnode = e.numNodes();
00206 
00207   // Sum element residual and Jacobian into global residual, Jacobian
00208   // Loop over nodes in element
00209   int row, col;
00210   unsigned int lrow, lcol;
00211   for (unsigned int node_row=0; node_row<nnode; node_row++) {
00212 
00213     // Loop over equations per node
00214     for (unsigned int eq_row=0; eq_row<neqn; eq_row++) {
00215       lrow = neqn*node_row+eq_row;
00216 
00217       // Global row
00218       row = static_cast<int>(e.nodeGID(node_row)*neqn + eq_row);
00219 
00220       // Sum residual
00221       if (f != Teuchos::null)
00222   f->SumIntoGlobalValue(row, 0, elem_f[lrow].val());
00223   
00224       // Check derivative array is nonzero
00225       if (elem_f[lrow].hasFastAccess()) {
00226 
00227   // Loop over nodes in element
00228   for (unsigned int node_col=0; node_col<nnode; node_col++){
00229       
00230     // Loop over equations per node
00231     for (unsigned int eq_col=0; eq_col<neqn; eq_col++) {
00232       lcol = neqn*node_col+eq_col;
00233         
00234       // Global column
00235       col = static_cast<int>(e.nodeGID(node_col)*neqn + eq_col);
00236 
00237       // Sum Jacobian
00238       jac->SumIntoGlobalValues(row, 1, 
00239              &(elem_f[lrow].fastAccessDx(lcol)),
00240              &col);
00241 
00242     } // column equations
00243     
00244   } // column nodes
00245   
00246       } // has fast access
00247       
00248     } // row equations
00249 
00250   } // row node
00251 
00252 }
00253 
00254 void
00255 FEApp::JacobianOp::nodeInit(
00256        const FEApp::NodeBC& bc,
00257        unsigned int neqn,
00258        std::vector< Sacado::Fad::DFad<double> >* node_xdot,
00259        std::vector< Sacado::Fad::DFad<double> >& node_x)
00260 {
00261   // Global node ID
00262   unsigned int node_GID = bc.getNodeGID();
00263 
00264   // Local ID of first DOF
00265   unsigned int firstDOF = x->Map().LID(node_GID*neqn);
00266 
00267   // Copy element solution
00268   for (unsigned int j=0; j<neqn; j++) {
00269     node_x[j] = Sacado::Fad::DFad<double>(neqn, (*x)[firstDOF+j]);
00270     node_x[j].fastAccessDx(j) = j_coeff;
00271     if (node_xdot != NULL) {
00272       (*node_xdot)[j] = Sacado::Fad::DFad<double>(neqn, (*xdot)[firstDOF+j]);
00273       (*node_xdot)[j].fastAccessDx(j) = m_coeff;
00274     }
00275   }
00276 }
00277 
00278 void
00279 FEApp::JacobianOp::nodePost(const FEApp::NodeBC& bc,
00280           unsigned int neqn,
00281           std::vector< Sacado::Fad::DFad<double> >& node_f)
00282 {
00283   // Global node ID
00284   unsigned int node_GID = bc.getNodeGID();
00285 
00286   // Global ID of first DOF
00287   unsigned int firstDOF = node_GID*neqn;
00288 
00289   // Residual offsets
00290   const std::vector<unsigned int>& offsets = bc.getOffsets();
00291 
00292   int num_entries;
00293   double* row_view = 0;
00294   int row, col;
00295 
00296   // Loop over equations per node
00297   for (unsigned int eq_row=0; eq_row<offsets.size(); eq_row++) {
00298 
00299     // Global row
00300     row = static_cast<int>(firstDOF + offsets[eq_row]);
00301     
00302     // Replace residual
00303     if (f != Teuchos::null) {
00304       if (bc.isOwned())
00305   f->ReplaceGlobalValue(row, 0, node_f[offsets[eq_row]].val());
00306       else if (bc.isShared())
00307   f->ReplaceGlobalValue(row, 0, 0.0);
00308     }
00309 
00310     // Always zero out row (This takes care of the not-owned case)
00311     if (bc.isOwned() || bc.isShared()) {
00312       jac->ExtractGlobalRowView(row, num_entries, row_view);
00313       for (int k=0; k<num_entries; k++)
00314   row_view[k] = 0.0;
00315     }
00316   
00317     // Check derivative array is nonzero
00318     if (node_f[offsets[eq_row]].hasFastAccess()) {
00319       
00320       // Loop over equations per node
00321       for (unsigned int eq_col=0; eq_col<neqn; eq_col++) {
00322         
00323   // Global column
00324   col = static_cast<int>(firstDOF + eq_col);
00325 
00326   // Replace Jacobian
00327   if (bc.isOwned())
00328     jac->ReplaceGlobalValues(row, 1, 
00329            &(node_f[eq_row].fastAccessDx(eq_col)),
00330            &col);
00331 
00332       } // column equations
00333   
00334     } // has fast access
00335       
00336   } // row equations
00337 
00338 }
00339 
00340 FEApp::TangentOp::TangentOp(
00341         double alpha, double beta, bool sum_derivs_,
00342   const Teuchos::RCP<const Epetra_Vector>& overlapped_xdot,
00343   const Teuchos::RCP<const Epetra_Vector>& overlapped_x,
00344   const Teuchos::RCP<Sacado::ScalarParameterVector>& p,
00345   const Teuchos::RCP<const Epetra_MultiVector>& overlapped_Vx,
00346   const Teuchos::RCP<const Epetra_MultiVector>& overlapped_Vxdot,
00347   const Teuchos::RCP<const Teuchos::SerialDenseMatrix<int,double> >& Vp_,
00348   const Teuchos::RCP<Epetra_Vector>& overlapped_f,
00349   const Teuchos::RCP<Epetra_MultiVector>& overlapped_JV,
00350   const Teuchos::RCP<Epetra_MultiVector>& overlapped_fp) :
00351   m_coeff(alpha),
00352   j_coeff(beta),
00353   sum_derivs(sum_derivs_),
00354   xdot(overlapped_xdot),
00355   x(overlapped_x),
00356   params(p),
00357   Vx(overlapped_Vx),
00358   Vxdot(overlapped_Vxdot),
00359   Vp(Vp_),
00360   f(overlapped_f),
00361   JV(overlapped_JV),
00362   fp(overlapped_fp),
00363   num_cols_x(0),
00364   num_cols_p(0),
00365   num_cols_tot(0),
00366   param_offset(0)
00367 {
00368   if (Vx != Teuchos::null)
00369     num_cols_x = Vx->NumVectors();
00370   else if (Vxdot != Teuchos::null)
00371     num_cols_x = Vxdot->NumVectors();
00372   if (params != Teuchos::null) {
00373     if (Vp != Teuchos::null)
00374       num_cols_p = Vp->numCols();
00375     else
00376       num_cols_p = params->size();
00377   }
00378   if (sum_derivs) {
00379     num_cols_tot = num_cols_x;
00380     param_offset = 0;
00381   }
00382   else {
00383     num_cols_tot = num_cols_x + num_cols_p;
00384     param_offset = num_cols_x;
00385   }
00386 
00387   TEST_FOR_EXCEPTION(sum_derivs && (num_cols_x != 0) && (num_cols_p != 0) && 
00388          (num_cols_x != num_cols_p),
00389          std::logic_error,
00390          "Seed matrices Vx and Vp must have the same number " << 
00391          " of columns when sum_derivs is true and both are "
00392          << "non-null!" << std::endl);
00393 }
00394 
00395 FEApp::TangentOp::~TangentOp()
00396 {
00397 }
00398 
00399 void
00400 FEApp::TangentOp::elementInit(
00401        const FEApp::AbstractElement& e,
00402        unsigned int neqn,
00403        std::vector< Sacado::Fad::DFad<double> >* elem_xdot,
00404        std::vector< Sacado::Fad::DFad<double> >& elem_x)
00405 {
00406   // Global node ID
00407   unsigned int node_GID;
00408 
00409   // Local ID of first DOF
00410   unsigned int firstDOF;
00411 
00412   // Number of nodes
00413   unsigned int nnode = e.numNodes();
00414 
00415   // Copy element solution
00416   for (unsigned int i=0; i<nnode; i++) {
00417     node_GID = e.nodeGID(i);
00418     firstDOF = x->Map().LID(node_GID*neqn);
00419 
00420     for (unsigned int j=0; j<neqn; j++) {
00421       if (Vx != Teuchos::null && j_coeff != 0.0) {
00422   elem_x[neqn*i+j] = 
00423     Sacado::Fad::DFad<double>(num_cols_tot, (*x)[firstDOF+j]);
00424   for (int k=0; k<num_cols_x; k++)
00425     elem_x[neqn*i+j].fastAccessDx(k) = j_coeff*(*Vx)[k][firstDOF+j];
00426       }
00427       else
00428   elem_x[neqn*i+j] = 
00429     Sacado::Fad::DFad<double>((*x)[firstDOF+j]);
00430 
00431       if (elem_xdot != NULL) {
00432   if (Vxdot != Teuchos::null && m_coeff != 0.0) {
00433     (*elem_xdot)[neqn*i+j] = 
00434       Sacado::Fad::DFad<double>(num_cols_tot, (*xdot)[firstDOF+j]);
00435     for (int k=0; k<num_cols_x; k++)
00436       (*elem_xdot)[neqn*i+j].fastAccessDx(k) = 
00437         m_coeff*(*Vxdot)[k][firstDOF+j];
00438   }
00439   else
00440     (*elem_xdot)[neqn*i+j] = 
00441       Sacado::Fad::DFad<double>((*xdot)[firstDOF+j]);
00442       }
00443   
00444     }
00445   }
00446 
00447   if (params != Teuchos::null) {
00448     FadType p;
00449     for (unsigned int i=0; i<params->size(); i++) {
00450       p = FadType(num_cols_tot, (*params)[i].baseValue);
00451       if (Vp != Teuchos::null) 
00452   for (int k=0; k<num_cols_p; k++)
00453     p.fastAccessDx(param_offset+k) = (*Vp)(i,k);
00454       else
00455   p.fastAccessDx(param_offset+i) = 1.0;
00456       (*params)[i].family->setValueAsIndependent(p);
00457     }
00458   }
00459 }
00460 
00461 void
00462 FEApp::TangentOp::elementPost(
00463           const FEApp::AbstractElement& e,
00464           unsigned int neqn,
00465           std::vector< Sacado::Fad::DFad<double> >& elem_f)
00466 {
00467   // Number of nodes
00468   unsigned int nnode = e.numNodes();
00469 
00470   int row;
00471   unsigned int lrow;
00472   for (unsigned int node_row=0; node_row<nnode; node_row++) {
00473 
00474     // Loop over equations per node
00475     for (unsigned int eq_row=0; eq_row<neqn; eq_row++) {
00476       lrow = neqn*node_row+eq_row;
00477 
00478       // Global row
00479       row = static_cast<int>(e.nodeGID(node_row)*neqn + eq_row);
00480 
00481       // Sum residual
00482       if (f != Teuchos::null)
00483   f->SumIntoGlobalValue(row, 0, elem_f[lrow].val());
00484   
00485       // Extract derivative components for each column
00486       if (JV != Teuchos::null)
00487   for (int col=0; col<num_cols_x; col++)
00488     JV->SumIntoGlobalValue(row, col, elem_f[lrow].dx(col));
00489       if (fp != Teuchos::null)
00490   for (int col=0; col<num_cols_p; col++)
00491     fp->SumIntoGlobalValue(row, col, elem_f[lrow].dx(col+param_offset));
00492       
00493     } // row equations
00494 
00495   } // row node
00496 
00497 }
00498 
00499 void
00500 FEApp::TangentOp::nodeInit(
00501        const FEApp::NodeBC& bc,
00502        unsigned int neqn,
00503        std::vector< Sacado::Fad::DFad<double> >* node_xdot,
00504        std::vector< Sacado::Fad::DFad<double> >& node_x)
00505 {
00506   // Global node ID
00507   unsigned int node_GID = bc.getNodeGID();
00508 
00509   // Local ID of first DOF
00510   unsigned int firstDOF = x->Map().LID(node_GID*neqn);
00511 
00512   // Copy element solution
00513   for (unsigned int j=0; j<neqn; j++) {
00514     if (Vx != Teuchos::null && j_coeff != 0.0) {
00515       node_x[j] = Sacado::Fad::DFad<double>(num_cols_tot, (*x)[firstDOF+j]);
00516       for (int k=0; k < num_cols_x; k++)
00517   node_x[j].fastAccessDx(k) = j_coeff*(*Vx)[k][firstDOF+j];
00518     }
00519     else
00520       node_x[j] = Sacado::Fad::DFad<double>((*x)[firstDOF+j]);
00521 
00522     if (node_xdot != NULL) {
00523       if (Vxdot != Teuchos::null && m_coeff != 0.0) {
00524   (*node_xdot)[j] = 
00525     Sacado::Fad::DFad<double>(num_cols_tot, (*xdot)[firstDOF+j]);
00526   for (int k=0; k < num_cols_x; k++)
00527     (*node_xdot)[j].fastAccessDx(k) = m_coeff*(*Vxdot)[k][firstDOF+j];
00528       }
00529       else
00530   (*node_xdot)[j] = 
00531     Sacado::Fad::DFad<double>((*xdot)[firstDOF+j]);
00532     }
00533   }
00534 
00535   if (params != Teuchos::null) {
00536     FadType p;
00537     for (unsigned int i=0; i<params->size(); i++) {
00538       p = FadType(num_cols_tot, (*params)[i].baseValue);
00539       if (Vp != Teuchos::null) 
00540   for (int k=0; k<num_cols_p; k++)
00541     p.fastAccessDx(param_offset+k) = (*Vp)(i,k);
00542       else
00543   p.fastAccessDx(param_offset+i) = 1.0;
00544       (*params)[i].family->setValueAsIndependent(p);
00545     }
00546   }
00547 }
00548 
00549 void
00550 FEApp::TangentOp::nodePost(const FEApp::NodeBC& bc,
00551           unsigned int neqn,
00552           std::vector< Sacado::Fad::DFad<double> >& node_f)
00553 {
00554   // Global node ID
00555   unsigned int node_GID = bc.getNodeGID();
00556 
00557   // Global ID of first DOF
00558   unsigned int firstDOF = node_GID*neqn;
00559 
00560   // Residual offsets
00561   const std::vector<unsigned int>& offsets = bc.getOffsets();
00562 
00563   int row;
00564 
00565   // Loop over equations per node
00566   for (unsigned int eq_row=0; eq_row<offsets.size(); eq_row++) {
00567 
00568     // Global row
00569     row = static_cast<int>(firstDOF + offsets[eq_row]);
00570     
00571     // Replace residual
00572     if (f != Teuchos::null) {
00573       if (bc.isOwned())
00574   f->ReplaceGlobalValue(row, 0, node_f[offsets[eq_row]].val());
00575       else if (bc.isShared())
00576   f->ReplaceGlobalValue(row, 0, 0.0);
00577     }
00578 
00579     if (bc.isOwned()) {
00580 
00581       // Extract derivative components for each column
00582       if (JV != Teuchos::null && Vx != Teuchos::null)
00583   for (int col=0; col<num_cols_x; col++)
00584     JV->ReplaceGlobalValue(row, col, node_f[offsets[eq_row]].dx(col));
00585 
00586       if (fp != Teuchos::null)
00587   for (int col=0; col<num_cols_p; col++)
00588     fp->ReplaceGlobalValue(row, col, 
00589          node_f[offsets[eq_row]].dx(col+param_offset));
00590     }
00591     else if (bc.isShared()) {
00592       if (JV != Teuchos::null && Vx != Teuchos::null)
00593   for (int col=0; col<num_cols_x; col++)
00594     JV->ReplaceGlobalValue(row, col, 0.0);
00595 
00596       if (fp != Teuchos::null)
00597   for (int col=0; col<num_cols_p; col++)
00598     fp->ReplaceGlobalValue(row, col, 0.0);
00599     }
00600     
00601   } // row equations
00602 
00603 }
00604   

Generated on Tue Oct 20 12:55:03 2009 for Sacado Package Browser (Single Doxygen Collection) by doxygen 1.4.7