Finite Element Domain Decomposition Library
FEDDLib
Loading...
Searching...
No Matches
Mesh_def.hpp
1#ifndef Mesh_def_hpp
2#define Mesh_def_hpp
3
12
13namespace FEDD {
14
15template <class SC, class LO, class GO, class NO>
16Mesh<SC,LO,GO,NO>::Mesh():
17numElementsGlob_(0),
18mapUnique_(),
19mapRepeated_(),
20pointsRep_(),
21pointsUni_(),
22bcFlagRep_(),
23bcFlagUni_(),
24surfaceElements_(),
25elementMap_(),
26comm_(),
27pointsRepRef_(),
28pointsUniRef_(),
29AABBTree_()
30{
31
32 surfaceElements_.reset(new Elements());
33
34 elementsC_.reset(new Elements());
35
36 FEType_ = "P1"; // We generally assume the mesh to be p1. In case of P1 or Q2 the FEType is allways adjusted
37}
38
39template <class SC, class LO, class GO, class NO>
40Mesh<SC,LO,GO,NO>::Mesh(CommConstPtrConst_Type& comm):
41numElementsGlob_(0),
42mapUnique_(),
43mapRepeated_(),
44pointsRep_(),
45pointsUni_(),
46bcFlagRep_(),
47bcFlagUni_(),
48surfaceElements_(),
49elementMap_(),
50edgeMap_(),
51comm_(comm),
52pointsRepRef_(),
53pointsUniRef_(),
54AABBTree_()
55{
56 AABBTree_.reset(new AABBTree_Type());
57 surfaceElements_.reset(new Elements());
58
59 elementsC_.reset(new Elements());
60
61 FEType_ = "P1";
62}
63
64template <class SC, class LO, class GO, class NO>
66
67 ElementsPtr_Type elements = this->getElementsC();
68// this->elementFlag_.reset( new vec_int_Type( elements->numberElements(), 0 ) );
69 if (type == "TPM_square") {
70 double xRef, yRef;
71
72 for (int i=0; i<elements->numberElements(); i++) {
73 xRef = ( this->pointsRep_->at( elements->getElement(i).getNode(0) )[0] + this->pointsRep_->at( elements->getElement(i).getNode(1) )[0] + this->pointsRep_->at( elements->getElement(i).getNode(2) )[0] ) / 3.;
74 yRef = ( this->pointsRep_->at( elements->getElement(i).getNode(0) )[1] + this->pointsRep_->at( elements->getElement(i).getNode(1) )[1] + this->pointsRep_->at( elements->getElement(i).getNode(2) )[1] ) / 3.;
75 if ( xRef>=0.3 && xRef<=0.7) {
76 if ( yRef>= 0.6) {
77 elements->getElement(i).setFlag(1);
78// this->elementFlag_->at(i) = 1;
79 }
80 }
81 }
82 }
83 else if (type == "Excavation1"){
84 }
85 else{
86
87 }
88
90
91template <class SC, class LO, class GO, class NO>
92vec_int_ptr_Type Mesh<SC,LO,GO,NO>::getElementsFlag() const{
93 TEUCHOS_TEST_FOR_EXCEPTION( true, std::runtime_error, "we are not using the correct flags here. use the flags of elementC_." );
94 vec_int_ptr_Type tmp;
95 return tmp;
96}
98template <class SC, class LO, class GO, class NO>
99typename Mesh<SC,LO,GO,NO>::MapConstPtr_Type Mesh<SC,LO,GO,NO>::getMapUnique() const{
100
101 return mapUnique_;
102}
103
104template <class SC, class LO, class GO, class NO>
105typename Mesh<SC,LO,GO,NO>::MapConstPtr_Type Mesh<SC,LO,GO,NO>::getMapRepeated() const{
106
107 return mapRepeated_;
108}
110template <class SC, class LO, class GO, class NO>
111typename Mesh<SC,LO,GO,NO>::MapConstPtr_Type Mesh<SC,LO,GO,NO>::getElementMap() const{
112 TEUCHOS_TEST_FOR_EXCEPTION( elementMap_.is_null(), std::runtime_error, "Element map of mesh does not exist." );
113 return elementMap_;
114}
115
116// edgeMap
117template <class SC, class LO, class GO, class NO>
118typename Mesh<SC,LO,GO,NO>::MapConstPtr_Type Mesh<SC,LO,GO,NO>::getEdgeMap(){
119 TEUCHOS_TEST_FOR_EXCEPTION( edgeMap_.is_null(), std::runtime_error, "Element map of mesh does not exist." );
120 return edgeMap_;
122
123template <class SC, class LO, class GO, class NO>
124vec2D_dbl_ptr_Type Mesh<SC,LO,GO,NO>::getPointsRepeated() const{
126 return pointsRep_;
127}
128
129template <class SC, class LO, class GO, class NO>
130vec2D_dbl_ptr_Type Mesh<SC,LO,GO,NO>::getPointsUnique() const{
131
132 return pointsUni_;
133}
135template <class SC, class LO, class GO, class NO>
137
138 return bcFlagRep_;
139}
140
141template <class SC, class LO, class GO, class NO>
142vec_int_ptr_Type Mesh<SC,LO,GO,NO>::getBCFlagUnique() const{
143
144 return bcFlagUni_;
145}
146
147template <class SC, class LO, class GO, class NO>
148typename Mesh<SC,LO,GO,NO>::ElementsPtr_Type Mesh<SC,LO,GO,NO>::getElementsC(){
149 return elementsC_;
151
152template <class SC, class LO, class GO, class NO>
153typename Mesh<SC,LO,GO,NO>::ElementsPtr_Type Mesh<SC,LO,GO,NO>::getSurfaceElements(){
154 return surfaceElements_;
156
157template <class SC, class LO, class GO, class NO>
159
160 return dim_;
161}
162
163template <class SC, class LO, class GO, class NO>
165
166 return numElementsGlob_;
167}
168
169template <class SC, class LO, class GO, class NO>
171 TEUCHOS_TEST_FOR_EXCEPTION( this->elementsC_.is_null(), std::runtime_error ,"Elements do not exist." );
172 return this->elementsC_->numberElements();
173}
174
175template <class SC, class LO, class GO, class NO>
177 if (!type.compare("Unique"))
178 return pointsUni_->size();
179 else if(!type.compare("Repeated"))
180 return pointsRep_->size();
181
182 TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,"Select valid map type: unique or repeated.");
183 return 0;
184}
185
186template <class SC, class LO, class GO, class NO>
188
189 switch (dim_) {
190 case 2:
191 if ( !FEType_.compare("P1") )
192 return 3;
193 else if ( !FEType_.compare("P1-disc") || !FEType_.compare("P1-disc-global") ){
194 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "P1-disc only available in 3D.");
196 else if( !FEType_.compare("P2") )
197 return 6;
198 else if( !FEType_.compare("P2-CR") ){
199 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "P2-CR only available in 3D.");
200 }
201 else if( !FEType_.compare("Q2-20") ){
202 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Q2-20 only available in 3D.");
203 }
204 else if( !FEType_.compare("Q2") ){
205 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Q2 only available in 3D.");
206 }
207 break;
208 case 3:
209 if ( !FEType_.compare("P1") )
210 return 4;
211 if ( !FEType_.compare("P1-disc") || !FEType_.compare("P1-disc-global") )
212 return 4;
213 else if( !FEType_.compare("P2") )
214 return 10;
215 else if( !FEType_.compare("P2-CR") )
216 return 15;
217 else if( !FEType_.compare("Q2-20") )
218 return 20; // Q2 Serendipity (missing interior volume node and missing interior face nodes gives 20 nodes)
219 else if( !FEType_.compare("Q2") )
220 return 27;
221 break;
222 default:
223 return -1;
224 break;
225 }
226 return -1;
227}
228
229template <class SC, class LO, class GO, class NO>
231{
232 // Bemerkung: Repeated und Unique sind unterschiedlich lang!!! => zwei Schleifen
233
234 // Setze zunaechst alles auf Null, andernfalls kann man nicht drauf zugreifen
235 // vec2D_dbl_ptr_Type zeroRep(new vec2D_dbl_Type(pointsRep_->size(),vec_dbl_Type(pointsRep_->at(0).size(),0.0)));
236 // vec2D_dbl_ptr_Type zeroUni(new vec2D_dbl_Type(pointsUni_->size(),vec_dbl_Type(pointsUni_->at(0).size(),0.0)));
237
238
239 pointsRepRef_.reset( new vec2D_dbl_Type() );
240 pointsUniRef_.reset( new vec2D_dbl_Type() );
241 // zeroRep und zeroUni leben nur hier drinnen, weswegen wir Pointer gleich Pointer setzen koennen.
242 // TODO: *PointsRepRef_ = *zeroRep funktioniert nicht.
243 *pointsRepRef_ = *pointsRep_;
244 *pointsUniRef_ = *pointsUni_;
245
246 // // Repeated
247 // for(int i = 0; i < pointsRep_->size(); i++)
248 // {
249 // for(int j = 0; j < pointsRep_->at(0).size(); j++)
250 // {
251 // pointsRepRef_->at(i).at(j) = PointsRep_->at(i).at(j);
252 // }
253 // }
254 //
255 // // Unique
256 // for(int i = 0; i < PointsUni_->size(); i++)
257 // {
258 // for(int j = 0; j < PointsUni_->at(0).size(); j++)
259 // {
260 // PointsUniRef_->at(i).at(j) = PointsUni_->at(i).at(j);
261 // }
262 // }
263}
264
265template <class SC, class LO, class GO, class NO>
266void Mesh<SC,LO,GO,NO>::moveMesh( MultiVectorPtr_Type displacementUnique, MultiVectorPtr_Type displacementRepeated )
267{
268 // Bemerkung: Repeated und Unique sind unterschiedlich lang!!! => zwei Schleifen
269 TEUCHOS_TEST_FOR_EXCEPTION (displacementRepeated.is_null(), std::runtime_error," displacementRepeated in moveMesh is null.")
270 TEUCHOS_TEST_FOR_EXCEPTION (displacementUnique.is_null(), std::runtime_error," displacementRepeated in moveMesh is null.")
271 // Repeated
272 Teuchos::ArrayRCP<const SC> values = displacementRepeated->getData(0); //only 1 MV
273 for(int i = 0; i < pointsRepRef_->size(); i++)
274 {
275 for(int j = 0; j < pointsRepRef_->at(0).size(); j++)
276 {
277 // Sortierung von DisplacementRepeated ist x-y-x-y-x-y-x-y bzw. x-y-z-x-y-z-x-y-z
278 // Achtung: DisplacementRepeated ist ein Pointer der mit (*) dereferenziert werden muss.
279 // Operator[] kann nicht auf einen Pointer angewendet werden!!!
280 // Es sei denn es ist ein Array.
281 pointsRep_->at(i).at(j) = pointsRepRef_->at(i).at(j) + values[dim_*i+j];
282 }
283 }
284
285 // Unique
286 values = displacementUnique->getData(0); //only 1 MV
287 for(int i = 0; i < pointsUniRef_->size(); i++)
288 {
289 for(int j = 0; j < pointsUniRef_->at(0).size(); j++)
290 {
291 // Sortierung von DisplacementRepeated ist x-y-x-y-x-y-x-y bzw. x-y-z-x-y-z-x-y-z
292 // Erklaerung: DisplacementUnique ist ein Vector-Pointer, wo in jedem Eintrag ein MultiVector-Pointer drin steht (std::vector<MultiVector_ptr_Type>)
293 // Greife mit ->at auf den Eintrag des Vektors zu (hier nur ein Eintrag vorhanden), dereferenziere den damit erhaltenen MultiVector-Pointer (als Referenz) um einen
294 // MultiVector zu erhalten.
295 // Greife dann mit [] auf das entsprechende Array (double *&) im MultiVector zu (hier gibt es nur einen)
296 // und anschliessend mit [] auf den Wert des Arrays.
297 // Beachte falls x ein Array ist (also z.B. double *), dann ist x[i] := *(x+i)!!!
298 // Liefert also direkt den Wert und keinen Pointer auf einen double.
299 // Achtung: MultiVector[] liefert double* wohingegen MultiVector() Tpetra_Vector* zurueck liefert
300 pointsUni_->at(i).at(j) = pointsUniRef_->at(i).at(j) + values[dim_*i+j];
301 }
302 }
303}
304
305template <class SC, class LO, class GO, class NO>
306void Mesh<SC,LO,GO,NO>::create_AABBTree(){
307 if (AABBTree_.is_null()){
308 AABBTree_.reset(new AABBTree_Type());
309 }
310 AABBTree_->createTreeFromElements(
311 getElementsC(),
312 getPointsRepeated()
313 );
314}
315
316template <class SC, class LO, class GO, class NO>
317vec_int_ptr_Type Mesh<SC,LO,GO,NO>::findElemsForPoints(
318 vec2D_dbl_ptr_Type queryPoints
319){
320 int numPoints = queryPoints->size();
321
322 // Return vector. -1 means that point is in no elem, otherwise entry is the
323 // elem the point is in
324 vec_int_ptr_Type pointToElem(
325 new vec_int_Type(
326 numPoints,
327 -1
328 )
329 );
330
331 // Create tree if it is empty
332 if (AABBTree_->isEmpty()){
333 AABBTree_->createTreeFromElements(
334 getElementsC(),
335 getPointsRepeated(),
336 false
337 );
338 }
339
340 // Query the AABBTree
341 std::map<int, std::list<int> > treeToItem;
342 std::map<int, std::list<int> > itemToTree;
343 tie(treeToItem, itemToTree) = AABBTree_->scanTree(queryPoints, false);
344
345 // FIXME: put this in a function of AABBTree?
346 // unnest the returned answer for each query_point
347 int point = -1;
348 bool found = false;
349 std::list<int> rectangles;
350 std::list<int> elements;
351 for (auto keyValue: itemToTree){
352 // FIXME: put this in a function of AABBTree?
353 // rectangles is a list<int> of all rectangles point is in
354 // find the element(s) that is/are in all of said rectangles.
355 // If there is only one element that is the element the point is in,
356 // if not we have to query all remaining elements
357 point = keyValue.first;
358 rectangles = keyValue.second;
359
360
361 // query all remaining elements
362 for(auto rectangle: rectangles){
363 elements = AABBTree_->getElements(rectangle);
364 for(auto element: elements){
365 found = isPointInElem(queryPoints->at(point), element);
366 if( found ){
367 pointToElem->at(point) = element;
368 break;
369 }
370 }
371 if( found ){
372 // we already found the element, no need to check additional rectangles
373 break;
374 }
375 }
376
377 }
378 return pointToElem;
379}
380
381template <class SC, class LO, class GO, class NO>
382vec_dbl_Type Mesh<SC,LO,GO,NO>::getBaryCoords(vec_dbl_Type point, int element){
383 vec_int_Type localNodes = elementsC_->getElement(element).getVectorNodeList();
384 vec2D_dbl_Type coords(
385 localNodes.size(),
386 vec_dbl_Type(2, 0.0) // FIXME: this depends on the dimension
387 );
388 int node = 0;
389 for (int localNode=0; localNode<localNodes.size(); localNode++){
390 node = localNodes.at(localNode); // get global node_id
391 coords.at(localNode) = pointsRep_->at(node); //get global coordinates
392 }
393
394 double px, py, x1, x2, x3, y1, y2, y3;
395 px = point.at(0); py = point.at(1);
396 x1 = coords.at(0).at(0); y1 = coords.at(0).at(1);
397 x2 = coords.at(1).at(0); y2 = coords.at(1).at(1);
398 x3 = coords.at(2).at(0); y3 = coords.at(2).at(1);
399
400 // baryzentric coordinates
401 double det_T = (y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3);
402
403 vec_dbl_Type baryCoords(
404 3,
405 0.0
406 );
407 baryCoords[0] =(y2 - y3) * (px - x3) + (x3 - x2) * (py - y3);
408 baryCoords[0] = baryCoords[0] / det_T;
409
410 baryCoords[1] = (y3 -y1) * (px - x3) + (x1 - x3) * (py - y3);
411 baryCoords[1] = baryCoords[1] / det_T;
412
413 baryCoords[2] = 1 - baryCoords[1] - baryCoords[0];
414 return baryCoords;
415}
416
417
418template <class SC, class LO, class GO, class NO>
419bool Mesh<SC,LO,GO,NO>:: isPointInElem(vec_dbl_Type point, int element){
420 // FIXME: This is only valid for a triangle
421 vec_dbl_Type baryCoords;
422 baryCoords = getBaryCoords(point, element);
423
424 if(baryCoords[0] >= 0 && baryCoords[1] >= 0 && baryCoords[2] >= 0){
425 return true;
426 }
427 return false;
428}
429
430template <class SC, class LO, class GO, class NO>
432 this->elementsVec_ = Teuchos::rcp( new vec2D_int_Type( this->elementsC_->numberElements() ) );
433 for (int i=0; i<this->elementsVec_->size(); i++)
434 this->elementsVec_->at(i) = this->elementsC_->getElement(i).getVectorNodeList();
435
436 return this->elementsVec_;
437}
438
439template <class SC, class LO, class GO, class NO>
441
442 int outwardNormals = 0;
443 int inwardNormals = 0;
444 for (UN T=0; T<elementsC_->numberElements(); T++) {
445 FiniteElement fe = elementsC_->getElement( T );
446 ElementsPtr_Type subEl = fe.getSubElements(); // might be null
447 for (int surface=0; surface<fe.numSubElements(); surface++) {
448 FiniteElement feSub = subEl->getElement( surface );
449 vec_int_Type nodeListElement = fe.getVectorNodeList();
450 if(subEl->getDimension() == dim_-1 ){
451 vec_int_Type nodeList = feSub.getVectorNodeListNonConst();
452 int numNodes_T = nodeList.size();
453
454 vec_dbl_Type v_E(dim_,1.);
455 double norm_v_E=1.;
456 LO id0 = nodeList[0];
457
458 Helper::computeSurfaceNormal(dim_, pointsRep_,nodeList,v_E,norm_v_E);
459
460 std::sort(nodeList.begin(), nodeList.end());
461 std::sort(nodeListElement.begin(), nodeListElement.end());
462
463 std::vector<int> v_symDifference;
464
465 std::set_symmetric_difference(
466 nodeList.begin(), nodeList.end(),
467 nodeListElement.begin(), nodeListElement.end(),
468 std::back_inserter(v_symDifference));
469
470 LO id1 = v_symDifference[0]; // This is a node that is not part of the surface, i.e. 4th element node in 3D
471
472 vec_dbl_Type p0(dim_,0.);
473 for(int i=0; i< dim_; i++)
474 p0[i] = pointsRep_->at(id1)[i] - pointsRep_->at(id0)[i];
475
476 double sum = 0.;
477 for(int i=0; i< dim_; i++)
478 sum += p0[i] * v_E[i];
479
480 if(sum<=0){
481 outwardNormals++;
482 }
483 if(sum>0){
484 inwardNormals++;
485 }
486 if(sum>0) // if the sum is greater than 0, the normal is in inward direction and thus is flipped.
487 flipSurface(subEl,surface);
488
489
490 }
491 }
492 }
493 Teuchos::reduceAll<int, int> (*this->getComm(), Teuchos::REDUCE_SUM, inwardNormals, Teuchos::outArg (inwardNormals));
494 Teuchos::reduceAll<int, int> (*this->getComm(), Teuchos::REDUCE_SUM, outwardNormals, Teuchos::outArg (outwardNormals));
495
496 if(this->getComm()->getRank() == 0){
497 std::cout << " ############################################ " << std::endl;
498 std::cout << " Mesh Orientation Statistic " << std::endl;
499 std::cout << " Number of outward normals " << outwardNormals << std::endl;
500 std::cout << " Number of inward normals " << inwardNormals << std::endl;
501 std::cout << " ############################################ " << std::endl;
502 }
503
504}
505template <class SC, class LO, class GO, class NO>
507
508 int posDet=0;
509 int negDet=0;
510
511 SC detB;
512 SmallMatrix<SC> B(dim_);
513 SmallMatrix<SC> Binv(dim_);
514
515 for (UN T=0; T<elementsC_->numberElements(); T++) {
516 Helper::buildTransformation(elementsC_->getElement(T).getVectorNodeList(), pointsRep_, B);
517 detB = B.computeInverse(Binv);
518
519 if(detB<0){
520 negDet++;
521 }
522 if(detB>0){
523 posDet++;
524 }
525 if(detB<0) // If the determinant is smaller than zero we flip the element
526 flipElement(elementsC_,T);
527
528 }
529 Teuchos::reduceAll<int, int> (*this->getComm(), Teuchos::REDUCE_SUM, negDet, Teuchos::outArg (negDet));
530 Teuchos::reduceAll<int, int> (*this->getComm(), Teuchos::REDUCE_SUM, posDet, Teuchos::outArg (posDet));
531
532 if(this->getComm()->getRank() == 0){
533 std::cout << " ############################################ " << std::endl;
534 std::cout << " Mesh Orientation Statistic " << std::endl;
535 std::cout << " Number of positive dets " << posDet << std::endl;
536 std::cout << " Number of negative dets " << negDet << std::endl;
537 std::cout << " ############################################ " << std::endl;
538 }
539
540}
541
542// We allways want a outward normal direction
543// Assumptions: We are flipping a surface which is a subelement. Subelement are generally element that are on the boundary layers of the domain. Thus, they are unique. (There are no two identical triangles in two elements as subelements)
544// Question: Easiest way to flip the surface without redoing whole dim-element (surface being dim-1-element)
545template <class SC, class LO, class GO, class NO>
546void Mesh<SC,LO,GO,NO>::flipSurface(ElementsPtr_Type subEl, int surfaceNumber){
547
548 vec_LO_Type surfaceElements_vec = subEl->getElement(surfaceNumber).getVectorNodeList();
549
550 if(dim_ == 2){
551 if(FEType_ == "P1"){
552 LO id1,id2;
553 id1= surfaceElements_vec[0];
554 id2= surfaceElements_vec[1];
555
556 surfaceElements_vec[0] = id2;
557 surfaceElements_vec[1] = id1;
558 }
559 else if(FEType_ == "P2"){
560 LO id1,id2,id3;
561 id1= surfaceElements_vec[0];
562 id2= surfaceElements_vec[1];
563 id3= surfaceElements_vec[2];
564
565 surfaceElements_vec[0] = id2;
566 surfaceElements_vec[1] = id1;
567 surfaceElements_vec[2] = id3;
568 }
569 }
570 else if(dim_ == 3){
571
572 if(FEType_ == "P1"){
573 LO id1,id2,id3,id4,id5,id6;
574 id1= surfaceElements_vec[0];
575 id2= surfaceElements_vec[1];
576 id3= surfaceElements_vec[2];
577
578 surfaceElements_vec[0] = id1;
579 surfaceElements_vec[1] = id3;
580 surfaceElements_vec[2] = id2;
581 }
582 else if(FEType_ == "P2"){
583 LO id1,id2,id3,id4,id5,id6;
584 id1= surfaceElements_vec[0];
585 id2= surfaceElements_vec[1];
586 id3= surfaceElements_vec[2];
587 id4= surfaceElements_vec[3];
588 id5= surfaceElements_vec[4];
589 id6= surfaceElements_vec[5];
590
591 surfaceElements_vec[0] = id1;
592 surfaceElements_vec[1] = id3;
593 surfaceElements_vec[2] = id2;
594 surfaceElements_vec[3] = id6;
595 surfaceElements_vec[4] = id5;
596 surfaceElements_vec[5] = id4;
597 }
598 else
599 TEUCHOS_TEST_FOR_EXCEPTION( true, std::runtime_error, "We can only flip normals for P1 or P2 elements. Invalid " << FEType_ << " " );
600
601 }
602 FiniteElement feFlipped(surfaceElements_vec,subEl->getElement(surfaceNumber).getFlag());
603 subEl->switchElement(surfaceNumber,feFlipped); // We can switch the current element with the newly defined element which has just a different node ordering.
604
605
606}
607
608// We allways want a positive determinant
609template <class SC, class LO, class GO, class NO>
610void Mesh<SC,LO,GO,NO>::flipElement(ElementsPtr_Type elements, int elementNumber){
611
612 vec_LO_Type surfaceElements_vec = elements->getElement(elementNumber).getVectorNodeList();
613 if(dim_ == 2){
614 if(FEType_ == "P1"){
615 LO id1,id2,id3;
616 id1= surfaceElements_vec[0];
617 id2= surfaceElements_vec[1];
618 id3= surfaceElements_vec[2];
619
620 surfaceElements_vec[0] = id1;
621 surfaceElements_vec[1] = id3;
622 surfaceElements_vec[2] = id2;
623
624 }
625 else if(FEType_ == "P2"){
626 LO id1,id2,id3,id4,id5,id6;
627 id1= surfaceElements_vec[0];
628 id2= surfaceElements_vec[1];
629 id3= surfaceElements_vec[2];
630 id4= surfaceElements_vec[3];
631 id5= surfaceElements_vec[4];
632 id6= surfaceElements_vec[5];
633
634 surfaceElements_vec[0] = id1;
635 surfaceElements_vec[1] = id3;
636 surfaceElements_vec[2] = id2;
637 surfaceElements_vec[3] = id6;
638 surfaceElements_vec[4] = id5;
639 surfaceElements_vec[5] = id4;
640 }
641 }
642 else if(dim_ == 3){
643
644 if(FEType_ == "P1"){
645 LO id1,id2,id3,id4;
646 id1= surfaceElements_vec[0];
647 id2= surfaceElements_vec[1];
648 id3= surfaceElements_vec[2];
649 id4= surfaceElements_vec[3];
650
651 surfaceElements_vec[0] = id1;
652 surfaceElements_vec[1] = id3;
653 surfaceElements_vec[2] = id2;
654 surfaceElements_vec[3] = id4;
655
656 }
657 else if(FEType_ == "P2"){
658 LO id1,id2,id3,id4,id5,id6, id7,id8,id9,id0;
659 id0= surfaceElements_vec[0];
660 id1= surfaceElements_vec[1];
661 id2= surfaceElements_vec[2];
662 id3= surfaceElements_vec[3];
663 id4= surfaceElements_vec[4];
664 id5= surfaceElements_vec[5];
665 id6= surfaceElements_vec[6];
666 id7= surfaceElements_vec[7];
667 id8= surfaceElements_vec[8];
668 id9= surfaceElements_vec[9];
669
670 surfaceElements_vec[0] = id0;
671 surfaceElements_vec[1] = id2;
672 surfaceElements_vec[2] = id1;
673 surfaceElements_vec[3] = id3;
674
675 surfaceElements_vec[4] = id6;
676 surfaceElements_vec[5] = id5;
677 surfaceElements_vec[6] = id4;
678 surfaceElements_vec[7] = id7;
679 surfaceElements_vec[8] = id9;
680 surfaceElements_vec[9] = id8;
681 }
682 else
683 TEUCHOS_TEST_FOR_EXCEPTION( true, std::runtime_error, "We can only flip normals for P1 or P2 elements. Invalid " << FEType_ << " " );
684
685 }
686 FiniteElement feFlipped(surfaceElements_vec,elements->getElement(elementNumber).getFlag());
687 ElementsPtr_Type subElements = elements->getElement(elementNumber).getSubElements();
688 for(int T = 0; T<elements->getElement(elementNumber).numSubElements(); T++){
689 if(!feFlipped.subElementsInitialized())
690 feFlipped.initializeSubElements( this->FEType_, this->dim_ -1) ;
691 feFlipped.addSubElement(subElements->getElement(T));
692 }
693 elements->switchElement(elementNumber,feFlipped); // We can switch the current element with the newly defined element which has just a different node ordering.
694
695}
696
697}
698#endif
Definition FiniteElement.hpp:17
static void buildTransformation(const vec_int_Type &element, vec2D_dbl_ptr_Type pointsRep, SmallMatrix< SC > &B, std::string FEType="P")
Build transformation of element to reference element depending on FEType.
Definition Helper.cpp:138
static void computeSurfaceNormal(int dim, vec2D_dbl_ptr_Type pointsRep, vec_int_Type nodeList, vec_dbl_Type &v_E, double &norm_v_E)
Compute surface normal of corresponding surface.
Definition Helper.cpp:103
ElementsPtr_Type getElementsC()
Returns element list as c-object.
Definition Mesh_def.hpp:148
vec2D_dbl_ptr_Type getPointsRepeated() const
getter for list of repeated points with x,y,z coordinates in each row
Definition Mesh_def.hpp:124
CommConstPtrConst_Type getComm()
Communicator object.
Definition Mesh_decl.hpp:138
MapConstPtr_Type getEdgeMap()
Getter for edge map.
Definition Mesh_def.hpp:118
vec2D_dbl_ptr_Type getPointsUnique() const
getter for list of unique points with x,y,z coordinates in each row
Definition Mesh_def.hpp:130
vec_int_ptr_Type getBCFlagRepeated() const
Getter for flags corresponting to repeated points.
Definition Mesh_def.hpp:136
void setElementFlags(std::string type="")
Something for TPM. Can be deprecated soon.
Definition Mesh_def.hpp:65
void correctNormalDirections()
Correcting the normal direction of all surface normals set as subelements of volume elements to be ou...
Definition Mesh_def.hpp:440
GO getNumElementsGlobal()
Global number of elements.
Definition Mesh_def.hpp:164
vec_int_ptr_Type getElementsFlag() const
Getter for element flags.
Definition Mesh_def.hpp:92
MapConstPtr_Type getMapUnique() const
Getter for unique node map.
Definition Mesh_def.hpp:99
MapConstPtr_Type getElementMap() const
Getter for element map.
Definition Mesh_def.hpp:111
void correctElementOrientation()
Correct the element orientation of all elements to have positive volume / det when doint transformati...
Definition Mesh_def.hpp:506
vec2D_int_ptr_Type getElements()
Returns elements as a vector type contrary to the C-object list.
Definition Mesh_def.hpp:431
ElementsPtr_Type getSurfaceElements()
Getter for surface elements. Probably set in mesh partitioner. They are generally the dim-1 surface e...
Definition Mesh_def.hpp:153
MapConstPtr_Type getMapRepeated() const
Getter for repeated node mal.
Definition Mesh_def.hpp:105
LO getNumElements()
Local number of elements.
Definition Mesh_def.hpp:170
LO getNumPoints(std::string type="Unique")
Get local (LO) number of points either in unique or repeated version.
Definition Mesh_def.hpp:176
int getDimension()
Definition Mesh_def.hpp:158
void moveMesh(MultiVectorPtr_Type displacementUnique, MultiVectorPtr_Type displacementRepeated)
Moving mesh according to displacement based on reference configuration.
Definition Mesh_def.hpp:266
int getOrderElement()
Definition Mesh_def.hpp:187
void setReferenceConfiguration()
Setting current coordinates as reference configuration. Should only be called once :D.
Definition Mesh_def.hpp:230
vec_int_ptr_Type getBCFlagUnique() const
Getter for flags corresponting to unique points.
Definition Mesh_def.hpp:142
This class represents a templated small Matrix of type T. Primarily created for 2x2 and 3x3 matrices....
Definition SmallMatrix.hpp:20
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement_decl.hpp:36