525 {
526 TRACE();
527
529 std::vector<MFloat> RANSSectors;
530 RANSSectors.push_back(std::numeric_limits<MFloat>::max());
531 RANSSectors.push_back(-std::numeric_limits<MFloat>::max());
532 std::vector<MFloat> RANSSectorLimits;
533 RANSSectorLimits.push_back(std::numeric_limits<MFloat>::max());
534 RANSSectorLimits.push_back(-std::numeric_limits<MFloat>::max());
535 std::vector<MInt> cylinderExchangeIds;
536 std::vector<MFloat> cylinderExchangeLocations;
537
540
541 MInt noRANSExchangeCells = 0;
546
547
554
555 if(sector < RANSSectors[0]) {
556 RANSSectors[0] = sector;
557 }
558 if(sector > RANSSectors[1]) {
559 RANSSectors[1] = sector;
560 }
561 if(angle < RANSSectorLimits[0]) {
562 RANSSectorLimits[0] = angle;
563 }
564 if(angle > RANSSectorLimits[1]) {
565 RANSSectorLimits[1] = angle;
566 }
567
568 noRANSExchangeCells++;
569 cylinderExchangeIds.push_back(RANSId);
570 cylinderExchangeLocations.push_back(x);
571 cylinderExchangeLocations.push_back(
y);
572 cylinderExchangeLocations.push_back(z);
574
575 }
576 }
577 }
578
579 if(noRANSExchangeCells > 0) {
580 MInt noRANSExchangeCells_ = noRANSExchangeCells;
581
582 for(
MInt i = 0; i < noRANSExchangeCells_; i++) {
583 MInt RANSId = cylinderExchangeIds[i];
585 for(
MInt n = 0; n < noNghbrIds; n++) {
587 if(
RANSSolver().a_isBndryGhostCell(nghbrId)) {
591 noRANSExchangeCells++;
592 cylinderExchangeIds.push_back(nghbrId);
593 cylinderExchangeLocations.push_back(x);
594 cylinderExchangeLocations.push_back(
y);
595 cylinderExchangeLocations.push_back(z);
597 }
598 }
599 }
600 }
601
602
603#ifdef _MB_DEBUG_
604 if(noRANSExchangeCells > 0) {
605 stringstream f;
606 f.clear();
607 f <<
"globalCylinderExchange_" << to_string(
RANSSolver().domainId()) <<
".txt";
609 MString header =
"#id isHalo x1 x2 x3 sector";
610 ofstream data;
611 data.precision(16);
612 data.open(fname);
613 data << header << endl;
614 for(
MInt i = 0; i < noRANSExchangeCells; i++) {
616 line.append(to_string(cylinderExchangeIds[i]) + " "
617 + to_string(
RANSSolver().a_isBndryGhostCell(cylinderExchangeIds[i])) +
" "
618 + to_string(cylinderExchangeLocations[i * (nDim + 1) + 0]) + " "
619 + to_string(cylinderExchangeLocations[i * (nDim + 1) + 1]) + " "
620 + to_string(cylinderExchangeLocations[i * (nDim + 1) + 2]) + " "
621 + to_string(cylinderExchangeLocations[i * (nDim + 1) + 3]));
622 data << line << endl;
623 }
624 data.close();
625 }
626#endif
627
628
629
630 MPI_Allreduce(MPI_IN_PLACE, &RANSSectors[0], 1, MPI_DOUBLE, MPI_MIN,
LESSolver().mpiComm(), AT_,
"MPI_IN_PLACE",
631 "RANSSectors");
632 MPI_Allreduce(MPI_IN_PLACE, &RANSSectors[1], 1, MPI_DOUBLE, MPI_MAX,
LESSolver().mpiComm(), AT_,
"MPI_IN_PLACE",
633 "RANSSectors");
635 "MPI_IN_PLACE", "RANSSectorLimits");
637 "MPI_IN_PLACE", "RANSSectorLimits");
638
643
649
650
652 "noRANSExchangeCells", "m_noGlobalRANSExchangeCells");
653
659
663 "m_globalCylinderExchangeLocations", F0, FUN_);
665 "m_globalCylinderRANSExchangeValues", F0, FUN_);
667 "m_globalCylinderLESExchangeValues", F0, FUN_);
669
670
671
676
677
678 MPI_Allgather(&noRANSExchangeCells, 1, MPI_INT, &cellsPerDomain[0], 1, MPI_INT,
LESSolver().mpiComm(), AT_,
679 "noBc7909Cells ", "bc7909CellsperDomain");
681 "cylRanks");
682
683 MInt noInvolvedRanks = 0;
686 if(cellsPerDomain[i]) {
687 involvedRanks[noInvolvedRanks] = i;
688 ++noInvolvedRanks;
689 }
690 }
691
692 MPI_Comm commCyl;
693 MPI_Group group;
694 MPI_Group groupCyl;
696 MPI_Group_incl(group, noInvolvedRanks, &involvedRanks[0], &groupCyl, AT_);
697
700
701 MInt myCommRank = -1;
702 for(
MInt r = 0; r < noInvolvedRanks; r++) {
703 if(myCylRank == involvedRanks[r]) {
704 myCommRank = r;
705 break;
706 }
707 }
708
710
711
713
714
715 if(noRANSExchangeCells > 0) {
717
718
719 MInt noLocations = noRANSExchangeCells * (nDim + 1);
720 MInt noIds = noRANSExchangeCells;
721 if(noInvolvedRanks > 0) {
724 recvbufLocations.fill(0);
725
726 recvbufIds.fill(0);
727
728 MPI_Gather(&noLocations, 1, MPI_INT, &recvbufLocations[0], 1, MPI_INT, 0, commCyl, AT_,
"noLocations",
729 "recvbufLocations");
730
731
732 MPI_Gather(&noIds, 1, MPI_INT, &recvbufIds[0], 1, MPI_INT, 0, commCyl, AT_,
"noIds",
"recvbufIds");
733
735 if(myCommRank == 0) {
736 MInt offsetLocations = 0;
737
739 for(
MInt dom = 0; dom < noInvolvedRanks; dom++) {
740 displsLocations[dom] = offsetLocations;
741 displsIds[dom] = offsetIds;
742 offsetLocations += recvbufLocations[dom];
743 offsetIds += recvbufIds[dom];
744 }
745 }
746
748 &recvbufLocations[myCommRank], &displsLocations[myCommRank], MPI_DOUBLE, 0, commCyl, AT_,
749 "cylinderExchangeLocations", "m_globalCylinderExchangeLocations");
751 &displsIds[myCommRank], MPI_INT, 0, commCyl, AT_, "cylinderExchangeIds",
752 "m_globalCylinderExchangeIds");
753
754 } else {
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770 }
771 }
772
774 for(
MInt dom = 0; dom < noInvolvedRanks; dom++) {
775 if(dom == myCommRank) {
777 }
778 }
779
781 "m_cylRoot");
783 LESSolver().mpiComm(), AT_,
"m_globalCylinderExchangeLocations");
785 LESSolver().mpiComm(), AT_,
"m_globalCylinderExchangeIds");
786
787
788
789#ifdef _MB_DEBUG_
791 stringstream fn2;
792 fn2.clear();
793 fn2 << "globalCylinderExchange.txt";
795 MString header2 =
"#exchangeIndex id x1 x2 x3 sector";
796 ofstream data2;
797 data2.precision(16);
798 data2.open(fname2);
799 data2 << header2 << endl;
807 data2 << line << endl;
808 }
809 data2.close();
810 }
811#endif
812
813
814
815
816
820
823 }
824
827 }
828
829 MInt maxInterpCells = 4;
830 vector<vector<pair<MFloat, MInt>>> minDistIndex(
832 vector<pair<MFloat, MInt>>(maxInterpCells, make_pair(std::numeric_limits<MFloat>::infinity(), -1)));
833 vector<vector<pair<MFloat, MInt>>> minDistCell(
835 vector<pair<MFloat, MInt>>(maxInterpCells, make_pair(std::numeric_limits<MFloat>::infinity(), -1)));
836
837
846
851
852
853 for(
MInt r = 0; r < 2; r++) {
855 MFloat yRotated_ =
cos(rotationAngle_) *
y - sin(rotationAngle_) * z;
856 MFloat zRotated_ = sin(rotationAngle_) *
y +
cos(rotationAngle_) * z;
857 if(
approx(x, xExchange, F3 * cellHalfLength) &&
approx(yRotated_, yExchange, F3 * cellHalfLength)
858 &&
approx(zRotated_, zExchange, F3 * cellHalfLength)) {
859
860
864 make_pair<MInt, MFloat>((
MInt)LESId, (
MFloat)rotationAngle_));
865 }
866 }
867 }
868
869
870 MFloat rotationAngle = F0;
873 MFloat minAngleDist1 = F0;
874 MFloat minAngleDist2 = F0;
879 } else {
881 }
882 }
887 } else {
889 }
890 }
891 if(minAngleDist2 > minAngleDist1) {
892 rotationAngle = rotationAngle2;
893 } else {
894 rotationAngle = rotationAngle1;
895 }
897
898 if(RANSId != -1) rotationAngle = 0;
900 MFloat yRotated_ =
cos(rotationAngle) *
y - sin(rotationAngle) * z;
901 MFloat zRotated_ = sin(rotationAngle) *
y +
cos(rotationAngle) * z;
902 if(
approx(x, xExchange, F3 * cellHalfLength) &&
approx(yRotated_, yExchange, F4 * cellHalfLength)
903 &&
approx(zRotated_, zExchange, F4 * cellHalfLength)) {
904 MFloat delta_y = yRotated_ - yExchange;
905 MFloat delta_z = zRotated_ - zExchange;
907
908 MBool checkWindowHalo =
false;
909 if(!checkWindowHalo) {
910 if(
dist < minDistIndex[LESId][maxInterpCells - 1].first) {
911 minDistIndex[LESId][maxInterpCells - 1] = make_pair(
dist, exchangeIndex);
912
913 sort(minDistIndex[LESId].begin(), minDistIndex[LESId].end());
914 }
915 }
916 }
917 }
918 }
919
921 MFloat minY = std::numeric_limits<MFloat>::infinity();
922 MFloat maxY = -std::numeric_limits<MFloat>::infinity();
923 MFloat minZ = std::numeric_limits<MFloat>::infinity();
924 MFloat maxZ = -std::numeric_limits<MFloat>::infinity();
927 MFloat yRotated =
cos(rotationAngle) * coordLES[1] - sin(rotationAngle) * coordLES[2];
928 MFloat zRotated = sin(rotationAngle) * coordLES[1] +
cos(rotationAngle) * coordLES[2];
929
930
931
932
933 for(
MInt i = 0; i < maxInterpCells; i++) {
934 if(minDistIndex[LESId][i].second != -1) {
935 MInt exchangeIndex = minDistIndex[LESId][i].second;
936 MBool usePoint =
true;
938 if(i == maxInterpCells - 1) {
939 if(yRotated > minY && yRotated < maxY && zRotated > minZ && zRotated < maxZ) usePoint = false;
940 }
941 if(coordRANS[1] > yRotated && coordRANS[1] > maxY) maxY = coordRANS[1];
942 if(coordRANS[1] < yRotated && coordRANS[1] < minY) minY = coordRANS[1];
943 if(coordRANS[2] > zRotated && coordRANS[2] > maxZ) maxZ = coordRANS[2];
944 if(coordRANS[2] < zRotated && coordRANS[2] < minZ) minZ = coordRANS[2];
946 }
947 }
948
949
950 if(yRotated < minY || yRotated > maxY || zRotated < minZ || zRotated > maxZ) {
954 }
955 }
956
957 }
958
959
961 MInt testForOnlyHalo = 0;
965 }
966
969 }
970 }
971
972
973
974#ifdef _MB_DEBUG_
975 stringstream fn3;
976 fn3.clear();
977 fn3 <<
"globalCylinderLESCell_" << to_string(
LESSolver().domainId()) <<
".txt";
979 MString header3 =
"#exchangeIndex ...";
980 ofstream data3;
981 data3.precision(16);
982 data3.open(fname3);
983 data3 << header3 << endl;
985 MString line = to_string(exchangeIndex) +
" | ";
989 line.append("(" + to_string(cellId) + " " + to_string(rotationAngle) + " "
990 + to_string(
LESSolver().a_isHalo(cellId)) +
" ," + to_string(
LESSolver().a_coordinate(cellId, 0))
991 +
" " + to_string(
LESSolver().a_coordinate(cellId, 1)) +
" "
992 + to_string(
LESSolver().a_coordinate(cellId, 2)) +
") ");
993 }
994 data3 << line << endl;
995 }
996 data3.close();
997
998 stringstream fn4;
999 fn4.clear();
1000 fn4 <<
"globalCylinderLESIndex_" << to_string(
LESSolver().domainId()) <<
".txt";
1002 MString header4 =
"#LESId exchangeIndex ";
1003 ofstream data4;
1004 data4.precision(16);
1005 data4.open(fname4);
1006 data4 << header4 << endl;
1010 to_string(LESId) +
" " + to_string(
LESSolver().a_isHalo(LESId)) +
" "
1011 + to_string(
LESSolver().c_isLeafCell(LESId)) +
" | " + to_string(
LESSolver().a_coordinate(LESId, 0)) +
" "
1012 + to_string(
LESSolver().a_coordinate(LESId, 1)) +
" " + to_string(
LESSolver().a_coordinate(LESId, 2)) +
" ";
1015 line.append("(" + to_string(exchangeIndex) + ", "
1020 }
1021 data4 << line << endl;
1022 }
1023 data4.close();
1024#endif
1025
1026 }
1027}
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
MFloat c_cellLengthAtLevel(const MInt level) const
Returns the length of the cell for level.
MInt & a_reconstructionNeighborId(const MInt cellId, const MInt nghbrNo)
Returns reconstruction neighbor n of the cell cellId.
MInt & a_noReconstructionNeighbors(const MInt cellId)
Returns the noRcnstrctnNghbrIds of the cell cellId.
MInt m_commSizeCylExchange
MFloat * m_RANSSectorLimits
MInt m_noCylindricalGlobalExchangeIds
MInt m_noCylindricalGlobalExchangeLocations
MInt a_noFvGridCellsRANS() const
virtual MInt domainId() const
Return the domainId (rank)
MInt convertId(SolverA &solverA, SolverB &solverB, const MInt solverAId)
Conversion from solverA id to the solverB id on the same-level only!
std::basic_string< char > MString
int MPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm *newcomm, const MString &name, const MString &varname)
same as MPI_Comm_create, but updates the number of MPI communicators
int MPI_Group_incl(MPI_Group group, int n, const int ranks[], MPI_Group *newgroup, const MString &name)
same as MPI_Group_incl
int MPI_Comm_group(MPI_Comm comm, MPI_Group *group, const MString &name, const MString &varname)
same as MPI_Comm_group
int MPI_Gatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int recvcounts[], const int displs[], MPI_Datatype recvtype, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Gatherv
int MPI_Gather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Gather
int MPI_Allgather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allgather
MFloat getSector(MFloat y, MFloat z, MFloat azimuthalAngle)
MFloat getAngle(MFloat y, MFloat z)
MFloat dist(const Point< DIM > &p, const Point< DIM > &q)