Skip to content
Snippets Groups Projects
IndexRearrangementForStreams.cpp 28.9 KiB
Newer Older
#include "IndexRearrangementForStreams.h"

#include "Communication/Communicator.h"
#include <GridGenerator/grid/Grid.h>
#include <GridGenerator/grid/GridBuilder/GridBuilder.h>

IndexRearrangementForStreams::IndexRearrangementForStreams(std::shared_ptr<Parameter> para,
                                                           std::shared_ptr<GridBuilder> builder,
                                                           vf::gpu::CommunicationRoutine &communicator)
    : para(para), builder(builder), communicator(communicator)
Anna Wellmann's avatar
Anna Wellmann committed
void IndexRearrangementForStreams::initCommunicationArraysForCommAfterFinetoCoarseX(uint level,
                                                                                    int indexOfProcessNeighbor,
Anna Wellmann's avatar
Anna Wellmann committed
                                                                                    int direction) const
{
    std::cout << "communication: reorder send indices X ";
    std::vector<uint> sendIndicesForCommAfterFtoCPositions =
        initSendIndicesForCommAfterFToCX(level, indexOfProcessNeighbor, direction);
Anna Wellmann's avatar
Anna Wellmann committed
    std::vector<uint> recvIndicesForCommAfterFtoCPositions = exchangeIndicesForCommAfterFtoCX(
Anna Wellmann's avatar
Anna Wellmann committed
        level, indexOfProcessNeighbor, sendIndicesForCommAfterFtoCPositions);

    std::cout << "reorder receive indices ";
    initRecvIndicesForCommAfterFToCX(level, indexOfProcessNeighbor, direction, recvIndicesForCommAfterFtoCPositions);

    copyProcessNeighborToCommAfterFtoCX(level, indexOfProcessNeighbor);
Anna Wellmann's avatar
Anna Wellmann committed
void IndexRearrangementForStreams::initCommunicationArraysForCommAfterFinetoCoarseY(uint level,
                                                                                    int indexOfProcessNeighbor,
Anna Wellmann's avatar
Anna Wellmann committed
                                                                                    int direction) const
{
    std::cout << "communication: reorder send indices Y ";
    std::vector<uint> sendIndicesForCommAfterFtoCPositions =
        initSendIndicesForCommAfterFToCY(level, indexOfProcessNeighbor, direction);
Anna Wellmann's avatar
Anna Wellmann committed
    std::vector<uint> recvIndicesForCommAfterFtoCPositions = exchangeIndicesForCommAfterFtoCY(
Anna Wellmann's avatar
Anna Wellmann committed
        level, indexOfProcessNeighbor, sendIndicesForCommAfterFtoCPositions);

    std::cout << "reorder receive indices ";
    initRecvIndicesForCommAfterFToCY(level, indexOfProcessNeighbor, direction, recvIndicesForCommAfterFtoCPositions);
    copyProcessNeighborToCommAfterFtoCY(level, indexOfProcessNeighbor);
Anna Wellmann's avatar
Anna Wellmann committed
void IndexRearrangementForStreams::initCommunicationArraysForCommAfterFinetoCoarseZ(uint level,
                                                                                    int indexOfProcessNeighbor,
Anna Wellmann's avatar
Anna Wellmann committed
                                                                                    int direction) const
{
    std::cout << "communication: reorder send indices Z ";
    std::vector<uint> sendIndicesForCommAfterFtoCPositions =
        initSendIndicesForCommAfterFToCZ(level, indexOfProcessNeighbor, direction);

    std::cout << "mpi send and receive ";
Anna Wellmann's avatar
Anna Wellmann committed
    std::vector<uint> recvIndicesForCommAfterFtoCPositions = exchangeIndicesForCommAfterFtoCZ(
Anna Wellmann's avatar
Anna Wellmann committed
        level, indexOfProcessNeighbor, sendIndicesForCommAfterFtoCPositions);

    std::cout << "reorder receive indices ";
    initRecvIndicesForCommAfterFToCZ(level, indexOfProcessNeighbor, direction, recvIndicesForCommAfterFtoCPositions);

    copyProcessNeighborToCommAfterFtoCZ(level, indexOfProcessNeighbor);

    std::cout << "done." << std::endl;
}

std::vector<uint> IndexRearrangementForStreams::initSendIndicesForCommAfterFToCX(uint level, int indexOfProcessNeighbor,
Anna Wellmann's avatar
Anna Wellmann committed
                                                                                 int direction) const 
{
    para->initProcessNeighborsAfterFtoCX(level);
    std::vector<uint> sendIndicesForCommAfterFtoCPositions;
    reorderSendIndicesForCommAfterFtoCX(direction, level, indexOfProcessNeighbor, sendIndicesForCommAfterFtoCPositions);
    para->setSendProcessNeighborsAfterFtoCX(
        para->getParH(level)->sendProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].numberOfNodes, level,
        indexOfProcessNeighbor);
    return sendIndicesForCommAfterFtoCPositions;
}

std::vector<uint> IndexRearrangementForStreams::initSendIndicesForCommAfterFToCY(uint level, int indexOfProcessNeighbor,
Anna Wellmann's avatar
Anna Wellmann committed
                                                                                 int direction) const 
{
    para->initProcessNeighborsAfterFtoCY(level);
    std::vector<uint> sendIndicesForCommAfterFtoCPositions;
    reorderSendIndicesForCommAfterFtoCY(direction, level, indexOfProcessNeighbor, sendIndicesForCommAfterFtoCPositions);
    para->setSendProcessNeighborsAfterFtoCY(
        para->getParH(level)->sendProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].numberOfNodes, level,
        indexOfProcessNeighbor);
    return sendIndicesForCommAfterFtoCPositions;
}

