Finite Element Domain Decomposition Library
FEDDLib
Loading...
Searching...
No Matches
MeshUnstructured_def.hpp
1#ifndef MESHUNSTRUCTURED_def_hpp
2#define MESHUNSTRUCTURED_def_hpp
3
12
13using Teuchos::reduceAll;
14using Teuchos::REDUCE_SUM;
15using Teuchos::outArg;
16
17namespace FEDD {
18
19template <class SC, class LO, class GO, class NO>
20MeshUnstructured<SC,LO,GO,NO>::MeshUnstructured():
21Mesh<SC,LO,GO,NO>(),
22meshInterface_(),
23volumeID_(10),
24edgeElements_(),
25surfaceEdgeElements_(),
26meshFileName_("fileName.mesh"),
27delimiter_(" ")
28//#ifdef FULL_TIMER
29//,TotalP1ToP2Time_(Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Total P1 to P2")),
30//BuildRedundantInfoTime_ (Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Build Redundant Info")),
31//SortUniqueRedundantInfoTime_ (Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Sort Unique redundant")),
32//CheckingFlaggedAndDeleteTime_ (Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Flagged & Delete Interior")),
33//CheckingFlaggedTime_ (Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Flagged & Delete Interior: Flagged")),
34//DeleteInteriorTime_(Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Flagged & Delete Interior: Interior")),
35//SetGlobalInterfaceIDTime_ (Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Set Global IDs")),
36//SetP2InfoTime_(Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Set P2 Information")),
37//GatherAllMarkedTime_(Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Flagged & Delete Interior: Flagged: Gather All")),
38//UniqueAndFindMarkedTime_(Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Flagged & Delete Interior: Flagged: Unique and MaxAll")),
39//UniqueNewFaceTime_(Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Flagged & Delete Interior: Flagged: Unique new Faces")),
40//SumAllMarkedTime_(Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Flagged & Delete Interior: Flagged: Sum All")),
41//SetP2PointsTime_(Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Set P2 Information: Set Points")),
42//SetP2ElementsTime_(Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Set P2 Information: Set Elements"))
43//#endif
44{
45 edgeElements_ = Teuchos::rcp( new EdgeElements_Type() );
46 surfaceEdgeElements_ = Teuchos::rcp( new Elements_Type() );
47
48}
49
50template <class SC, class LO, class GO, class NO>
51MeshUnstructured<SC,LO,GO,NO>::MeshUnstructured(CommConstPtr_Type comm, int volumeID,std::string meshUnit, bool convertToCM):
52Mesh<SC,LO,GO,NO>(comm),
53meshInterface_(),
54volumeID_(volumeID),
55edgeElements_(),
56surfaceEdgeElements_(),
57meshFileName_("fileName.mesh"),
58delimiter_(" ")
59{
60 edgeElements_ = Teuchos::rcp( new EdgeElements_Type() );
61 surfaceEdgeElements_ = Teuchos::rcp( new Elements_Type() );
62 meshUnitRead_ = meshUnit;
63 meshUnitFinal_ = meshUnit;
64 convertToCM_ = convertToCM;
65}
66
67template <class SC, class LO, class GO, class NO>
68MeshUnstructured<SC,LO,GO,NO>::~MeshUnstructured(){
69}
70
71
72
73template <class SC, class LO, class GO, class NO>
74void MeshUnstructured<SC,LO,GO,NO>::getTriangles(int vertex1ID, int vertex2ID, vec_int_Type &vertices3ID){
75 vertices3ID.resize(2);
76 if (vertex2ID<vertex1ID) {
77 int tmp = vertex2ID;
78 vertex2ID = vertex1ID;
79 vertex1ID = tmp;
80 }
81 if (vertex1ID == 0) {
82 if (vertex2ID == 1) {
83 vertices3ID.at(0) = 2;
84 vertices3ID.at(1) = 3;
85 }
86 else if (vertex2ID == 2) {
87 vertices3ID.at(0) = 1;
88 vertices3ID.at(1) = 3;
89 }
90 else if (vertex2ID == 3) {
91 vertices3ID.at(0) = 1;
92 vertices3ID.at(1) = 2;
93 }
94
95 }
96 else if(vertex1ID == 1){
97 if (vertex2ID == 2) {
98 vertices3ID.at(0) = 0;
99 vertices3ID.at(1) = 3;
100 }
101 else if (vertex2ID == 3) {
102 vertices3ID.at(0) = 0;
103 vertices3ID.at(1) = 2;
104 }
105 }
107 else if(vertex1ID == 2){
108 if (vertex2ID == 3) {
109 vertices3ID.at(0) = 0;
110 vertices3ID.at(1) = 1;
111 }
112 }
113 else {
114#ifdef ASSERTS_WARNINGS
115 MYASSERT(false,"Could not identify triangle.");
116#endif
117 }
118}
119
120template <class SC, class LO, class GO, class NO>
122
123 // If flags of line segments should be used over surface flags, this functions must be checked
124
125 int rank = this->comm_->getRank();
126 this->rankRange_ = meshP1->rankRange_;
127 bool verbose( this->comm_->getRank() == 0 );
128 this->elementMap_ = meshP1->elementMap_;
129 this->edgeMap_ = meshP1->edgeMap_;
130 this->dim_ = meshP1->getDimension();
131 this->FEType_ = "P2";
132 this->numElementsGlob_ = meshP1->numElementsGlob_;
133 this->surfaceTriangleElements_ = meshP1->surfaceTriangleElements_; // for later
134
135 meshP1->assignEdgeFlags(); // Function that determines the flag for each edge. That way the P2 flags can easily be determined
136 GO P1Offset = meshP1->mapUnique_->getMaxAllGlobalIndex()+1;
137 EdgeElementsPtr_Type edgeElements = meshP1->getEdgeElements();
138 ElementsPtr_Type elements = meshP1->getElementsC();
140 if (verbose)
141 std::cout << "-- -- Start building P2 mesh -- -- " << std::endl;
142
143 if (verbose)
144 std::cout << "-- Building edge mid points with edges and setting P2 elements ... " << std::flush;
145
146 vec2D_dbl_Type newPoints( edgeElements->numberElements(), vec_dbl_Type( this->dim_ ) );
147 vec_int_Type newFlags( edgeElements->numberElements(), -1 );
148 int newNodesPerElement = -1;
149 if (this->dim_==2)
150 newNodesPerElement = 3;
151 else if (this->dim_==3)
152 newNodesPerElement = 6;
153
154 vec2D_LO_Type newElementNodes( elements->numberElements(), vec_LO_Type( newNodesPerElement, -1 ) );
155
156 vec2D_dbl_ptr_Type pointsP1 = meshP1->getPointsRepeated();
157 MapConstPtr_Type mapRepeatedP1 = meshP1->getMapRepeated();
158
159
160 // loop over all previously created edges to construct new P2 points
161
162 for (int i=0; i<edgeElements->numberElements(); i++) {
163
164 LO p1ID = edgeElements->getElement(i).getNode( 0 );
165 LO p2ID = edgeElements->getElement(i).getNode( 1 );
166
167 for (int d=0; d<this->dim_; d++)
168 newPoints[i][d] = ( (*pointsP1)[p1ID][d] + (*pointsP1)[p2ID][d] ) / 2.; // New point on middle of nodes
169
171 newFlags[i] = edgeElements->getElement(i).getFlag(); // New flags according to edge flags
172
173 const vec_LO_Type elementsOfEdge = edgeElements->getElementsOfEdge( i );
174 const vec_GO_Type elementsGlobalOfEdge = edgeElements->getElementsOfEdgeGlobal( i );
175
176 vec_GO_Type relevantElementsOfEdge(0);
177 for (int j=0; j<elementsOfEdge.size(); j++) {
178 if ( elementsOfEdge[j] != OTLO::invalid() )
179 relevantElementsOfEdge.push_back( elementsOfEdge[j] );
180 }
181
182 // We need to determine the correct location in the P2 element as prescribed by a specific pattern
183 vec_int_Type positions( relevantElementsOfEdge.size() );
184 if ( relevantElementsOfEdge.size() > 0 )
185 determinePositionInElementP2( positions, relevantElementsOfEdge, p1ID, p2ID, meshP1 );
186
187 int factor = 0;
188 if (this->dim_==2)
189 factor=3;
190 else if(this->dim_==3)
191 factor = 4;
192 for (int j=0; j<relevantElementsOfEdge.size(); j++)
193 newElementNodes[ relevantElementsOfEdge[j] ][ positions[j]-factor ] = i ;
194
195 }
196
197 // Set P2 Elements, by resetting 'old' elements and adding them with the new nodes per element
198 this->elementsC_.reset(new Elements());
199
200 LO numberLocalP1Nodes = meshP1->getPointsRepeated()->size();
201
202 for (int i=0; i<elements->numberElements(); i++) {
203 vec_int_Type feNodeList = elements->getElement( i ).getVectorNodeListNonConst(); // get a copy
204 for (int j=0; j<newElementNodes[i].size(); j++)
205 feNodeList.push_back( newElementNodes[i][j] + numberLocalP1Nodes );
206 FiniteElement feP2( feNodeList,elements->getElement( i ).getFlag() );
207 this->elementsC_->addElement(feP2);
209
210 if (verbose)
211 std::cout << "done --" << std::endl;
212
213 if (verbose)
214 std::cout << "-- Setting global point IDs and building repeated P2 map and repeated points ... " << std::flush;
215
216 // Now the corresponding maps for nodes and flags are updated.
217 // Generally the P2 points are added after the P1 points in the node lists. Thus the new IDs just need to be added at the
218 // end of the maps
220 this->pointsRep_.reset(new std::vector<std::vector<double> >(meshP1->pointsRep_->size(),std::vector<double>(this->dim_,-1.)));
221 *this->pointsRep_ = *meshP1->pointsRep_;
222 this->bcFlagRep_.reset(new std::vector<int>(meshP1->bcFlagRep_->size()));
223 *this->bcFlagRep_ = *meshP1->bcFlagRep_;
225 this->pointsRep_->insert( this->pointsRep_->end(), newPoints.begin(), newPoints.end() );
226 this->bcFlagRep_->insert( this->bcFlagRep_->end(), newFlags.begin(), newFlags.end());
227
228 Teuchos::ArrayView<const GO> nodeList = meshP1->getMapRepeated()->getNodeElementList();
229 std::vector<GO> vecGlobalIDs = Teuchos::createVector( nodeList );
230
231 // To correctly determine the global nodeIDs of the new P2 nodes we set them via the global edge IDs.
232 // As can be on more than one processor at a time, they are an easy way to determine the correct
233 // nodeIDs via the edges'globalID.
234 for (int i=0; i<edgeElements->numberElements(); i++){
235 vecGlobalIDs.push_back( edgeElements->getGlobalID( (LO) i ) + P1Offset );
236 edgeElements->setMidpoint( i, edgeElements->getGlobalID( (LO) i ) + P1Offset);
237 }
238 Teuchos::RCP<std::vector<GO> > pointsRepGlobMapping = Teuchos::rcp( new std::vector<GO>( vecGlobalIDs ) );
239 Teuchos::ArrayView<GO> pointsRepGlobMappingArray = Teuchos::arrayViewFromVector( *pointsRepGlobMapping );
240
241 this->mapRepeated_.reset(new Map<LO,GO,NO>( Teuchos::OrdinalTraits<GO>::invalid(), pointsRepGlobMappingArray, 0, this->comm_) );
242
243 if (verbose)
244 std::cout << "done --" << std::endl;
245
246 if (verbose)
247 std::cout << "-- Building unique P2 map, setting unique points and setting P2 elements ... " << std::flush;
248
249 this->mapUnique_ = this->mapRepeated_->buildUniqueMap( this->rankRange_ );
250
251 this->pointsUni_.reset(new std::vector<std::vector<double> >( this->mapUnique_->getNodeNumElements(), std::vector<double>(this->dim_,-1. ) ) );
252 this->bcFlagUni_.reset( new std::vector<int> ( this->mapUnique_->getNodeNumElements(), 0 ) );
253 for (int i=0; i<this->mapUnique_->getNodeNumElements(); i++) {
254 GO gid = this->mapUnique_->getGlobalElement( i );
255
256 LO id = this->mapRepeated_->getLocalElement( this->mapUnique_->getGlobalElement( i ) );
257 this->pointsUni_->at(i) = this->pointsRep_->at(id);
258 this->bcFlagUni_->at(i) = this->bcFlagRep_->at(id);
259
260 }
261 // Setting local P2 Node as Midpoint.
262 for (int i=0; i<edgeElements->numberElements(); i++){
263 edgeElements->setMidpoint( i, this->mapRepeated_->getLocalElement(edgeElements->getGlobalID( (LO) i ) + P1Offset));
264 }
265
266 this->edgeElements_ = edgeElements;
267
268
269 if (verbose)
270 std::cout << "done --" << std::endl;
271
272 if (verbose)
273 std::cout << "-- Building P2 surface elements ... " << std::flush;
274
275 setP2SurfaceElements( meshP1 );
276
277 if (verbose)
278 std::cout << "done --" << std::endl;
279
280}
281
282template <class SC, class LO, class GO, class NO>
284 // loop over all elements. Inside we loop over all P1 surface elements and set the P2 surface elements accordingly
285 ElementsPtr_Type elementsP1 = meshP1->getElementsC();
286 ElementsPtr_Type elementsP2 = this->getElementsC();
287 vec2D_int_Type localSurfaceIndices;
288 int surfaceElementOrder = 2;
289 if (this->dim_==3)
290 surfaceElementOrder = 3;
291
292
293 vec2D_int_Type surfacePermutation;
294 getLocalSurfaceIndices( surfacePermutation, surfaceElementOrder );
295
296 vec2D_int_Type surfacePermutation2D; // only used if in 3D, since we need to additionally set edges
297 if (this->dim_==3)
298 getLocalSurfaceIndices( surfacePermutation2D, 2 );
299
300 for (int i=0; i<elementsP1->numberElements(); i++) {
301
302 FiniteElement fe = elementsP1->getElement( i );
303 FiniteElement feP2 = elementsP2->getElement( i );
304
305 ElementsPtr_Type subEl = fe.getSubElements(); //might be null
306 for (int j=0; j<fe.numSubElements(); j++) {
307 FiniteElement feSurf = subEl->getElement(j);
308 // In some instances a element has only an edge as subelement. In that case this step is not required
309 if(feSurf.getVectorNodeList().size() == this->dim_)
310 this->addSurfaceP2Nodes(feP2, feSurf, surfacePermutation, this->dim_);
311
312 // set edges for 3D case and if there are any edges, for 2D the edges are handled above
313 ElementsPtr_Type subElSurf = feSurf.getSubElements(); //might be null
314 if (!subElSurf.is_null()) {
315 ElementsPtr_Type subElP2 = feP2.getSubElements();
316 FiniteElement feSubP2 = subElP2->getElement(j);
317 for (int e=0; e<feSurf.numSubElements(); e++) {
318 FiniteElement feEdge = subElSurf->getElement(e);
319 this->setSurfaceP2( feSubP2, feEdge, surfacePermutation2D, this->dim_-1 );
320 subElP2->switchElement( j, feSubP2 );
321 }
322 }
323 elementsP2->switchElement( i, feP2 );
324 }
325
326 }
327}
328
329template <class SC, class LO, class GO, class NO>
330void MeshUnstructured<SC,LO,GO,NO>::addSurfaceP2Nodes( FiniteElement &feP2, const FiniteElement &surfFeP1, const vec2D_int_Type &surfacePermutation, int dim ){
331
332 vec2D_LO_Type edgeElementList = this->edgeElements_->getElementsNodeList();
333 vec_int_Type surfaceNodeP2(0);
334
335 if (dim == 2) {
336 const vec_int_Type surfaceNodeP1 = surfFeP1.getVectorNodeList();
337
338 vec_int_Type tmpSurface = surfFeP1.getVectorNodeList();
339 sort(tmpSurface.begin(),tmpSurface.end());
340
341 auto it1 = find( edgeElementList.begin(),edgeElementList.end() , tmpSurface );
342 int edgeID = distance( edgeElementList.begin() , it1 );
343
344 surfaceNodeP2.push_back( surfaceNodeP1[0] );
345 surfaceNodeP2.push_back( surfaceNodeP1[1] );
346
347 surfaceNodeP2.push_back(this->edgeElements_->getMidpoint( edgeID ) );
348
349 int flag = surfFeP1.getFlag();
350 FiniteElement feP2Surf( surfaceNodeP2, flag );
351
352 if ( !feP2.subElementsInitialized() )
353 feP2.initializeSubElements("P2",dim-1);
354 feP2.addSubElement(feP2Surf);
355
356 }
357 else if (dim == 3){
358
359 const vec_int_Type surfaceNodeP1 = surfFeP1.getVectorNodeList();
360 vec2D_LO_Type edges(3,vec_LO_Type(2));
361 edges[0] = {surfaceNodeP1[0] , surfaceNodeP1[1]};
362 edges[1] = {surfaceNodeP1[1],surfaceNodeP1[2]};
363 edges[2] = {surfaceNodeP1[0],surfaceNodeP1[2]};
364
365
366 surfaceNodeP2.push_back( surfaceNodeP1[0] );
367 surfaceNodeP2.push_back( surfaceNodeP1[1] );
368 surfaceNodeP2.push_back( surfaceNodeP1[2] );
369
370
371 bool criticalEdge = false;
372 for(int i=0; i<3 ; i++){
373
374 sort(edges[i].begin(),edges[i].end());
375
376 auto it1 = find( edgeElementList.begin(),edgeElementList.end() , edges[i] );
377 int edgeID = distance( edgeElementList.begin() , it1 );
378 if(it1 == edgeElementList.end())
379 criticalEdge=true; // Some triangles can be -1 -1 -1 thus no edge can be found. Why does that happen??
380 else
381 surfaceNodeP2.push_back(this->edgeElements_->getMidpoint( edgeID ) );
382
383 }
384
385 if(criticalEdge==false){
386
387
388 int flag = surfFeP1.getFlag();
389 FiniteElement feP2Surf( surfaceNodeP2, flag );
390
391 if ( !feP2.subElementsInitialized() )
392 feP2.initializeSubElements("P2",dim-1);
393 feP2.addSubElement(feP2Surf);
394 }
395
396 }
397
398}
399
400
401template <class SC, class LO, class GO, class NO>
402void MeshUnstructured<SC,LO,GO,NO>::setSurfaceP2( FiniteElement &feP2, const FiniteElement &surfFeP1, const vec2D_int_Type &surfacePermutation, int dim ){
403
404 if (dim == 2) {
405 for (int j=0; j<surfacePermutation.size(); j++) {
406 vec_int_Type tmpSurface(2);
407 tmpSurface[0] = feP2.getNode( surfacePermutation.at(j).at(0) );
408 tmpSurface[1] = feP2.getNode( surfacePermutation.at(j).at(1) );
409
410 sort( tmpSurface.begin(), tmpSurface.end() );
411
412 vec_int_Type surfaceNodeP2(0);
413 const vec_int_Type surfaceNodeP1 = surfFeP1.getVectorNodeList();
414 if ( tmpSurface[0] == surfaceNodeP1[0] && tmpSurface[1] == surfaceNodeP1[1] ) {
415
416 surfaceNodeP2.push_back( surfaceNodeP1[0] );
417 surfaceNodeP2.push_back( surfaceNodeP1[1] );
418 if (j == 0)
419 surfaceNodeP2.push_back( feP2.getNode( 3 ) );
420 else if( j == 1 )
421 surfaceNodeP2.push_back( feP2.getNode( 5 ) );
422 else if( j == 2 )
423 surfaceNodeP2.push_back( feP2.getNode( 4 ) );
424
425 int flag = surfFeP1.getFlag();
426 FiniteElement feP2Surf( surfaceNodeP2, flag );
427
428 if ( !feP2.subElementsInitialized() )
429 feP2.initializeSubElements("P2",dim-1);
430 feP2.addSubElement(feP2Surf);
431 }
432
433 }
434 }
435 else if (dim == 3){
436 for (int j=0; j<surfacePermutation.size(); j++) {
437 vec_int_Type tmpSurface(3);
438 tmpSurface[0] = feP2.getNode( surfacePermutation.at(j).at(0) );
439 tmpSurface[1] = feP2.getNode( surfacePermutation.at(j).at(1) );
440 tmpSurface[2] = feP2.getNode( surfacePermutation.at(j).at(2) );
441 //sort( tmpSurface.begin(), tmpSurface.end() );
442
443
444 vec_int_Type index(3, 0);
445 for (int i = 0 ; i != index.size() ; i++)
446 index[i] = i;
447
448 sort(index.begin(), index.end(),
449 [&](const int& a, const int& b) {
450 return tmpSurface[a] < tmpSurface[b];
451 }
452 );
453
454 tmpSurface = sort_from_ref(tmpSurface, index);
455
456 vec_int_Type surfaceNodeP2(0);
457 const vec_int_Type surfaceNodeP1Unsorted = surfFeP1.getVectorNodeList();
458 vec_int_Type surfaceNodeP1 = surfFeP1.getVectorNodeList();
459 //sort( surfaceNodeP1.begin(), surfaceNodeP1.end() );
460
461 vec_int_Type index2(3, 0);
462 for (int i = 0 ; i != index2.size() ; i++)
463 index2[i] = i;
464
465 sort(index2.begin(), index2.end(),
466 [&](const int& a, const int& b) {
467 return surfaceNodeP1[a] < surfaceNodeP1[b];
468 }
469 );
470
471 surfaceNodeP1 = sort_from_ref(surfaceNodeP1, index2);
472
473 if ( tmpSurface[0] == surfaceNodeP1[0] &&
474 tmpSurface[1] == surfaceNodeP1[1] &&
475 tmpSurface[2] == surfaceNodeP1[2]) {
476 surfaceNodeP2.push_back( surfaceNodeP1Unsorted[0] );
477 surfaceNodeP2.push_back( surfaceNodeP1Unsorted[1] );
478 surfaceNodeP2.push_back( surfaceNodeP1Unsorted[2] );
479 vec_int_Type additionalP2IDs(3);
480 if (j == 0){
481 additionalP2IDs[0] = feP2.getNode( 4 );
482 additionalP2IDs[1] = feP2.getNode( 5 );
483 additionalP2IDs[2] = feP2.getNode( 6 );
484 }
485 else if( j == 1 ){
486 additionalP2IDs[0] = feP2.getNode( 4 );
487 additionalP2IDs[1] = feP2.getNode( 7 );
488 additionalP2IDs[2] = feP2.getNode( 8 );
489 }
490 else if( j == 2 ){
491 additionalP2IDs[0] = feP2.getNode( 5 );
492 additionalP2IDs[1] = feP2.getNode( 8 );
493 additionalP2IDs[2] = feP2.getNode( 9 );
494 }
495 else if( j == 3 ){
496 additionalP2IDs[0] = feP2.getNode( 6 );
497 additionalP2IDs[1] = feP2.getNode( 7 );
498 additionalP2IDs[2] = feP2.getNode( 9 );
499 }
500
501 additionalP2IDs = this->reorderP2SurfaceIndices(additionalP2IDs, index);
502 surfaceNodeP2.push_back( additionalP2IDs[0] );
503 surfaceNodeP2.push_back( additionalP2IDs[1] );
504 surfaceNodeP2.push_back( additionalP2IDs[2] );
505
506 // Resorting according to original IDs from GMSH
507
508 int flag = surfFeP1.getFlag();
509 FiniteElement feP2Surf( surfaceNodeP2, flag );
510 if ( !feP2.subElementsInitialized() )
511 feP2.initializeSubElements("P2",dim-1);
512 feP2.addSubElement(feP2Surf);
513 }
514 }
515 }
516
517}
518
519
520template <class SC, class LO, class GO, class NO>
521vec_int_Type MeshUnstructured<SC,LO,GO,NO>::reorderP2SurfaceIndices( vec_int_Type& additionalP2IDs, vec_int_Type& index , bool track){
522 vec_int_Type reorderedIDs(3);
523 // depending on the sorting of P1 surface nodes we have to adjust the new ordering of P2 edge midpoints for surfaces in 3D
524 if (index[0] == 0){
525 if(index[1] == 1){
526 reorderedIDs[0] = 0; reorderedIDs[1] = 1; reorderedIDs[2] = 2;
527 }
528 else if(index[1] == 2){
529 reorderedIDs[0] = 2; reorderedIDs[1] = 1; reorderedIDs[2] = 0;
530 }
531 }
532 else if (index[0] == 1){
533 if(index[1] == 0){
534 reorderedIDs[0] = 0; reorderedIDs[1] = 2; reorderedIDs[2] = 1;
535 }
536 else if(index[1] == 2){
537 reorderedIDs[0] = 1; reorderedIDs[1] = 2; reorderedIDs[2] = 0;
538 }
539 }
540 else if (index[0] == 2){
541 if(index[1] == 0){
542 reorderedIDs[0] = 2; reorderedIDs[1] = 0; reorderedIDs[2] = 1;
543 }
544 else if(index[1] == 1){
545 reorderedIDs[0] = 1; reorderedIDs[1] = 0; reorderedIDs[2] = 2;
546 }
547 }
548
549 return sort_from_ref(additionalP2IDs, reorderedIDs);
550}
551
552//template <class SC, class LO, class GO, class NO>
553//void MeshUnstructured<SC,LO,GO,NO>::setSurfaceP2( const FiniteElement &elementP2 , const vec_int_Type& surfaceNode, vec_int_Type& surfaceNodeP2, const vec2D_int_Type &surfacePermutation ){
554//
555// int loc, id1, id2, id3;
556// if (this->dim_ == 2) {
557// for (int j=0; j<surfacePermutation.size(); j++) {
558// id1 = elementP2.getNode( surfacePermutation.at(j).at(0) );
559// id2 = elementP2.getNode( surfacePermutation.at(j).at(1) );
560//
561// vec_int_Type tmpSurface(2);
562// if (id1 > id2){
563// tmpSurface[0] = id2;
564// tmpSurface[1] = id1;
565// }
566// else{
567// tmpSurface[0] = id1;
568// tmpSurface[1] = id2;
569// }
570//
571// if ( tmpSurface[0] == surfaceNode[0] && tmpSurface[1] == surfaceNode[1] ) {
572// surfaceNodeP2.push_back( surfaceNode[0] );
573// surfaceNodeP2.push_back( surfaceNode[1] );
574// if (j == 0)
575// surfaceNodeP2.push_back( elementP2.getNode( 3 ) );
576// else if( j == 1 )
577// surfaceNodeP2.push_back( elementP2.getNode( 5 ) );
578// else if( j == 2 )
579// surfaceNodeP2.push_back( elementP2.getNode( 4 ) );
580// }
581// }
582// }
583// else if (this->dim_ == 3){
584// for (int j=0; j<surfacePermutation.size(); j++) {
585// id1 = elementP2.getNode( surfacePermutation.at(j).at(0) );
586// id2 = elementP2.getNode( surfacePermutation.at(j).at(1) );
587// id3 = elementP2.getNode( surfacePermutation.at(j).at(2) );
588//
589// vec_int_Type tmpSurface = {id1 , id2 , id3};
590// sort( tmpSurface.begin(), tmpSurface.end() );
591//
592// if ( tmpSurface[0] == surfaceNode[0] &&
593// tmpSurface[1] == surfaceNode[1] &&
594// tmpSurface[2] == surfaceNode[2]) {
595// surfaceNodeP2.push_back( surfaceNode[0] );
596// surfaceNodeP2.push_back( surfaceNode[1] );
597// surfaceNodeP2.push_back( surfaceNode[2] );
598// if (j == 0){
599// surfaceNodeP2.push_back( elementP2.getNode( 4 ) );
600// surfaceNodeP2.push_back( elementP2.getNode( 5 ) );
601// surfaceNodeP2.push_back( elementP2.getNode( 6 ) );
602// }
603// else if( j == 1 ){
604// surfaceNodeP2.push_back( elementP2.getNode( 4 ) );
605// surfaceNodeP2.push_back( elementP2.getNode( 7 ) );
606// surfaceNodeP2.push_back( elementP2.getNode( 8 ) );
607// }
608// else if( j == 2 ){
609// surfaceNodeP2.push_back( elementP2.getNode( 5 ) );
610// surfaceNodeP2.push_back( elementP2.getNode( 8 ) );
611// surfaceNodeP2.push_back( elementP2.getNode( 9 ) );
612// }
613// else if( j == 3 ){
614// surfaceNodeP2.push_back( elementP2.getNode( 6 ) );
615// surfaceNodeP2.push_back( elementP2.getNode( 7 ) );
616// surfaceNodeP2.push_back( elementP2.getNode( 9 ) );
617// }
618// }
619// }
620// }
621//
622//}
623//
624template <class SC, class LO, class GO, class NO>
625void MeshUnstructured<SC,LO,GO,NO>::getLocalSurfaceIndices(vec2D_int_Type &localSurfaceIndices , int surfaceElementOrder ){
626
627 if ( this->dim_ == 2 ) {
628
629 if (surfaceElementOrder == 2) { //P1
630 localSurfaceIndices.resize(3,vec_int_Type(3,-1));
631 localSurfaceIndices.at(0).at(0) = 0;
632 localSurfaceIndices.at(0).at(1) = 1;
633 localSurfaceIndices.at(1).at(0) = 0;
634 localSurfaceIndices.at(1).at(1) = 2;
635 localSurfaceIndices.at(2).at(0) = 1;
636 localSurfaceIndices.at(2).at(1) = 2;
637 }
638 else{
639#ifdef ASSERTS_WARNINGS
640 MYASSERT(false,"no permutation for this surface yet.");
641#endif
642 }
643 }
644 else if ( this->dim_ == 3 ){
645 if (surfaceElementOrder == 3) {
646 localSurfaceIndices.resize(4,vec_int_Type(3,-1));
647 localSurfaceIndices.at(0).at(0) = 0;
648 localSurfaceIndices.at(0).at(1) = 1;
649 localSurfaceIndices.at(0).at(2) = 2;
650 localSurfaceIndices.at(1).at(0) = 0;
651 localSurfaceIndices.at(1).at(1) = 1;
652 localSurfaceIndices.at(1).at(2) = 3;
653 localSurfaceIndices.at(2).at(0) = 1;
654 localSurfaceIndices.at(2).at(1) = 2;
655 localSurfaceIndices.at(2).at(2) = 3;
656 localSurfaceIndices.at(3).at(0) = 0;
657 localSurfaceIndices.at(3).at(1) = 2;
658 localSurfaceIndices.at(3).at(2) = 3;
659 }
660 else{
661#ifdef ASSERTS_WARNINGS
662 MYASSERT(false,"no permutation for this surface yet.");
663#endif
664 }
665 }
666}
667
668
669template <class SC, class LO, class GO, class NO>
670void MeshUnstructured<SC,LO,GO,NO>::getEdgeCombinations( vec2D_int_Type& edgeCombinations ){
671
672 if (this->dim_ == 2) {
673 edgeCombinations[0][0] = 0; edgeCombinations[0][1] = 1;
674 edgeCombinations[1][0] = 0; edgeCombinations[1][1] = 2;
675 edgeCombinations[2][0] = 1; edgeCombinations[2][1] = 2;
676 }
677 else if (this->dim_ == 3) {
678 edgeCombinations[0][0] = 0; edgeCombinations[0][1] = 1;
679 edgeCombinations[1][0] = 0; edgeCombinations[1][1] = 2;
680 edgeCombinations[2][0] = 0; edgeCombinations[2][1] = 3;
681 edgeCombinations[3][0] = 1; edgeCombinations[3][1] = 2;
682 edgeCombinations[4][0] = 1; edgeCombinations[4][1] = 3;
683 edgeCombinations[5][0] = 2; edgeCombinations[5][1] = 3;
684 }
685
686}
687
688template <class SC, class LO, class GO, class NO>
689void MeshUnstructured<SC,LO,GO,NO>::determinePositionInElementP2( vec_int_Type& positions, vec_GO_Type& elementsOfEdge, LO p1ID, LO p2ID, MeshUnstrPtr_Type meshP1 ){
690 ElementsPtr_Type elements = meshP1->getElementsC();
691 for (int i=0; i<elementsOfEdge.size(); i++) {
692
693 const vec_int_Type nodeList = elements->getElement( elementsOfEdge[i] ).getVectorNodeList();
694
695 auto it1 = find( nodeList.begin(), nodeList.end() , p1ID );
696 int localElNum1 = distance( nodeList.begin() , it1 );
697 auto it2 = find( nodeList.begin(), nodeList.end() , p2ID );
698 int localElNum2 = distance( nodeList.begin() , it2 );
699 if (localElNum1 > localElNum2) {
700 int tmp = localElNum1;
701 localElNum1 = localElNum2;
702 localElNum2 = tmp;
703 }
704 if (this->dim_ == 2) {
705 if (localElNum1==0) {
706 if (localElNum2==1)
707 positions[i] = 3;
708 else if(localElNum2==2)
709 positions[i] = 5;
710 }
711 else
712 positions[i] = 4;
713 }
714 else if (this->dim_ == 3) {
715 if (localElNum1==0) {
716 if (localElNum2==1)
717 positions[i] = 4;
718 else if(localElNum2==2)
719 positions[i] = 6;
720 else if(localElNum2==3)
721 positions[i] = 7;
722
723 }
724 else if(localElNum1==1){
725 if (localElNum2==2)
726 positions[i] = 5;
727 else if(localElNum2==3)
728 positions[i] = 8;
729 }
730 else
731 positions[i] = 9;
732 }
733 }
734}
735
736template <class SC, class LO, class GO, class NO>
737int MeshUnstructured<SC,LO,GO,NO>::determineFlagP2( FiniteElement& fe, LO p1ID, LO p2ID, vec2D_int_Type& permutation ){
738
739 int newFlag = std::numeric_limits<int>::max();
740 vec_int_Type newFlags(0);
741 bool foundLineSegment;
742 const vec_int_Type nodeList = fe.getVectorNodeList();
743
744 vec_int_Type localElementNumbering(2);
745 auto it1 = find( nodeList.begin(), nodeList.end() , p1ID );
746 localElementNumbering[0] = distance( nodeList.begin() , it1 );
747 auto it2 = find( nodeList.begin(), nodeList.end() , p2ID );
748 localElementNumbering[1] = distance( nodeList.begin() , it2 );
749
750 fe.findEdgeFlagInSubElements( localElementNumbering, newFlags, false /*we are not in a subElement yet*/, permutation, foundLineSegment );
751
752 if (newFlags.size() == 0)
753 newFlag = volumeID_;
754
755 // We use the lowest flag
756 for (int k = 0; k < newFlags.size(); k++) {
757 if ( newFlag > newFlags[k] )
758 newFlag = newFlags[k];
759 }
760
761 return newFlag;
762}
763
764template <class SC, class LO, class GO, class NO>
765int MeshUnstructured<SC,LO,GO,NO>::determineFlagP2( LO p1ID, LO p2ID, LO localEdgeID, vec2D_LO_Type& markedPoint ){
766
767
768 ElementsPtr_Type elements = this->getElementsC();
769
770 vec2D_int_Type permutation = elements->getElementEdgePermutation();
771
772 EdgeElementsPtr_Type edgeElements = this->getEdgeElements();
773
774 MapConstPtr_Type elementMap = this->getElementMap();
775
776 int rank = this->comm_->getRank();
777
778 int flag1 = ( *this->getBCFlagRepeated() )[p1ID];
779
780 int flag2 = ( *this->getBCFlagRepeated() )[p2ID];
781
782 int newFlag = std::numeric_limits<int>::max();
783
784 if(flag1 == this->volumeID_ || flag2 == this->volumeID_ ) // one node is in an inner node, than the new node is an inner node aswell
785 newFlag = this->volumeID_;
786 else{
787
788 // check if node 1 and node 2 are part of the same surface. In this case we can use the flag of the corresponding surface. Otherwise we mark the new point as an interior point and it gets the volumeID_.
789
790 const vec_LO_Type elementsOfEdge = edgeElements->getElementsOfEdge( (int) localEdgeID );
791
792 const vec_GO_Type elementsOfEdgeGlobal = edgeElements->getElementsOfEdgeGlobal( (int) localEdgeID );
793
794
795 bool markPoint = false;
796 bool foundFlag = false;
797 vec_int_Type localElementNumbering(2);
798 vec_int_Type edge(2);
799 bool foundLineSegment = false;
800 vec_int_Type newFlags(0);
801 for (int i=0; i<elementsOfEdge.size() && !foundLineSegment; i++) {
802 if ( elementsOfEdge[i] != OTLO::invalid() ) {
803 //In elementsOfEdge we can access all elements which have this (the current) edge.
804
805 FiniteElement fe = elements->getElement( elementsOfEdge[i] );
806 const vec_int_Type nodeList = fe.getVectorNodeList();
807
808 // we need to determine the numbering of p1ID and p2ID corresponding to the current element
809 auto it1 = find( nodeList.begin(), nodeList.end() , p1ID );
810 localElementNumbering[0] = distance( nodeList.begin() , it1 );
811 auto it2 = find( nodeList.begin(), nodeList.end() , p2ID );
812 localElementNumbering[1] = distance( nodeList.begin() , it2 );
813 edge[0] = p1ID; edge[1] = p2ID;
814 sort( edge.begin(), edge.end() );
815
816 fe.findEdgeFlagInSubElements( edge, newFlags, false /*we are not in a subElement yet*/, permutation, foundLineSegment );
817
818 //We need to mark this point since it can still be on the surface and another element holds the corresponding surface with the correct flag.
819 if (newFlags.size() == 0 && newFlag > this->volumeID_)
820 newFlag = this->volumeID_; //do we need this?
821
822 //If we found a line element, then we choose this flag
823 if (foundLineSegment){
824 foundFlag = true;
825 newFlag = newFlags [0];
826 }
827 else {
828 // We use the lowest flag of all surfaces
829
830 for (int k = 0; k < newFlags.size(); k++) {
831 foundFlag = true;
832 if (newFlag > newFlags[k] )
833 newFlag = newFlags[k];
834 }
835 }
836 }
837 else
838 markPoint = true;
839 }
840 if (markPoint && !foundFlag) {
841 // We have not found a surface flag for this point.
842 // No part of the element which owns this edge is part of the surface, but there might be a different element which has this edge but does not own it, but this element might have a part of the surface. We mark this point and determine the correct flag later
843 markedPoint.push_back( {p1ID, p2ID, localEdgeID } );
844 newFlag = -1;
845 }
846
847 }
848
849 return newFlag;
850}
851
852
853template <class SC, class LO, class GO, class NO>
854void MeshUnstructured<SC,LO,GO,NO>::findSurfaces( const vec_int_Type& elementNodeList, vec_int_Type numbering, vec2D_int_Type& localSurfaceNodeList_vec, vec_int_Type& loc_vector, bool critical){
855 int tmpID;
856 loc_vector.resize(0);
857 vec2D_int_Type::iterator it;
858 int id1 = elementNodeList.at(numbering.at(0));
859 int id2 = elementNodeList.at(numbering.at(1));
860
861 if (this->dim_==2) {
862 vec_int_Type searchfor(2,-1);
863 // Here, we use that the local surfaces are sorted. See MyMeshConvert::ReadMesh(...)
864 if ( id1 < id2 ) {
865 searchfor.at(0) = id1;
866 searchfor.at(1) = id2;
867 }
868 else{
869 searchfor.at(0) = id2;
870 searchfor.at(1) = id1;
871 }
872
873 it = find( localSurfaceNodeList_vec.begin(), localSurfaceNodeList_vec.end(), searchfor );
874 if (it!=localSurfaceNodeList_vec.end()) {
875 loc_vector.push_back( distance(localSurfaceNodeList_vec.begin(),it) );
876 }
877
878 }
879 else if (this->dim_==3){
880
881 vec_int_Type vertices3ID(0);
882 //we want to identify the possible third surface component of a triangle. If we use other elements in 3D we might change this function.
883 getTriangles(numbering.at(0), numbering.at(1), vertices3ID);
884 // we have the two possible combinations as a vector: vertices3ID
885
886 vec_int_Type searchfor(3,-1);
887 for (int i=0; i<2; i++) {
888 searchfor.at(0) = id1;
889 searchfor.at(1) = id2;
890 searchfor.at(2) = elementNodeList.at( vertices3ID.at(i) );
891
892 sort( searchfor.begin(), searchfor.end() );
893
894
895 it = find( localSurfaceNodeList_vec.begin(), localSurfaceNodeList_vec.end(), searchfor );
896 if (it!=localSurfaceNodeList_vec.end()){
897 loc_vector.push_back( distance(localSurfaceNodeList_vec.begin(),it) );
898 }
899 }
900 }
901}
902
903template <class SC, class LO, class GO, class NO>
904void MeshUnstructured<SC,LO,GO,NO>::findEdges( const vec_int_Type& elementNodeList, vec_int_Type numbering, vec2D_int_Type& localEdgeNodeList_vec, vec_int_Type& loc_vector){
905 int tmpID;
906 loc_vector.resize(0);
907 vec2D_int_Type::iterator it;
908 int id1 = elementNodeList.at(numbering.at(0));
909 int id2 = elementNodeList.at(numbering.at(1));
910 vec_int_Type searchEdge(0);
911 if (id2 > id1)
912 searchEdge = { id1, id2 };
913 else
914 searchEdge = { id2, id1 };
915
916 it = find( localEdgeNodeList_vec.begin(), localEdgeNodeList_vec.end(), searchEdge );
917 if ( it != localEdgeNodeList_vec.end() )
918 loc_vector.push_back( distance(localEdgeNodeList_vec.begin(),it) );
919}
920
921template <class SC, class LO, class GO, class NO>
922typename MeshUnstructured<SC,LO,GO,NO>::MeshInterfacePtr_Type MeshUnstructured<SC,LO,GO,NO>::getMeshInterface(){
923 TEUCHOS_TEST_FOR_EXCEPTION( meshInterface_.is_null(), std::runtime_error, "MeshInterface is null.");
924 return meshInterface_;
925}
926
927template <class SC, class LO, class GO, class NO>
928void MeshUnstructured<SC,LO,GO,NO>::buildMeshInterfaceParallelAndDistance( MeshUnstrPtr_Type mesh, vec_int_Type flag_vec, vec_dbl_ptr_Type &distancesToInterface ){
929 this->meshInterface_.reset( new MeshInterface<SC,LO,GO,NO> ( this->getComm() ) );
930
931 // BuildMeshInterface for different flags
932 this->meshInterface_->determineInterfaceParallelAndDistance( this->pointsUni_, mesh->pointsUni_, this->bcFlagUni_, mesh->bcFlagUni_, flag_vec, this->getMapUnique(), mesh->getMapUnique(), distancesToInterface, this->pointsRep_, this->getDimension() );
933
934 mesh->meshInterface_.reset( new MeshInterface_Type ( mesh->getComm() ) );
935 mesh->meshInterface_->buildFromOtherInterface( meshInterface_ );
936
937 //because we had to communicated all interface information in determineInterfaceParallel(), we can now partition the information again.
938 this->partitionInterface();
939 mesh->partitionInterface();
940}
941
942template <class SC, class LO, class GO, class NO>
943void MeshUnstructured<SC,LO,GO,NO>::partitionInterface(){
944 FEDD_TIMER_START(interfacePartitionTimer," : Mesh : Partition Interface");
945 if (!this->meshInterface_.is_null())
946 this->meshInterface_->partitionMeshInterface( this->mapRepeated_, this->mapUnique_);
947
948}
949template <class SC, class LO, class GO, class NO>
950void MeshUnstructured<SC,LO,GO,NO>::setMeshFileName(std::string meshFileName, std::string delimiter){
951
952 meshFileName_ = meshFileName;
953 delimiter_ = delimiter;
954}
955
962
963
964template <class SC, class LO, class GO, class NO>
966
967 vec2D_LO_Type markedPoints(0);
968 EdgeElementsPtr_Type edgeElements = this->getEdgeElements();
969 ElementsPtr_Type elements = this->getElementsC();
970 MapConstPtr_Type mapRepeatedP1 = this->getMapRepeated();
971 vec_int_Type newFlags(edgeElements->numberElements());
972
973 MapConstPtr_Type edgeMap = this->getEdgeMap();
974
975 vec_int_Type markedTrue(edgeElements->numberElements());
976 for(int i=0; i< edgeElements->numberElements() ; i++){
977 LO p1ID =edgeElements->getElement(i).getNode(0);
978 LO p2ID =edgeElements->getElement(i).getNode(1);
979 newFlags[i]=this->determineFlagP2(p1ID, p2ID, i , markedPoints );
980 if(newFlags[i] != -1){ // questionable point that were given a flag, but that is not certain yet
981 vec_LO_Type elementsOfEdge = edgeElements->getElementsOfEdge( (int) i );
982 for (int j=0; j<elementsOfEdge.size(); j++) {
983 if ( elementsOfEdge[j] == -1 )
984 markedTrue[i] =1;
985 }
986 }
987 }
988 // It is possible that a Edge is conencted to two surfaces with different Flags, that are also on different Processors
989 // This Leads to two different Flags for the same Edge
990 // In order to counter that effect we check the interface edges of which we determined the flag via surfaces and check if they have the same flag and if not choose the lower one
991 int maxRank = std::get<1>(this->rankRange_);
992 if(maxRank >0 ){
993 vec_GO_Type edgeSwitch(0);
994 vec_LO_Type flags(0);
995 for(int i=0; i<edgeElements->numberElements(); i++){
996 if(markedTrue[i]==1){
997 edgeSwitch.push_back(edgeMap->getGlobalElement(i));
998 flags.push_back(newFlags[i]);
999 }
1000 }
1001
1002 // communticating elements across interface
1003 Teuchos::ArrayView<GO> edgeSwitchArray = Teuchos::arrayViewFromVector( edgeSwitch);
1004
1005 MapPtr_Type mapGlobalInterface =
1006 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), edgeSwitchArray, 0, this->comm_) );
1007
1008 // Global IDs of Procs
1009 // Setting newPoints as to be communicated Values
1010 MultiVectorLOPtr_Type edgeFlags = Teuchos::rcp( new MultiVectorLO_Type( mapGlobalInterface, 1 ) );
1011 Teuchos::ArrayRCP< LO > edgeFlagsEntries = edgeFlags->getDataNonConst(0);
1012
1013 for(int i=0; i< edgeFlagsEntries.size() ; i++){
1014 edgeFlagsEntries[i] = flags[i] ;
1015 }
1016
1017 MapConstPtr_Type mapGlobalInterfaceUnique = mapGlobalInterface;
1018 if(mapGlobalInterface->getGlobalNumElements()>0){
1019 mapGlobalInterfaceUnique = mapGlobalInterface->buildUniqueMap( this->rankRange_ );
1020 }
1021
1022
1023 MultiVectorLOPtr_Type isInterfaceElement_imp = Teuchos::rcp( new MultiVectorLO_Type( mapGlobalInterfaceUnique, 1 ) );
1024 isInterfaceElement_imp->putScalar( (LO) 0 );
1025 isInterfaceElement_imp->importFromVector( edgeFlags, false, "Insert");
1026
1027 MultiVectorLOPtr_Type isInterfaceElement_exp = Teuchos::rcp( new MultiVectorLO_Type( mapGlobalInterfaceUnique, 1 ) );
1028 isInterfaceElement_exp->putScalar( (LO) 0 );
1029 isInterfaceElement_exp->exportFromVector( edgeFlags, false, "Insert");
1030
1031 MultiVectorLOPtr_Type isInterfaceElement2_imp = Teuchos::rcp( new MultiVectorLO_Type( mapGlobalInterface, 1 ) );
1032 isInterfaceElement2_imp->putScalar( (LO) 0 );
1033 isInterfaceElement2_imp->importFromVector(isInterfaceElement_imp, false, "Insert");
1034
1035 isInterfaceElement2_imp->exportFromVector(isInterfaceElement_exp, false, "Insert");
1036
1037 edgeFlagsEntries = isInterfaceElement2_imp->getDataNonConst(0);
1038
1039 for(int i=0; i<edgeFlagsEntries.size(); i++){
1040 LO entry = edgeMap->getLocalElement(edgeSwitch[i]);
1041 if(newFlags[entry] > edgeFlagsEntries[i]){
1042 newFlags[entry] = edgeFlagsEntries[i];
1043
1044 }
1045 }
1046 }
1047 // In the next Step we need to determine the missing Flags of the 'MarkedMissing' Edges
1048 // We create a Map of the entries we have and one of the ones we need
1049 vec_GO_Type edgesNeeded(0); // For the Flag entries we need
1050 vec_GO_Type edgesActive(0);
1051 vec_int_Type flagsTmp(0);
1052 for(int i=0; i<edgeElements->numberElements(); i++){
1053 if(newFlags[i]==-1){
1054 edgesNeeded.push_back(edgeMap->getGlobalElement(i));
1055 }
1056 else{
1057 edgesActive.push_back(edgeMap->getGlobalElement(i));
1058 flagsTmp.push_back(newFlags[i]);
1059
1060 }
1061 }
1062
1063 // communticating elements across interface
1064 Teuchos::ArrayView<GO> edgesNeededArray = Teuchos::arrayViewFromVector( edgesNeeded);
1065 Teuchos::ArrayView<GO> edgesActiveArray = Teuchos::arrayViewFromVector( edgesActive);
1066
1067 MapPtr_Type mapEdgesNeeded =
1068 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), edgesNeededArray, 0, this->comm_) );
1069
1070 MapPtr_Type mapEdgesActive =
1071 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), edgesActiveArray, 0, this->comm_) );
1072
1073 MultiVectorLOPtr_Type flagsImport = Teuchos::rcp( new MultiVectorLO_Type( mapEdgesNeeded, 1 ) );
1074 flagsImport->putScalar(this->volumeID_);
1075
1076 MultiVectorLOPtr_Type flagsExport = Teuchos::rcp( new MultiVectorLO_Type( mapEdgesActive, 1 ) );
1077 Teuchos::ArrayRCP< LO > flagExportEntries = flagsExport->getDataNonConst(0);
1078 for(int i=0; i< flagExportEntries.size(); i++){
1079 flagExportEntries[i] = flagsTmp[i];
1080 }
1081
1082 flagsImport->importFromVector(flagsExport, false, "Insert");
1083
1084 Teuchos::ArrayRCP< LO > flagImportEntries = flagsImport->getDataNonConst(0);
1085 for(int i=0; i<flagImportEntries.size(); i++){
1086 LO entry = edgeMap->getLocalElement(edgesNeeded[i]);
1087 if(newFlags[entry] ==-1){
1088 newFlags[entry] = flagImportEntries[i];
1089 }
1090 }
1091
1092 for(int i=0; i< edgeElements->numberElements() ; i++){
1093 edgeElements->getElement(i).setFlag(newFlags[i]);
1094 }
1095
1096}
1097
1098template <class SC, class LO, class GO, class NO>
1100
1101 int maxRank = std::get<1>(this->rankRange_);
1102 vec_GO_Type globalProcs(0);
1103 for (int i=0; i<= maxRank; i++)
1104 globalProcs.push_back(i);
1105
1106 Teuchos::ArrayView<GO> globalProcArray = Teuchos::arrayViewFromVector( globalProcs);
1107
1108 vec_GO_Type localProc(0);
1109 localProc.push_back(this->comm_->getRank());
1110 Teuchos::ArrayView<GO> localProcArray = Teuchos::arrayViewFromVector( localProc);
1111
1112 MapPtr_Type mapGlobalProc =
1113 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), globalProcArray, 0, this->comm_) );
1114
1115 MapPtr_Type mapProc =
1116 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), localProcArray, 0, this->comm_) );
1117
1118
1119 vec2D_int_Type interfaceEdgesLocalId(1,vec_int_Type(1));
1120 const int myRank = this->comm_->getRank();
1121
1122 MultiVectorLOPtr_Type exportLocalEntry = Teuchos::rcp( new MultiVectorLO_Type( mapProc, 1 ) );
1123
1124 // First we determine a Map only for the interface Nodes
1125 // This will reduce the size of the Matrix we build later significantly if only look at the interface edges
1126 int numEdges= this->edgeElements_->numberElements();
1127 vec2D_GO_Type inzidenzIndices(0,vec_GO_Type(2)); // Vector that stores global IDs of each edge (in Repeated Sense)
1128 vec_LO_Type localEdgeIndex(0); // stores the local ID of edges in question
1129 vec_GO_Type id(2);
1130 int edgesUnique=0;
1131 EdgeElementsPtr_Type edgeElements = this->edgeElements_; // Edges
1132
1133 vec2D_dbl_ptr_Type points = this->pointsRep_;
1134
1135 int interfaceNum=0;
1136 for(int i=0; i<numEdges; i++ ){
1137 if(edgeElements->getElement(i).isInterfaceElement()){
1138
1139 id[0] = this->mapRepeated_->getGlobalElement(edgeElements->getElement(i).getNode(0));
1140 id[1] = this->mapRepeated_->getGlobalElement(edgeElements->getElement(i).getNode(1));
1141
1142
1143
1144 sort(id.begin(),id.end());
1145 inzidenzIndices.push_back(id);
1146
1147 localEdgeIndex.push_back(i);
1148 interfaceNum++;
1149 }
1150
1151 else{
1152 edgesUnique++;
1153 }
1154
1155
1156 }
1157 // This Matrix is row based, where the row is based on mapInterfaceNodesUnqiue
1158 // We then add a '1' Entry when two global Node IDs form an edge
1159 MatrixPtr_Type inzidenzMatrix = Teuchos::rcp( new Matrix_Type(this->mapUnique_, 40 ) );
1160 Teuchos::Array<GO> index(1);
1161 Teuchos::Array<GO> col(1);
1162 Teuchos::Array<SC> value(1, Teuchos::ScalarTraits<SC>::one() );
1163
1164 for(int i=0; i<inzidenzIndices.size(); i++ ){
1165
1166 index[0] = inzidenzIndices[i][0];
1167 col[0] = inzidenzIndices[i][1];
1168 inzidenzMatrix->insertGlobalValues(index[0], col(), value());
1169
1170 }
1171 inzidenzMatrix->fillComplete(); //mapInterfaceNodesUnique,mapInterfaceNodesUnique);
1172
1173
1174 // Set unique edges IDs
1175 // Setting the IDs of Edges that are uniquely on one Processor
1176
1177 exportLocalEntry->putScalar( (LO) edgesUnique );
1178
1179 MultiVectorLOPtr_Type newEdgesUniqueGlobal= Teuchos::rcp( new MultiVectorLO_Type( mapGlobalProc, 1 ) );
1180 newEdgesUniqueGlobal->putScalar( (LO) 0 );
1181 newEdgesUniqueGlobal->importFromVector( exportLocalEntry, true, "Insert");
1182 // offset EdgesUnique for proc and globally
1183 Teuchos::ArrayRCP< const LO > newEdgesList = newEdgesUniqueGlobal->getData(0);
1184
1185 GO procOffsetEdges=0;
1186 for(int i=0; i< myRank; i++)
1187 procOffsetEdges= procOffsetEdges + newEdgesList[i];
1188
1189 // global IDs for map
1190 vec_GO_Type vecGlobalIDsEdges(this->edgeElements_->numberElements());
1191
1192 // Step 1: adding unique global edge IDs
1193 int count=0;
1194 for(int i=0; i< this->edgeElements_->numberElements(); i++){
1195 if(!this->edgeElements_->getElement(i).isInterfaceElement()){
1196 vecGlobalIDsEdges.at(i) = procOffsetEdges+count;
1197 count++;
1198 }
1199 }
1200
1201 // Now we add the repeated ids, by first turning interfaceEdgesTag into a map
1202 // Offset for interface IDS:
1203 GO offsetInterface=0;
1204 for(int i=0; i< maxRank+1; i++)
1205 offsetInterface= offsetInterface + newEdgesList[i];
1206
1207 //Now we count the row entries on each processor an set global IDs
1208
1209 Teuchos::ArrayView<const LO> indices;
1210 Teuchos::ArrayView<const SC> values;
1211 vec2D_GO_Type inzidenzIndicesUnique(0,vec_GO_Type(2)); // Vector that stores only both global IDs if the first is part of my unique Interface Nodes
1212 MapConstPtr_Type colMap = inzidenzMatrix->getMap("col");
1213 MapConstPtr_Type rowMap = inzidenzMatrix->getMap("row");
1214 int numRows = rowMap->getNodeNumElements();
1215 int uniqueEdges =0;
1216 for(int i=0; i<numRows; i++ ){
1217 inzidenzMatrix->getLocalRowView(i, indices,values);
1218 uniqueEdges = uniqueEdges+indices.size();
1219 vec_GO_Type edgeTmp(2);
1220 for(int j=0; j<indices.size(); j++){
1221 edgeTmp[0] = rowMap->getGlobalElement(i);
1222 edgeTmp[1] = colMap->getGlobalElement(indices[j]);
1223 inzidenzIndicesUnique.push_back(edgeTmp);
1224 }
1225 }
1226
1227 exportLocalEntry->putScalar( uniqueEdges );
1228 MultiVectorLOPtr_Type newEdgesInterfaceGlobal= Teuchos::rcp( new MultiVectorLO_Type( mapGlobalProc, 1 ) );
1229 newEdgesInterfaceGlobal->putScalar( (LO) 0 );
1230 newEdgesInterfaceGlobal->importFromVector( exportLocalEntry, true, "Insert");
1231
1232 // offset EdgesUnique for proc and globally
1233 Teuchos::ArrayRCP< const LO > numUniqueInterface = newEdgesInterfaceGlobal->getData(0);
1234
1235 procOffsetEdges=0;
1236 for(int i=0; i< myRank; i++)
1237 procOffsetEdges= procOffsetEdges + numUniqueInterface[i];
1238
1239 int numInterfaceEdges=0;
1240
1241 vec_GO_Type uniqueInterfaceIDsList_(inzidenzIndicesUnique.size());
1242 for(int i=0; i< uniqueInterfaceIDsList_.size(); i++)
1243 uniqueInterfaceIDsList_[i] = procOffsetEdges + i;
1244
1245 MatrixPtr_Type indMatrix = Teuchos::rcp( new Matrix_Type(this->mapUnique_, 40 ) );
1246
1247 for(int i=0; i<inzidenzIndicesUnique.size(); i++ ){
1248 index[0] = inzidenzIndicesUnique[i][0];
1249 col[0] = inzidenzIndicesUnique[i][1];
1250 Teuchos::Array<SC> value2(1,uniqueInterfaceIDsList_[i]);
1251 indMatrix->insertGlobalValues(index[0], col(), value2());
1252 }
1253 indMatrix->fillComplete();
1254
1255 MatrixPtr_Type importMatrix = Teuchos::rcp( new Matrix_Type(this->mapRepeated_, 40 ) );
1256
1257 importMatrix->importFromVector(indMatrix,false,"Insert");
1258 importMatrix->fillComplete();
1259
1260 // Determine global indices
1261 GO edgeID=0;
1262 colMap = importMatrix->getMap("col");
1263 rowMap = importMatrix->getMap("row");
1264
1265 LO valueID=0;
1266 bool found = false;
1267 GO entry =0;
1268 for(int i=0; i<inzidenzIndices.size(); i++ ){
1269
1270 importMatrix->getLocalRowView(rowMap->getLocalElement(inzidenzIndices[i][0]), indices,values); // Indices and values connected to node i / row i in Matrix
1271 // Entries in 'indices' represent the local entry in 'colmap
1272 // with 'getGlobalElement' we know the global Node ID that belongs to the first Node that form an edge
1273 // vector in with entries only for edges belonging to node i;
1274 vec2D_GO_Type indicesTmp(indices.size(),vec_GO_Type(2));
1275 vec_GO_Type indTmp(2);
1276 for(int j=0; j<indices.size(); j++){
1277 indTmp[0] = colMap->getGlobalElement(indices[j]);
1278 indTmp[1] = values[j];
1279 indicesTmp.push_back(indTmp); // vector with the indices and values belonging to node i
1280 }
1281 found = false;
1282 for(int k=0; k<indicesTmp.size();k++){
1283 if(inzidenzIndices[i][1] == indicesTmp[k][0]){
1284 entry =k;
1285 k = indicesTmp.size();
1286 edgeID = indicesTmp[entry][1];
1287 vecGlobalIDsEdges.at(localEdgeIndex[i]) = offsetInterface + edgeID;
1288 found =true;
1289 }
1290 }
1291
1292 }
1293
1294
1295 Teuchos::RCP<std::vector<GO>> edgesGlobMapping = Teuchos::rcp( new std::vector<GO>( vecGlobalIDsEdges ) );
1296 Teuchos::ArrayView<GO> edgesGlobMappingArray = Teuchos::arrayViewFromVector( *edgesGlobMapping);
1297
1298 this->edgeMap_.reset(new Map<LO,GO,NO>( Teuchos::OrdinalTraits<GO>::invalid(), edgesGlobMappingArray, 0, this->comm_) );
1299 //this->edgeMap_->print();
1300}
1301
1302
1303template <class SC, class LO, class GO, class NO>
1305
1306 int numElement;
1307 int orderElement;
1308 int dim;
1309 int numNode;
1310 int numSurface = -1;
1311 int orderSurface = -1;
1312 int numEdges = 0;
1313 int orderEdges = 0;
1314 bool verbose ( this->comm_->getRank() == 0 );
1315
1316 if (verbose) {
1317 std::cout << "\n";
1318 std::cout << " Read data of mesh " << meshFileName_<< ":\n";
1319 }
1320
1321 meshReadSize ( meshFileName_, numNode, dim, numElement, orderElement, numSurface, orderSurface, numEdges, orderEdges );
1322
1323 if (verbose) {
1324 std::cout << "\n";
1325 std::cout << "\n";
1326 std::cout << " Number of nodes = " << numNode << "\n";
1327 std::cout << " Spatial dimension = " << dim << "\n";
1328 std::cout << " Number of elements = " << numElement << "\n";
1329 std::cout << " Element order = " << orderElement << "\n";
1330 std::cout << " Number of surface elements = " << numSurface << "\n";
1331 std::cout << " Surface element order = " << orderSurface << "\n";
1332 std::cout << " Number of edge elements (for 3D) = " << numEdges << "\n";
1333 std::cout << " Edges element order (for 3D) = " << orderEdges << "\n";
1334
1335 std::cout << "\n";
1336 std::cout << "\n";
1337 std::cout << " Starting to read the data. \n";
1338 }
1339
1340
1341 this->elementOrder_ = orderElement;
1342 this->surfaceElementOrder_ = orderSurface;
1343 this->edgesElementOrder_ = orderEdges;
1344 this->numSurfaces_ = numSurface;
1345 this->numEdges_ = numEdges;
1346 this->numNodes_ = numNode;
1347
1348 this->numElementsGlob_ = numElement;
1349}
1350
1351template <class SC, class LO, class GO, class NO>
1353
1354 if (entityType == "element")
1355 this->readElements( );
1356 else if (entityType == "surface")
1357 this->readSurfaces( );
1358 else if (entityType == "line")
1359 this->readLines( );
1360 else if (entityType == "node")
1361 this->readNodes( );
1362 else
1363 TEUCHOS_TEST_FOR_EXCEPTION( true, std::runtime_error, "Unknown entity type.");
1364}
1365
1366//template <class SC, class LO, class GO, class NO>
1367//void MeshUnstructured<SC,LO,GO,NO>::readSurfaces(){
1368// bool verbose ( this->comm_->getRank() == 0 );
1369// if (verbose)
1370// std::cout << "### Starting to read surface data ... " << std::flush;
1371//
1372// vec_int_Type surfaceFlags( numSurfaces_, 0 );
1373// vec_int_Type surfacesCont( numSurfaces_* surfaceElementOrder_, 0 );
1374//
1375// // We need the edges of surface elements to use special surface flags, which are only set on 1D line segments. We need to save these edges to determine the correct flag of P2 elements which might be build later
1376// meshReadData ( meshFileName_, "surface", delimiter_, this->getDimension(), numSurfaces_, surfaceElementOrder_, surfacesCont, surfaceFlags );
1377//
1378// if (verbose){
1379// std::cout << "done." << std::endl;
1380// std::cout << "### Setting surface data ... " << std::flush;
1381// }
1382// ElementsPtr_Type surfaceElementsMesh = this->getSurfaceElements();
1383//
1384// for (int i=0; i<numSurfaces_; i++) {
1385// vec_int_Type tmp(surfaceElementOrder_);
1386// for (int j=0; j<surfaceElementOrder_; j++)
1387// tmp.at(j) = surfacesCont.at( i * surfaceElementOrder_ + j ) - 1;// -1 to have start index 0
1388//
1389// sort( tmp.begin(), tmp.end() ); // we sort here in order to identify the corresponding element faster!
1390// FiniteElement feSurface( tmp , surfaceFlags[i] );
1391// surfaceElementsMesh->addElement( feSurface );
1392// }
1393//
1394//
1395// if (verbose)
1396// std::cout << "done." << std::endl;
1397//}
1398
1399//template <class SC, class LO, class GO, class NO>
1400//void MeshUnstructured<SC,LO,GO,NO>::readLines(){
1401// bool verbose ( this->comm_->getRank() == 0 );
1402// if (verbose)
1403// std::cout << "### Starting to read line data ... " << std::flush;
1404//
1405// vec_int_Type edgeFlags( numEdges_, 0 );
1406// vec_int_Type edgesCont( numEdges_* edgesElementOrder_, 0 );
1407//
1408// // We need the edges of surface elements to use special surface flags, which are only set on 1D line segments. We need to save these edges to determine the correct flag of P2 elements which might be build later
1409// meshReadData ( meshFileName_, "line", delimiter_, this->getDimension(), numEdges_, edgesElementOrder_, edgesCont, edgeFlags );
1410//
1411//
1412// if (verbose){
1413// std::cout << "done." << std::endl;
1414// std::cout << "### Setting line data ... " << std::flush;
1415// }
1416//
1417// ElementsPtr_Type edgeElementsMesh = this->getSurfaceEdgeElements();
1418//
1419// //Continous edge surface elements to FiniteElement object (only relevant in 3D)
1420// for (int i=0; i<numEdges_; i++) {
1421// vec_int_Type tmp(edgesElementOrder_);
1422// for (int j=0; j<edgesElementOrder_; j++)
1423// tmp.at(j) = edgesCont.at( i * edgesElementOrder_ + j ) - 1;// -1 to have start index 0
1424//
1425// sort( tmp.begin(), tmp.end() ); // we sort here in order to identify the corresponding element faster!
1426// FiniteElement feEdge( tmp , edgeFlags[i] );
1427// edgeElementsMesh->addElement( feEdge );
1428// }
1429//
1430// if (verbose)
1431// std::cout << "done." << std::endl;
1432//}
1433
1434template <class SC, class LO, class GO, class NO>
1435void MeshUnstructured<SC,LO,GO,NO>::readNodes(){
1436 bool verbose ( this->comm_->getRank() == 0 );
1437 if (verbose)
1438 std::cout << "### Starting to read node data ... " << std::flush;
1439
1440 vec_dbl_Type nodes(numNodes_ * this->getDimension(), 0.);
1441 vec_int_Type nodeFlags(numNodes_,0);
1442 meshReadData ( meshFileName_, "node", delimiter_, this->getDimension(), numNodes_, 3/*order of nodes is always 3*/, nodes, nodeFlags );
1443
1444 if (verbose){
1445 std::cout << "done." << std::endl;
1446 std::cout << "### Setting node data ... " << std::flush;
1447 }
1448 //Here, all points are saved on every proc
1449 this->pointsRep_.reset(new std::vector<std::vector<double> >(numNodes_,std::vector<double>(this->getDimension(),-1.)));
1450 this->bcFlagRep_.reset(new std::vector<int> (numNodes_,0));
1451
1452 FEDD_TIMER_START(pointsTimer," : MeshReader : Set Points not partitioned");
1453
1454 double scale=1.0;
1455 if(convertToCM_){
1456 if(meshUnitRead_ == "mm")
1457 scale = pow(10,-1);
1458 else if(meshUnitRead_ == "cm")
1459 scale = pow(10,0);
1460 else if(meshUnitRead_ == "dm")
1461 scale = pow(10,1);
1462 else if(meshUnitRead_ == "m")
1463 scale = pow(10,2);
1464 else
1465 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Meshunstr: Read Nodes() - convertToSI_ = true, but read unit unknown, please check.");
1466
1467 meshUnitFinal_ = "cm";
1468 if(this->comm_->getRank() == 0)
1469 std::cout << " Transforming the mesh with original unit " << meshUnitRead_ << " to unit cm." << std::endl;
1470 }
1471
1472 for (int i=0; i<numNodes_ ; i++) {
1473 for (int j=0; j<this->getDimension(); j++)
1474 this->pointsRep_->at(i).at(j) = scale*nodes[this->getDimension()*i+j];
1475
1476 this->bcFlagRep_->at(i) = nodeFlags[i];
1477 }
1478
1479 if (verbose)
1480 std::cout << "done." << std::endl;
1481}
1482
1483template <class SC, class LO, class GO, class NO>
1484void MeshUnstructured<SC,LO,GO,NO>::readElements(){
1485 bool verbose ( this->comm_->getRank() == 0 );
1486 if (verbose)
1487 std::cout << "### Starting to read element data ... " << std::flush;
1488
1489 vec_int_Type elementFlags( this->numElementsGlob_, 0 );
1490 vec_int_Type elementsCont( this->numElementsGlob_* this->elementOrder_, 0 );
1491
1492 // We need the edges of surface elements to use special surface flags, which are only set on 1D line segments. We need to save these edges to determine the correct flag of P2 elements which might be build later
1493 meshReadData ( meshFileName_, "element", delimiter_, this->getDimension(), this->numElementsGlob_, this->elementOrder_, elementsCont, elementFlags );
1494
1495 if (verbose){
1496 std::cout << "done." << std::endl;
1497 std::cout << "### Setting element data ... " << std::flush;
1498 }
1499 ElementsPtr_Type elementsMesh = this->getElementsC();
1500 elementsMesh->setFiniteElementType("P1");
1501 elementsMesh->setDimension(this->getDimension());
1502
1503
1504 int id;
1505 for (int i=0; i<this->numElementsGlob_; i++) {
1506 vec_int_Type tmp(this->elementOrder_);
1507 for (int j=0; j<this->elementOrder_; j++){
1508 id = elementsCont.at(i*this->elementOrder_ + j) - 1;
1509 tmp.at(j) = id;
1510 }
1511 FiniteElement fe( tmp , elementFlags[i] );
1512 elementsMesh->addElement( fe );
1513 }
1514
1515 if (verbose)
1516 std::cout << "done." << std::endl;
1517}
1518
1519
1520template <class SC, class LO, class GO, class NO>
1521void MeshUnstructured<SC,LO,GO,NO>::readSurfaces(){
1522 bool verbose ( this->comm_->getRank() == 0 );
1523 if (verbose)
1524 std::cout << "### Starting to read surface data ... " << std::flush;
1525
1526 vec_int_Type surfaceFlags( numSurfaces_, 0 );
1527 vec_int_Type surfacesCont( numSurfaces_* this->surfaceElementOrder_, 0 );
1528
1529 // We need the edges of surface elements to use special surface flags, which are only set on 1D line segments. We need to save these edges to determine the correct flag of P2 elements which might be build later
1530 meshReadData ( meshFileName_, "surface", delimiter_, this->getDimension(), numSurfaces_, this->surfaceElementOrder_, surfacesCont, surfaceFlags );
1531
1532 if (verbose){
1533 std::cout << "done." << std::endl;
1534 std::cout << "### Setting surface data ... " << std::flush;
1535 }
1536 ElementsPtr_Type surfaceElementsMesh = this->getSurfaceElements();
1537
1538 for (int i=0; i<numSurfaces_; i++) {
1539 vec_int_Type tmp(this->surfaceElementOrder_);
1540 for (int j=0; j<this->surfaceElementOrder_; j++)
1541 tmp.at(j) = surfacesCont.at( i * this->surfaceElementOrder_ + j ) - 1;// -1 to have start index 0
1542
1543 //cout << " Reading surfaces " << tmp[0] << " " << tmp[1] << " " << tmp[2] << std::endl;
1544 //sort( tmp.begin(), tmp.end() ); // we sort here in order to identify the corresponding element faster! !!! We refrain from that so the numbering of surface element nodes remains the consisten with respct to normals.
1545 FiniteElement feSurface( tmp , surfaceFlags[i] );
1546 surfaceElementsMesh->addElement( feSurface );
1547 }
1548
1549
1550 if (verbose)
1551 std::cout << "done." << std::endl;
1552}
1553
1554template <class SC, class LO, class GO, class NO>
1555void MeshUnstructured<SC,LO,GO,NO>::readLines(){
1556 bool verbose ( this->comm_->getRank() == 0 );
1557
1558 if (verbose)
1559 std::cout << "### Starting to read line data ... " << std::flush;
1560
1561 vec_int_Type edgeFlags( numEdges_, 0 );
1562 vec_int_Type edgesCont( numEdges_* this->edgesElementOrder_, 0 );
1563
1564 // We need the edges of surface elements to use special surface flags, which are only set on 1D line segments. We need to save these edges to determine the correct flag of P2 elements which might be build later
1565 meshReadData ( meshFileName_, "line", delimiter_, this->getDimension(), numEdges_, this->edgesElementOrder_, edgesCont, edgeFlags );
1566
1567
1568 if (verbose){
1569 std::cout << "done." << std::endl;
1570 std::cout << "### Setting line data ... " << std::flush;
1571 }
1572
1573 ElementsPtr_Type edgeElementsMesh = this->getSurfaceEdgeElements();
1574
1575 //Continous edge surface elements to FiniteElement object (only relevant in 3D)
1576 for (int i=0; i<numEdges_; i++) {
1577 vec_int_Type tmp(this->edgesElementOrder_);
1578 for (int j=0; j<this->edgesElementOrder_; j++)
1579 tmp.at(j) = edgesCont.at( i * this->edgesElementOrder_ + j ) - 1;// -1 to have start index 0
1580
1581 sort( tmp.begin(), tmp.end() ); // we sort here in order to identify the corresponding element faster!
1582 FiniteElement feEdge( tmp , edgeFlags[i] );
1583 edgeElementsMesh->addElement( feEdge );
1584 }
1585
1586 if (verbose)
1587 std::cout << "done." << std::endl;
1588}
1589template <class SC, class LO, class GO, class NO>
1590void MeshUnstructured<SC,LO,GO,NO>::exportMesh(MapConstPtr_Type mapUnique, MapConstPtr_Type mapRep, bool exportEdges, bool exportSurface, std::string meshName){
1591
1592
1593 std::ofstream myFile;
1594 if(this->comm_->getRank() ==0)
1595 myFile.open (meshName);
1596
1597 bool verbose = (this->comm_->getRank() == 0);
1598 if(verbose){
1599 std::cout << " --------------------------------------" << std::endl;
1600 std::cout << " ------------ Exporting Mesh ----------" << std::endl;
1601 std::cout << " --------------------------------------" << std::endl;
1602
1603 }
1604 // ################ Vertices #################
1605 int numberNodes = mapUnique->getGlobalNumElements();
1606
1607
1608 // ##########################################
1609 // Import missing nodes
1610 vec_GO_Type globalImportIDsNodes(0);
1611 for(int i = 0; i < this->mapUnique_->getGlobalNumElements(); i++)
1612 {
1613 if(this->mapUnique_->getLocalElement(i) == -1){
1614 globalImportIDsNodes.push_back(i);
1615 }
1616 }
1617 Teuchos::ArrayView<GO> globalNodesArrayImp = Teuchos::arrayViewFromVector( globalImportIDsNodes);
1618 // Map of global IDs with missing Elements
1619 MapPtr_Type mapNodesImport =
1620 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), globalNodesArrayImp, 0, this->getComm()) );
1621
1622 MultiVectorPtr_Type nodesImp = Teuchos::rcp( new MultiVector_Type( mapNodesImport, 1 ) );
1623 Teuchos::ArrayRCP< SC > entriesNodesImp = nodesImp->getDataNonConst(0);
1624
1625 MultiVectorPtr_Type nodesExport = Teuchos::rcp( new MultiVector_Type( this->mapUnique_, 1 ) );
1626 Teuchos::ArrayRCP< SC > entriesNodesExport = nodesExport->getDataNonConst(0);
1627
1628 vec2D_dbl_Type missingNodes(entriesNodesImp.size(),vec_dbl_Type(this->dim_+1));
1629
1630 for(int j= 0; j < this->dim_; j++)
1631 {
1632 for(int i=0; i< entriesNodesExport.size(); i++)
1633 entriesNodesExport[i] = this->getPointsUnique()->at(i).at(j);
1634
1635 nodesImp->importFromVector(nodesExport, false, "Insert");
1636 for(int i=0; i< entriesNodesImp.size(); i++)
1637 missingNodes[i][j] = entriesNodesImp[i];
1638
1639
1640 }
1641
1642 // Lastly import flags
1643 for(int i=0; i< entriesNodesExport.size(); i++)
1644 entriesNodesExport[i] = this->bcFlagUni_->at(i);
1645
1646 nodesImp->importFromVector(nodesExport, false, "Insert");
1647 for(int i=0; i< entriesNodesImp.size(); i++)
1648 missingNodes[i][this->dim_] = entriesNodesImp[i];
1649
1650 // #############################################
1651
1652 if(this->comm_->getRank() == 0){
1653 if(verbose)
1654 std::cout << " ----- Write Nodes .....";
1655
1656 myFile << "MeshVersionFormatted 2" << std::endl;
1657 myFile << "Dimension" << " " << this->dim_ << std::endl;
1658 myFile << std::endl;
1659 myFile << "Vertices";
1660 myFile << std::endl;
1661 myFile << numberNodes;
1662 myFile << std::endl;
1663 for(int i = 0; i < mapUnique->getGlobalNumElements(); i++)
1664 {
1665
1666 if(mapUnique->getLocalElement(i) != -1){
1667 LO id = mapUnique->getLocalElement(i);
1668 for(int j= 0; j < this->getPointsUnique()->at(id).size(); j++)
1669 {
1670 myFile << this->getPointsUnique()->at(id).at(j);
1671 myFile << " ";
1672 }
1673 if(this->dim_ == 2){
1674 myFile << 0.0;
1675 myFile << " ";
1676 }
1677 myFile << this->bcFlagUni_->at(id);
1678 myFile << std::endl;
1679 }
1680 else{
1681 LO id = mapNodesImport->getLocalElement(i);
1682 for(int j= 0; j < this->dim_; j++)
1683 {
1684 myFile << missingNodes[id][j];
1685 myFile << " ";
1686 }
1687 if(this->dim_ == 2){
1688 myFile << 0.0;
1689 myFile << " ";
1690 }
1691 myFile << missingNodes[id][this->dim_];
1692 myFile << std::endl;
1693 }
1694
1695
1696
1697 }
1698 myFile << std::endl;
1699 if(verbose)
1700 std::cout << ".... done ----- " << '\n';
1701
1702 }
1703
1704 // ################ Edges #################
1705 if(exportEdges){
1706 if(verbose)
1707 std::cout << " ----- Write Edges .....";
1708 int dofsEdges=2;
1709 if(this->FEType_ == "P2")
1710 dofsEdges=3;
1711 // Assumption in 2D no edge is subelement of two elements, as they are only subelement if they are part of the surface
1712 if(this->dim_ == 2)
1713 {
1714 vec2D_GO_Type edgesSubelements(0,vec_GO_Type(dofsEdges+1)); // nodes +
1715 ElementsPtr_Type elements = this->getElementsC();
1716 for(int T=0; T< elements->numberElements() ; T++){
1717 FiniteElement fe = elements->getElement( T );
1718 ElementsPtr_Type subEl = fe.getSubElements(); // might be null
1719 for (int surface=0; surface<fe.numSubElements(); surface++) {
1720 FiniteElement feSub = subEl->getElement( surface );
1721 vec_GO_Type edgeTmp;
1722 edgeTmp = {feSub.getVectorNodeList().at(0),feSub.getVectorNodeList().at(1),feSub.getFlag()};
1723 if(this->FEType_=="P2")
1724 edgeTmp = {feSub.getVectorNodeList().at(0),feSub.getVectorNodeList().at(1),feSub.getVectorNodeList().at(2),feSub.getFlag()};
1725
1726 edgesSubelements.push_back(edgeTmp);
1727 }
1728
1729 }
1730 // Local number of subelement edges:
1731 int numSubEl = edgesSubelements.size();
1732
1733 int maxRank = std::get<1>(this->rankRange_);
1734 vec_GO_Type globalProcs(0);
1735 for (int i=0; i<= maxRank; i++)
1736 globalProcs.push_back(i);
1737
1738 Teuchos::ArrayView<GO> globalProcArray = Teuchos::arrayViewFromVector( globalProcs);
1739
1740 vec_GO_Type localProc(0);
1741 localProc.push_back(this->comm_->getRank());
1742 Teuchos::ArrayView<GO> localProcArray = Teuchos::arrayViewFromVector( localProc);
1743
1744 MapPtr_Type mapGlobalProc =
1745 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), globalProcArray, 0, this->comm_) );
1746
1747 MapPtr_Type mapProc =
1748 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), localProcArray, 0, this->comm_) );
1749
1750 MultiVectorLOPtr_Type exportLocalEntry = Teuchos::rcp( new MultiVectorLO_Type( mapProc, 1 ) );
1751 exportLocalEntry->putScalar( (LO) numSubEl );
1752
1753 // map equal to the original edgeMap with zero entries
1754 MultiVectorLOPtr_Type numEdgesProc= Teuchos::rcp( new MultiVectorLO_Type( mapGlobalProc, 1 ) );
1755 numEdgesProc->putScalar( (LO) 0 );
1756 numEdgesProc->importFromVector( exportLocalEntry, false, "Insert");
1757
1758 // number of new elements per Processor
1759 Teuchos::ArrayRCP< const LO > edgesRanks = numEdgesProc->getData(0);
1760 vec_GO_Type vecGlobalIDsElements(0);
1761
1762 GO procOffsetElements=0;
1763 int myRank = this->comm_->getRank();
1764 for(int i=0; i< myRank; i++)
1765 procOffsetElements = procOffsetElements + edgesRanks[i];
1766
1767 for (int i=0; i<numSubEl; i++){
1768 vecGlobalIDsElements.push_back( i + procOffsetElements);
1769 }
1770
1771 Teuchos::RCP<std::vector<GO> > edgesGlobMapping = Teuchos::rcp( new std::vector<GO>( vecGlobalIDsElements ) );
1772 Teuchos::ArrayView<GO> edgesGlobMappingArray = Teuchos::arrayViewFromVector( *edgesGlobMapping);
1773 MapPtr_Type mapEdgesExport =
1774 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), edgesGlobMappingArray, 0, this->getComm()) );
1775
1776 vec_GO_Type vecGlobalIDsEdgesImport(0);
1777 int maxIndex = mapEdgesExport->getMaxAllGlobalIndex();
1778 if(this->comm_->getRank() == 0){
1779 for(int i=numSubEl; i<maxIndex+1 ; i++)
1780 vecGlobalIDsEdgesImport.push_back(i);
1781 }
1782 Teuchos::RCP<std::vector<GO> > edgesGlobMappingImport = Teuchos::rcp( new std::vector<GO>( vecGlobalIDsEdgesImport ) );
1783 Teuchos::ArrayView<GO> edgesGlobMappingImportArray = Teuchos::arrayViewFromVector( *edgesGlobMappingImport);
1784 MapPtr_Type mapEdgesImport =
1785 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), edgesGlobMappingImportArray, 0, this->getComm()) );
1786
1787 int numberEdges = maxIndex+1;
1788
1789 MultiVectorPtr_Type edgesImp = Teuchos::rcp( new MultiVector_Type( mapEdgesImport, 1 ) );
1790 Teuchos::ArrayRCP< SC > entriesEdgesImp = edgesImp->getDataNonConst(0);
1791
1792 MultiVectorPtr_Type edgesExport = Teuchos::rcp( new MultiVector_Type( mapEdgesExport , 1 ) );
1793 Teuchos::ArrayRCP< SC > entriesEdgesExport = edgesExport->getDataNonConst(0);
1794
1795
1796 vec2D_dbl_Type missingEdges(entriesEdgesImp.size(),vec_dbl_Type(dofsEdges+1));
1797
1798 for(int j= 0; j < dofsEdges+1; j++)
1799 {
1800 for(int i=0; i< entriesEdgesExport.size(); i++){
1801 if(j<dofsEdges)
1802 entriesEdgesExport[i] = mapRep->getGlobalElement(edgesSubelements[i][j]);
1803 else
1804 entriesEdgesExport[i] = edgesSubelements[i][j];
1805 }
1806
1807
1808 edgesImp->importFromVector(edgesExport, false, "Insert");
1809 for(int i=0; i< entriesEdgesImp.size(); i++)
1810 missingEdges[i][j] = entriesEdgesImp[i];
1811
1812 }
1813 if(this->comm_->getRank() == 0){
1814
1815 myFile << "Edges";
1816 myFile << std::endl;
1817 myFile << numberEdges;
1818 myFile << std::endl;
1819 for(int i = 0; i < mapEdgesExport->getGlobalNumElements(); i++)
1820 {
1821 if(mapEdgesExport->getLocalElement(i) != -1){
1822 LO id = this->edgeMap_->getLocalElement(i);
1823
1824 for(int j= 0; j < dofsEdges; j++)
1825 {
1826 myFile << mapRep->getGlobalElement(edgesSubelements[i][j])+1;
1827 myFile << " ";
1828 }
1829
1830 myFile << edgesSubelements[i][dofsEdges]; // Flag
1831 myFile << std::endl;
1832
1833
1834 }
1835 else{
1836 LO id = mapEdgesImport->getLocalElement(i);
1837 for(int j= 0; j < dofsEdges; j++)
1838 {
1839 myFile << missingEdges[id][j]+1;
1840 myFile << " ";
1841 }
1842 myFile << missingEdges[id][dofsEdges]; // Flag
1843 myFile << std::endl;
1844
1845 }
1846
1847 }
1848 myFile << std::endl;
1849 }
1850
1851 if(verbose)
1852 std::cout << ".... done ---- " << '\n';
1853
1854 }
1855 else if(this->dim_ == 3){
1856
1857 if(this->FEType_ != "P2") // In case of P2 this function was already called!
1858 this->assignEdgeFlags();
1859
1860 vec_GO_Type globalImportIDsEdges(0);
1861
1862 MapConstPtr_Type edgeMapUnique = this->edgeMap_->buildUniqueMap( this->rankRange_ );
1863
1864 vec2D_int_Type edgesUnique(edgeMapUnique->getNodeNumElements(),vec_int_Type(2,0));
1865 for (int i=0; i < edgeMapUnique->getNodeNumElements(); i++) {
1866 GO gid = edgeMapUnique->getGlobalElement( i );
1867 LO id = this->edgeMap_->getLocalElement( gid );
1868 edgesUnique[i] = this->edgeElements_->getElement(id).getVectorNodeListNonConst();
1869
1870 }
1871 if(this->comm_->getRank() == 0){
1872 for(int i = 0; i < edgeMapUnique->getGlobalNumElements(); i++)
1873 {
1874 if(edgeMapUnique->getLocalElement(i) == -1){
1875 globalImportIDsEdges.push_back(i);
1876 }
1877 }
1878 }
1879 int numberEdges = edgeMapUnique->getGlobalNumElements();
1880
1881 Teuchos::ArrayView<GO> globalEdgesArrayImp = Teuchos::arrayViewFromVector( globalImportIDsEdges);
1882 // Map of global IDs with missing Elements
1883 MapPtr_Type mapEdgesImport =
1884 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), globalEdgesArrayImp, 0, this->getComm()) );
1885
1886 MultiVectorPtr_Type edgesImp = Teuchos::rcp( new MultiVector_Type( mapEdgesImport, 1 ) );
1887 Teuchos::ArrayRCP< SC > entriesEdgesImp = edgesImp->getDataNonConst(0);
1888
1889 MultiVectorPtr_Type edgesExport = Teuchos::rcp( new MultiVector_Type( edgeMapUnique, 1 ) );
1890 Teuchos::ArrayRCP< SC > entriesEdgesExport = edgesExport->getDataNonConst(0);
1891
1892 vec2D_dbl_Type missingEdges(entriesEdgesImp.size(),vec_dbl_Type(dofsEdges+1));
1893
1894 for(int j= 0; j < 2; j++)
1895 {
1896 for(int i=0; i< entriesEdgesExport.size(); i++)
1897 entriesEdgesExport[i] = mapRep->getGlobalElement(edgesUnique[i][j])+1;
1898
1899 edgesImp->importFromVector(edgesExport, false, "Insert");
1900 for(int i=0; i< entriesEdgesImp.size(); i++)
1901 missingEdges[i][j] = entriesEdgesImp[i];
1902
1903 }
1904 if(this->FEType_ == "P2"){
1905 for(int i=0; i< entriesEdgesExport.size(); i++){
1906 GO gid = edgeMapUnique->getGlobalElement( i );
1907 LO id = this->edgeMap_->getLocalElement( gid );
1908 entriesEdgesExport[i] = mapRep->getGlobalElement(this->edgeElements_->getMidpoint(id))+1;
1909 }
1910
1911 edgesImp->importFromVector(edgesExport, false, "Insert");
1912 for(int i=0; i< entriesEdgesImp.size(); i++)
1913 missingEdges[i][2] = entriesEdgesImp[i];
1914
1915 }
1916 // Lastly import flags
1917 for(int i=0; i< entriesEdgesExport.size(); i++){
1918 GO gid = edgeMapUnique->getGlobalElement( i );
1919 LO id = this->edgeMap_->getLocalElement( gid);
1920 entriesEdgesExport[i] = this->edgeElements_->getElement(id).getFlag();
1921 }
1922
1923 edgesImp->importFromVector(edgesExport, false, "Insert");
1924 for(int i=0; i< entriesEdgesImp.size(); i++)
1925 missingEdges[i][dofsEdges] = entriesEdgesImp[i];
1926
1927 // ########## Writing #######################
1928 if(this->comm_->getRank() == 0){
1929
1930
1931 vec2D_int_Type edges(0,vec_int_Type(0));
1932 for(int i = 0; i < edgeMapUnique->getGlobalNumElements(); i++)
1933 {
1934 vec_int_Type entry(0);
1935 if(edgeMapUnique->getLocalElement(i) != -1){
1936 LO id = this->edgeMap_->getLocalElement(i);
1937 if(this->edgeElements_->getElement(id).getFlag() < this->volumeID_)
1938 {
1939 for(int j= 0; j < 2; j++)
1940 {
1941 entry.push_back(mapRep->getGlobalElement(this->edgeElements_->getElement(id).getVectorNodeList().at(j))+1);
1942 }
1943 if(this->FEType_ == "P2")
1944 entry.push_back(mapRep->getGlobalElement(this->edgeElements_->getMidpoint(id))+1);
1945
1946 entry.push_back(this->edgeElements_->getElement(id).getFlag());
1947
1948 edges.push_back(entry);
1949
1950 }
1951
1952 }
1953 else{
1954 LO id = mapEdgesImport->getLocalElement(i);
1955 if(missingEdges[id][dofsEdges]< this->volumeID_){
1956
1957 for(int j= 0; j < dofsEdges; j++)
1958 {
1959 entry.push_back(missingEdges[id][j]);
1960 }
1961 entry.push_back(missingEdges[id][dofsEdges]);
1962
1963 edges.push_back(entry);
1964
1965 }
1966 }
1967 }
1968
1969
1970 myFile << "Edges";
1971 myFile << std::endl;
1972 myFile << edges.size();
1973 myFile << std::endl;
1974
1975 for(int i = 0; i < edges.size(); i++)
1976 {
1977
1978 for(int j= 0; j < 2; j++)
1979 {
1980 myFile << edges[i][j]; //mapRep->getGlobalElement(this->edgeElements_->getElement(id).getVectorNodeList().at(j))+1;
1981 myFile << " ";
1982 }
1983 if(this->FEType_ == "P2")
1984 myFile << edges[i][2]; //mapRep->getGlobalElement(this->edgeElements_->getMidpoint(id))+1 << " ";
1985
1986 myFile << edges[i][edges[i].size()-1]; // this->edgeElements_->getElement(id).getFlag(); last entry
1987 myFile << std::endl;
1988
1989 }
1990
1991 }
1992 myFile << std::endl;
1993 if(verbose)
1994 std::cout << ".... done ----- " << '\n';
1995 }
1996
1997
1998 }
1999 this->comm_->barrier();
2000 // ################ Surfaces #################
2001 if(exportSurface && this->dim_ >2){
2002 if(verbose)
2003 std::cout << " ----- Write Surfaces ...";
2004 int dofsSurfaces=3;
2005 if(this->FEType_ == "P2")
2006 dofsSurfaces=6;
2007 // Assumption in 2D no edge is subelement of two elements, as they are only subelement if they are part of the surface
2008 if(this->dim_ == 3)
2009 {
2010 vec2D_GO_Type surfacesSubelements(0,vec_GO_Type(dofsSurfaces+1)); // nodes +
2011 ElementsPtr_Type elements = this->getElementsC();
2012 for(int T=0; T< elements->numberElements() ; T++){
2013 FiniteElement fe = elements->getElement( T );
2014 for (int surface=0; surface<fe.numSubElements(); surface++) {
2015 ElementsPtr_Type subEl = fe.getSubElements(); // might be null
2016 if(subEl->getDimension() == this->dim_-1 ){
2017 FiniteElement feSub = subEl->getElement( surface );
2018 vec_GO_Type surfaceTmp;
2019 surfaceTmp = {feSub.getVectorNodeList().at(0),feSub.getVectorNodeList().at(1),feSub.getVectorNodeList().at(2),feSub.getFlag()};
2020 if(this->FEType_=="P2")
2021 surfaceTmp = {feSub.getVectorNodeList().at(0),feSub.getVectorNodeList().at(1),feSub.getVectorNodeList().at(2),feSub.getVectorNodeList().at(3),feSub.getVectorNodeList().at(4),feSub.getVectorNodeList().at(5),feSub.getFlag()};
2022
2023 surfacesSubelements.push_back(surfaceTmp);
2024 }
2025 }
2026 }
2027 // Local number of subelement edges:
2028 int numSubEl = surfacesSubelements.size();
2029
2030 int maxRank = std::get<1>(this->rankRange_);
2031 vec_GO_Type globalProcs(0);
2032 for (int i=0; i<= maxRank; i++)
2033 globalProcs.push_back(i);
2034
2035 Teuchos::ArrayView<GO> globalProcArray = Teuchos::arrayViewFromVector( globalProcs);
2036
2037 vec_GO_Type localProc(0);
2038 localProc.push_back(this->comm_->getRank());
2039 Teuchos::ArrayView<GO> localProcArray = Teuchos::arrayViewFromVector( localProc);
2040
2041 MapPtr_Type mapGlobalProc =
2042 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), globalProcArray, 0, this->comm_) );
2043
2044 MapPtr_Type mapProc =
2045 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), localProcArray, 0, this->comm_) );
2046
2047 MultiVectorLOPtr_Type exportLocalEntry = Teuchos::rcp( new MultiVectorLO_Type( mapProc, 1 ) );
2048 exportLocalEntry->putScalar( (LO) numSubEl );
2049 // map equal to the original edgeMap with zero entries
2050 MultiVectorLOPtr_Type numSurfacesProc= Teuchos::rcp( new MultiVectorLO_Type( mapGlobalProc, 1 ) );
2051 numSurfacesProc->putScalar( (LO) 0 );
2052 numSurfacesProc->importFromVector( exportLocalEntry, false, "Insert");
2053 // number of new elements per Processor
2054 Teuchos::ArrayRCP< const LO > surfacesRanks = numSurfacesProc->getData(0);
2055 vec_GO_Type vecGlobalIDsElements(0);
2056
2057 GO procOffsetElements=0;
2058 int myRank = this->comm_->getRank();
2059 for(int i=0; i< myRank; i++)
2060 procOffsetElements = procOffsetElements + surfacesRanks[i];
2061
2062 for (int i=0; i<numSubEl; i++){
2063 vecGlobalIDsElements.push_back( i + procOffsetElements);
2064 }
2065
2066 Teuchos::RCP<std::vector<GO> > surfacesGlobMapping = Teuchos::rcp( new std::vector<GO>( vecGlobalIDsElements ) );
2067 Teuchos::ArrayView<GO> surfacesGlobMappingArray = Teuchos::arrayViewFromVector( *surfacesGlobMapping);
2068 MapPtr_Type mapSurfacesExport =
2069 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), surfacesGlobMappingArray, 0, this->getComm()) );
2070
2071
2072 vec_GO_Type vecGlobalIDsSurfacesImport(0);
2073 int maxIndex = mapSurfacesExport->getMaxAllGlobalIndex();
2074 if(this->comm_->getRank() == 0){
2075 for(int i=numSubEl; i<maxIndex+1 ; i++)
2076 vecGlobalIDsSurfacesImport.push_back(i);
2077 }
2078 Teuchos::RCP<std::vector<GO> > surfacesGlobMappingImport = Teuchos::rcp( new std::vector<GO>( vecGlobalIDsSurfacesImport ) );
2079 Teuchos::ArrayView<GO> surfacesGlobMappingImportArray = Teuchos::arrayViewFromVector( *surfacesGlobMappingImport);
2080 MapPtr_Type mapSurfacesImport =
2081 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), surfacesGlobMappingImportArray, 0, this->getComm()) );
2082
2083 int numberSurfaces = maxIndex+1;
2084
2085 MultiVectorPtr_Type surfacesImp = Teuchos::rcp( new MultiVector_Type( mapSurfacesImport, 1 ) );
2086 Teuchos::ArrayRCP< SC > entriesSurfacesImp = surfacesImp->getDataNonConst(0);
2087
2088 MultiVectorPtr_Type surfacesExport = Teuchos::rcp( new MultiVector_Type( mapSurfacesExport , 1 ) );
2089 Teuchos::ArrayRCP< SC > entriesSurfacesExport = surfacesExport->getDataNonConst(0);
2090
2091
2092 vec2D_dbl_Type missingSurfaces(entriesSurfacesImp.size(),vec_dbl_Type(dofsSurfaces+1));
2093
2094 for(int j= 0; j < dofsSurfaces+1; j++)
2095 {
2096 for(int i=0; i< entriesSurfacesExport.size(); i++){
2097 if(j<dofsSurfaces)
2098 entriesSurfacesExport[i] = mapRep->getGlobalElement(surfacesSubelements[i][j]);
2099 else{
2100 entriesSurfacesExport[i] = surfacesSubelements[i][j]; // FLAG!
2101 }
2102 }
2103 surfacesImp->importFromVector(surfacesExport, false, "Insert");
2104 for(int i=0; i< entriesSurfacesImp.size(); i++)
2105 missingSurfaces[i][j] = entriesSurfacesImp[i];
2106
2107 }
2108 if(this->comm_->getRank() == 0){
2109
2110 myFile << "Triangles";
2111 myFile << std::endl;
2112 myFile << numberSurfaces;
2113 myFile << std::endl;
2114 for(int i = 0; i < mapSurfacesExport->getGlobalNumElements(); i++)
2115 {
2116 if(mapSurfacesExport->getLocalElement(i) != -1){
2117
2118 for(int j= 0; j < dofsSurfaces; j++)
2119 {
2120 myFile << mapRep->getGlobalElement(surfacesSubelements[i][j])+1;
2121 myFile << " ";
2122 }
2123
2124
2125 myFile << surfacesSubelements[i][dofsSurfaces];
2126 myFile << std::endl;
2127
2128
2129 }
2130 else{
2131 LO id = mapSurfacesImport->getLocalElement(i);
2132 for(int j= 0; j < dofsSurfaces; j++)
2133 {
2134 myFile << missingSurfaces[id][j]+1;
2135 myFile << " ";
2136 }
2137 myFile << missingSurfaces[id][dofsSurfaces];
2138 myFile << std::endl;
2139
2140 }
2141
2142 }
2143 myFile << std::endl;
2144 }
2145
2146
2147 }
2148 if(verbose)
2149 std::cout << "... done -----" << '\n';
2150
2151 }
2152
2153
2154 // ################ Elements #################
2155 this->comm_->barrier();
2156
2157 if(verbose)
2158 std::cout << " ----- Write Elements ...";
2159
2160 // ###########################################
2161 // 1. Import missing Elements
2162 vec_GO_Type globalImportIDs(0);
2163 for(int i = 0; i < this->elementMap_->getGlobalNumElements(); i++)
2164 {
2165 if(this->elementMap_->getLocalElement(i) == -1){
2166 globalImportIDs.push_back(i);
2167 }
2168 }
2169 Teuchos::ArrayView<GO> globalElementArrayImp = Teuchos::arrayViewFromVector( globalImportIDs);
2170 // Map of global IDs with missing Elements
2171 MapPtr_Type mapElementImport =
2172 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), globalElementArrayImp, 0, this->getComm()) );
2173
2174 MultiVectorPtr_Type idsElement = Teuchos::rcp( new MultiVector_Type( mapElementImport, 1 ) );
2175 Teuchos::ArrayRCP< SC > entriesElement = idsElement->getDataNonConst(0);
2176
2177 MultiVectorPtr_Type idsElementExport = Teuchos::rcp( new MultiVector_Type( this->elementMap_, 1 ) );
2178 Teuchos::ArrayRCP< SC > entriesElementExport = idsElementExport->getDataNonConst(0);
2179
2180 int dofsElement = this->getElements()->at(0).size();
2181 vec2D_GO_Type missingElements(entriesElement.size(),vec_GO_Type(dofsElement+1));
2182
2183 for(int j= 0; j < this->getElements()->at(0).size(); j++)
2184 {
2185 for(int i=0; i< entriesElementExport.size(); i++)
2186 entriesElementExport[i] = mapRep->getGlobalElement(this->getElements()->at(i).at(j))+1;
2187
2188 idsElement->importFromVector(idsElementExport, false, "Insert");
2189 for(int i=0; i< entriesElement.size(); i++)
2190 missingElements[i][j] = entriesElement[i];
2191 }
2192 for(int i=0; i< entriesElementExport.size(); i++)
2193 entriesElementExport[i] = this->getElementsC()->getElement(i).getFlag();
2194
2195 idsElement->importFromVector(idsElementExport, false, "Insert");
2196 for(int i=0; i< entriesElement.size(); i++)
2197 missingElements[i][dofsElement] = entriesElement[i];
2198 // --------------------------------------
2199 if(this->comm_->getRank() == 0){
2200
2201 if(this->dim_ == 2)
2202 myFile << "Triangles";
2203 else if(this->dim_ ==3)
2204 myFile << "Tetrahedra";
2205
2206 myFile << std::endl;
2207
2208 int numberElements = this->elementMap_->getGlobalNumElements();
2209
2210 myFile << numberElements;
2211 myFile << std::endl;
2212
2213 for(int i = 0; i < this->elementMap_->getGlobalNumElements(); i++)
2214 {
2215 if(this->elementMap_->getLocalElement(i) != -1){
2216 LO id = this->elementMap_->getLocalElement(i);
2217
2218 for(int j= 0; j < this->getElements()->at(id).size(); j++)
2219 {
2220 myFile << mapRep->getGlobalElement(this->getElements()->at(id).at(j))+1;
2221 myFile << " ";
2222 }
2223 myFile << this->getElementsC()->getElement(id).getFlag();
2224 myFile << std::endl;
2225
2226 }
2227 else{
2228 LO id = mapElementImport->getLocalElement(i);
2229 for(int j= 0; j < dofsElement; j++)
2230 {
2231 myFile << missingElements[id][j];
2232 myFile << " ";
2233 }
2234 myFile << missingElements[id][dofsElement];
2235 myFile << std::endl;
2236 }
2237
2238 }
2239 if(verbose)
2240 std::cout << "... done ----- " << '\n';
2241
2242 }
2243 if(this->comm_->getRank() ==0)
2244 myFile.close();
2245 if(verbose){
2246 std::cout << " --------------------------------------" << std::endl;
2247 std::cout << " ------- Finished exporting Mesh ------" << std::endl;
2248 std::cout << " ------- File Name: " << meshName << " -------" << std::endl;
2249 if(this->dim_ == 3)
2250 std::cout << " - Info: In 3D all edges are exported -" << std::endl;
2251
2252 std::cout << " --------------------------------------" << std::endl;
2253
2254 }
2255 this->comm_->barrier();
2256
2257
2258}
2259
2260}
2261#endif
Definition Elements.hpp:23
Definition FiniteElement.hpp:17
Definition Map_decl.hpp:30
Definition MeshInterface_decl.hpp:19
void buildEdgeMap()
Building an edgemap from scratch when edges are already distributed parallel.
Definition MeshUnstructured_def.hpp:1099
void buildP2ofP1MeshEdge(MeshUnstrPtr_Type meshP1)
Function to build a P2 mesh of a P1 mesh.
Definition MeshUnstructured_def.hpp:121
void setSurfaceP2(FiniteElement &feP2, const FiniteElement &surfFeP1, const vec2D_int_Type &surfacePermutation, int dim)
Helper function for setP2SurfaceElements. Adds the correct nodes to the meshP1 subelements....
Definition MeshUnstructured_def.hpp:402
void addSurfaceP2Nodes(FiniteElement &feP2, const FiniteElement &surfFeP1, const vec2D_int_Type &surfacePermutation, int dim)
Helper function for setP2SurfaceElements. Adds the correct nodes to the meshP1 subelements....
Definition MeshUnstructured_def.hpp:330
void readMeshSize()
Reading mesh size.
Definition MeshUnstructured_def.hpp:1304
void exportMesh(MapConstPtr_Type mapUnique, MapConstPtr_Type mapRep, bool exportEdges=false, bool exportSurface=false, std::string meshName="export.mesh")
Exporting Mesh as .mesh file. For most detailed export we also write surfaces and edges....
Definition MeshUnstructured_def.hpp:1590
int determineFlagP2(FiniteElement &fe, LO p1ID, LO p2ID, vec2D_int_Type &permutation)
Essentially determine flag of an edge. Thus determine P2 Flag for building P2 mesh.
Definition MeshUnstructured_def.hpp:737
void setMeshFileName(std::string meshFileName, std::string delimiter)
Set the .mesh file name.
Definition MeshUnstructured_def.hpp:950
void setP2SurfaceElements(MeshUnstrPtr_Type meshP1)
Adding the correct surface subelement to the new P2 Elements based on the P1 subelements.
Definition MeshUnstructured_def.hpp:283
EdgeElementsPtr_Type getEdgeElements()
Get EdgeElements.
Definition MeshUnstructured_decl.hpp:186
vec_int_Type reorderP2SurfaceIndices(vec_int_Type &additionalP2IDs, vec_int_Type &index, bool track=false)
Depending on the sorting of P1 surface nodes we have to adjust the new ordering of P2 edge midpoints ...
Definition MeshUnstructured_def.hpp:521
void getLocalSurfaceIndices(vec2D_int_Type &surfacePermutation, int surfaceElementOrder)
Get local Surface Indices.
Definition MeshUnstructured_def.hpp:625
void getEdgeCombinations(vec2D_int_Type &edgeCombinations)
Get edge combinations.
Definition MeshUnstructured_def.hpp:670
void determinePositionInElementP2(vec_int_Type &positions, vec_GO_Type &elementsGlobalOfEdge, LO p1ID, LO p2ID, MeshUnstrPtr_Type meshP1)
Determine position of new P2 node in element, as all elements should follow the same structure.
Definition MeshUnstructured_def.hpp:689
void findEdges(const vec_int_Type &elementNodeList, vec_int_Type numbering, vec2D_int_Type &localEdgeNodeList_vec, vec_int_Type &locEdges)
Determine which edges belong to an element.
Definition MeshUnstructured_def.hpp:904
void assignEdgeFlags()
Assigning flags to all edges.
Definition MeshUnstructured_def.hpp:965
void readMeshEntity(std::string entityType)
Reading the .mesh files entities.
Definition MeshUnstructured_def.hpp:1352
MeshInterfacePtr_Type getMeshInterface()
Get mesh interface.
Definition MeshUnstructured_def.hpp:922
Definition Mesh_decl.hpp:25
ElementsPtr_Type getElementsC()
Definition Mesh_def.hpp:148
CommConstPtrConst_Type getComm()
Definition Mesh_decl.hpp:138
MapConstPtr_Type getEdgeMap()
Definition Mesh_def.hpp:118
vec2D_dbl_ptr_Type getPointsUnique() const
Definition Mesh_def.hpp:130
vec_int_ptr_Type getBCFlagRepeated() const
Definition Mesh_def.hpp:136
MapConstPtr_Type getElementMap() const
Definition Mesh_def.hpp:111
vec2D_int_ptr_Type getElements()
Definition Mesh_def.hpp:431
MapConstPtr_Type getMapRepeated() const
Definition Mesh_def.hpp:105
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement_decl.hpp:36