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.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 // Class implementing our problem
12 
13 // Epetra communicator
14 #ifdef HAVE_MPI
15 #include "Epetra_MpiComm.h"
16 #else
17 #include "Epetra_SerialComm.h"
18 #endif
19 
20 // solver
21 #include "Ifpack2_Factory.hpp"
22 #include "BelosLinearProblem.hpp"
23 #include "BelosTpetraAdapter.hpp"
24 #include "BelosPseudoBlockCGSolMgr.hpp"
25 #include "BelosPseudoBlockGmresSolMgr.hpp"
26 #include "Tpetra_Core.hpp"
27 #include "MatrixMarket_Tpetra.hpp"
28 
29 // Stokhos Stochastic Galerkin
30 #include "Stokhos_Epetra.hpp"
31 
32 // Timing utilities
33 #include "Teuchos_TimeMonitor.hpp"
34 
35 int main(int argc, char *argv[]) {
36  typedef double Scalar;
37  typedef double MeshScalar;
38  typedef double BasisScalar;
39  typedef int LocalOrdinal;
40  typedef int GlobalOrdinal;
42 
43  using Teuchos::RCP;
44  using Teuchos::rcp;
46 
47  LocalOrdinal n = 32; // spatial discretization (per dimension)
48  LocalOrdinal num_KL = 2; // number of KL terms
49  LocalOrdinal p = 3; // polynomial order
50  BasisScalar mu = 0.2; // mean of exponential random field
51  BasisScalar s = 0.1; // std. dev. of exponential r.f.
52  bool nonlinear_expansion = false; // nonlinear expansion of diffusion coeff
53  // (e.g., log-normal)
54  bool symmetric = false; // use symmetric formulation
55 
56 // Initialize MPI
57 #ifdef HAVE_MPI
58  MPI_Init(&argc,&argv);
59 #endif
60 
61  LocalOrdinal MyPID;
62 
63  try {
64 
65  {
66  TEUCHOS_FUNC_TIME_MONITOR("Total PCE Calculation Time");
67 
68  // Create a communicator for Epetra objects
69  RCP<const Epetra_Comm> globalComm;
70 #ifdef HAVE_MPI
71  globalComm = rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
72 #else
73  globalComm = rcp(new Epetra_SerialComm);
74 #endif
75  MyPID = globalComm->MyPID();
76 
77  // Create Stochastic Galerkin basis and expansion
79  for (LocalOrdinal i=0; i<num_KL; i++)
81  RCP<const Stokhos::CompletePolynomialBasis<LocalOrdinal,BasisScalar> > basis =
83  1e-12));
84  LocalOrdinal sz = basis->size();
85  RCP<Stokhos::Sparse3Tensor<LocalOrdinal,BasisScalar> > Cijk;
86  if (nonlinear_expansion)
87  Cijk = basis->computeTripleProductTensor();
88  else
89  Cijk = basis->computeLinearTripleProductTensor();
90  RCP<Stokhos::OrthogPolyExpansion<LocalOrdinal,BasisScalar> > expansion =
92  Cijk));
93  if (MyPID == 0)
94  std::cout << "Stochastic Galerkin expansion size = " << sz << std::endl;
95 
96  // Create stochastic parallel distribution
97  LocalOrdinal num_spatial_procs = -1;
98  if (argc > 1)
99  num_spatial_procs = std::atoi(argv[1]);
100  ParameterList parallelParams;
101  parallelParams.set("Number of Spatial Processors", num_spatial_procs);
102  // parallelParams.set("Rebalance Stochastic Graph", true);
103  // Teuchos::ParameterList& isorropia_params =
104  // parallelParams.sublist("Isorropia");
105  // isorropia_params.set("Balance objective", "nonzeros");
106  RCP<Stokhos::ParallelData> sg_parallel_data =
107  rcp(new Stokhos::ParallelData(basis, Cijk, globalComm,
108  parallelParams));
109  RCP<const EpetraExt::MultiComm> sg_comm =
110  sg_parallel_data->getMultiComm();
111  RCP<const Epetra_Comm> app_comm =
112  sg_parallel_data->getSpatialComm();
113 
114  // Create Teuchos::Comm from Epetra_Comm
115  RCP< Teuchos::Comm<int> > teuchos_app_comm;
116 #ifdef HAVE_MPI
117  RCP<const Epetra_MpiComm> app_mpi_comm =
118  Teuchos::rcp_dynamic_cast<const Epetra_MpiComm>(app_comm);
119  RCP<const Teuchos::OpaqueWrapper<MPI_Comm> > raw_mpi_comm =
120  Teuchos::opaqueWrapper(app_mpi_comm->Comm());
121  teuchos_app_comm = rcp(new Teuchos::MpiComm<int>(raw_mpi_comm));
122 #else
123  teuchos_app_comm = rcp(new Teuchos::SerialComm<int>());
124 #endif
125 
126  // Create application
128  RCP<problem_type> model =
129  rcp(new problem_type(teuchos_app_comm, n, num_KL, s, mu,
130  nonlinear_expansion, symmetric));
131 
132 
133  // Create vectors and operators
134  typedef problem_type::Tpetra_Vector Tpetra_Vector;
135  typedef problem_type::Tpetra_CrsMatrix Tpetra_CrsMatrix;
136  typedef Tpetra::MatrixMarket::Writer<Tpetra_CrsMatrix> Writer;
137  RCP<const Tpetra_Vector> p = model->get_p_init(0);
138  RCP<Tpetra_Vector> x = Tpetra::createVector<Scalar>(model->get_x_map());
139  x->putScalar(0.0);
140  RCP<Tpetra_Vector> f = Tpetra::createVector<Scalar>(model->get_f_map());
141  RCP<Tpetra_Vector> dx = Tpetra::createVector<Scalar>(model->get_x_map());
142  RCP<Tpetra_CrsMatrix> J = model->create_W();
143 
144  // Create preconditioner
145  Teuchos::ParameterList precParams;
146  std::string prec_name = "RILUK";
147  precParams.set("fact: iluk level-of-fill", 1);
148  precParams.set("fact: iluk level-of-overlap", 0);
149  typedef Ifpack2::Preconditioner<Scalar,LocalOrdinal,GlobalOrdinal,Node> Tprec;
151  Ifpack2::Factory factory;
152  M = factory.create<Tpetra_CrsMatrix>(prec_name, J);
153  M->setParameters(precParams);
154 
155  // Evaluate model
156  model->computeResidual(*x, *p, *f);
157  model->computeJacobian(*x, *p, *J);
158  M->initialize();
159  M->compute();
160 
161  // Print initial residual norm
162  Scalar norm_f;
163  f->norm2(Teuchos::arrayView(&norm_f,1));
164  if (MyPID == 0)
165  std::cout << "\nInitial residual norm = " << norm_f << std::endl;
166 
167  // Setup Belos solver
168  RCP<ParameterList> belosParams = rcp(new ParameterList);
169  belosParams->set("Num Blocks", 20);
170  belosParams->set("Convergence Tolerance", 1e-12);
171  belosParams->set("Maximum Iterations", 1000);
172  belosParams->set("Verbosity", 33);
173  belosParams->set("Output Style", 1);
174  belosParams->set("Output Frequency", 1);
175  typedef Tpetra::Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node> OP;
176  typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> MV;
177  typedef Belos::OperatorTraits<Scalar,MV,OP> BOPT;
178  typedef Belos::MultiVecTraits<Scalar,MV> BMVT;
179  typedef Belos::LinearProblem<Scalar,MV,OP> BLinProb;
180  RCP< BLinProb > problem = rcp(new BLinProb(J, dx, f));
181  problem->setRightPrec(M);
182  problem->setProblem();
183  RCP<Belos::SolverManager<Scalar,MV,OP> > solver;
184  if (symmetric)
185  solver = rcp(new Belos::PseudoBlockCGSolMgr<Scalar,MV,OP>(problem,
186  belosParams));
187  else
188  solver = rcp(new Belos::PseudoBlockGmresSolMgr<Scalar,MV,OP>(problem,
189  belosParams));
190 
191  // Solve linear system
192  Belos::ReturnType ret = solver->solve();
193 
194  // Update x
195  x->update(-1.0, *dx, 1.0);
196 
197  // Compute new residual & response function
198  RCP<Tpetra_Vector> g = Tpetra::createVector<Scalar>(model->get_g_map(0));
199  f->putScalar(0.0);
200  model->computeResidual(*x, *p, *f);
201  model->computeResponse(*x, *p, *g);
202 
203  // Print final residual norm
204  f->norm2(Teuchos::arrayView(&norm_f,1));
205  if (MyPID == 0)
206  std::cout << "\nFinal residual norm = " << norm_f << std::endl;
207 
208  // Print response
209  std::cout << "\nResponse = " << std::endl;
210  Writer::writeDense(std::cout, g);
211 
212  }
213 
216 
217  }
218 
219  catch (std::exception& e) {
220  std::cout << e.what() << std::endl;
221  }
222  catch (string& s) {
223  std::cout << s << std::endl;
224  }
225  catch (char *s) {
226  std::cout << s << std::endl;
227  }
228  catch (...) {
229  std::cout << "Caught unknown exception!" <<std:: endl;
230  }
231 
232 #ifdef HAVE_MPI
233  MPI_Finalize() ;
234 #endif
235 
236 }
#define TEUCHOS_FUNC_TIME_MONITOR(FUNCNAME)
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.
Kokkos::Serial node_type
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)
expr expr expr dx(i, j)
Multivariate orthogonal polynomial basis generated from a total-order complete-polynomial tensor prod...
Legendre polynomial basis.
int main(int argc, char **argv)
ScalarType f(const Teuchos::Array< ScalarType > &x, double a, double b)
Tpetra::KokkosClassic::DefaultNode::DefaultNodeType Node
int n
ScalarType g(const Teuchos::Array< ScalarType > &x, const ScalarType &y)
static void zeroOutTimers()
A linear 2-D diffusion problem.