std::vector<uint> IndexRearrangementForStreams::initSendIndicesForCommAfterFToCZ(uint level, int indexOfProcessNeighbor,
Anna Wellmann's avatar
Anna Wellmann committed
                                                                                 int direction) const 
    para->initProcessNeighborsAfterFtoCZ(level);
    std::vector<uint> sendIndicesForCommAfterFtoCPositions;
    reorderSendIndicesForCommAfterFtoCZ(direction, level, indexOfProcessNeighbor, sendIndicesForCommAfterFtoCPositions);
    para->setSendProcessNeighborsAfterFtoCZ(
        para->getParH(level)->sendProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].numberOfNodes, level,
        indexOfProcessNeighbor);
    return sendIndicesForCommAfterFtoCPositions;
}
Anna Wellmann's avatar
Anna Wellmann committed
std::vector<uint> IndexRearrangementForStreams::exchangeIndicesForCommAfterFtoCX(
Anna Wellmann's avatar
Anna Wellmann committed
    uint level, int indexOfProcessNeighbor, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const
    // fill the receive vector with zeros as placeholders (0 is never a valid fluid node)
    // give vector an arbitrary size (larger than needed) // TODO: Find a better way
    std::vector<uint> recvIndicesForCommAfterFtoCPositions(
        (size_t)para->getParH(level)->sendProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].numberOfNodes * 2, 0);
    communicator.receive_send(
        recvIndicesForCommAfterFtoCPositions.data(), (int)recvIndicesForCommAfterFtoCPositions.size(),
        para->getParH(level)->recvProcessNeighborX[indexOfProcessNeighbor].rankNeighbor,
        sendIndicesForCommAfterFtoCPositions.data(), (int)sendIndicesForCommAfterFtoCPositions.size(),
        para->getParH(level)->sendProcessNeighborX[indexOfProcessNeighbor].rankNeighbor);

    // resize receiving vector to correct size (remove all zeros)
    auto it = std::find(recvIndicesForCommAfterFtoCPositions.begin(), recvIndicesForCommAfterFtoCPositions.end(), 0);
    recvIndicesForCommAfterFtoCPositions.erase(it, recvIndicesForCommAfterFtoCPositions.end());
    return recvIndicesForCommAfterFtoCPositions;
}

