Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
epetra/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 // 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_Epetra.hpp"
25 
26 // Timing utilities
27 #include "Teuchos_TimeMonitor.hpp"
28 
29 // I/O utilities
30 #include "EpetraExt_VectorOut.h"
31 
32 int main(int argc, char *argv[]) {
33  int n = 32; // spatial discretization (per dimension)
34  int num_KL = 2; // number of KL terms
35  int p = 3; // polynomial order
36  double mu = 0.2; // mean of exponential random field
37  double s = 0.1; // std. dev. of exponential r.f.
38  bool nonlinear_expansion = false; // nonlinear expansion of diffusion coeff
39  // (e.g., log-normal)
40  bool symmetric = false; // use symmetric formulation
41 
42  double g_mean_exp = 0.172988; // expected response mean
43  double g_std_dev_exp = 0.0380007; // expected response std. dev.
44  double g_tol = 1e-6; // tolerance on determining success
45 
46 // Initialize MPI
47 #ifdef HAVE_MPI
48  MPI_Init(&argc,&argv);
49 #endif
50 
51  int MyPID;
52 
53  try {
54 
55  {
56  TEUCHOS_FUNC_TIME_MONITOR("Total PCE Calculation Time");
57 
58  // Create a communicator for Epetra objects
60 #ifdef HAVE_MPI
61  globalComm = Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
62 #else
63  globalComm = Teuchos::rcp(new Epetra_SerialComm);
64 #endif
65  MyPID = globalComm->MyPID();
66 
67  // Create Stochastic Galerkin basis and expansion
69  for (int i=0; i<num_KL; i++)
70  bases[i] = Teuchos::rcp(new Stokhos::LegendreBasis<int,double>(p,true));
73  1e-12));
74  int sz = basis->size();
76  if (nonlinear_expansion)
77  Cijk = basis->computeTripleProductTensor();
78  else
79  Cijk = basis->computeLinearTripleProductTensor();
82  Cijk));
83  if (MyPID == 0)
84  std::cout << "Stochastic Galerkin expansion size = " << sz << std::endl;
85 
86  // Create stochastic parallel distribution
87  int num_spatial_procs = -1;
88  if (argc > 1)
89  num_spatial_procs = std::atoi(argv[1]);
90  Teuchos::ParameterList parallelParams;
91  parallelParams.set("Number of Spatial Processors", num_spatial_procs);
92  // parallelParams.set("Rebalance Stochastic Graph", true);
93  // Teuchos::ParameterList& isorropia_params =
94  // parallelParams.sublist("Isorropia");
95  // isorropia_params.set("Balance objective", "nonzeros");
96  Teuchos::RCP<Stokhos::ParallelData> sg_parallel_data =
97  Teuchos::rcp(new Stokhos::ParallelData(basis, Cijk, globalComm,
98  parallelParams));
100  sg_parallel_data->getMultiComm();
102  sg_parallel_data->getSpatialComm();
103 
104  // Create application
106  Teuchos::rcp(new twoD_diffusion_ME(app_comm, n, num_KL, s, mu, basis,
107  nonlinear_expansion, symmetric));
108 
109  // Setup stochastic Galerkin algorithmic parameters
112  Teuchos::ParameterList& sgOpParams =
113  sgParams->sublist("SG Operator");
114  Teuchos::ParameterList& sgPrecParams =
115  sgParams->sublist("SG Preconditioner");
116  if (!nonlinear_expansion) {
117  sgParams->set("Parameter Expansion Type", "Linear");
118  sgParams->set("Jacobian Expansion Type", "Linear");
119  }
120  sgOpParams.set("Operator Method", "Matrix Free");
121  sgPrecParams.set("Preconditioner Method", "Mean-based");
122  //sgPrecParams.set("Preconditioner Method", "Approximate Gauss-Seidel");
123  //sgPrecParams.set("Preconditioner Method", "Approximate Schur Complement");
124  sgPrecParams.set("Symmetric Gauss-Seidel", symmetric);
125  sgPrecParams.set("Mean Preconditioner Type", "ML");
126  Teuchos::ParameterList& precParams =
127  sgPrecParams.sublist("Mean Preconditioner Parameters");
128  precParams.set("default values", "SA");
129  precParams.set("ML output", 0);
130  precParams.set("max levels",5);
131  precParams.set("increasing or decreasing","increasing");
132  precParams.set("aggregation: type", "Uncoupled");
133  precParams.set("smoother: type","ML symmetric Gauss-Seidel");
134  precParams.set("smoother: sweeps",2);
135  precParams.set("smoother: pre or post", "both");
136  precParams.set("coarse: max size", 200);
137 #ifdef HAVE_ML_AMESOS
138  precParams.set("coarse: type","Amesos-KLU");
139 #else
140  precParams.set("coarse: type","Jacobi");
141 #endif
142 
143  // Create stochastic Galerkin model evaluator
146  expansion, sg_parallel_data,
147  sgParams));
148 
149  // Set up stochastic parameters
150  // The current implementation of the model doesn't actually use these
151  // values, but is hard-coded to certain uncertainty models
152  Teuchos::Array<double> point(num_KL, 1.0);
153  Teuchos::Array<double> basis_vals(sz);
154  basis->evaluateBases(point, basis_vals);
156  sg_model->create_p_sg(0);
157  for (int i=0; i<num_KL; i++) {
158  sg_p_poly->term(i,0)[i] = 0.0;
159  sg_p_poly->term(i,1)[i] = 1.0 / basis_vals[i+1];
160  }
161  std::cout << *sg_p_poly << std::endl;
162 
163  // Create vectors and operators
166  Teuchos::rcp(new Epetra_Vector(*(sg_model->get_x_map())));
167  sg_x->PutScalar(0.0);
169  Teuchos::rcp(new Epetra_Vector(*(sg_model->get_f_map())));
171  Teuchos::rcp(new Epetra_Vector(*(sg_model->get_x_map())));
172  Teuchos::RCP<Epetra_Operator> sg_J = sg_model->create_W();
173  Teuchos::RCP<Epetra_Operator> sg_M = sg_model->create_WPrec()->PrecOp;
174 
175 
176  // Setup InArgs and OutArgs
177  EpetraExt::ModelEvaluator::InArgs sg_inArgs = sg_model->createInArgs();
178  EpetraExt::ModelEvaluator::OutArgs sg_outArgs = sg_model->createOutArgs();
179  sg_inArgs.set_p(1, sg_p);
180  sg_inArgs.set_x(sg_x);
181  sg_outArgs.set_f(sg_f);
182  sg_outArgs.set_W(sg_J);
183  sg_outArgs.set_WPrec(sg_M);
184 
185  // Evaluate model
186  sg_model->evalModel(sg_inArgs, sg_outArgs);
187 
188  // Print initial residual norm
189  double norm_f;
190  sg_f->Norm2(&norm_f);
191  if (MyPID == 0)
192  std::cout << "\nInitial residual norm = " << norm_f << std::endl;
193 
194  // Setup AztecOO solver
195  AztecOO aztec;
196  if (symmetric)
197  aztec.SetAztecOption(AZ_solver, AZ_cg);
198  else
199  aztec.SetAztecOption(AZ_solver, AZ_gmres);
200  aztec.SetAztecOption(AZ_precond, AZ_none);
201  aztec.SetAztecOption(AZ_kspace, 20);
202  aztec.SetAztecOption(AZ_conv, AZ_r0);
203  aztec.SetAztecOption(AZ_output, 1);
204  aztec.SetUserOperator(sg_J.get());
205  aztec.SetPrecOperator(sg_M.get());
206  aztec.SetLHS(sg_dx.get());
207  aztec.SetRHS(sg_f.get());
208 
209  // Solve linear system
210  aztec.Iterate(1000, 1e-12);
211 
212  // Update x
213  sg_x->Update(-1.0, *sg_dx, 1.0);
214 
215  // Save solution to file
216  EpetraExt::VectorToMatrixMarketFile("stochastic_solution.mm", *sg_x);
217 
218  // Save RHS to file
219  EpetraExt::VectorToMatrixMarketFile("stochastic_RHS.mm", *sg_f);
220 
221  // Save operator to file (set "Operator Method" to "Fully Assembled" above)
223  Teuchos::rcp_dynamic_cast<Epetra_CrsMatrix>(sg_J);
224  if (sg_J_crs != Teuchos::null)
225  EpetraExt::RowMatrixToMatrixMarketFile("stochastic_operator.mm",
226  *sg_J_crs);
227 
228  // Save mean and variance to file
230  sg_model->create_x_sg(View, sg_x.get());
231  Epetra_Vector mean(*(model->get_x_map()));
232  Epetra_Vector std_dev(*(model->get_x_map()));
233  sg_x_poly->computeMean(mean);
234  sg_x_poly->computeStandardDeviation(std_dev);
235  EpetraExt::VectorToMatrixMarketFile("mean_gal.mm", mean);
236  EpetraExt::VectorToMatrixMarketFile("std_dev_gal.mm", std_dev);
237 
238  // Compute new residual & response function
239  EpetraExt::ModelEvaluator::OutArgs sg_outArgs2 = sg_model->createOutArgs();
241  Teuchos::rcp(new Epetra_Vector(*(sg_model->get_g_map(0))));
242  sg_f->PutScalar(0.0);
243  sg_outArgs2.set_f(sg_f);
244  sg_outArgs2.set_g(0, sg_g);
245  sg_model->evalModel(sg_inArgs, sg_outArgs2);
246 
247  // Print initial residual norm
248  sg_f->Norm2(&norm_f);
249  if (MyPID == 0)
250  std::cout << "\nFinal residual norm = " << norm_f << std::endl;
251 
252  // Print mean and standard deviation of responses
254  sg_model->create_g_sg(0, View, sg_g.get());
255  Epetra_Vector g_mean(*(model->get_g_map(0)));
256  Epetra_Vector g_std_dev(*(model->get_g_map(0)));
257  sg_g_poly->computeMean(g_mean);
258  sg_g_poly->computeStandardDeviation(g_std_dev);
259  std::cout.precision(16);
260  // std::cout << "\nResponse Expansion = " << std::endl;
261  // std::cout.precision(12);
262  // sg_g_poly->print(std::cout);
263  std::cout << std::endl;
264  std::cout << "Response Mean = " << std::endl << g_mean << std::endl;
265  std::cout << "Response Std. Dev. = " << std::endl << g_std_dev << std::endl;
266 
267  // Determine if example passed
268  bool passed = false;
269  if (norm_f < 1.0e-10 &&
270  std::abs(g_mean[0]-g_mean_exp) < g_tol &&
271  std::abs(g_std_dev[0]-g_std_dev_exp) < g_tol)
272  passed = true;
273  if (MyPID == 0) {
274  if (passed)
275  std::cout << "Example Passed!" << std::endl;
276  else
277  std::cout << "Example Failed!" << std::endl;
278  }
279 
280  }
281 
284 
285  }
286 
287  catch (std::exception& e) {
288  std::cout << e.what() << std::endl;
289  }
290  catch (std::string& s) {
291  std::cout << s << std::endl;
292  }
293  catch (char *s) {
294  std::cout << s << std::endl;
295  }
296  catch (...) {
297  std::cout << "Caught unknown exception!" << std::endl;
298  }
299 
300 #ifdef HAVE_MPI
301  MPI_Finalize() ;
302 #endif
303 
304 }
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_Map > get_x_map() const
Return solution vector map.
#define TEUCHOS_FUNC_TIME_MONITOR(FUNCNAME)
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.
Teuchos::RCP< const Epetra_Map > get_f_map() const
Return residual vector map.
void evalModel(const InArgs &inArgs, const OutArgs &outArgs) const
Evaluate model on InArgs.
void computeMean(Epetra_Vector &v) const
Compute mean.
Teuchos::RCP< EpetraExt::BlockVector > getBlockVector()
Get block vector.
RCP< ParameterList > sublist(const RCP< ParameterList > &paramList, const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
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
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)
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)
KOKKOS_INLINE_FUNCTION PCE< Storage > abs(const PCE< Storage > &a)
Teuchos::RCP< const Epetra_Map > get_g_map(int j) const
Return response function map.
Legendre polynomial basis.
InArgs createInArgs() const
Create InArgs.
int main(int argc, char **argv)
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.
coeff_type & term(ordinal_type dimension, ordinal_type order)
Get term for dimension dimension and order order.
int n
Teuchos::RCP< EpetraExt::ModelEvaluator::Preconditioner > create_WPrec() const
Create preconditioner operator.
static void zeroOutTimers()