Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
nonlinear_sg_example.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 #include <iostream>
11 
12 // NOX
13 #include "NOX.H"
14 #include "NOX_Epetra.H"
15 
16 // Epetra communicator
17 #ifdef HAVE_MPI
18 #include "Epetra_MpiComm.h"
19 #else
20 #include "Epetra_SerialComm.h"
21 #endif
22 
23 // Stokhos Stochastic Galerkin
24 #include "Stokhos_Epetra.hpp"
25 
26 // Utilities
29 
30 // Our model
31 #include "SimpleME.hpp"
32 
33 // Function to create NOX's parameter list
38 
39  // Set the nonlinear solver method
40  noxParams->set("Nonlinear Solver", "Line Search Based");
41 
42  // Set the printing parameters in the "Printing" sublist
43  Teuchos::ParameterList& printParams = noxParams->sublist("Printing");
44  printParams.set("MyPID", MyPID);
45  printParams.set("Output Precision", 3);
46  printParams.set("Output Processor", 0);
47  printParams.set("Output Information",
48  NOX::Utils::OuterIteration +
49  NOX::Utils::OuterIterationStatusTest +
50  NOX::Utils::InnerIteration +
51  //NOX::Utils::Parameters +
52  //NOX::Utils::Details +
53  NOX::Utils::LinearSolverDetails +
54  NOX::Utils::Warning +
55  NOX::Utils::Error);
56 
57  // Sublist for line search
58  Teuchos::ParameterList& searchParams = noxParams->sublist("Line Search");
59  searchParams.set("Method", "Full Step");
60 
61  // Sublist for direction
62  Teuchos::ParameterList& dirParams = noxParams->sublist("Direction");
63  dirParams.set("Method", "Newton");
64  Teuchos::ParameterList& newtonParams = dirParams.sublist("Newton");
65  newtonParams.set("Forcing Term Method", "Constant");
66 
67  // Sublist for linear solver for the Newton method
68  Teuchos::ParameterList& lsParams = newtonParams.sublist("Linear Solver");
69  lsParams.set("Aztec Solver", "GMRES");
70  lsParams.set("Max Iterations", 100);
71  lsParams.set("Size of Krylov Subspace", 100);
72  lsParams.set("Tolerance", 1e-4);
73  lsParams.set("Output Frequency", 10);
74  lsParams.set("Preconditioner", "Ifpack");
75 
76  // Sublist for convergence tests
77  Teuchos::ParameterList& statusParams = noxParams->sublist("Status Tests");
78  statusParams.set("Test Type", "Combo");
79  statusParams.set("Number of Tests", 2);
80  statusParams.set("Combo Type", "OR");
81  Teuchos::ParameterList& normF = statusParams.sublist("Test 0");
82  normF.set("Test Type", "NormF");
83  normF.set("Tolerance", 1e-10);
84  normF.set("Scale Type", "Scaled");
85  Teuchos::ParameterList& maxIters = statusParams.sublist("Test 1");
86  maxIters.set("Test Type", "MaxIters");
87  maxIters.set("Maximum Iterations", 10);
88 
89  return noxParams;
90 }
91 
95  using Teuchos::rcp;
96  using Teuchos::RCP;
98 
99  // Set up NOX parameters (implemented above)
100  RCP<ParameterList> noxParams = create_nox_parameter_list(MyPID);
101 
102  // Create printing utilities
103  ParameterList& printParams = noxParams->sublist("Printing");
104  NOX::Utils utils(printParams);
105 
106  // Create NOX interface
107  RCP<NOX::Epetra::ModelEvaluatorInterface> nox_interface =
108  rcp(new NOX::Epetra::ModelEvaluatorInterface(sg_model));
109 
110  // Create NOX linear system object
111  RCP<const Epetra_Vector> u = sg_model->get_x_init();
112  RCP<Epetra_Operator> A = sg_model->create_W();
113  RCP<NOX::Epetra::Interface::Required> iReq = nox_interface;
114  RCP<NOX::Epetra::Interface::Jacobian> iJac = nox_interface;
115  RCP<NOX::Epetra::LinearSystemAztecOO> linsys;
116  RCP<Epetra_Operator> M = sg_model->create_WPrec()->PrecOp;
117  RCP<NOX::Epetra::Interface::Preconditioner> iPrec = nox_interface;
118  ParameterList& dirParams = noxParams->sublist("Direction");
119  ParameterList& newtonParams = dirParams.sublist("Newton");
120  ParameterList& lsParams = newtonParams.sublist("Linear Solver");
121  lsParams.set("Preconditioner", "User Defined");
122  linsys = rcp(new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams,
123  iJac, A, iPrec, M, *u));
124 
125  // Build NOX group
126  RCP<NOX::Epetra::Group> grp =
127  rcp(new NOX::Epetra::Group(printParams, iReq, *u, linsys));
128 
129  // Create the Solver convergence test
130  ParameterList& statusParams = noxParams->sublist("Status Tests");
131  RCP<NOX::StatusTest::Generic> statusTests =
132  NOX::StatusTest::buildStatusTests(statusParams, utils);
133 
134  // Create the solver
135  RCP<NOX::Solver::Generic> solver =
136  NOX::Solver::buildSolver(grp, statusTests, noxParams);
137 
138  return solver;
139 }
140 
141 const Epetra_Vector& get_final_solution(const NOX::Solver::Generic& solver) {
142  const NOX::Epetra::Group& finalGroup =
143  dynamic_cast<const NOX::Epetra::Group&>(solver.getSolutionGroup());
144  const Epetra_Vector& finalSolution =
145  (dynamic_cast<const NOX::Epetra::Vector&>(finalGroup.getX())).getEpetraVector();
146  return finalSolution;
147 }
148 
149 int main(int argc, char *argv[]) {
150  using Teuchos::rcp;
151  using Teuchos::RCP;
152  using Teuchos::Array;
159  using Stokhos::ParallelData;
162 
163  // Initialize MPI
164  Teuchos::GlobalMPISession mpiSession(&argc, &argv);
165 
166  int MyPID;
167  bool success = true;
168  try {
169 
170  // Create a communicator for Epetra objects
171  RCP<const Epetra_Comm> globalComm;
172 #ifdef HAVE_MPI
173  globalComm = rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
174 #else
175  globalComm = rcp(new Epetra_SerialComm);
176 #endif
177  MyPID = globalComm->MyPID();
178 
179  // Create Stochastic Galerkin basis and expansion
180  const int p = 5;
181  Array< RCP<const OneDOrthogPolyBasis<int,double> > > bases(1);
182  bases[0] = rcp(new LegendreBasis<int,double>(p));
183  RCP<const CompletePolynomialBasis<int,double> > basis =
184  rcp(new CompletePolynomialBasis<int,double>(bases));
185  RCP<Stokhos::Sparse3Tensor<int,double> > Cijk =
186  basis->computeTripleProductTensor();
187  RCP<OrthogPolyExpansion<int,double> > expansion =
188  rcp(new AlgebraicOrthogPolyExpansion<int,double>(basis, Cijk));
189 
190  // Create stochastic parallel distribution
191  int num_spatial_procs = -1;
192  ParameterList parallelParams;
193  parallelParams.set("Number of Spatial Processors", num_spatial_procs);
194  RCP<ParallelData> sg_parallel_data =
195  rcp(new ParallelData(basis, Cijk, globalComm, parallelParams));
196  RCP<const Epetra_Comm> app_comm = sg_parallel_data->getSpatialComm();
197 
198  // Create application model evaluator
199  RCP<EpetraExt::ModelEvaluator> model = rcp(new SimpleME(app_comm));
200 
201  // Setup stochastic Galerkin algorithmic parameters
202  RCP<ParameterList> sgParams = rcp(new ParameterList);
203  ParameterList& sgPrecParams = sgParams->sublist("SG Preconditioner");
204  sgPrecParams.set("Preconditioner Method", "Mean-based");
205  //sgPrecParams.set("Preconditioner Method", "Approximate Gauss-Seidel");
206  //sgPrecParams.set("Preconditioner Method", "Approximate Schur Complement");
207  sgPrecParams.set("Mean Preconditioner Type", "Ifpack");
208 
209  // Create stochastic Galerkin model evaluator
210  RCP<SGModelEvaluator> sg_model =
211  rcp(new SGModelEvaluator(model, basis, Teuchos::null, expansion,
212  sg_parallel_data, sgParams));
213 
214  // Stochastic Galerkin initial guess
215  // Set the mean to the deterministic initial guess, higher-order terms
216  // to zero
217  RCP<EpetraVectorOrthogPoly> x_init_sg = sg_model->create_x_sg();
218  x_init_sg->init(0.0);
219  (*x_init_sg)[0] = *(model->get_x_init());
220  sg_model->set_x_sg_init(*x_init_sg);
221 
222  // Stochastic Galerkin parameters
223  // Linear expansion with the mean given by the deterministic initial
224  // parameter values, linear terms equal to 1, and higher order terms
225  // equal to zero.
226  RCP<EpetraVectorOrthogPoly> p_init_sg = sg_model->create_p_sg(0);
227  p_init_sg->init(0.0);
228  (*p_init_sg)[0] = *(model->get_p_init(0));
229  for (int i=0; i<model->get_p_map(0)->NumMyElements(); i++)
230  (*p_init_sg)[i+1][i] = 1.0;
231  sg_model->set_p_sg_init(0, *p_init_sg);
232  std::cout << "Stochatic Galerkin parameter expansion = " << std::endl
233  << *p_init_sg << std::endl;
234 
235  // Build nonlinear solver (implemented above)
236  RCP<NOX::Solver::Generic> solver = create_nox_solver(MyPID, sg_model);
237 
238  // Solve the system
239  NOX::StatusTest::StatusType status = solver->solve();
240 
241  // Get final solution
242  const Epetra_Vector& finalSolution = get_final_solution(*solver);
243 
244  // Convert block Epetra_Vector to orthogonal polynomial of Epetra_Vector's
245  RCP<Stokhos::EpetraVectorOrthogPoly> x_sg =
246  sg_model->create_x_sg(View, &finalSolution);
247 
248  if (MyPID == 0)
249  std::cout << "Final Solution = " << std::endl;
250  std::cout << *x_sg << std::endl;
251 
252  if (status != NOX::StatusTest::Converged)
253  success = false;
254  }
255  TEUCHOS_STANDARD_CATCH_STATEMENTS(true, std::cerr, success);
256 
257  if (success && MyPID == 0)
258  std::cout << "Example Passed!" << std::endl;
259 
260  if (!success)
261  return 1;
262  return 0;
263 }
RCP< ParameterList > sublist(const RCP< ParameterList > &paramList, const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
Orthogonal polynomial expansions limited to algebraic operations.
Nonlinear, stochastic Galerkin ModelEvaluator.
Teuchos::RCP< Teuchos::ParameterList > create_nox_parameter_list(int MyPID)
Abstract base class for orthogonal polynomial-based expansions.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
const Epetra_Vector & get_final_solution(const NOX::Solver::Generic &solver)
A container class storing an orthogonal polynomial whose coefficients are vectors, operators, or in general any type that would have an expensive copy constructor.
#define TEUCHOS_STANDARD_CATCH_STATEMENTS(VERBOSE, ERR_STREAM, SUCCESS_FLAG)
Multivariate orthogonal polynomial basis generated from a total-order complete-polynomial tensor prod...
Legendre polynomial basis.
int main(int argc, char **argv)
Abstract base class for 1-D orthogonal polynomials.
Teuchos::RCP< NOX::Solver::Generic > create_nox_solver(int MyPID, const Teuchos::RCP< EpetraExt::ModelEvaluator > &sg_model)