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_collocation.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 // AztecOO solver
21 #include "AztecOO.h"
22 
23 // Stokhos Stochastic Galerkin
24 #include "Stokhos.hpp"
25 
26 // Timing utilities
28 #include "Teuchos_TimeMonitor.hpp"
29 
30 // I/O utilities
31 #include "EpetraExt_VectorOut.h"
32 
33 // Krylov methods
35 const int num_krylov_method = 2;
37 const char *krylov_method_names[] = { "GMRES", "CG" };
38 
39 // Collocation preconditioning strategies
41 const int num_prec_strategy = 3;
43 const char *prec_strategy_names[] = { "Mean", "Reuse", "Rebuild" };
44 
45 // Random field types
47 const int num_sg_rf = 4;
49 const char *sg_rf_names[] = { "Uniform", "CC-Uniform", "Rys", "Log-Normal" };
50 
51 // Quadrature types
53 const int num_sg_quad = 2;
55 const char *sg_quad_names[] = { "tensor", "sparse-grid" };
56 
57 // Sparse grid growth rules
59 const int num_sg_growth = 3;
62 const char *sg_growth_names[] = {
63  "Slow Restricted", "Moderate Restricted", "Unrestricted" };
64 
65 int main(int argc, char *argv[]) {
66 
67 // Initialize MPI
68 #ifdef HAVE_MPI
69  MPI_Init(&argc,&argv);
70 #endif
71 
72  // Create a communicator for Epetra objects
74 #ifdef HAVE_MPI
75  Comm = Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
76 #else
77  Comm = Teuchos::rcp(new Epetra_SerialComm);
78 #endif
79 
80  int MyPID = Comm->MyPID();
81 
82  try {
83 
84  // Setup command line options
86  CLP.setDocString(
87  "This example runs a stochastic collocation method.\n");
88 
89  int n = 32;
90  CLP.setOption("num_mesh", &n, "Number of mesh points in each direction");
91 
92  SG_RF randField = UNIFORM;
93  CLP.setOption("rand_field", &randField,
95  "Random field type");
96 
97  double mean = 0.2;
98  CLP.setOption("mean", &mean, "Mean");
99 
100  double sigma = 0.1;
101  CLP.setOption("std_dev", &sigma, "Standard deviation");
102 
103  double weightCut = 1.0;
104  CLP.setOption("weight_cut", &weightCut, "Weight cut");
105 
106  int num_KL = 2;
107  CLP.setOption("num_kl", &num_KL, "Number of KL terms");
108 
109  int p = 3;
110  CLP.setOption("order", &p, "Polynomial order");
111 
112  bool normalize_basis = true;
113  CLP.setOption("normalize", "unnormalize", &normalize_basis,
114  "Normalize PC basis");
115 
116  Krylov_Method krylov_method = CG;
117  CLP.setOption("krylov_method", &krylov_method,
119  "Krylov method");
120 
121  PrecStrategy precStrategy = MEAN;
122  CLP.setOption("prec_strategy", &precStrategy,
124  "Preconditioner strategy");
125 
126  double tol = 1e-12;
127  CLP.setOption("tol", &tol, "Solver tolerance");
128 
129 #ifdef HAVE_STOKHOS_DAKOTA
130  SG_Quad quad_method = SPARSE_GRID;
131 #else
132  SG_Quad quad_method = TENSOR;
133 #endif
134  CLP.setOption("quadrature", &quad_method,
136  "Quadrature type");
137 
138  SG_GROWTH sg_growth = MODERATE_RESTRICTED;
139  CLP.setOption("sg_growth", &sg_growth,
141  "Sparse grid growth rule");
142 
143  CLP.parse( argc, argv );
144 
145  if (MyPID == 0) {
146  std::cout << "Summary of command line options:" << std::endl
147  << "\tnum_mesh = " << n << std::endl
148  << "\trand_field = " << sg_rf_names[randField] << std::endl
149  << "\tmean = " << mean << std::endl
150  << "\tstd_dev = " << sigma << std::endl
151  << "\tnum_kl = " << num_KL << std::endl
152  << "\torder = " << p << std::endl
153  << "\tnormalize_basis = " << normalize_basis << std::endl
154  << "\tkrylov_method = " << krylov_method_names[krylov_method]
155  << std::endl
156  << "\tprec_strategy = " << prec_strategy_names[precStrategy]
157  << std::endl
158  << "\ttol = " << tol << std::endl
159  << "\tquadrature = " << sg_quad_names[quad_method]
160  << std::endl
161  << "\tsg_growth = " << sg_growth_names[sg_growth]
162  << std::endl;
163  }
164 
165  bool nonlinear_expansion = false;
166  if (randField == LOGNORMAL)
167  nonlinear_expansion = true;
168 
169  {
170  TEUCHOS_FUNC_TIME_MONITOR("Total Collocation Calculation Time");
171 
172  // Create Stochastic Galerkin basis
174  for (int i=0; i<num_KL; i++) {
176  if (randField == UNIFORM) {
178  p, normalize_basis));
179  }
180  else if (randField == CC_UNIFORM) {
181  b =
183  p, normalize_basis, true));
184  }
185  else if (randField == RYS) {
187  p, weightCut, normalize_basis));
188  }
189  else if (randField == LOGNORMAL) {
191  p, normalize_basis));
192  }
193  bases[i] = b;
194  }
197 
198  // Create sparse grid
200  if (quad_method == SPARSE_GRID) {
201 #ifdef HAVE_STOKHOS_DAKOTA
202  int sparse_grid_growth = Pecos::MODERATE_RESTRICTED_GROWTH;
203  if (sg_growth == SLOW_RESTRICTED)
204  sparse_grid_growth = Pecos::SLOW_RESTRICTED_GROWTH;
205  else if (sg_growth == MODERATE_RESTRICTED)
206  sparse_grid_growth = Pecos::MODERATE_RESTRICTED_GROWTH;
207  else if (sg_growth == UNRESTRICTED)
208  sparse_grid_growth = Pecos::UNRESTRICTED_GROWTH;
209  quad = Teuchos::rcp(new Stokhos::SparseGridQuadrature<int,double>(
210  basis,p,1e-12,sparse_grid_growth));
211 #else
213  true, std::logic_error,
214  "Sparse grids require building with Dakota support!");
215 #endif
216  }
217  else if (quad_method == TENSOR) {
218  quad =
220  }
221  const Teuchos::Array< Teuchos::Array<double> >& quad_points =
222  quad->getQuadPoints();
223  const Teuchos::Array<double>& quad_weights = quad->getQuadWeights();
224  int nqp = quad_weights.size();
225 
226  // Create application
227  twoD_diffusion_ME model(Comm, n, num_KL, sigma, mean,
228  basis, nonlinear_expansion);
229 
230  // Model data
232  Teuchos::rcp(new Epetra_Vector(*(model.get_p_map(0))));
234  Teuchos::rcp(new Epetra_Vector(*(model.get_x_map())));
236  Teuchos::rcp(new Epetra_Vector(*(model.get_f_map())));
238  Teuchos::rcp(new Epetra_Vector(*(model.get_g_map(0))));
240  Teuchos::rcp_dynamic_cast<Epetra_CrsMatrix>(model.create_W());
241  EpetraExt::ModelEvaluator::InArgs inArgs = model.createInArgs();
242  EpetraExt::ModelEvaluator::OutArgs outArgs = model.createOutArgs();
243  EpetraExt::ModelEvaluator::OutArgs outArgs2 = model.createOutArgs();
244 
245  // Data to compute/store mean & variance
246  Epetra_Vector x2(*(model.get_x_map()));
247  Epetra_Vector x_mean(*(model.get_x_map()));
248  Epetra_Vector x_var(*(model.get_x_map()));
249  Epetra_Vector g2(*(model.get_g_map(0)));
250  Epetra_Vector g_mean(*(model.get_g_map(0)));
251  Epetra_Vector g_var(*(model.get_g_map(0)));
252 
253  // Setup preconditioner
254  Teuchos::ParameterList precParams;
255  precParams.set("default values", "SA");
256  precParams.set("ML output", 0);
257  precParams.set("max levels",5);
258  precParams.set("increasing or decreasing","increasing");
259  precParams.set("aggregation: type", "Uncoupled");
260  precParams.set("smoother: type","ML symmetric Gauss-Seidel");
261  precParams.set("smoother: sweeps",2);
262  precParams.set("smoother: pre or post", "both");
263  precParams.set("coarse: max size", 200);
264 #ifdef HAVE_ML_AMESOS
265  precParams.set("coarse: type","Amesos-KLU");
266 #else
267  precParams.set("coarse: type","Jacobi");
268 #endif
269  bool checkFiltering = false;
270  if (precStrategy == REUSE) {
271  checkFiltering = true;
272  precParams.set("reuse: enable", true);
273  }
275  Teuchos::rcp(new ML_Epetra::MultiLevelPreconditioner(*A, precParams,
276  false));
277  if (precStrategy == MEAN) {
278  TEUCHOS_FUNC_TIME_MONITOR("Deterministic Preconditioner Calculation");
279  *A = *(model.get_mean());
280  M->ComputePreconditioner();
281  }
282 
283  // Setup AztecOO solver
284  AztecOO aztec;
285  if (krylov_method == GMRES)
286  aztec.SetAztecOption(AZ_solver, AZ_gmres);
287  else if (krylov_method == CG)
288  aztec.SetAztecOption(AZ_solver, AZ_cg);
289  aztec.SetAztecOption(AZ_precond, AZ_none);
290  aztec.SetAztecOption(AZ_kspace, 100);
291  aztec.SetAztecOption(AZ_conv, AZ_r0);
292  aztec.SetAztecOption(AZ_output, 0);
293  aztec.SetUserOperator(A.get());
294  aztec.SetPrecOperator(M.get());
295  aztec.SetLHS(x.get());
296  aztec.SetRHS(f.get());
297 
298  x_mean.PutScalar(0.0);
299  x_var.PutScalar(0.0);
300  // Loop over colloction points
301  for (int qp=0; qp<nqp; qp++) {
302  TEUCHOS_FUNC_TIME_MONITOR("Collocation Loop");
303 
304  if (qp%100 == 0 || qp == nqp-1)
305  std::cout << "Collocation point " << qp+1 <<'/' << nqp << "\n";
306 
307  // Set parameters
308  for (int i=0; i<num_KL; i++)
309  (*p)[i] = quad_points[qp][i];
310 
311  // Set in/out args
312  inArgs.set_p(0, p);
313  inArgs.set_x(x);
314  outArgs.set_f(f);
315  outArgs.set_W(A);
316 
317  // Evaluate model at collocation point
318  x->PutScalar(0.0);
319  model.evalModel(inArgs, outArgs);
320  f->Scale(-1.0);
321 
322  // Compute preconditioner
323  if (precStrategy != MEAN) {
324  TEUCHOS_FUNC_TIME_MONITOR("Deterministic Preconditioner Calculation");
325  M->ComputePreconditioner(checkFiltering);
326  }
327 
328  // Solve linear system
329  {
330  TEUCHOS_FUNC_TIME_MONITOR("Deterministic Solve");
331  aztec.Iterate(1000, tol);
332  }
333 
334  // Compute responses
335  outArgs2.set_g(0, g);
336  model.evalModel(inArgs, outArgs2);
337 
338  // Sum contributions to mean and variance
339  x2.Multiply(1.0, *x, *x, 0.0);
340  g2.Multiply(1.0, *g, *g, 0.0);
341  x_mean.Update(quad_weights[qp], *x, 1.0);
342  x_var.Update(quad_weights[qp], x2, 1.0);
343  g_mean.Update(quad_weights[qp], *g, 1.0);
344  g_var.Update(quad_weights[qp], g2, 1.0);
345 
346  }
347  x2.Multiply(1.0, x_mean, x_mean, 0.0);
348  g2.Multiply(1.0, g_mean, g_mean, 0.0);
349  x_var.Update(-1.0, x2, 1.0);
350  g_var.Update(-1.0, g2, 1.0);
351 
352  // Compute standard deviations
353  for (int i=0; i<x_var.MyLength(); i++)
354  x_var[i] = std::sqrt(x_var[i]);
355  for (int i=0; i<g_var.MyLength(); i++)
356  g_var[i] = std::sqrt(g_var[i]);
357 
358  std::cout.precision(16);
359  std::cout << "\nResponse Mean = " << std::endl << g_mean << std::endl;
360  std::cout << "Response Std. Dev. = " << std::endl << g_var << std::endl;
361 
362  // Save mean and variance to file
363  EpetraExt::VectorToMatrixMarketFile("mean_col.mm", x_mean);
364  EpetraExt::VectorToMatrixMarketFile("std_dev_col.mm", x_var);
365 
366  }
367 
370 
371  }
372 
373  catch (std::exception& e) {
374  std::cout << e.what() << std::endl;
375  }
376  catch (std::string& s) {
377  std::cout << s << std::endl;
378  }
379  catch (char *s) {
380  std::cout << s << std::endl;
381  }
382  catch (...) {
383  std::cout << "Caught unknown exception!" <<std:: endl;
384  }
385 
386 #ifdef HAVE_MPI
387  MPI_Finalize() ;
388 #endif
389 
390 }
const char * prec_strategy_names[]
KOKKOS_INLINE_FUNCTION PCE< Storage > sqrt(const PCE< Storage > &a)
#define TEUCHOS_FUNC_TIME_MONITOR(FUNCNAME)
Hermite polynomial basis.
const Krylov_Method krylov_method_values[]
void evalModel(const InArgs &inArgs, const OutArgs &outArgs) const
Evaluate model on InArgs.
const SG_Quad sg_quad_values[]
Teuchos::RCP< Epetra_CrsMatrix > get_mean() const
Get mean matrix.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
const int num_prec_strategy
T * get() const
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
virtual int MyPID() const =0
const SG_GROWTH sg_growth_values[]
const char * sg_growth_names[]
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)
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
const SG_RF sg_rf_values[]
const char * sg_quad_names[]
EParseCommandLineReturn parse(int argc, char *argv[], std::ostream *errout=&std::cerr) const
const int num_sg_rf
Teuchos::RCP< const Epetra_Map > get_p_map(int l) const
Return parameter vector map.
Teuchos::RCP< const Epetra_Map > get_g_map(int j) const
Return response function map.
Legendre polynomial basis.
int main(int argc, char **argv)
Teuchos::RCP< Epetra_Operator > create_W() const
Create W = alpha*M + beta*J matrix.
InArgs createInArgs() const
Create InArgs.
const char * sg_rf_names[]
OutArgs createOutArgs() const
Create OutArgs.
ScalarType f(const Teuchos::Array< ScalarType > &x, double a, double b)
Legendre polynomial basis using Clenshaw-Curtis quadrature points.
void setDocString(const char doc_string[])
const int num_sg_growth
size_type size() const
Teuchos::RCP< const Epetra_Map > get_x_map() const
Return solution vector map.
const PrecStrategy prec_strategy_values[]
const int num_sg_quad
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()
Teuchos::RCP< const Epetra_Map > get_f_map() const
Return residual vector map.
const char * krylov_method_names[]