Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Stokhos_MatrixFreeOperatorUnitTest.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 // Test the exponential of a linear Hermite expansion using an analytic
11 // closed form solution
12 
17 
18 #include "Stokhos_Epetra.hpp"
19 #include "EpetraExt_BlockUtility.h"
21 
22 #ifdef HAVE_MPI
23 #include "Epetra_MpiComm.h"
24 #else
25 #include "Epetra_SerialComm.h"
26 #endif
27 
28 namespace MatrixFreeOperatorUnitTest {
29 
30  struct UnitTestSetup {
35  double tol;
36 
37  // Can't be a constructor because MPI will not be initialized
38  void setup() {
39 
40  Epetra_Object::SetTracebackMode(2);
41 
42  // Test tolerance
43  tol = 1.0e-12;
44 
45  // Basis of dimension 3, order 5
46  const int d = 2;
47  const int p = 3;
49  for (int i=0; i<d; i++) {
51  }
54 
55  // Triple product tensor
57  basis->computeTripleProductTensor();
58 
59  // Create a communicator for Epetra objects
61 #ifdef HAVE_MPI
62  globalComm = Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
63 #else
64  globalComm = Teuchos::rcp(new Epetra_SerialComm);
65 #endif
66 
67  // Create stochastic parallel distribution
68  int num_spatial_procs = -1;
69  int num_procs = globalComm->NumProc();
70  if (num_procs > 1)
71  num_spatial_procs = num_procs / 2;
72  Teuchos::ParameterList parallelParams;
73  parallelParams.set("Number of Spatial Processors", num_spatial_procs);
74  Teuchos::RCP<Stokhos::ParallelData> sg_parallel_data =
75  Teuchos::rcp(new Stokhos::ParallelData(basis, Cijk, globalComm,
76  parallelParams));
78  sg_parallel_data->getMultiComm();
80  sg_parallel_data->getSpatialComm();
82  sg_parallel_data->getEpetraCijk();
83 
84  // Deterministic domain map
85  const int num_x = 5;
87  Teuchos::rcp(new Epetra_Map(num_x, 0, *app_comm));
88 
89  // Deterministic column map
90  Teuchos::RCP<Epetra_Map> x_overlap_map =
91  Teuchos::rcp(new Epetra_LocalMap(num_x, 0, *app_comm));
92 
93  // Deterministic range map
94  const int num_f = 3;
96  Teuchos::rcp(new Epetra_Map(num_f, 0, *app_comm));
97 
98  // Product domain & range maps
100  epetraCijk->getStochasticRowMap();
101  sg_x_map = Teuchos::rcp(EpetraExt::BlockUtility::GenerateBlockMap(
102  *x_map, *stoch_row_map, *sg_comm));
103  sg_f_map = Teuchos::rcp(EpetraExt::BlockUtility::GenerateBlockMap(
104  *f_map, *stoch_row_map, *sg_comm));
105 
106  // Deterministic matrix graph
107  const int num_indices = num_x;
109  Teuchos::rcp(new Epetra_CrsGraph(Copy, *f_map, num_indices));
110  int indices[num_indices];
111  for (int j=0; j<num_indices; j++)
112  indices[j] = x_overlap_map->GID(j);
113  for (int i=0; i<f_map->NumMyElements(); i++)
114  graph->InsertGlobalIndices(f_map->GID(i), num_indices, indices);
115  graph->FillComplete(*x_map, *f_map);
116 
117  // Create matrix expansion
118  Teuchos::RCP<Epetra_BlockMap> sg_overlap_map =
120  basis->size(), 0,
121  *(sg_parallel_data->getStochasticComm())));
124  basis, sg_overlap_map, x_map, f_map, sg_f_map, sg_comm));
125  for (int block=0; block<basis->size(); block++) {
127  Teuchos::rcp(new Epetra_CrsMatrix(Copy, *graph));
128  TEUCHOS_TEST_FOR_EXCEPTION(!mat->IndicesAreLocal(), std::logic_error,
129  "Indices are not local!");
130  double values[num_indices];
131  for (int i=0; i<f_map->NumMyElements(); i++) {
132  for (int j=0; j<num_indices; j++) {
133  indices[j] = x_overlap_map->GID(j);
134  values[j] = 0.1*(i+1)*(j+1)*(block+1);
135  }
136  mat->ReplaceMyValues(i, num_indices, values, indices);
137  }
138  mat->FillComplete(*x_map, *f_map);
139  mat_sg->setCoeffPtr(block, mat);
140  }
141 
142  // Matrix-free operator
145  mat_free_op =
147  sg_comm, basis, epetraCijk, x_map, f_map,
148  sg_x_map, sg_f_map, op_params));
149  mat_free_op->setupOperator(mat_sg);
150 
151  // Fully assembled operator
152  assembled_op =
154  sg_comm, basis, epetraCijk, graph, sg_x_map, sg_f_map,
155  op_params));
156  assembled_op->setupOperator(mat_sg);
157  }
158 
159  };
160 
162 
163  TEUCHOS_UNIT_TEST( Stokhos_MatrixFreeOperator, ApplyUnitTest ) {
164  // Test Apply()
165  Epetra_Vector input(*setup.sg_x_map), result1(*setup.sg_f_map),
166  result2(*setup.sg_f_map), diff(*setup.sg_f_map);
167  input.Random();
168  setup.mat_free_op->Apply(input, result1);
169  setup.assembled_op->Apply(input, result2);
170  diff.Update(1.0, result1, -1.0, result2, 0.0);
171  double nrm;
172  diff.NormInf(&nrm);
173  success = std::fabs(nrm) < setup.tol;
174  out << "Apply infinity norm of difference: " << nrm << std::endl;
175  out << "Matrix-free result = " << std::endl << result1 << std::endl
176  << "Assebled result = " << std::endl << result2 << std::endl;
177  }
178 
179  TEUCHOS_UNIT_TEST( Stokhos_MatrixFreeOperator, ApplyTransposeUnitTest ) {
180  // Test tranposed Apply()
181  Epetra_Vector input(*setup.sg_f_map), result1(*setup.sg_x_map),
182  result2(*setup.sg_x_map), diff(*setup.sg_x_map);
183  input.Random();
186  setup.mat_free_op->Apply(input, result1);
187  setup.assembled_op->Apply(input, result2);
188  diff.Update(1.0, result1, -1.0, result2, 0.0);
189  double nrm;
190  diff.NormInf(&nrm);
191  success = std::fabs(nrm) < setup.tol;
192  out << "Apply-transpose infinity norm of difference: " << nrm << std::endl;
193  out << "Matrix-free result = " << std::endl << result1 << std::endl
194  << "Assebled result = " << std::endl << result2 << std::endl;
195  }
196 
197 }
198 
199 int main( int argc, char* argv[] ) {
200  Teuchos::GlobalMPISession mpiSession(&argc, &argv);
203 }
KOKKOS_INLINE_FUNCTION PCE< Storage > fabs(const PCE< Storage > &a)
An Epetra operator representing the block stochastic Galerkin operator.
A container class storing an orthogonal polynomial whose coefficients are vectors, operators, or in general any type that would have an expensive copy constructor.
virtual int SetUseTranspose(bool UseTranspose)=0
Teuchos::RCP< const EpetraExt::MultiComm > getMultiComm() const
Get global comm.
virtual void setupOperator(const Teuchos::RCP< Stokhos::EpetraOperatorOrthogPoly > &poly)
Setup operator.
TEUCHOS_UNIT_TEST(Stokhos_MatrixFreeOperator, ApplyUnitTest)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
bool IndicesAreLocal() const
virtual int SetUseTranspose(bool UseTranspose)
Set to true if the transpose of the operator is requested.
int InsertGlobalIndices(int_type GlobalRow, int NumIndices, int_type *Indices)
Teuchos::RCP< const Epetra_Comm > getStochasticComm() const
Get stochastic comm.
int FillComplete(bool OptimizeDataStorage=true)
Teuchos::RCP< const Stokhos::EpetraSparse3Tensor > getEpetraCijk() const
Get Epetra Cijk.
int NumMyElements() const
Teuchos::RCP< Stokhos::MatrixFreeOperator > mat_free_op
static int runUnitTestsFromMain(int argc, char *argv[])
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::RCP< const Epetra_BlockMap > getStochasticRowMap() const
Get stochastic row map.
int GID(int LID) const
virtual int Apply(const Epetra_MultiVector &Input, Epetra_MultiVector &Result) const
Wrap Apply() to add a timer.
virtual int Apply(const Epetra_MultiVector &Input, Epetra_MultiVector &Result) const
Returns the result of a Epetra_Operator applied to a Epetra_MultiVector Input in Result as described ...
Legendre polynomial basis.
int main(int argc, char **argv)
virtual int NumProc() const =0
Teuchos::RCP< Stokhos::FullyAssembledOperator > assembled_op
Teuchos::RCP< const Epetra_Comm > getSpatialComm() const
Get spatial comm.
virtual void setupOperator(const Teuchos::RCP< Stokhos::EpetraOperatorOrthogPoly > &poly)
Setup operator.
int ReplaceMyValues(int MyRow, int NumEntries, const double *Values, const int *Indices)
An Epetra operator representing the block stochastic Galerkin operator generated by fully assembling ...