VirtualFluids 0.2.0
Parallel CFD LBM Solver
Loading...
Searching...
No Matches
IndexRearrangementForStreams.cpp
Go to the documentation of this file.
1//=======================================================================================
2// ____ ____ __ ______ __________ __ __ __ __
3// \ \ | | | | | _ \ |___ ___| | | | | / \ | |
4// \ \ | | | | | |_) | | | | | | | / \ | |
5// \ \ | | | | | _ / | | | | | | / /\ \ | |
6// \ \ | | | | | | \ \ | | | \__/ | / ____ \ | |____
7// \ \ | | |__| |__| \__\ |__| \________/ /__/ \__\ |_______|
8// \ \ | | ________________________________________________________________
9// \ \ | | | ______________________________________________________________|
10// \ \| | | | __ __ __ __ ______ _______
11// \ | | |_____ | | | | | | | | | _ \ / _____)
12// \ | | _____| | | | | | | | | | | \ \ \_______
13// \ | | | | |_____ | \_/ | | | | |_/ / _____ |
14// \ _____| |__| |________| \_______/ |__| |______/ (_______/
15//
16// This file is part of VirtualFluids. VirtualFluids is free software: you can
17// redistribute it and/or modify it under the terms of the GNU General Public
18// License as published by the Free Software Foundation, either version 3 of
19// the License, or (at your option) any later version.
20//
21// VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
22// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24// for more details.
25//
26// SPDX-License-Identifier: GPL-3.0-or-later
27// SPDX-FileCopyrightText: Copyright © VirtualFluids Project contributors, see AUTHORS.md in root folder
28//
33//=======================================================================================
35
36#include <algorithm>
37#include <iostream>
38
39#include <logger/Logger.h>
40
43
45
47#include "Parameter/Parameter.h"
48#include "lbm/constants/D3Q27.h"
49
50namespace vf::gpu {
51
53{
54 return std::find(array, array + numberOfElements, index) != array + numberOfElements;
55}
56
57bool indexInVector(const std::vector<uint>& vector, uint index)
58{
59 return std::find(vector.begin(), vector.end(), index) != vector.end();
60}
61
63 std::shared_ptr<GridBuilder> builder,
64 vf::parallel::Communicator& communicator)
65 : para(std::move(para)), builder(std::move(builder)), communicator(communicator)
66{
67}
68
69std::array<ProcessNeighbor27, 4>
94
96 int direction, int level) const
97{
98 VF_LOG_INFO("Reorder send indices for communication after fine to coarse: level: {} direction: {}", level, direction);
99
100 const ICells& fineToCoarse = para->getParH(level)->fineToCoarse;
101 if (para->getParH(level)->coarseToFine.numberOfCells == 0 || fineToCoarse.numberOfCells == 0)
102 VF_LOG_CRITICAL("reorderSendIndicesForCommAfterFtoC(): para->getParH(level)->intCF needs to be initialized "
103 "before calling this function");
104
105 std::vector<uint> sendIndicesAfterFtoC, sendIndicesForCommAfterFtoCPositions;
106
107 const uint numberOfSendIndices = builder->getNumberOfSendIndices(direction, level);
108
109 const std::vector<uint> aggregatedCoarseNodesForCtoF = aggregateCoarseNodesForCtoF(level);
110
111 // coarse cells of interpolation fine to coarse (iCellFCC)
112 for (uint posInSendIndices = 0; posInSendIndices < numberOfSendIndices; posInSendIndices++) {
113 const uint sparseIndexSend = indices[posInSendIndices];
115 continue;
116 if (indexInArray(fineToCoarse.coarseCellIndices, fineToCoarse.numberOfCells, sparseIndexSend) ||
119 sendIndicesForCommAfterFtoCPositions.push_back(posInSendIndices);
120 }
121 }
122
123 const std::vector<uint> sendIndicesOther =
124 findIndicesNotInCommAfterFtoC(numberOfSendIndices, indices, sendIndicesAfterFtoC);
125
126 std::copy(sendIndicesAfterFtoC.begin(), sendIndicesAfterFtoC.end(), indices);
127 std::copy(sendIndicesOther.begin(), sendIndicesOther.end(), indices + sendIndicesAfterFtoC.size());
128
129 VF_LOG_INFO("Reorder send indices: process {}, numberOfSendNodesAfterFtoC {}", communicator.getProcessID(),
130 sendIndicesAfterFtoC.size());
131
132 if (sendIndicesAfterFtoC.size() + sendIndicesOther.size() != numberOfSendIndices) {
133 VF_LOG_CRITICAL("reorderSendIndicesForCommAfterFtoC(): incorrect number of nodes");
134 VF_LOG_CRITICAL("numberOfSendNodesAfterFtoC = {}, sendIndicesOther.size() = {}, numberOfSendIndices = {}",
135 sendIndicesAfterFtoC.size(), sendIndicesOther.size(), numberOfSendIndices);
136 }
137 return sendIndicesForCommAfterFtoCPositions;
138}
139
140std::vector<uint>
143 const std::vector<uint>& sendIndicesForCommAfterFtoCPositions) const
144{
145 // fill the receive vector with zeros as placeholders
146 // give vector an arbitrary size (larger than needed) // TODO: Find a better way
147 std::vector<uint> recvIndicesForCommAfterFtoCPositions((size_t)sendNeighbor.numberOfNodes * 2, 0);
148
150 recvNeighbor.rankNeighbor, sendIndicesForCommAfterFtoCPositions.data(),
151 (int)sendIndicesForCommAfterFtoCPositions.size(), sendNeighbor.rankNeighbor);
152
153 // resize receiving vector to correct size
155 auto it = std::unique(
157 recvIndicesForCommAfterFtoCPositions.end()); // finds the second zero when there are multiple zeros in a row
158 recvIndicesForCommAfterFtoCPositions.erase(std::prev(it, 1), // begin erasing at the first zero
159 recvIndicesForCommAfterFtoCPositions.end()); // TODO: Find a better way
160 }
161
163}
164
165
167 uint* indices, const int direction, const int level,
168 const std::vector<uint>& recvIndicesForCommAfterFtoCPositions) const
169{
170 VF_LOG_INFO("Reorder recv indices for communication after fine to coarse: level: {} direction: {}", level, direction);
171
173 VF_LOG_WARNING("ReorderRecvIndicesForCommAfterFtoC(): sendIndicesForCommAfterFtoCPositions is empty.");
174
175 const uint numberOfRecvIndices = builder->getNumberOfReceiveIndices(direction, level);
176
177 std::vector<uint> recvIndicesAfterFtoC;
179
180 // find recvIndices for Communication after fine to coarse
182 recvIndicesAfterFtoC.push_back(indices[vectorPos]);
183
184 const std::vector<uint> recvIndicesOther = findIndicesNotInCommAfterFtoC(numberOfRecvIndices, indices, recvIndicesAfterFtoC);
185
186 // copy new vectors back to recvIndices array
187 std::copy(recvIndicesAfterFtoC.begin(), recvIndicesAfterFtoC.end(), indices);
188 std::copy(recvIndicesOther.begin(), recvIndicesOther.end(), indices + recvIndicesAfterFtoC.size());
189
190 VF_LOG_INFO("Reorder recv indices: process {}, numberOfRecvNodesAfterFtoC {}", communicator.getProcessID(),
191 recvIndicesAfterFtoC.size());
192
193 if (recvIndicesAfterFtoC.size() + recvIndicesOther.size() != numberOfRecvIndices) {
194 VF_LOG_CRITICAL("reorderRecvIndicesForCommAfterFtoC(): incorrect number of nodes");
195 VF_LOG_CRITICAL("numberOfRecvNodesAfterFtoC = {}, recvIndicesOther.size() = {}, numberOfRecvIndices = {}",
196 recvIndicesAfterFtoC.size(), recvIndicesOther.size(), numberOfRecvIndices);
197 }
198}
199
201 const uint numberOfNodes)
202{
204 neighborAfterFtoC.numberOfNodes = numberOfNodes;
205 neighborAfterFtoC.numberOfFs = vf::lbm::dir::NUMBER_Of_DIRECTIONS * numberOfNodes;
206 neighborAfterFtoC.memsizeIndex = sizeof(uint) * numberOfNodes;
207 neighborAfterFtoC.memsizeFs = sizeof(real) * vf::lbm::dir::NUMBER_Of_DIRECTIONS * numberOfNodes;
208 return neighborAfterFtoC;
209}
210
211std::vector<uint> IndexRearrangementForStreams::aggregateCoarseNodesForCtoF(const int level) const
212{
213 std::vector<uint> nodesCFC;
214 const uint* neighborX = para->getParH(level)->neighborX;
215 const uint* neighborY = para->getParH(level)->neighborY;
216 const uint* neighborZ = para->getParH(level)->neighborZ;
217
218 for (uint x = 0; x < para->getParH(level)->coarseToFine.numberOfCells; x++) {
219 const uint sparseIndex = para->getParH(level)->coarseToFine.coarseCellIndices[x];
220 nodesCFC.push_back(sparseIndex);
221 nodesCFC.push_back(neighborX[sparseIndex]);
222 nodesCFC.push_back(neighborY[sparseIndex]);
223 nodesCFC.push_back(neighborZ[sparseIndex]);
224 nodesCFC.push_back(neighborY[neighborX[sparseIndex]]);
225 nodesCFC.push_back(neighborZ[neighborX[sparseIndex]]);
226 nodesCFC.push_back(neighborZ[neighborY[sparseIndex]]);
227 nodesCFC.push_back(neighborZ[neighborY[neighborX[sparseIndex]]]);
228 }
229
230 // remove duplicate nodes
231 std::sort(nodesCFC.begin(), nodesCFC.end());
232 auto iterator = std::unique(nodesCFC.begin(), nodesCFC.end());
233 nodesCFC.erase(iterator, nodesCFC.end());
234 return nodesCFC;
235}
236
238 const uint* indices,
239 const std::vector<uint>& indicesAfterFtoC)
240{
241 std::vector<uint> otherIndices;
242 for (uint posInSendIndices = 0; posInSendIndices < numberOfIndices; posInSendIndices++) {
243 const uint sparseIndexSend = indices[posInSendIndices];
245 otherIndices.push_back(sparseIndexSend);
246 }
247 return otherIndices;
248}
249
250}
251
#define VF_LOG_INFO(...)
Definition Logger.h:50
#define VF_LOG_CRITICAL(...)
Definition Logger.h:52
#define VF_LOG_WARNING(...)
Definition Logger.h:51
void reorderRecvIndicesForCommAfterFtoC(uint *recvIndices, int direction, int level, const std::vector< uint > &recvIndicesForCommAfterFtoCPositions) const
Reorder the receive indices in the same way that the send indices were reordered.
static std::vector< uint > findIndicesNotInCommAfterFtoC(uint numberOfIndices, const uint *indices, const std::vector< uint > &indicesAfterFtoC)
Find all indices which are not part of the communication after the interpolation from fine to coarse.
std::vector< uint > reorderSendIndicesForCommAfterFtoC(uint *indices, int direction, int level) const
The send indices are reordered for the communication after the interpolation from fine to coarse.
static ProcessNeighbor27 makeProcessNeighborToCommAfterFtoC(const ProcessNeighbor27 &neighbor, uint numberOfNodes)
Initializes pointers for reduced communication after the interpolation from fine to coarse by copying...
virtual std::array< ProcessNeighbor27, 4 > initCommunicationArraysForCommAfterFinetoCoarse(const ProcessNeighbor27 &sendNeighborHost, const ProcessNeighbor27 &sendNeighborDevice, const ProcessNeighbor27 &recvNeighborHost, const ProcessNeighbor27 &recvNeighborDevice, int level, int direction) const
Initialize the arrays for the communication after the interpolation from fine to coarse.
std::vector< uint > aggregateCoarseNodesForCtoF(int level) const
Aggregate all nodes in the coarse cells for the interpolation in coarse to fine.
IndexRearrangementForStreams(std::shared_ptr< Parameter > para, std::shared_ptr< GridBuilder > builder, vf::parallel::Communicator &communicator)
std::vector< uint > exchangeIndicesForCommAfterFtoC(const ProcessNeighbor27 &sendNeighbor, const ProcessNeighbor27 &recvNeighbor, const std::vector< uint > &sendIndicesForCommAfterFtoCPositions) const
send sendIndicesForCommAfterFtoCPositions to receiving process and receive recvIndicesForCommAfterFto...
An abstract class for communication between processes in parallel computation.
virtual int getProcessID() const =0
virtual void receiveSend(uint *buffer_receive, int size_buffer_recv, int neighbor_rank_recv, const uint *buffer_send, int size_buffer_send, int neighbor_rank_send) const =0
std::shared_ptr< T > SPtr
float real
Definition DataTypes.h:42
unsigned int uint
Definition DataTypes.h:47
@ x
Definition Axis.h:42
bool indexInVector(const std::vector< uint > &vector, uint index)
bool indexInArray(const uint *array, uint numberOfElements, uint index)
uint * coarseCellIndices
Definition Calculation.h:77