FEApp_Application.cpp

Go to the documentation of this file.
00001 // $Id: FEApp_Application.cpp,v 1.11 2008/08/01 22:57:12 etphipp Exp $ 
00002 // $Source: /space/CVS/Trilinos/packages/sacado/example/FEApp/FEApp_Application.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_Application.hpp"
00033 #include "FEApp_ProblemFactory.hpp"
00034 #include "FEApp_QuadratureFactory.hpp"
00035 #include "FEApp_DiscretizationFactory.hpp"
00036 #include "FEApp_GlobalFill.hpp"
00037 #include "FEApp_SGMatrixFreeOp.hpp"
00038 #include "FEApp_SGMeanPrecOp.hpp"
00039 
00040 FEApp::Application::Application(
00041        const std::vector<double>& coords,
00042        const Teuchos::RCP<const Epetra_Comm>& comm,
00043        const Teuchos::RCP<Teuchos::ParameterList>& params,
00044        bool is_transient) :
00045   transient(is_transient)
00046 {
00047   // Create parameter library
00048   paramLib = Teuchos::rcp(new Sacado::ScalarParameterLibrary);
00049 
00050   // Create problem object
00051   Teuchos::RCP<Teuchos::ParameterList> problemParams = 
00052     Teuchos::rcp(&(params->sublist("Problem")),false);
00053   FEApp::ProblemFactory problemFactory(problemParams, paramLib);
00054   Teuchos::RCP<FEApp::AbstractProblem> problem = 
00055     problemFactory.create();
00056 
00057   // Get number of equations
00058   unsigned int num_equations = problem->numEquations();
00059 
00060   // Create quadrature object
00061   Teuchos::RCP<Teuchos::ParameterList> quadParams = 
00062     Teuchos::rcp(&(params->sublist("Quadrature")),false);
00063   FEApp::QuadratureFactory quadFactory(quadParams);
00064   quad = quadFactory.create();
00065 
00066   // Create discretization object
00067   Teuchos::RCP<Teuchos::ParameterList> discParams = 
00068     Teuchos::rcp(&(params->sublist("Discretization")),false);
00069   FEApp::DiscretizationFactory discFactory(discParams);
00070   disc = discFactory.create(coords, num_equations, comm);
00071   disc->createMesh();
00072   disc->createMaps();
00073   disc->createJacobianGraphs();
00074 
00075   // Create Epetra objects
00076   importer = Teuchos::rcp(new Epetra_Import(*(disc->getOverlapMap()), 
00077               *(disc->getMap())));
00078   exporter = Teuchos::rcp(new Epetra_Export(*(disc->getOverlapMap()), 
00079               *(disc->getMap())));
00080   overlapped_x = Teuchos::rcp(new Epetra_Vector(*(disc->getOverlapMap())));
00081   if (transient)
00082     overlapped_xdot = 
00083       Teuchos::rcp(new Epetra_Vector(*(disc->getOverlapMap())));
00084   overlapped_f = Teuchos::rcp(new Epetra_Vector(*(disc->getOverlapMap())));
00085   overlapped_jac = 
00086     Teuchos::rcp(new Epetra_CrsMatrix(Copy, 
00087               *(disc->getOverlapJacobianGraph())));
00088 
00089   // Initialize problem
00090   initial_x = Teuchos::rcp(new Epetra_Vector(*(disc->getMap())));
00091   problem->buildProblem(*(disc->getMap()), *(disc->getOverlapMap()), 
00092       pdeTM, bc, initial_x);
00093   typedef FEApp::AbstractPDE_TemplateManager<ValidTypes>::iterator iterator;
00094   int nqp = quad->numPoints();
00095   int nn = disc->getNumNodesPerElement();
00096   for (iterator it = pdeTM.begin(); it != pdeTM.end(); ++it)
00097     it->init(nqp, nn);
00098 
00099 #if SG_ACTIVE
00100   enable_sg = params->get("Enable Stochastic Galerkin",false);
00101   if (enable_sg) {
00102     sg_solver_method = params->get("SG Solver Method", "Fully Assembled");
00103     sg_basis = params->get< Teuchos::RCP<const Stokhos::OrthogPolyBasis<double> > >("Stochastic Galerkin basis");
00104     Cijk = params->get< Teuchos::RCP<const tp_type> >("Stochastic Galerkin triple product");
00105 
00106     bool makeJacobian = sg_solver_method == "Fully Assembled";
00107     sg_disc = Teuchos::rcp(new FEApp::BlockDiscretization(comm, disc,
00108                 sg_basis,
00109                 makeJacobian));
00110 
00111     // Create Epetra objects
00112     sg_initial_x = 
00113       Teuchos::rcp(new EpetraExt::BlockVector(*(disc->getMap()),
00114                 *(sg_disc->getMap())));
00115     sg_importer = Teuchos::rcp(new Epetra_Import(*(sg_disc->getOverlapMap()), 
00116              *(sg_disc->getMap())));
00117     sg_exporter = Teuchos::rcp(new Epetra_Export(*(sg_disc->getOverlapMap()), 
00118              *(sg_disc->getMap())));
00119     sg_overlapped_x = 
00120       Teuchos::rcp(new EpetraExt::BlockVector(*(disc->getOverlapMap()),
00121                 *(sg_disc->getOverlapMap())));
00122     if (transient)
00123       sg_overlapped_xdot = 
00124   Teuchos::rcp(new EpetraExt::BlockVector(*(disc->getOverlapMap()),
00125             *(sg_disc->getOverlapMap())));
00126     sg_overlapped_f = 
00127       Teuchos::rcp(new EpetraExt::BlockVector(*(disc->getOverlapMap()),
00128                 *(sg_disc->getOverlapMap())));
00129     if (sg_solver_method == "Fully Assembled")
00130       sg_overlapped_jac = sg_disc->getOverlapJacobian();
00131     else if (sg_solver_method == "Matrix Free Mean Prec")
00132       precParams = Teuchos::rcp(&(params->sublist("SG Preconditioner")),
00133         false);
00134   }
00135 #endif
00136 }
00137 
00138 FEApp::Application::~Application()
00139 {
00140 }
00141 
00142 Teuchos::RCP<const Epetra_Map>
00143 FEApp::Application::getMap() const
00144 {
00145 #if SG_ACTIVE
00146   if (enable_sg)
00147     return sg_disc->getMap();
00148   else
00149 #endif
00150     return disc->getMap();
00151 }
00152 
00153 Teuchos::RCP<const Epetra_CrsGraph>
00154 FEApp::Application::getJacobianGraph() const
00155 {
00156 #if SG_ACTIVE
00157   if (enable_sg)
00158     return sg_disc->getJacobianGraph();
00159   else
00160 #endif
00161     return disc->getJacobianGraph();
00162 }
00163 
00164 Teuchos::RCP<const Epetra_Vector>
00165 FEApp::Application::getInitialSolution() const
00166 {
00167 #if SG_ACTIVE
00168   if (enable_sg)
00169     return sg_initial_x;
00170   else
00171 #endif
00172     return initial_x;
00173 }
00174 
00175 Teuchos::RCP<Sacado::ScalarParameterLibrary> 
00176 FEApp::Application::getParamLib()
00177 {
00178   return paramLib;
00179 }
00180 
00181 bool
00182 FEApp::Application::isTransient() const
00183 {
00184   return transient;
00185 }
00186 
00187 Teuchos::RCP<Epetra_Operator>
00188 FEApp::Application::createW() const
00189 {
00190   #if SG_ACTIVE
00191   if (enable_sg) {
00192     if (sg_solver_method == "Fully Assembled") {
00193       return 
00194   Teuchos::rcp(new Epetra_CrsMatrix(::Copy, 
00195             *(sg_disc->getJacobianGraph())));
00196     }
00197     else if (sg_solver_method == "Matrix Free Mean Prec") {
00198       unsigned int sz = sg_basis->size();
00199       Teuchos::RCP<std::vector< Teuchos::RCP<Epetra_CrsMatrix> > > jacs = 
00200   Teuchos::rcp(new std::vector< Teuchos::RCP<Epetra_CrsMatrix> >(sz));
00201       for (unsigned int i=0; i<sz; i++)
00202   (*jacs)[i] = 
00203     Teuchos::rcp(new  Epetra_CrsMatrix(::Copy, 
00204                *(disc->getJacobianGraph())));
00205       return 
00206   Teuchos::rcp(new FEApp::SGMatrixFreeOp(disc->getMap(),
00207                  sg_disc->getMap(),
00208                  Cijk,
00209                  jacs));
00210     }
00211   }
00212   else
00213 #endif
00214     return Teuchos::rcp(new Epetra_CrsMatrix(::Copy, 
00215                *(disc->getJacobianGraph())));
00216 }
00217 
00218 Teuchos::RCP<Epetra_Operator>
00219 FEApp::Application::createPrec() const
00220 {
00221   #if SG_ACTIVE
00222   if (enable_sg) {
00223     if (sg_solver_method == "Fully Assembled") {
00224       return 
00225   Teuchos::rcp(new Epetra_CrsMatrix(::Copy, 
00226             *(sg_disc->getJacobianGraph())));
00227     }
00228     else if (sg_solver_method == "Matrix Free Mean Prec") {
00229       unsigned int sz = sg_basis->size();
00230       Teuchos::RCP<Epetra_CrsMatrix> mean_jac = 
00231   Teuchos::rcp(new  Epetra_CrsMatrix(::Copy, 
00232              *(disc->getJacobianGraph())));
00233       return 
00234   Teuchos::rcp(new FEApp::SGMeanPrecOp(disc->getMap(),
00235                sg_disc->getMap(),
00236                sz,
00237                mean_jac,
00238                precParams));
00239     }
00240   }
00241   else
00242 #endif
00243     return Teuchos::rcp(new Epetra_CrsMatrix(::Copy, 
00244                *(disc->getJacobianGraph())));
00245 }
00246 
00247 void
00248 FEApp::Application::computeGlobalResidual(
00249             const Epetra_Vector* xdot,
00250             const Epetra_Vector& x,
00251             const Sacado::ScalarParameterVector* p,
00252             Epetra_Vector& f)
00253 {
00254   if (enable_sg) {
00255     computeGlobalSGResidual(xdot, x, p, f);
00256     return;
00257   }
00258 
00259   // Scatter x to the overlapped distrbution
00260   overlapped_x->Import(x, *importer, Insert);
00261 
00262   // Scatter xdot to the overlapped distribution
00263   if (transient)
00264     overlapped_xdot->Import(*xdot, *importer, Insert);
00265 
00266   // Set parameters
00267   if (p != NULL) {
00268     for (unsigned int i=0; i<p->size(); ++i) {
00269       (*p)[i].family->setRealValueForAllTypes((*p)[i].baseValue);
00270     }
00271   }
00272 
00273   // Zero out overlapped residual
00274   overlapped_f->PutScalar(0.0);
00275   f.PutScalar(0.0);
00276 
00277   // Create residual init/post op
00278   Teuchos::RCP<FEApp::ResidualOp> op;
00279   op = Teuchos::rcp(new FEApp::ResidualOp(overlapped_xdot, overlapped_x, 
00280             overlapped_f));
00281 
00282   // Get template PDE instantiation
00283   Teuchos::RCP< FEApp::AbstractPDE<ResidualOp::fill_type> > pde = 
00284     pdeTM.getAsObject<ResidualOp::fill_type>();
00285 
00286   // Do global fill
00287   FEApp::GlobalFill<ResidualOp::fill_type> globalFill(disc->getMesh(), quad, 
00288                   pde, bc, transient);
00289   globalFill.computeGlobalFill(*op);
00290 
00291   // Assemble global residual
00292   f.Export(*overlapped_f, *exporter, Add);
00293 }
00294 
00295 void
00296 FEApp::Application::computeGlobalJacobian(
00297               double alpha, double beta,
00298               const Epetra_Vector* xdot,
00299               const Epetra_Vector& x,
00300               const Sacado::ScalarParameterVector* p,
00301               Epetra_Vector* f,
00302               Epetra_Operator& jacOp)
00303 {
00304   if (enable_sg) {
00305     computeGlobalSGJacobian(alpha, beta, xdot, x, p, f, jacOp);
00306     return;
00307   }
00308 
00309   // Cast jacOp to an Epetra_CrsMatrix
00310   Epetra_CrsMatrix& jac = dynamic_cast<Epetra_CrsMatrix&>(jacOp);
00311 
00312   // Scatter x to the overlapped distrbution
00313   overlapped_x->Import(x, *importer, Insert);
00314 
00315   // Scatter xdot to the overlapped distribution
00316   if (transient)
00317     overlapped_xdot->Import(*xdot, *importer, Insert);
00318 
00319   // Set parameters
00320   if (p != NULL) {
00321     for (unsigned int i=0; i<p->size(); ++i) {
00322       (*p)[i].family->setRealValueForAllTypes((*p)[i].baseValue);
00323     }
00324   }
00325 
00326   // Zero out overlapped residual
00327   Teuchos::RCP<Epetra_Vector> overlapped_ff;
00328   if (f != NULL) {
00329     overlapped_ff = overlapped_f;
00330     overlapped_ff->PutScalar(0.0);
00331     f->PutScalar(0.0);
00332   }
00333 
00334   // Zero out Jacobian
00335   overlapped_jac->PutScalar(0.0);
00336   jac.PutScalar(0.0);
00337 
00338   // Create Jacobian init/post op
00339   Teuchos::RCP<FEApp::JacobianOp> op;
00340   op = Teuchos::rcp(new FEApp::JacobianOp(alpha, beta, overlapped_xdot, 
00341             overlapped_x, overlapped_ff, 
00342             overlapped_jac));
00343 
00344   // Get template PDE instantiation
00345   Teuchos::RCP< FEApp::AbstractPDE<JacobianOp::fill_type> > pde = 
00346     pdeTM.getAsObject<JacobianOp::fill_type>();
00347 
00348   // Do global fill
00349   FEApp::GlobalFill<JacobianOp::fill_type> globalFill(disc->getMesh(), 
00350                   quad, pde, bc, 
00351                   transient);
00352   globalFill.computeGlobalFill(*op);
00353 
00354   // Assemble global residual
00355   if (f != NULL)
00356     f->Export(*overlapped_f, *exporter, Add);
00357 
00358   // Assemble global Jacobian
00359   jac.Export(*overlapped_jac, *exporter, Add);
00360 
00361   jac.FillComplete(true);
00362 }
00363 
00364 void
00365 FEApp::Application::computeGlobalPreconditioner(
00366               double alpha, double beta,
00367               const Epetra_Vector* xdot,
00368               const Epetra_Vector& x,
00369               const Sacado::ScalarParameterVector* p,
00370               Epetra_Vector* f,
00371               Epetra_Operator& jacOp)
00372 {
00373   if (enable_sg) {
00374     computeGlobalSGPreconditioner(alpha, beta, xdot, x, p, f, jacOp);
00375     return;
00376   }
00377 
00378   // Cast jacOp to an Epetra_CrsMatrix
00379   Epetra_CrsMatrix& jac = dynamic_cast<Epetra_CrsMatrix&>(jacOp);
00380 
00381   // Scatter x to the overlapped distrbution
00382   overlapped_x->Import(x, *importer, Insert);
00383 
00384   // Scatter xdot to the overlapped distribution
00385   if (transient)
00386     overlapped_xdot->Import(*xdot, *importer, Insert);
00387 
00388   // Set parameters
00389   if (p != NULL) {
00390     for (unsigned int i=0; i<p->size(); ++i) {
00391       (*p)[i].family->setRealValueForAllTypes((*p)[i].baseValue);
00392     }
00393   }
00394 
00395   // Zero out overlapped residual
00396   Teuchos::RCP<Epetra_Vector> overlapped_ff;
00397   if (f != NULL) {
00398     overlapped_ff = overlapped_f;
00399     overlapped_ff->PutScalar(0.0);
00400     f->PutScalar(0.0);
00401   }
00402 
00403   // Zero out Jacobian
00404   overlapped_jac->PutScalar(0.0);
00405   jac.PutScalar(0.0);
00406 
00407   // Create Jacobian init/post op
00408   Teuchos::RCP<FEApp::JacobianOp> op;
00409   op = Teuchos::rcp(new FEApp::JacobianOp(alpha, beta, overlapped_xdot, 
00410             overlapped_x, overlapped_ff, 
00411             overlapped_jac));
00412 
00413   // Get template PDE instantiation
00414   Teuchos::RCP< FEApp::AbstractPDE<JacobianOp::fill_type> > pde = 
00415     pdeTM.getAsObject<JacobianOp::fill_type>();
00416 
00417   // Do global fill
00418   FEApp::GlobalFill<JacobianOp::fill_type> globalFill(disc->getMesh(), 
00419                   quad, pde, bc, 
00420                   transient);
00421   globalFill.computeGlobalFill(*op);
00422 
00423   // Assemble global residual
00424   if (f != NULL)
00425     f->Export(*overlapped_f, *exporter, Add);
00426 
00427   // Assemble global Jacobian
00428   jac.Export(*overlapped_jac, *exporter, Add);
00429 
00430   jac.FillComplete(true);
00431 }
00432 
00433 void
00434 FEApp::Application::computeGlobalTangent(
00435             double alpha, double beta,
00436             bool sum_derivs,
00437             const Epetra_Vector* xdot,
00438             const Epetra_Vector& x,
00439             Sacado::ScalarParameterVector* p,
00440             const Epetra_MultiVector* Vx,
00441             const Teuchos::SerialDenseMatrix<int,double>* Vp,
00442             Epetra_Vector* f,
00443             Epetra_MultiVector* JVx,
00444             Epetra_MultiVector* fVp)
00445 {
00446   // Scatter x to the overlapped distrbution
00447   overlapped_x->Import(x, *importer, Insert);
00448 
00449   // Scatter xdot to the overlapped distribution
00450   if (transient)
00451     overlapped_xdot->Import(*xdot, *importer, Insert);
00452 
00453   // Zero out overlapped residual
00454   Teuchos::RCP<Epetra_Vector> overlapped_ff;
00455   if (f != NULL) {
00456     overlapped_ff = overlapped_f;
00457     overlapped_ff->PutScalar(0.0);
00458     f->PutScalar(0.0);
00459   }
00460 
00461   Teuchos::RCP<Epetra_MultiVector> overlapped_JVx;
00462   if (JVx != NULL) {
00463     overlapped_JVx = 
00464       Teuchos::rcp(new Epetra_MultiVector(*(disc->getOverlapMap()), 
00465             JVx->NumVectors()));
00466     overlapped_JVx->PutScalar(0.0);
00467     JVx->PutScalar(0.0);
00468   }
00469   
00470   Teuchos::RCP<Epetra_MultiVector> overlapped_fVp;
00471   if (fVp != NULL) {
00472     overlapped_fVp = 
00473       Teuchos::rcp(new Epetra_MultiVector(*(disc->getOverlapMap()), 
00474             fVp->NumVectors()));
00475     overlapped_fVp->PutScalar(0.0);
00476     fVp->PutScalar(0.0);
00477   }
00478 
00479   Teuchos::RCP<Epetra_MultiVector> overlapped_Vx;
00480   if (Vx != NULL) {
00481     overlapped_Vx = 
00482       Teuchos::rcp(new Epetra_MultiVector(*(disc->getOverlapMap()), 
00483             Vx->NumVectors()));
00484   }
00485 
00486   Teuchos::RCP<const Teuchos::SerialDenseMatrix<int,double> > vp =
00487     Teuchos::rcp(Vp, false);
00488   Teuchos::RCP<Sacado::ScalarParameterVector> params = 
00489     Teuchos::rcp(p, false);
00490 
00491   // Create Jacobian init/post op
00492   Teuchos::RCP<FEApp::TangentOp> op;
00493   op = Teuchos::rcp(new FEApp::TangentOp(alpha, beta, sum_derivs,
00494            overlapped_xdot, 
00495            overlapped_x,
00496            params,
00497            overlapped_Vx,
00498            overlapped_Vx,
00499            vp,
00500            overlapped_ff, 
00501            overlapped_JVx,
00502            overlapped_fVp));
00503 
00504   // Get template PDE instantiation
00505   Teuchos::RCP< FEApp::AbstractPDE<JacobianOp::fill_type> > pde = 
00506     pdeTM.getAsObject<JacobianOp::fill_type>();
00507 
00508   // Do global fill
00509   FEApp::GlobalFill<JacobianOp::fill_type> globalFill(disc->getMesh(), 
00510                   quad, pde, bc, 
00511                   transient);
00512   globalFill.computeGlobalFill(*op);
00513 
00514   // Assemble global residual
00515   if (f != NULL)
00516     f->Export(*overlapped_f, *exporter, Add);
00517 
00518   // Assemble derivatives
00519   if (JVx != NULL)
00520     JVx->Export(*overlapped_JVx, *exporter, Add);
00521   if (fVp != NULL)
00522     fVp->Export(*overlapped_fVp, *exporter, Add);
00523 }
00524 
00525 void
00526 FEApp::Application::computeGlobalSGResidual(
00527             const Epetra_Vector* sg_xdot,
00528             const Epetra_Vector& sg_x,
00529             const Sacado::ScalarParameterVector* p,
00530             Epetra_Vector& sg_f)
00531 {
00532 #if SG_ACTIVE
00533   // Scatter x to the overlapped distrbution
00534   sg_overlapped_x->Import(sg_x, *sg_importer, Insert);
00535 
00536   // Scatter xdot to the overlapped distribution
00537   if (transient)
00538     sg_overlapped_xdot->Import(*sg_xdot, *sg_importer, Insert);
00539 
00540   // Set parameters
00541   if (p != NULL) {
00542     for (unsigned int i=0; i<p->size(); ++i) {
00543       (*p)[i].family->setRealValueForAllTypes((*p)[i].baseValue);
00544     }
00545   }
00546 
00547   // Zero out overlapped residual
00548   sg_overlapped_f->PutScalar(0.0);
00549   sg_f.PutScalar(0.0);
00550 
00551   // Create residual init/post op
00552   if (sg_res_fill_op == Teuchos::null)
00553     sg_res_fill_op = 
00554       Teuchos::rcp(new FEApp::SGResidualOp(disc->getOverlapMap(),
00555              sg_basis,
00556              sg_overlapped_xdot, 
00557              sg_overlapped_x, 
00558              sg_overlapped_f));
00559   else
00560     sg_res_fill_op->reset(sg_overlapped_xdot, sg_overlapped_x);
00561 
00562   // Get template PDE instantiation
00563   Teuchos::RCP< FEApp::AbstractPDE<SGResidualOp::fill_type> > pde = 
00564     pdeTM.getAsObject<SGResidualOp::fill_type>();
00565 
00566   // Do global fill
00567   FEApp::GlobalFill<SGResidualOp::fill_type> globalFill(disc->getMesh(), quad, 
00568               pde, bc, transient);
00569   globalFill.computeGlobalFill(*sg_res_fill_op);
00570 
00571   // Assemble global residual
00572   sg_f.Export(*sg_overlapped_f, *sg_exporter, Add);
00573 #endif
00574 }
00575 
00576 void
00577 FEApp::Application::computeGlobalSGJacobian(
00578               double alpha, double beta,
00579               const Epetra_Vector* sg_xdot,
00580               const Epetra_Vector& sg_x,
00581               const Sacado::ScalarParameterVector* p,
00582               Epetra_Vector* sg_f,
00583               Epetra_Operator& sg_jacOp)
00584 {
00585 #if SGFAD_ACTIVE
00586   // Scatter x to the overlapped distrbution
00587   sg_overlapped_x->Import(sg_x, *sg_importer, Insert);
00588 
00589   // Scatter xdot to the overlapped distribution
00590   if (transient)
00591     sg_overlapped_xdot->Import(*sg_xdot, *sg_importer, Insert);
00592 
00593   // Set parameters
00594   if (p != NULL) {
00595     for (unsigned int i=0; i<p->size(); ++i) {
00596       (*p)[i].family->setRealValueForAllTypes((*p)[i].baseValue);
00597     }
00598   }
00599 
00600   // Zero out overlapped residual
00601   Teuchos::RCP<EpetraExt::BlockVector> sg_overlapped_ff;
00602   if (sg_f != NULL) {
00603     sg_overlapped_ff = sg_overlapped_f;
00604     sg_overlapped_ff->PutScalar(0.0);
00605     sg_f->PutScalar(0.0);
00606   }
00607 
00608   // Create Jacobian init/post op
00609   Teuchos::RCP<FEApp::AbstractInitPostOp<SGJacobianOp::fill_type> > jac_fill_op;
00610   if (sg_solver_method == "Fully Assembled") {
00611     sg_overlapped_jac->PutScalar(0.0);
00612     if (sg_full_jac_fill_op == Teuchos::null)
00613       sg_full_jac_fill_op = 
00614   Teuchos::rcp(new FEApp::SGJacobianOp(disc->getOverlapMap(),
00615                disc->getOverlapJacobianGraph(),
00616                sg_basis,
00617                Cijk,
00618                alpha, beta, 
00619                sg_overlapped_xdot, 
00620                sg_overlapped_x, 
00621                sg_overlapped_ff, 
00622                sg_overlapped_jac));
00623     else
00624       sg_full_jac_fill_op->reset(alpha, beta, sg_overlapped_xdot, 
00625          sg_overlapped_x);
00626     jac_fill_op = sg_full_jac_fill_op;
00627   }
00628   else if (sg_solver_method == "Matrix Free Mean Prec") {
00629     if (sg_mf_jac_fill_op == Teuchos::null)
00630       sg_mf_jac_fill_op = 
00631   Teuchos::rcp(new FEApp::SGMatrixFreeJacobianOp(
00632                disc->getOverlapMap(),
00633                disc->getOverlapJacobianGraph(),
00634                sg_basis,
00635                alpha, beta, 
00636                sg_overlapped_xdot, 
00637                sg_overlapped_x, 
00638                sg_overlapped_ff));
00639     else
00640       sg_mf_jac_fill_op->reset(alpha, beta, sg_overlapped_xdot, 
00641              sg_overlapped_x);
00642     jac_fill_op = sg_mf_jac_fill_op;
00643   }
00644 
00645   // Get template PDE instantiation
00646   Teuchos::RCP< FEApp::AbstractPDE<SGJacobianOp::fill_type> > pde = 
00647     pdeTM.getAsObject<SGJacobianOp::fill_type>();
00648 
00649   // Do global fill
00650   FEApp::GlobalFill<SGJacobianOp::fill_type> globalFill(disc->getMesh(), 
00651               quad, pde, bc, 
00652               transient);
00653   globalFill.computeGlobalFill(*jac_fill_op);
00654 
00655   // Assemble global residual
00656   if (sg_f != NULL)
00657     sg_f->Export(*sg_overlapped_f, *sg_exporter, Add);
00658 
00659   
00660   if (sg_solver_method == "Fully Assembled") {
00661     // Cast sg_jacOp to an Epetra_CrsMatrix
00662     Epetra_CrsMatrix& sg_jac = dynamic_cast<Epetra_CrsMatrix&>(sg_jacOp);
00663 
00664     // Assemble global Jacobian
00665     sg_jac.PutScalar(0.0);
00666     sg_jac.Export(*sg_overlapped_jac, *sg_exporter, Add);
00667     sg_jac.FillComplete(true);
00668 
00669 //     Epetra_Vector input(*(sg_disc->getMap()));
00670 //     Epetra_Vector result(*(sg_disc->getMap()));
00671 //     input.PutScalar(1.0);
00672 //     sg_jac.Apply(input, result);
00673 //     result.Print(std::cout);
00674   }
00675   else if (sg_solver_method == "Matrix Free Mean Prec") {
00676     // Cast sg_jacOp to an FEApp::SGMatrixFreeOp
00677     FEApp::SGMatrixFreeOp& sg_jac = 
00678       dynamic_cast<FEApp::SGMatrixFreeOp&>(sg_jacOp);
00679     
00680     // Assemble block Jacobians
00681     std::vector< Teuchos::RCP<Epetra_CrsMatrix> > jacs = 
00682       sg_jac.getJacobianBlocks();
00683     std::vector< Teuchos::RCP<Epetra_CrsMatrix> > ov_jacs = 
00684       sg_mf_jac_fill_op->getJacobianBlocks();
00685     for (unsigned int i=0; i<jacs.size(); i++) {
00686       jacs[i]->PutScalar(0.0);
00687       jacs[i]->Export(*ov_jacs[i], *exporter, Add);
00688       jacs[i]->FillComplete(true);
00689     }
00690 
00691 //     Epetra_Vector input(*(sg_disc->getMap()));
00692 //     Epetra_Vector result(*(sg_disc->getMap()));
00693 //     input.PutScalar(1.0);
00694 //     sg_jac.Apply(input, result);
00695 //     result.Print(std::cout);
00696   }
00697 #endif
00698 }
00699 
00700 void
00701 FEApp::Application::computeGlobalSGPreconditioner(
00702               double alpha, double beta,
00703               const Epetra_Vector* sg_xdot,
00704               const Epetra_Vector& sg_x,
00705               const Sacado::ScalarParameterVector* p,
00706               Epetra_Vector* sg_f,
00707               Epetra_Operator& sg_jacOp)
00708 {
00709 #if SGFAD_ACTIVE
00710   
00711   // We are assuming we have a valid and up-to-date fill
00712   // from computeGlobalSGJacobian()
00713 
00714   // Assemble global residual
00715   if (sg_f != NULL)
00716     sg_f->Export(*sg_overlapped_f, *sg_exporter, Add);
00717   
00718   if (sg_solver_method == "Fully Assembled") {
00719     // Cast sg_jacOp to an Epetra_CrsMatrix
00720     Epetra_CrsMatrix& sg_jac = dynamic_cast<Epetra_CrsMatrix&>(sg_jacOp);
00721 
00722     // Assemble global Jacobian
00723     sg_jac.PutScalar(0.0);
00724     sg_jac.Export(*sg_overlapped_jac, *sg_exporter, Add);
00725     sg_jac.FillComplete(true);
00726   }
00727   else if (sg_solver_method == "Matrix Free Mean Prec") {
00728     // Cast sg_jacOp to an FEApp::SGMeanPrecOp
00729     FEApp::SGMeanPrecOp& sg_jac = 
00730       dynamic_cast<FEApp::SGMeanPrecOp&>(sg_jacOp);
00731     
00732     // Assemble mean Jacobian
00733     Teuchos::RCP<Epetra_CrsMatrix> mean_jac = 
00734       sg_jac.getMeanJacobian();
00735     std::vector< Teuchos::RCP<Epetra_CrsMatrix> > ov_jacs = 
00736       sg_mf_jac_fill_op->getJacobianBlocks();
00737     mean_jac->PutScalar(0.0);
00738     mean_jac->Export(*ov_jacs[0], *exporter, Add);
00739     mean_jac->FillComplete(true);
00740     sg_jac.reset();
00741   }
00742 #endif
00743 }

Generated on Wed May 12 21:59:03 2010 for Sacado Package Browser (Single Doxygen Collection) by  doxygen 1.4.7