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[]