13 #include <stk_mesh/base/GetEntities.hpp>
14 #include <stk_mesh/base/GetBuckets.hpp>
15 #include <stk_mesh/base/FieldBase.hpp>
18 #include "Tpetra_Map.hpp"
19 #include "Tpetra_Import.hpp"
20 #include "Tpetra_Vector.hpp"
22 #include "Teuchos_FancyOStream.hpp"
24 #ifdef PANZER_HAVE_STKSEARCH
25 namespace panzer_stk {
27 namespace periodic_helpers {
29 void fillLocalSearchVector(
const STK_Interface & mesh, SphereIdVector & searchVector,
const double & error,
30 const std::string & sideName,
const std::string & type_,
const bool & getGhostedIDs)
38 std::vector<std::string> matchedSides;
39 std::vector<SearchId> potentialIDsToRemap;
41 fillLocalSearchVector(mesh,searchVector,error,sideName,type_,getGhostedIDs,matchedSides,potentialIDsToRemap);
47 void fillLocalSearchVector(
const STK_Interface & mesh, SphereIdVector & searchVector,
const double & error,
48 const std::string & sideName,
const std::string & type_,
const bool & getGhostedIDs,
49 const std::vector<std::string> & matchedSides, std::vector<SearchId> & potentialIDsToRemap)
51 unsigned physicalDim = mesh.getDimension();
56 const unsigned parallelRank = bulkData->parallel_rank();
61 ss <<
"Can't find a sideset named \"" << sideName <<
"\" in the mesh" << std::endl;
62 stk::mesh::Part * side = metaData->get_part(sideName,ss.str().c_str());
65 stk::mesh::Selector mySides = getGhostedIDs ?
66 (*side) & (metaData->locally_owned_part() | metaData->globally_shared_part()) :
67 (*side) & metaData->locally_owned_part();
69 stk::mesh::EntityRank rank;
73 stk::mesh::EntityId offset = 0;
75 rank = mesh.getNodeRank();
76 field = & mesh.getCoordinatesField();
78 }
else if(type_ ==
"edge"){
79 rank = mesh.getEdgeRank();
80 field = & mesh.getEdgesField();
81 offset = mesh.getMaxEntityId(mesh.getNodeRank());
82 }
else if(type_ ==
"face"){
83 rank = mesh.getFaceRank();
84 field = & mesh.getFacesField();
85 offset = mesh.getMaxEntityId(mesh.getNodeRank())+mesh.getMaxEntityId(mesh.getEdgeRank());
87 ss <<
"Can't do BCs of type " << type_ << std::endl;
93 stk::mesh::Selector intersection;
95 if (matchedSides.size()>0) {
96 for (
size_t j=0; j<matchedSides.size(); ++j) {
97 auto previouslyMatched = matchedSides[j];
99 intersection = intersection | (mySides & *(metaData->get_part(previouslyMatched)));
102 mySides = mySides - intersection;
106 std::vector<stk::mesh::Bucket*>
const& entityBuckets =
107 bulkData->get_buckets(rank, mySides);
111 for(
size_t b=0;b<entityBuckets.size();b++) {
112 stk::mesh::Bucket & bucket = *entityBuckets[b];
113 double const* array = stk::mesh::field_data(*field, bucket);
116 for(
size_t n=0;n<bucket.size();n++) {
120 for(
size_t d=0;d<physicalDim;d++)
121 coord[d] = array[physicalDim*n + d];
125 for(
size_t d=physicalDim;d<3;d++)
131 stk::search::Point<double> center(coord[0],coord[1],coord[2]);
132 stk::mesh::EntityKey trueKey = bulkData->entity_key(bucket[n]);
133 stk::mesh::EntityKey shiftedKey(trueKey.rank(), trueKey.id()+offset);
134 SearchId search_id(shiftedKey, parallelRank);
136 searchVector.emplace_back( Sphere(center, error), search_id);
143 if (matchedSides.size()>0) {
146 mySides = getGhostedIDs ?
147 (*side) & (metaData->locally_owned_part() | metaData->globally_shared_part()) :
148 (*side) & metaData->locally_owned_part();
150 std::vector<stk::mesh::Bucket*>
const & intersectionEntityBuckets =
151 bulkData->get_buckets(rank, mySides & intersection);
155 for(
size_t b=0;b<intersectionEntityBuckets.size();b++) {
156 stk::mesh::Bucket & bucket = *intersectionEntityBuckets[b];
158 for(
size_t n=0;n<bucket.size();n++) {
159 stk::mesh::EntityKey trueKey = bulkData->entity_key(bucket[n]);
160 stk::mesh::EntityKey shiftedKey(trueKey.rank(), trueKey.id()+offset);
161 potentialIDsToRemap.emplace_back(shiftedKey, parallelRank);
169 const std::vector<double> computeGlobalCentroid(
const STK_Interface & mesh,
const std::string & sideName)
172 unsigned physicalDim = mesh.getDimension();
179 std::stringstream ss;
180 ss <<
"Can't find part=\"" << sideName <<
"\"" << std::endl;
181 stk::mesh::Part * side = metaData->get_part(sideName,ss.str().c_str());
182 stk::mesh::Selector mySides = (*side) & metaData->locally_owned_part();
185 std::vector<stk::mesh::Bucket*>
const& entityBuckets =
186 bulkData->get_buckets(mesh.getNodeRank(), mySides);
189 double localCentroid[3] = {0.,0.,0.};
190 int localNodeCount = 0;
191 for(
size_t b=0;b<entityBuckets.size();b++) {
192 stk::mesh::Bucket & bucket = *entityBuckets[b];
193 double const* array = stk::mesh::field_data(mesh.getCoordinatesField(), bucket);
196 for(
size_t n=0;n<bucket.size();n++) {
200 for(
size_t d=0;d<physicalDim;d++)
201 localCentroid[d] += array[physicalDim*n + d];
205 int globalNodeCount = 0;
207 auto comm = mesh.getComm();
209 double globalCentroid[3] = { };
214 std::vector<double>
result = {0.,0.,0.};
215 for (
size_t d=0;d<physicalDim;d++)
216 result[d] = globalCentroid[d]/globalNodeCount;
221 void updateMapping(
Teuchos::RCP<std::vector<std::pair<size_t,size_t> > > & currentMatches,
222 const std::vector<std::pair<size_t,size_t> > & previousMatches,
223 const std::vector<SearchId> & IDsToRemap,
const STK_Interface & mesh)
226 using LO = panzer::LocalOrdinal;
227 using GO = panzer::GlobalOrdinal;
229 using Map = Tpetra::Map<LO,GO,NODE>;
230 using Importer = Tpetra::Import<LO,GO,NODE>;
232 auto comm = mesh.getComm();
238 std::map<size_t,size_t> myPreviousAtoB,myCurrentAtoB;
239 std::map<size_t,std::vector<size_t> > myPreviousBtoA;
240 for (
size_t i=0;i<previousMatches.size();++i) {
241 myPreviousAtoB[previousMatches[i].first] = previousMatches[i].second;
243 myPreviousBtoA[previousMatches[i].second].push_back(previousMatches[i].first);
245 for (
size_t i=0;i<currentMatches->size();++i)
246 myCurrentAtoB[(*currentMatches)[i].first] = (*currentMatches)[i].second;
250 std::vector<GO> requestedAIDs;
252 for (
auto &
id : IDsToRemap)
253 requestedAIDs.push_back(myPreviousAtoB[
id.
id().
id()]);
256 std::set<GO> uniqueAIDs(requestedAIDs.begin(),requestedAIDs.end());
257 requestedAIDs = std::vector<GO>(uniqueAIDs.begin(),uniqueAIDs.end());
260 std::vector<GO> newAIDs(currentMatches->size());
262 for (
size_t i=0;i<currentMatches->size();++i) {
263 newAIDs[i] = (*currentMatches)[i].first;
271 if (!testMap->isOneToOne()){
272 newAIDsMap = Tpetra::createOneToOne<LO,GO,NODE>(testMap);
274 newAIDsMap = testMap;
279 Importer importer(newAIDsMap,requestedAIDsMap);
282 Tpetra::Vector<GO,LO,GO,NODE> newBIDs(newAIDsMap);
283 auto newBIDsHost = newBIDs.getLocalViewHost(Tpetra::Access::OverwriteAll);
284 auto myGIDs = newAIDsMap->getMyGlobalIndices();
285 for (
size_t i=0;i<myGIDs.size();++i)
286 newBIDsHost(i,0) = myCurrentAtoB[myGIDs[i]];
288 Tpetra::Vector<GO,LO,GO,NODE> requestedBIDs(requestedAIDsMap);
289 requestedBIDs.doImport(newBIDs,importer,Tpetra::INSERT);
290 auto requestedBIDsHost = requestedBIDs.getLocalViewHost(Tpetra::Access::ReadOnly);
297 for (
const auto &
id : requestedAIDs) {
299 for (
const auto & idToUpdate : myPreviousBtoA[
id])
301 myPreviousAtoB[idToUpdate] = requestedBIDsHost(ind,0);
307 for (
const auto & AB : previousMatches) {
311 (*currentMatches).emplace_back(std::pair<size_t,size_t>(
id,myPreviousAtoB[
id]));
317 void appendMapping(
Teuchos::RCP<std::vector<std::pair<size_t,size_t> > > & currentMatches,
318 const std::vector<std::pair<size_t,size_t> > & previousMatches)
321 for (
const auto & AB : previousMatches)
322 (*currentMatches).push_back(AB);
stk::mesh::Field< double > VectorFieldType
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
PHX::MDField< ScalarT, panzer::Cell, panzer::IP > result
A field that will be used to build up the result of the integral we're performing.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
PHX::MDField< ScalarT, panzer::Cell, panzer::BASIS > field
A field to which we'll contribute, or in which we'll store, the result of computing this integral...
#define TEUCHOS_ASSERT(assertion_test)
Tpetra::KokkosCompat::KokkosDeviceWrapperNode< PHX::Device > TpetraNodeType