513 for (
unsigned int i = 0; i <
Dim; ++i) {
534 const int ranks =
Comm->size();
536 auto view2 =
rho2_mr.getView();
537 auto view1 = this->
rhs_mp->getView();
539 const int nghost2 =
rho2_mr.getNghost();
540 const int nghost1 = this->
rhs_mp->getNghost();
542 const auto& ldom2 =
layout2_m->getLocalNDIndex();
543 const auto& ldom1 =
layout_mp->getLocalNDIndex();
547 const auto& lDomains2 =
layout2_m->getHostLocalDomains();
550 std::vector<MPI_Request> requests(0);
552 for (
int i = 0; i < ranks; ++i) {
553 if (lDomains2[i].touches(ldom1)) {
554 auto intersection = lDomains2[i].intersect(ldom1);
562 const auto& lDomains1 =
layout_mp->getHostLocalDomains();
564 for (
int i = 0; i < ranks; ++i) {
565 if (lDomains1[i].touches(ldom2)) {
566 auto intersection = lDomains1[i].intersect(ldom2);
569 nrecvs = intersection.size();
576 unpack(intersection, view2,
fd_m, nghost2, ldom2);
581 if (requests.size() > 0) {
582 MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
587 Kokkos::parallel_for(
588 "Write rho on the doubled grid", this->
rhs_mp->getFieldRangePolicy(),
589 KOKKOS_LAMBDA(
const size_t i,
const size_t j,
const size_t k) {
590 const size_t ig2 = i + ldom2[0].first() - nghost2;
591 const size_t jg2 = j + ldom2[1].first() - nghost2;
592 const size_t kg2 = k + ldom2[2].first() - nghost2;
594 const size_t ig1 = i + ldom1[0].first() - nghost1;
595 const size_t jg1 = j + ldom1[1].first() - nghost1;
596 const size_t kg1 = k + ldom1[2].first() - nghost1;
599 const bool isQuadrant1 = ((ig1 == ig2) && (jg1 == jg2) && (kg1 == kg2));
600 view2(i, j, k) = view1(i, j, k) * isQuadrant1;
642 for (
unsigned int i = 0; i <
Dim; ++i) {
656 "FFTOpenPoissonSolver::initializeFields()",
657 "Currently only HOCKNEY, VICO, DCT_VICO, and BIHARMONIC are "
658 "supported for open BCs");
673 const auto& lDomains1 =
layout_mp->getHostLocalDomains();
675 std::vector<MPI_Request> requests(0);
677 for (
int i = 0; i < ranks; ++i) {
678 if (lDomains1[i].touches(ldom2)) {
679 auto intersection = lDomains1[i].intersect(ldom2);
682 view2,
fd_m, requests);
687 const auto& lDomains2 =
layout2_m->getHostLocalDomains();
689 for (
int i = 0; i < ranks; ++i) {
690 if (ldom1.touches(lDomains2[i])) {
691 auto intersection = ldom1.intersect(lDomains2[i]);
694 nrecvs = intersection.size();
702 unpack(intersection, view1,
fd_m, nghost1, ldom1);
707 if (requests.size() > 0) {
708 MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
713 Kokkos::parallel_for(
714 "Write the solution into the LHS on physical grid",
715 this->
rhs_mp->getFieldRangePolicy(),
716 KOKKOS_LAMBDA(
const int i,
const int j,
const int k) {
717 const int ig2 = i + ldom2[0].first() - nghost2;
718 const int jg2 = j + ldom2[1].first() - nghost2;
719 const int kg2 = k + ldom2[2].first() - nghost2;
721 const int ig = i + ldom1[0].first() - nghost1;
722 const int jg = j + ldom1[1].first() - nghost1;
723 const int kg = k + ldom1[2].first() - nghost1;
726 const bool isQuadrant1 = ((ig == ig2) && (jg == jg2) && (kg == kg2));
727 view1(i, j, k) = view2(i, j, k) * isQuadrant1;
747 auto viewL = this->
lhs_mp->getView();
748 const int nghostL = this->
lhs_mp->getNghost();
752 const int nghostR =
rho2tr_m.getNghost();
756 auto view_g =
temp_m.getView();
760 const Kokkos::complex<Trhs> I = {0.0, 1.0};
767 for (
size_t gd = 0; gd <
Dim; ++gd) {
769 Kokkos::parallel_for(
770 "Gradient - E field",
rho2tr_m.getFieldRangePolicy(),
771 KOKKOS_LAMBDA(
const int i,
const int j,
const int k) {
773 const int ig = i + ldomR[0].first() - nghostR;
774 const int jg = j + ldomR[1].first() - nghostR;
775 const int kg = k + ldomR[2].first() - nghostR;
781 const bool shift = (iVec[gd] > N[gd]);
782 const bool notMid = (iVec[gd] != N[gd]);
784 k_gd = notMid * (
pi / Len) * (iVec[gd] - shift * 2 * N[gd]);
786 view_g(i, j, k) = -(I * k_gd) * viewR(i, j, k);
799 for (
unsigned int i = 0; i <
Dim; ++i) {
813 "FFTOpenPoissonSolver::initializeFields()",
814 "Currently only HOCKNEY, VICO, DCT_VICO, and BIHARMONIC are "
815 "supported for open BCs");
830 const auto& lDomains1 =
layout_mp->getHostLocalDomains();
831 std::vector<MPI_Request> requests(0);
833 for (
int i = 0; i < ranks; ++i) {
834 if (lDomains1[i].touches(ldom2)) {
835 auto intersection = lDomains1[i].intersect(ldom2);
838 view2,
fd_m, requests);
843 const auto& lDomains2 =
layout2_m->getHostLocalDomains();
845 for (
int i = 0; i < ranks; ++i) {
846 if (ldom1.touches(lDomains2[i])) {
847 auto intersection = ldom1.intersect(lDomains2[i]);
850 nrecvs = intersection.size();
858 unpack(intersection, viewL, gd,
fd_m, nghostL, ldom1);
863 if (requests.size() > 0) {
864 MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
869 Kokkos::parallel_for(
870 "Write the E-field on physical grid", this->
lhs_mp->getFieldRangePolicy(),
871 KOKKOS_LAMBDA(
const int i,
const int j,
const int k) {
872 const int ig2 = i + ldom2[0].first() - nghost2;
873 const int jg2 = j + ldom2[1].first() - nghost2;
874 const int kg2 = k + ldom2[2].first() - nghost2;
876 const int ig = i + ldom1[0].first() - nghostL;
877 const int jg = j + ldom1[1].first() - nghostL;
878 const int kg = k + ldom1[2].first() - nghostL;
881 const bool isQuadrant1 = ((ig == ig2) && (jg == jg2) && (kg == kg2));
882 viewL(i, j, k)[gd] = view2(i, j, k) * isQuadrant1;
897 auto viewH =
hess_m.getView();
898 const int nghostH =
hess_m.getNghost();
902 const int nghostR =
rho2tr_m.getNghost();
906 auto view_g =
temp_m.getView();
916 for (
size_t row = 0; row <
Dim; ++row) {
917 for (
size_t col = 0; col <
Dim; ++col) {
922 Kokkos::parallel_for(
923 "Hessian",
rho2tr_m.getFieldRangePolicy(),
924 KOKKOS_LAMBDA(
const int i,
const int j,
const int k) {
926 const int ig = i + ldomR[0].first() - nghostR;
927 const int jg = j + ldomR[1].first() - nghostR;
928 const int kg = k + ldomR[2].first() - nghostR;
933 for (
size_t d = 0; d <
Dim; ++d) {
935 const bool shift = (iVec[d] > N[d]);
936 const bool isMid = (iVec[d] == N[d]);
937 const bool notDiag = (row != col);
939 kVec[d] = (1 - (notDiag * isMid)) * (
pi / Len)
940 * (iVec[d] - shift * 2 * N[d]);
943 view_g(i, j, k) = -(kVec[col] * kVec[row]) * viewR(i, j, k);
956 for (
unsigned int i = 0; i <
Dim; ++i) {
970 "FFTOpenPoissonSolver::initializeFields()",
971 "Currently only HOCKNEY, VICO, DCT_VICO, and BIHARMONIC are "
972 "supported for open BCs");
987 const auto& lDomains1 =
layout_mp->getHostLocalDomains();
988 std::vector<MPI_Request> requests(0);
990 for (
int i = 0; i < ranks; ++i) {
991 if (lDomains1[i].touches(ldom2)) {
992 auto intersection = lDomains1[i].intersect(ldom2);
995 nghost2, view2,
fd_m, requests);
1000 const auto& lDomains2 =
layout2_m->getHostLocalDomains();
1002 for (
int i = 0; i < ranks; ++i) {
1003 if (ldom1.touches(lDomains2[i])) {
1004 auto intersection = ldom1.intersect(lDomains2[i]);
1007 nrecvs = intersection.size();
1012 nrecvs *
sizeof(
Trhs), nrecvs);
1013 buf->resetReadPos();
1015 unpack(intersection, viewH,
fd_m, nghostH, ldom1, row, col);
1020 if (requests.size() > 0) {
1021 MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
1026 Kokkos::parallel_for(
1027 "Write Hessian on physical grid",
hess_m.getFieldRangePolicy(),
1028 KOKKOS_LAMBDA(
const int i,
const int j,
const int k) {
1029 const int ig2 = i + ldom2[0].first() - nghost2;
1030 const int jg2 = j + ldom2[1].first() - nghost2;
1031 const int kg2 = k + ldom2[2].first() - nghost2;
1033 const int ig = i + ldom1[0].first() - nghostH;
1034 const int jg = j + ldom1[1].first() - nghostH;
1035 const int kg = k + ldom1[2].first() - nghostH;
1038 const bool isQuadrant1 =
1039 ((ig == ig2) && (jg == jg2) && (kg == kg2));
1040 viewH(i, j, k)[row][col] = view2(i, j, k) * isQuadrant1;
1068 for (
unsigned int i = 0; i <
Dim; ++i) {
1069 hs_m[i] =
pi * 0.5 / l[i];
1070 L_sum = L_sum + l[i] * l[i];
1076 for (
unsigned int i = 0; i <
Dim; ++i) {
1077 origin[i] = -2 *
nr_m[i] *
pi / l[i];
1081 mesh4_m->setMeshSpacing(hs_m);
1084 L_sum = std::sqrt(L_sum);
1086 L_sum = 1.1 * L_sum;
1090 const int nghost_g =
grnL_m.getNghost();
1091 const auto& ldom_g =
layout4_m->getLocalNDIndex();
1097 Kokkos::parallel_for(
1098 "Initialize Green's function ",
grnL_m.getFieldRangePolicy(),
1099 KOKKOS_LAMBDA(
const int i,
const int j,
const int k) {
1101 const int ig = i + ldom_g[0].first() - nghost_g;
1102 const int jg = j + ldom_g[1].first() - nghost_g;
1103 const int kg = k + ldom_g[2].first() - nghost_g;
1105 bool isOutside = (ig > 2 * size[0] - 1);
1106 const Tg t = ig * hs_m[0] + isOutside * origin[0];
1108 isOutside = (jg > 2 * size[1] - 1);
1109 const Tg u = jg * hs_m[1] + isOutside * origin[1];
1111 isOutside = (kg > 2 * size[2] - 1);
1112 const Tg v = kg * hs_m[2] + isOutside * origin[2];
1114 Tg s = (t * t) + (u * u) + (v * v);
1115 s = Kokkos::sqrt(s);
1120 const bool isOrig = ((ig == 0 && jg == 0 && kg == 0));
1121 const Tg analyticLim = -L_sum * L_sum * 0.5;
1122 const Tg value = -2.0 * (Kokkos::sin(0.5 * L_sum * s) / (s + isOrig * 1.0))
1123 * (Kokkos::sin(0.5 * L_sum * s) / (s + isOrig * 1.0));
1125 view_g(i, j, k) = (!isOrig) * value + isOrig * analyticLim;
1128 Kokkos::parallel_for(
1129 "Initialize Green's function ",
grnL_m.getFieldRangePolicy(),
1130 KOKKOS_LAMBDA(
const int i,
const int j,
const int k) {
1132 const int ig = i + ldom_g[0].first() - nghost_g;
1133 const int jg = j + ldom_g[1].first() - nghost_g;
1134 const int kg = k + ldom_g[2].first() - nghost_g;
1136 bool isOutside = (ig > 2 * size[0] - 1);
1137 const Tg t = ig * hs_m[0] + isOutside * origin[0];
1139 isOutside = (jg > 2 * size[1] - 1);
1140 const Tg u = jg * hs_m[1] + isOutside * origin[1];
1142 isOutside = (kg > 2 * size[2] - 1);
1143 const Tg v = kg * hs_m[2] + isOutside * origin[2];
1145 Tg s = (t * t) + (u * u) + (v * v);
1146 s = Kokkos::sqrt(s);
1149 const bool isOrig = ((ig == 0 && jg == 0 && kg == 0));
1150 const Tg analyticLim = -L_sum * L_sum * L_sum * L_sum / 8.0;
1151 const Tg value = -((2 - (L_sum * L_sum * s * s)) * Kokkos::cos(L_sum * s)
1152 + 2 * L_sum * s * Kokkos::sin(L_sum * s) - 2)
1153 / (2 * s * s * s * s + isOrig * 1.0);
1155 view_g(i, j, k) = (!isOrig) * value + isOrig * analyticLim;
1172 const int nghost =
grn_mr.getNghost();
1173 const auto& ldom =
layout2_m->getLocalNDIndex();
1180 const int ranks =
Comm->size();
1186 using mdrange_type = Kokkos::MDRangePolicy<Kokkos::Rank<3>>;
1187 Kokkos::parallel_for(
1188 "Restrict domain of Green's function from 4N to 2N",
1189 mdrange_type({nghost, nghost, nghost}, {view.extent(0) - nghost - size[0],
1190 view.extent(1) - nghost - size[1],
1191 view.extent(2) - nghost - size[2]}),
1192 KOKKOS_LAMBDA(
const int i,
const int j,
const int k) {
1194 const int ig = i + ldom[0].first() - nghost;
1195 const int jg = j + ldom[1].first() - nghost;
1196 const int kg = k + ldom[2].first() - nghost;
1198 const int ig2 = i + ldom_g[0].first() - nghost_g;
1199 const int jg2 = j + ldom_g[1].first() - nghost_g;
1200 const int kg2 = k + ldom_g[2].first() - nghost_g;
1202 const bool isOrig = (ig == ig2) && (jg == jg2) && (kg == kg2);
1203 view(i, j, k) = isOrig * real(view_g(i, j, k));
1206 const int s = 2 * size[0] - ig - 1 - ldom_g[0].first() + nghost_g;
1207 const int p = 2 * size[1] - jg - 1 - ldom_g[1].first() + nghost_g;
1208 const int q = 2 * size[2] - kg - 1 - ldom_g[2].first() + nghost_g;
1210 view(s, j, k) = real(view_g(i + 1, j, k));
1211 view(i, p, k) = real(view_g(i, j + 1, k));
1212 view(i, j, q) = real(view_g(i, j, k + 1));
1213 view(s, j, q) = real(view_g(i + 1, j, k + 1));
1214 view(s, p, k) = real(view_g(i + 1, j + 1, k));
1215 view(i, p, q) = real(view_g(i, j + 1, k + 1));
1216 view(s, p, q) = real(view_g(i + 1, j + 1, k + 1));
1228 for (
unsigned int i = 0; i <
Dim; ++i) {
1229 hs_m[i] = Kokkos::numbers::pi_v<Trhs> * 0.5 / l[i];
1230 L_sum = L_sum + l[i] * l[i];
1240 L_sum = Kokkos::sqrt(L_sum);
1241 L_sum = 1.1 * L_sum;
1248 const int nghost_g2n1 =
grn2n1_m.getNghost();
1249 const auto& ldom_g2n1 =
layout2n1_m->getLocalNDIndex();
1251 Kokkos::parallel_for(
1252 "Initialize 2N+1 Green's function ",
grn2n1_m.getFieldRangePolicy(),
1253 KOKKOS_LAMBDA(
const int i,
const int j,
const int k) {
1255 const int ig = i + ldom_g2n1[0].first() - nghost_g2n1;
1256 const int jg = j + ldom_g2n1[1].first() - nghost_g2n1;
1257 const int kg = k + ldom_g2n1[2].first() - nghost_g2n1;
1259 double t = ig * hs_m[0];
1260 double u = jg * hs_m[1];
1261 double v = kg * hs_m[2];
1263 double s = (t * t) + (u * u) + (v * v);
1264 s = Kokkos::sqrt(s);
1266 const bool isOrig = ((ig == 0 && jg == 0 && kg == 0));
1267 const double val = -2.0 * (Kokkos::sin(0.5 * L_sum * s) / (s + isOrig * 1.0))
1268 * (Kokkos::sin(0.5 * L_sum * s) / (s + isOrig * 1.0));
1269 const double analyticLim = -L_sum * L_sum * 0.5;
1271 view_g2n1(i, j, k) = ((!isOrig) * val) + (isOrig * analyticLim);
1287 const int nghost =
grn_mr.getNghost();
1288 const auto& ldom =
layout2_m->getLocalNDIndex();
1298 using mdrange_type = Kokkos::MDRangePolicy<Kokkos::Rank<3>>;
1301 communicateVico(size, view_g2n1, ldom_g2n1, nghost_g2n1, view, ldom, nghost);
1304 Kokkos::parallel_for(
1305 "Restrict domain of Green's function from 2N+1 to 2N",
1306 mdrange_type({nghost, nghost, nghost}, {view.extent(0) - nghost - size[0],
1307 view.extent(1) - nghost - size[1],
1308 view.extent(2) - nghost - size[2]}),
1309 KOKKOS_LAMBDA(
const int i,
const int j,
const int k) {
1311 const int ig = i + ldom[0].first() - nghost;
1312 const int jg = j + ldom[1].first() - nghost;
1313 const int kg = k + ldom[2].first() - nghost;
1315 const int ig2 = i + ldom_g2n1[0].first() - nghost_g2n1;
1316 const int jg2 = j + ldom_g2n1[1].first() - nghost_g2n1;
1317 const int kg2 = k + ldom_g2n1[2].first() - nghost_g2n1;
1319 const bool isOrig = ((ig == ig2) && (jg == jg2) && (kg == kg2));
1320 view(i, j, k) = isOrig * view_g2n1(i, j, k);
1323 const int s = 2 * size[0] - ig - 1 - ldom_g2n1[0].first() + nghost_g2n1;
1324 const int p = 2 * size[1] - jg - 1 - ldom_g2n1[1].first() + nghost_g2n1;
1325 const int q = 2 * size[2] - kg - 1 - ldom_g2n1[2].first() + nghost_g2n1;
1327 view(s, j, k) = view_g2n1(i + 1, j, k);
1328 view(i, p, k) = view_g2n1(i, j + 1, k);
1329 view(i, j, q) = view_g2n1(i, j, k + 1);
1330 view(s, j, q) = view_g2n1(i + 1, j, k + 1);
1331 view(s, p, k) = view_g2n1(i + 1, j + 1, k);
1332 view(i, p, q) = view_g2n1(i, j + 1, k + 1);
1333 view(s, p, q) = view_g2n1(i + 1, j + 1, k + 1);
1344 for (
unsigned int i = 0; i <
Dim; ++i) {
1351 const int nghost =
grn_mr.getNghost();
1352 const auto& ldom =
layout2_m->getLocalNDIndex();
1355 Kokkos::parallel_for(
1356 "Regularize Green's function ",
grn_mr.getFieldRangePolicy(),
1357 KOKKOS_LAMBDA(
const int i,
const int j,
const int k) {
1359 const int ig = i + ldom[0].first() - nghost;
1360 const int jg = j + ldom[1].first() - nghost;
1361 const int kg = k + ldom[2].first() - nghost;
1364 const bool isOrig = (ig == 0 && jg == 0 && kg == 0);
1365 view(i, j, k) = isOrig * (-1.0 / (4.0 *
pi)) + (!isOrig) * view(i, j, k);
1384 const auto& lDomains2 =
layout2_m->getHostLocalDomains();
1385 const auto& lDomains4 =
layout4_m->getHostLocalDomains();
1387 std::vector<MPI_Request> requests(0);
1388 const int ranks =
Comm->size();
1392 for (
unsigned i = 0; i <
Dim; i++) {
1427 for (
unsigned i = 0; i <
Dim; i++) {
1432 for (
int i = 0; i < ranks; ++i) {
1433 auto domain2 = lDomains2[i];
1435 if (domain2.touches(none)) {
1436 auto intersection = domain2.intersect(none);
1438 if (ldom_g.
touches(intersection)) {
1439 intersection = intersection.intersect(ldom_g);
1446 if (domain2.touches(x)) {
1447 auto intersection = domain2.intersect(x);
1449 (2 * size[0] - intersection[0].last()), -1);
1453 domain4[1] = intersection[1];
1454 domain4[2] = intersection[2];
1456 if (ldom_g.
touches(domain4)) {
1457 intersection = ldom_g.
intersect(domain4);
1464 if (domain2.touches(y)) {
1465 auto intersection = domain2.intersect(y);
1467 (2 * size[1] - intersection[1].last()), -1);
1470 domain4[0] = intersection[0];
1472 domain4[2] = intersection[2];
1474 if (ldom_g.
touches(domain4)) {
1475 intersection = ldom_g.
intersect(domain4);
1482 if (domain2.touches(z)) {
1483 auto intersection = domain2.intersect(z);
1485 (2 * size[2] - intersection[2].last()), -1);
1488 domain4[0] = intersection[0];
1489 domain4[1] = intersection[1];
1492 if (ldom_g.
touches(domain4)) {
1493 intersection = ldom_g.
intersect(domain4);
1500 if (domain2.touches(xy)) {
1501 auto intersection = domain2.intersect(xy);
1503 (2 * size[0] - intersection[0].last()), -1);
1505 (2 * size[1] - intersection[1].last()), -1);
1510 domain4[2] = intersection[2];
1512 if (ldom_g.
touches(domain4)) {
1513 intersection = ldom_g.
intersect(domain4);
1520 if (domain2.touches(yz)) {
1521 auto intersection = domain2.intersect(yz);
1523 (2 * size[1] - intersection[1].last()), -1);
1525 (2 * size[2] - intersection[2].last()), -1);
1528 domain4[0] = intersection[0];
1532 if (ldom_g.
touches(domain4)) {
1533 intersection = ldom_g.
intersect(domain4);
1539 if (domain2.touches(xz)) {
1540 auto intersection = domain2.intersect(xz);
1542 (2 * size[0] - intersection[0].last()), -1);
1544 (2 * size[2] - intersection[2].last()), -1);
1548 domain4[1] = intersection[1];
1551 if (ldom_g.
touches(domain4)) {
1552 intersection = ldom_g.
intersect(domain4);
1558 if (domain2.touches(xyz)) {
1559 auto intersection = domain2.intersect(xyz);
1561 (2 * size[0] - intersection[0].last()), -1);
1563 (2 * size[1] - intersection[1].last()), -1);
1565 (2 * size[2] - intersection[2].last()), -1);
1572 if (ldom_g.
touches(domain4)) {
1573 intersection = ldom_g.
intersect(domain4);
1581 for (
int i = 0; i < ranks; ++i) {
1583 auto intersection = ldom.
intersect(none);
1585 if (lDomains4[i].touches(intersection)) {
1586 intersection = intersection.intersect(lDomains4[i]);
1597 (2 * size[0] - intersection[0].last()), -1);
1601 domain4[1] = intersection[1];
1602 domain4[2] = intersection[2];
1604 if (lDomains4[i].touches(domain4)) {
1605 domain4 = lDomains4[i].
intersect(domain4);
1607 2 * size[0] - domain4[0].last(), -1);
1609 intersection = intersection.intersect(domain4);
1612 true,
false,
false);
1620 (2 * size[1] - intersection[1].last()), -1);
1623 domain4[0] = intersection[0];
1625 domain4[2] = intersection[2];
1627 if (lDomains4[i].touches(domain4)) {
1628 domain4 = lDomains4[i].
intersect(domain4);
1630 2 * size[1] - domain4[1].last(), -1);
1632 intersection = intersection.intersect(domain4);
1635 false,
true,
false);
1643 (2 * size[2] - intersection[2].last()), -1);
1646 domain4[0] = intersection[0];
1647 domain4[1] = intersection[1];
1650 if (lDomains4[i].touches(domain4)) {
1651 domain4 = lDomains4[i].
intersect(domain4);
1653 2 * size[2] - domain4[2].last(), -1);
1655 intersection = intersection.intersect(domain4);
1658 false,
false,
true);
1666 (2 * size[0] - intersection[0].last()), -1);
1668 (2 * size[1] - intersection[1].last()), -1);
1673 domain4[2] = intersection[2];
1675 if (lDomains4[i].touches(domain4)) {
1676 domain4 = lDomains4[i].
intersect(domain4);
1678 2 * size[0] - domain4[0].last(), -1);
1680 2 * size[1] - domain4[1].last(), -1);
1682 intersection = intersection.intersect(domain4);
1693 (2 * size[1] - intersection[1].last()), -1);
1695 (2 * size[2] - intersection[2].last()), -1);
1698 domain4[0] = intersection[0];
1702 if (lDomains4[i].touches(domain4)) {
1703 domain4 = lDomains4[i].
intersect(domain4);
1705 2 * size[1] - domain4[1].last(), -1);
1707 2 * size[2] - domain4[2].last(), -1);
1709 intersection = intersection.intersect(domain4);
1720 (2 * size[0] - intersection[0].last()), -1);
1722 (2 * size[2] - intersection[2].last()), -1);
1726 domain4[1] = intersection[1];
1729 if (lDomains4[i].touches(domain4)) {
1730 domain4 = lDomains4[i].
intersect(domain4);
1732 2 * size[0] - domain4[0].last(), -1);
1734 2 * size[2] - domain4[2].last(), -1);
1736 intersection = intersection.intersect(domain4);
1744 auto intersection = ldom.
intersect(xyz);
1747 (2 * size[0] - intersection[0].last()), -1);
1749 (2 * size[1] - intersection[1].last()), -1);
1751 (2 * size[2] - intersection[2].last()), -1);
1758 if (lDomains4[i].touches(domain4)) {
1759 domain4 = lDomains4[i].
intersect(domain4);
1761 2 * size[0] - domain4[0].last(), -1);
1763 2 * size[1] - domain4[1].last(), -1);
1765 2 * size[2] - domain4[2].last(), -1);
1767 intersection = intersection.intersect(domain4);
1775 if (requests.size() > 0) {
1776 MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
1787 const auto& lDomains2 =
layout2_m->getHostLocalDomains();
1788 const auto& lDomains2n1 =
layout2n1_m->getHostLocalDomains();
1790 std::vector<MPI_Request> requests(0);
1795 for (
unsigned i = 0; i <
Dim; i++) {
1830 for (
unsigned i = 0; i <
Dim; i++) {
1835 for (
int i = 0; i < ranks; ++i) {
1836 auto domain2 = lDomains2[i];
1838 if (domain2.touches(none)) {
1839 auto intersection = domain2.intersect(none);
1841 if (ldom_g.
touches(intersection)) {
1842 intersection = intersection.intersect(ldom_g);
1849 if (domain2.touches(x)) {
1850 auto intersection = domain2.intersect(x);
1852 (2 * size[0] - intersection[0].last()), -1);
1855 domain2n1[0] = xdom;
1856 domain2n1[1] = intersection[1];
1857 domain2n1[2] = intersection[2];
1859 if (ldom_g.
touches(domain2n1)) {
1860 intersection = ldom_g.
intersect(domain2n1);
1867 if (domain2.touches(y)) {
1868 auto intersection = domain2.intersect(y);
1870 (2 * size[1] - intersection[1].last()), -1);
1873 domain2n1[0] = intersection[0];
1874 domain2n1[1] = ydom;
1875 domain2n1[2] = intersection[2];
1877 if (ldom_g.
touches(domain2n1)) {
1878 intersection = ldom_g.
intersect(domain2n1);
1885 if (domain2.touches(z)) {
1886 auto intersection = domain2.intersect(z);
1888 (2 * size[2] - intersection[2].last()), -1);
1891 domain2n1[0] = intersection[0];
1892 domain2n1[1] = intersection[1];
1893 domain2n1[2] = zdom;
1895 if (ldom_g.
touches(domain2n1)) {
1896 intersection = ldom_g.
intersect(domain2n1);
1903 if (domain2.touches(xy)) {
1904 auto intersection = domain2.intersect(xy);
1906 (2 * size[0] - intersection[0].last()), -1);
1908 (2 * size[1] - intersection[1].last()), -1);
1911 domain2n1[0] = xdom;
1912 domain2n1[1] = ydom;
1913 domain2n1[2] = intersection[2];
1915 if (ldom_g.
touches(domain2n1)) {
1916 intersection = ldom_g.
intersect(domain2n1);
1923 if (domain2.touches(yz)) {
1924 auto intersection = domain2.intersect(yz);
1926 (2 * size[1] - intersection[1].last()), -1);
1928 (2 * size[2] - intersection[2].last()), -1);
1931 domain2n1[0] = intersection[0];
1932 domain2n1[1] = ydom;
1933 domain2n1[2] = zdom;
1935 if (ldom_g.
touches(domain2n1)) {
1936 intersection = ldom_g.
intersect(domain2n1);
1943 if (domain2.touches(xz)) {
1944 auto intersection = domain2.intersect(xz);
1946 (2 * size[0] - intersection[0].last()), -1);
1948 (2 * size[2] - intersection[2].last()), -1);
1951 domain2n1[0] = xdom;
1952 domain2n1[1] = intersection[1];
1953 domain2n1[2] = zdom;
1955 if (ldom_g.
touches(domain2n1)) {
1956 intersection = ldom_g.
intersect(domain2n1);
1963 if (domain2.touches(xyz)) {
1964 auto intersection = domain2.intersect(xyz);
1966 (2 * size[0] - intersection[0].last()), -1);
1968 (2 * size[1] - intersection[1].last()), -1);
1970 (2 * size[2] - intersection[2].last()), -1);
1973 domain2n1[0] = xdom;
1974 domain2n1[1] = ydom;
1975 domain2n1[2] = zdom;
1977 if (ldom_g.
touches(domain2n1)) {
1978 intersection = ldom_g.
intersect(domain2n1);
1987 for (
int i = 0; i < ranks; ++i) {
1989 auto intersection = ldom.
intersect(none);
1991 if (lDomains2n1[i].touches(intersection)) {
1992 intersection = intersection.intersect(lDomains2n1[i]);
2003 (2 * size[0] - intersection[0].last()), -1);
2006 domain2n1[0] = xdom;
2007 domain2n1[1] = intersection[1];
2008 domain2n1[2] = intersection[2];
2010 if (lDomains2n1[i].touches(domain2n1)) {
2011 domain2n1 = lDomains2n1[i].
intersect(domain2n1);
2013 2 * size[0] - domain2n1[0].last(), -1);
2015 intersection = intersection.intersect(domain2n1);
2018 true,
false,
false);
2026 (2 * size[1] - intersection[1].last()), -1);
2029 domain2n1[0] = intersection[0];
2030 domain2n1[1] = ydom;
2031 domain2n1[2] = intersection[2];
2033 if (lDomains2n1[i].touches(domain2n1)) {
2034 domain2n1 = lDomains2n1[i].
intersect(domain2n1);
2036 2 * size[1] - domain2n1[1].last(), -1);
2038 intersection = intersection.intersect(domain2n1);
2041 false,
true,
false);
2049 (2 * size[2] - intersection[2].last()), -1);
2052 domain2n1[0] = intersection[0];
2053 domain2n1[1] = intersection[1];
2054 domain2n1[2] = zdom;
2056 if (lDomains2n1[i].touches(domain2n1)) {
2057 domain2n1 = lDomains2n1[i].
intersect(domain2n1);
2059 2 * size[2] - domain2n1[2].last(), -1);
2061 intersection = intersection.intersect(domain2n1);
2064 false,
false,
true);
2072 (2 * size[0] - intersection[0].last()), -1);
2074 (2 * size[1] - intersection[1].last()), -1);
2077 domain2n1[0] = xdom;
2078 domain2n1[1] = ydom;
2079 domain2n1[2] = intersection[2];
2081 if (lDomains2n1[i].touches(domain2n1)) {
2082 domain2n1 = lDomains2n1[i].
intersect(domain2n1);
2084 2 * size[0] - domain2n1[0].last(), -1);
2086 2 * size[1] - domain2n1[1].last(), -1);
2088 intersection = intersection.intersect(domain2n1);
2099 (2 * size[1] - intersection[1].last()), -1);
2101 (2 * size[2] - intersection[2].last()), -1);
2104 domain2n1[0] = intersection[0];
2105 domain2n1[1] = ydom;
2106 domain2n1[2] = zdom;
2108 if (lDomains2n1[i].touches(domain2n1)) {
2109 domain2n1 = lDomains2n1[i].
intersect(domain2n1);
2111 2 * size[1] - domain2n1[1].last(), -1);
2113 2 * size[2] - domain2n1[2].last(), -1);
2115 intersection = intersection.intersect(domain2n1);
2126 (2 * size[0] - intersection[0].last()), -1);
2128 (2 * size[2] - intersection[2].last()), -1);
2131 domain2n1[0] = xdom;
2132 domain2n1[1] = intersection[1];
2133 domain2n1[2] = zdom;
2135 if (lDomains2n1[i].touches(domain2n1)) {
2136 domain2n1 = lDomains2n1[i].
intersect(domain2n1);
2138 2 * size[0] - domain2n1[0].last(), -1);
2140 2 * size[2] - domain2n1[2].last(), -1);
2142 intersection = intersection.intersect(domain2n1);
2150 auto intersection = ldom.
intersect(xyz);
2153 (2 * size[0] - intersection[0].last()), -1);
2155 (2 * size[1] - intersection[1].last()), -1);
2157 (2 * size[2] - intersection[2].last()), -1);
2160 domain2n1[0] = xdom;
2161 domain2n1[1] = ydom;
2162 domain2n1[2] = zdom;
2164 if (lDomains2n1[i].touches(domain2n1)) {
2165 domain2n1 = lDomains2n1[i].
intersect(domain2n1);
2167 2 * size[0] - domain2n1[0].last(), -1);
2169 2 * size[1] - domain2n1[1].last(), -1);
2171 2 * size[2] - domain2n1[2].last(), -1);
2173 intersection = intersection.intersect(domain2n1);
2181 if (requests.size() > 0) {
2182 MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);