00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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
00048 paramLib = Teuchos::rcp(new Sacado::ScalarParameterLibrary);
00049
00050
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
00058 unsigned int num_equations = problem->numEquations();
00059
00060
00061 Teuchos::RCP<Teuchos::ParameterList> quadParams =
00062 Teuchos::rcp(&(params->sublist("Quadrature")),false);
00063 FEApp::QuadratureFactory quadFactory(quadParams);
00064 quad = quadFactory.create();
00065
00066
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
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
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
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
00260 overlapped_x->Import(x, *importer, Insert);
00261
00262
00263 if (transient)
00264 overlapped_xdot->Import(*xdot, *importer, Insert);
00265
00266
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
00274 overlapped_f->PutScalar(0.0);
00275 f.PutScalar(0.0);
00276
00277
00278 Teuchos::RCP<FEApp::ResidualOp> op;
00279 op = Teuchos::rcp(new FEApp::ResidualOp(overlapped_xdot, overlapped_x,
00280 overlapped_f));
00281
00282
00283 Teuchos::RCP< FEApp::AbstractPDE<ResidualOp::fill_type> > pde =
00284 pdeTM.getAsObject<ResidualOp::fill_type>();
00285
00286
00287 FEApp::GlobalFill<ResidualOp::fill_type> globalFill(disc->getMesh(), quad,
00288 pde, bc, transient);
00289 globalFill.computeGlobalFill(*op);
00290
00291
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
00310 Epetra_CrsMatrix& jac = dynamic_cast<Epetra_CrsMatrix&>(jacOp);
00311
00312
00313 overlapped_x->Import(x, *importer, Insert);
00314
00315
00316 if (transient)
00317 overlapped_xdot->Import(*xdot, *importer, Insert);
00318
00319
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
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
00335 overlapped_jac->PutScalar(0.0);
00336 jac.PutScalar(0.0);
00337
00338
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
00345 Teuchos::RCP< FEApp::AbstractPDE<JacobianOp::fill_type> > pde =
00346 pdeTM.getAsObject<JacobianOp::fill_type>();
00347
00348
00349 FEApp::GlobalFill<JacobianOp::fill_type> globalFill(disc->getMesh(),
00350 quad, pde, bc,
00351 transient);
00352 globalFill.computeGlobalFill(*op);
00353
00354
00355 if (f != NULL)
00356 f->Export(*overlapped_f, *exporter, Add);
00357
00358
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
00379 Epetra_CrsMatrix& jac = dynamic_cast<Epetra_CrsMatrix&>(jacOp);
00380
00381
00382 overlapped_x->Import(x, *importer, Insert);
00383
00384
00385 if (transient)
00386 overlapped_xdot->Import(*xdot, *importer, Insert);
00387
00388
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
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
00404 overlapped_jac->PutScalar(0.0);
00405 jac.PutScalar(0.0);
00406
00407
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
00414 Teuchos::RCP< FEApp::AbstractPDE<JacobianOp::fill_type> > pde =
00415 pdeTM.getAsObject<JacobianOp::fill_type>();
00416
00417
00418 FEApp::GlobalFill<JacobianOp::fill_type> globalFill(disc->getMesh(),
00419 quad, pde, bc,
00420 transient);
00421 globalFill.computeGlobalFill(*op);
00422
00423
00424 if (f != NULL)
00425 f->Export(*overlapped_f, *exporter, Add);
00426
00427
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
00447 overlapped_x->Import(x, *importer, Insert);
00448
00449
00450 if (transient)
00451 overlapped_xdot->Import(*xdot, *importer, Insert);
00452
00453
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
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
00505 Teuchos::RCP< FEApp::AbstractPDE<JacobianOp::fill_type> > pde =
00506 pdeTM.getAsObject<JacobianOp::fill_type>();
00507
00508
00509 FEApp::GlobalFill<JacobianOp::fill_type> globalFill(disc->getMesh(),
00510 quad, pde, bc,
00511 transient);
00512 globalFill.computeGlobalFill(*op);
00513
00514
00515 if (f != NULL)
00516 f->Export(*overlapped_f, *exporter, Add);
00517
00518
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
00534 sg_overlapped_x->Import(sg_x, *sg_importer, Insert);
00535
00536
00537 if (transient)
00538 sg_overlapped_xdot->Import(*sg_xdot, *sg_importer, Insert);
00539
00540
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
00548 sg_overlapped_f->PutScalar(0.0);
00549 sg_f.PutScalar(0.0);
00550
00551
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
00563 Teuchos::RCP< FEApp::AbstractPDE<SGResidualOp::fill_type> > pde =
00564 pdeTM.getAsObject<SGResidualOp::fill_type>();
00565
00566
00567 FEApp::GlobalFill<SGResidualOp::fill_type> globalFill(disc->getMesh(), quad,
00568 pde, bc, transient);
00569 globalFill.computeGlobalFill(*sg_res_fill_op);
00570
00571
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
00587 sg_overlapped_x->Import(sg_x, *sg_importer, Insert);
00588
00589
00590 if (transient)
00591 sg_overlapped_xdot->Import(*sg_xdot, *sg_importer, Insert);
00592
00593
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
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
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
00646 Teuchos::RCP< FEApp::AbstractPDE<SGJacobianOp::fill_type> > pde =
00647 pdeTM.getAsObject<SGJacobianOp::fill_type>();
00648
00649
00650 FEApp::GlobalFill<SGJacobianOp::fill_type> globalFill(disc->getMesh(),
00651 quad, pde, bc,
00652 transient);
00653 globalFill.computeGlobalFill(*jac_fill_op);
00654
00655
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
00662 Epetra_CrsMatrix& sg_jac = dynamic_cast<Epetra_CrsMatrix&>(sg_jacOp);
00663
00664
00665 sg_jac.PutScalar(0.0);
00666 sg_jac.Export(*sg_overlapped_jac, *sg_exporter, Add);
00667 sg_jac.FillComplete(true);
00668
00669
00670
00671
00672
00673
00674 }
00675 else if (sg_solver_method == "Matrix Free Mean Prec") {
00676
00677 FEApp::SGMatrixFreeOp& sg_jac =
00678 dynamic_cast<FEApp::SGMatrixFreeOp&>(sg_jacOp);
00679
00680
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
00692
00693
00694
00695
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
00712
00713
00714
00715 if (sg_f != NULL)
00716 sg_f->Export(*sg_overlapped_f, *sg_exporter, Add);
00717
00718 if (sg_solver_method == "Fully Assembled") {
00719
00720 Epetra_CrsMatrix& sg_jac = dynamic_cast<Epetra_CrsMatrix&>(sg_jacOp);
00721
00722
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
00729 FEApp::SGMeanPrecOp& sg_jac =
00730 dynamic_cast<FEApp::SGMeanPrecOp&>(sg_jacOp);
00731
00732
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 }