1#ifndef MESHINTERFACE_def_hpp
2#define MESHINTERFACE_def_hpp
16std::vector<T> sort_from_ref(
17 std::vector<T>
const& in,
18 std::vector<int>
const& reference
20 std::vector<T> ret(in.size());
22 int const size = in.size();
23 for (
int i = 0; i < size; ++i)
24 ret[i] = in[reference[i]];
30std::vector<T> sort_from_ref(
31 std::vector<T>
const& in,
32 std::vector<long long>
const& reference
34 std::vector<T> ret(in.size());
36 int const size = in.size();
37 for (
long long i = 0; i < size; ++i)
38 ret[i] = in[reference[i]];
45template <
class SC,
class LO,
class GO,
class NO>
46MeshInterface<SC,LO,GO,NO>::MeshInterface():
47indicesGlobalMatched_(),
48indicesGlobalMatchedOrigin_(),
49indicesGlobalMatchedUnique_(),
51partialCouplingFlag_(0),
52partialCouplingType_(0),
58template <
class SC,
class LO,
class GO,
class NO>
59MeshInterface<SC,LO,GO,NO>::MeshInterface(CommConstPtr_Type comm):
60indicesGlobalMatched_(),
61indicesGlobalMatchedOrigin_(),
62indicesGlobalMatchedUnique_(),
64partialCouplingFlag_(0),
65partialCouplingType_(0),
71template <
class SC,
class LO,
class GO,
class NO>
72void MeshInterface<SC,LO,GO,NO>::partitionMeshInterface(MapPtr_Type mapRepeated, MapPtr_Type mapUnique){
75 vec3D_GO_ptr_Type indicesSerial = indicesGlobalMatchedOrigin_;
78 indicesGlobalMatched_.reset(
new vec3D_GO_Type ( indicesSerial->size() , vec2D_GO_Type( 2 , vec_GO_Type(0) ) ) );
81 indicesGlobalMatchedUnique_.reset(
new vec3D_GO_Type ( indicesSerial->size() , vec2D_GO_Type( 2 , vec_GO_Type(0) ) ) );
83 for (
int flag=0; flag<indicesSerial->size(); flag++) {
84 for (
int i=0; i<indicesSerial->at(flag).at(0).size(); i++) {
86 GO indexThis = mapRepeated->getLocalElement( indicesSerial->at(flag).at(0).at(i) );
87 if ( indexThis != Teuchos::OrdinalTraits<LO>::invalid() ) {
88 indicesGlobalMatched_->at(flag).at(0).push_back( indicesSerial->at(flag).at(0).at(i) );
89 indicesGlobalMatched_->at(flag).at(1).push_back( indicesSerial->at(flag).at(1).at(i) );
92 GO indexThisUni = mapUnique->getLocalElement( indicesSerial->at(flag).at(0).at(i) );
94 if ( indexThisUni != Teuchos::OrdinalTraits<LO>::invalid() ) {
95 indicesGlobalMatchedUnique_->at(flag).at(0).push_back( indicesSerial->at(flag).at(0).at(i) );
96 indicesGlobalMatchedUnique_->at(flag).at(1).push_back( indicesSerial->at(flag).at(1).at(i) );
102 isPartitioned_ =
true;
106template <
class SC,
class LO,
class GO,
class NO>
107void MeshInterface<SC,LO,GO,NO>::determineInterface( vec2D_dbl_ptr_Type pointsRepThis, vec2D_dbl_ptr_Type pointsRepOther, vec_int_ptr_Type flagThis, vec_int_ptr_Type flagOther, vec_int_Type relevant_flag_vec ){
109 indicesGlobalMatched_.reset(
new vec3D_GO_Type( relevant_flag_vec.size(), vec2D_GO_Type(2) ) );
112 indicesGlobalMatchedOrigin_.reset(
new vec3D_GO_Type( relevant_flag_vec.size(), vec2D_GO_Type(2) ) );
115 for (
int flag=0; flag<relevant_flag_vec.size(); flag++) {
116 vec2D_dbl_Type pointThis(0);
117 vec2D_dbl_Type pointOther(0);
118 vec_GO_Type indexGlobalThis(0);
119 vec_GO_Type indexGlobalOther(0);
120 vec_int_Type indexThis(0);
121 vec_int_Type indexOther(0);
123 for (
int i=0; i<pointsRepThis->size(); i++) {
124 if (flagThis->at(i) == relevant_flag_vec.at(flag)) {
125 pointThis.push_back( pointsRepThis->at(i) );
126 indexGlobalThis.push_back(i);
127 indexThis.push_back(counter);
132 for (
int i=0; i<pointsRepOther->size(); i++) {
133 if (flagOther->at(i) == relevant_flag_vec.at(flag)) {
134 pointOther.push_back( pointsRepOther->at(i) );
135 indexGlobalOther.push_back(i);
136 indexOther.push_back(counter);
143 sort(indexThis.begin(), indexThis.end(),
144 [&](
const int& a,
const int& b) {
145 return pointThis[a] < pointThis[b];
149 sort(indexOther.begin(), indexOther.end(),
150 [&](
const int& a,
const int& b) {
151 return pointOther[a] < pointOther[b];
155 indexGlobalThis = sort_from_ref(indexGlobalThis, indexThis);
156 indexGlobalOther = sort_from_ref(indexGlobalOther, indexOther);
158 TEUCHOS_TEST_FOR_EXCEPTION( indexGlobalThis.size()!=indexGlobalOther.size(), std::logic_error,
"Interfaces do not have the same length!");
161 indicesGlobalMatched_->at(flag).at(0) = indexGlobalThis;
162 indicesGlobalMatched_->at(flag).at(1) = indexGlobalOther;
164 indicesGlobalMatchedOrigin_->at(flag).at(0) = indexGlobalThis;
165 indicesGlobalMatchedOrigin_->at(flag).at(1) = indexGlobalOther;
171template <
class SC,
class LO,
class GO,
class NO>
172int MeshInterface<SC,LO,GO,NO>::isPartialCouplingFlag(
int flag){
174 auto it = std::find( partialCouplingFlag_.begin(), partialCouplingFlag_.end(), flag );
175 if ( it!=partialCouplingFlag_.end() )
176 return std::distance( partialCouplingFlag_.begin(), it );
181template <
class SC,
class LO,
class GO,
class NO>
182void MeshInterface<SC,LO,GO,NO>::setPartialCoupling(
int flag, std::string type){
183 partialCouplingFlag_.push_back(flag);
184 partialCouplingType_.push_back(type);
188template <
class SC,
class LO,
class GO,
class NO>
189int MeshInterface<SC,LO,GO,NO>::getPartialCouplingFlag(
int i){
190 TEUCHOS_TEST_FOR_EXCEPTION(sizePartialCoupling()-1 < i, std::runtime_error,
"There is no partial coupling for this index");
191 return partialCouplingFlag_[i];
194template <
class SC,
class LO,
class GO,
class NO>
195std::string MeshInterface<SC,LO,GO,NO>::getPartialCouplingType(
int i){
196 TEUCHOS_TEST_FOR_EXCEPTION(sizePartialCoupling()-1 < i, std::runtime_error,
"There is no partial coupling for this index");
197 return partialCouplingType_[i];
200template <
class SC,
class LO,
class GO,
class NO>
201int MeshInterface<SC,LO,GO,NO>::sizePartialCoupling(){
202 return partialCouplingFlag_.size();
205template <
class SC,
class LO,
class GO,
class NO>
206void MeshInterface<SC,LO,GO,NO>::determineInterfaceParallelAndDistance( vec2D_dbl_ptr_Type pointsUniThis, vec2D_dbl_ptr_Type pointsUniOther, vec_int_ptr_Type flagUniThis, vec_int_ptr_Type flagUniOther, vec_int_Type relevant_flag_vec, MapConstPtr_Type mapUniThis, MapConstPtr_Type mapUniOther, vec_dbl_ptr_Type &distancesToInterface, vec2D_dbl_ptr_Type pointsRepThis,
int dim ) {
208 SC eps100 = 100. * Teuchos::ScalarTraits<SC>::eps();
209 GO invalid = Teuchos::OrdinalTraits<GO>::invalid();
211 indicesGlobalMatched_.reset(
new vec3D_GO_Type( relevant_flag_vec.size(), vec2D_GO_Type(2) ) );
216 indicesGlobalMatchedOrigin_.reset(
new vec3D_GO_Type( relevant_flag_vec.size(), vec2D_GO_Type(2) ) );
219 for (
int flagIndex=0; flagIndex<relevant_flag_vec.size(); flagIndex++) {
220 int flag = relevant_flag_vec[flagIndex];
222 vec_GO_Type indexGlobalCommThis(0);
223 vec_GO_Type indexGlobalCommOther(0);
225 for (
int i=0; i<pointsUniThis->size(); i++) {
226 if ( flagUniThis->at(i) == flag ) {
227 indexGlobalCommThis.push_back( mapUniThis->getGlobalElement( i ) );
231 for (
int i=0; i<pointsUniOther->size(); i++) {
232 if ( flagUniOther->at(i) == flag ) {
233 indexGlobalCommOther.push_back( mapUniOther->getGlobalElement( i ) );
239 GO numInterfaceGlobalThis = 0;
240 GO numInterfaceGlobalOther = 0;
242 Teuchos::reduceAll( *this->comm_, Teuchos::REDUCE_SUM, (GO) indexGlobalCommThis.size(), Teuchos::ptrFromRef( numInterfaceGlobalThis ) );
244 Teuchos::reduceAll( *this->comm_, Teuchos::REDUCE_SUM, (GO) indexGlobalCommOther.size(), Teuchos::ptrFromRef( numInterfaceGlobalOther ) );
246 MapPtr_Type mapThis = Teuchos::rcp(
new Map_Type( -1, Teuchos::arrayViewFromVector( indexGlobalCommThis ), 0, this->comm_ ) );
248 MapPtr_Type mapOther = Teuchos::rcp(
new Map_Type( -1, Teuchos::arrayViewFromVector( indexGlobalCommOther ), 0, this->comm_ ) );
252 TEUCHOS_TEST_FOR_EXCEPTION( numInterfaceGlobalThis != numInterfaceGlobalOther, std::runtime_error,
"DetermineInterfaceInParallel failed. ThisMesh and OtherMesh seem to have different numbers of interface nodes." );
254 std::vector<GO> gatherAllIndices(numInterfaceGlobalThis);
255 std::iota ( std::begin( gatherAllIndices ), std::end( gatherAllIndices ), 0 );
257 MapPtr_Type linearMapThis = Teuchos::rcp(
new Map_Type( numInterfaceGlobalThis, indexGlobalCommThis.size(), 0, this->comm_ ) );
258 MapPtr_Type linearMapOther = Teuchos::rcp(
new Map_Type(numInterfaceGlobalThis, indexGlobalCommOther.size(), 0, this->comm_ ) );
259 MapPtr_Type gatherAllMap = Teuchos::rcp(
new Map_Type( invalid, Teuchos::arrayViewFromVector( gatherAllIndices ), 0, this->comm_ ) );
263 vec_int_Type localSizeThis( this->comm_->getSize(),0 );
264 vec_int_Type localSizeOther( this->comm_->getSize(),0 );
267 int sizeThis = indexGlobalCommThis.size();
268 int sizeOther = indexGlobalCommOther.size();
269 Teuchos::gather<int, int>( &sizeThis, 1, &localSizeThis[0], 1, root, *this->comm_ );
270 Teuchos::gather<int, int>( &sizeOther, 1, &localSizeOther[0], 1, root, *this->comm_ );
273 if (indexGlobalCommThis.size()>0)
274 sendThis = &indexGlobalCommThis[0];
275 GO* sendOther = NULL;
276 if (indexGlobalCommOther.size()>0)
277 sendOther = &indexGlobalCommOther[0];
279 vec_GO_Type gatheredThis( numInterfaceGlobalThis , -1);
280 vec_GO_Type gatheredOther( numInterfaceGlobalThis, -1);
282 vec_int_Type displacementsThis( ((
int) this->comm_->getRank()==root ) * this->comm_->getSize(),0 );
283 vec_int_Type displacementsOther( ((
int) this->comm_->getRank()==root ) * this->comm_->getSize(),0 );
284 int* displThis = NULL;
285 if (displacementsThis.size()>0)
286 displThis = &displacementsThis[0];
287 int* displOther = NULL;
288 if (displacementsOther.size()>0)
289 displOther = &displacementsOther[0];
291 for (
int i=1; i<displacementsThis.size(); i++)
292 displacementsThis[i] = displacementsThis[i-1] + localSizeThis[i-1];
293 for (
int i=1; i<displacementsOther.size(); i++)
294 displacementsOther[i] = displacementsOther[i-1] + localSizeOther[i-1];
296 Teuchos::gatherv<int,GO>( sendThis, indexGlobalCommThis.size(), &gatheredThis[0], &localSizeThis[0], displThis, root, *this->comm_ );
297 Teuchos::gatherv<int,GO>( sendOther, indexGlobalCommOther.size(), &gatheredOther[0], &localSizeOther[0], displOther, root, *this->comm_ );
300 Teuchos::broadcast<int,GO>( *this->comm_, root, Teuchos::arrayViewFromVector( gatheredThis ) );
301 Teuchos::broadcast<int,GO>( *this->comm_, root, Teuchos::arrayViewFromVector( gatheredOther ) );
303 MapPtr_Type mapAllThis = Teuchos::rcp(
new Map_Type(invalid, Teuchos::arrayViewFromVector( gatheredThis ), 0, this->comm_ ) );
304 MapPtr_Type mapAllOther = Teuchos::rcp(
new Map_Type( invalid, Teuchos::arrayViewFromVector( gatheredOther ), 0, this->comm_ ) );
306 bool meshOnRank =
false;
307 if (pointsUniThis->size() > 0)
310 MultiVectorPtr_Type mvLocalThis;
311 MultiVectorPtr_Type mvLocalOther;
313 mvLocalThis = Teuchos::rcp(
new MultiVector_Type( mapThis, dim + 1 ) );
314 mvLocalOther = Teuchos::rcp(
new MultiVector_Type( mapOther, dim + 1 ) );
318 for (
int j=0; j<dim; j++) {
319 Teuchos::ArrayRCP< SC > data = mvLocalThis->getDataNonConst(j);
320 for (
int i=0; i<data.size(); i++) {
321 LO index = mapUniThis->getLocalElement( indexGlobalCommThis[i] );
322 data[i] = pointsUniThis->at( index )[j];
326 Teuchos::ArrayRCP< SC > dataThis = mvLocalThis->getDataNonConst( dim );
327 for (
int i=0; i<dataThis.size(); i++)
328 dataThis[i] = indexGlobalCommThis[i];
332 for (
int j=0; j<dim; j++) {
333 Teuchos::ArrayRCP< SC > data = mvLocalOther->getDataNonConst(j);
334 for (
int i=0; i<data.size(); i++) {
335 LO index = mapUniOther->getLocalElement( indexGlobalCommOther[i] );
336 data[i] = pointsUniOther->at( index )[j];
340 Teuchos::ArrayRCP< SC > dataOther = mvLocalOther->getDataNonConst( dim );
341 for (
int i=0; i<dataOther.size(); i++)
342 dataOther[i] = indexGlobalCommOther[i];
345 MultiVectorPtr_Type mvGlobalThis;
346 MultiVectorPtr_Type mvGlobalOther;
348 mvGlobalThis = Teuchos::rcp(
new MultiVector_Type( mapAllThis, dim + 1 ) );
349 mvGlobalOther = Teuchos::rcp(
new MultiVector_Type( mapAllOther, dim + 1 ) );
351 mvGlobalThis->exportFromVector( mvLocalThis,
true,
"Insert",
"Reverse" );
352 mvGlobalOther->exportFromVector( mvLocalOther,
true,
"Insert",
"Reverse" );
358 vec_int_Type indexThis( numInterfaceGlobalThis );
359 vec_int_Type indexOther( numInterfaceGlobalThis );
360 std::iota ( std::begin( indexThis ), std::end( indexThis ), 0 );
361 std::iota ( std::begin( indexOther ), std::end( indexOther ), 0 );
363 vec2D_dbl_Type pointThis( numInterfaceGlobalThis, vec_dbl_Type(dim) );
364 vec2D_dbl_Type pointOther( numInterfaceGlobalThis, vec_dbl_Type(dim) );
366 vec_GO_Type indexGlobalThis( numInterfaceGlobalThis );
367 vec_GO_Type indexGlobalOther( numInterfaceGlobalThis );
372 Teuchos::ArrayRCP< const SC > dataX = mvGlobalThis->getData(0);
373 Teuchos::ArrayRCP< const SC > dataY = mvGlobalThis->getData(1);
374 Teuchos::ArrayRCP< const SC > dataZ;
375 Teuchos::ArrayRCP< const SC > dataGlob;
377 dataZ = mvGlobalThis->getData(2);
378 dataGlob = mvGlobalThis->getData(dim);
381 dataGlob = mvGlobalThis->getData(dim);
383 for (
int i=0; i<pointThis.size(); i++) {
384 pointThis[i][0] = dataX[i];
385 pointThis[i][1] = dataY[i];
387 pointThis[i][2] = dataZ[i];
388 indexGlobalThis[i] = (GO) dataGlob[i] + eps100;
392 Teuchos::ArrayRCP< const SC > dataX = mvGlobalOther->getData(0);
393 Teuchos::ArrayRCP< const SC > dataY = mvGlobalOther->getData(1);
394 Teuchos::ArrayRCP< const SC > dataZ;
395 Teuchos::ArrayRCP< const SC > dataGlob;
397 dataZ = mvGlobalOther->getData(2);
398 dataGlob = mvGlobalOther->getData(dim);
401 dataGlob = mvGlobalOther->getData(dim);
403 for (
int i=0; i<pointOther.size(); i++) {
404 pointOther[i][0] = dataX[i];
405 pointOther[i][1] = dataY[i];
407 pointOther[i][2] = dataZ[i];
408 indexGlobalOther[i] = (GO) dataGlob[i] + eps100;
413 sort(indexThis.begin(), indexThis.end(),
414 [&](
const int& a,
const int& b) {
415 return pointThis[a] < pointThis[b];
419 sort(indexOther.begin(), indexOther.end(),
420 [&](
const int& a,
const int& b) {
421 return pointOther[a] < pointOther[b];
425 indexGlobalThis = sort_from_ref(indexGlobalThis, indexThis);
426 indexGlobalOther = sort_from_ref(indexGlobalOther, indexOther);
429 indicesGlobalMatched_->at(flagIndex).at(0) = indexGlobalThis;
430 indicesGlobalMatched_->at(flagIndex).at(1) = indexGlobalOther;
433 indicesGlobalMatchedOrigin_->at(flagIndex).at(0) = indexGlobalThis;
434 indicesGlobalMatchedOrigin_->at(flagIndex).at(1) = indexGlobalOther;
437 calculateDistancesToInterfaceParallel( distancesToInterface, pointThis, pointsRepThis );
442template <
class SC,
class LO,
class GO,
class NO>
443void MeshInterface<SC,LO,GO,NO>::calculateDistancesToInterfaceParallel( vec_dbl_ptr_Type &distancesToInterface, vec2D_dbl_Type &pointThis, vec2D_dbl_ptr_Type sourceNodesRep )
447 if (pointThis.size() > 0)
448 dim = pointThis[0].size();
454 vec3D_GO_ptr_Type indicesGlobalMatched = this->indicesGlobalMatched_;
463 int numberInterfaceNodes = indicesGlobalMatched->at(0).at(0).size();
466 vec2D_dbl_ptr_Type endNodesRep = Teuchos::rcpFromRef(pointThis);
471 if ( distancesToInterface.is_null() )
472 distancesToInterface = Teuchos::rcp(
new vec_dbl_Type( sourceNodesRep->size(), 1000.0 ) );
475 double distance = 0.0;
476 for(
int i = 0; i < sourceNodesRep->size(); i++)
478 for(
int j = 0; j < endNodesRep->size(); j++)
480 for(
int k = 0; k < dim; k++)
482 distance = distance + std::pow( sourceNodesRep->at(i).at(k) - endNodesRep->at(j).at(k), 2.0 );
486 distance = std::sqrt(distance);
488 if(distancesToInterface->at(i) > distance)
489 distancesToInterface->at(i) = distance;
498template <
class SC,
class LO,
class GO,
class NO>
499void MeshInterface<SC,LO,GO,NO>::buildFromOtherInterface( Teuchos::RCP<MeshInterface> otherMeshInterface){
501 TEUCHOS_TEST_FOR_EXCEPTION( otherMeshInterface->indicesGlobalMatched_->size()<=0, std::logic_error,
"MeshInterface given is empty.");
502 TEUCHOS_TEST_FOR_EXCEPTION( otherMeshInterface->indicesGlobalMatched_->at(0).size()<=0, std::logic_error,
"MeshInterface given is empty.");
503 TEUCHOS_TEST_FOR_EXCEPTION( otherMeshInterface->isPartitioned_, std::logic_error,
"Other MeshInterface already partitioned.");
504 TEUCHOS_TEST_FOR_EXCEPTION( isPartitioned_, std::logic_error,
"This MeshInterface already partitioned.");
506 indicesGlobalMatched_.reset(
new vec3D_GO_Type( otherMeshInterface->indicesGlobalMatched_->size(), vec2D_GO_Type ( 2 , vec_GO_Type( 0 ) ) ) );
508 indicesGlobalMatchedOrigin_.reset(
new vec3D_GO_Type( otherMeshInterface->indicesGlobalMatchedOrigin_->size(), vec2D_GO_Type ( 2 , vec_GO_Type( 0 ) ) ) );
510 for (
int i=0; i<otherMeshInterface->indicesGlobalMatched_->size(); i++) {
511 indicesGlobalMatched_->at(i).at(0).resize( otherMeshInterface->indicesGlobalMatched_->at(i).at(0).size() );
512 indicesGlobalMatched_->at(i).at(1).resize( otherMeshInterface->indicesGlobalMatched_->at(i).at(1).size() );
513 indicesGlobalMatchedOrigin_->at(i).at(0).resize( otherMeshInterface->indicesGlobalMatchedOrigin_->at(i).at(0).size() );
514 indicesGlobalMatchedOrigin_->at(i).at(1).resize( otherMeshInterface->indicesGlobalMatchedOrigin_->at(i).at(1).size() );
515 for (
int j=0; j<otherMeshInterface->indicesGlobalMatched_->at(i).at(0).size(); j++) {
516 indicesGlobalMatched_->at(i).at(0).at(j) = otherMeshInterface->indicesGlobalMatched_->at(i).at(1).at(j);
517 indicesGlobalMatched_->at(i).at(1).at(j) = otherMeshInterface->indicesGlobalMatched_->at(i).at(0).at(j);
519 indicesGlobalMatchedOrigin_->at(i).at(0).at(j) = otherMeshInterface->indicesGlobalMatchedOrigin_->at(i).at(1).at(j);
520 indicesGlobalMatchedOrigin_->at(i).at(1).at(j) = otherMeshInterface->indicesGlobalMatchedOrigin_->at(i).at(0).at(j);
526template <
class SC,
class LO,
class GO,
class NO>
527void MeshInterface<SC,LO,GO,NO>::print(CommConstPtr_Type comm){
529 for (
int i=0; i<indicesGlobalMatched_->size(); i++) {
530 for (
int j=0; j<indicesGlobalMatched_->at(i).at(0).size(); j++) {
531 std::cout << comm->getRank()<<
" Matched IDs for flag " << i <<
" :" << indicesGlobalMatched_->at(i).at(0).at(j) <<
" - " << indicesGlobalMatched_->at(i).at(0).at(j) << std::endl;
536template <
class SC,
class LO,
class GO,
class NO>
537typename MeshInterface<SC,LO,GO,NO>::vec3D_GO_ptr_Type MeshInterface<SC,LO,GO,NO>::getIndicesGlobalMatched(){
538 return indicesGlobalMatched_;
541template <
class SC,
class LO,
class GO,
class NO>
542typename MeshInterface<SC,LO,GO,NO>::vec3D_GO_ptr_Type MeshInterface<SC,LO,GO,NO>::getIndicesGlobalMatchedOrigin()
544 return indicesGlobalMatchedOrigin_;
547template <
class SC,
class LO,
class GO,
class NO>
548typename MeshInterface<SC,LO,GO,NO>::vec3D_GO_ptr_Type MeshInterface<SC,LO,GO,NO>::getIndicesGlobalMatchedUnique()
550 return indicesGlobalMatchedUnique_;
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement_decl.hpp:36