Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Stokhos_AdaptivityManager.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 
13 
14 #include "EpetraExt_BlockVector.h"
15 #include "EpetraExt_RowMatrixOut.h"
16 
17 #ifdef HAVE_STOKHOS_BOOST
18 #include <boost/functional/hash.hpp>
19 #endif
20 
21 #ifdef HAVE_STOKHOS_BOOST // we have boost, use the hash Stokhos, use the hash!
22 std::size_t Stokhos::AdaptivityManager::Sparse3TensorHash::IJKHash::
23 operator()(const Stokhos::AdaptivityManager::Sparse3TensorHash::IJK & ijk) const
24 {
25  std::size_t seed=0;
26  boost::hash_combine(seed,ijk.i_);
27  boost::hash_combine(seed,ijk.j_);
28  boost::hash_combine(seed,ijk.k_);
29  return seed;
30 }
31 
33 {
37 
38  for(k_iterator k_it = Cijk.k_begin();k_it!=Cijk.k_end();k_it++) {
39  int k = *k_it;
40  for(kj_iterator j_it = Cijk.j_begin(k_it);j_it!=Cijk.j_end(k_it);j_it++) {
41  int j = *j_it;
42  for(kji_iterator i_it = Cijk.i_begin(j_it);i_it!=Cijk.i_end(j_it);i_it++) {
43  int i = *i_it;
44  hashMap_[IJK(i,j,k)] = i_it.value();
45  }
46  }
47  }
48 }
49 
50 double Stokhos::AdaptivityManager::Sparse3TensorHash::getValue(int i,int j,int k) const
51 {
52  boost::unordered_map<IJK,double>::const_iterator itr;
53  itr = hashMap_.find(IJK(i,j,k));
54 
55  if(itr==hashMap_.end()) return 0.0;
56 
57  return itr->second;
58 }
59 #else // no BOOST, just default to the slow thing
61  : Cijk_(Cijk)
62 { }
63 
65 {
66  return Cijk_.getValue(i,j,k);
67 }
68 #endif
69 
71  const Teuchos::RCP<const Stokhos::ProductBasis<int,double> >& sg_master_basis,
72  const std::vector<Teuchos::RCP<const Stokhos::ProductBasis<int,double> > > & sg_basis_row_dof,
73  const Epetra_CrsGraph & determ_graph,
74  bool onlyUseLinear,int kExpOrder,
75  bool scaleOp)
76  : sg_master_basis_(sg_master_basis), sg_basis_row_dof_(sg_basis_row_dof), scaleOp_(scaleOp)
77 {
79 
80  setupWithGraph(determ_graph,onlyUseLinear,kExpOrder);
81 }
82 
84  const Teuchos::RCP<const Stokhos::ProductBasis<int,double> >& sg_master_basis,
85  const std::vector<Teuchos::RCP<const Stokhos::ProductBasis<int,double> > > & sg_basis_row_dof,
86  const Epetra_Comm & comm,
87  bool scaleOp)
88  : sg_master_basis_(sg_master_basis), sg_basis_row_dof_(sg_basis_row_dof), scaleOp_(scaleOp)
89 {
91 }
92 
95 {
96  return Teuchos::rcp(new Epetra_CrsMatrix(Copy,*graph_));
97 }
98 
99 void Stokhos::AdaptivityManager::setupWithGraph(const Epetra_CrsGraph & determGraph,bool onlyUseLinear,int kExpOrder)
100 {
101  graph_ = adapt_utils::buildAdaptedGraph(determGraph, sg_master_basis_, sg_basis_row_dof_, onlyUseLinear, kExpOrder);
102 
103  adapt_utils::buildAdaptedColOffsets(determGraph,myRowGidOffsets_,myColGidOffsets_);
104  adapt_utils::buildColBasisFunctions(determGraph,sg_master_basis_,sg_basis_row_dof_,sg_basis_col_dof_);
105 }
106 
109 void
112  bool onlyUseLinear,bool includeMean) const
113 {
115 
116  // build the sparse hash only once
117  Sparse3TensorHash hashLookup(Cijk);
118 
119  // Zero out matrix
120  A.PutScalar(0.0);
121 
122  // Compute loop bounds
123  Cijk_type::k_iterator k_begin = Cijk.k_begin();
124  Cijk_type::k_iterator k_end = Cijk.k_end();
125  if (!includeMean && index(k_begin) == 0)
126  ++k_begin;
127  if (onlyUseLinear) {
128  int dim = sg_master_basis_->dimension();
129  k_end = Cijk.find_k(dim+1);
130  }
131 
132  // Assemble matrix
133  // const Teuchos::Array<double>& norms = sg_basis->norm_squared();
134  for (Cijk_type::k_iterator k_it=k_begin; k_it!=k_end; ++k_it) {
135  int k = index(k_it);
137  Teuchos::rcp_dynamic_cast<Epetra_CrsMatrix>(poly.getCoeffPtr(k),
138  true);
139 
140  // add in matrix k
141  sumInOperator(A,hashLookup,k,*block);
142  }
143 }
144 
145 void
148 {
149  // this allows the simple interface of taking a Sparse3Tensor but immediately computes
150  // the sparse hash (if boost is enabled)
151 
152  Sparse3TensorHash hashLookup(Cijk);
153  sumInOperator(A,hashLookup,k,J_k);
154 }
155 
156 void
159 {
160  TEUCHOS_ASSERT(J_k.NumMyRows() == int(sg_basis_row_dof_.size()));
161  TEUCHOS_ASSERT(J_k.NumMyCols() == int(sg_basis_col_dof_.size()));
162 
163  const Teuchos::Array<double> & normValues = sg_master_basis_->norm_squared();
164 
165  // loop over deterministic rows
166  for(int localM=0;localM<J_k.NumMyRows();localM++) {
167  // int m = J_k.GRID(localM); // unused
168 
169  // grab row basis
171  = sg_basis_row_dof_[localM];
172 
173  // grab row from deterministic system
174  int d_numEntries;
175  int * d_Indices;
176  double * d_Values;
177 
178  J_k.ExtractMyRowView(localM,d_numEntries,d_Values,d_Indices);
179 
180  // loop over stochastic degrees of freedom of this row
181  for(int rb_i=0;rb_i<rowStochBasis->size();rb_i++) {
182  int i = sg_master_basis_->index(rowStochBasis->term(rb_i));
183 
184  double normValue = normValues[i]; // sg_master_basis->norm_squared(i);
185 
186  int sg_m = getGlobalRowId(localM,rb_i);
187 
188  // we wipe out old values, capacity should gurantee
189  // we don't allocate more often than neccessary!
190  std::vector<int> sg_indices;
191  std::vector<double> sg_values;
192 
193  // sg_indices.resize(0);
194  // sg_values.resize(0);
195 
196  // loop over each column
197  for(int colInd=0;colInd<d_numEntries;colInd++) {
198  int localN = d_Indices[colInd]; // grab local deterministic column id
199 
200  // grab row basis
202  = sg_basis_col_dof_[localN];
203 
204  // build values array
205  for(int cb_j=0;cb_j<colStochBasis->size();cb_j++) {
206  int j = sg_master_basis_->index(colStochBasis->term(cb_j));
207  int sg_n = getGlobalColId(localN,cb_j);
208  double cijk = Cijk.getValue(i,j,k);
209 
210  // no reason to work it in!
211  if(cijk==0) continue;
212 
213  if(scaleOp_)
214  cijk = cijk/normValue;
215 
216  sg_indices.push_back(sg_n);
217  sg_values.push_back(cijk*d_Values[colInd]);
218  }
219  }
220 
221  // add in matrix values
222  A.SumIntoGlobalValues(sg_m,sg_indices.size(),&sg_values[0],&sg_indices[0]);
223  }
224  }
225 }
226 
230 {
232 
233  // copy from adapted vector to deterministic
234  for(std::size_t i=0;i<sg_basis_row_dof_.size();i++) {
235  int P_i = getRowStochasticBasisSize(i);
236  int localId = rowMap_->LID(getGlobalRowId(i,0));
237 
238  for(int j=0;j<P_i;j++,localId++) {
239  int blk = sg_master_basis_->index(sg_basis_row_dof_[i]->term(j));
240  x[localId] = x_sg_bv->GetBlock(blk)->operator[](i);
241  }
242  }
243 }
244 
248 {
249  int numBlocks = x_sg.size();
251 
252  // zero out determinstic vectors
253  for(int blk=0;blk<numBlocks;blk++)
254  x_sg_bv->GetBlock(blk)->PutScalar(0.0);
255 
256  // copy from adapted vector to deterministic
257  for(std::size_t i=0;i<sg_basis_row_dof_.size();i++) {
258  int P_i = getRowStochasticBasisSize(i);
259  int localId = rowMap_->LID(getGlobalRowId(i,0));
260 
261  for(int j=0;j<P_i;j++,localId++) {
262  int blk = sg_master_basis_->index(sg_basis_row_dof_[i]->term(j));
263  x_sg_bv->GetBlock(blk)->operator[](i) = x[localId];
264  }
265  }
266 }
A container class storing an orthogonal polynomial whose coefficients are vectors, operators, or in general any type that would have an expensive copy constructor.
k_iterator k_begin() const
Iterator pointing to first k entry.
const Epetra_Comm & Comm() const
void buildColBasisFunctions(const Epetra_CrsGraph &determGraph, const Teuchos::RCP< const Stokhos::ProductBasis< int, double > > &masterBasis, const std::vector< Teuchos::RCP< const Stokhos::ProductBasis< int, double > > > &per_dof_row_basis, std::vector< Teuchos::RCP< const Stokhos::ProductBasis< int, double > > > &per_dof_col_basis)
Teuchos::RCP< EpetraExt::BlockVector > getBlockVector()
Get block vector.
kj_iterator j_begin(const k_iterator &k) const
Iterator pointing to first j entry for given k.
std::vector< Teuchos::RCP< const Stokhos::ProductBasis< int, double > > > sg_basis_row_dof_
virtual int SumIntoGlobalValues(int GlobalRow, int NumEntries, const double *Values, const int *Indices)
void setupOperator(Epetra_CrsMatrix &A, const Sparse3Tensor< int, double > &Cijk, Stokhos::EpetraOperatorOrthogPoly &poly, bool onlyUseLinear=false, bool includeMean=true) const
kj_iterator j_end(const k_iterator &k) const
Iterator pointing to last j entry for given k.
Bi-directional iterator for traversing a sparse array.
int ExtractMyRowView(int MyRow, int &NumEntries, double *&Values, int *&Indices) const
int PutScalar(double ScalarConstant)
Teuchos::RCP< Epetra_CrsGraph > buildAdaptedGraph(const Epetra_CrsGraph &determGraph, const Teuchos::RCP< const Stokhos::ProductBasis< int, double > > &masterBasis, const std::vector< Teuchos::RCP< const Stokhos::ProductBasis< int, double > > > &per_dof_row_basis, bool onlyUseLinear=false, int kExpOrder=-1)
int NumMyCols() const
void copyFromAdaptiveVector(const Epetra_Vector &x, Stokhos::EpetraVectorOrthogPoly &x_sg) const
void copyToAdaptiveVector(const Stokhos::EpetraVectorOrthogPoly &x_sg, Epetra_Vector &x) const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
A container class storing an orthogonal polynomial whose coefficients are vectors, operators, or in general any type that would have an expensive copy constructor.
int NumMyRows() const
Teuchos::RCP< Epetra_Map > buildAdaptedRowMapAndOffsets(const Epetra_Comm &Comm, const std::vector< Teuchos::RCP< const Stokhos::ProductBasis< int, double > > > &per_dof_row_basis, std::vector< int > &myRowGidOffsets)
Sparse3TensorHash(const Stokhos::Sparse3Tensor< int, double > &Cijk)
void setupWithGraph(const Epetra_CrsGraph &graph, bool onlyUseLinear, int kExpOrder)
void buildAdaptedColOffsets(const Epetra_CrsGraph &determGraph, const std::vector< int > &myRowGidOffsets, std::vector< int > &myColGidOffsets)
k_iterator k_end() const
Iterator pointing to last k entry.
k_iterator find_k(ordinal_type k) const
Return k iterator for given index k.
KOKKOS_INLINE_FUNCTION constexpr std::enable_if< is_view_uq_pce< view_type >::value, typename CijkType< view_type >::type >::type cijk(const view_type &view)
Stokhos::Sparse3Tensor< int, double > Cijk_type
Teuchos::RCP< coeff_type > getCoeffPtr(ordinal_type i)
Return ref-count pointer to coefficient i.
Teuchos::RCP< Epetra_CrsMatrix > buildMatrixFromGraph() const
Teuchos::RCP< const Stokhos::ProductBasis< int, double > > sg_master_basis_
#define TEUCHOS_ASSERT(assertion_test)
kji_iterator i_begin(const kj_iterator &j) const
Iterator pointing to first i entry for given j and k.
kji_iterator i_end(const kj_iterator &j) const
Iterator pointing to last i entry for given j and k.
void sumInOperator(Epetra_CrsMatrix &A, const Stokhos::Sparse3Tensor< int, double > &Cijk, int k, const Epetra_CrsMatrix &J_k) const
ordinal_type size() const
Return size.
Teuchos::RCP< Epetra_Map > rowMap_
AdaptivityManager(const Teuchos::RCP< const Stokhos::ProductBasis< int, double > > &sg_master_basis, const std::vector< Teuchos::RCP< const Stokhos::ProductBasis< int, double > > > &sg_basis_row_dof, const Epetra_CrsGraph &determ_graph, bool onlyUseLinear, int kExpOrder, bool scaleOp=true)