1194 auto ldom =
layout_m.getLocalNDIndex();
1195 auto doms =
layout_m.getHostLocalDomains();
1199 std::vector<size_t> neighbors;
1200 std::vector< Kokkos::View<size_t*> > sendIdxs;
1201 std::vector< Kokkos::View<size_t*> > recvIdxs;
1202 std::vector< std::vector<size_t> > sendIdxsTemp;
1203 std::vector< std::vector<size_t> > recvIdxsTemp;
1207 size_t myRank =
Comm->rank();
1208 for (
size_t i = 0; i < doms.extent(0); ++i) {
1213 auto odom = doms(i);
1216 if (ldom.
last()[0] == odom.first()[0]-1 &&
1217 !(odom.last()[1] < ldom.
first()[1] || odom.first()[1] > ldom.
last()[1])) {
1219 int begin = std::max(odom.first()[1], ldom.
first()[1]);
1220 int end = std::min(odom.last()[1], ldom.
last()[1]);
1221 int pos = ldom.
last()[0];
1224 neighbors.push_back(i);
1225 sendIdxsTemp.push_back(std::vector<size_t>());
1226 recvIdxsTemp.push_back(std::vector<size_t>());
1227 size_t idx = neighbors.size() - 1;
1231 elementPosHalo(0) = pos;
1233 elementPosSend(0) = pos;
1234 for (
int k = begin; k <= end; ++k) {
1235 elementPosHalo(1) = k;
1236 elementPosSend(1) = k;
1239 recvIdxsTemp[idx].push_back(dofIndicesHalo[3]);
1242 sendIdxsTemp[idx].push_back(dofIndicesSend[0]);
1243 sendIdxsTemp[idx].push_back(dofIndicesSend[1]);
1246 if (end ==
layout_m.getDomain().last()[1] || ldom.
last()[1] > odom.last()[1]) {
1247 elementPosSend(1) = end;
1250 sendIdxsTemp[idx].push_back(dofIndicesSend[2]);
1255 if (ldom.
first()[0] == odom.last()[0]+1 &&
1256 !(odom.last()[1] < ldom.
first()[1] || odom.first()[1] > ldom.
last()[1])) {
1258 int begin = std::max(odom.first()[1], ldom.
first()[1]);
1259 int end = std::min(odom.last()[1], ldom.
last()[1]);
1260 int pos = ldom.
first()[0];
1263 neighbors.push_back(i);
1264 sendIdxsTemp.push_back(std::vector<size_t>());
1265 recvIdxsTemp.push_back(std::vector<size_t>());
1266 size_t idx = neighbors.size() - 1;
1270 elementPosHalo(0) = pos-1;
1272 elementPosSend(0) = pos;
1273 for (
int k = begin; k <= end; ++k) {
1274 elementPosHalo(1) = k;
1275 elementPosSend(1) = k;
1278 recvIdxsTemp[idx].push_back(dofIndicesHalo[0]);
1279 recvIdxsTemp[idx].push_back(dofIndicesHalo[1]);
1282 sendIdxsTemp[idx].push_back(dofIndicesSend[1]);
1285 if (end ==
layout_m.getDomain().last()[1] || odom.last()[1] > ldom.
last()[1]) {
1286 elementPosHalo(1) = end;
1289 recvIdxsTemp[idx].push_back(dofIndicesHalo[2]);
1294 if (ldom.
last()[1] == odom.first()[1]-1 &&
1295 !(odom.last()[0] < ldom.
first()[0] || odom.first()[0] > ldom.
last()[0])) {
1297 int begin = std::max(odom.first()[0], ldom.
first()[0]);
1298 int end = std::min(odom.last()[0], ldom.
last()[0]);
1299 int pos = ldom.
last()[1];
1302 neighbors.push_back(i);
1303 sendIdxsTemp.push_back(std::vector<size_t>());
1304 recvIdxsTemp.push_back(std::vector<size_t>());
1305 size_t idx = neighbors.size() - 1;
1309 elementPosHalo(1) = pos;
1311 elementPosSend(1) = pos;
1312 for (
int k = begin; k <= end; ++k) {
1313 elementPosHalo(0) = k;
1314 elementPosSend(0) = k;
1317 recvIdxsTemp[idx].push_back(dofIndicesHalo[2]);
1320 sendIdxsTemp[idx].push_back(dofIndicesSend[0]);
1321 sendIdxsTemp[idx].push_back(dofIndicesSend[1]);
1324 if (end ==
layout_m.getDomain().last()[0] || ldom.
last()[0] > odom.last()[0]) {
1325 elementPosSend(0) = end;
1328 sendIdxsTemp[idx].push_back(dofIndicesSend[3]);
1333 if (ldom.
first()[1] == odom.last()[1]+1 &&
1334 !(odom.last()[0] < ldom.
first()[0] || odom.first()[0] > ldom.
last()[0])) {
1336 int begin = std::max(odom.first()[0], ldom.
first()[0]);
1337 int end = std::min(odom.last()[0], ldom.
last()[0]);
1338 int pos = ldom.
first()[1];
1341 neighbors.push_back(i);
1342 sendIdxsTemp.push_back(std::vector<size_t>());
1343 recvIdxsTemp.push_back(std::vector<size_t>());
1344 size_t idx = neighbors.size() - 1;
1348 elementPosHalo(1) = pos-1;
1350 elementPosSend(1) = pos;
1351 for (
int k = begin; k <= end; ++k) {
1352 elementPosHalo(0) = k;
1353 elementPosSend(0) = k;
1356 recvIdxsTemp[idx].push_back(dofIndicesHalo[0]);
1357 recvIdxsTemp[idx].push_back(dofIndicesHalo[1]);
1360 sendIdxsTemp[idx].push_back(dofIndicesSend[0]);
1363 if (end ==
layout_m.getDomain().last()[0] || odom.last()[0] > ldom.
last()[0]) {
1364 elementPosHalo(0) = end;
1367 recvIdxsTemp[idx].push_back(dofIndicesHalo[3]);
1377 for (
size_t i = 0; i < neighbors.size(); ++i) {
1378 sendIdxs.push_back(Kokkos::View<size_t*>(
"FEMvector::sendIdxs[" + std::to_string(i) +
1379 "]", sendIdxsTemp[i].size()));
1380 recvIdxs.push_back(Kokkos::View<size_t*>(
"FEMvector::recvIdxs[" + std::to_string(i) +
1381 "]", recvIdxsTemp[i].size()));
1382 auto sendView = sendIdxs[i];
1383 auto recvView = recvIdxs[i];
1384 auto hSendView = Kokkos::create_mirror_view(sendView);
1385 auto hRecvView = Kokkos::create_mirror_view(recvView);
1387 for (
size_t j = 0; j < sendIdxsTemp[i].size(); ++j) {
1388 hSendView(j) = sendIdxsTemp[i][j];
1391 for (
size_t j = 0; j < recvIdxsTemp[i].size(); ++j) {
1392 hRecvView(j) = recvIdxsTemp[i][j];
1395 Kokkos::deep_copy(sendView, hSendView);
1396 Kokkos::deep_copy(recvView, hRecvView);
1403 extents = (ldom.
last() - ldom.
first()) + 3;
1404 size_t nx = extents(0);
1405 size_t ny = extents(1);
1406 size_t n = nx*(ny-1) + ny*(nx-1);
1453 auto ldom =
layout_m.getLocalNDIndex();
1454 auto doms =
layout_m.getHostLocalDomains();
1458 std::vector<size_t> neighbors;
1459 std::vector< Kokkos::View<size_t*> > sendIdxs;
1460 std::vector< Kokkos::View<size_t*> > recvIdxs;
1461 std::vector< std::vector<size_t> > sendIdxsTemp;
1462 std::vector< std::vector<size_t> > recvIdxsTemp;
1489 auto flatBoundaryExchange = [
this, &neighbors, &ldom](
1490 size_t i,
size_t a,
size_t f,
size_t s,
1491 std::vector<std::vector<size_t> >& va, std::vector<std::vector<size_t> >& vb,
1493 const std::vector<size_t>& idxsA,
const std::vector<size_t>& idxsB,
1496 int beginF = std::max(bdom.first()[f], adom.first()[f]);
1497 int endF = std::min(bdom.last()[f], adom.last()[f]);
1498 int beginS = std::max(bdom.first()[s], adom.first()[s]);
1499 int endS = std::min(bdom.last()[s], adom.last()[s]);
1501 neighbors.push_back(i);
1502 va.push_back(std::vector<size_t>());
1503 vb.push_back(std::vector<size_t>());
1504 size_t idx = neighbors.size() - 1;
1508 elementPosA(a) = posA;
1510 elementPosB(a) = posB;
1514 for (
int k = beginF; k <= endF; ++k) {
1517 for (
int l = beginS; l <= endS; ++l) {
1522 va[idx].push_back(dofIndicesA[idxsA[0]]);
1523 va[idx].push_back(dofIndicesA[idxsA[1]]);
1526 vb[idx].push_back(dofIndicesB[idxsB[0]]);
1527 vb[idx].push_back(dofIndicesB[idxsB[1]]);
1528 vb[idx].push_back(dofIndicesB[idxsB[2]]);
1537 if (endF ==
layout_m.getDomain().last()[f] ||
1538 bdom.last()[f] > adom.last()[f]) {
1539 va[idx].push_back(dofIndicesA[idxsA[2]]);
1542 if (endF ==
layout_m.getDomain().last()[f] ||
1543 adom.last()[f] > bdom.last()[f]) {
1544 vb[idx].push_back(dofIndicesB[idxsB[3]]);
1545 vb[idx].push_back(dofIndicesB[idxsB[4]]);
1552 if (bdom.first()[f] < adom.first()[f]) {
1554 tmpPos(f) = beginF-1;
1556 va[idx].push_back(dofIndicestmp[idxsA[0]]);
1557 va[idx].push_back(dofIndicestmp[idxsA[1]]);
1568 if (endS ==
layout_m.getDomain().last()[s] || bdom.last()[s] > adom.last()[s]) {
1569 elementPosA(s) = endS;
1571 va[idx].push_back(dofIndicesA[idxsA[3]]);
1574 if (endS ==
layout_m.getDomain().last()[s] || adom.last()[s] > bdom.last()[s]) {
1575 elementPosB(s) = endS;
1577 vb[idx].push_back(dofIndicesB[idxsB[5]]);
1578 vb[idx].push_back(dofIndicesB[idxsB[6]]);
1585 if (bdom.first()[f] < adom.first()[f]) {
1587 tmpPos(s) = beginS-1;
1589 va[idx].push_back(dofIndicestmp[idxsA[0]]);
1590 va[idx].push_back(dofIndicestmp[idxsA[1]]);
1595 if ((endF ==
layout_m.getDomain().last()[f] || adom.last()[f] > bdom.last()[f]) &&
1596 (endS ==
layout_m.getDomain().last()[s] || adom.last()[s] > bdom.last()[s])) {
1597 elementPosB(f) = endF;
1598 elementPosB(s) = endS;
1600 vb[idx].push_back(dofIndicesB[idxsB[7]]);
1623 auto negativeDiagonalExchange = [
this, &neighbors, &ldom](
1624 size_t i,
size_t a,
size_t f,
size_t s,
int ao,
int bo,
1625 std::vector<std::vector<size_t> >& va, std::vector<std::vector<size_t> >& vb,
1626 const std::vector<size_t>& idxsA,
const std::vector<size_t>& idxsB,
1629 neighbors.push_back(i);
1630 va.push_back(std::vector<size_t>());
1631 vb.push_back(std::vector<size_t>());
1632 size_t idx = neighbors.size() - 1;
1635 elementPosA(f) = ldom.
last()[f];
1636 elementPosA(s) = ldom.
first()[s] + ao;
1639 elementPosB(f) = ldom.
last()[f];
1640 elementPosB(s) = ldom.
first()[s] + bo;
1642 int begin = std::max(odom.first()[a], ldom.
first()[a]);
1643 int end = std::min(odom.last()[a], ldom.
last()[a]);
1645 for (
int k = begin; k <= end; ++k) {
1650 va[idx].push_back(dofIndicesA[idxsA[0]]);
1651 va[idx].push_back(dofIndicesA[idxsA[1]]);
1654 vb[idx].push_back(dofIndicesB[idxsB[0]]);
1655 vb[idx].push_back(dofIndicesB[idxsB[1]]);
1677 auto positiveDiagonalExchange = [
this, &neighbors, &ldom](
1678 size_t i,
size_t a,
size_t f,
size_t s,
1680 std::vector<std::vector<size_t> >& va, std::vector<std::vector<size_t> >& vb,
1681 const std::vector<size_t>& idxsA,
const std::vector<size_t>& idxsB,
1684 neighbors.push_back(i);
1685 va.push_back(std::vector<size_t>());
1686 vb.push_back(std::vector<size_t>());
1687 size_t idx = neighbors.size() - 1;
1690 elementPosA(f) = posA(f);
1691 elementPosA(s) = posA(s);
1694 elementPosB(f) = posB(f);
1695 elementPosB(s) = posB(s);
1697 int begin = std::max(odom.first()[a], ldom.
first()[a]);
1698 int end = std::min(odom.last()[a], ldom.
last()[a]);
1700 for (
int k = begin; k <= end; ++k) {
1705 va[idx].push_back(dofIndicesA[idxsA[0]]);
1706 va[idx].push_back(dofIndicesA[idxsA[1]]);
1707 va[idx].push_back(dofIndicesA[idxsA[2]]);
1710 vb[idx].push_back(dofIndicesB[idxsB[0]]);
1721 size_t myRank =
Comm->rank();
1722 for (
size_t i = 0; i < doms.extent(0); ++i) {
1727 auto odom = doms(i);
1730 if (ldom.
last()[0] == odom.first()[0]-1 &&
1731 !(odom.last()[1] < ldom.
first()[1] || odom.first()[1] > ldom.
last()[1]) &&
1732 !(odom.last()[2] < ldom.
first()[2] || odom.first()[2] > ldom.
last()[2])) {
1734 int pos = ldom.
last()[0];
1735 flatBoundaryExchange(
1737 recvIdxsTemp, sendIdxsTemp,
1739 {3,5,6,11}, {0,1,4,2,7,8,9,10},
1745 if (ldom.
first()[0] == odom.last()[0]+1 &&
1746 !(odom.last()[1] < ldom.
first()[1] || odom.first()[1] > ldom.
last()[1]) &&
1747 !(odom.last()[2] < ldom.
first()[2] || odom.first()[2] > ldom.
last()[2])) {
1749 int pos = ldom.
first()[0];
1750 flatBoundaryExchange(
1752 sendIdxsTemp, recvIdxsTemp,
1754 {1,4,7,9}, {0,1,4,2,7,8,9,10},
1760 if (ldom.
last()[1] == odom.first()[1]-1 &&
1761 !(odom.last()[0] < ldom.
first()[0] || odom.first()[0] > ldom.
last()[0]) &&
1762 !(odom.last()[2] < ldom.
first()[2] || odom.first()[2] > ldom.
last()[2])) {
1764 int pos = ldom.
last()[1];
1765 flatBoundaryExchange(
1767 recvIdxsTemp, sendIdxsTemp,
1769 {2,7,6,10}, {0,1,4,3,5,8,9,11},
1775 if (ldom.
first()[1] == odom.last()[1]+1 &&
1776 !(odom.last()[0] < ldom.
first()[0] || odom.first()[0] > ldom.
last()[0]) &&
1777 !(odom.last()[2] < ldom.
first()[2] || odom.first()[2] > ldom.
last()[2])) {
1779 int pos = ldom.
first()[1];
1780 flatBoundaryExchange(
1782 sendIdxsTemp, recvIdxsTemp,
1784 {0,4,5,8}, {0,1,4,3,5,8,9,11},
1791 if (ldom.
last()[2] == odom.first()[2]-1 &&
1792 !(odom.last()[0] < ldom.
first()[0] || odom.first()[0] > ldom.
last()[0]) &&
1793 !(odom.last()[1] < ldom.
first()[1] || odom.first()[1] > ldom.
last()[1])) {
1795 int pos = ldom.
last()[2];
1796 flatBoundaryExchange(
1798 recvIdxsTemp, sendIdxsTemp,
1800 {8,9,11,10}, {0,1,4,3,5,2,7,6},
1806 if (ldom.
first()[2] == odom.last()[2]+1 &&
1807 !(odom.last()[0] < ldom.
first()[0] || odom.first()[0] > ldom.
last()[0]) &&
1808 !(odom.last()[1] < ldom.
first()[1] || odom.first()[1] > ldom.
last()[1])) {
1810 int pos = ldom.
first()[2];
1811 flatBoundaryExchange(
1813 sendIdxsTemp, recvIdxsTemp,
1815 {0,1,3,2}, {0,1,4,3,5,2,7,6},
1825 if (ldom.
last()[0] == odom.first()[0]-1 && ldom.
first()[2] == odom.last()[2]+1 &&
1826 !(odom.last()[1] < ldom.
first()[1] || odom.first()[1] > ldom.
last()[1])) {
1828 negativeDiagonalExchange(
1830 sendIdxsTemp, recvIdxsTemp,
1837 if (ldom.
first()[0] == odom.last()[0]+1 && ldom.
last()[2] == odom.first()[2]-1 &&
1838 !(odom.last()[1] < ldom.
first()[1] || odom.first()[1] > ldom.
last()[1])) {
1840 negativeDiagonalExchange(
1842 recvIdxsTemp, sendIdxsTemp,
1850 if (ldom.
last()[1] == odom.first()[1]-1 && ldom.
first()[2] == odom.last()[2]+1 &&
1851 !(odom.last()[0] < ldom.
first()[0] || odom.first()[0] > ldom.
last()[0])) {
1852 negativeDiagonalExchange(
1854 sendIdxsTemp, recvIdxsTemp,
1861 if (ldom.
first()[1] == odom.last()[1]+1 && ldom.
last()[2] == odom.first()[2]-1 &&
1862 !(odom.last()[0] < ldom.
first()[0] || odom.first()[0] > ldom.
last()[0])) {
1863 negativeDiagonalExchange(
1865 recvIdxsTemp, sendIdxsTemp,
1873 if (ldom.
last()[0] == odom.first()[0]-1 && ldom.
first()[1] == odom.last()[1]+1 &&
1874 !(odom.last()[2] < ldom.
first()[2] || odom.first()[2] > ldom.
last()[2])) {
1875 negativeDiagonalExchange(
1877 sendIdxsTemp, recvIdxsTemp,
1884 if (ldom.
first()[0] == odom.last()[0]+1 && ldom.
last()[1] == odom.first()[1]-1 &&
1885 !(odom.last()[2] < ldom.
first()[2] || odom.first()[2] > ldom.
last()[2])) {
1886 negativeDiagonalExchange(
1888 recvIdxsTemp, sendIdxsTemp,
1898 if (ldom.
last()[0] == odom.first()[0]-1 && ldom.
last()[2] == odom.first()[2]-1 &&
1899 !(odom.last()[1] < ldom.
first()[1] || odom.first()[1] > ldom.
last()[1])) {
1900 positiveDiagonalExchange(
1903 sendIdxsTemp, recvIdxsTemp,
1910 if (ldom.
first()[0] == odom.last()[0]+1 && ldom.
first()[2] == odom.last()[2]+1 &&
1911 !(odom.last()[1] < ldom.
first()[1] || odom.first()[1] > ldom.
last()[1])) {
1912 positiveDiagonalExchange(
1915 recvIdxsTemp, sendIdxsTemp,
1923 if (ldom.
last()[1] == odom.first()[1]-1 && ldom.
last()[2] == odom.first()[2]-1 &&
1924 !(odom.last()[0] < ldom.
first()[0] || odom.first()[0] > ldom.
last()[0])) {
1925 positiveDiagonalExchange(
1928 sendIdxsTemp, recvIdxsTemp,
1935 if (ldom.
first()[1] == odom.last()[1]+1 && ldom.
first()[2] == odom.last()[2]+1 &&
1936 !(odom.last()[0] < ldom.
first()[0] || odom.first()[0] > ldom.
last()[0])) {
1937 positiveDiagonalExchange(
1940 recvIdxsTemp, sendIdxsTemp,
1948 if (ldom.
last()[0] == odom.first()[0]-1 && ldom.
last()[1] == odom.first()[1]-1 &&
1949 !(odom.last()[2] < ldom.
first()[2] || odom.first()[2] > ldom.
last()[2])) {
1950 positiveDiagonalExchange(
1953 sendIdxsTemp, recvIdxsTemp,
1960 if (ldom.
first()[0] == odom.last()[0]+1 && ldom.
first()[1] == odom.last()[1]+1 &&
1961 !(odom.last()[2] < ldom.
first()[2] || odom.first()[2] > ldom.
last()[2])) {
1962 positiveDiagonalExchange(
1965 recvIdxsTemp, sendIdxsTemp,
1979 for (
size_t i = 0; i < neighbors.size(); ++i) {
1980 sendIdxs.push_back(Kokkos::View<size_t*>(
"FEMvector::sendIdxs[" + std::to_string(i) +
1981 "]", sendIdxsTemp[i].size()));
1982 recvIdxs.push_back(Kokkos::View<size_t*>(
"FEMvector::recvIdxs[" + std::to_string(i) +
1983 "]", recvIdxsTemp[i].size()));
1984 auto sendView = sendIdxs[i];
1985 auto recvView = recvIdxs[i];
1986 auto hSendView = Kokkos::create_mirror_view(sendView);
1987 auto hRecvView = Kokkos::create_mirror_view(recvView);
1989 for (
size_t j = 0; j < sendIdxsTemp[i].size(); ++j) {
1990 hSendView(j) = sendIdxsTemp[i][j];
1993 for (
size_t j = 0; j < recvIdxsTemp[i].size(); ++j) {
1994 hRecvView(j) = recvIdxsTemp[i][j];
1997 Kokkos::deep_copy(sendView, hSendView);
1998 Kokkos::deep_copy(recvView, hRecvView);
2005 extents = (ldom.
last() - ldom.
first()) + 3;
2006 size_t nx = extents(0);
2007 size_t ny = extents(1);
2008 size_t nz = extents(2);
2009 size_t n = (nz-1)*(nx*(ny-1) + ny*(nx-1) + nx*ny) + nx*(ny-1) + ny*(nx-1);