45 #include "Stokhos_Ifpack2.hpp"
58 #include "Ifpack2_Factory.hpp"
59 #include "BelosLinearProblem.hpp"
60 #include "kokkos_pce_specializations.hpp"
61 #include "BelosPseudoBlockCGSolMgr.hpp"
62 #include "BelosPseudoBlockGmresSolMgr.hpp"
63 #include "MatrixMarket_Tpetra.hpp"
64 #include "BelosBlockGmresSolMgr.hpp"
127 typedef double MeshScalar;
128 typedef double BasisScalar;
141 MPI_Init(&argc,&argv);
149 RCP<const Epetra_Comm> globalComm;
155 MyPID = globalComm->MyPID();
160 "This example runs an interlaced stochastic Galerkin solvers.\n");
163 CLP.
setOption(
"num_mesh", &n,
"Number of mesh points in each direction");
165 bool symmetric =
false;
166 CLP.
setOption(
"symmetric",
"unsymmetric", &symmetric,
167 "Symmetric discretization");
169 int num_spatial_procs = -1;
170 CLP.
setOption(
"num_spatial_procs", &num_spatial_procs,
"Number of spatial processors (set -1 for all available procs)");
175 "Random field type");
181 CLP.
setOption(
"std_dev", &s,
"Standard deviation");
184 CLP.
setOption(
"num_kl", &num_KL,
"Number of KL terms");
187 CLP.
setOption(
"order", &order,
"Polynomial order");
189 bool normalize_basis =
true;
190 CLP.
setOption(
"normalize",
"unnormalize", &normalize_basis,
191 "Normalize PC basis");
194 CLP.
setOption(
"solver_method", &solver_method,
196 "Krylov solver method");
199 CLP.
setOption(
"prec_method", &prec_method,
201 "Preconditioner method");
204 CLP.
setOption(
"division_method", &division_method,
206 "Stochastic division method");
209 CLP.
setOption(
"divprec_method", &divprec_method,
211 "Preconditioner for division method");
213 CLP.
setOption(
"schur_option", &schur_option,
217 CLP.
setOption(
"prec_option", &prec_option,
222 double solver_tol = 1e-12;
223 CLP.
setOption(
"solver_tol", &solver_tol,
"Outer solver tolerance");
225 double div_tol = 1e-6;
226 CLP.
setOption(
"div_tol", &div_tol,
"Tolerance in Iterative Solver");
229 CLP.
setOption(
"prec_level", &prec_level,
"Level in Schur Complement Prec 0->Solve A0u0=g0 with division; 1->Form 1x1 Schur Complement");
232 CLP.
setOption(
"max_it_div", &max_it_div,
"Maximum # of Iterations in Iterative Solver for Division");
234 bool equilibrate =
true;
235 CLP.
setOption(
"equilibrate",
"noequilibrate", &equilibrate,
236 "Equilibrate the linear system");
239 CLP.
parse( argc, argv );
242 std::cout <<
"Summary of command line options:" << std::endl
243 <<
"\tnum_mesh = " << n << std::endl
244 <<
"\tsymmetric = " << symmetric << std::endl
245 <<
"\tnum_spatial_procs = " << num_spatial_procs << std::endl
248 <<
"\tmean = " << mu << std::endl
249 <<
"\tstd_dev = " << s << std::endl
250 <<
"\tnum_kl = " << num_KL << std::endl
251 <<
"\torder = " << order << std::endl
252 <<
"\tnormalize_basis = " << normalize_basis << std::endl
254 <<
"\tprec_method = " <<
sg_prec_names[prec_method] << std::endl
255 <<
"\tdivision_method = " <<
sg_div_names[division_method] << std::endl
256 <<
"\tdiv_tol = " << div_tol << std::endl
258 <<
"\tprec_level = " << prec_level << std::endl
259 <<
"\tmax_it_div = " << max_it_div << std::endl;
261 bool nonlinear_expansion =
false;
263 nonlinear_expansion =
false;
265 nonlinear_expansion =
true;
277 RCP<const Stokhos::CompletePolynomialBasis<LocalOrdinal,BasisScalar> > basis =
280 RCP<Stokhos::Sparse3Tensor<LocalOrdinal,BasisScalar> > Cijk =
281 basis->computeTripleProductTensor();
282 RCP<const Stokhos::Quadrature<int,double> > quad =
284 RCP<ParameterList> expn_params =
Teuchos::rcp(
new ParameterList);
286 expn_params->set(
"Division Strategy",
"Mean-Based");
287 expn_params->set(
"Use Quadrature for Division",
false);
289 else if (division_method ==
DIRECT) {
290 expn_params->set(
"Division Strategy",
"Dense Direct");
291 expn_params->set(
"Use Quadrature for Division",
false);
294 expn_params->set(
"Division Strategy",
"SPD Dense Direct");
295 expn_params->set(
"Use Quadrature for Division",
false);
297 else if (division_method ==
CGD) {
298 expn_params->set(
"Division Strategy",
"CG");
299 expn_params->set(
"Use Quadrature for Division",
false);
302 else if (division_method ==
QUAD) {
303 expn_params->set(
"Use Quadrature for Division",
true);
306 if (divprec_method ==
NO)
307 expn_params->set(
"Prec Strategy",
"None");
308 else if (divprec_method ==
DIAG)
309 expn_params->set(
"Prec Strategy",
"Diag");
310 else if (divprec_method ==
JACOBI)
311 expn_params->set(
"Prec Strategy",
"Jacobi");
312 else if (divprec_method ==
GS)
313 expn_params->set(
"Prec Strategy",
"GS");
314 else if (divprec_method ==
SCHUR)
315 expn_params->set(
"Prec Strategy",
"Schur");
317 if (schur_option ==
diag)
318 expn_params->set(
"Schur option",
"diag");
320 expn_params->set(
"Schur option",
"full");
321 if (prec_option ==
linear)
322 expn_params->set(
"Prec option",
"linear");
326 expn_params->set(
"Equilibrate", 1);
328 expn_params->set(
"Equilibrate", 0);
329 expn_params->set(
"Division Tolerance", div_tol);
330 expn_params->set(
"prec_iter", prec_level);
331 expn_params->set(
"max_it_div", max_it_div);
333 RCP<Stokhos::OrthogPolyExpansion<LocalOrdinal,BasisScalar> > expansion =
335 basis, Cijk, quad, expn_params));
338 std::cout <<
"Stochastic Galerkin expansion size = " << sz << std::endl;
341 ParameterList parallelParams;
342 parallelParams.set(
"Number of Spatial Processors", num_spatial_procs);
347 RCP<Stokhos::ParallelData> sg_parallel_data =
349 RCP<const EpetraExt::MultiComm> sg_comm =
350 sg_parallel_data->getMultiComm();
351 RCP<const Epetra_Comm> app_comm =
352 sg_parallel_data->getSpatialComm();
355 RCP< Teuchos::Comm<int> > teuchos_app_comm;
357 RCP<const Epetra_MpiComm> app_mpi_comm =
359 RCP<const Teuchos::OpaqueWrapper<MPI_Comm> > raw_mpi_comm =
360 Teuchos::opaqueWrapper(app_mpi_comm->Comm());
361 teuchos_app_comm =
rcp(
new Teuchos::MpiComm<int>(raw_mpi_comm));
368 RCP<problem_type> model =
369 rcp(
new problem_type(teuchos_app_comm, n, num_KL, s, mu,
370 nonlinear_expansion, symmetric));
373 typedef problem_type::Tpetra_Vector Tpetra_Vector;
374 typedef problem_type::Tpetra_CrsMatrix Tpetra_CrsMatrix;
375 typedef Tpetra::MatrixMarket::Writer<Tpetra_CrsMatrix> Writer;
377 RCP<Tpetra_Vector> p = Tpetra::createVector<Scalar>(model->get_p_map(0));
378 RCP<Tpetra_Vector> x = Tpetra::createVector<Scalar>(model->get_x_map());
380 RCP<Tpetra_Vector>
f = Tpetra::createVector<Scalar>(model->get_f_map());
381 RCP<Tpetra_Vector>
dx = Tpetra::createVector<Scalar>(model->get_x_map());
382 RCP<Tpetra_CrsMatrix> J = model->create_W();
383 RCP<Tpetra_CrsMatrix> J0;
384 if (prec_method ==
MEAN)
385 J0 = model->create_W();
389 ArrayRCP<Scalar> p_view = p->get1dViewNonConst();
390 for (ArrayRCP<Scalar>::size_type i=0; i<p_view.size(); i++) {
391 p_view[i].reset(expansion);
392 p_view[i].copyForWrite();
394 Array<double> point(num_KL, 1.0);
395 Array<double> basis_vals(sz);
396 basis->evaluateBases(point, basis_vals);
398 for (
int i=0; i<num_KL; i++) {
399 p_view[i].term(i,1) = 1.0 / basis_vals[i+1];
404 typedef Ifpack2::Preconditioner<Scalar,LocalOrdinal,GlobalOrdinal,Node> Tprec;
406 if (prec_method !=
NONE) {
407 ParameterList precParams;
408 std::string prec_name =
"RILUK";
409 precParams.set(
"fact: iluk level-of-fill", 4);
410 precParams.set(
"fact: iluk level-of-overlap", 0);
415 Ifpack2::Factory factory;
416 if (prec_method ==
MEAN) {
417 M = factory.create<Tpetra_CrsMatrix>(prec_name, J0);
419 M = factory.create<Tpetra_CrsMatrix>(prec_name, J);
421 M->setParameters(precParams);
425 model->computeResidual(*x, *p, *f);
426 model->computeJacobian(*x, *p, *J);
429 if (prec_method ==
MEAN) {
430 size_t nrows = J->getNodeNumRows();
431 ArrayView<const LocalOrdinal> indices;
432 ArrayView<const Scalar> values;
434 for (
size_t i=0; i<nrows; i++) {
435 J->getLocalRowView(i, indices, values);
436 Array<Scalar> values0(values.size());
438 values0[
j] = values[
j].coeff(0);
439 J0->replaceLocalValues(i, indices, values0);
445 if (prec_method !=
NONE) {
451 RCP<ParameterList> belosParams =
rcp(
new ParameterList);
452 belosParams->set(
"Flexible Gmres",
false);
453 belosParams->set(
"Num Blocks", 500);
454 belosParams->set(
"Convergence Tolerance", solver_tol);
455 belosParams->set(
"Maximum Iterations", 1000);
456 belosParams->set(
"Verbosity", 33);
457 belosParams->set(
"Output Style", 1);
458 belosParams->set(
"Output Frequency", 1);
460 typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> MV;
461 typedef Tpetra::Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node> OP;
462 typedef Belos::OperatorTraits<Scalar,MV,OP> BOPT;
463 typedef Belos::MultiVecTraits<double,MV> BMVT;
464 typedef Belos::LinearProblem<double,MV,OP> BLinProb;
465 RCP< BLinProb > problem =
rcp(
new BLinProb(J, dx, f));
466 if (prec_method !=
NONE)
467 problem->setRightPrec(M);
468 problem->setProblem();
469 RCP<Belos::SolverManager<double,MV,OP> > solver;
470 if (solver_method ==
CG)
471 solver =
rcp(
new Belos::PseudoBlockCGSolMgr<double,MV,OP>(problem, belosParams));
472 else if (solver_method ==
GMRES)
473 solver =
rcp(
new Belos::BlockGmresSolMgr<double,MV,OP>(problem, belosParams));
476 std::vector<double> norm_f(1);
477 BMVT::MvNorm(*f, norm_f);
479 std::cout <<
"\nInitial residual norm = " << norm_f[0] << std::endl;
482 Belos::ReturnType ret = solver->solve();
485 if (ret == Belos::Converged)
486 std::cout <<
"Solver converged!" << std::endl;
488 std::cout <<
"Solver failed to converge!" << std::endl;
492 x->update(-1.0, *dx, 1.0);
493 Writer::writeDenseFile(
"stochastic_solution.mm", x);
496 RCP<Tpetra_Vector>
g = Tpetra::createVector<Scalar>(model->get_g_map(0));
498 model->computeResidual(*x, *p, *f);
499 model->computeResponse(*x, *p, *g);
502 BMVT::MvNorm(*f, norm_f);
504 std::cout <<
"\nFinal residual norm = " << norm_f[0] << std::endl;
507 double g_mean_exp = 0.172988;
508 double g_std_dev_exp = 0.0380007;
511 g_mean_exp = 1.327563e-01;
512 g_std_dev_exp = 2.949064e-02;
515 double g_mean = g->get1dView()[0].mean();
516 double g_std_dev = g->get1dView()[0].standard_deviation();
517 std::cout << std::endl;
518 std::cout <<
"Response Mean = " << g_mean << std::endl;
519 std::cout <<
"Response Std. Dev. = " << g_std_dev << std::endl;
521 if (norm_f[0] < 1.0e-10 &&
522 std::abs(g_mean-g_mean_exp) < g_tol &&
523 std::abs(g_std_dev - g_std_dev_exp) < g_tol)
527 std::cout <<
"Example Passed!" << std::endl;
529 std::cout <<
"Example Failed!" << std::endl;
530 std::cout <<
"Expected Response Mean = "<< g_mean_exp << std::endl;
531 std::cout <<
"Expected Response Std. Dev. = "<< g_std_dev_exp << std::endl;
542 catch (std::exception& e) {
543 std::cout << e.what() << std::endl;
546 std::cout << s << std::endl;
549 std::cout << s << std::endl;
552 std::cout <<
"Caught unknown exception!" <<std:: endl;
#define TEUCHOS_FUNC_TIME_MONITOR(FUNCNAME)
const char * sg_divprec_names[]
const Prec_option Prec_option_values[]
Hermite polynomial basis.
const Krylov_Method krylov_method_values[]
const char * schur_option_names[]
const char * prec_option_names[]
const SG_Prec sg_prec_values[]
const SG_DivPrec sg_divprec_values[]
const Schur_option Schur_option_values[]
const SG_Div sg_div_values[]
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
const int num_krylov_method
static void summarize(Ptr< const Comm< int > > comm, std::ostream &out=std::cout, const bool alwaysWriteLocal=false, const bool writeGlobalStats=true, const bool writeZeroTimers=true, const ECounterSetOp setOp=Intersection, const std::string &filter="", const bool ignoreZeroTimers=false)
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
const SG_RF sg_rf_values[]
KokkosClassic::DefaultNode::DefaultNodeType Node
EParseCommandLineReturn parse(int argc, char *argv[], std::ostream *errout=&std::cerr) const
KOKKOS_INLINE_FUNCTION PCE< Storage > abs(const PCE< Storage > &a)
Multivariate orthogonal polynomial basis generated from a total-order complete-polynomial tensor prod...
const int num_schur_option
Legendre polynomial basis.
int main(int argc, char **argv)
const char * sg_rf_names[]
ScalarType f(const Teuchos::Array< ScalarType > &x, double a, double b)
void setDocString(const char doc_string[])
const char * sg_prec_names[]
const char * sg_div_names[]
Orthogonal polynomial expansions based on numerical quadrature.
const int num_prec_option
Defines quadrature for a tensor product basis by tensor products of 1-D quadrature rules...
ScalarType g(const Teuchos::Array< ScalarType > &x, const ScalarType &y)
static void zeroOutTimers()
A linear 2-D diffusion problem.
const char * krylov_method_names[]