Panzer Version of the Day
Loading...
Searching...
No Matches
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
15#include "PanzerAdaptersSTK_config.hpp"
17
18#include "Teuchos_FancyOStream.hpp"
19
20#include <set>
21
22namespace panzer_stk {
23namespace periodic_helpers {
24
25template <typename Matcher>
26Teuchos::RCP<std::vector<std::pair<size_t,size_t> > >
27matchPeriodicSidesSearch(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
45template <typename Matcher>
46Teuchos::RCP<std::vector<std::pair<size_t,size_t> > >
47matchPeriodicSidesSearch(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
91 Teuchos::RCP<std::vector<std::pair<size_t,size_t> > > myMap
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
120template<typename Matcher> void
121transformLocalSearchVector( 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< stk::mesh::BulkData > getBulkData() const
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_)
void transformLocalSearchVector(SphereIdVector &searchVectorSideA, const Matcher &matcher, const std::vector< double > &centroidSideB)