13 #include "Stokhos_Ifpack2.hpp" 
   26 #include "Ifpack2_Factory.hpp" 
   27 #include "BelosLinearProblem.hpp" 
   28 #include "kokkos_pce_specializations.hpp" 
   29 #include "BelosPseudoBlockCGSolMgr.hpp" 
   30 #include "BelosPseudoBlockGmresSolMgr.hpp" 
   31 #include "MatrixMarket_Tpetra.hpp" 
   32 #include "BelosBlockGmresSolMgr.hpp" 
   95   typedef double MeshScalar;
 
   96   typedef double BasisScalar;
 
  109   MPI_Init(&argc,&argv);
 
  117     RCP<const Epetra_Comm> globalComm;
 
  123     MyPID = globalComm->MyPID();
 
  128       "This example runs an interlaced stochastic Galerkin solvers.\n");
 
  131     CLP.
setOption(
"num_mesh", &n, 
"Number of mesh points in each direction");
 
  133     bool symmetric = 
false;
 
  134     CLP.
setOption(
"symmetric", 
"unsymmetric", &symmetric, 
 
  135                   "Symmetric discretization");
 
  137     int num_spatial_procs = -1;
 
  138     CLP.
setOption(
"num_spatial_procs", &num_spatial_procs, 
"Number of spatial processors (set -1 for all available procs)");
 
  143                   "Random field type");
 
  149     CLP.
setOption(
"std_dev", &s, 
"Standard deviation");
 
  152     CLP.
setOption(
"num_kl", &num_KL, 
"Number of KL terms");
 
  155     CLP.
setOption(
"order", &order, 
"Polynomial order");
 
  157     bool normalize_basis = 
true;
 
  158     CLP.
setOption(
"normalize", 
"unnormalize", &normalize_basis, 
 
  159                   "Normalize PC basis");
 
  162     CLP.
setOption(
"solver_method", &solver_method, 
 
  164                   "Krylov solver method");
 
  167     CLP.
setOption(
"prec_method", &prec_method, 
 
  169                   "Preconditioner method");
 
  172     CLP.
setOption(
"division_method", &division_method, 
 
  174                   "Stochastic division method");
 
  177     CLP.
setOption(
"divprec_method", &divprec_method,
 
  179                   "Preconditioner for division method");
 
  181     CLP.
