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 //
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_GlobalIndexer_hpp__
44 #define __Panzer_GlobalIndexer_hpp__
45 
46 #include <vector>
47 #include <string>
48 #include <unordered_map> // a hash table for buildLocalIds()
49 #include "Teuchos_RCP.hpp"
50 #include "Teuchos_Comm.hpp"
51 #include "Phalanx_KokkosDeviceTypes.hpp"
52 #include "PanzerDofMgr_config.hpp"
53 
54 namespace panzer {
55 
56 // Forward declaration.
57 class ConnManager;
58 
60 public:
62  virtual ~GlobalIndexer() {}
63 
66  virtual Teuchos::RCP<Teuchos::Comm<int> > getComm() const = 0;
67 
70  virtual int getNumFields() const = 0;
71 
86  virtual int getFieldNum(const std::string & str) const = 0;
87 
90  virtual void getFieldOrder(std::vector<std::string> & fieldOrder) const = 0;
91 
101  virtual const std::string & getFieldString(int num) const = 0;
102 
105  virtual void getElementBlockIds(std::vector<std::string> & elementBlockIds) const = 0;
106 
109  virtual bool fieldInBlock(const std::string & field, const std::string & block) const = 0;
110 
113  virtual const std::vector<int> & getBlockFieldNumbers(const std::string & blockId) const = 0;
114 
118  virtual const std::vector<int> & getGIDFieldOffsets(const std::string & blockId,int fieldNum) const = 0;
119 
132  virtual const std::pair<std::vector<int>,std::vector<int> > &
133  getGIDFieldOffsets_closure(const std::string & blockId, int fieldNum,
134  int subcellDim,int subcellId) const = 0;
135 
141  virtual int getElementBlockGIDCount(const std::size_t & blockIndex) const = 0;
142 
145  virtual void getElementOrientation(panzer::LocalOrdinal localElmtId,std::vector<double> & gidsOrientation) const = 0;
146 
154  virtual const std::vector<panzer::LocalOrdinal> & getElementBlock(const std::string & blockId) const = 0;
155 
159  virtual void getElementGIDs(panzer::LocalOrdinal localElmtId,std::vector<panzer::GlobalOrdinal> & gids,const std::string & blockIdHint="") const = 0;
160 
167  virtual void
168  getOwnedIndices(std::vector<panzer::GlobalOrdinal>& indices) const = 0;
169 
176  virtual void
177  getGhostedIndices(std::vector<panzer::GlobalOrdinal>& indices) const = 0;
178 
185  virtual void
186  getOwnedAndGhostedIndices(std::vector<panzer::GlobalOrdinal>& indices) const = 0;
187 
190 
194  virtual void getElementGIDsAsInt(panzer::LocalOrdinal localElmtId,std::vector<int> & gids,const std::string & blockIdHint="") const = 0;
195 
202  virtual void getOwnedIndicesAsInt(std::vector<int>& indices) const = 0;
203 
210  virtual void getGhostedIndicesAsInt(std::vector<int>& indices) const = 0;
211 
218  virtual void getOwnedAndGhostedIndicesAsInt(std::vector<int>& indices) const = 0;
219 
221 
227  virtual int
228  getNumOwned() const = 0;
229 
235  virtual int
236  getNumGhosted() const = 0;
237 
243  virtual int
244  getNumOwnedAndGhosted() const = 0;
245 
248  virtual void ownedIndices(const std::vector<panzer::GlobalOrdinal> & indices,std::vector<bool> & isOwned) const = 0;
249 
253  const Kokkos::View<const panzer::LocalOrdinal*,Kokkos::LayoutRight,PHX::Device> getElementLIDs(panzer::LocalOrdinal localElmtId) const
254  { return Kokkos::subview(localIDs_k_, localElmtId, Kokkos::ALL() ); }
255 
258  const Kokkos::View<const panzer::LocalOrdinal**,Kokkos::LayoutRight,PHX::Device> getLIDs() const
259  {return localIDs_k_;}
260 
264  void getElementLIDs(Kokkos::View<const int*,PHX::Device> cellIds,
265  Kokkos::View<panzer::LocalOrdinal**,PHX::Device> lids) const
266  {
267  CopyCellLIDsFunctor functor;
268  functor.cellIds = cellIds;
269  functor.global_lids = localIDs_k_;
270  functor.local_lids = lids; // we assume this array is sized correctly!
271 
272  Kokkos::parallel_for(cellIds.extent(0),functor);
273  }
274 
280  virtual int getElementBlockGIDCount(const std::string & blockId) const = 0;
281 
285 
287  public:
288  typedef typename PHX::Device execution_space;
289 
290  Kokkos::View<const int*,PHX::Device> cellIds;
291  Kokkos::View<const panzer::LocalOrdinal**,Kokkos::LayoutRight,PHX::Device> global_lids;
292  Kokkos::View<panzer::LocalOrdinal**,PHX::Device> local_lids;
293 
294  KOKKOS_INLINE_FUNCTION
295  void operator()(const int cell) const
296  {
297  for(int i=0;i<static_cast<int>(local_lids.extent(1));i++)
298  local_lids(cell,i) = global_lids(cellIds(cell),i);
299  }
300 
301  };
302 
303 protected:
304 
309  {
310  // this method is implmented as two steps to ensure
311  // that setLocalIds works, it would be better to simply
312  // call:
313  // buildLocalIdsFromOwnedElements(localIDs_);
314 
315  std::vector<std::vector<panzer::LocalOrdinal> > localIDs;
317  setLocalIds(localIDs);
318  }
319 
323  void buildLocalIdsFromOwnedElements(std::vector<std::vector<panzer::LocalOrdinal> > & localIDs) const ;
324 
329  void setLocalIds(const std::vector<std::vector<panzer::LocalOrdinal> > & localIDs)
330  {
331  // determine the maximium second dimension of the local IDs
332  std::size_t max = 0;
333  for(std::size_t i=0;i<localIDs.size();i++)
334  max = localIDs[i].size() > max ? localIDs[i].size() : max;
335 
336  // allocate for the kokkos size
337  Kokkos::View<panzer::LocalOrdinal**,Kokkos::LayoutRight,PHX::Device> localIDs_k
338  = Kokkos::View<panzer::LocalOrdinal**,Kokkos::LayoutRight,PHX::Device>("ugi:localIDs_",localIDs.size(),max);
339  for(std::size_t i=0;i<localIDs.size();i++) {
340  for(std::size_t j=0;j<localIDs[i].size();j++)
341  localIDs_k(i,j) = localIDs[i][j];
342  }
343 
344  // store in Kokkos type
345  localIDs_k_ = localIDs_k;
346  }
347 
353  void shareLocalIDs(const GlobalIndexer & src)
354  {
355  localIDs_k_ = src.localIDs_k_;
356  }
357 
358 private:
359  Kokkos::View<const panzer::LocalOrdinal**,Kokkos::LayoutRight,PHX::Device> localIDs_k_;
360 };
361 
362 inline void GlobalIndexer::
363 buildLocalIdsFromOwnedElements(std::vector<std::vector<panzer::LocalOrdinal> > & localIDs) const
364 {
365  std::vector<panzer::GlobalOrdinal> ownedAndGhosted;
366  this->getOwnedAndGhostedIndices(ownedAndGhosted);
367 
368  // build global to local hash map (temporary and used only once)
369  std::unordered_map<panzer::GlobalOrdinal,panzer::LocalOrdinal> hashMap;
370  for(std::size_t i=0;i<ownedAndGhosted.size();i++)
371  hashMap[ownedAndGhosted[i]] = i;
372 
373  std::vector<std::string> elementBlocks;
374  this->getElementBlockIds(elementBlocks);
375 
376  // compute total number of elements
377  std::size_t numElmts = 0;
378  for(std::size_t eb=0;eb<elementBlocks.size();eb++)
379  numElmts += this->getElementBlock(elementBlocks[eb]).size();
380  localIDs.resize(numElmts); // allocate local ids
381 
382  // perform computation of local ids
383  for(std::size_t eb=0;eb<elementBlocks.size();eb++) {
384  std::vector<panzer::GlobalOrdinal> gids;
385  const std::vector<panzer::LocalOrdinal> & elmts = this->getElementBlock(elementBlocks[eb]);
386 
387  for(std::size_t e=0;e<elmts.size();e++) {
388  this->getElementGIDs(elmts[e],gids,elementBlocks[eb]);
389  std::vector<panzer::LocalOrdinal> & lids = localIDs[elmts[e]];
390  lids.resize(gids.size());
391 
392  for(std::size_t g=0;g<gids.size();g++)
393  lids[g] = hashMap[gids[g]];
394  }
395  }
396 }
397 
398 }
399 
400 #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 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
Kokkos::View< const panzer::LocalOrdinal **, Kokkos::LayoutRight, PHX::Device > global_lids
void getElementLIDs(Kokkos::View< const int *, PHX::Device > cellIds, Kokkos::View< panzer::LocalOrdinal **, PHX::Device > lids) 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.
Kokkos::View< const LO **, PHX::Device > lids
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
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...
Kokkos::View< const int *, PHX::Device > cellIds
KOKKOS_INLINE_FUNCTION void operator()(const int cell) const
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.
Kokkos::View< panzer::LocalOrdinal **, PHX::Device > local_lids
virtual void getFieldOrder(std::vector< std::string > &fieldOrder) const =0
void buildLocalIdsFromOwnedElements(std::vector< std::vector< panzer::LocalOrdinal > > &localIDs) const