Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
experimental/linear2d_diffusion_pce.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Stokhos Package
4 //
5 // Copyright 2009 NTESS and the Stokhos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 // Stokhos Stochastic Galerkin
11 #include "Stokhos_Epetra.hpp"
12 #include "Stokhos_Sacado.hpp"
13 #include "Stokhos_Ifpack2.hpp"
14 
15 // Class implementing our problem
17 
18 // Epetra communicator
19 #ifdef HAVE_MPI
20 #include "Epetra_MpiComm.h"
21 #else
22 #include "Epetra_SerialComm.h"
23 #endif
24 
25 // solver
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"
33 
34 // Utilities
35 #include "Teuchos_TimeMonitor.hpp"
37 
38 // Scalar types
40 
41 // MueLu includes
42 #include "Stokhos_MueLu.hpp"
43 #include "Stokhos_MueLu_QR_Interface_decl.hpp"
44 #include "Stokhos_MueLu_QR_Interface_def.hpp"
45 #include "MueLu_SmootherFactory.hpp"
46 #include "MueLu_TrilinosSmoother.hpp"
47 typedef Tpetra::KokkosClassic::DefaultNode::DefaultNodeType Node;
48 //#include <MueLu_UseShortNames.hpp>
49 
50 #include <BelosXpetraAdapter.hpp> // => This header defines Belos::XpetraOp
51 #include <BelosMueLuAdapter.hpp> // => This header defines Belos::MueLuOp
52 
53 #include "Xpetra_MultiVectorFactory.hpp"
54 #include "Xpetra_Matrix.hpp"
55 #include "Xpetra_Map.hpp"
56 #include "MueLu_Level.hpp"
57 #include "MueLu_CoupledAggregationFactory.hpp"
58 #include "MueLu_SaPFactory.hpp"
59 
60 // Random field types
62 const int num_sg_rf = 2;
64 const char *sg_rf_names[] = { "Uniform", "Log-Normal" };
65 
66 // Krylov methods
68 const int num_krylov_method = 2;
70 const char *krylov_method_names[] = { "GMRES", "CG" };
71 
72 // Multigrid preconditioning
74 const int num_multigrid_smoother = 2;
76 const char *multigrid_smoother_names[] = { "Chebyshev", "SGS" };
77 
78 // Preconditioning approaches
80 const int num_sg_prec = 3;
82 const char *sg_prec_names[] = { "None",
83  "Mean-Based",
84  "Stochastic" };
85 
86 // Stochastic division approaches
88 const int num_sg_div = 5;
90 const char *sg_div_names[] = { "Direct",
91  "SPD-Direct",
92  "Mean-Based",
93  "Quadrature",
94  "CG"};
95 
96 // Stochastic division preconditioner approaches
98 const int num_sg_divprec = 5;
100 const char *sg_divprec_names[] = { "None",
101  "Diag",
102  "Jacobi",
103  "GS",
104  "Schur"};
105 
106 
107 // Option for Schur complement precond: full or diag D
109 const int num_schur_option = 2;
111 const char *schur_option_names[] = { "full", "diag"};
112 
113 // Full matrix or linear matrix (pb = dim + 1 ) used for preconditioner
115 const int num_prec_option = 2;
117 const char *prec_option_names[] = { "full", "linear"};
118 
119 // #define _GNU_SOURCE 1
120 // #include <fenv.h>
121 
122 template<typename ordinal_type, typename value_type, typename Storage>
123 //void returnScalarAsDenseMatrix(Scalar const &inval,
127 {
128  Stokhos::OrthogPolyApprox<ordinal_type, value_type> val= inval.getOrthogPolyApprox();
130  ordinal_type pb = val.size();
131  const value_type* cv = val.coeff();
132 
133  denseEntry->putScalar(0.0);
134  typename Cijk_type::k_iterator k_begin = Cijk->k_begin();
135  typename Cijk_type::k_iterator k_end = Cijk->k_end();
136  if (pb < Cijk->num_k())
137  k_end = Cijk->find_k(pb);
139  ordinal_type i,j,k;
140  for (typename Cijk_type::k_iterator k_it=k_begin; k_it!=k_end; ++k_it) {
141  k = index(k_it);
142  for (typename Cijk_type::kj_iterator j_it = Cijk->j_begin(k_it); j_it != Cijk->j_end(k_it); ++j_it) {
143  j = index(j_it);
144  for (typename Cijk_type::kji_iterator i_it = Cijk->i_begin(j_it); i_it != Cijk->i_end(j_it); ++i_it) {
145  i = index(i_it);
146  cijk = value(i_it);
147  (*denseEntry)(i,j) += cijk*cv[k];
148  }
149  }
150  }
151 }
152 
153 typedef Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> Xpetra_Matrix;
154 typedef Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node> Xpetra_Map;
155 
156 template<typename ordinal_type,typename value_type>
160 {
161  ordinal_type sz = basis->size();
163  sz, sz));
164  size_t maxLength = A->getLocalMaxNumRowEntries();
165  size_t NumEntries;
166  Scalar val;
167  Teuchos::Array<ordinal_type> Indices(maxLength);
168  Teuchos::Array<Scalar> Values(maxLength);
169  Teuchos::RCP<const Xpetra_Map> colMap = A->getColMap();
170  for (ordinal_type i = 0 ; i < Teuchos::as<ordinal_type>(A->getLocalNumRows()); ++i) {
171  A->getLocalRowCopy(i, Indices(), Values(), NumEntries);
172  fos << "++++++++++++++" << std::endl << "row " << A->getRowMap()->getGlobalElement(i) << ": ";
173  fos << " col ids: ";
174  for (size_t ii=0; ii<NumEntries; ++ii) fos << colMap->getGlobalElement(Indices[ii]) << " ";
175  fos << std::endl << "++++++++++++++" << std::endl;
176  for (size_t k=0; k< NumEntries; ++k) {
177  val = Values[k];
178  Teuchos::OSTab tab1(fos);
179  fos << std::endl << "col " << colMap->getGlobalElement(Indices[k]) << std::endl;
180  returnScalarAsDenseMatrix(val,denseEntry,Cijk);
181  //TODO tab thing
182  Teuchos::OSTab tab2(fos);
183  denseEntry->print(fos);
184  }
185  }
186 }
187 
188 int main(int argc, char *argv[]) {
189  typedef double MeshScalar;
190  typedef double BasisScalar;
192  typedef Teuchos::ScalarTraits<Scalar>::magnitudeType magnitudeType;
193 
194  using Teuchos::RCP;
195  using Teuchos::rcp;
196  using Teuchos::Array;
197  using Teuchos::ArrayRCP;
198  using Teuchos::ArrayView;
200 
201 // Initialize MPI
202 #ifdef HAVE_MPI
203  MPI_Init(&argc,&argv);
204 #endif
205 
206  LocalOrdinal MyPID;
207 
208  try {
209 
210  // Create a communicator for Epetra objects
211  RCP<const Epetra_Comm> globalComm;
212 #ifdef HAVE_MPI
213  globalComm = rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
214 #else
215  globalComm = rcp(new Epetra_SerialComm);
216 #endif
217  MyPID = globalComm->MyPID();
218 
219  // Setup command line options
221  CLP.setDocString(
222  "This example runs an interlaced stochastic Galerkin solvers.\n");
223 
224  int n = 32;
225  CLP.setOption("num_mesh", &n, "Number of mesh points in each direction");
226 
227  // multigrid specific options
228  int minAggSize = 1;
229  CLP.setOption("min_agg_size", &minAggSize, "multigrid aggregate size");
230  Multigrid_Smoother smoother_type = CHEBYSHEV;
231  CLP.setOption("smoother_type", &smoother_type,
233  "Multigrid smoother types");
234  int smootherSweeps = 3;
235  CLP.setOption("smoother_sweeps", &smootherSweeps, "# multigrid smoother sweeps");
236  bool plainAgg=false;
237  CLP.setOption("plain_aggregation", "smoothed_aggregation", &plainAgg, "multigrid prolongator smoothing");
238  LocalOrdinal nsSize=1;
239  CLP.setOption("nullspace_size", &nsSize, "multigrid nullspace dimension");
240  int maxAMGLevels=10;
241  CLP.setOption("max_multigrid_levels", &maxAMGLevels, "maximum # levels in multigrid preconditioner");
242 
243  bool printTimings=true;
244  CLP.setOption("timings", "notimings", &printTimings, "print timing summary");
245 
246 
247  bool symmetric = false;
248  CLP.setOption("symmetric", "unsymmetric", &symmetric, "Symmetric discretization");
249 
250  int num_spatial_procs = -1;
251  CLP.setOption("num_spatial_procs", &num_spatial_procs, "Number of spatial processors (set -1 for all available procs)");
252 
253  SG_RF randField = UNIFORM;
254  CLP.setOption("rand_field", &randField,
256  "Random field type");
257 
258  double mu = 0.2;
259  CLP.setOption("mean", &mu, "Mean");
260 
261  double s = 0.1;
262  CLP.setOption("std_dev", &s, "Standard deviation");
263 
264  int num_KL = 2;
265  CLP.setOption("num_kl", &num_KL, "Number of KL terms");
266 
267  int order = 3;
268  CLP.setOption("order", &order, "Polynomial order");
269 
270  bool normalize_basis = true;
271  CLP.setOption("normalize", "unnormalize", &normalize_basis,
272  "Normalize PC basis");
273 
274  Krylov_Method solver_method = GMRES;
275  CLP.setOption("solver_method", &solver_method,
277  "Krylov solver method");
278 
279  SG_Prec prec_method = STOCHASTIC;
280  CLP.setOption("prec_method", &prec_method,
282  "Preconditioner method");
283 
284  SG_Div division_method = DIRECT;
285  CLP.setOption("division_method", &division_method,
287  "Stochastic division method");
288 
289  SG_DivPrec divprec_method = NO;
290  CLP.setOption("divprec_method", &divprec_method,
292  "Preconditioner for division method");
293  Schur_option schur_option = diag;
294  CLP.setOption("schur_option", &schur_option,
296  "Schur option");
297  Prec_option prec_option = whole;
298  CLP.setOption("prec_option", &prec_option,
300  "Prec option");
301 
302 
303  double solver_tol = 1e-12;
304  CLP.setOption("solver_tol", &solver_tol, "Outer solver tolerance");
305 
306  double div_tol = 1e-6;
307  CLP.setOption("div_tol", &div_tol, "Tolerance in Iterative Solver");
308 
309  int prec_level = 1;
310  CLP.setOption("prec_level", &prec_level, "Level in Schur Complement Prec 0->Solve A0u0=g0 with division; 1->Form 1x1 Schur Complement");
311 
312  int max_it_div = 50;
313  CLP.setOption("max_it_div", &max_it_div, "Maximum # of Iterations in Iterative Solver for Division");
314 
315  bool equilibrate = true; //JJH 8/26/12 changing to true to match ETP example
316  CLP.setOption("equilibrate", "noequilibrate", &equilibrate,
317  "Equilibrate the linear system");
318 
319  bool printHierarchy = false;
320  CLP.setOption("print_hierarchy", "noprint_Hierarchy", &printHierarchy,
321  "Print matrices in multigrid hierarchy");
322 
323 
324  CLP.parse( argc, argv );
325 
326  if (MyPID == 0) {
327  std::cout << "Summary of command line options:" << std::endl
328  << "\tnum_mesh = " << n << std::endl
329  << "\tsymmetric = " << symmetric << std::endl
330  << "\tnum_spatial_procs = " << num_spatial_procs << std::endl
331  << "\trand_field = " << sg_rf_names[randField]
332  << std::endl
333  << "\tmean = " << mu << std::endl
334  << "\tstd_dev = " << s << std::endl
335  << "\tnum_kl = " << num_KL << std::endl
336  << "\torder = " << order << std::endl
337  << "\tnormalize_basis = " << normalize_basis << std::endl
338  << "\tsolver_method = " << krylov_method_names[solver_method] << std::endl
339  << "\tprec_method = " << sg_prec_names[prec_method] << std::endl
340  << "\tdivision_method = " << sg_div_names[division_method] << std::endl
341  << "\tdiv_tol = " << div_tol << std::endl
342  << "\tdiv_prec = " << sg_divprec_names[divprec_method] << std::endl
343  << "\tprec_level = " << prec_level << std::endl
344  << "\tmax_it_div = " << max_it_div << std::endl
345  << "\t~~~ multigrid options ~~~" << std::endl
346  << "\tsmoother_type = " << multigrid_smoother_names[smoother_type] << std::endl
347  << "\tsmoother_sweeps = " << smootherSweeps << std::endl
348  << "\tplain_aggregation = " << plainAgg << std::endl
349  << "\tmax_multigrid_levels = " << maxAMGLevels << std::endl
350  << "\tnullspace_size = " << nsSize << std::endl
351  << "\tmin_agg_size = " << minAggSize << std::endl;
352  }
353  bool nonlinear_expansion = false;
354  if (randField == UNIFORM)
355  nonlinear_expansion = false;
356  else if (randField == LOGNORMAL)
357  nonlinear_expansion = true;
358 
359  {
360  TEUCHOS_FUNC_TIME_MONITOR("Total PCE Calculation Time");
361 
362  // Create Stochastic Galerkin basis and expansion
364  for (LocalOrdinal i=0; i<num_KL; i++)
365  if (randField == UNIFORM)
366  bases[i] = rcp(new Stokhos::LegendreBasis<LocalOrdinal,BasisScalar>(order, normalize_basis));
367  else if (randField == LOGNORMAL)
368  bases[i] = rcp(new Stokhos::HermiteBasis<int,double>(order, normalize_basis));
369  RCP<const Stokhos::CompletePolynomialBasis<LocalOrdinal,BasisScalar> > basis =
371  LocalOrdinal sz = basis->size();
372  RCP<Stokhos::Sparse3Tensor<LocalOrdinal,BasisScalar> > Cijk =
373  basis->computeTripleProductTensor();
374  RCP<const Stokhos::Quadrature<int,double> > quad =
376  RCP<ParameterList> expn_params = Teuchos::rcp(new ParameterList);
377  if (division_method == MEAN_DIV) {
378  expn_params->set("Division Strategy", "Mean-Based");
379  expn_params->set("Use Quadrature for Division", false);
380  }
381  else if (division_method == DIRECT) {
382  expn_params->set("Division Strategy", "Dense Direct");
383  expn_params->set("Use Quadrature for Division", false);
384  }
385  else if (division_method == SPD_DIRECT) {
386  expn_params->set("Division Strategy", "SPD Dense Direct");
387  expn_params->set("Use Quadrature for Division", false);
388  }
389  else if (division_method == CGD) {
390  expn_params->set("Division Strategy", "CG");
391  expn_params->set("Use Quadrature for Division", false);
392  }
393 
394  else if (division_method == QUAD) {
395  expn_params->set("Use Quadrature for Division", true);
396  }
397 
398  if (divprec_method == NO)
399  expn_params->set("Prec Strategy", "None");
400  else if (divprec_method == DIAG)
401  expn_params->set("Prec Strategy", "Diag");
402  else if (divprec_method == JACOBI)
403  expn_params->set("Prec Strategy", "Jacobi");
404  else if (divprec_method == GS)
405  expn_params->set("Prec Strategy", "GS");
406  else if (divprec_method == SCHUR)
407  expn_params->set("Prec Strategy", "Schur");
408 
409  if (schur_option == diag)
410  expn_params->set("Schur option", "diag");
411  else
412  expn_params->set("Schur option", "full");
413  if (prec_option == linear)
414  expn_params->set("Prec option", "linear");
415 
416 
417  if (equilibrate)
418  expn_params->set("Equilibrate", 1);
419  else
420  expn_params->set("Equilibrate", 0);
421  expn_params->set("Division Tolerance", div_tol);
422  expn_params->set("prec_iter", prec_level);
423  expn_params->set("max_it_div", max_it_div);
424 
425  RCP<Stokhos::OrthogPolyExpansion<LocalOrdinal,BasisScalar> > expansion =
427  basis, Cijk, quad, expn_params));
428 
429  if (MyPID == 0)
430  std::cout << "Stochastic Galerkin expansion size = " << sz << std::endl;
431 
432  // Create stochastic parallel distribution
433  ParameterList parallelParams;
434  parallelParams.set("Number of Spatial Processors", num_spatial_procs);
435  // parallelParams.set("Rebalance Stochastic Graph", true);
436  // Teuchos::ParameterList& isorropia_params =
437  // parallelParams.sublist("Isorropia");
438  // isorropia_params.set("Balance objective", "nonzeros");
439  RCP<Stokhos::ParallelData> sg_parallel_data =
440  rcp(new Stokhos::ParallelData(basis, Cijk, globalComm, parallelParams));
441  RCP<const EpetraExt::MultiComm> sg_comm =
442  sg_parallel_data->getMultiComm();
443  RCP<const Epetra_Comm> app_comm =
444  sg_parallel_data->getSpatialComm();
445 
446  // Create Teuchos::Comm from Epetra_Comm
447  RCP< Teuchos::Comm<int> > teuchos_app_comm;
448 #ifdef HAVE_MPI
449  RCP<const Epetra_MpiComm> app_mpi_comm =
450  Teuchos::rcp_dynamic_cast<const Epetra_MpiComm>(app_comm);
451  RCP<const Teuchos::OpaqueWrapper<MPI_Comm> > raw_mpi_comm =
452  Teuchos::opaqueWrapper(app_mpi_comm->Comm());
453  teuchos_app_comm = rcp(new Teuchos::MpiComm<int>(raw_mpi_comm));
454 #else
455  teuchos_app_comm = rcp(new Teuchos::SerialComm<int>());
456 #endif
457 
458  // Create application
460  RCP<problem_type> model =
461  rcp(new problem_type(teuchos_app_comm, n, num_KL, s, mu,
462  nonlinear_expansion, symmetric));
463 
464  // Create vectors and operators
465  typedef problem_type::Tpetra_Vector Tpetra_Vector;
466  typedef problem_type::Tpetra_CrsMatrix Tpetra_CrsMatrix;
467  typedef Tpetra::MatrixMarket::Writer<Tpetra_CrsMatrix> Writer;
468  //Xpetra matrices
469  typedef Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> Xpetra_CrsMatrix;
470  typedef Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> Xpetra_MultiVector;
471  typedef Xpetra::MultiVectorFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node> Xpetra_MultiVectorFactory;
472  typedef Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> Xpetra_TpetraCrsMatrix;
473  typedef Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node> Xpetra_CrsMatrixWrap;
474  typedef Belos::MueLuOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> Belos_MueLuOperator;
475  //MueLu typedefs
476  typedef MueLu::Hierarchy<Scalar, LocalOrdinal, GlobalOrdinal, Node> MueLu_Hierarchy;
477  typedef MueLu::SmootherPrototype<Scalar,LocalOrdinal,GlobalOrdinal,Node> SmootherPrototype;
478  typedef MueLu::TrilinosSmoother<Scalar,LocalOrdinal,GlobalOrdinal,Node> TrilinosSmoother;
479  typedef MueLu::SmootherFactory<Scalar,LocalOrdinal,GlobalOrdinal,Node> SmootherFactory;
480  typedef MueLu::FactoryManager<Scalar,LocalOrdinal,GlobalOrdinal,Node> FactoryManager;
481 
482  //feenableexcept(FE_ALL_EXCEPT);
483  //feenableexcept(FE_INVALID | FE_DIVBYZERO);
484 
485  RCP<Tpetra_Vector> p = Tpetra::createVector<Scalar>(model->get_p_map(0));
486  RCP<Tpetra_Vector> x = Tpetra::createVector<Scalar>(model->get_x_map());
487  x->putScalar(0.0);
488  RCP<Tpetra_Vector> f = Tpetra::createVector<Scalar>(model->get_f_map());
489  RCP<Tpetra_Vector> dx = Tpetra::createVector<Scalar>(model->get_x_map());
490  RCP<Tpetra_CrsMatrix> J = model->create_W();
491  RCP<Tpetra_CrsMatrix> J0;
492  if (prec_method == MEAN)
493  J0 = model->create_W();
494 
495  // Set PCE expansion of p
496  p->putScalar(0.0);
497  ArrayRCP<Scalar> p_view = p->get1dViewNonConst();
498  for (ArrayRCP<Scalar>::size_type i=0; i<p_view.size(); i++) {
499  p_view[i].reset(expansion);
500  p_view[i].copyForWrite();
501  }
502  Array<double> point(num_KL, 1.0);
503  Array<double> basis_vals(sz);
504  basis->evaluateBases(point, basis_vals);
505  if (order > 0) {
506  for (int i=0; i<num_KL; i++) {
507  p_view[i].term(i,1) = 1.0 / basis_vals[i+1];
508  }
509  }
510 
511  // Create preconditioner
512  typedef Ifpack2::Preconditioner<Scalar,LocalOrdinal,GlobalOrdinal,Node> Tprec;
513  RCP<Belos_MueLuOperator> M;
514  RCP<MueLu_Hierarchy> H;
515  RCP<Xpetra_CrsMatrix> xcrsJ = rcp(new Xpetra_TpetraCrsMatrix(J));
516  RCP<Xpetra_Matrix> xopJ = rcp(new Xpetra_CrsMatrixWrap(xcrsJ));
517  RCP<Xpetra_Matrix> xopJ0;
518  if (prec_method != NONE) {
519  ParameterList precParams;
520  std::string prec_name = "RILUK";
521  precParams.set("fact: iluk level-of-fill", 1);
522  precParams.set("fact: iluk level-of-overlap", 0);
523  //Ifpack2::Factory factory;
524  if (prec_method == MEAN) {
525  RCP<Xpetra_CrsMatrix> xcrsJ0 = rcp(new Xpetra_TpetraCrsMatrix(J0));
526  xopJ0 = rcp(new Xpetra_CrsMatrixWrap(xcrsJ0));
527  //M = factory.create<Tpetra_CrsMatrix>(prec_name, J0);
528  } else if (prec_method == STOCHASTIC) {
529  xopJ0 = xopJ;
530  //M = factory.create<Tpetra_CrsMatrix>(prec_name, J);
531  }
532  H = rcp(new MueLu_Hierarchy(xopJ0));
533  M = rcp(new Belos_MueLuOperator(H));
534  //M->setParameters(precParams);
535  if (nsSize==-1) nsSize=sz;
536  RCP<Xpetra_MultiVector> Z = Xpetra_MultiVectorFactory::Build(xcrsJ->getDomainMap(), nsSize);
537  size_t n = Z->getLocalLength();
538  for (LocalOrdinal j=0; j<nsSize; ++j) {
539  ArrayRCP<Scalar> col = Z->getDataNonConst(j);
540  for (size_t i=0; i<n; ++i) {
541  col[i].reset(expansion);
542  col[i].copyForWrite();
543  col[i].fastAccessCoeff(j) = 1.0;
544  }
545  }
546  H->GetLevel(0)->Set("Nullspace", Z);
547  //RCP<Teuchos::FancyOStream> fos = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
548  //fos->setOutputToRootOnly(-1);
549  //Z->describe(*fos);
550  }
551 
552  // Evaluate model
553  model->computeResidual(*x, *p, *f);
554  model->computeJacobian(*x, *p, *J);
555 
556 
557  // Compute mean for mean-based preconditioner
558  if (prec_method == MEAN) {
559  size_t nrows = J->getLocalNumRows();
560  ArrayView<const LocalOrdinal> indices;
561  ArrayView<const Scalar> values;
562  J0->resumeFill();
563  for (size_t i=0; i<nrows; i++) {
564  J->getLocalRowView(i, indices, values);
565  Array<Scalar> values0(values.size());
566  for (LocalOrdinal j=0; j<values.size(); j++)
567  values0[j] = values[j].coeff(0);
568  J0->replaceLocalValues(i, indices, values0);
569  }
570  J0->fillComplete();
571  }
572 
573 
574  // compute preconditioner
575  if (prec_method != NONE) {
576  //M->initialize();
577  //M->compute();
578 
579  //override MueLu defaults via factory manager
580  RCP<FactoryManager> fm = rcp( new FactoryManager() );;
581 
582  //smoother
583  ParameterList smootherParamList;
584  RCP<SmootherPrototype> smooPrototype;
585  switch(smoother_type) {
586  case CHEBYSHEV: {
587  smootherParamList.set("chebyshev: degree", smootherSweeps);
588  smootherParamList.set("chebyshev: ratio eigenvalue", (double) 20);
589  Scalar minusOne=-1.0;
590  smootherParamList.set("chebyshev: max eigenvalue", minusOne);
591  smootherParamList.set("chebyshev: min eigenvalue", (double) 1.0);
592  smootherParamList.set("chebyshev: zero starting solution", true);
593  smooPrototype = rcp( new TrilinosSmoother("CHEBYSHEV", smootherParamList) );
594  break;
595  }
596 
597  case SGS:
598  default:
599  smootherParamList.set("relaxation: sweeps", smootherSweeps);
600  smootherParamList.set("relaxation: type", "Symmetric Gauss-Seidel");
601  smooPrototype = rcp( new TrilinosSmoother("RELAXATION", smootherParamList) );
602  break;
603  }
604 
605  RCP<SmootherFactory> smooFact = rcp( new SmootherFactory(smooPrototype) );
606  fm->SetFactory("Smoother", smooFact);
607 
608  // coarse level solve
609  // TODO until KLU in Amesos2 is fully templated, use incomplete factorization as coarsest level solve
610  ParameterList coarseParamList;
611  coarseParamList.set("fact: level-of-fill", 0);
612  RCP<SmootherPrototype> coarsePrototype = rcp( new TrilinosSmoother("ILUT", coarseParamList) );
613  //RCP<SmootherPrototype> coarsePrototype = rcp( new TrilinosSmoother("RILUK", coarseParamList) );
614  RCP<SmootherFactory> coarseSolverFact = rcp( new SmootherFactory(coarsePrototype, Teuchos::null) );
615  fm->SetFactory("CoarseSolver", coarseSolverFact);
616  //fm->SetFactory("CoarseSolver", smooFact);
617 
618  //allow for larger aggregates
619  typedef MueLu::CoupledAggregationFactory<LocalOrdinal,GlobalOrdinal,Node>
620  MueLu_CoupledAggregationFactory;
621  RCP<MueLu_CoupledAggregationFactory> aggFact = rcp(new MueLu_CoupledAggregationFactory());
622  aggFact->SetMinNodesPerAggregate(minAggSize);
623  fm->SetFactory("Aggregates", aggFact);
624 
625  //turn off damping
626  typedef MueLu::SaPFactory<Scalar,LocalOrdinal,GlobalOrdinal,Node> MueLu_SaPFactory;
627  if (plainAgg) {
628  RCP<MueLu_SaPFactory> sapFactory = rcp(new MueLu_SaPFactory);
629  sapFactory->SetDampingFactor( (Scalar) 0.0 );
630  fm->SetFactory("P", sapFactory);
631  }
632 
633  H->Setup(*fm,0,maxAMGLevels); //start at level 0, at most 3 levels
634 
635  if (printHierarchy)
636  {
637  //FIXME #levels
638  RCP<Teuchos::FancyOStream> fos = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
639  int numLevels = H->GetNumLevels();
640  for (int i=0; i<numLevels; ++i) {
641  RCP<Xpetra_Matrix> A = H->GetLevel(i)->Get<RCP<Xpetra_Matrix> >("A");
642  *fos << "================\n" << "matrix A, multigrid level " << i << "\n================" << std::endl;
643  PrintMatrix<LocalOrdinal,BasisScalar>(*fos,A,Cijk,basis);
644  }
645  }
646  }
647 
648  // Setup Belos solver
649  RCP<ParameterList> belosParams = rcp(new ParameterList);
650  belosParams->set("Flexible Gmres", false);
651  belosParams->set("Num Blocks", 500);//20
652  belosParams->set("Convergence Tolerance", solver_tol);
653  belosParams->set("Maximum Iterations", 1000);
654  belosParams->set("Verbosity", 33);
655  belosParams->set("Output Style", 1);
656  belosParams->set("Output Frequency", 1);
657  typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> MV;
658  typedef Belos::OperatorT<Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > OP;
659  typedef Belos::OperatorTraits<Scalar,MV,OP> BOPT;
660  typedef Belos::MultiVecTraits<Scalar,MV> BMVT;
661  typedef Belos::MultiVecTraits<double,MV> BTMVT;
662  typedef Belos::LinearProblem<double,MV,OP> BLinProb;
663  typedef Belos::XpetraOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> BXpetraOp;
664  RCP<OP> belosJ = rcp(new BXpetraOp(xopJ)); // Turns an Xpetra::Matrix object into a Belos operator
665  RCP< BLinProb > problem = rcp(new BLinProb(belosJ, dx, f));
666  if (prec_method != NONE)
667  problem->setRightPrec(M);
668  problem->setProblem();
669  RCP<Belos::SolverManager<double,MV,OP> > solver;
670  if (solver_method == CG)
671  solver = rcp(new Belos::PseudoBlockCGSolMgr<double,MV,OP>(problem, belosParams));
672  else if (solver_method == GMRES)
673  solver = rcp(new Belos::BlockGmresSolMgr<double,MV,OP>(problem, belosParams));
674 
675  // Print initial residual norm
676  std::vector<double> norm_f(1);
677  //BMVT::MvNorm(*f, norm_f);
678  BTMVT::MvNorm(*f, norm_f);
679  if (MyPID == 0)
680  std::cout << "\nInitial residual norm = " << norm_f[0] << std::endl;
681 
682  // Solve linear system
683  Belos::ReturnType ret = solver->solve();
684 
685  if (MyPID == 0) {
686  if (ret == Belos::Converged)
687  std::cout << "Solver converged!" << std::endl;
688  else
689  std::cout << "Solver failed to converge!" << std::endl;
690  }
691 
692  // Update x
693  x->update(-1.0, *dx, 1.0);
694  Writer::writeDenseFile("stochastic_solution.mm", x);
695 
696  // Compute new residual & response function
697  RCP<Tpetra_Vector> g = Tpetra::createVector<Scalar>(model->get_g_map(0));
698  f->putScalar(0.0);
699  model->computeResidual(*x, *p, *f);
700  model->computeResponse(*x, *p, *g);
701 
702  // Print final residual norm
703  //BMVT::MvNorm(*f, norm_f);
704  BTMVT::MvNorm(*f, norm_f);
705  if (MyPID == 0)
706  std::cout << "\nFinal residual norm = " << norm_f[0] << std::endl;
707 
708  // Expected results for num_mesh=32
709  double g_mean_exp = 0.172988; // expected response mean
710  double g_std_dev_exp = 0.0380007; // expected response std. dev.
711  double g_tol = 1e-6; // tolerance on determining success
712  if (n == 8) {
713  g_mean_exp = 1.327563e-01;
714  g_std_dev_exp = 2.949064e-02;
715  }
716 
717  double g_mean = g->get1dView()[0].mean();
718  double g_std_dev = g->get1dView()[0].standard_deviation();
719  std::cout << std::endl;
720  std::cout << "Response Mean = " << g_mean << std::endl;
721  std::cout << "Response Std. Dev. = " << g_std_dev << std::endl;
722  bool passed = false;
723  if (norm_f[0] < 1.0e-10 &&
724  std::abs(g_mean-g_mean_exp) < g_tol &&
725  std::abs(g_std_dev - g_std_dev_exp) < g_tol)
726  passed = true;
727  if (MyPID == 0) {
728  if (passed)
729  std::cout << "Example Passed!" << std::endl;
730  else{
731  std::cout << "Example Failed!" << std::endl;
732  std::cout << "Expected Response Mean = "<< g_mean_exp << std::endl;
733  std::cout << "Expected Response Std. Dev. = "<< g_std_dev_exp << std::endl;
734  }
735  }
736 
737  }
738 
739  if (printTimings) {
742  }
743 
744  }
745 
746  catch (std::exception& e) {
747  std::cout << e.what() << std::endl;
748  }
749  catch (string& s) {
750  std::cout << s << std::endl;
751  }
752  catch (char *s) {
753  std::cout << s << std::endl;
754  }
755  catch (...) {
756  std::cout << "Caught unknown exception!" <<std:: endl;
757  }
758 
759 #ifdef HAVE_MPI
760  MPI_Finalize() ;
761 #endif
762 
763 }
const char * multigrid_smoother_names[]
#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[]
SparseArrayIterator< index_iterator, value_iterator >::value_type index(const SparseArrayIterator< index_iterator, value_iterator > &it)
Data structure storing a sparse 3-tensor C(i,j,k) in a a compressed format.
Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > Xpetra_Matrix
const char * schur_option_names[]
const int num_multigrid_smoother
const char * prec_option_names[]
const SG_Prec sg_prec_values[]
pointer coeff()
Return coefficient array.
const SG_DivPrec sg_divprec_values[]
const Schur_option Schur_option_values[]
Kokkos::Serial node_type
const SG_Div sg_div_values[]
Abstract base class for multivariate orthogonal polynomials.
const Multigrid_Smoother multigrid_smoother_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[]
Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > Xpetra_Map
EParseCommandLineReturn parse(int argc, char *argv[], std::ostream *errout=&std::cerr) const
KOKKOS_INLINE_FUNCTION PCE< Storage > abs(const PCE< Storage > &a)
const int num_sg_rf
expr expr expr dx(i, j)
Multivariate orthogonal polynomial basis generated from a total-order complete-polynomial tensor prod...
void PrintMatrix(Teuchos::FancyOStream &fos, Teuchos::RCP< Xpetra_Matrix > const &A, Teuchos::RCP< Stokhos::Sparse3Tensor< ordinal_type, value_type > > const &Cijk, Teuchos::RCP< const Stokhos::OrthogPolyBasis< ordinal_type, value_type > > const &basis)
KOKKOS_INLINE_FUNCTION constexpr std::enable_if< is_view_uq_pce< view_type >::value, typename CijkType< view_type >::type >::type cijk(const view_type &view)
Legendre polynomial basis.
Stokhos::Sparse3Tensor< int, double > Cijk_type
int main(int argc, char **argv)
expr val()
const char * sg_rf_names[]
ScalarType f(const Teuchos::Array< ScalarType > &x, double a, double b)
void setDocString(const char doc_string[])
SparseArrayIterator< index_iterator, value_iterator >::value_reference value(const SparseArrayIterator< index_iterator, value_iterator > &it)
const char * sg_prec_names[]
ordinal_type size() const
Return size.
Tpetra::KokkosClassic::DefaultNode::DefaultNodeType Node
const char * sg_div_names[]
Orthogonal polynomial expansions based on numerical quadrature.
int n
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()
void returnScalarAsDenseMatrix(Sacado::PCE::OrthogPoly< value_type, Storage > const &inval, Teuchos::RCP< Teuchos::SerialDenseMatrix< ordinal_type, value_type > > &denseEntry, Teuchos::RCP< Stokhos::Sparse3Tensor< ordinal_type, value_type > > const &Cijk)
A linear 2-D diffusion problem.
const char * krylov_method_names[]