Anna Wellmann's avatar
Anna Wellmann committed
std::vector<uint> IndexRearrangementForStreams::exchangeIndicesForCommAfterFtoCY(
Anna Wellmann's avatar
Anna Wellmann committed
    uint level, int indexOfProcessNeighbor, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const
    // fill the receive vector with zeros as placeholders (0 is never a valid fluid node)
    // give vector an arbitrary size (larger than needed) // TODO: Find a better way
    std::vector<uint> recvIndicesForCommAfterFtoCPositions(
        (size_t)para->getParH(level)->sendProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].numberOfNodes * 2, 0);

    communicator.receive_send(
        recvIndicesForCommAfterFtoCPositions.data(), (int)recvIndicesForCommAfterFtoCPositions.size(),
        para->getParH(level)->recvProcessNeighborY[indexOfProcessNeighbor].rankNeighbor,
        sendIndicesForCommAfterFtoCPositions.data(), (int)sendIndicesForCommAfterFtoCPositions.size(),
        para->getParH(level)->sendProcessNeighborY[indexOfProcessNeighbor].rankNeighbor);

    // resize receiving vector to correct size (remove all zeros)
    auto it = std::find(recvIndicesForCommAfterFtoCPositions.begin(), recvIndicesForCommAfterFtoCPositions.end(), 0);
    recvIndicesForCommAfterFtoCPositions.erase(it, recvIndicesForCommAfterFtoCPositions.end());
    return recvIndicesForCommAfterFtoCPositions;
}

Anna Wellmann's avatar
Anna Wellmann committed
std::vector<uint> IndexRearrangementForStreams::exchangeIndicesForCommAfterFtoCZ(
Anna Wellmann's avatar
Anna Wellmann committed
    uint level, int indexOfProcessNeighbor, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const
    // fill the receive vector with zeros as placeholders (0 is never a valid fluid node)
    // give vector an arbitrary size (larger than needed) // TODO: Find a better way
    std::vector<uint> recvIndicesForCommAfterFtoCPositions(
        (size_t)para->getParH(level)->sendProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].numberOfNodes * 2, 0);

    communicator.receive_send(
        recvIndicesForCommAfterFtoCPositions.data(), (int)recvIndicesForCommAfterFtoCPositions.size(),
        para->getParH(level)->recvProcessNeighborZ[indexOfProcessNeighbor].rankNeighbor,
        sendIndicesForCommAfterFtoCPositions.data(), (int)sendIndicesForCommAfterFtoCPositions.size(),
        para->getParH(level)->sendProcessNeighborZ[indexOfProcessNeighbor].rankNeighbor);
    // resize receiving vector to correct size (remove all zeros)
    auto it = std::find(recvIndicesForCommAfterFtoCPositions.begin(), recvIndicesForCommAfterFtoCPositions.end(), 0);
    recvIndicesForCommAfterFtoCPositions.erase(it, recvIndicesForCommAfterFtoCPositions.end());
    return recvIndicesForCommAfterFtoCPositions;
}
void IndexRearrangementForStreams::initRecvIndicesForCommAfterFToCX(
Anna Wellmann's avatar
Anna Wellmann committed
    uint level, int indexOfProcessNeighbor, int direction, std::vector<uint> &recvIndicesForCommAfterFtoCPositions) const 
{
    reorderRecvIndicesForCommAfterFtoCX(direction, level, indexOfProcessNeighbor, recvIndicesForCommAfterFtoCPositions);
    para->setRecvProcessNeighborsAfterFtoCX(
        para->getParH(level)->recvProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].numberOfNodes, level,
        indexOfProcessNeighbor);
}

