Panzer  Version of the Day
Panzer_UniqueGlobalIndexer.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Panzer: A partial differential equation assembly
5 // engine for strongly coupled complex multiphysics systems
6 // Copyright (2011) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Roger P. Pawlowski (rppawlo@sandia.gov) and
39 // Eric C. Cyr (eccyr@sandia.gov)
40 // ***********************************************************************
41 // @HEADER
42 
43 #ifndef __Panzer_UniqueGlobalIndexer_hpp__
44 #define __Panzer_UniqueGlobalIndexer_hpp__
45 
46 #include <vector>
47 #include <string>
48 
49 #include <unordered_map> // a hash table for buildLocalIds()
50 
51 #include "Teuchos_RCP.hpp"
52 #include "Teuchos_Comm.hpp"
53 
54 #include "Phalanx_KokkosDeviceTypes.hpp"
55 
56 namespace panzer {
57 
58 // Forward declaration.
59 template <typename LocalOrdinalT> class ConnManagerBase;
60 
62 public:
64  virtual ~UniqueGlobalIndexerBase() = 0;
65 
68  virtual Teuchos::RCP<Teuchos::Comm<int> > getComm() const = 0;
69 
72  virtual int getNumFields() const = 0;
73 
88  virtual int getFieldNum(const std::string & str) const = 0;
89 
92  virtual void getFieldOrder(std::vector<std::string> & fieldOrder) const = 0;
93 
103  virtual const std::string & getFieldString(int num) const = 0;
104 
107  virtual void getElementBlockIds(std::vector<std::string> & elementBlockIds) const = 0;
108 
111  virtual bool fieldInBlock(const std::string & field, const std::string & block) const = 0;
112 
115  virtual const std::vector<int> & getBlockFieldNumbers(const std::string & blockId) const = 0;
116 
120  virtual const std::vector<int> & getGIDFieldOffsets(const std::string & blockId,int fieldNum) const = 0;
121 
134  virtual const std::pair<std::vector<int>,std::vector<int> > &
135  getGIDFieldOffsets_closure(const std::string & blockId, int fieldNum,
136  int subcellDim,int subcellId) const = 0;
137 
143  virtual int getElementBlockGIDCount(const std::string & blockId) const = 0;
144 
150  virtual int getElementBlockGIDCount(const std::size_t & blockIndex) const = 0;
151 };
152 
153 template <typename LocalOrdinalT,typename GlobalOrdinalT>
155 public:
157  virtual ~UniqueGlobalIndexer() = 0;
158 
161  virtual Teuchos::RCP<Teuchos::Comm<int> > getComm() const = 0;
162 
165  virtual int getNumFields() const = 0;
166 
181  virtual int getFieldNum(const std::string & str) const = 0;
182 
185  virtual void getFieldOrder(std::vector<std::string> & fieldOrder) const = 0;
186 
189  virtual void getElementBlockIds(std::vector<std::string> & elementBlockIds) const = 0;
190 
193  virtual bool fieldInBlock(const std::string & field, const std::string & block) const = 0;
194 
197  virtual const std::vector<int> & getBlockFieldNumbers(const std::string & blockId) const = 0;
198 
202  virtual const std::vector<int> & getGIDFieldOffsets(const std::string & blockId,int fieldNum) const = 0;
203 
216  virtual const std::pair<std::vector<int>,std::vector<int> > &
217  getGIDFieldOffsets_closure(const std::string & blockId, int fieldNum,
218  int subcellDim,int subcellId) const = 0;
219 
220  // Methods requiring Local or Global OrdinalT
222 
225  virtual void getElementOrientation(LocalOrdinalT localElmtId,std::vector<double> & gidsOrientation) const = 0;
226 
234  virtual const std::vector<LocalOrdinalT> & getElementBlock(const std::string & blockId) const = 0;
235 
239  virtual void getElementGIDs(LocalOrdinalT localElmtId,std::vector<GlobalOrdinalT> & gids,const std::string & blockIdHint="") const = 0;
240 
243  virtual void getOwnedIndices(std::vector<GlobalOrdinalT> & indices) const = 0;
244 
247  virtual void getOwnedAndGhostedIndices(std::vector<GlobalOrdinalT> & indices) const = 0;
248 
251  virtual void ownedIndices(const std::vector<GlobalOrdinalT> & indices,std::vector<bool> & isOwned) const = 0;
252 
256  const std::vector<LocalOrdinalT> & getElementLIDs(LocalOrdinalT localElmtId) const
257  { return localIDs_[localElmtId]; }
258 
262  void getElementLIDs(Kokkos::View<const int*,PHX::Device> cellIds,
263  Kokkos::View<LocalOrdinalT**,PHX::Device> lids) const
264  {
265  CopyCellLIDsFunctor functor;
266  functor.cellIds = cellIds;
267  functor.global_lids = localIDs_k_;
268  functor.local_lids = lids; // we assume this array is sized correctly!
269 
270  Kokkos::parallel_for(cellIds.dimension_0(),functor);
271  }
272 
278  virtual int getElementBlockGIDCount(const std::string & blockId) const = 0;
279 
285  virtual int getElementBlockGIDCount(const std::size_t & blockIndex) const = 0;
286 
290 
292  public:
293  typedef typename PHX::Device execution_space;
294 
295  Kokkos::View<const int*,PHX::Device> cellIds;
296  Kokkos::View<const LocalOrdinalT**,PHX::Device> global_lids;
297  Kokkos::View<LocalOrdinalT**,PHX::Device> local_lids;
298 
299  KOKKOS_INLINE_FUNCTION
300  void operator()(const int cell) const
301  {
302  for(int i=0;i<Teuchos::as<int>(local_lids.dimension_1());i++)
303  local_lids(cell,i) = global_lids(cellIds(cell),i);
304  }
305 
306  };
307 
308 protected:
309 
314  {
315  // this method is implmented as two steps to ensure
316  // that setLocalIds works, it would be better to simply
317  // call:
318  // buildLocalIdsFromOwnedElements(localIDs_);
319 
320  std::vector<std::vector<LocalOrdinalT> > localIDs;
322  setLocalIds(localIDs);
323  }
324 
328  void buildLocalIdsFromOwnedElements(std::vector<std::vector<LocalOrdinalT> > & localIDs) const ;
329 
334  void setLocalIds(const std::vector<std::vector<LocalOrdinalT> > & localIDs)
335  { localIDs_ = localIDs;
336 
337  // determine the maximium second dimension of the local IDs
338  std::size_t max = 0;
339  for(std::size_t i=0;i<localIDs.size();i++)
340  max = localIDs[i].size() > max ? localIDs[i].size() : max;
341 
342  // allocate for the kokkos size
343  Kokkos::View<LocalOrdinalT**,PHX::Device> localIDs_k
344  = Kokkos::View<LocalOrdinalT**,PHX::Device>("ugi:localIDs_",localIDs.size(),max);
345  for(std::size_t i=0;i<localIDs.size();i++) {
346  for(std::size_t j=0;j<localIDs[i].size();j++)
347  localIDs_k(i,j) = localIDs[i][j];
348  }
349 
350  // store in Kokkos type
351  localIDs_k_ = localIDs_k;
352  }
353 
360  {
361  localIDs_ = src.localIDs_;
362  localIDs_k_ = src.localIDs_k_;
363  }
364 
365 private:
366  std::vector<std::vector<LocalOrdinalT> > localIDs_;
367  Kokkos::View<const LocalOrdinalT**,PHX::Device> localIDs_k_;
368 };
369 
370 // prevents a warning because a destructor does not exist
372 
373 // prevents a warning because a destructor does not exist
374 template <typename LocalOrdinalT,typename GlobalOrdinalT>
376 
377 template <typename LocalOrdinalT,typename GlobalOrdinalT>
379 buildLocalIdsFromOwnedElements(std::vector<std::vector<LocalOrdinalT> > & localIDs) const
380 {
381  std::vector<GlobalOrdinalT> ownedAndGhosted;
382  this->getOwnedAndGhostedIndices(ownedAndGhosted);
383 
384  // build global to local hash map (temporary and used only once)
385  std::unordered_map<GlobalOrdinalT,LocalOrdinalT> hashMap;
386  for(std::size_t i=0;i<ownedAndGhosted.size();i++)
387  hashMap[ownedAndGhosted[i]] = i;
388 
389  std::vector<std::string> elementBlocks;
390  this->getElementBlockIds(elementBlocks);
391 
392  // compute total number of elements
393  std::size_t numElmts = 0;
394  for(std::size_t eb=0;eb<elementBlocks.size();eb++)
395  numElmts += this->getElementBlock(elementBlocks[eb]).size();
396  localIDs.resize(numElmts); // allocate local ids
397 
398  // perform computation of local ids
399  for(std::size_t eb=0;eb<elementBlocks.size();eb++) {
400  std::vector<GlobalOrdinalT> gids;
401  const std::vector<LocalOrdinalT> & elmts = this->getElementBlock(elementBlocks[eb]);
402 
403  for(std::size_t e=0;e<elmts.size();e++) {
404  this->getElementGIDs(elmts[e],gids,elementBlocks[eb]);
405  std::vector<LocalOrdinalT> & lids = localIDs[elmts[e]];
406  lids.resize(gids.size());
407 
408  for(std::size_t g=0;g<gids.size();g++)
409  lids[g] = hashMap[gids[g]];
410  }
411  }
412 }
413 
414 }
415 
416 #endif
virtual int getNumFields() const =0
virtual const std::vector< int > & getGIDFieldOffsets(const std::string &blockId, int fieldNum) const =0
Use the field pattern so that you can find a particular field in the GIDs array.
virtual bool fieldInBlock(const std::string &field, const std::string &block) const =0
virtual void getElementGIDs(LocalOrdinalT localElmtId, std::vector< GlobalOrdinalT > &gids, const std::string &blockIdHint="") const =0
Get the global IDs for a particular element. This function overwrites the gids variable.
virtual int getElementBlockGIDCount(const std::string &blockId) const =0
How any GIDs are associate with a particular element block.
virtual int getNumFields() const =0
virtual void getOwnedAndGhostedIndices(std::vector< GlobalOrdinalT > &indices) const =0
virtual void getElementBlockIds(std::vector< std::string > &elementBlockIds) const =0
virtual ~UniqueGlobalIndexer()=0
Pure virtual destructor: prevents warnings with inline empty implementation.
Kokkos::View< LocalOrdinalT **, PHX::Device > local_lids
Kokkos::View< const LocalOrdinalT **, PHX::Device > global_lids
void setLocalIds(const std::vector< std::vector< LocalOrdinalT > > &localIDs)
virtual ~UniqueGlobalIndexerBase()=0
Pure virtual destructor: prevents warnings with inline empty implementation.
virtual const std::pair< std::vector< int >, std::vector< int > > & getGIDFieldOffsets_closure(const std::string &blockId, int fieldNum, int subcellDim, int subcellId) const =0
Use the field pattern so that you can find a particular field in the GIDs array. This version lets yo...
KOKKOS_INLINE_FUNCTION void operator()(const int cell) const
virtual Teuchos::RCP< Teuchos::Comm< int > > getComm() const =0
void buildLocalIdsFromOwnedElements(std::vector< std::vector< LocalOrdinalT > > &localIDs) const
virtual void getElementOrientation(LocalOrdinalT localElmtId, std::vector< double > &gidsOrientation) const =0
Get a vector containg the orientation of the GIDs relative to the neighbors.
virtual const std::vector< int > & getGIDFieldOffsets(const std::string &blockId, int fieldNum) const =0
Use the field pattern so that you can find a particular field in the GIDs array.
virtual void getFieldOrder(std::vector< std::string > &fieldOrder) const =0
PHX::MDField< ScalarT > vector
virtual Teuchos::RCP< Teuchos::Comm< int > > getComm() const =0
Kokkos::View< const LO **, PHX::Device > lids
virtual bool fieldInBlock(const std::string &field, const std::string &block) const =0
const std::vector< LocalOrdinalT > & getElementLIDs(LocalOrdinalT localElmtId) const
virtual Teuchos::RCP< const ConnManagerBase< LocalOrdinalT > > getConnManagerBase() const =0
Returns the connection manager currently being used.
Kokkos::View< const LocalOrdinalT **, PHX::Device > localIDs_k_
virtual const std::pair< std::vector< int >, std::vector< int > > & getGIDFieldOffsets_closure(const std::string &blockId, int fieldNum, int subcellDim, int subcellId) const =0
Use the field pattern so that you can find a particular field in the GIDs array. This version lets yo...
virtual void getElementBlockIds(std::vector< std::string > &elementBlockIds) const =0
virtual const std::vector< int > & getBlockFieldNumbers(const std::string &blockId) const =0
PHX::MDField< const ScalarT, Cell, IP > field
virtual int getElementBlockGIDCount(const std::string &blockId) const =0
How many GIDs are associate with a particular element block.
void shareLocalIDs(const UniqueGlobalIndexer< LocalOrdinalT, GlobalOrdinalT > &src)
virtual const std::string & getFieldString(int num) const =0
Reverse lookup of the field string from a field number.
virtual int getFieldNum(const std::string &str) const =0
Get the number used for access to this field.
void getElementLIDs(Kokkos::View< const int *, PHX::Device > cellIds, Kokkos::View< LocalOrdinalT **, PHX::Device > lids) const
virtual void ownedIndices(const std::vector< GlobalOrdinalT > &indices, std::vector< bool > &isOwned) const =0
std::vector< std::vector< LocalOrdinalT > > localIDs_
virtual const std::vector< int > & getBlockFieldNumbers(const std::string &blockId) const =0
virtual void getFieldOrder(std::vector< std::string > &fieldOrder) const =0
virtual const std::vector< LocalOrdinalT > & getElementBlock(const std::string &blockId) const =0
virtual int getFieldNum(const std::string &str) const =0
Get the number used for access to this field.
virtual void getOwnedIndices(std::vector< GlobalOrdinalT > &indices) const =0