Finite Element Domain Decomposition Library
FEDDLib
Loading...
Searching...
No Matches
MeshUnstructured_def.hpp
1#ifndef MESHUNSTRUCTURED_def_hpp
2#define MESHUNSTRUCTURED_def_hpp
3#include "MeshUnstructured_decl.hpp"
4#include "feddlib/core/LinearAlgebra/MultiVector_def.hpp"
5
14
15using Teuchos::reduceAll;
16using Teuchos::REDUCE_SUM;
17using Teuchos::outArg;
18
19namespace FEDD {
20
21template <class SC, class LO, class GO, class NO>
22MeshUnstructured<SC,LO,GO,NO>::MeshUnstructured():
23Mesh<SC,LO,GO,NO>(),
24meshInterface_(),
25volumeID_(10),
26edgeElements_(),
27surfaceEdgeElements_(),
28meshFileName_("fileName.mesh"),
29delimiter_(" ")
30//#ifdef FULL_TIMER
31//,TotalP1ToP2Time_(Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Total P1 to P2")),
32//BuildRedundantInfoTime_ (Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Build Redundant Info")),
33//SortUniqueRedundantInfoTime_ (Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Sort Unique redundant")),
34//CheckingFlaggedAndDeleteTime_ (Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Flagged & Delete Interior")),
35//CheckingFlaggedTime_ (Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Flagged & Delete Interior: Flagged")),
36//DeleteInteriorTime_(Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Flagged & Delete Interior: Interior")),
37//SetGlobalInterfaceIDTime_ (Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Set Global IDs")),
38//SetP2InfoTime_(Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Set P2 Information")),
39//GatherAllMarkedTime_(Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Flagged & Delete Interior: Flagged: Gather All")),
40//UniqueAndFindMarkedTime_(Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Flagged & Delete Interior: Flagged: Unique and MaxAll")),
41//UniqueNewFaceTime_(Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Flagged & Delete Interior: Flagged: Unique new Faces")),
42//SumAllMarkedTime_(Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Flagged & Delete Interior: Flagged: Sum All")),
43//SetP2PointsTime_(Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Set P2 Information: Set Points")),
44//SetP2ElementsTime_(Teuchos::TimeMonitor::getNewCounter("FE: Unstructured Mesh: Set P2 Information: Set Elements"))
45//#endif
46{
47 edgeElements_ = Teuchos::rcp( new EdgeElements_Type() );
48 surfaceEdgeElements_ = Teuchos::rcp( new Elements_Type() );
49
50}
51
52template <class SC, class LO, class GO, class NO>
53MeshUnstructured<SC,LO,GO,NO>::MeshUnstructured(CommConstPtr_Type comm, int volumeID):
54Mesh<SC,LO,GO,NO>(comm),
55meshInterface_(),
56volumeID_(volumeID),
57edgeElements_(),
58surfaceEdgeElements_(),
59meshFileName_("fileName.mesh"),
60delimiter_(" ")
61{
62 edgeElements_ = Teuchos::rcp( new EdgeElements_Type() );
63 surfaceEdgeElements_ = Teuchos::rcp( new Elements_Type() );
64
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 }
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;
105 }
106
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 }
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();
139
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
170
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
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();
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);
208 }
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
219
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_;
224
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 for (int i=0; i<numNodes_ ; i++) {
1455 for (int j=0; j<this->getDimension(); j++)
1456 this->pointsRep_->at(i).at(j) = nodes[this->getDimension()*i+j];
1457
1458 this->bcFlagRep_->at(i) = nodeFlags[i];
1459 }
1460
1461 if (verbose)
1462 std::cout << "done." << std::endl;
1463}
1464
1465template <class SC, class LO, class GO, class NO>
1466void MeshUnstructured<SC,LO,GO,NO>::readElements(){
1467 bool verbose ( this->comm_->getRank() == 0 );
1468 if (verbose)
1469 std::cout << "### Starting to read element data ... " << std::flush;
1470
1471 vec_int_Type elementFlags( this->numElementsGlob_, 0 );
1472 vec_int_Type elementsCont( this->numElementsGlob_* this->elementOrder_, 0 );
1473
1474 // 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
1475 meshReadData ( meshFileName_, "element", delimiter_, this->getDimension(), this->numElementsGlob_, this->elementOrder_, elementsCont, elementFlags );
1476
1477 if (verbose){
1478 std::cout << "done." << std::endl;
1479 std::cout << "### Setting element data ... " << std::flush;
1480 }
1481 ElementsPtr_Type elementsMesh = this->getElementsC();
1482 elementsMesh->setFiniteElementType("P1");
1483 elementsMesh->setDimension(this->getDimension());
1484
1485
1486 int id;
1487 for (int i=0; i<this->numElementsGlob_; i++) {
1488 vec_int_Type tmp(this->elementOrder_);
1489 for (int j=0; j<this->elementOrder_; j++){
1490 id = elementsCont.at(i*this->elementOrder_ + j) - 1;
1491 tmp.at(j) = id;
1492 }
1493 FiniteElement fe( tmp , elementFlags[i] );
1494 elementsMesh->addElement( fe );
1495 }
1496
1497 if (verbose)
1498 std::cout << "done." << std::endl;
1499}
1500
1501
1502template <class SC, class LO, class GO, class NO>
1503void MeshUnstructured<SC,LO,GO,NO>::readSurfaces(){
1504 bool verbose ( this->comm_->getRank() == 0 );
1505 if (verbose)
1506 std::cout << "### Starting to read surface data ... " << std::flush;
1507
1508 vec_int_Type surfaceFlags( numSurfaces_, 0 );
1509 vec_int_Type surfacesCont( numSurfaces_* this->surfaceElementOrder_, 0 );
1510
1511 // 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
1512 meshReadData ( meshFileName_, "surface", delimiter_, this->getDimension(), numSurfaces_, this->surfaceElementOrder_, surfacesCont, surfaceFlags );
1513
1514 if (verbose){
1515 std::cout << "done." << std::endl;
1516 std::cout << "### Setting surface data ... " << std::flush;
1517 }
1518 ElementsPtr_Type surfaceElementsMesh = this->getSurfaceElements();
1519
1520 for (int i=0; i<numSurfaces_; i++) {
1521 vec_int_Type tmp(this->surfaceElementOrder_);
1522 for (int j=0; j<this->surfaceElementOrder_; j++)
1523 tmp.at(j) = surfacesCont.at( i * this->surfaceElementOrder_ + j ) - 1;// -1 to have start index 0
1524
1525 //cout << " Reading surfaces " << tmp[0] << " " << tmp[1] << " " << tmp[2] << std::endl;
1526 //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.
1527 FiniteElement feSurface( tmp , surfaceFlags[i] );
1528 surfaceElementsMesh->addElement( feSurface );
1529 }
1530
1531
1532 if (verbose)
1533 std::cout << "done." << std::endl;
1534}
1535
1536template <class SC, class LO, class GO, class NO>
1537void MeshUnstructured<SC,LO,GO,NO>::readLines(){
1538 bool verbose ( this->comm_->getRank() == 0 );
1539
1540 if (verbose)
1541 std::cout << "### Starting to read line data ... " << std::flush;
1542
1543 vec_int_Type edgeFlags( numEdges_, 0 );
1544 vec_int_Type edgesCont( numEdges_* this->edgesElementOrder_, 0 );
1545
1546 // 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
1547 meshReadData ( meshFileName_, "line", delimiter_, this->getDimension(), numEdges_, this->edgesElementOrder_, edgesCont, edgeFlags );
1548
1549
1550 if (verbose){
1551 std::cout << "done." << std::endl;
1552 std::cout << "### Setting line data ... " << std::flush;
1553 }
1554
1555 ElementsPtr_Type edgeElementsMesh = this->getSurfaceEdgeElements();
1556
1557 //Continous edge surface elements to FiniteElement object (only relevant in 3D)
1558 for (int i=0; i<numEdges_; i++) {
1559 vec_int_Type tmp(this->edgesElementOrder_);
1560 for (int j=0; j<this->edgesElementOrder_; j++)
1561 tmp.at(j) = edgesCont.at( i * this->edgesElementOrder_ + j ) - 1;// -1 to have start index 0
1562
1563 sort( tmp.begin(), tmp.end() ); // we sort here in order to identify the corresponding element faster!
1564 FiniteElement feEdge( tmp , edgeFlags[i] );
1565 edgeElementsMesh->addElement( feEdge );
1566 }
1567
1568 if (verbose)
1569 std::cout << "done." << std::endl;
1570}
1571template <class SC, class LO, class GO, class NO>
1572void MeshUnstructured<SC,LO,GO,NO>::exportMesh(MapConstPtr_Type mapUnique, MapConstPtr_Type mapRep, bool exportEdges, bool exportSurface, std::string meshName){
1573
1574
1575 std::ofstream myFile;
1576 if(this->comm_->getRank() ==0)
1577 myFile.open (meshName);
1578
1579 bool verbose = (this->comm_->getRank() == 0);
1580 if(verbose){
1581 std::cout << " --------------------------------------" << std::endl;
1582 std::cout << " ------------ Exporting Mesh ----------" << std::endl;
1583 std::cout << " --------------------------------------" << std::endl;
1584
1585 }
1586 // ################ Vertices #################
1587 int numberNodes = mapUnique->getGlobalNumElements();
1588
1589
1590 // ##########################################
1591 // Import missing nodes
1592 vec_GO_Type globalImportIDsNodes(0);
1593 for(int i = 0; i < this->mapUnique_->getGlobalNumElements(); i++)
1594 {
1595 if(this->mapUnique_->getLocalElement(i) == -1){
1596 globalImportIDsNodes.push_back(i);
1597 }
1598 }
1599 Teuchos::ArrayView<GO> globalNodesArrayImp = Teuchos::arrayViewFromVector( globalImportIDsNodes);
1600 // Map of global IDs with missing Elements
1601 MapPtr_Type mapNodesImport =
1602 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), globalNodesArrayImp, 0, this->getComm()) );
1603
1604 MultiVectorPtr_Type nodesImp = Teuchos::rcp( new MultiVector_Type( mapNodesImport, 1 ) );
1605 Teuchos::ArrayRCP< SC > entriesNodesImp = nodesImp->getDataNonConst(0);
1606
1607 MultiVectorPtr_Type nodesExport = Teuchos::rcp( new MultiVector_Type( this->mapUnique_, 1 ) );
1608 Teuchos::ArrayRCP< SC > entriesNodesExport = nodesExport->getDataNonConst(0);
1609
1610 vec2D_dbl_Type missingNodes(entriesNodesImp.size(),vec_dbl_Type(this->dim_+1));
1611
1612 for(int j= 0; j < this->dim_; j++)
1613 {
1614 for(int i=0; i< entriesNodesExport.size(); i++)
1615 entriesNodesExport[i] = this->getPointsUnique()->at(i).at(j);
1616
1617 nodesImp->importFromVector(nodesExport, false, "Insert");
1618 for(int i=0; i< entriesNodesImp.size(); i++)
1619 missingNodes[i][j] = entriesNodesImp[i];
1620
1621
1622 }
1623
1624 // Lastly import flags
1625 for(int i=0; i< entriesNodesExport.size(); i++)
1626 entriesNodesExport[i] = this->bcFlagUni_->at(i);
1627
1628 nodesImp->importFromVector(nodesExport, false, "Insert");
1629 for(int i=0; i< entriesNodesImp.size(); i++)
1630 missingNodes[i][this->dim_] = entriesNodesImp[i];
1631
1632 // #############################################
1633
1634 if(this->comm_->getRank() == 0){
1635 if(verbose)
1636 std::cout << " ----- Write Nodes .....";
1637
1638 myFile << "MeshVersionFormatted 2" << std::endl;
1639 myFile << "Dimension" << " " << this->dim_ << std::endl;
1640 myFile << std::endl;
1641 myFile << "Vertices";
1642 myFile << std::endl;
1643 myFile << numberNodes;
1644 myFile << std::endl;
1645 for(int i = 0; i < mapUnique->getGlobalNumElements(); i++)
1646 {
1647
1648 if(mapUnique->getLocalElement(i) != -1){
1649 LO id = mapUnique->getLocalElement(i);
1650 for(int j= 0; j < this->getPointsUnique()->at(id).size(); j++)
1651 {
1652 myFile << this->getPointsUnique()->at(id).at(j);
1653 myFile << " ";
1654 }
1655 if(this->dim_ == 2){
1656 myFile << 0.0;
1657 myFile << " ";
1658 }
1659 myFile << this->bcFlagUni_->at(id);
1660 myFile << std::endl;
1661 }
1662 else{
1663 LO id = mapNodesImport->getLocalElement(i);
1664 for(int j= 0; j < this->dim_; j++)
1665 {
1666 myFile << missingNodes[id][j];
1667 myFile << " ";
1668 }
1669 if(this->dim_ == 2){
1670 myFile << 0.0;
1671 myFile << " ";
1672 }
1673 myFile << missingNodes[id][this->dim_];
1674 myFile << std::endl;
1675 }
1676
1677
1678
1679 }
1680 myFile << std::endl;
1681 if(verbose)
1682 std::cout << ".... done ----- " << '\n';
1683
1684 }
1685
1686 // ################ Edges #################
1687 if(exportEdges){
1688 if(verbose)
1689 std::cout << " ----- Write Edges .....";
1690 int dofsEdges=2;
1691 if(this->FEType_ == "P2")
1692 dofsEdges=3;
1693 // Assumption in 2D no edge is subelement of two elements, as they are only subelement if they are part of the surface
1694 if(this->dim_ == 2)
1695 {
1696 vec2D_GO_Type edgesSubelements(0,vec_GO_Type(dofsEdges+1)); // nodes +
1697 ElementsPtr_Type elements = this->getElementsC();
1698 for(int T=0; T< elements->numberElements() ; T++){
1699 FiniteElement fe = elements->getElement( T );
1700 ElementsPtr_Type subEl = fe.getSubElements(); // might be null
1701 for (int surface=0; surface<fe.numSubElements(); surface++) {
1702 FiniteElement feSub = subEl->getElement( surface );
1703 vec_GO_Type edgeTmp;
1704 edgeTmp = {feSub.getVectorNodeList().at(0),feSub.getVectorNodeList().at(1),feSub.getFlag()};
1705 if(this->FEType_=="P2")
1706 edgeTmp = {feSub.getVectorNodeList().at(0),feSub.getVectorNodeList().at(1),feSub.getVectorNodeList().at(2),feSub.getFlag()};
1707
1708 edgesSubelements.push_back(edgeTmp);
1709 }
1710
1711 }
1712 // Local number of subelement edges:
1713 int numSubEl = edgesSubelements.size();
1714
1715 int maxRank = std::get<1>(this->rankRange_);
1716 vec_GO_Type globalProcs(0);
1717 for (int i=0; i<= maxRank; i++)
1718 globalProcs.push_back(i);
1719
1720 Teuchos::ArrayView<GO> globalProcArray = Teuchos::arrayViewFromVector( globalProcs);
1721
1722 vec_GO_Type localProc(0);
1723 localProc.push_back(this->comm_->getRank());
1724 Teuchos::ArrayView<GO> localProcArray = Teuchos::arrayViewFromVector( localProc);
1725
1726 MapPtr_Type mapGlobalProc =
1727 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), globalProcArray, 0, this->comm_) );
1728
1729 MapPtr_Type mapProc =
1730 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), localProcArray, 0, this->comm_) );
1731
1732 MultiVectorLOPtr_Type exportLocalEntry = Teuchos::rcp( new MultiVectorLO_Type( mapProc, 1 ) );
1733 exportLocalEntry->putScalar( (LO) numSubEl );
1734
1735 // map equal to the original edgeMap with zero entries
1736 MultiVectorLOPtr_Type numEdgesProc= Teuchos::rcp( new MultiVectorLO_Type( mapGlobalProc, 1 ) );
1737 numEdgesProc->putScalar( (LO) 0 );
1738 numEdgesProc->importFromVector( exportLocalEntry, false, "Insert");
1739
1740 // number of new elements per Processor
1741 Teuchos::ArrayRCP< const LO > edgesRanks = numEdgesProc->getData(0);
1742 vec_GO_Type vecGlobalIDsElements(0);
1743
1744 GO procOffsetElements=0;
1745 int myRank = this->comm_->getRank();
1746 for(int i=0; i< myRank; i++)
1747 procOffsetElements = procOffsetElements + edgesRanks[i];
1748
1749 for (int i=0; i<numSubEl; i++){
1750 vecGlobalIDsElements.push_back( i + procOffsetElements);
1751 }
1752
1753 Teuchos::RCP<std::vector<GO> > edgesGlobMapping = Teuchos::rcp( new std::vector<GO>( vecGlobalIDsElements ) );
1754 Teuchos::ArrayView<GO> edgesGlobMappingArray = Teuchos::arrayViewFromVector( *edgesGlobMapping);
1755 MapPtr_Type mapEdgesExport =
1756 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), edgesGlobMappingArray, 0, this->getComm()) );
1757
1758 vec_GO_Type vecGlobalIDsEdgesImport(0);
1759 int maxIndex = mapEdgesExport->getMaxAllGlobalIndex();
1760 if(this->comm_->getRank() == 0){
1761 for(int i=numSubEl; i<maxIndex+1 ; i++)
1762 vecGlobalIDsEdgesImport.push_back(i);
1763 }
1764 Teuchos::RCP<std::vector<GO> > edgesGlobMappingImport = Teuchos::rcp( new std::vector<GO>( vecGlobalIDsEdgesImport ) );
1765 Teuchos::ArrayView<GO> edgesGlobMappingImportArray = Teuchos::arrayViewFromVector( *edgesGlobMappingImport);
1766 MapPtr_Type mapEdgesImport =
1767 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), edgesGlobMappingImportArray, 0, this->getComm()) );
1768
1769 int numberEdges = maxIndex+1;
1770
1771 MultiVectorPtr_Type edgesImp = Teuchos::rcp( new MultiVector_Type( mapEdgesImport, 1 ) );
1772 Teuchos::ArrayRCP< SC > entriesEdgesImp = edgesImp->getDataNonConst(0);
1773
1774 MultiVectorPtr_Type edgesExport = Teuchos::rcp( new MultiVector_Type( mapEdgesExport , 1 ) );
1775 Teuchos::ArrayRCP< SC > entriesEdgesExport = edgesExport->getDataNonConst(0);
1776
1777
1778 vec2D_dbl_Type missingEdges(entriesEdgesImp.size(),vec_dbl_Type(dofsEdges+1));
1779
1780 for(int j= 0; j < dofsEdges+1; j++)
1781 {
1782 for(int i=0; i< entriesEdgesExport.size(); i++){
1783 if(j<dofsEdges)
1784 entriesEdgesExport[i] = mapRep->getGlobalElement(edgesSubelements[i][j]);
1785 else
1786 entriesEdgesExport[i] = edgesSubelements[i][j];
1787 }
1788
1789
1790 edgesImp->importFromVector(edgesExport, false, "Insert");
1791 for(int i=0; i< entriesEdgesImp.size(); i++)
1792 missingEdges[i][j] = entriesEdgesImp[i];
1793
1794 }
1795 if(this->comm_->getRank() == 0){
1796
1797 myFile << "Edges";
1798 myFile << std::endl;
1799 myFile << numberEdges;
1800 myFile << std::endl;
1801 for(int i = 0; i < mapEdgesExport->getGlobalNumElements(); i++)
1802 {
1803 if(mapEdgesExport->getLocalElement(i) != -1){
1804 LO id = this->edgeMap_->getLocalElement(i);
1805
1806 for(int j= 0; j < dofsEdges; j++)
1807 {
1808 myFile << mapRep->getGlobalElement(edgesSubelements[i][j])+1;
1809 myFile << " ";
1810 }
1811
1812 myFile << edgesSubelements[i][dofsEdges]; // Flag
1813 myFile << std::endl;
1814
1815
1816 }
1817 else{
1818 LO id = mapEdgesImport->getLocalElement(i);
1819 for(int j= 0; j < dofsEdges; j++)
1820 {
1821 myFile << missingEdges[id][j]+1;
1822 myFile << " ";
1823 }
1824 myFile << missingEdges[id][dofsEdges]; // Flag
1825 myFile << std::endl;
1826
1827 }
1828
1829 }
1830 myFile << std::endl;
1831 }
1832
1833 if(verbose)
1834 std::cout << ".... done ---- " << '\n';
1835
1836 }
1837 else if(this->dim_ == 3){
1838
1839 if(this->FEType_ != "P2") // In case of P2 this function was already called!
1840 this->assignEdgeFlags();
1841
1842 vec_GO_Type globalImportIDsEdges(0);
1843
1844 MapConstPtr_Type edgeMapUnique = this->edgeMap_->buildUniqueMap( this->rankRange_ );
1845
1846 vec2D_int_Type edgesUnique(edgeMapUnique->getNodeNumElements(),vec_int_Type(2,0));
1847 for (int i=0; i < edgeMapUnique->getNodeNumElements(); i++) {
1848 GO gid = edgeMapUnique->getGlobalElement( i );
1849 LO id = this->edgeMap_->getLocalElement( gid );
1850 edgesUnique[i] = this->edgeElements_->getElement(id).getVectorNodeListNonConst();
1851
1852 }
1853 if(this->comm_->getRank() == 0){
1854 for(int i = 0; i < edgeMapUnique->getGlobalNumElements(); i++)
1855 {
1856 if(edgeMapUnique->getLocalElement(i) == -1){
1857 globalImportIDsEdges.push_back(i);
1858 }
1859 }
1860 }
1861 int numberEdges = edgeMapUnique->getGlobalNumElements();
1862
1863 Teuchos::ArrayView<GO> globalEdgesArrayImp = Teuchos::arrayViewFromVector( globalImportIDsEdges);
1864 // Map of global IDs with missing Elements
1865 MapPtr_Type mapEdgesImport =
1866 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), globalEdgesArrayImp, 0, this->getComm()) );
1867
1868 MultiVectorPtr_Type edgesImp = Teuchos::rcp( new MultiVector_Type( mapEdgesImport, 1 ) );
1869 Teuchos::ArrayRCP< SC > entriesEdgesImp = edgesImp->getDataNonConst(0);
1870
1871 MultiVectorPtr_Type edgesExport = Teuchos::rcp( new MultiVector_Type( edgeMapUnique, 1 ) );
1872 Teuchos::ArrayRCP< SC > entriesEdgesExport = edgesExport->getDataNonConst(0);
1873
1874 vec2D_dbl_Type missingEdges(entriesEdgesImp.size(),vec_dbl_Type(dofsEdges+1));
1875
1876 for(int j= 0; j < 2; j++)
1877 {
1878 for(int i=0; i< entriesEdgesExport.size(); i++)
1879 entriesEdgesExport[i] = mapRep->getGlobalElement(edgesUnique[i][j])+1;
1880
1881 edgesImp->importFromVector(edgesExport, false, "Insert");
1882 for(int i=0; i< entriesEdgesImp.size(); i++)
1883 missingEdges[i][j] = entriesEdgesImp[i];
1884
1885 }
1886 if(this->FEType_ == "P2"){
1887 for(int i=0; i< entriesEdgesExport.size(); i++){
1888 GO gid = edgeMapUnique->getGlobalElement( i );
1889 LO id = this->edgeMap_->getLocalElement( gid );
1890 entriesEdgesExport[i] = mapRep->getGlobalElement(this->edgeElements_->getMidpoint(id))+1;
1891 }
1892
1893 edgesImp->importFromVector(edgesExport, false, "Insert");
1894 for(int i=0; i< entriesEdgesImp.size(); i++)
1895 missingEdges[i][2] = entriesEdgesImp[i];
1896
1897 }
1898 // Lastly import flags
1899 for(int i=0; i< entriesEdgesExport.size(); i++){
1900 GO gid = edgeMapUnique->getGlobalElement( i );
1901 LO id = this->edgeMap_->getLocalElement( gid);
1902 entriesEdgesExport[i] = this->edgeElements_->getElement(id).getFlag();
1903 }
1904
1905 edgesImp->importFromVector(edgesExport, false, "Insert");
1906 for(int i=0; i< entriesEdgesImp.size(); i++)
1907 missingEdges[i][dofsEdges] = entriesEdgesImp[i];
1908
1909 // ########## Writing #######################
1910 if(this->comm_->getRank() == 0){
1911
1912
1913 vec2D_int_Type edges(0,vec_int_Type(0));
1914 for(int i = 0; i < edgeMapUnique->getGlobalNumElements(); i++)
1915 {
1916 vec_int_Type entry(0);
1917 if(edgeMapUnique->getLocalElement(i) != -1){
1918 LO id = this->edgeMap_->getLocalElement(i);
1919 if(this->edgeElements_->getElement(id).getFlag() < this->volumeID_)
1920 {
1921 for(int j= 0; j < 2; j++)
1922 {
1923 entry.push_back(mapRep->getGlobalElement(this->edgeElements_->getElement(id).getVectorNodeList().at(j))+1);
1924 }
1925 if(this->FEType_ == "P2")
1926 entry.push_back(mapRep->getGlobalElement(this->edgeElements_->getMidpoint(id))+1);
1927
1928 entry.push_back(this->edgeElements_->getElement(id).getFlag());
1929
1930 edges.push_back(entry);
1931
1932 }
1933
1934 }
1935 else{
1936 LO id = mapEdgesImport->getLocalElement(i);
1937 if(missingEdges[id][dofsEdges]< this->volumeID_){
1938
1939 for(int j= 0; j < dofsEdges; j++)
1940 {
1941 entry.push_back(missingEdges[id][j]);
1942 }
1943 entry.push_back(missingEdges[id][dofsEdges]);
1944
1945 edges.push_back(entry);
1946
1947 }
1948 }
1949 }
1950
1951
1952 myFile << "Edges";
1953 myFile << std::endl;
1954 myFile << edges.size();
1955 myFile << std::endl;
1956
1957 for(int i = 0; i < edges.size(); i++)
1958 {
1959
1960 for(int j= 0; j < 2; j++)
1961 {
1962 myFile << edges[i][j]; //mapRep->getGlobalElement(this->edgeElements_->getElement(id).getVectorNodeList().at(j))+1;
1963 myFile << " ";
1964 }
1965 if(this->FEType_ == "P2")
1966 myFile << edges[i][2]; //mapRep->getGlobalElement(this->edgeElements_->getMidpoint(id))+1 << " ";
1967
1968 myFile << edges[i][edges[i].size()-1]; // this->edgeElements_->getElement(id).getFlag(); last entry
1969 myFile << std::endl;
1970
1971 }
1972
1973 }
1974 myFile << std::endl;
1975 if(verbose)
1976 std::cout << ".... done ----- " << '\n';
1977 }
1978
1979
1980 }
1981 this->comm_->barrier();
1982 // ################ Surfaces #################
1983 if(exportSurface && this->dim_ >2){
1984 if(verbose)
1985 std::cout << " ----- Write Surfaces ...";
1986 int dofsSurfaces=3;
1987 if(this->FEType_ == "P2")
1988 dofsSurfaces=6;
1989 // Assumption in 2D no edge is subelement of two elements, as they are only subelement if they are part of the surface
1990 if(this->dim_ == 3)
1991 {
1992 vec2D_GO_Type surfacesSubelements(0,vec_GO_Type(dofsSurfaces+1)); // nodes +
1993 ElementsPtr_Type elements = this->getElementsC();
1994 for(int T=0; T< elements->numberElements() ; T++){
1995 FiniteElement fe = elements->getElement( T );
1996 for (int surface=0; surface<fe.numSubElements(); surface++) {
1997 ElementsPtr_Type subEl = fe.getSubElements(); // might be null
1998 if(subEl->getDimension() == this->dim_-1 ){
1999 FiniteElement feSub = subEl->getElement( surface );
2000 vec_GO_Type surfaceTmp;
2001 surfaceTmp = {feSub.getVectorNodeList().at(0),feSub.getVectorNodeList().at(1),feSub.getVectorNodeList().at(2),feSub.getFlag()};
2002 if(this->FEType_=="P2")
2003 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()};
2004
2005 surfacesSubelements.push_back(surfaceTmp);
2006 }
2007 }
2008 }
2009 // Local number of subelement edges:
2010 int numSubEl = surfacesSubelements.size();
2011
2012 int maxRank = std::get<1>(this->rankRange_);
2013 vec_GO_Type globalProcs(0);
2014 for (int i=0; i<= maxRank; i++)
2015 globalProcs.push_back(i);
2016
2017 Teuchos::ArrayView<GO> globalProcArray = Teuchos::arrayViewFromVector( globalProcs);
2018
2019 vec_GO_Type localProc(0);
2020 localProc.push_back(this->comm_->getRank());
2021 Teuchos::ArrayView<GO> localProcArray = Teuchos::arrayViewFromVector( localProc);
2022
2023 MapPtr_Type mapGlobalProc =
2024 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), globalProcArray, 0, this->comm_) );
2025
2026 MapPtr_Type mapProc =
2027 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), localProcArray, 0, this->comm_) );
2028
2029 MultiVectorLOPtr_Type exportLocalEntry = Teuchos::rcp( new MultiVectorLO_Type( mapProc, 1 ) );
2030 exportLocalEntry->putScalar( (LO) numSubEl );
2031 // map equal to the original edgeMap with zero entries
2032 MultiVectorLOPtr_Type numSurfacesProc= Teuchos::rcp( new MultiVectorLO_Type( mapGlobalProc, 1 ) );
2033 numSurfacesProc->putScalar( (LO) 0 );
2034 numSurfacesProc->importFromVector( exportLocalEntry, false, "Insert");
2035 // number of new elements per Processor
2036 Teuchos::ArrayRCP< const LO > surfacesRanks = numSurfacesProc->getData(0);
2037 vec_GO_Type vecGlobalIDsElements(0);
2038
2039 GO procOffsetElements=0;
2040 int myRank = this->comm_->getRank();
2041 for(int i=0; i< myRank; i++)
2042 procOffsetElements = procOffsetElements + surfacesRanks[i];
2043
2044 for (int i=0; i<numSubEl; i++){
2045 vecGlobalIDsElements.push_back( i + procOffsetElements);
2046 }
2047
2048 Teuchos::RCP<std::vector<GO> > surfacesGlobMapping = Teuchos::rcp( new std::vector<GO>( vecGlobalIDsElements ) );
2049 Teuchos::ArrayView<GO> surfacesGlobMappingArray = Teuchos::arrayViewFromVector( *surfacesGlobMapping);
2050 MapPtr_Type mapSurfacesExport =
2051 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), surfacesGlobMappingArray, 0, this->getComm()) );
2052
2053
2054 vec_GO_Type vecGlobalIDsSurfacesImport(0);
2055 int maxIndex = mapSurfacesExport->getMaxAllGlobalIndex();
2056 if(this->comm_->getRank() == 0){
2057 for(int i=numSubEl; i<maxIndex+1 ; i++)
2058 vecGlobalIDsSurfacesImport.push_back(i);
2059 }
2060 Teuchos::RCP<std::vector<GO> > surfacesGlobMappingImport = Teuchos::rcp( new std::vector<GO>( vecGlobalIDsSurfacesImport ) );
2061 Teuchos::ArrayView<GO> surfacesGlobMappingImportArray = Teuchos::arrayViewFromVector( *surfacesGlobMappingImport);
2062 MapPtr_Type mapSurfacesImport =
2063 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), surfacesGlobMappingImportArray, 0, this->getComm()) );
2064
2065 int numberSurfaces = maxIndex+1;
2066
2067 MultiVectorPtr_Type surfacesImp = Teuchos::rcp( new MultiVector_Type( mapSurfacesImport, 1 ) );
2068 Teuchos::ArrayRCP< SC > entriesSurfacesImp = surfacesImp->getDataNonConst(0);
2069
2070 MultiVectorPtr_Type surfacesExport = Teuchos::rcp( new MultiVector_Type( mapSurfacesExport , 1 ) );
2071 Teuchos::ArrayRCP< SC > entriesSurfacesExport = surfacesExport->getDataNonConst(0);
2072
2073
2074 vec2D_dbl_Type missingSurfaces(entriesSurfacesImp.size(),vec_dbl_Type(dofsSurfaces+1));
2075
2076 for(int j= 0; j < dofsSurfaces+1; j++)
2077 {
2078 for(int i=0; i< entriesSurfacesExport.size(); i++){
2079 if(j<dofsSurfaces)
2080 entriesSurfacesExport[i] = mapRep->getGlobalElement(surfacesSubelements[i][j]);
2081 else{
2082 entriesSurfacesExport[i] = surfacesSubelements[i][j]; // FLAG!
2083 }
2084 }
2085 surfacesImp->importFromVector(surfacesExport, false, "Insert");
2086 for(int i=0; i< entriesSurfacesImp.size(); i++)
2087 missingSurfaces[i][j] = entriesSurfacesImp[i];
2088
2089 }
2090 if(this->comm_->getRank() == 0){
2091
2092 myFile << "Triangles";
2093 myFile << std::endl;
2094 myFile << numberSurfaces;
2095 myFile << std::endl;
2096 for(int i = 0; i < mapSurfacesExport->getGlobalNumElements(); i++)
2097 {
2098 if(mapSurfacesExport->getLocalElement(i) != -1){
2099
2100 for(int j= 0; j < dofsSurfaces; j++)
2101 {
2102 myFile << mapRep->getGlobalElement(surfacesSubelements[i][j])+1;
2103 myFile << " ";
2104 }
2105
2106
2107 myFile << surfacesSubelements[i][dofsSurfaces];
2108 myFile << std::endl;
2109
2110
2111 }
2112 else{
2113 LO id = mapSurfacesImport->getLocalElement(i);
2114 for(int j= 0; j < dofsSurfaces; j++)
2115 {
2116 myFile << missingSurfaces[id][j]+1;
2117 myFile << " ";
2118 }
2119 myFile << missingSurfaces[id][dofsSurfaces];
2120 myFile << std::endl;
2121
2122 }
2123
2124 }
2125 myFile << std::endl;
2126 }
2127
2128
2129 }
2130 if(verbose)
2131 std::cout << "... done -----" << '\n';
2132
2133 }
2134
2135
2136 // ################ Elements #################
2137 this->comm_->barrier();
2138
2139 if(verbose)
2140 std::cout << " ----- Write Elements ...";
2141
2142 // ###########################################
2143 // 1. Import missing Elements
2144 vec_GO_Type globalImportIDs(0);
2145 for(int i = 0; i < this->elementMap_->getGlobalNumElements(); i++)
2146 {
2147 if(this->elementMap_->getLocalElement(i) == -1){
2148 globalImportIDs.push_back(i);
2149 }
2150 }
2151 Teuchos::ArrayView<GO> globalElementArrayImp = Teuchos::arrayViewFromVector( globalImportIDs);
2152 // Map of global IDs with missing Elements
2153 MapPtr_Type mapElementImport =
2154 Teuchos::rcp( new Map_Type( Teuchos::OrdinalTraits<GO>::invalid(), globalElementArrayImp, 0, this->getComm()) );
2155
2156 MultiVectorPtr_Type idsElement = Teuchos::rcp( new MultiVector_Type( mapElementImport, 1 ) );
2157 Teuchos::ArrayRCP< SC > entriesElement = idsElement->getDataNonConst(0);
2158
2159 MultiVectorPtr_Type idsElementExport = Teuchos::rcp( new MultiVector_Type( this->elementMap_, 1 ) );
2160 Teuchos::ArrayRCP< SC > entriesElementExport = idsElementExport->getDataNonConst(0);
2161
2162 int dofsElement = this->getElements()->at(0).size();
2163 vec2D_GO_Type missingElements(entriesElement.size(),vec_GO_Type(dofsElement+1));
2164
2165 for(int j= 0; j < this->getElements()->at(0).size(); j++)
2166 {
2167 for(int i=0; i< entriesElementExport.size(); i++)
2168 entriesElementExport[i] = mapRep->getGlobalElement(this->getElements()->at(i).at(j))+1;
2169
2170 idsElement->importFromVector(idsElementExport, false, "Insert");
2171 for(int i=0; i< entriesElement.size(); i++)
2172 missingElements[i][j] = entriesElement[i];
2173 }
2174 for(int i=0; i< entriesElementExport.size(); i++)
2175 entriesElementExport[i] = this->getElementsC()->getElement(i).getFlag();
2176
2177 idsElement->importFromVector(idsElementExport, false, "Insert");
2178 for(int i=0; i< entriesElement.size(); i++)
2179 missingElements[i][dofsElement] = entriesElement[i];
2180 // --------------------------------------
2181 if(this->comm_->getRank() == 0){
2182
2183 if(this->dim_ == 2)
2184 myFile << "Triangles";
2185 else if(this->dim_ ==3)
2186 myFile << "Tetrahedra";
2187
2188 myFile << std::endl;
2189
2190 int numberElements = this->elementMap_->getGlobalNumElements();
2191
2192 myFile << numberElements;
2193 myFile << std::endl;
2194
2195 for(int i = 0; i < this->elementMap_->getGlobalNumElements(); i++)
2196 {
2197 if(this->elementMap_->getLocalElement(i) != -1){
2198 LO id = this->elementMap_->getLocalElement(i);
2199
2200 for(int j= 0; j < this->getElements()->at(id).size(); j++)
2201 {
2202 myFile << mapRep->getGlobalElement(this->getElements()->at(id).at(j))+1;
2203 myFile << " ";
2204 }
2205 myFile << this->getElementsC()->getElement(id).getFlag();
2206 myFile << std::endl;
2207
2208 }
2209 else{
2210 LO id = mapElementImport->getLocalElement(i);
2211 for(int j= 0; j < dofsElement; j++)
2212 {
2213 myFile << missingElements[id][j];
2214 myFile << " ";
2215 }
2216 myFile << missingElements[id][dofsElement];
2217 myFile << std::endl;
2218 }
2219
2220 }
2221 if(verbose)
2222 std::cout << "... done ----- " << '\n';
2223
2224 }
2225 if(this->comm_->getRank() ==0)
2226 myFile.close();
2227 if(verbose){
2228 std::cout << " --------------------------------------" << std::endl;
2229 std::cout << " ------- Finished exporting Mesh ------" << std::endl;
2230 std::cout << " ------- File Name: " << meshName << " -------" << std::endl;
2231 if(this->dim_ == 3)
2232 std::cout << " - Info: In 3D all edges are exported -" << std::endl;
2233
2234 std::cout << " --------------------------------------" << std::endl;
2235
2236 }
2237 this->comm_->barrier();
2238
2239
2240}
2241
2242}
2243#endif
Definition Elements.hpp:22
Definition FiniteElement.hpp:17
Definition Map_decl.hpp:36
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:1572
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:184
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:150
CommConstPtrConst_Type getComm()
Definition Mesh_decl.hpp:138
MapConstPtr_Type getEdgeMap()
Definition Mesh_def.hpp:120
vec2D_dbl_ptr_Type getPointsUnique() const
Definition Mesh_def.hpp:132
vec_int_ptr_Type getBCFlagRepeated() const
Definition Mesh_def.hpp:138
MapConstPtr_Type getElementMap() const
Definition Mesh_def.hpp:113
vec2D_int_ptr_Type getElements()
Definition Mesh_def.hpp:433
MapConstPtr_Type getMapRepeated() const
Definition Mesh_def.hpp:107
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement.cpp:5