Panzer  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Panzer_GlobalIndexer.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Panzer: A partial differential equation assembly
4 // engine for strongly coupled complex multiphysics systems
5 //
6 // Copyright 2011 NTESS and the Panzer contributors.
7 // SPDX-License-Identifier: BSD-3-Clause
8 // *****************************************************************************
9 // @HEADER
10 
11 #ifndef __Panzer_GlobalIndexer_hpp__
12 #define __Panzer_GlobalIndexer_hpp__
13 
14 #include <vector>
15 #include <string>
16 #include <unordered_map> // a hash table for buildLocalIds()
17 #include "Teuchos_RCP.hpp"
18 #include "Teuchos_Comm.hpp"
19 #include "Phalanx_KokkosDeviceTypes.hpp"
20 #include "PanzerDofMgr_config.hpp"
21 
22 namespace panzer {
23 
24 // Forward declaration.
25 class ConnManager;
26 
28 public:
30  virtual ~GlobalIndexer() {}
31 
34  virtual Teuchos::RCP<Teuchos::Comm<int> > getComm() const = 0;
35 
38  virtual int getNumFields() const = 0;
39 
54  virtual int getFieldNum(const std::string & str) const = 0;
55 
58  virtual void getFieldOrder(std::vector<std::string> & fieldOrder) const = 0;
59 
69  virtual const std::string & getFieldString(int num) const = 0;
70 
73  virtual void getElementBlockIds(std::vector<std::string> & elementBlockIds) const = 0;
74 
77  virtual bool fieldInBlock(const std::string & field, const std::string & block) const = 0;
78 
81  virtual const std::vector<int> & getBlockFieldNumbers(const std::string & blockId) const = 0;
82 
86  virtual const std::vector<int> & getGIDFieldOffsets(const std::string & blockId,int fieldNum) const = 0;
87 
100  virtual const std::pair<std::vector<int>,std::vector<int> > &
101  getGIDFieldOffsets_closure(const std::string & blockId, int fieldNum,
102  int subcellDim,int subcellId) const = 0;
103 
109  virtual int getElementBlockGIDCount(const std::size_t & blockIndex) const = 0;
110 
113  virtual void getElementOrientation(panzer::LocalOrdinal localElmtId,std::vector<double> & gidsOrientation) const = 0;
114 
122  virtual const std::vector<panzer::LocalOrdinal> & getElementBlock(const std::string & blockId) const = 0;
123 
127  virtual void getElementGIDs(panzer::LocalOrdinal localElmtId,std::vector<panzer::GlobalOrdinal> & gids,const std::string & blockIdHint="") const = 0;
128 
135  virtual void
136  getOwnedIndices(std::vector<panzer::GlobalOrdinal>& indices) const = 0;
137 
144  virtual void
145  getGhostedIndices(std::vector<panzer::GlobalOrdinal>& indices) const = 0;
146 
153  virtual void
154  getOwnedAndGhostedIndices(std::vector<panzer::GlobalOrdinal>& indices) const = 0;
155 
158 
162  virtual void getElementGIDsAsInt(panzer::LocalOrdinal localElmtId,std::vector<int> & gids,const std::string & blockIdHint="") const = 0;
163 
170  virtual void getOwnedIndicesAsInt(std::vector<int>& indices) const = 0;
171 
178  virtual void getGhostedIndicesAsInt(std::vector<int>& indices) const = 0;
179 
186  virtual void getOwnedAndGhostedIndicesAsInt(std::vector<int>& indices) const = 0;
187 
189 
195  virtual int
196  getNumOwned() const = 0;
197 
203  virtual int
204  getNumGhosted() const = 0;
205 
211  virtual int
212  getNumOwnedAndGhosted() const = 0;
213 
216  virtual void ownedIndices(const std::vector<panzer::GlobalOrdinal> & indices,std::vector<bool> & isOwned) const = 0;
217 
222  { return Kokkos::subview(localIDs_k_, localElmtId, Kokkos::ALL() ); }
223 
227  {return localIDs_k_;}
228 
245  template <typename ArrayT>
246  void getElementLIDs(PHX::View<const int*> cellIds, ArrayT lids, const int num_dofs = 0) const
247  {
249  functor.cellIds = cellIds;
250  functor.global_lids = localIDs_k_;
251  functor.local_lids = lids; // we assume this array is sized correctly if num_dofs not specified!
252  if (num_dofs > 0)
253  functor.num_dofs = num_dofs;
254  else
255  functor.num_dofs = lids.extent(1);
256 
257 #ifdef PANZER_DEBUG
258  TEUCHOS_ASSERT(static_cast<int>(functor.local_lids.extent(1)) >= num_dofs);
259  TEUCHOS_ASSERT(static_cast<int>(functor.global_lids.extent(1)) >= num_dofs);
260 #endif
261 
262  Kokkos::parallel_for(cellIds.extent(0),functor);
263  }
264 
270  virtual int getElementBlockGIDCount(const std::string & blockId) const = 0;
271 
275 
276  template <typename ArrayT>
278  public:
279  typedef typename PHX::Device execution_space;
280 
281  PHX::View<const int*> cellIds;
283  ArrayT local_lids;
284  int num_dofs;
285 
286  KOKKOS_INLINE_FUNCTION
287  void operator()(const int cell) const
288  {
289  for(int i=0;i<num_dofs;i++)
290  local_lids(cell,i) = global_lids(cellIds(cell),i);
291  }
292 
293  };
294 
295 protected:
296 
301  {
302  // this method is implmented as two steps to ensure
303  // that setLocalIds works, it would be better to simply
304  // call:
305  // buildLocalIdsFromOwnedElements(localIDs_);
306 
307  std::vector<std::vector<panzer::LocalOrdinal> > localIDs;
309  setLocalIds(localIDs);
310  }
311 
315  void buildLocalIdsFromOwnedElements(std::vector<std::vector<panzer::LocalOrdinal> > & localIDs) const ;
316 
321  void setLocalIds(const std::vector<std::vector<panzer::LocalOrdinal> > & localIDs)
322  {
323  // determine the maximium second dimension of the local IDs
324  std::size_t max = 0;
325  for(std::size_t i=0;i<localIDs.size();i++)
326  max = localIDs[i].size() > max ? localIDs[i].size() : max;
327 
328  // allocate for the kokkos size
330  = Kokkos::View<panzer::LocalOrdinal**,Kokkos::LayoutRight,PHX::Device>("ugi:localIDs_",localIDs.size(),max);
331  auto localIDs_h = Kokkos::create_mirror_view(localIDs_k);
332  for(std::size_t i=0;i<localIDs.size();i++) {
333  for(std::size_t j=0;j<localIDs[i].size();j++)
334  localIDs_h(i,j) = localIDs[i][j];
335  }
336  Kokkos::deep_copy(localIDs_k, localIDs_h);
337 
338  // store in Kokkos type
339  localIDs_k_ = localIDs_k;
340  }
341 
347  void shareLocalIDs(const GlobalIndexer & src)
348  {
349  localIDs_k_ = src.localIDs_k_;
350  }
351 
352 private:
354 };
355 
356 inline void GlobalIndexer::
357 buildLocalIdsFromOwnedElements(std::vector<std::vector<panzer::LocalOrdinal> > & localIDs) const
358 {
359  std::vector<panzer::GlobalOrdinal> ownedAndGhosted;
360  this->getOwnedAndGhostedIndices(ownedAndGhosted);
361 
362  // build global to local hash map (temporary and used only once)
363  std::unordered_map<panzer::GlobalOrdinal,panzer::LocalOrdinal> hashMap;
364  for(std::size_t i=0;i<ownedAndGhosted.size();i++)
365  hashMap[ownedAndGhosted[i]] = i;
366 
367  std::vector<std::string> elementBlocks;
368  this->getElementBlockIds(elementBlocks);
369 
370  // compute total number of elements
371  std::size_t numElmts = 0;
372  for(std::size_t eb=0;eb<elementBlocks.size();eb++)
373  numElmts += this->getElementBlock(elementBlocks[eb]).size();
374  localIDs.resize(numElmts); // allocate local ids
375 
376  // perform computation of local ids
377  for(std::size_t eb=0;eb<elementBlocks.size();eb++) {
378  std::vector<panzer::GlobalOrdinal> gids;
379  const std::vector<panzer::LocalOrdinal> & elmts = this->getElementBlock(elementBlocks[eb]);
380 
381  for(std::size_t e=0;e<elmts.size();e++) {
382  this->getElementGIDs(elmts[e],gids,elementBlocks[eb]);
383  std::vector<panzer::LocalOrdinal> & lids = localIDs[elmts[e]];
384  lids.resize(gids.size());
385 
386  for(std::size_t g=0;g<gids.size();g++)
387  lids[g] = hashMap[gids[g]];
388  }
389  }
390 }
391 
392 }
393 
394 #endif
virtual const std::string & getFieldString(int num) const =0
Reverse lookup of the field string from a field number.
virtual Teuchos::RCP< Teuchos::Comm< int > > getComm() const =0
void shareLocalIDs(const GlobalIndexer &src)
virtual void getGhostedIndices(std::vector< panzer::GlobalOrdinal > &indices) const =0
Get the set of indices ghosted for this processor.
const Kokkos::View< const panzer::LocalOrdinal *, Kokkos::LayoutRight, PHX::Device > getElementLIDs(panzer::LocalOrdinal localElmtId) const
virtual void getGhostedIndicesAsInt(std::vector< int > &indices) const =0
Get the set of indices ghosted for this processor.
virtual int getElementBlockGIDCount(const std::size_t &blockIndex) const =0
How any GIDs are associate with each element in a particular element block.
const Kokkos::View< const panzer::LocalOrdinal **, Kokkos::LayoutRight, PHX::Device > getLIDs() const
virtual const std::vector< panzer::LocalOrdinal > & getElementBlock(const std::string &blockId) const =0
virtual void getOwnedAndGhostedIndicesAsInt(std::vector< int > &indices) const =0
Get the set of owned and ghosted indices for this processor.
virtual void getElementOrientation(panzer::LocalOrdinal localElmtId, std::vector< double > &gidsOrientation) const =0
Get a vector containg the orientation of the GIDs relative to the neighbors.
virtual void getElementBlockIds(std::vector< std::string > &elementBlockIds) const =0
void getElementLIDs(PHX::View< const int * > cellIds, ArrayT lids, const int num_dofs=0) const
virtual void getElementGIDsAsInt(panzer::LocalOrdinal localElmtId, std::vector< int > &gids, const std::string &blockIdHint="") const =0
Get the global IDs for a particular element. This function overwrites the gids variable.
virtual void getOwnedIndices(std::vector< panzer::GlobalOrdinal > &indices) const =0
Get the set of indices owned by this processor.
virtual bool fieldInBlock(const std::string &field, const std::string &block) const =0
virtual int getNumGhosted() const =0
Get the number of indices ghosted for this processor.
virtual int getNumFields() const =0
Kokkos::View< const panzer::LocalOrdinal **, Kokkos::LayoutRight, PHX::Device > global_lids
virtual void ownedIndices(const std::vector< panzer::GlobalOrdinal > &indices, std::vector< bool > &isOwned) const =0
virtual Teuchos::RCP< const ConnManager > getConnManager() const =0
Returns the connection manager currently being used.
virtual int getFieldNum(const std::string &str) const =0
Get the number used for access to this field.
virtual void getOwnedIndicesAsInt(std::vector< int > &indices) const =0
Get the set of indices owned by this processor.
virtual void getOwnedAndGhostedIndices(std::vector< panzer::GlobalOrdinal > &indices) const =0
Get the set of owned and ghosted indices for this processor.
virtual int getNumOwnedAndGhosted() const =0
Get the number of owned and ghosted indices for this processor.
void setLocalIds(const std::vector< std::vector< panzer::LocalOrdinal > > &localIDs)
virtual ~GlobalIndexer()
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...
virtual int getNumOwned() const =0
Get the number of indices owned by this processor.
Kokkos::View< const panzer::LocalOrdinal **, Kokkos::LayoutRight, PHX::Device > localIDs_k_
PHX::MDField< ScalarT, panzer::Cell, panzer::BASIS > field
A field to which we&#39;ll contribute, or in which we&#39;ll store, the result of computing this integral...
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 const std::vector< int > & getBlockFieldNumbers(const std::string &blockId) const =0
virtual void getElementGIDs(panzer::LocalOrdinal localElmtId, std::vector< panzer::GlobalOrdinal > &gids, const std::string &blockIdHint="") const =0
Get the global IDs for a particular element. This function overwrites the gids variable.
virtual void getFieldOrder(std::vector< std::string > &fieldOrder) const =0
#define TEUCHOS_ASSERT(assertion_test)
Kokkos::View< const LO **, Kokkos::LayoutRight, PHX::Device > lids
KOKKOS_INLINE_FUNCTION void operator()(const int cell) const
void buildLocalIdsFromOwnedElements(std::vector< std::vector< panzer::LocalOrdinal > > &localIDs) const