193 if ( !FEType_.compare(
"P1") )
195 else if ( !FEType_.compare(
"P1-disc") || !FEType_.compare(
"P1-disc-global") ){
196 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"P1-disc only available in 3D.");
198 else if( !FEType_.compare(
"P2") )
200 else if( !FEType_.compare(
"P2-CR") ){
201 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"P2-CR only available in 3D.");
203 else if( !FEType_.compare(
"Q2-20") ){
204 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Q2-20 only available in 3D.");
206 else if( !FEType_.compare(
"Q2") ){
207 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Q2 only available in 3D.");
211 if ( !FEType_.compare(
"P1") )
213 if ( !FEType_.compare(
"P1-disc") || !FEType_.compare(
"P1-disc-global") )
215 else if( !FEType_.compare(
"P2") )
217 else if( !FEType_.compare(
"P2-CR") )
219 else if( !FEType_.compare(
"Q2-20") )
221 else if( !FEType_.compare(
"Q2") )
231template <
class SC,
class LO,
class GO,
class NO>
241 pointsRepRef_.reset(
new vec2D_dbl_Type() );
242 pointsUniRef_.reset(
new vec2D_dbl_Type() );
245 *pointsRepRef_ = *pointsRep_;
246 *pointsUniRef_ = *pointsUni_;
267template <
class SC,
class LO,
class GO,
class NO>
271 TEUCHOS_TEST_FOR_EXCEPTION (displacementRepeated.is_null(), std::runtime_error,
" displacementRepeated in moveMesh is null.")
272 TEUCHOS_TEST_FOR_EXCEPTION (displacementUnique.is_null(), std::runtime_error,
" displacementRepeated in moveMesh is null.")
274 Teuchos::ArrayRCP<const SC> values = displacementRepeated->getData(0);
275 for(
int i = 0; i < pointsRepRef_->size(); i++)
277 for(
int j = 0; j < pointsRepRef_->at(0).size(); j++)
283 pointsRep_->at(i).at(j) = pointsRepRef_->at(i).at(j) + values[dim_*i+j];
288 values = displacementUnique->getData(0);
289 for(
int i = 0; i < pointsUniRef_->size(); i++)
291 for(
int j = 0; j < pointsUniRef_->at(0).size(); j++)
302 pointsUni_->at(i).at(j) = pointsUniRef_->at(i).at(j) + values[dim_*i+j];
307template <
class SC,
class LO,
class GO,
class NO>
308void Mesh<SC,LO,GO,NO>::create_AABBTree(){
309 if (AABBTree_.is_null()){
310 AABBTree_.reset(
new AABBTree_Type());
312 AABBTree_->createTreeFromElements(
318template <
class SC,
class LO,
class GO,
class NO>
319vec_int_ptr_Type Mesh<SC,LO,GO,NO>::findElemsForPoints(
320 vec2D_dbl_ptr_Type queryPoints
322 int numPoints = queryPoints->size();
326 vec_int_ptr_Type pointToElem(
334 if (AABBTree_->isEmpty()){
335 AABBTree_->createTreeFromElements(
343 std::map<int, std::list<int> > treeToItem;
344 std::map<int, std::list<int> > itemToTree;
345 tie(treeToItem, itemToTree) = AABBTree_->scanTree(queryPoints,
false);
351 std::list<int> rectangles;
352 std::list<int> elements;
353 for (
auto keyValue: itemToTree){
359 point = keyValue.first;
360 rectangles = keyValue.second;
364 for(
auto rectangle: rectangles){
365 elements = AABBTree_->getElements(rectangle);
366 for(
auto element: elements){
367 found = isPointInElem(queryPoints->at(point), element);
369 pointToElem->at(point) = element;
383template <
class SC,
class LO,
class GO,
class NO>
384vec_dbl_Type Mesh<SC,LO,GO,NO>::getBaryCoords(vec_dbl_Type point,
int element){
385 vec_int_Type localNodes = elementsC_->getElement(element).getVectorNodeList();
386 vec2D_dbl_Type coords(
391 for (
int localNode=0; localNode<localNodes.size(); localNode++){
392 node = localNodes.at(localNode);
393 coords.at(localNode) = pointsRep_->at(node);
396 double px, py, x1, x2, x3, y1, y2, y3;
397 px = point.at(0); py = point.at(1);
398 x1 = coords.at(0).at(0); y1 = coords.at(0).at(1);
399 x2 = coords.at(1).at(0); y2 = coords.at(1).at(1);
400 x3 = coords.at(2).at(0); y3 = coords.at(2).at(1);
403 double det_T = (y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3);
405 vec_dbl_Type baryCoords(
409 baryCoords[0] =(y2 - y3) * (px - x3) + (x3 - x2) * (py - y3);
410 baryCoords[0] = baryCoords[0] / det_T;
412 baryCoords[1] = (y3 -y1) * (px - x3) + (x1 - x3) * (py - y3);
413 baryCoords[1] = baryCoords[1] / det_T;
415 baryCoords[2] = 1 - baryCoords[1] - baryCoords[0];
420template <
class SC,
class LO,
class GO,
class NO>
421bool Mesh<SC,LO,GO,NO>:: isPointInElem(vec_dbl_Type point,
int element){
423 vec_dbl_Type baryCoords;
424 baryCoords = getBaryCoords(point, element);
426 if(baryCoords[0] >= 0 && baryCoords[1] >= 0 && baryCoords[2] >= 0){
432template <
class SC,
class LO,
class GO,
class NO>
434 this->elementsVec_ = Teuchos::rcp(
new vec2D_int_Type( this->elementsC_->numberElements() ) );
435 for (
int i=0; i<this->elementsVec_->size(); i++)
436 this->elementsVec_->at(i) = this->elementsC_->getElement(i).getVectorNodeList();
438 return this->elementsVec_;
441template <
class SC,
class LO,
class GO,
class NO>
444 int outwardNormals = 0;
445 int inwardNormals = 0;
446 for (UN T=0; T<elementsC_->numberElements(); T++) {
448 ElementsPtr_Type subEl = fe.getSubElements();
449 for (
int surface=0; surface<fe.numSubElements(); surface++) {
451 vec_int_Type nodeListElement = fe.getVectorNodeList();
452 if(subEl->getDimension() == dim_-1 ){
453 vec_int_Type nodeList = feSub.getVectorNodeListNonConst();
454 int numNodes_T = nodeList.size();
456 vec_dbl_Type v_E(dim_,1.);
458 LO id0 = nodeList[0];
462 std::sort(nodeList.begin(), nodeList.end());
463 std::sort(nodeListElement.begin(), nodeListElement.end());
465 std::vector<int> v_symDifference;
467 std::set_symmetric_difference(
468 nodeList.begin(), nodeList.end(),
469 nodeListElement.begin(), nodeListElement.end(),
470 std::back_inserter(v_symDifference));
472 LO id1 = v_symDifference[0];
474 vec_dbl_Type p0(dim_,0.);
475 for(
int i=0; i< dim_; i++)
476 p0[i] = pointsRep_->at(id1)[i] - pointsRep_->at(id0)[i];
479 for(
int i=0; i< dim_; i++)
480 sum += p0[i] * v_E[i];
489 flipSurface(subEl,surface);
495 Teuchos::reduceAll<int, int> (*this->
getComm(), Teuchos::REDUCE_SUM, inwardNormals, Teuchos::outArg (inwardNormals));
496 Teuchos::reduceAll<int, int> (*this->
getComm(), Teuchos::REDUCE_SUM, outwardNormals, Teuchos::outArg (outwardNormals));
498 if(this->
getComm()->getRank() == 0){
499 std::cout <<
" ############################################ " << std::endl;
500 std::cout <<
" Mesh Orientation Statistic " << std::endl;
501 std::cout <<
" Number of outward normals " << outwardNormals << std::endl;
502 std::cout <<
" Number of inward normals " << inwardNormals << std::endl;
503 std::cout <<
" ############################################ " << std::endl;
507template <
class SC,
class LO,
class GO,
class NO>
517 for (UN T=0; T<elementsC_->numberElements(); T++) {
519 detB = B.computeInverse(Binv);
528 flipElement(elementsC_,T);
531 std::cout <<
" Finished " << std::endl;
532 Teuchos::reduceAll<int, int> (*this->
getComm(), Teuchos::REDUCE_SUM, negDet, Teuchos::outArg (negDet));
533 Teuchos::reduceAll<int, int> (*this->
getComm(), Teuchos::REDUCE_SUM, posDet, Teuchos::outArg (posDet));
535 if(this->
getComm()->getRank() == 0){
536 std::cout <<
" ############################################ " << std::endl;
537 std::cout <<
" Mesh Orientation Statistic " << std::endl;
538 std::cout <<
" Number of positive dets " << posDet << std::endl;
539 std::cout <<
" Number of negative dets " << negDet << std::endl;
540 std::cout <<
" ############################################ " << std::endl;
548template <
class SC,
class LO,
class GO,
class NO>
549void Mesh<SC,LO,GO,NO>::flipSurface(ElementsPtr_Type subEl,
int surfaceNumber){
551 vec_LO_Type surfaceElements_vec = subEl->getElement(surfaceNumber).getVectorNodeList();
556 id1= surfaceElements_vec[0];
557 id2= surfaceElements_vec[1];
559 surfaceElements_vec[0] = id2;
560 surfaceElements_vec[1] = id1;
562 else if(FEType_ ==
"P2"){
564 id1= surfaceElements_vec[0];
565 id2= surfaceElements_vec[1];
566 id3= surfaceElements_vec[2];
568 surfaceElements_vec[0] = id2;
569 surfaceElements_vec[1] = id1;
570 surfaceElements_vec[2] = id3;
576 LO id1,id2,id3,id4,id5,id6;
577 id1= surfaceElements_vec[0];
578 id2= surfaceElements_vec[1];
579 id3= surfaceElements_vec[2];
581 surfaceElements_vec[0] = id1;
582 surfaceElements_vec[1] = id3;
583 surfaceElements_vec[2] = id2;
585 else if(FEType_ ==
"P2"){
586 LO id1,id2,id3,id4,id5,id6;
587 id1= surfaceElements_vec[0];
588 id2= surfaceElements_vec[1];
589 id3= surfaceElements_vec[2];
590 id4= surfaceElements_vec[3];
591 id5= surfaceElements_vec[4];
592 id6= surfaceElements_vec[5];
594 surfaceElements_vec[0] = id1;
595 surfaceElements_vec[1] = id3;
596 surfaceElements_vec[2] = id2;
597 surfaceElements_vec[3] = id6;
598 surfaceElements_vec[4] = id5;
599 surfaceElements_vec[5] = id4;
602 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
"We can only flip normals for P1 or P2 elements. Invalid " << FEType_ <<
" " );
605 FiniteElement feFlipped(surfaceElements_vec,subEl->getElement(surfaceNumber).getFlag());
606 subEl->switchElement(surfaceNumber,feFlipped);
612template <
class SC,
class LO,
class GO,
class NO>
613void Mesh<SC,LO,GO,NO>::flipElement(ElementsPtr_Type elements,
int elementNumber){
615 vec_LO_Type surfaceElements_vec = elements->getElement(elementNumber).getVectorNodeList();
619 id1= surfaceElements_vec[0];
620 id2= surfaceElements_vec[1];
621 id3= surfaceElements_vec[2];
623 surfaceElements_vec[0] = id1;
624 surfaceElements_vec[1] = id3;
625 surfaceElements_vec[2] = id2;
628 else if(FEType_ ==
"P2"){
629 LO id1,id2,id3,id4,id5,id6;
630 id1= surfaceElements_vec[0];
631 id2= surfaceElements_vec[1];
632 id3= surfaceElements_vec[2];
633 id4= surfaceElements_vec[3];
634 id5= surfaceElements_vec[4];
635 id6= surfaceElements_vec[5];
637 surfaceElements_vec[0] = id1;
638 surfaceElements_vec[1] = id3;
639 surfaceElements_vec[2] = id2;
640 surfaceElements_vec[3] = id6;
641 surfaceElements_vec[4] = id5;
642 surfaceElements_vec[5] = id4;
649 id1= surfaceElements_vec[0];
650 id2= surfaceElements_vec[1];
651 id3= surfaceElements_vec[2];
652 id4= surfaceElements_vec[3];
654 surfaceElements_vec[0] = id1;
655 surfaceElements_vec[1] = id3;
656 surfaceElements_vec[2] = id2;
657 surfaceElements_vec[3] = id4;
660 else if(FEType_ ==
"P2"){
661 LO id1,id2,id3,id4,id5,id6, id7,id8,id9,id0;
662 id0= surfaceElements_vec[0];
663 id1= surfaceElements_vec[1];
664 id2= surfaceElements_vec[2];
665 id3= surfaceElements_vec[3];
666 id4= surfaceElements_vec[4];
667 id5= surfaceElements_vec[5];
668 id6= surfaceElements_vec[6];
669 id7= surfaceElements_vec[7];
670 id8= surfaceElements_vec[8];
671 id9= surfaceElements_vec[9];
673 surfaceElements_vec[0] = id0;
674 surfaceElements_vec[1] = id2;
675 surfaceElements_vec[2] = id1;
676 surfaceElements_vec[3] = id3;
678 surfaceElements_vec[4] = id6;
679 surfaceElements_vec[5] = id5;
680 surfaceElements_vec[6] = id4;
681 surfaceElements_vec[7] = id7;
682 surfaceElements_vec[8] = id9;
683 surfaceElements_vec[9] = id8;
686 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
"We can only flip normals for P1 or P2 elements. Invalid " << FEType_ <<
" " );
689 FiniteElement feFlipped(surfaceElements_vec,elements->getElement(elementNumber).getFlag());
690 ElementsPtr_Type subElements = elements->getElement(elementNumber).getSubElements();
691 for(
int T = 0; T<elements->getElement(elementNumber).numSubElements(); T++){
692 if(!feFlipped.subElementsInitialized())
693 feFlipped.initializeSubElements( this->FEType_, this->dim_ -1) ;
694 feFlipped.addSubElement(subElements->getElement(T));
696 elements->switchElement(elementNumber,feFlipped);