MaMiCo 1.2
Loading...
Searching...
No Matches
IndexingService.h
1#pragma once
2
3// parallel topologies
4#include "coupling/CouplingMDDefinitions.h"
5#include "coupling/paralleltopology/ParallelTopology.h"
6#include "coupling/paralleltopology/ParallelTopologyFactory.h"
7
8#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
9#include <mpi.h>
10#endif
11
12namespace coupling {
13namespace indexing {
14
15template <unsigned int dim> class IndexingService;
16
17}
18} // namespace coupling
19
20// Include CellIndex template class definition
21#include "coupling/indexing/IndexTypes.h"
22
23namespace coupling {
24namespace indexing {
25
26template <unsigned int dim> std::vector<unsigned int> getRanksForGlobalIndex(const BaseIndex<dim>& globalCellIndex, unsigned int topologyOffset);
27
28} // namespace indexing
29} // namespace coupling
30
31// Include non-member functions operating on indexes
32#include "Operations.h"
33
34class IndexingServiceTest;
35
48template <unsigned int dim> class coupling::indexing::IndexingService {
49public:
50 static IndexingService& getInstance() {
51 static IndexingService singleton{};
52 return singleton;
53 }
54
55 void initWithCells(tarch::la::Vector<dim, unsigned int> globalNumberCouplingCells, tarch::la::Vector<dim, unsigned int> numberProcesses,
56 coupling::paralleltopology::ParallelTopologyType parallelTopologyType, unsigned int outerRegion, const unsigned int rank
57#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
58 ,
59 MPI_Comm comm = MPI_COMM_WORLD
60#endif
61 ) {
62 // regular grid
64 for (unsigned int i = 0; i < dim; i++) {
65 subdomainWeights[i].reserve(numberProcesses[i]);
66 for (unsigned int j = 0; j < numberProcesses[i]; j++) {
67 subdomainWeights[i].push_back(1);
68 }
69 }
70 initWithCells(subdomainWeights, globalNumberCouplingCells, numberProcesses, parallelTopologyType, outerRegion, rank
71#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
72 ,
73 comm
74#endif
75 );
76 }
77
78 void initWithCells(const tarch::la::Vector<dim, std::vector<unsigned int>>& subdomainWeights, tarch::la::Vector<dim, unsigned int> globalNumberCouplingCells,
80 unsigned int outerRegion, const unsigned int rank
81#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
82 ,
83 MPI_Comm comm = MPI_COMM_WORLD
84#endif
85 );
86
87 void initWithMDSize(const tarch::la::Vector<3, double>& globalMDDomainSize, const tarch::la::Vector<3, double>& globalMDDomainOffset,
88 const tarch::la::Vector<3, unsigned int>& mdNumberProcesses, const tarch::la::Vector<3, double>& couplingCellSize,
89 coupling::paralleltopology::ParallelTopologyType parallelTopologyType, unsigned int outerRegion, unsigned int rank
90#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
91 ,
92 MPI_Comm comm = MPI_COMM_WORLD
93#endif
94 ) {
95 // regular grid
97 for (unsigned int i = 0; i < dim; i++) {
98 subdomainWeights[i].reserve(mdNumberProcesses[i]);
99 for (unsigned int j = 0; j < mdNumberProcesses[i]; j++) {
100 subdomainWeights[i].push_back(1);
101 }
102 }
103
104 initWithMDSize(subdomainWeights, globalMDDomainSize, globalMDDomainOffset, mdNumberProcesses, couplingCellSize, parallelTopologyType, outerRegion, rank
105#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
106 ,
107 comm
108#endif
109 );
110 }
111 void initWithMDSize(const tarch::la::Vector<dim, std::vector<unsigned int>>& subdomainWeights, const tarch::la::Vector<3, double>& globalMDDomainSize,
112 const tarch::la::Vector<3, double>& globalMDDomainOffset, const tarch::la::Vector<3, unsigned int>& mdNumberProcesses,
113 const tarch::la::Vector<3, double>& couplingCellSize, coupling::paralleltopology::ParallelTopologyType parallelTopologyType,
114 unsigned int outerRegion, unsigned int rank
115#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
116 ,
117 MPI_Comm comm = MPI_COMM_WORLD
118#endif
119 ) {
120 _globalMDDomainSize = globalMDDomainSize;
121 _globalMDDomainOffset = globalMDDomainOffset;
122 _couplingCellSize = couplingCellSize;
123 _initedWithMDSize = true;
124
125 // calculate total number of coupling cells on all ranks in Base Domain
126 tarch::la::Vector<dim, unsigned int> globalNumberCouplingCells(0);
127 for (unsigned int d = 0; d < dim; d++) {
128 globalNumberCouplingCells[d] = (unsigned int)floor(globalMDDomainSize[d] / couplingCellSize[d] + 0.5);
129
130 if (fabs((globalNumberCouplingCells[d]) * couplingCellSize[d] - globalMDDomainSize[d]) > 1e-13)
131 std::cout << "IndexingService: Deviation of domain size > 1e-13!" << std::endl;
132 }
133
134 initWithCells(subdomainWeights, globalNumberCouplingCells, mdNumberProcesses, parallelTopologyType, outerRegion, rank
135#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
136 ,
137 comm
138#endif
139 );
140 }
141
142 void finalize() {
143#if (COUPLING_MD_ERROR == COUPLING_MD_YES)
144 _isInitialized = false;
145#endif
146 }
147
157 std::vector<unsigned int> getRanksForGlobalIndex(const BaseIndex<dim>& globalCellIndex, unsigned int topologyOffset) const;
158
159 unsigned int getUniqueRankForCouplingCell(const BaseIndex<dim>& globalCellIndex, unsigned int topologyOffset) const;
160
161#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES) // parallel scenario
162 MPI_Comm getComm() const {
163#if (COUPLING_MD_ERROR == COUPLING_MD_YES)
164 if (!_isInitialized) {
165 throw std::runtime_error(std::string("IndexingService: Called index system getComm() before initialization! "));
166 }
167#endif
168
169 return _comm;
170 }
171#endif
172
173 unsigned int getRank() const {
174#if (COUPLING_MD_ERROR == COUPLING_MD_YES)
175 if (!_isInitialized) {
176 throw std::runtime_error(std::string("IndexingService: Called index system getRank() before initialization! "));
177 }
178#endif
179
180 return _rank;
181 }
182
183#if (COUPLING_MD_ERROR == COUPLING_MD_YES)
184 bool isInitialized() const { return _isInitialized; }
185#endif
186
191#if (COUPLING_MD_ERROR == COUPLING_MD_YES)
192 if (!_isInitialized) {
193 throw std::runtime_error(std::string("IndexingService: Called getGlobalMDDomainSize() before initalization! "));
194 }
195 if (!_initedWithMDSize) {
196 throw std::runtime_error(std::string("IndexingService: Called getGlobalMDDomainSize() without calling initWithMDSize()! "));
197 }
198#endif
199 return _globalMDDomainSize;
200 }
201
206#if (COUPLING_MD_ERROR == COUPLING_MD_YES)
207 if (!_isInitialized) {
208 throw std::runtime_error(std::string("IndexingService: Called getGlobalMDDomainOffset() before initalization! "));
209 }
210 if (!_initedWithMDSize) {
211 throw std::runtime_error(std::string("IndexingService: Called getGlobalMDDomainOffset() without calling initWithMDSize()! "));
212 }
213#endif
214 return _globalMDDomainOffset;
215 }
216
220#if (COUPLING_MD_ERROR == COUPLING_MD_YES)
221 if (!_isInitialized) {
222 throw std::runtime_error(std::string("IndexingService: Called getCouplingCellSize() before initalization! "));
223 }
224 if (!_initedWithMDSize) {
225 throw std::runtime_error(std::string("IndexingService: Called getCouplingCellSize() without calling initWithMDSize()! "));
226 }
227#endif
228 return _couplingCellSize;
229 }
230
231 unsigned int getScalarNumberProcesses() const {
232#if (COUPLING_MD_ERROR == COUPLING_MD_YES)
233 if (!_isInitialized) {
234 throw std::runtime_error(std::string("IndexingService: Called getScalarNumberProcesses() before initalization! "));
235 }
236#endif
237 return _scalarNumberProcesses;
238 }
239
240 BaseIndex<dim> getCellIndex(tarch::la::Vector<dim, double> position) const {
241#if (COUPLING_MD_ERROR == COUPLING_MD_YES)
242 if (!_isInitialized) {
243 throw std::runtime_error(std::string("IndexingService: Called getCellIndex() before initalization! "));
244 }
245 if (!_initedWithMDSize) {
246 throw std::runtime_error(std::string("IndexingService: Called getCellIndex() without calling initWithMDSize()! "));
247 }
248#endif
249
250 tarch::la::Vector<dim, int> res_raw;
251 for (unsigned int d = 0; d < dim; d++) {
252 const double buf = position[d] - (_globalMDDomainOffset[d] - _couplingCellSize[d]);
253 res_raw[d] = buf / _couplingCellSize[d];
254 }
255
256 BaseIndex<dim> res{res_raw};
257#if (COUPLING_MD_ERROR == COUPLING_MD_YES)
258 if (!BaseIndex<dim>::contains(res)) {
259 throw std::runtime_error(std::string("IndexingService::getCellIndex(): Invalid conversion!"));
260 }
261#endif
262 return res;
263 }
264
265private:
266 unsigned int getUniqueRankForCouplingCell(tarch::la::Vector<dim, unsigned int> globalCellIndex,
267 const tarch::la::Vector<dim, unsigned int>& globalNumberCouplingCells, unsigned int topologyOffset) const;
268
269 /*const*/ tarch::la::Vector<dim, unsigned int> _numberProcesses; // TODO: make const
270 unsigned int _scalarNumberProcesses;
271 const coupling::paralleltopology::ParallelTopology<dim>* _parallelTopology;
272#if (COUPLING_MD_PARALLEL == COUPLING_MD_YES) // parallel scenario
273 MPI_Comm _comm;
274#endif
275 unsigned int _rank;
276#if (COUPLING_MD_ERROR == COUPLING_MD_YES)
277 bool _isInitialized = false;
278#endif
279 bool _initedWithMDSize = false;
280 tarch::la::Vector<dim, std::vector<unsigned int>> _subdomainOwnership;
281 tarch::la::Vector<dim, double> _globalMDDomainSize;
282 tarch::la::Vector<dim, double> _globalMDDomainOffset;
283 tarch::la::Vector<dim, double> _couplingCellSize;
285 friend IndexingServiceTest;
286};
static bool contains(const coupling::indexing::BaseIndex< dim > &index)
Definition CellIndex.h:227
Definition IndexingService.h:48
tarch::la::Vector< dim, double > getCouplingCellSize() const
returns the vector size of each coupling cell.
Definition IndexingService.h:219
tarch::la::Vector< dim, double > getGlobalMDDomainSize() const
Definition IndexingService.h:190
tarch::la::Vector< dim, double > getGlobalMDDomainOffset() const
returns the offset, i.e. the lower,left... corner coordinate, of the MD domain.
Definition IndexingService.h:205
std::vector< unsigned int > getRanksForGlobalIndex(const BaseIndex< dim > &globalCellIndex, unsigned int topologyOffset) const
Definition Vector.h:24
ParallelTopologyType
Definition ParallelTopologyFactory.h:24
everything necessary for coupling operations, is defined in here
Definition AdditiveMomentumInsertion.h:15