setOption(
"schur_option", &schur_option,
 
  185     CLP.
setOption(
"prec_option", &prec_option,
 
  190     double solver_tol = 1e-12;
 
  191     CLP.
setOption(
"solver_tol", &solver_tol, 
"Outer solver tolerance");
 
  193     double div_tol = 1e-6;
 
  194     CLP.
setOption(
"div_tol", &div_tol, 
"Tolerance in Iterative Solver");
 
  197     CLP.
setOption(
"prec_level", &prec_level, 
"Level in Schur Complement Prec 0->Solve A0u0=g0 with division; 1->Form 1x1 Schur Complement");
 
  200     CLP.
setOption(
"max_it_div", &max_it_div, 
"Maximum # of Iterations in Iterative Solver for Division");
 
  202     bool equilibrate = 
true; 
 
  203     CLP.
setOption(
"equilibrate", 
"noequilibrate", &equilibrate,
 
  204                   "Equilibrate the linear system");
 
  207     CLP.
parse( argc, argv );
 
  210       std::cout << 
"Summary of command line options:" << std::endl
 
  211                 << 
"\tnum_mesh           = " << n << std::endl
 
  212                 << 
"\tsymmetric          = " << symmetric << std::endl
 
  213                 << 
"\tnum_spatial_procs  = " << num_spatial_procs << std::endl
 
  216                 << 
"\tmean               = " << mu << std::endl
 
  217                 << 
"\tstd_dev            = " << s << std::endl
 
  218                 << 
"\tnum_kl             = " << num_KL << std::endl
 
  219                 << 
"\torder              = " << order << std::endl
 
  220                 << 
"\tnormalize_basis    = " << normalize_basis << std::endl
 
  222                 << 
"\tprec_method        = " << 
sg_prec_names[prec_method]    << std::endl
 
  223                 << 
"\tdivision_method    = " << 
sg_div_names[division_method]     << std::endl
 
  224                 << 
"\tdiv_tol            = " << div_tol << std::endl
 
  226                 << 
"\tprec_level         = " << prec_level << std::endl
 
  227                 << 
"\tmax_it_div     = " << max_it_div << std::endl;
 
  229     bool nonlinear_expansion = 
false;
 
  231       nonlinear_expansion = 
false;
 
  233       nonlinear_expansion = 
true;
 
  245     RCP<const Stokhos::CompletePolynomialBasis<LocalOrdinal,BasisScalar> > basis = 
 
  248     RCP<Stokhos::Sparse3Tensor<LocalOrdinal,BasisScalar> > Cijk = 
 
  249       basis->computeTripleProductTensor();
 
  250     RCP<const Stokhos::Quadrature<int,double> > quad = 
 
  252     RCP<ParameterList> expn_params = 
Teuchos::rcp(
new ParameterList);
 
  254       expn_params->set(
"Division Strategy", 
"Mean-Based");
 
  255       expn_params->set(
"Use Quadrature for Division", 
false);
 
  257     else if (division_method == 
DIRECT) {
 
  258       expn_params->set(
"Division Strategy", 
"Dense Direct");
 
  259       expn_params->set(
"Use Quadrature for Division", 
false);
 
  262       expn_params->set(
"Division Strategy", 
"SPD Dense Direct");
 
  263       expn_params->set(
"Use Quadrature for Division", 
false);
 
  265     else if (division_method == 
CGD) {
 
  266       expn_params->set(
"Division Strategy", 
"CG");
 
  267       expn_params->set(
"Use Quadrature for Division", 
false);
 
  270     else if (division_method == 
QUAD) {
 
  271       expn_params->set(
"Use Quadrature for Division", 
true);
 
  274     if (divprec_method == 
NO)
 
  275          expn_params->set(
"Prec Strategy", 
"None");
 
  276     else if (divprec_method == 
DIAG)
 
  277          expn_params->set(
"Prec Strategy", 
"Diag");
 
  278     else if (divprec_method == 
JACOBI)
 
  279          expn_params->set(
"Prec Strategy", 
"Jacobi");
 
  280     else if (divprec_method == 
GS)
 
  281          expn_params->set(
"Prec Strategy", 
"GS");
 
  282     else if (divprec_method == 
SCHUR)
 
  283          expn_params->set(
"Prec Strategy", 
"Schur");
 
  285     if (schur_option == 
diag)
 
  286         expn_params->set(
"Schur option", 
"diag");
 
  288         expn_params->set(
"Schur option", 
"full");
 
  289     if (prec_option == 
linear)
 
  290         expn_params->set(
"Prec option", 
"linear");
 
  294       expn_params->set(
"Equilibrate", 1);
 
  296       expn_params->set(
"Equilibrate", 0); 
 
  297     expn_params->set(
"Division Tolerance", div_tol);
 
  298     expn_params->set(
"prec_iter", prec_level);
 
  299     expn_params->set(
"max_it_div", max_it_div);
 
  301     RCP<Stokhos::OrthogPolyExpansion<LocalOrdinal,BasisScalar> > expansion = 
 
  303             basis, Cijk, quad, expn_params));
 
  306       std::cout << 
"Stochastic Galerkin expansion size = " << sz << std::endl;
 
  309     ParameterList parallelParams;
 
  310     parallelParams.set(
"Number of Spatial Processors", num_spatial_procs);
 
  315     RCP<Stokhos::ParallelData> sg_parallel_data =
 
  317     RCP<const EpetraExt::MultiComm> sg_comm = 
 
  318       sg_parallel_data->getMultiComm();
 
  319     RCP<const Epetra_Comm> app_comm = 
 
  320       sg_parallel_data->getSpatialComm();
 
  323     RCP< Teuchos::Comm<int> > teuchos_app_comm;
 
  325     RCP<const Epetra_MpiComm> app_mpi_comm = 
 
  327     RCP<const Teuchos::OpaqueWrapper<MPI_Comm> > raw_mpi_comm = 
 
  328       Teuchos::opaqueWrapper(app_mpi_comm->Comm());
 
  329     teuchos_app_comm = 
rcp(
new Teuchos::MpiComm<int>(raw_mpi_comm));
 
  336     RCP<problem_type> model = 
 
  337       rcp(
new problem_type(teuchos_app_comm, n, num_KL, s, mu, 
 
  338                nonlinear_expansion, symmetric));
 
  341     typedef problem_type::Tpetra_Vector Tpetra_Vector;
 
  342     typedef problem_type::Tpetra_CrsMatrix Tpetra_CrsMatrix;
 
  343     typedef Tpetra::MatrixMarket::Writer<Tpetra_CrsMatrix> Writer;
 
  345     RCP<Tpetra_Vector> p = Tpetra::createVector<Scalar>(model->get_p_map(0));
 
  346     RCP<Tpetra_Vector> x = Tpetra::createVector<Scalar>(model->get_x_map());
 
  348     RCP<Tpetra_Vector> 
f = Tpetra::createVector<Scalar>(model->get_f_map());
 
  349     RCP<Tpetra_Vector> 
dx = Tpetra::createVector<Scalar>(model->get_x_map());
 
  350     RCP<Tpetra_CrsMatrix> J = model->create_W();
 
  351     RCP<Tpetra_CrsMatrix> J0;
 
  352     if (prec_method == 
MEAN)
 
  353       J0 = model->create_W();
 
  357     ArrayRCP<Scalar> p_view = p->get1dViewNonConst();
 
  358     for (ArrayRCP<Scalar>::size_type i=0; i<p_view.size(); i++) {
 
  359       p_view[i].reset(expansion);
 
  360       p_view[i].copyForWrite();
 
  362     Array<double> point(num_KL, 1.0);
 
  363     Array<double> basis_vals(sz);
 
  364     basis->evaluateBases(point, basis_vals);
 
  366       for (
int i=0; i<num_KL; i++) {
 
  367         p_view[i].term(i,1) = 1.0 / basis_vals[i+1];
 
  372     typedef Ifpack2::Preconditioner<Scalar,LocalOrdinal,GlobalOrdinal,Node> Tprec;
 
  374     if (prec_method != 
NONE) {
 
  375       ParameterList precParams;
 
  376       std::string prec_name = 
"RILUK";
 
  377       precParams.set(
"fact: iluk level-of-fill", 4);
 
  378       precParams.set(
"fact: iluk level-of-overlap", 0);
 
  383       Ifpack2::Factory factory;
 
  384       if (prec_method == 
MEAN) {
 
  385         M = factory.create<Tpetra_CrsMatrix>(prec_name, J0);
 
  387         M = factory.create<Tpetra_CrsMatrix>(prec_name, J);
 
  389       M->setParameters(precParams);
 
  393     model->computeResidual(*x, *p, *f);
 
  394     model->computeJacobian(*x, *p, *J);
 
  397     if (prec_method == 
MEAN) {
 
  398       size_t nrows = J->getLocalNumRows();
 
  399       ArrayView<const LocalOrdinal> indices;
 
  400       ArrayView<const Scalar> values;
 
  402       for (
size_t i=0; i<nrows; i++) {
 
  403         J->getLocalRowView(i, indices, values);
 
  404         Array<Scalar> values0(values.size());
 
  406           values0[
j] = values[
j].coeff(0);
 
  407         J0->replaceLocalValues(i, indices, values0);
 
  413     if (prec_method != 
NONE) {
 
  419     RCP<ParameterList> belosParams = 
rcp(
new ParameterList);
 
  420     belosParams->set(
"Flexible Gmres", 
false);
 
  421     belosParams->set(
"Num Blocks", 500);
 
  422     belosParams->set(
"Convergence Tolerance", solver_tol);
 
  423     belosParams->set(
"Maximum Iterations", 1000);
 
  424     belosParams->set(
"Verbosity", 33);
 
  425     belosParams->set(
"Output Style", 1);
 
  426     belosParams->set(
"Output Frequency", 1);
 
  428     typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> MV;
 
  429     typedef Tpetra::Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node> OP;
 
  430     typedef Belos::OperatorTraits<Scalar,MV,OP> BOPT;
 
  431     typedef Belos::MultiVecTraits<double,MV> BMVT;
 
  432     typedef Belos::LinearProblem<double,MV,OP> BLinProb;
 
  433     RCP< BLinProb > problem = 
rcp(
new BLinProb(J, dx, f));
 
  434     if (prec_method != 
NONE)
 
  435       problem->setRightPrec(M);
 
  436     problem->setProblem();
 
  437     RCP<Belos::SolverManager<double,MV,OP> > solver;
 
  438     if (solver_method == 
CG)
 
  439       solver = 
rcp(
new Belos::PseudoBlockCGSolMgr<double,MV,OP>(problem, belosParams));
 
  440     else if (solver_method == 
GMRES)
 
  441       solver = 
rcp(
new Belos::BlockGmresSolMgr<double,MV,OP>(problem, belosParams));
 
  444     std::vector<double> norm_f(1);
 
  445     BMVT::MvNorm(*f, norm_f);
 
  447       std::cout << 
"\nInitial residual norm = " << norm_f[0] << std::endl;
 
  450     Belos::ReturnType ret = solver->solve();
 
  453       if (ret == Belos::Converged)
 
  454         std::cout << 
"Solver converged!" << std::endl;
 
  456         std::cout << 
"Solver failed to converge!" << std::endl;
 
  460     x->update(-1.0, *dx, 1.0);
 
  461     Writer::writeDenseFile(
"stochastic_solution.mm", x);
 
  464     RCP<Tpetra_Vector> 
g = Tpetra::createVector<Scalar>(model->get_g_map(0));
 
  466     model->computeResidual(*x, *p, *f);
 
  467     model->computeResponse(*x, *p, *g);
 
  470     BMVT::MvNorm(*f, norm_f);
 
  472       std::cout << 
"\nFinal residual norm = " << norm_f[0] << std::endl;
 
  475     double g_mean_exp = 0.172988;      
 
  476     double g_std_dev_exp = 0.0380007;  
 
  479       g_mean_exp = 1.327563e-01;
 
  480       g_std_dev_exp = 2.949064e-02;
 
  483     double g_mean = g->get1dView()[0].mean();
 
  484     double g_std_dev = g->get1dView()[0].standard_deviation();
 
  485     std::cout << std::endl;
 
  486     std::cout << 
"Response Mean =      " << g_mean << std::endl;
 
  487     std::cout << 
"Response Std. Dev. = " << g_std_dev << std::endl;
 
  489     if (norm_f[0] < 1.0e-10 &&
 
  490         std::abs(g_mean-g_mean_exp) < g_tol &&
 
  491         std::abs(g_std_dev - g_std_dev_exp) < g_tol)
 
  495         std::cout << 
"Example Passed!" << std::endl;
 
  497         std::cout << 
"Example Failed!" << std::endl;
 
  498         std::cout << 
"Expected Response Mean      = "<< g_mean_exp << std::endl;
 
  499         std::cout << 
"Expected Response Std. Dev. = "<< g_std_dev_exp << std::endl;
 
  510   catch (std::exception& e) {
 
  511     std::cout << e.what() << std::endl;
 
  514     std::cout << s << std::endl;
 
  517     std::cout << s << std::endl;
 
  520     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[]
 
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[]
 
Tpetra::KokkosClassic::DefaultNode::DefaultNodeType Node
 
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[]