191 if ( !FEType_.compare(
"P1") )
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") )
198 else if( !FEType_.compare(
"P2-CR") ){
199 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"P2-CR only available in 3D.");
201 else if( !FEType_.compare(
"Q2-20") ){
202 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Q2-20 only available in 3D.");
204 else if( !FEType_.compare(
"Q2") ){
205 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Q2 only available in 3D.");
209 if ( !FEType_.compare(
"P1") )
211 if ( !FEType_.compare(
"P1-disc") || !FEType_.compare(
"P1-disc-global") )
213 else if( !FEType_.compare(
"P2") )
215 else if( !FEType_.compare(
"P2-CR") )
217 else if( !FEType_.compare(
"Q2-20") )
219 else if( !FEType_.compare(
"Q2") )
229template <
class SC,
class LO,
class GO,
class NO>
239 pointsRepRef_.reset(
new vec2D_dbl_Type() );
240 pointsUniRef_.reset(
new vec2D_dbl_Type() );
243 *pointsRepRef_ = *pointsRep_;
244 *pointsUniRef_ = *pointsUni_;
265template <
class SC,
class LO,
class GO,
class NO>
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.")
272 Teuchos::ArrayRCP<const SC> values = displacementRepeated->getData(0);
273 for(
int i = 0; i < pointsRepRef_->size(); i++)
275 for(
int j = 0; j < pointsRepRef_->at(0).size(); j++)
281 pointsRep_->at(i).at(j) = pointsRepRef_->at(i).at(j) + values[dim_*i+j];
286 values = displacementUnique->getData(0);
287 for(
int i = 0; i < pointsUniRef_->size(); i++)
289 for(
int j = 0; j < pointsUniRef_->at(0).size(); j++)
300 pointsUni_->at(i).at(j) = pointsUniRef_->at(i).at(j) + values[dim_*i+j];
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());
310 AABBTree_->createTreeFromElements(
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
320 int numPoints = queryPoints->size();
324 vec_int_ptr_Type pointToElem(
332 if (AABBTree_->isEmpty()){
333 AABBTree_->createTreeFromElements(
341 std::map<int, std::list<int> > treeToItem;
342 std::map<int, std::list<int> > itemToTree;
343 tie(treeToItem, itemToTree) = AABBTree_->scanTree(queryPoints,
false);
349 std::list<int> rectangles;
350 std::list<int> elements;
351 for (
auto keyValue: itemToTree){
357 point = keyValue.first;
358 rectangles = keyValue.second;
362 for(
auto rectangle: rectangles){
363 elements = AABBTree_->getElements(rectangle);
364 for(
auto element: elements){
365 found = isPointInElem(queryPoints->at(point), element);
367 pointToElem->at(point) = element;
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(
389 for (
int localNode=0; localNode<localNodes.size(); localNode++){
390 node = localNodes.at(localNode);
391 coords.at(localNode) = pointsRep_->at(node);
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);
401 double det_T = (y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3);
403 vec_dbl_Type baryCoords(
407 baryCoords[0] =(y2 - y3) * (px - x3) + (x3 - x2) * (py - y3);
408 baryCoords[0] = baryCoords[0] / det_T;
410 baryCoords[1] = (y3 -y1) * (px - x3) + (x1 - x3) * (py - y3);
411 baryCoords[1] = baryCoords[1] / det_T;
413 baryCoords[2] = 1 - baryCoords[1] - baryCoords[0];
418template <
class SC,
class LO,
class GO,
class NO>
419bool Mesh<SC,LO,GO,NO>:: isPointInElem(vec_dbl_Type point,
int element){
421 vec_dbl_Type baryCoords;
422 baryCoords = getBaryCoords(point, element);
424 if(baryCoords[0] >= 0 && baryCoords[1] >= 0 && baryCoords[2] >= 0){
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();
436 return this->elementsVec_;
439template <
class SC,
class LO,
class GO,
class NO>
442 int outwardNormals = 0;
443 int inwardNormals = 0;
444 for (UN T=0; T<elementsC_->numberElements(); T++) {
446 ElementsPtr_Type subEl = fe.getSubElements();
447 for (
int surface=0; surface<fe.numSubElements(); 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();
454 vec_dbl_Type v_E(dim_,1.);
456 LO id0 = nodeList[0];
460 std::sort(nodeList.begin(), nodeList.end());
461 std::sort(nodeListElement.begin(), nodeListElement.end());
463 std::vector<int> v_symDifference;
465 std::set_symmetric_difference(
466 nodeList.begin(), nodeList.end(),
467 nodeListElement.begin(), nodeListElement.end(),
468 std::back_inserter(v_symDifference));
470 LO id1 = v_symDifference[0];
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];
477 for(
int i=0; i< dim_; i++)
478 sum += p0[i] * v_E[i];
487 flipSurface(subEl,surface);
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));
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;
505template <
class SC,
class LO,
class GO,
class NO>
515 for (UN T=0; T<elementsC_->numberElements(); T++) {
517 detB = B.computeInverse(Binv);
526 flipElement(elementsC_,T);
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));
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;
545template <
class SC,
class LO,
class GO,
class NO>
546void Mesh<SC,LO,GO,NO>::flipSurface(ElementsPtr_Type subEl,
int surfaceNumber){
548 vec_LO_Type surfaceElements_vec = subEl->getElement(surfaceNumber).getVectorNodeList();
553 id1= surfaceElements_vec[0];
554 id2= surfaceElements_vec[1];
556 surfaceElements_vec[0] = id2;
557 surfaceElements_vec[1] = id1;
559 else if(FEType_ ==
"P2"){
561 id1= surfaceElements_vec[0];
562 id2= surfaceElements_vec[1];
563 id3= surfaceElements_vec[2];
565 surfaceElements_vec[0] = id2;
566 surfaceElements_vec[1] = id1;
567 surfaceElements_vec[2] = id3;
573 LO id1,id2,id3,id4,id5,id6;
574 id1= surfaceElements_vec[0];
575 id2= surfaceElements_vec[1];
576 id3= surfaceElements_vec[2];
578 surfaceElements_vec[0] = id1;
579 surfaceElements_vec[1] = id3;
580 surfaceElements_vec[2] = id2;
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];
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;
599 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
"We can only flip normals for P1 or P2 elements. Invalid " << FEType_ <<
" " );
602 FiniteElement feFlipped(surfaceElements_vec,subEl->getElement(surfaceNumber).getFlag());
603 subEl->switchElement(surfaceNumber,feFlipped);
609template <
class SC,
class LO,
class GO,
class NO>
610void Mesh<SC,LO,GO,NO>::flipElement(ElementsPtr_Type elements,
int elementNumber){
612 vec_LO_Type surfaceElements_vec = elements->getElement(elementNumber).getVectorNodeList();
616 id1= surfaceElements_vec[0];
617 id2= surfaceElements_vec[1];
618 id3= surfaceElements_vec[2];
620 surfaceElements_vec[0] = id1;
621 surfaceElements_vec[1] = id3;
622 surfaceElements_vec[2] = id2;
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];
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;
646 id1= surfaceElements_vec[0];
647 id2= surfaceElements_vec[1];
648 id3= surfaceElements_vec[2];
649 id4= surfaceElements_vec[3];
651 surfaceElements_vec[0] = id1;
652 surfaceElements_vec[1] = id3;
653 surfaceElements_vec[2] = id2;
654 surfaceElements_vec[3] = id4;
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];
670 surfaceElements_vec[0] = id0;
671 surfaceElements_vec[1] = id2;
672 surfaceElements_vec[2] = id1;
673 surfaceElements_vec[3] = id3;
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;
683 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
"We can only flip normals for P1 or P2 elements. Invalid " << FEType_ <<
" " );
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));
693 elements->switchElement(elementNumber,feFlipped);