Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
linear2d_diffusion_pce_nox_sg_solvers.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 // ModelEvaluator implementing our problem
11 #include "twoD_diffusion_ME.hpp"
12 
13 // Epetra communicator
14 #ifdef HAVE_MPI
15 #include "Epetra_MpiComm.h"
16 #else
17 #include "Epetra_SerialComm.h"
18 #endif
19 
20 // NOX
21 #include "NOX.H"
22 #include "NOX_Epetra.H"
23 #include "NOX_Epetra_LinearSystem_Stratimikos.H"
26 
27 // Stokhos Stochastic Galerkin
28 #include "Stokhos_Epetra.hpp"
29 
30 // Utilities
32 #include "Teuchos_TimeMonitor.hpp"
33 #include "Teuchos_Assert.hpp"
34 
35 // I/O utilities
36 #include "EpetraExt_VectorOut.h"
37 
38 //The probability distribution of the random variables.
39 double uniform_weight(const double& x){
40  return 1;
41 }
42 
43 // Linear solvers
45 const int num_krylov_solver = 2;
47 const char *krylov_solver_names[] = { "AztecOO", "Belos" };
48 
49 // SG solver approaches
51 const int num_sg_solver = 3;
53 const char *sg_solver_names[] = { "Krylov", "Gauss-Seidel", "Jacobi" };
54 
55 // Krylov methods
57 const int num_krylov_method = 4;
59 const char *krylov_method_names[] = { "GMRES", "CG", "FGMRES", "RGMRES" };
60 
61 // Krylov operator approaches
63 const int num_sg_op = 4;
65 const char *sg_op_names[] = { "Matrix-Free",
66  "KL-Matrix-Free",
67  "KL-Reduced-Matrix-Free",
68  "Fully-Assembled" };
69 
70 // Krylov preconditioning approaches
71 enum SG_Prec { MEAN, GS, AGS, AJ, ASC, KP, NONE };
72 const int num_sg_prec = 7;
73 const SG_Prec sg_prec_values[] = { MEAN, GS, AGS, AJ, ASC, KP, NONE };
74 const char *sg_prec_names[] = { "Mean-Based",
75  "Gauss-Seidel",
76  "Approx-Gauss-Seidel",
77  "Approx-Jacobi",
78  "Approx-Schur-Complement",
79  "Kronecker-Product",
80  "None" };
81 
82 // Random field types
84 const int num_sg_rf = 3;
86 const char *sg_rf_names[] = { "Uniform", "Rys", "Log-Normal" };
87 
88 int main(int argc, char *argv[]) {
89 
90 // Initialize MPI
91 #ifdef HAVE_MPI
92  MPI_Init(&argc,&argv);
93 #endif
94 
95  // Create a communicator for Epetra objects
97 #ifdef HAVE_MPI
98  globalComm = Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
99 #else
100  globalComm = Teuchos::rcp(new Epetra_SerialComm);
101 #endif
102  int MyPID = globalComm->MyPID();
103 
104  try {
105 
106  // Setup command line options
108  CLP.setDocString(
109  "This example runs a variety of stochastic Galerkin solvers.\n");
110 
111  int n = 32;
112  CLP.setOption("num_mesh", &n, "Number of mesh points in each direction");
113 
114  bool symmetric = false;
115  CLP.setOption("symmetric", "unsymmetric", &symmetric,
116  "Symmetric discretization");
117 
118  int num_spatial_procs = -1;
119  CLP.setOption("num_spatial_procs", &num_spatial_procs, "Number of spatial processors (set -1 for all available procs)");
120 
121  bool rebalance_stochastic_graph = false;
122  CLP.setOption("rebalance", "no-rebalance", &rebalance_stochastic_graph,
123  "Rebalance parallel stochastic graph (requires Isorropia)");
124 
125  SG_RF randField = UNIFORM;
126  CLP.setOption("rand_field", &randField,
128  "Random field type");
129 
130  double mean = 0.2;
131  CLP.setOption("mean", &mean, "Mean");
132 
133  double sigma = 0.1;
134  CLP.setOption("std_dev", &sigma, "Standard deviation");
135 
136  double weightCut = 1.0;
137  CLP.setOption("weight_cut", &weightCut, "Weight cut");
138 
139  int num_KL = 2;
140  CLP.setOption("num_kl", &num_KL, "Number of KL terms");
141 
142  int p = 3;
143  CLP.setOption("order", &p, "Polynomial order");
144 
145  bool normalize_basis = true;
146  CLP.setOption("normalize", "unnormalize", &normalize_basis,
147  "Normalize PC basis");
148 
149  SG_Solver solve_method = SG_KRYLOV;
150  CLP.setOption("sg_solver", &solve_method,
152  "SG solver method");
153 
154  Krylov_Method outer_krylov_method = GMRES;
155  CLP.setOption("outer_krylov_method", &outer_krylov_method,
157  "Outer Krylov method (for Krylov-based SG solver)");
158 
159  Krylov_Solver outer_krylov_solver = AZTECOO;
160  CLP.setOption("outer_krylov_solver", &outer_krylov_solver,
162  "Outer linear solver");
163 
164  double outer_tol = 1e-12;
165  CLP.setOption("outer_tol", &outer_tol, "Outer solver tolerance");
166 
167  int outer_its = 1000;
168  CLP.setOption("outer_its", &outer_its, "Maximum outer iterations");
169 
170  Krylov_Method inner_krylov_method = GMRES;
171  CLP.setOption("inner_krylov_method", &inner_krylov_method,
173  "Inner Krylov method (for G-S, Jacobi, etc...)");
174 
175  Krylov_Solver inner_krylov_solver = AZTECOO;
176  CLP.setOption("inner_krylov_solver", &inner_krylov_solver,
178  "Inner linear solver");
179 
180  double inner_tol = 3e-13;
181  CLP.setOption("inner_tol", &inner_tol, "Inner solver tolerance");
182 
183  int inner_its = 1000;
184  CLP.setOption("inner_its", &inner_its, "Maximum inner iterations");
185 
186  SG_Op opMethod = MATRIX_FREE;
187  CLP.setOption("sg_operator_method", &opMethod,
189  "Operator method");
190 
191  SG_Prec precMethod = AGS;
192  CLP.setOption("sg_prec_method", &precMethod,
194  "Preconditioner method");
195 
196  double gs_prec_tol = 1e-1;
197  CLP.setOption("gs_prec_tol", &gs_prec_tol, "Gauss-Seidel preconditioner tolerance");
198 
199  int gs_prec_its = 1;
200  CLP.setOption("gs_prec_its", &gs_prec_its, "Maximum Gauss-Seidel preconditioner iterations");
201 
202  CLP.parse( argc, argv );
203 
204  if (MyPID == 0) {
205  std::cout << "Summary of command line options:" << std::endl
206  << "\tnum_mesh = " << n << std::endl
207  << "\tsymmetric = " << symmetric << std::endl
208  << "\tnum_spatial_procs = " << num_spatial_procs << std::endl
209  << "\trebalance = " << rebalance_stochastic_graph
210  << std::endl
211  << "\trand_field = " << sg_rf_names[randField]
212  << std::endl
213  << "\tmean = " << mean << std::endl
214  << "\tstd_dev = " << sigma << std::endl
215  << "\tweight_cut = " << weightCut << std::endl
216  << "\tnum_kl = " << num_KL << std::endl
217  << "\torder = " << p << std::endl
218  << "\tnormalize_basis = " << normalize_basis << std::endl
219  << "\tsg_solver = " << sg_solver_names[solve_method]
220  << std::endl
221  << "\touter_krylov_method = "
222  << krylov_method_names[outer_krylov_method] << std::endl
223  << "\touter_krylov_solver = "
224  << krylov_solver_names[outer_krylov_solver] << std::endl
225  << "\touter_tol = " << outer_tol << std::endl
226  << "\touter_its = " << outer_its << std::endl
227  << "\tinner_krylov_method = "
228  << krylov_method_names[inner_krylov_method] << std::endl
229  << "\tinner_krylov_solver = "
230  << krylov_solver_names[inner_krylov_solver] << std::endl
231  << "\tinner_tol = " << inner_tol << std::endl
232  << "\tinner_its = " << inner_its << std::endl
233  << "\tsg_operator_method = " << sg_op_names[opMethod]
234  << std::endl
235  << "\tsg_prec_method = " << sg_prec_names[precMethod]
236  << std::endl
237  << "\tgs_prec_tol = " << gs_prec_tol << std::endl
238  << "\tgs_prec_its = " << gs_prec_its << std::endl;
239  }
240 
241  bool nonlinear_expansion = false;
242  if (randField == UNIFORM || randField == RYS)
243  nonlinear_expansion = false;
244  else if (randField == LOGNORMAL)
245  nonlinear_expansion = true;
246  bool scaleOP = true;
247 
248  {
249  TEUCHOS_FUNC_TIME_MONITOR("Total PCE Calculation Time");
250 
251  // Create Stochastic Galerkin basis and expansion
253  for (int i=0; i<num_KL; i++)
254  if (randField == UNIFORM)
255  bases[i] = Teuchos::rcp(new Stokhos::LegendreBasis<int,double>(p,normalize_basis));
256  else if (randField == RYS)
257  bases[i] = Teuchos::rcp(new Stokhos::RysBasis<int,double>(p,weightCut,normalize_basis));
258  else if (randField == LOGNORMAL)
259  bases[i] = Teuchos::rcp(new Stokhos::HermiteBasis<int,double>(p,normalize_basis));
260 
261  // bases[i] = Teuchos::rcp(new Stokhos::DiscretizedStieltjesBasis<int,double>("beta",p,&uniform_weight,-weightCut,weightCut,true));
264  int sz = basis->size();
266  if (nonlinear_expansion)
267  Cijk = basis->computeTripleProductTensor();
268  else
269  Cijk = basis->computeLinearTripleProductTensor();
272  Cijk));
273  if (MyPID == 0)
274  std::cout << "Stochastic Galerkin expansion size = " << sz << std::endl;
275 
276  // Create stochastic parallel distribution
277  Teuchos::ParameterList parallelParams;
278  parallelParams.set("Number of Spatial Processors", num_spatial_procs);
279  parallelParams.set("Rebalance Stochastic Graph",
280  rebalance_stochastic_graph);
281  Teuchos::RCP<Stokhos::ParallelData> sg_parallel_data =
282  Teuchos::rcp(new Stokhos::ParallelData(basis, Cijk, globalComm,
283  parallelParams));
285  sg_parallel_data->getMultiComm();
287  sg_parallel_data->getSpatialComm();
288 
289  // Create application
291  Teuchos::rcp(new twoD_diffusion_ME(app_comm, n, num_KL, sigma,
292  mean, basis, nonlinear_expansion,
293  symmetric));
294 
295  // Set up NOX parameters
298 
299  // Set the nonlinear solver method
300  noxParams->set("Nonlinear Solver", "Line Search Based");
301 
302  // Set the printing parameters in the "Printing" sublist
303  Teuchos::ParameterList& printParams = noxParams->sublist("Printing");
304  printParams.set("MyPID", MyPID);
305  printParams.set("Output Precision", 3);
306  printParams.set("Output Processor", 0);
307  printParams.set("Output Information",
308  NOX::Utils::OuterIteration +
309  NOX::Utils::OuterIterationStatusTest +
310  NOX::Utils::InnerIteration +
311  //NOX::Utils::Parameters +
312  NOX::Utils::Details +
313  NOX::Utils::LinearSolverDetails +
314  NOX::Utils::Warning +
315  NOX::Utils::Error);
316 
317  // Create printing utilities
318  NOX::Utils utils(printParams);
319 
320  // Sublist for line search
321  Teuchos::ParameterList& searchParams = noxParams->sublist("Line Search");
322  searchParams.set("Method", "Full Step");
323 
324  // Sublist for direction
325  Teuchos::ParameterList& dirParams = noxParams->sublist("Direction");
326  dirParams.set("Method", "Newton");
327  Teuchos::ParameterList& newtonParams = dirParams.sublist("Newton");
328  newtonParams.set("Forcing Term Method", "Constant");
329 
330  // Sublist for linear solver for the Newton method
331  Teuchos::ParameterList& lsParams = newtonParams.sublist("Linear Solver");
332 
333  // Alternative linear solver list for Stratimikos
334  Teuchos::ParameterList& stratLinSolParams =
335  newtonParams.sublist("Stratimikos Linear Solver");
336  // Teuchos::ParameterList& noxStratParams =
337  // stratLinSolParams.sublist("NOX Stratimikos Options");
338  Teuchos::ParameterList& stratParams =
339  stratLinSolParams.sublist("Stratimikos");
340 
341  // Sublist for convergence tests
342  Teuchos::ParameterList& statusParams = noxParams->sublist("Status Tests");
343  statusParams.set("Test Type", "Combo");
344  statusParams.set("Number of Tests", 2);
345  statusParams.set("Combo Type", "OR");
346  Teuchos::ParameterList& normF = statusParams.sublist("Test 0");
347  normF.set("Test Type", "NormF");
348  normF.set("Tolerance", outer_tol);
349  normF.set("Scale Type", "Scaled");
350  Teuchos::ParameterList& maxIters = statusParams.sublist("Test 1");
351  maxIters.set("Test Type", "MaxIters");
352  maxIters.set("Maximum Iterations", 1);
353 
354  // Create NOX interface
356  Teuchos::rcp(new NOX::Epetra::ModelEvaluatorInterface(model));
357 
358  // Create NOX linear system object
360  Teuchos::RCP<Epetra_Operator> det_A = model->create_W();
361  Teuchos::RCP<NOX::Epetra::Interface::Required> det_iReq = det_nox_interface;
362  Teuchos::RCP<NOX::Epetra::Interface::Jacobian> det_iJac = det_nox_interface;
363  Teuchos::ParameterList det_printParams;
364  det_printParams.set("MyPID", MyPID);
365  det_printParams.set("Output Precision", 3);
366  det_printParams.set("Output Processor", 0);
367  det_printParams.set("Output Information", NOX::Utils::Error);
368 
369  Teuchos::ParameterList det_lsParams;
370  Teuchos::ParameterList& det_stratParams =
371  det_lsParams.sublist("Stratimikos");
372  if (inner_krylov_solver == AZTECOO) {
373  det_stratParams.set("Linear Solver Type", "AztecOO");
374  Teuchos::ParameterList& aztecOOParams =
375  det_stratParams.sublist("Linear Solver Types").sublist("AztecOO").sublist("Forward Solve");
376  Teuchos::ParameterList& aztecOOSettings =
377  aztecOOParams.sublist("AztecOO Settings");
378  if (inner_krylov_method == GMRES) {
379  aztecOOSettings.set("Aztec Solver","GMRES");
380  }
381  else if (inner_krylov_method == CG) {
382  aztecOOSettings.set("Aztec Solver","CG");
383  }
384  aztecOOSettings.set("Output Frequency", 0);
385  aztecOOSettings.set("Size of Krylov Subspace", 100);
386  aztecOOParams.set("Max Iterations", inner_its);
387  aztecOOParams.set("Tolerance", inner_tol);
388  Teuchos::ParameterList& verbParams =
389  det_stratParams.sublist("Linear Solver Types").sublist("AztecOO").sublist("VerboseObject");
390  verbParams.set("Verbosity Level", "none");
391  }
392  else if (inner_krylov_solver == BELOS) {
393  det_stratParams.set("Linear Solver Type", "Belos");
394  Teuchos::ParameterList& belosParams =
395  det_stratParams.sublist("Linear Solver Types").sublist("Belos");
396  Teuchos::ParameterList* belosSolverParams = NULL;
397  if (inner_krylov_method == GMRES || inner_krylov_method == FGMRES) {
398  belosParams.set("Solver Type","Block GMRES");
399  belosSolverParams =
400  &(belosParams.sublist("Solver Types").sublist("Block GMRES"));
401  if (inner_krylov_method == FGMRES)
402  belosSolverParams->set("Flexible Gmres", true);
403  }
404  else if (inner_krylov_method == CG) {
405  belosParams.set("Solver Type","Block CG");
406  belosSolverParams =
407  &(belosParams.sublist("Solver Types").sublist("Block CG"));
408  }
409  else if (inner_krylov_method == RGMRES) {
410  belosParams.set("Solver Type","GCRODR");
411  belosSolverParams =
412  &(belosParams.sublist("Solver Types").sublist("GCRODR"));
413  }
414  belosSolverParams->set("Convergence Tolerance", inner_tol);
415  belosSolverParams->set("Maximum Iterations", inner_its);
416  belosSolverParams->set("Output Frequency",0);
417  belosSolverParams->set("Output Style",1);
418  belosSolverParams->set("Verbosity",0);
419  Teuchos::ParameterList& verbParams = belosParams.sublist("VerboseObject");
420  verbParams.set("Verbosity Level", "none");
421  }
422  det_stratParams.set("Preconditioner Type", "ML");
423  Teuchos::ParameterList& det_ML =
424  det_stratParams.sublist("Preconditioner Types").sublist("ML").sublist("ML Settings");
425  ML_Epetra::SetDefaults("SA", det_ML);
426  det_ML.set("ML output", 0);
427  det_ML.set("max levels",5);
428  det_ML.set("increasing or decreasing","increasing");
429  det_ML.set("aggregation: type", "Uncoupled");
430  det_ML.set("smoother: type","ML symmetric Gauss-Seidel");
431  det_ML.set("smoother: sweeps",2);
432  det_ML.set("smoother: pre or post", "both");
433  det_ML.set("coarse: max size", 200);
434 #ifdef HAVE_ML_AMESOS
435  det_ML.set("coarse: type","Amesos-KLU");
436 #else
437  det_ML.set("coarse: type","Jacobi");
438 #endif
440  Teuchos::rcp(new NOX::Epetra::LinearSystemStratimikos(
441  det_printParams, det_lsParams, det_iJac,
442  det_A, *det_u));
443 
444  // Setup stochastic Galerkin algorithmic parameters
447  Teuchos::ParameterList& sgOpParams =
448  sgParams->sublist("SG Operator");
449  Teuchos::ParameterList& sgPrecParams =
450  sgParams->sublist("SG Preconditioner");
451 
452  if (!nonlinear_expansion) {
453  sgParams->set("Parameter Expansion Type", "Linear");
454  sgParams->set("Jacobian Expansion Type", "Linear");
455  }
456  if (opMethod == MATRIX_FREE)
457  sgOpParams.set("Operator Method", "Matrix Free");
458  else if (opMethod == KL_MATRIX_FREE)
459  sgOpParams.set("Operator Method", "KL Matrix Free");
460  else if (opMethod == KL_REDUCED_MATRIX_FREE) {
461  sgOpParams.set("Operator Method", "KL Reduced Matrix Free");
462  if (randField == UNIFORM || randField == RYS)
463  sgOpParams.set("Number of KL Terms", num_KL);
464  else
465  sgOpParams.set("Number of KL Terms", basis->size());
466  sgOpParams.set("KL Tolerance", outer_tol);
467  sgOpParams.set("Sparse 3 Tensor Drop Tolerance", outer_tol);
468  sgOpParams.set("Do Error Tests", true);
469  }
470  else if (opMethod == FULLY_ASSEMBLED)
471  sgOpParams.set("Operator Method", "Fully Assembled");
472  else
473  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
474  "Error! Unknown operator method " << opMethod
475  << "." << std::endl);
476  if (precMethod == MEAN) {
477  sgPrecParams.set("Preconditioner Method", "Mean-based");
478  sgPrecParams.set("Mean Preconditioner Type", "ML");
479  Teuchos::ParameterList& precParams =
480  sgPrecParams.sublist("Mean Preconditioner Parameters");
481  precParams = det_ML;
482  }
483  else if(precMethod == GS) {
484  sgPrecParams.set("Preconditioner Method", "Gauss-Seidel");
485  sgPrecParams.sublist("Deterministic Solver Parameters") = det_lsParams;
486  sgPrecParams.set("Deterministic Solver", det_linsys);
487  sgPrecParams.set("Max Iterations", gs_prec_its);
488  sgPrecParams.set("Tolerance", gs_prec_tol);
489  }
490  else if (precMethod == AGS) {
491  sgPrecParams.set("Preconditioner Method", "Approximate Gauss-Seidel");
492  if (outer_krylov_method == CG)
493  sgPrecParams.set("Symmetric Gauss-Seidel", true);
494  sgPrecParams.set("Mean Preconditioner Type", "ML");
495  Teuchos::ParameterList& precParams =
496  sgPrecParams.sublist("Mean Preconditioner Parameters");
497  precParams = det_ML;
498  }
499  else if (precMethod == AJ) {
500  sgPrecParams.set("Preconditioner Method", "Approximate Jacobi");
501  sgPrecParams.set("Mean Preconditioner Type", "ML");
502  Teuchos::ParameterList& precParams =
503  sgPrecParams.sublist("Mean Preconditioner Parameters");
504  precParams = det_ML;
505  Teuchos::ParameterList& jacobiOpParams =
506  sgPrecParams.sublist("Jacobi SG Operator");
507  jacobiOpParams.set("Only Use Linear Terms", true);
508  }
509  else if (precMethod == ASC) {
510  sgPrecParams.set("Preconditioner Method", "Approximate Schur Complement");
511  sgPrecParams.set("Mean Preconditioner Type", "ML");
512  Teuchos::ParameterList& precParams =
513  sgPrecParams.sublist("Mean Preconditioner Parameters");
514  precParams = det_ML;
515  }
516  else if (precMethod == KP) {
517  sgPrecParams.set("Preconditioner Method", "Kronecker Product");
518  sgPrecParams.set("Only Use Linear Terms", true);
519  sgPrecParams.set("Mean Preconditioner Type", "ML");
520  Teuchos::ParameterList& meanPrecParams =
521  sgPrecParams.sublist("Mean Preconditioner Parameters");
522  meanPrecParams = det_ML;
523  sgPrecParams.set("G Preconditioner Type", "Ifpack");
524  Teuchos::ParameterList& GPrecParams =
525  sgPrecParams.sublist("G Preconditioner Parameters");
526  if (outer_krylov_method == GMRES || outer_krylov_method == FGMRES)
527  GPrecParams.set("Ifpack Preconditioner", "ILUT");
528  if (outer_krylov_method == CG)
529  GPrecParams.set("Ifpack Preconditioner", "ICT");
530  GPrecParams.set("Overlap", 1);
531  GPrecParams.set("fact: drop tolerance", 1e-4);
532  GPrecParams.set("fact: ilut level-of-fill", 1.0);
533  GPrecParams.set("schwarz: combine mode", "Add");
534  }
535  else if (precMethod == NONE) {
536  sgPrecParams.set("Preconditioner Method", "None");
537  }
538  else
539  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
540  "Error! Unknown preconditioner method " << precMethod
541  << "." << std::endl);
542 
543  // Create stochastic Galerkin model evaluator
546  expansion, sg_parallel_data,
547  sgParams, scaleOP));
548  EpetraExt::ModelEvaluator::InArgs sg_inArgs = sg_model->createInArgs();
549  EpetraExt::ModelEvaluator::OutArgs sg_outArgs =
550  sg_model->createOutArgs();
551 
552  // Set up stochastic parameters
553  // The current implementation of the model doesn't actually use these
554  // values, but is hard-coded to certain uncertainty models
555  Teuchos::Array<double> point(num_KL, 1.0);
556  Teuchos::Array<double> basis_vals(sz);
557  basis->evaluateBases(point, basis_vals);
559  sg_model->create_p_sg(0);
560  for (int i=0; i<num_KL; i++) {
561  sg_p_init->term(i,0)[i] = 0.0;
562  sg_p_init->term(i,1)[i] = 1.0 / basis_vals[i+1];
563  }
564  sg_model->set_p_sg_init(0, *sg_p_init);
565 
566  // Setup stochastic initial guess
568  sg_model->create_x_sg();
569  sg_x_init->init(0.0);
570  sg_model->set_x_sg_init(*sg_x_init);
571 
572  // Create NOX interface
574  Teuchos::rcp(new NOX::Epetra::ModelEvaluatorInterface(sg_model));
575 
576  // Create NOX stochastic linear system object
578  Teuchos::RCP<const Epetra_Map> base_map = model->get_x_map();
579  Teuchos::RCP<const Epetra_Map> sg_map = sg_model->get_x_map();
583 
584  // Build linear solver
586  if (solve_method==SG_KRYLOV) {
587  bool has_M =
588  sg_outArgs.supports(EpetraExt::ModelEvaluator::OUT_ARG_WPrec);
591  if (has_M) {
592  M = sg_model->create_WPrec()->PrecOp;
593  iPrec = nox_interface;
594  }
595  stratParams.set("Preconditioner Type", "None");
596  if (outer_krylov_solver == AZTECOO) {
597  stratParams.set("Linear Solver Type", "AztecOO");
598  Teuchos::ParameterList& aztecOOParams =
599  stratParams.sublist("Linear Solver Types").sublist("AztecOO").sublist("Forward Solve");
600  Teuchos::ParameterList& aztecOOSettings =
601  aztecOOParams.sublist("AztecOO Settings");
602  if (outer_krylov_method == GMRES) {
603  aztecOOSettings.set("Aztec Solver","GMRES");
604  }
605  else if (outer_krylov_method == CG) {
606  aztecOOSettings.set("Aztec Solver","CG");
607  }
608  aztecOOSettings.set("Output Frequency", 1);
609  aztecOOSettings.set("Size of Krylov Subspace", 100);
610  aztecOOParams.set("Max Iterations", outer_its);
611  aztecOOParams.set("Tolerance", outer_tol);
612  stratLinSolParams.set("Preconditioner", "User Defined");
613  if (has_M)
614  linsys =
615  Teuchos::rcp(new NOX::Epetra::LinearSystemStratimikos(
616  printParams, stratLinSolParams, iJac, A, iPrec, M,
617  *u, true));
618  else
619  linsys =
620  Teuchos::rcp(new NOX::Epetra::LinearSystemStratimikos(
621  printParams, stratLinSolParams, iJac, A, *u));
622  }
623  else if (outer_krylov_solver == BELOS){
624  stratParams.set("Linear Solver Type", "Belos");
625  Teuchos::ParameterList& belosParams =
626  stratParams.sublist("Linear Solver Types").sublist("Belos");
627  Teuchos::ParameterList* belosSolverParams = NULL;
628  if (outer_krylov_method == GMRES || outer_krylov_method == FGMRES) {
629  belosParams.set("Solver Type","Block GMRES");
630  belosSolverParams =
631  &(belosParams.sublist("Solver Types").sublist("Block GMRES"));
632  if (outer_krylov_method == FGMRES)
633  belosSolverParams->set("Flexible Gmres", true);
634  }
635  else if (outer_krylov_method == CG) {
636  belosParams.set("Solver Type","Block CG");
637  belosSolverParams =
638  &(belosParams.sublist("Solver Types").sublist("Block CG"));
639  }
640  else if (inner_krylov_method == RGMRES) {
641  belosParams.set("Solver Type","GCRODR");
642  belosSolverParams =
643  &(belosParams.sublist("Solver Types").sublist("GCRODR"));
644  }
645  belosSolverParams->set("Convergence Tolerance", outer_tol);
646  belosSolverParams->set("Maximum Iterations", outer_its);
647  belosSolverParams->set("Output Frequency",1);
648  belosSolverParams->set("Output Style",1);
649  belosSolverParams->set("Verbosity",33);
650  stratLinSolParams.set("Preconditioner", "User Defined");
651  if (has_M)
652  linsys =
653  Teuchos::rcp(new NOX::Epetra::LinearSystemStratimikos(
654  printParams, stratLinSolParams, iJac, A, iPrec, M,
655  *u, true));
656  else
657  linsys =
658  Teuchos::rcp(new NOX::Epetra::LinearSystemStratimikos(
659  printParams, stratLinSolParams, iJac, A, *u));
660 
661  }
662  }
663  else if (solve_method==SG_GS) {
664  lsParams.sublist("Deterministic Solver Parameters") = det_lsParams;
665  lsParams.set("Max Iterations", outer_its);
666  lsParams.set("Tolerance", outer_tol);
667  linsys =
668  Teuchos::rcp(new NOX::Epetra::LinearSystemSGGS(
669  printParams, lsParams, det_linsys, iReq, iJac,
670  basis, sg_parallel_data, A, base_map, sg_map));
671  }
672  else {
673  lsParams.sublist("Deterministic Solver Parameters") = det_lsParams;
674  lsParams.set("Max Iterations", outer_its);
675  lsParams.set("Tolerance", outer_tol);
676  Teuchos::ParameterList& jacobiOpParams =
677  lsParams.sublist("Jacobi SG Operator");
678  jacobiOpParams.set("Only Use Linear Terms", true);
679  linsys =
680  Teuchos::rcp(new NOX::Epetra::LinearSystemSGJacobi(
681  printParams, lsParams, det_linsys, iReq, iJac,
682  basis, sg_parallel_data, A, base_map, sg_map));
683  }
684 
685  // Build NOX group
687  Teuchos::rcp(new NOX::Epetra::Group(printParams, iReq, *u, linsys));
688 
689  // Create the Solver convergence test
691  NOX::StatusTest::buildStatusTests(statusParams, utils);
692 
693  // Create the solver
695  NOX::Solver::buildSolver(grp, statusTests, noxParams);
696 
697  // Solve the system
698  NOX::StatusTest::StatusType status;
699  {
700  TEUCHOS_FUNC_TIME_MONITOR("Total Solve Time");
701  status = solver->solve();
702  }
703 
704  // Get final solution
705  const NOX::Epetra::Group& finalGroup =
706  dynamic_cast<const NOX::Epetra::Group&>(solver->getSolutionGroup());
707  const Epetra_Vector& finalSolution =
708  (dynamic_cast<const NOX::Epetra::Vector&>(finalGroup.getX())).getEpetraVector();
709 
710  // Save final solution to file
711  EpetraExt::VectorToMatrixMarketFile("nox_solver_stochastic_solution.mm",
712  finalSolution);
713 
714  // Save mean and variance to file
716  sg_model->create_x_sg(View, &finalSolution);
717  Epetra_Vector mean(*(model->get_x_map()));
718  Epetra_Vector std_dev(*(model->get_x_map()));
719  sg_x_poly->computeMean(mean);
720  sg_x_poly->computeStandardDeviation(std_dev);
721  EpetraExt::VectorToMatrixMarketFile("mean_gal.mm", mean);
722  EpetraExt::VectorToMatrixMarketFile("std_dev_gal.mm", std_dev);
723 
724  // Evaluate SG responses at SG parameters
725  Teuchos::RCP<const Epetra_Vector> sg_p = sg_model->get_p_init(1);
727  Teuchos::rcp(new Epetra_Vector(*(sg_model->get_g_map(0))));
728  sg_inArgs.set_p(1, sg_p);
729  sg_inArgs.set_x(Teuchos::rcp(&finalSolution,false));
730  sg_outArgs.set_g(0, sg_g);
731  sg_model->evalModel(sg_inArgs, sg_outArgs);
732 
733  // Print mean and standard deviation of response
735  sg_model->create_g_sg(0, View, sg_g.get());
736  Epetra_Vector g_mean(*(model->get_g_map(0)));
737  Epetra_Vector g_std_dev(*(model->get_g_map(0)));
738  sg_g_poly->computeMean(g_mean);
739  sg_g_poly->computeStandardDeviation(g_std_dev);
740  std::cout.precision(16);
741  // std::cout << "\nResponse Expansion = " << std::endl;
742  // std::cout.precision(12);
743  // sg_g_poly->print(std::cout);
744  std::cout << std::endl;
745  std::cout << "Response Mean = " << std::endl << g_mean << std::endl;
746  std::cout << "Response Std. Dev. = " << std::endl << g_std_dev << std::endl;
747 
748  if (status == NOX::StatusTest::Converged && MyPID == 0)
749  utils.out() << "Example Passed!" << std::endl;
750 
751  }
752 
755 
756  }
757 
758  catch (std::exception& e) {
759  std::cout << e.what() << std::endl;
760  }
761  catch (std::string& s) {
762  std::cout << s << std::endl;
763  }
764  catch (char *s) {
765  std::cout << s << std::endl;
766  }
767  catch (...) {
768  std::cout << "Caught unknown exception!" << std::endl;
769  }
770 
771 #ifdef HAVE_MPI
772  MPI_Finalize() ;
773 #endif
774 
775 }
Teuchos::RCP< Stokhos::EpetraVectorOrthogPoly > create_x_sg(Epetra_DataAccess CV=Copy, const Epetra_Vector *v=NULL) const
Create vector orthog poly using x map and owned sg map.
Teuchos::RCP< Stokhos::EpetraVectorOrthogPoly > create_p_sg(int l, Epetra_DataAccess CV=Copy, const Epetra_Vector *v=NULL) const
Create vector orthog poly using p map.
Teuchos::RCP< const Epetra_Vector > get_x_init() const
Return initial solution.
Teuchos::RCP< const Epetra_Map > get_x_map() const
Return solution vector map.
#define TEUCHOS_FUNC_TIME_MONITOR(FUNCNAME)
Hermite polynomial basis.
const Krylov_Method krylov_method_values[]
void computeStandardDeviation(Epetra_Vector &v) const
Compute standard deviation.
Teuchos::RCP< const Epetra_Map > get_g_map(int l) const
Return response map.
Teuchos::RCP< const EpetraExt::MultiComm > getMultiComm() const
Get global comm.
double uniform_weight(const double &x)
void evalModel(const InArgs &inArgs, const OutArgs &outArgs) const
Evaluate model on InArgs.
void computeMean(Epetra_Vector &v) const
Compute mean.
void init(const value_type &val)
Initialize coefficients.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
const SG_Prec sg_prec_values[]
RCP< ParameterList > sublist(const RCP< ParameterList > &paramList, const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
T * get() const
const char * sg_op_names[]
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
const char * krylov_solver_names[]
virtual int MyPID() const =0
Nonlinear, stochastic Galerkin ModelEvaluator.
OutArgs createOutArgs() const
Create OutArgs.
Teuchos::RCP< Stokhos::EpetraVectorOrthogPoly > create_g_sg(int l, Epetra_DataAccess CV=Copy, const Epetra_Vector *v=NULL) const
Create vector orthog poly using g map.
ModelEvaluator for a linear 2-D diffusion problem.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Rys polynomial basis.
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)
Teuchos::RCP< const Epetra_Vector > get_x_init() const
Return initial solution.
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
const SG_RF sg_rf_values[]
void set_p_sg_init(int i, const Stokhos::EpetraVectorOrthogPoly &p_sg_in)
Set initial parameter polynomial.
EParseCommandLineReturn parse(int argc, char *argv[], std::ostream *errout=&std::cerr) const
const char * sg_solver_names[]
const int num_sg_rf
const SG_Op sg_op_values[]
Teuchos::RCP< const Epetra_Map > get_g_map(int j) const
Return response function map.
Legendre polynomial basis.
InArgs createInArgs() const
Create InArgs.
void set_x_sg_init(const Stokhos::EpetraVectorOrthogPoly &x_sg_in)
Set initial solution polynomial.
int main(int argc, char **argv)
Teuchos::RCP< Epetra_Operator > create_W() const
Create W = alpha*M + beta*J matrix.
const char * sg_rf_names[]
void setDocString(const char doc_string[])
const char * sg_prec_names[]
Teuchos::RCP< const Epetra_Comm > getSpatialComm() const
Get spatial comm.
Teuchos::RCP< const Epetra_Map > get_x_map() const
Return solution vector map.
Teuchos::RCP< Epetra_Operator > create_W() const
Create W = alpha*M + beta*J matrix.
const Krylov_Solver krylov_solver_values[]
coeff_type & term(ordinal_type dimension, ordinal_type order)
Get term for dimension dimension and order order.
int n
const SG_Solver sg_solver_values[]
Teuchos::RCP< const Epetra_Vector > get_p_init(int l) const
Return initial parameters.
Teuchos::RCP< EpetraExt::ModelEvaluator::Preconditioner > create_WPrec() const
Create preconditioner operator.
static void zeroOutTimers()
const char * krylov_method_names[]