void IndexRearrangementForStreams::initRecvIndicesForCommAfterFToCY(
Anna Wellmann's avatar
Anna Wellmann committed
    uint level, int indexOfProcessNeighbor, int direction, std::vector<uint> &recvIndicesForCommAfterFtoCPositions) const 
{
    reorderRecvIndicesForCommAfterFtoCY(direction, level, indexOfProcessNeighbor, recvIndicesForCommAfterFtoCPositions);
    para->setRecvProcessNeighborsAfterFtoCY(
        para->getParH(level)->recvProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].numberOfNodes, level,
        indexOfProcessNeighbor);
}
void IndexRearrangementForStreams::initRecvIndicesForCommAfterFToCZ(
Anna Wellmann's avatar
Anna Wellmann committed
    uint level, int indexOfProcessNeighbor, int direction, std::vector<uint> &recvIndicesForCommAfterFtoCPositions) const 
    reorderRecvIndicesForCommAfterFtoCZ(direction, level, indexOfProcessNeighbor, recvIndicesForCommAfterFtoCPositions);
    para->setRecvProcessNeighborsAfterFtoCZ(
        para->getParH(level)->recvProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].numberOfNodes, level,
        indexOfProcessNeighbor);
Anna Wellmann's avatar
Anna Wellmann committed
void IndexRearrangementForStreams::copyProcessNeighborToCommAfterFtoCX(uint level, int indexOfProcessNeighbor) const 
    para->getParD(level)->sendProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].f[0] =
        para->getParD(level)->sendProcessNeighborX[indexOfProcessNeighbor].f[0];
    para->getParH(level)->sendProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].f[0] =
        para->getParH(level)->sendProcessNeighborX[indexOfProcessNeighbor].f[0];
    para->getParD(level)->recvProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].f[0] =
        para->getParD(level)->recvProcessNeighborX[indexOfProcessNeighbor].f[0];
    para->getParH(level)->recvProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].f[0] =
        para->getParH(level)->recvProcessNeighborX[indexOfProcessNeighbor].f[0];
    para->getParD(level)->sendProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].index =
        para->getParD(level)->sendProcessNeighborX[indexOfProcessNeighbor].index;
    para->getParH(level)->sendProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].index =
        para->getParH(level)->sendProcessNeighborX[indexOfProcessNeighbor].index;
    para->getParD(level)->recvProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].index =
        para->getParD(level)->recvProcessNeighborX[indexOfProcessNeighbor].index;
    para->getParH(level)->recvProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].index =
        para->getParH(level)->recvProcessNeighborX[indexOfProcessNeighbor].index;
    para->getParH(level)->sendProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].rankNeighbor =
        para->getParH(level)->sendProcessNeighborX[indexOfProcessNeighbor].rankNeighbor;
    para->getParH(level)->recvProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].rankNeighbor =
        para->getParH(level)->recvProcessNeighborX[indexOfProcessNeighbor].rankNeighbor;
Anna Wellmann's avatar
Anna Wellmann committed
void IndexRearrangementForStreams::copyProcessNeighborToCommAfterFtoCY(uint level, int indexOfProcessNeighbor) const 
    para->getParD(level)->sendProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].f[0] =
        para->getParD(level)->sendProcessNeighborY[indexOfProcessNeighbor].f[0];
    para->getParH(level)->sendProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].f[0] =
        para->getParH(level)->sendProcessNeighborY[indexOfProcessNeighbor].f[0];
    para->getParD(level)->recvProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].f[0] =
        para->getParD(level)->recvProcessNeighborY[indexOfProcessNeighbor].f[0];
    para->getParH(level)->recvProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].f[0] =
        para->getParH(level)->recvProcessNeighborY[indexOfProcessNeighbor].f[0];
    para->getParD(level)->sendProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].index =
        para->getParD(level)->sendProcessNeighborY[indexOfProcessNeighbor].index;
    para->getParH(level)->sendProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].index =
        para->getParH(level)->sendProcessNeighborY[indexOfProcessNeighbor].index;
    para->getParD(level)->recvProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].index =
        para->getParD(level)->recvProcessNeighborY[indexOfProcessNeighbor].index;
    para->getParH(level)->recvProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].index =
        para->getParH(level)->recvProcessNeighborY[indexOfProcessNeighbor].index;
    para->getParH(level)->sendProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].rankNeighbor =
        para->getParH(level)->sendProcessNeighborY[indexOfProcessNeighbor].rankNeighbor;
    para->getParH(level)->recvProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].rankNeighbor =
        para->getParH(level)->recvProcessNeighborY[indexOfProcessNeighbor].rankNeighbor;
