Panzer  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Panzer_STK_PeriodicBC_Search_impl.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 #include "Teuchos_Tuple.hpp"
12 #include "Teuchos_RCP.hpp"
13 
14 #include "Panzer_STK_Version.hpp"
15 #include "PanzerAdaptersSTK_config.hpp"
16 #include "Panzer_STK_Interface.hpp"
17 
18 #include "Teuchos_FancyOStream.hpp"
19 
20 #include <set>
21 
22 namespace panzer_stk {
23 namespace periodic_helpers {
24 
25 template <typename Matcher>
27 matchPeriodicSidesSearch(const std::string & sideA,const std::string & sideB,
28  const STK_Interface & mesh,
29  const Matcher & matcher, const std::string type_)
30 {
31 
32  // this function should be called the first time a match is made
33  // we create a few empty objects for the previous mapping
34 
35  std::vector<std::string> matchedSides;
36  std::vector<std::pair<size_t,size_t> > previousMatches;
37 
38  // then pass along
39 
40  return matchPeriodicSidesSearch(sideA,sideB,mesh,matcher,matchedSides,previousMatches,type_);
41 
42 }
43 
44 
45 template <typename Matcher>
47 matchPeriodicSidesSearch(const std::string & sideA,const std::string & sideB,
48  const STK_Interface & mesh,
49  const Matcher & matcher, const std::vector<std::string> & matchedSides,
50  const std::vector<std::pair<size_t,size_t> > & previousMatches,
51  const std::string type_)
52 {
53  using Teuchos::Tuple;
54  using Teuchos::RCP;
55  using Teuchos::rcp;
56 
57  auto myRank = mesh.getBulkData()->parallel_rank();
58 
59  SphereIdVector coordsIdsA, coordsIdsB;
60  std::vector<SearchId> IDsToRemap;
61 
62  // populate the search vectors with the node coordinates and ids
63  // we will always search for ghosted IDs and repeats only on side A
64 
65  auto error = matcher.getAbsoluteTolerance();
66 
67  fillLocalSearchVector(mesh,coordsIdsA,error,sideA,type_,true,matchedSides,IDsToRemap);
68  fillLocalSearchVector(mesh,coordsIdsB,error,sideB,type_,false);
69 
70  // apply the matcher transform to side B to effectively align the periodic entities
71  // to do so we need the centroid of the other side
72 
73  // requires communication
74  std::vector<double> centroidA = computeGlobalCentroid(mesh,sideA);
75 
76  // now transform
77  transformLocalSearchVector(coordsIdsB,matcher,centroidA);
78 
79  // now we find the matches
80  SearchPairVector results;
81  stk::search::coarse_search(coordsIdsA,coordsIdsB,stk::search::KDTREE,mesh.getBulkData()->parallel(),results);
82 
83  // the results are pairs of matched A and B entity keys
84  // if my process has a match, it will be stored
85  // hence, we only keep the results if the A key proc matches our rank
86  // so each process has a map myAIDs --> BIDs
87 
88  // we store this A to B map, adding it to the pre-existing
89  // map of local periodic nodes to their matches, if necessary
90  // note the ids have been adjusted for entity type already
92  = Teuchos::rcp(new std::vector<std::pair<size_t,size_t>>());
93 
94  for (size_t i=0; i<results.size(); ++i) {
95  if (results[i].first.proc() == myRank) {
96  // first id grabs the entity key which has another id and the entity rank
97  (*myMap).emplace_back(
98  std::pair<size_t,size_t>(results[i].first.id().id(),results[i].second.id().id()) );
99  }
100  }
101 
102  TEUCHOS_TEST_FOR_EXCEPTION((*myMap).size()!=coordsIdsA.size(),std::logic_error,
103  "matchPeriodicSidesSearch: error in local match. "
104  "Number of matched IDs not equal to number of requested matches!");
105 
106  if (matchedSides.size()>0) {
107  // guaranteed to have previous matches and they are of the same entity type
108  // in this case we need to handle multiperiodicity
109  updateMapping(myMap,previousMatches,IDsToRemap,mesh);
110  } else if (previousMatches.size()>0) {
111  // we have previous matches, but they are of a different entity type
112  // in this case we just append the previous matches unaltered
113  appendMapping(myMap,previousMatches);
114  }
115 
116  return myMap;
117 
118 }
119 
120 template<typename Matcher> void
121 transformLocalSearchVector( SphereIdVector & searchVectorSideA, const Matcher & matcher, const std::vector<double> & centroidSideB)
122 {
123 
124  // loop over sphereIds objects and shift center according to the matcher's periodic transform
125 
126  for (auto && sphereIdSideA : searchVectorSideA )
127  matcher.transform(&sphereIdSideA.first.center()[0],centroidSideB);
128 
129  return;
130 }
131 
132 } // end periodic_helpers
133 } // end panzer_stk
Teuchos::RCP< std::vector< std::pair< size_t, size_t > > > matchPeriodicSidesSearch(const std::string &sideA, const std::string &sideB, const STK_Interface &mesh, const Matcher &matcher, const std::string type_)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void transformLocalSearchVector(SphereIdVector &searchVectorSideA, const Matcher &matcher, const std::vector< double > &centroidSideB)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::RCP< stk::mesh::BulkData > getBulkData() const