45 #include <stk_mesh/base/GetEntities.hpp>
46 #include <stk_mesh/base/GetBuckets.hpp>
47 #include <stk_mesh/base/FieldBase.hpp>
50 #include "Tpetra_Map.hpp"
51 #include "Tpetra_Import.hpp"
52 #include "Tpetra_Vector.hpp"
54 #include "Teuchos_FancyOStream.hpp"
56 #ifdef PANZER_HAVE_STKSEARCH
57 namespace panzer_stk {
59 namespace periodic_helpers {
61 void fillLocalSearchVector(
const STK_Interface & mesh, SphereIdVector & searchVector,
const double & error,
62 const std::string & sideName,
const std::string & type_,
const bool & getGhostedIDs)
70 std::vector<std::string> matchedSides;
71 std::vector<SearchId> potentialIDsToRemap;
73 fillLocalSearchVector(mesh,searchVector,error,sideName,type_,getGhostedIDs,matchedSides,potentialIDsToRemap);
79 void fillLocalSearchVector(
const STK_Interface & mesh, SphereIdVector & searchVector,
const double & error,
80 const std::string & sideName,
const std::string & type_,
const bool & getGhostedIDs,
81 const std::vector<std::string> & matchedSides, std::vector<SearchId> & potentialIDsToRemap)
83 unsigned physicalDim = mesh.getDimension();
88 const unsigned parallelRank = bulkData->parallel_rank();
93 ss <<
"Can't find a sideset named \"" << sideName <<
"\" in the mesh" << std::endl;
94 stk::mesh::Part * side = metaData->get_part(sideName,ss.str().c_str());
97 stk::mesh::Selector mySides = getGhostedIDs ?
98 (*side) & (metaData->locally_owned_part() | metaData->globally_shared_part()) :
99 (*side) & metaData->locally_owned_part();
101 stk::mesh::EntityRank rank;
105 stk::mesh::EntityId offset = 0;
106 if(type_ ==
"coord"){
107 rank = mesh.getNodeRank();
108 field = & mesh.getCoordinatesField();
110 }
else if(type_ ==
"edge"){
111 rank = mesh.getEdgeRank();
112 field = & mesh.getEdgesField();
113 offset = mesh.getMaxEntityId(mesh.getNodeRank());
114 }
else if(type_ ==
"face"){
115 rank = mesh.getFaceRank();
116 field = & mesh.getFacesField();
117 offset = mesh.getMaxEntityId(mesh.getNodeRank())+mesh.getMaxEntityId(mesh.getEdgeRank());
119 ss <<
"Can't do BCs of type " << type_ << std::endl;
125 stk::mesh::Selector intersection;
127 if (matchedSides.size()>0) {
128 for (
size_t j=0; j<matchedSides.size(); ++j) {
129 auto previouslyMatched = matchedSides[j];
131 intersection = intersection | (mySides & *(metaData->get_part(previouslyMatched)));
134 mySides = mySides - intersection;
138 std::vector<stk::mesh::Bucket*>
const& entityBuckets =
139 bulkData->get_buckets(rank, mySides);
143 for(
size_t b=0;b<entityBuckets.size();b++) {
144 stk::mesh::Bucket & bucket = *entityBuckets[b];
145 double const* array = stk::mesh::field_data(*field, bucket);
148 for(
size_t n=0;n<bucket.size();n++) {
152 for(
size_t d=0;d<physicalDim;d++)
153 coord[d] = array[physicalDim*n + d];
157 for(
size_t d=physicalDim;d<3;d++)
163 stk::search::Point<double> center(coord[0],coord[1],coord[2]);
164 stk::mesh::EntityKey trueKey = bulkData->entity_key(bucket[n]);
165 stk::mesh::EntityKey shiftedKey(trueKey.rank(), trueKey.id()+offset);
166 SearchId search_id(shiftedKey, parallelRank);
168 searchVector.emplace_back( Sphere(center, error), search_id);
175 if (matchedSides.size()>0) {
178 mySides = getGhostedIDs ?
179 (*side) & (metaData->locally_owned_part() | metaData->globally_shared_part()) :
180 (*side) & metaData->locally_owned_part();
182 std::vector<stk::mesh::Bucket*>
const & intersectionEntityBuckets =
183 bulkData->get_buckets(rank, mySides & intersection);
187 for(
size_t b=0;b<intersectionEntityBuckets.size();b++) {
188 stk::mesh::Bucket & bucket = *intersectionEntityBuckets[b];
190 for(
size_t n=0;n<bucket.size();n++) {
191 stk::mesh::EntityKey trueKey = bulkData->entity_key(bucket[n]);
192 stk::mesh::EntityKey shiftedKey(trueKey.rank(), trueKey.id()+offset);
193 potentialIDsToRemap.emplace_back(shiftedKey, parallelRank);
201 const std::vector<double> computeGlobalCentroid(
const STK_Interface & mesh,
const std::string & sideName)
204 unsigned physicalDim = mesh.getDimension();
211 std::stringstream ss;
212 ss <<
"Can't find part=\"" << sideName <<
"\"" << std::endl;
213 stk::mesh::Part * side = metaData->get_part(sideName,ss.str().c_str());
214 stk::mesh::Selector mySides = (*side) & metaData->locally_owned_part();
217 std::vector<stk::mesh::Bucket*>
const& entityBuckets =
218 bulkData->get_buckets(mesh.getNodeRank(), mySides);
221 double localCentroid[3] = {0.,0.,0.};
222 int localNodeCount = 0;
223 for(
size_t b=0;b<entityBuckets.size();b++) {
224 stk::mesh::Bucket & bucket = *entityBuckets[b];
225 double const* array = stk::mesh::field_data(mesh.getCoordinatesField(), bucket);
228 for(
size_t n=0;n<bucket.size();n++) {
232 for(
size_t d=0;d<physicalDim;d++)
233 localCentroid[d] += array[physicalDim*n + d];
237 int globalNodeCount = 0;
239 auto comm = mesh.getComm();
241 double globalCentroid[3] = { };
246 std::vector<double>
result = {0.,0.,0.};
247 for (
size_t d=0;d<physicalDim;d++)
248 result[d] = globalCentroid[d]/globalNodeCount;
253 void updateMapping(
Teuchos::RCP<std::vector<std::pair<size_t,size_t> > > & currentMatches,
254 const std::vector<std::pair<size_t,size_t> > & previousMatches,
255 const std::vector<SearchId> & IDsToRemap,
const STK_Interface & mesh)
258 using LO = panzer::LocalOrdinal;
259 using GO = panzer::GlobalOrdinal;
261 using Map = Tpetra::Map<LO,GO,NODE>;
262 using Importer = Tpetra::Import<LO,GO,NODE>;
264 auto comm = mesh.getComm();
270 std::map<size_t,size_t> myPreviousAtoB,myCurrentAtoB;
271 std::map<size_t,std::vector<size_t> > myPreviousBtoA;
272 for (
size_t i=0;i<previousMatches.size();++i) {
273 myPreviousAtoB[previousMatches[i].first] = previousMatches[i].second;
275 myPreviousBtoA[previousMatches[i].second].push_back(previousMatches[i].first);
277 for (
size_t i=0;i<currentMatches->size();++i)
278 myCurrentAtoB[(*currentMatches)[i].first] = (*currentMatches)[i].second;
282 std::vector<GO> requestedAIDs;
284 for (
auto &
id : IDsToRemap)
285 requestedAIDs.push_back(myPreviousAtoB[
id.
id().
id()]);
288 std::set<GO> uniqueAIDs(requestedAIDs.begin(),requestedAIDs.end());
289 requestedAIDs = std::vector<GO>(uniqueAIDs.begin(),uniqueAIDs.end());
292 std::vector<GO> newAIDs(currentMatches->size());
294 for (
size_t i=0;i<currentMatches->size();++i) {
295 newAIDs[i] = (*currentMatches)[i].first;
303 if (!testMap->isOneToOne()){
304 newAIDsMap = Tpetra::createOneToOne<LO,GO,NODE>(testMap);
306 newAIDsMap = testMap;
311 Importer importer(newAIDsMap,requestedAIDsMap);
314 Tpetra::Vector<GO,LO,GO,NODE> newBIDs(newAIDsMap);
315 auto newBIDsHost = newBIDs.getLocalViewHost(Tpetra::Access::OverwriteAll);
316 auto myGIDs = newAIDsMap->getMyGlobalIndices();
317 for (
size_t i=0;i<myGIDs.size();++i)
318 newBIDsHost(i,0) = myCurrentAtoB[myGIDs[i]];
320 Tpetra::Vector<GO,LO,GO,NODE> requestedBIDs(requestedAIDsMap);
321 requestedBIDs.doImport(newBIDs,importer,Tpetra::INSERT);
322 auto requestedBIDsHost = requestedBIDs.getLocalViewHost(Tpetra::Access::ReadOnly);
329 for (
const auto &
id : requestedAIDs) {
331 for (
const auto & idToUpdate : myPreviousBtoA[
id])
333 myPreviousAtoB[idToUpdate] = requestedBIDsHost(ind,0);
339 for (
const auto & AB : previousMatches) {
343 (*currentMatches).emplace_back(std::pair<size_t,size_t>(
id,myPreviousAtoB[
id]));
349 void appendMapping(
Teuchos::RCP<std::vector<std::pair<size_t,size_t> > > & currentMatches,
350 const std::vector<std::pair<size_t,size_t> > & previousMatches)
353 for (
const auto & AB : previousMatches)
354 (*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