OpenLB 1.8.1
Loading...
Searching...
No Matches
superLatticeRefinement.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2024 Adrian Kummerlaender
4 *
5 * E-mail contact: info@openlb.net
6 * The most recent release of OpenLB can be downloaded at
7 * <http://www.openlb.net/>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with this program; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 */
24
25#ifndef REFINEMENT_SUPER_LATTICE_REFINEMENT_H
26#define REFINEMENT_SUPER_LATTICE_REFINEMENT_H
27
28#include "operatorScope.h"
29#include "operatorPromise.h"
30
31#include "loadBalancer.h"
32
33namespace olb {
34
35template <typename T, typename DESCRIPTOR, Platform PLATFORM>
36class ConcreteBlockRefinementContextD final : public BlockRefinementContextD<T,DESCRIPTOR> {
37private:
41 std::map<CellID, CellID> _dataIndex;
43 bool _dataIndexChanged;
44
47
48 void updateContextNeighborIndices() {
49 using namespace fields::refinement;
50 const auto& cellIdFine = _data.template getField<CELL_ID_FINE>();
51 for (std::size_t i=0; i < cellIdFine.getSize(); ++i) {
52 auto latticeR = _fLattice.getLatticeR(cellIdFine[0][i]);
53 FieldD<T,DESCRIPTOR,CONTEXT_NEIGHBORS> neighbors(std::numeric_limits<CellID>::max());
54 for (unsigned iN=0; iN < CONTEXT_NEIGHBORS::count<DESCRIPTOR>(); ++iN) {
55 if (auto index = getDataIndex(latticeR + CONTEXT_NEIGHBORS::c<DESCRIPTOR>(iN))) {
56 neighbors[iN] = *index;
57 }
58 }
59 _data.template getField<CONTEXT_NEIGHBORS>().set(i, neighbors);
60 }
61 }
62
63public:
67 : _data{data}
68 , _dataIndex{}
69 , _dataIndexChanged{true}
70 , _cLattice{cLattice}
71 , _fLattice{fLattice}
72 {
73 auto size = _data.getCore();
74 size[0] = 0;
75 for (unsigned iD=1; iD < DESCRIPTOR::d; ++iD) {
76 size[iD] = 1;
77 }
78 _data.resize(size);
79 }
80
81 Platform getPlatform() const override {
82 return PLATFORM;
83 }
84
85 void setProcessingContext(ProcessingContext context) override {
86 _data.setProcessingContext(context);
87 }
88
90 return _fLattice;
91 }
92
94 return _cLattice;
95 }
96
98 return _data;
99 }
100
102 return _data;
103 }
104
105 void add(LatticeR<DESCRIPTOR::d> latticeR) override {
106 CellID iCell = _fLattice.getCellId(latticeR);
107 if (_dataIndex.find(iCell) == _dataIndex.end()) {
108 _dataIndexChanged = true;
109 _dataIndex[iCell] = _data.getNcells();
110
111 auto size = _data.getCore();
112 size[0] += 1;
113 _data.resize(size);
114
115 _data.template getField<fields::refinement::CELL_ID_FINE>().set(_dataIndex[iCell], iCell);
116
117 bool coIncident = true;
118 for (unsigned iD=0; iD < DESCRIPTOR::d; ++iD) {
119 coIncident &= latticeR[iD] % 2 == 0;
120 }
121 if (coIncident) {
122 _data.template getField<fields::refinement::CELL_ID_COARSE>().set(
123 _dataIndex[iCell], _cLattice.getCellId(latticeR / 2));
124 } else {
125 _data.template getField<fields::refinement::CELL_ID_COARSE>().set(_dataIndex[iCell], 0);
126 }
127 }
128 }
129
130 std::optional<std::size_t> getDataIndex(LatticeR<DESCRIPTOR::d> latticeR) const override {
131 auto iter = _dataIndex.find(_fLattice.getCellId(latticeR));
132 if (iter != _dataIndex.end()) {
133 return std::get<1>(*iter);
134 } else {
135 return std::nullopt;
136 }
137 }
138
140 if (_dataIndexChanged && promise.requiresContextNeighborAccess()) {
141 updateContextNeighborIndices();
142 _data.template getField<fields::refinement::CONTEXT_NEIGHBORS>()
144 _dataIndexChanged = false;
145 }
146 promise.apply(*this);
147 }
148
149};
150
151template <typename T, typename DESCRIPTOR>
153private:
155
158
160
161 std::vector<std::unique_ptr<BlockRefinementContextD<T,DESCRIPTOR>>> _context;
162
163 template <Platform PLATFORM>
164 auto constructConcreteBlockContext(int fineC) {
165 const int coarseC = _balancer.cloc(fineC);
166 return std::make_unique<ConcreteBlockRefinementContextD<T,DESCRIPTOR,PLATFORM>>(
167 _cLattice.getBlock(coarseC).template asConcrete<PLATFORM>()
168 , _fLattice.getBlock(fineC).template asConcrete<PLATFORM>()
169 , _data.getBlock(fineC).template asConcrete<PLATFORM>());
170 }
171
172 std::map<std::type_index,
173 std::unique_ptr<SuperCommunicator<T,SuperLattice<T,DESCRIPTOR>>>> _cCommunicator;
174 std::map<std::type_index,
175 std::unique_ptr<SuperCommunicator<T,SuperLattice<T,DESCRIPTOR>>>> _fCommunicator;
176
177public:
180 const LoadBalancer<T>& balancer)
181 : _data(balancer)
182 , _cLattice(cLattice)
183 , _fLattice(fLattice)
184 , _balancer(dynamic_cast<const RefinedLoadBalancer<T,DESCRIPTOR::d>&>(balancer))
185 {
186 for (int iC = 0; iC < _balancer.size(); ++iC) {
188 [&](auto platform) {
189 _context.emplace_back(constructConcreteBlockContext<platform.value>(iC));
190 });
191 }
192 }
193
195 return *_context[iC];
196 }
197
200 {
201 auto iter = _cCommunicator.find(promise.id());
202 if (iter != _cCommunicator.end()) {
203 std::get<1>(*iter)->communicate();
204 }
205 }
206 {
207 auto iter = _fCommunicator.find(promise.id());
208 if (iter != _fCommunicator.end()) {
209 std::get<1>(*iter)->communicate();
210 }
211 }
212
213 #ifdef PARALLEL_MODE_OMP
214 #pragma omp taskloop
215 #endif
216 for (int iC = 0; iC < _balancer.size(); ++iC) {
217 _context[iC]->apply(std::forward<BlockRefinementOperatorPromise<T,DESCRIPTOR>&&>(promise));
218 }
219 }
220
222 for (int iC = 0; iC < _balancer.size(); ++iC) {
223 _context[iC]->setProcessingContext(context);
224 }
225 }
226
229 auto iter = _cCommunicator.find(promise.id());
230 if (iter == _cCommunicator.end()) {
231 iter = std::get<0>(_cCommunicator.emplace(promise.id(),
232 std::make_unique<SuperCommunicator<T,SuperLattice<T,DESCRIPTOR>>>(_cLattice)));
233 }
234 return *std::get<1>(*iter);
235 }
236
239 auto iter = _fCommunicator.find(promise.id());
240 if (iter == _fCommunicator.end()) {
241 iter = std::get<0>(_fCommunicator.emplace(promise.id(),
242 std::make_unique<SuperCommunicator<T,SuperLattice<T,DESCRIPTOR>>>(_fLattice)));
243 }
244 return *std::get<1>(*iter);
245 }
246
247};
248
249}
250
251#endif
Untyped promise to execute some block refinement operator.
std::size_t getNcells() const
Get number of cells.
LatticeR< D > getLatticeR(CellID iCell) const
CellID getCellId(LatticeR< D > latticeR) const
Get 1D cell ID.
Implementation of BlockD on a concrete PLATFORM.
Definition cell.h:32
void resize(Vector< int, DESCRIPTOR::d > size) override
Definition blockD.hh:60
void setProcessingContext(ProcessingContext context) override
Set processing context.
Definition blockD.h:265
Implementation of BlockLattice on a concrete PLATFORM.
Context for the execution of block refinement operators.
BlockRefinementContextD< T, DESCRIPTOR >::Data & getData() override
Return reference to contextual data.
ConcreteBlockRefinementContextD(ConcreteBlockLattice< T, DESCRIPTOR, PLATFORM > &cLattice, ConcreteBlockLattice< T, DESCRIPTOR, PLATFORM > &fLattice, ConcreteBlockD< T, refinement::DATA_DESCRIPTOR< DESCRIPTOR >, PLATFORM > &data)
void apply(BlockRefinementOperatorPromise< T, DESCRIPTOR > &&promise) override
Apply promised algorithm step to the previously added connection points.
std::optional< std::size_t > getDataIndex(LatticeR< DESCRIPTOR::d > latticeR) const override
Return index where contextual data of connection point latticeR is stored.
void add(LatticeR< DESCRIPTOR::d > latticeR) override
Connect the coarse and fine lattice at position latticeR.
void setProcessingContext(ProcessingContext context) override
Base class for all LoadBalancer.
Definition vtiWriter.h:42
virtual Platform platform(int loc) const
Load balancer for refined lattice hierarchies.
int cloc(int fineLoc) const
Returns coarse loc for given fine loc.
Generic communicator for overlaps between blocks of SUPER.
BlockD< T, DESCRIPTOR > & getBlock(unsigned iB)
Definition superD.h:59
void setProcessingContext(ProcessingContext context)
SuperLatticeRefinement(SuperLattice< T, DESCRIPTOR > &cLattice, SuperLattice< T, DESCRIPTOR > &fLattice, const LoadBalancer< T > &balancer)
BlockRefinementContextD< T, DESCRIPTOR > & getBlock(int iC)
void apply(BlockRefinementOperatorPromise< T, DESCRIPTOR > &&promise)
Apply coupling operation on all blocks.
SuperCommunicator< T, SuperLattice< T, DESCRIPTOR > > & getCoarseCommunicator(BlockRefinementOperatorPromise< T, DESCRIPTOR > &&promise)
SuperCommunicator< T, SuperLattice< T, DESCRIPTOR > > & getFineCommunicator(BlockRefinementOperatorPromise< T, DESCRIPTOR > &&promise)
Super class maintaining block lattices for a cuboid decomposition.
BlockLattice< T, DESCRIPTOR > & getBlock(int locC)
Return BlockLattice with local index locC.
Plain old scalar vector.
Top level namespace for all of OpenLB.
auto callUsingConcretePlatform(Platform platform, typename CONCRETIZABLE::base_t *ptr, F f)
Dispatcher for concrete platform access.
Definition dispatch.h:41
std::uint32_t CellID
Type for sequential block-local cell indices.
ProcessingContext
OpenLB processing contexts.
Definition platform.h:54
@ Simulation
Data available on host for e.g. functor evaluation.
Platform
OpenLB execution targets.
Definition platform.h:35
Interface for the contextual data of a block refinement.
Definition operator.h:48
Base descriptor of a D-dimensional lattice with Q directions and a list of additional fields.
Definition base.h:95