Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
uq_handbook/SimpleME.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 "SimpleME.hpp"
11 #include "Teuchos_Assert.hpp"
12 #include "Stokhos_Epetra.hpp"
13 #include "Stokhos_Sacado.hpp"
14 #include "Sacado.hpp"
15 
16 namespace {
17 
18  template <typename ScalarA, typename ScalarX>
19  void func(const ScalarA& a, const ScalarX x[2], ScalarX y[2]) {
20  y[0] = a*a - x[0];
21  y[1] = x[1]*x[1] - x[0];
22  }
23 
24 }
25 
27 {
28  // Solution vector map
29  x_map = Teuchos::rcp(new Epetra_Map(2, 0, *comm));
30 
31  // Overlapped solution vector map
32  x_overlapped_map = Teuchos::rcp(new Epetra_LocalMap(2, 0, *comm));
33 
34  // Importer
36 
37  // Initial guess, initialized to 1.5
39  x_init->PutScalar(1.5);
40 
41  // Overlapped solution vector
43 
44  // Parameter vector map
45  p_map = Teuchos::rcp(new Epetra_LocalMap(1, 0, *comm));
46 
47  // Initial parameters
49  (*p_init)[0] = 2.0;
50 
51  // Parameter names
53  (*p_names)[0] = "alpha";
54 
55  // Jacobian graph (dense 2x2 matrix)
56  graph = Teuchos::rcp(new Epetra_CrsGraph(Copy, *x_map, 2));
57  int indices[2];
58  indices[0] = 0; indices[1] = 1;
59  if (x_map->MyGID(0))
60  graph->InsertGlobalIndices(0, 2, indices);
61  if (x_map->MyGID(1))
62  graph->InsertGlobalIndices(1, 2, indices);
65 }
66 
67 // Overridden from EpetraExt::ModelEvaluator
68 
70 SimpleME::get_x_map() const
71 {
72  return x_map;
73 }
74 
76 SimpleME::get_f_map() const
77 {
78  return x_map;
79 }
80 
82 SimpleME::get_p_map(int l) const
83 {
85  std::logic_error,
86  std::endl <<
87  "Error! SimpleME::get_p_map(): " <<
88  "Invalid parameter index l = " << l << std::endl);
89 
90  return p_map;
91 }
92 
94 SimpleME::get_p_names(int l) const
95 {
97  std::logic_error,
98  std::endl <<
99  "Error! SimpleME::get_p_names(): " <<
100  "Invalid parameter index l = " << l << std::endl);
101 
102  return p_names;
103 }
104 
106 SimpleME::get_x_init() const
107 {
108  return x_init;
109 }
110 
112 SimpleME::get_p_init(int l) const
113 {
115  std::logic_error,
116  std::endl <<
117  "Error! SimpleME::get_p_init(): " <<
118  "Invalid parameter index l = " << l << std::endl);
119 
120  return p_init;
121 }
122 
124 SimpleME::create_W() const
125 {
127  Teuchos::rcp(new Epetra_CrsMatrix(Copy, *graph));
128  A->FillComplete();
129  A->OptimizeStorage();
130  return A;
131 }
132 
133 EpetraExt::ModelEvaluator::InArgs
135 {
136  InArgsSetup inArgs;
137  inArgs.setModelEvalDescription("Simple Model Evaluator");
138 
139  // Deterministic InArgs
140  inArgs.setSupports(IN_ARG_x,true);
141  inArgs.set_Np(1); // 1 parameter vector
142 
143  // Stochastic InArgs
144  inArgs.setSupports(IN_ARG_x_sg,true);
145  inArgs.setSupports(IN_ARG_p_sg, 0, true); // 1 SG parameter vector
146  inArgs.setSupports(IN_ARG_sg_basis,true);
147  inArgs.setSupports(IN_ARG_sg_quadrature,true);
148  inArgs.setSupports(IN_ARG_sg_expansion,true);
149 
150  return inArgs;
151 }
152 
153 EpetraExt::ModelEvaluator::OutArgs
155 {
156  OutArgsSetup outArgs;
157  outArgs.setModelEvalDescription("Simple Model Evaluator");
158 
159  // Deterministic OutArgs
160  outArgs.set_Np_Ng(1, 0);
161  outArgs.setSupports(OUT_ARG_f,true);
162  outArgs.setSupports(OUT_ARG_W,true);
163 
164  // Stochastic OutArgs
165  outArgs.setSupports(OUT_ARG_f_sg,true);
166  outArgs.setSupports(OUT_ARG_W_sg,true);
167 
168  return outArgs;
169 }
170 
171 void
172 SimpleME::evalModel(const InArgs& inArgs, const OutArgs& outArgs) const
173 {
174  //
175  // Determinisic calculation
176  //
177 
178  // Solution vector
179  Teuchos::RCP<const Epetra_Vector> x = inArgs.get_x();
180  if (x != Teuchos::null) {
181  x_overlapped->Import(*x, *importer, Insert);
182  double x0 = (*x_overlapped)[0];
183  double x1 = (*x_overlapped)[1];
184 
185  // Parameters
186  Teuchos::RCP<const Epetra_Vector> p = inArgs.get_p(0);
187  if (p == Teuchos::null)
188  p = p_init;
189  double a = (*p)[0];
190 
191  // Residual
192  // f = | a*a - x0 |
193  // | x1*x1 - x0 |
194  // where a = p[0].
195  Teuchos::RCP<Epetra_Vector> f = outArgs.get_f();
196  if (f != Teuchos::null) {
197  double x[2] = { x0, x1 };
198  double y[2];
199  func(a, x, y);
200 
201  if (x_map->MyGID(0)) {
202  int row = 0;
203  f->ReplaceGlobalValues(1, &y[0], &row);
204  }
205  if (x_map->MyGID(1)) {
206  int row = 1;
207  f->ReplaceGlobalValues(1, &y[1], &row);
208  }
209  }
210 
211  // Jacobian
212  // J = | -1 0 |
213  // | -1 2*x1 |
214  Teuchos::RCP<Epetra_Operator> W = outArgs.get_W();
215  if (W != Teuchos::null) {
216  typedef Sacado::Fad::SFad<double,2> fad_type;
217  fad_type x[2], y[2];
218  x[0] = fad_type(2, 0, x0);
219  x[1] = fad_type(2, 1, x1);
220  func(a, x, y);
221 
223  Teuchos::rcp_dynamic_cast<Epetra_CrsMatrix>(W, true);
224  int indices[2] = { 0, 1 };
225  if (x_map->MyGID(0)) {
226  int row = 0;
227  jac->ReplaceGlobalValues(row, 2, y[0].dx(), indices);
228  }
229  if (x_map->MyGID(1)) {
230  int row = 1;
231  jac->ReplaceGlobalValues(row, 2, y[1].dx(), indices);
232  }
233  }
234  }
235 
236  //
237  // Stochastic Galerkin calculation
238  //
239 
240  // Stochastic solution vector
241  InArgs::sg_const_vector_t x_sg = inArgs.get_x_sg();
242  if (x_sg != Teuchos::null) {
243 
244  // Get stochastic expansion data
246  inArgs.get_sg_basis();
248  inArgs.get_sg_expansion();
251 
252  pce_type x0(expn), x1(expn);
253  for (int i=0; i<basis->size(); i++) {
254  x_overlapped->Import((*x_sg)[i], *importer, Insert);
255  x0.fastAccessCoeff(i) = (*x_overlapped)[0];
256  x1.fastAccessCoeff(i) = (*x_overlapped)[1];
257  }
258 
259  // Stochastic parameters
260  InArgs::sg_const_vector_t p_sg = inArgs.get_p_sg(0);
261  pce_type a(expn);
262  if (p_sg != Teuchos::null) {
263  for (int i=0; i<basis->size(); i++) {
264  a.fastAccessCoeff(i) = (*p_sg)[i][0];
265  }
266  }
267 
268  // Stochastic residual
269  // f[i] = | <a*a - x0, psi_i>/<psi_i^2> |
270  // | <x1*x1 - x0, psi_i>/<psi_i^2> |
271  OutArgs::sg_vector_t f_sg = outArgs.get_f_sg();
272  if (f_sg != Teuchos::null) {
273  pce_type x[2] = { x0, x1 };
274  pce_type y[2];
275  func(a, x, y);
276 
277  if (x_map->MyGID(0)) {
278  int row = 0;
279  for (int i=0; i<basis->size(); i++) {
280  double c = y[0].coeff(i);
281  (*f_sg)[i].ReplaceGlobalValues(1, &c, &row);
282  }
283  }
284  if (x_map->MyGID(1)) {
285  int row = 1;
286  for (int i=0; i<basis->size(); i++) {
287  double c = y[1].coeff(i);
288  (*f_sg)[i].ReplaceGlobalValues(1, &c, &row);
289  }
290  }
291  }
292 
293  // Stochastic Jacobian
294  // J[0] = | -1 0 |, J[i] = | 0 0 |, i > 0
295  // | -1 2*x0[0] | | 0 2*x0[i] |
296  OutArgs::sg_operator_t W_sg = outArgs.get_W_sg();
297  if (W_sg != Teuchos::null) {
298  typedef Sacado::Fad::SFad<pce_type,2> fad_type;
299  fad_type x[2], y[2];
300  x[0] = fad_type(2, 0, x0);
301  x[1] = fad_type(2, 1, x1);
302  func(a, x, y);
303 
304  for (int i=0; i<basis->size(); i++) {
306  Teuchos::rcp_dynamic_cast<Epetra_CrsMatrix>(W_sg->getCoeffPtr(i),
307  true);
308  int indices[2] = { 0, 1 };
309  if (x_map->MyGID(0)) {
310  int row = 0;
311  double values[2] = { y[0].dx(0).coeff(i), y[0].dx(1).coeff(i) };
312  jac->ReplaceGlobalValues(row, 2, values, indices);
313  }
314  if (x_map->MyGID(1)) {
315  int row = 1;
316  double values[2] = { y[1].dx(0).coeff(i), y[1].dx(1).coeff(i) };
317  jac->ReplaceGlobalValues(row, 2, values, indices);
318  }
319  }
320  }
321  }
322 }
Teuchos::RCP< const Epetra_Vector > get_x_init() const
Return initial solution.
Stokhos::StandardStorage< int, double > storage_type
Sacado::ETPCE::OrthogPoly< double, Stokhos::StandardStorage< int, double > > pce_type
Teuchos::RCP< Epetra_Vector > x_init
Initial guess.
Teuchos::RCP< const Epetra_Map > get_f_map() const
Return residual vector map.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
SimpleME(const Teuchos::RCP< const Epetra_Comm > &comm)
Constructor.
Teuchos::RCP< const Epetra_Map > get_x_map() const
Return solution vector map.
Teuchos::RCP< Epetra_Vector > p_init
Initial parameters.
InArgs createInArgs() const
Create InArgs.
Teuchos::RCP< Epetra_Vector > x_overlapped
Overlapped solution vector.
Teuchos::RCP< Epetra_Map > x_map
Solution vector map.
int InsertGlobalIndices(int_type GlobalRow, int NumIndices, int_type *Indices)
int FillComplete(bool OptimizeDataStorage=true)
int ReplaceGlobalValues(int NumEntries, const double *Values, const int *Indices)
void evalModel(const InArgs &inArgs, const OutArgs &outArgs) const
Evaluate model on InArgs.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::RCP< Epetra_Map > p_map
Parameter vector map.
bool MyGID(int GID_in) const
expr expr expr dx(i, j)
Teuchos::RCP< Teuchos::Array< std::string > > p_names
Parameter names.
Teuchos::RCP< Epetra_CrsGraph > graph
Jacobian graph.
ScalarType f(const Teuchos::Array< ScalarType > &x, double a, double b)
Teuchos::RCP< const Epetra_Map > get_p_map(int l) const
Return parameter vector map.
Teuchos::RCP< const Teuchos::Array< std::string > > get_p_names(int l) const
Return array of parameter names.
Teuchos::RCP< Epetra_Import > importer
Importer to overlapped distribution.
virtual int ReplaceGlobalValues(int GlobalRow, int NumEntries, const double *Values, const int *Indices)
OutArgs createOutArgs() const
Create OutArgs.
Sacado::Fad::DFad< double > fad_type
Teuchos::RCP< Epetra_Operator > create_W() const
Create W = alpha*M + beta*J matrix.
Teuchos::RCP< Epetra_Map > x_overlapped_map
Overlapped solution vector map.
Teuchos::RCP< const Epetra_Vector > get_p_init(int l) const
Return initial parameters.