Anna Wellmann's avatar
Anna Wellmann committed
void IndexRearrangementForStreams::copyProcessNeighborToCommAfterFtoCZ(uint level, int indexOfProcessNeighbor) const 
    para->getParD(level)->sendProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].f[0] =
        para->getParD(level)->sendProcessNeighborZ[indexOfProcessNeighbor].f[0];
    para->getParH(level)->sendProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].f[0] =
        para->getParH(level)->sendProcessNeighborZ[indexOfProcessNeighbor].f[0];
    para->getParD(level)->recvProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].f[0] =
        para->getParD(level)->recvProcessNeighborZ[indexOfProcessNeighbor].f[0];
    para->getParH(level)->recvProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].f[0] =
        para->getParH(level)->recvProcessNeighborZ[indexOfProcessNeighbor].f[0];
    para->getParD(level)->sendProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].index =
        para->getParD(level)->sendProcessNeighborZ[indexOfProcessNeighbor].index;
    para->getParH(level)->sendProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].index =
        para->getParH(level)->sendProcessNeighborZ[indexOfProcessNeighbor].index;
    para->getParD(level)->recvProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].index =
        para->getParD(level)->recvProcessNeighborZ[indexOfProcessNeighbor].index;
    para->getParH(level)->recvProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].index =
        para->getParH(level)->recvProcessNeighborZ[indexOfProcessNeighbor].index;
    para->getParH(level)->sendProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].rankNeighbor =
        para->getParH(level)->sendProcessNeighborZ[indexOfProcessNeighbor].rankNeighbor;
    para->getParH(level)->recvProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].rankNeighbor =
        para->getParH(level)->recvProcessNeighborZ[indexOfProcessNeighbor].rankNeighbor;
void IndexRearrangementForStreams::reorderSendIndicesForCommAfterFtoCX(
Anna Wellmann's avatar
Anna Wellmann committed
    int direction, int level, int indexOfProcessNeighbor, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const 
    int *sendIndices = para->getParH(level)->sendProcessNeighborX[indexOfProcessNeighbor].index;
    int &numberOfSendNodesAfterFtoC =
        para->getParH(level)->sendProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].numberOfNodes;
    reorderSendIndicesForCommAfterFtoC(sendIndices, numberOfSendNodesAfterFtoC, direction, level,
void IndexRearrangementForStreams::reorderSendIndicesForCommAfterFtoCY(
Anna Wellmann's avatar
Anna Wellmann committed
    int direction, int level, int indexOfProcessNeighbor, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const 
    int *sendIndices = para->getParH(level)->sendProcessNeighborY[indexOfProcessNeighbor].index;
    int &numberOfSendNodesAfterFtoC =
        para->getParH(level)->sendProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].numberOfNodes;
    reorderSendIndicesForCommAfterFtoC(sendIndices, numberOfSendNodesAfterFtoC, direction, level,
void IndexRearrangementForStreams::reorderSendIndicesForCommAfterFtoCZ(
Anna Wellmann's avatar
Anna Wellmann committed
    int direction, int level, int indexOfProcessNeighbor, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const 
    int *sendIndices = para->getParH(level)->sendProcessNeighborZ[indexOfProcessNeighbor].index;
    int &numberOfSendNodesAfterFtoC =
        para->getParH(level)->sendProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].numberOfNodes;
    reorderSendIndicesForCommAfterFtoC(sendIndices, numberOfSendNodesAfterFtoC, direction, level,
void IndexRearrangementForStreams::reorderSendIndicesForCommAfterFtoC(
    int *sendIndices, int &numberOfSendNodesAfterFtoC, int direction, int level,
Anna Wellmann's avatar
Anna Wellmann committed
    std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const 
{
    *logging::out << logging::Logger::INFO_INTERMEDIATE
                  << "reorder send indices for communication after fine to coarse: level: " << level
                  << " direction: " << direction;
    if (para->getParH(level)->intCF.kCF == 0 || para->getParH(level)->intFC.kFC == 0)
        *logging::out << logging::Logger::LOGGER_ERROR
                      << "reorderSendIndicesForCommAfterFtoC(): para->getParH(level)->intCF needs to be initialized before calling "
                         "this function "
                      << "\n";

    int sparseIndexSend;
    std::vector<int> sendIndicesAfterFtoC;
    std::vector<int> sendIndicesOther;
    uint numberOfSendIndices = builder->getNumberOfSendIndices(direction, level);

    for (uint posInSendIndices = 0; posInSendIndices < numberOfSendIndices; posInSendIndices++) {
        sparseIndexSend = sendIndices[posInSendIndices];
        if (isSparseIndexInICellFCC(para->getParH(level)->intFC.kFC, sparseIndexSend, level)) {
            addUniqueIndexToCommunicationVectors(sendIndicesAfterFtoC, sparseIndexSend,
                                                 sendIndicesForCommAfterFtoCPositions, posInSendIndices);
    }

    // iCellCFC
    std::vector<uint> nodesCFC;
    aggregateNodesInICellCFC(level, nodesCFC);
    for (auto sparseIndex : nodesCFC)
        findIfSparseIndexIsInSendIndicesAndAddToCommVectors(sparseIndex, sendIndices, numberOfSendIndices,
                                                            sendIndicesAfterFtoC, sendIndicesForCommAfterFtoCPositions);

    numberOfSendNodesAfterFtoC = (int)sendIndicesAfterFtoC.size();

    findIndicesNotInCommAfterFtoC(numberOfSendIndices, sendIndices, sendIndicesAfterFtoC, sendIndicesOther);

    // copy new vectors back to sendIndices array
    for (int i = 0; i < numberOfSendNodesAfterFtoC; i++)
        sendIndices[i] = sendIndicesAfterFtoC[i];
    for (uint i = 0; i < (uint)sendIndicesOther.size(); i++)
        sendIndices[i + numberOfSendNodesAfterFtoC] = sendIndicesOther[i];
    *logging::out << logging::Logger::INFO_INTERMEDIATE << "... Process "
                  << " numberOfSendNodesAfterFtoC: " << numberOfSendNodesAfterFtoC << "\n ";
    if (numberOfSendNodesAfterFtoC + sendIndicesOther.size() != numberOfSendIndices) {
        *logging::out << logging::Logger::LOGGER_ERROR
                      << "reorderSendIndicesForCommAfterFtoC(): incorrect number of nodes"
                      << "\n";
        std::cout << "numberOfSendNodesAfterFtoC = " << numberOfSendNodesAfterFtoC
                  << ", sendOrIndicesOther.size() = " << sendIndicesOther.size()
                  << ", numberOfSendOrRecvIndices = " << numberOfSendIndices << std::endl;
    }
}

Anna Wellmann's avatar
Anna Wellmann committed
bool IndexRearrangementForStreams::isSparseIndexInICellFCC(uint sizeOfICellFCC, int sparseIndex, int level) const 
{
    for (uint j = 0; j < sizeOfICellFCC; j++) {
        if (sparseIndex < 0)
            return false;
        if (para->getParH(level)->intFC.ICellFCC[j] == (uint)sparseIndex) {
            return true;
        }
    }
    return false;
}

Anna Wellmann's avatar
Anna Wellmann committed
void IndexRearrangementForStreams::aggregateNodesInICellCFC(int level, std::vector<uint> &nodesCFC) const 
    uint *neighborX = para->getParH(level)->neighborX;
    uint *neighborY = para->getParH(level)->neighborY;
    uint *neighborZ = para->getParH(level)->neighborZ;

    for (uint x = 0; x < para->getParH(level)->intCF.kCF; x++) {
        sparseIndex = para->getParH(level)->intCF.ICellCFC[x];
        nodesCFC.push_back(sparseIndex);
        nodesCFC.push_back(neighborX[sparseIndex]);
        nodesCFC.push_back(neighborY[sparseIndex]);
        nodesCFC.push_back(neighborZ[sparseIndex]);
        nodesCFC.push_back(neighborY[neighborX[sparseIndex]]);
        nodesCFC.push_back(neighborZ[neighborX[sparseIndex]]);
        nodesCFC.push_back(neighborZ[neighborY[sparseIndex]]);
        nodesCFC.push_back(neighborZ[neighborY[neighborX[sparseIndex]]]);
    std::sort(nodesCFC.begin(), nodesCFC.end());
    auto iterator = std::unique(nodesCFC.begin(), nodesCFC.end());
    nodesCFC.erase(iterator, nodesCFC.end());
}

void IndexRearrangementForStreams::addUniqueIndexToCommunicationVectors(
    std::vector<int> &sendIndicesAfterFtoC, int &sparseIndexSend,
    std::vector<unsigned int> &sendIndicesForCommAfterFtoCPositions, uint &posInSendIndices) const
{
    // add index to corresponding vectors, but omit indices which are already in sendIndicesAfterFtoC
    if (std::find(sendIndicesAfterFtoC.begin(), sendIndicesAfterFtoC.end(), sparseIndexSend) ==
        sendIndicesAfterFtoC.end()) {
        sendIndicesAfterFtoC.push_back(sparseIndexSend);
        sendIndicesForCommAfterFtoCPositions.push_back(posInSendIndices);
    }
}

void IndexRearrangementForStreams::findIfSparseIndexIsInSendIndicesAndAddToCommVectors(
    int sparseIndex, int *sendIndices, uint numberOfSendIndices, std::vector<int> &sendIndicesAfterFtoC,
    std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const
{
    int sparseIndexSend;
    for (uint posInSendIndices = 0; posInSendIndices < numberOfSendIndices; posInSendIndices++) {
        sparseIndexSend = sendIndices[posInSendIndices];
        if (sparseIndex == sparseIndexSend) {
            addUniqueIndexToCommunicationVectors(sendIndicesAfterFtoC, sparseIndex,
                                                 sendIndicesForCommAfterFtoCPositions, posInSendIndices);
            break;
        }
    }
}

void IndexRearrangementForStreams::findIndicesNotInCommAfterFtoC(const uint &numberOfSendOrRecvIndices,
                                                                 int *sendOrReceiveIndices,
                                                                 std::vector<int> &sendOrReceiveIndicesAfterFtoC,
Anna Wellmann's avatar
Anna Wellmann committed
                                                                 std::vector<int> &sendOrIndicesOther) const 
{
    int sparseIndexSend;
    for (uint posInSendIndices = 0; posInSendIndices < numberOfSendOrRecvIndices; posInSendIndices++) {
        sparseIndexSend = sendOrReceiveIndices[posInSendIndices];
        if (std::find(sendOrReceiveIndicesAfterFtoC.begin(), sendOrReceiveIndicesAfterFtoC.end(), sparseIndexSend) ==
            sendOrReceiveIndicesAfterFtoC.end())
            sendOrIndicesOther.push_back(sparseIndexSend);
    }
}

void IndexRearrangementForStreams::reorderRecvIndicesForCommAfterFtoCX(
Anna Wellmann's avatar
Anna Wellmann committed
    int direction, int level, int indexOfProcessNeighbor, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const 
    int *recvIndices                    = para->getParH(level)->recvProcessNeighborX[indexOfProcessNeighbor].index;
    int &numberOfRecvNodesAfterFtoC = para->getParH(level)->recvProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].numberOfNodes;
    reorderRecvIndicesForCommAfterFtoC(recvIndices, numberOfRecvNodesAfterFtoC, direction, level,
void IndexRearrangementForStreams::reorderRecvIndicesForCommAfterFtoCY(
Anna Wellmann's avatar
Anna Wellmann committed
    int direction, int level, int indexOfProcessNeighbor, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const 
    int *recvIndices                    = para->getParH(level)->recvProcessNeighborY[indexOfProcessNeighbor].index;
    int &numberOfRecvNodesAfterFtoC = para->getParH(level)->recvProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].numberOfNodes;
    reorderRecvIndicesForCommAfterFtoC(recvIndices, numberOfRecvNodesAfterFtoC, direction, level,
void IndexRearrangementForStreams::reorderRecvIndicesForCommAfterFtoCZ(
Anna Wellmann's avatar
Anna Wellmann committed
    int direction, int level, int indexOfProcessNeighbor, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const 
    int *recvIndices = para->getParH(level)->recvProcessNeighborZ[indexOfProcessNeighbor].index;
    int &numberOfRecvNodesAfterFtoC =
        para->getParH(level)->recvProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].numberOfNodes;
    reorderRecvIndicesForCommAfterFtoC(recvIndices, numberOfRecvNodesAfterFtoC, direction, level,
void IndexRearrangementForStreams::reorderRecvIndicesForCommAfterFtoC(
    int *recvIndices, int &numberOfRecvNodesAfterFtoC, int direction, int level,
Anna Wellmann's avatar
Anna Wellmann committed
    std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const 
{
    *logging::out << logging::Logger::INFO_INTERMEDIATE
                  << "reorder receive indices for communication after fine to coarse: level: " << level
                  << " direction: " << direction;

    std::cout << "\n n send indices: " << (uint)sendIndicesForCommAfterFtoCPositions.size() << std::endl;
    if (sendIndicesForCommAfterFtoCPositions.size() == 0)
        *logging::out << logging::Logger::INFO_HIGH
                      << "reorderRecvIndicesForCommAfterFtoC(): sendIndicesForCommAfterFtoCPositions is empty."
                      << "\n";

    uint numberOfRecvIndices = builder->getNumberOfReceiveIndices(direction, level);
    std::vector<int> recvIndicesAfterFtoC;
    std::vector<int> recvIndicesOther;

    // find recvIndices for Communication after fine to coarse
    for (uint vectorPos : sendIndicesForCommAfterFtoCPositions)
        recvIndicesAfterFtoC.push_back(recvIndices[vectorPos]);

    findIndicesNotInCommAfterFtoC(numberOfRecvIndices, recvIndices, recvIndicesAfterFtoC, recvIndicesOther);

    numberOfRecvNodesAfterFtoC = (int)recvIndicesAfterFtoC.size();
Anna Wellmann's avatar
Anna Wellmann committed
    // copy new vectors back to recvIndices array
    for (int i = 0; i < numberOfRecvNodesAfterFtoC; i++)
        recvIndices[i] = recvIndicesAfterFtoC[i];
    for (uint i = 0; i < (uint)recvIndicesOther.size(); i++)
        recvIndices[i + numberOfRecvNodesAfterFtoC] = recvIndicesOther[i];
    *logging::out << logging::Logger::INFO_INTERMEDIATE << "... Process "
                  << " numberOfRecvNodesAfterFtoC: " << numberOfRecvNodesAfterFtoC << "\n ";
    if (numberOfRecvNodesAfterFtoC + recvIndicesOther.size() != numberOfRecvIndices) {
        *logging::out << logging::Logger::LOGGER_ERROR
                      << "reorderRecvIndicesForCommAfterFtoC(): incorrect number of nodes"
                      << "\n";
        std::cout << "numberOfRecvNodesAfterFtoC = " << numberOfRecvNodesAfterFtoC
                  << ", recvIndicesOther.size() = " << recvIndicesOther.size()
                  << ", numberOfRecvIndices = " << numberOfRecvIndices << std::endl;
    }
}