OpenLB 1.7
Loading...
Searching...
No Matches
superLatticeCoupling.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2022 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 SUPER_LATTICE_COUPLING_H
26#define SUPER_LATTICE_COUPLING_H
27
28#include "operator.h"
29#include "superLattice.h"
30
31#include "utilities/typeMap.h"
32#include "solver/names.h"
33
34namespace olb {
35
36
37template <typename COUPLER, typename COUPLEES, Platform PLATFORM>
38class ConcreteBlockCouplingO<COUPLEES,PLATFORM,COUPLER,OperatorScope::PerCell>
39 final : public AbstractCouplingO<COUPLEES> {
40private:
41 template <typename VALUED_DESCRIPTOR>
42 using ptr_to_lattice = ConcreteBlockLattice<typename VALUED_DESCRIPTOR::value_t,
43 typename VALUED_DESCRIPTOR::descriptor_t,
44 PLATFORM>*;
45
46 utilities::TypeIndexedTuple<typename COUPLEES::template map_values<
48 >> _lattices;
49
51
52 std::unique_ptr<ConcreteBlockMask<typename COUPLEES::values_t::template get<0>::value_t,
53 PLATFORM>> _mask;
54
55 void execute(typename AbstractCouplingO<COUPLEES>::LatticeR latticeR)
56 {
57 CellID iCell = _lattices.template get<0>()->getCellId(latticeR);
58 auto cells = _lattices.exchange_values([&](auto name) -> auto {
59 return cpu::Cell{*_lattices.get(name), iCell};
60 });
61 COUPLER().apply(cells);
62 }
63
64public:
65 template <typename LATTICES>
66 ConcreteBlockCouplingO(LATTICES&& lattices):
67 _lattices{lattices}
68 { }
69
70 std::type_index id() const override {
71 return typeid(COUPLER);
72 }
73
75 return _parameters;
76 }
77
78 void set(CellID iCell, bool state) override
79 {
80 if (!_mask) {
81 _mask = std::make_unique<ConcreteBlockMask<typename COUPLEES::values_t::template get<0>::value_t,
82 PLATFORM>>(
83 _lattices.template get<0>()->template getData<CollisionSubdomainMask>()
84 );
85 }
86 _mask->set(iCell, state);
87 }
88
89 void execute() override
90 {
92 auto* lattice = _lattices.template get<0>();
93 if (_mask) {
94 #ifdef PARALLEL_MODE_OMP
95 #pragma omp parallel for schedule(static) collapse(1)
96 #endif
97 for (loc iX=0; iX < lattice->getNx(); ++iX) {
98 for (loc iY=0; iY < lattice->getNy(); ++iY) {
100 for (loc iZ=0; iZ < lattice->getNz(); ++iZ) {
101 if (_mask->operator[](lattice->getCellId(iX,iY,iZ))) {
102 execute({iX,iY,iZ});
103 }
104 }
105 } else {
106 if (_mask->operator[](lattice->getCellId(iX,iY))) {
107 execute({iX,iY});
108 }
109 }
110 }
111 }
112 } else {
113 #ifdef PARALLEL_MODE_OMP
114 #pragma omp parallel for schedule(static) collapse(1)
115 #endif
116 for (loc iX=0; iX < lattice->getNx(); ++iX) {
117 for (loc iY=0; iY < lattice->getNy(); ++iY) {
119 for (loc iZ=0; iZ < lattice->getNz(); ++iZ) {
120 execute({iX,iY,iZ});
121 }
122 } else {
123 execute({iX,iY});
124 }
125 }
126 }
127 }
128 }
129
130};
131
132template <typename COUPLER, typename COUPLEES, Platform PLATFORM>
134 final : public AbstractCouplingO<COUPLEES> {
135private:
136 template <typename VALUED_DESCRIPTOR>
137 using ptr_to_lattice = ConcreteBlockLattice<typename VALUED_DESCRIPTOR::value_t,
138 typename VALUED_DESCRIPTOR::descriptor_t,
139 PLATFORM>*;
140
141 utilities::TypeIndexedTuple<typename COUPLEES::template map_values<
143 >> _lattices;
144
145 typename COUPLER::parameters::template decompose_into<
147 > _parameters;
148
149 std::unique_ptr<ConcreteBlockMask<typename COUPLEES::values_t::template get<0>::value_t,
150 PLATFORM>> _mask;
151
152 void execute(typename AbstractCouplingO<COUPLEES>::LatticeR latticeR)
153 {
154 CellID iCell = _lattices.template get<0>()->getCellId(latticeR);
155 auto cells = _lattices.exchange_values([&](auto name) -> auto {
156 return cpu::Cell{*_lattices.get(name), iCell};
157 });
158 COUPLER().apply(cells, _parameters);
159 }
160
161public:
162 template <typename LATTICES>
163 ConcreteBlockCouplingO(LATTICES&& lattices):
164 _lattices{lattices}
165 { }
166
167 std::type_index id() const override {
168 return typeid(COUPLER);
169 }
170
172 return _parameters;
173 }
174
175 void set(CellID iCell, bool state) override
176 {
177 if (!_mask) {
178 _mask = std::make_unique<ConcreteBlockMask<typename COUPLEES::values_t::template get<0>::value_t,
179 PLATFORM>>(
180 _lattices.template get<0>()->template getData<CollisionSubdomainMask>()
181 );
182 }
183 _mask->set(iCell, state);
184 }
185
186 void execute() override
187 {
189 auto* lattice = _lattices.template get<0>();
190 if (_mask) {
191 #ifdef PARALLEL_MODE_OMP
192 #pragma omp parallel for schedule(static) collapse(1)
193 #endif
194 for (loc iX=0; iX < lattice->getNx(); ++iX) {
195 for (loc iY=0; iY < lattice->getNy(); ++iY) {
197 for (loc iZ=0; iZ < lattice->getNz(); ++iZ) {
198 if (_mask->operator[](lattice->getCellId(iX,iY,iZ))) {
199 execute({iX,iY,iZ});
200 }
201 }
202 } else {
203 if (_mask->operator[](lattice->getCellId(iX,iY))) {
204 execute({iX,iY});
205 }
206 }
207 }
208 }
209 } else {
210 #ifdef PARALLEL_MODE_OMP
211 #pragma omp parallel for schedule(static) collapse(1)
212 #endif
213 for (loc iX=0; iX < lattice->getNx(); ++iX) {
214 for (loc iY=0; iY < lattice->getNy(); ++iY) {
216 for (loc iZ=0; iZ < lattice->getNz(); ++iZ) {
217 execute({iX,iY,iZ});
218 }
219 } else {
220 execute({iX,iY});
221 }
222 }
223 }
224 }
225 }
226
227};
228
229
231template <typename COUPLER, typename COUPLEES>
233private:
234 template <typename VALUED_DESCRIPTOR>
235 using ptr_to_lattice = SuperLattice<typename VALUED_DESCRIPTOR::value_t,
236 typename VALUED_DESCRIPTOR::descriptor_t>*;
237
238 utilities::TypeIndexedTuple<typename COUPLEES::template map_values<
240 >> _lattices;
241
242 std::vector<std::unique_ptr<AbstractCouplingO<COUPLEES>>> _block;
243
244 template <Platform PLATFORM>
245 auto constructConcreteBlockCoupling(int iC)
246 {
247 auto block = _lattices.exchange_values([&](auto name) -> auto {
248 using NAME = typename decltype(name)::type;
249 using T = typename COUPLEES::template value<NAME>::value_t;
250 using DESCRIPTOR = typename COUPLEES::template value<NAME>::descriptor_t;
252 &_lattices.get(name)->getBlock(iC));
253 });
254 return std::make_unique<ConcreteBlockCouplingO<COUPLEES,PLATFORM,COUPLER,COUPLER::scope>>(block);
255 }
256
257public:
258 template <typename... MAP>
260 MAP&&... args) {
261 auto map = std::make_tuple(&args...);
262 COUPLEES::keys_t::for_each([&](auto id) {
263 using name_t = typename decltype(id)::type;
264 constexpr unsigned idx = COUPLEES::keys_t::template index<name_t>();
265 _lattices.template set<name_t>(std::get<2*idx+1>(map));
266 });
267
268 auto& load = _lattices.template get<0>()->getLoadBalancer();
269 for (int iC = 0; iC < load.size(); ++iC) {
270 Platform reference = _lattices.template get<0>()->getBlock(iC).getPlatform();
271 _lattices.for_each([&](auto name, auto lattice) {
272 if (lattice->getBlock(iC).getPlatform() != reference) {
273 throw std::runtime_error("Platforms of coupled block lattices must match");
274 }
275 });
277 [&](auto platform) {
278 _block.emplace_back(constructConcreteBlockCoupling<platform.value>(iC));
279 });
280 }
281 }
282
284 void execute()
285 {
286 auto& load = _lattices.template get<0>()->getLoadBalancer();
287 #ifdef PARALLEL_MODE_OMP
288 #pragma omp taskloop
289 #endif
290 for (int iC = 0; iC < load.size(); ++iC) {
291 _block[iC]->execute();
292 }
293 }
294
296 template <typename FIELD>
298 {
299 auto& load = _lattices.template get<0>()->getLoadBalancer();
300 for (int iC = 0; iC < load.size(); ++iC) {
301 _block[iC]->getParameters().template set<FIELD>(std::forward<decltype(field)>(field));
302 }
303 }
304
306
312 {
313 return *_block[iC];
314 }
315
317
322 {
323 using DESCRIPTOR = typename COUPLEES::values_t::template get<0>::descriptor_t;
324 auto& load = _lattices.template get<0>()->getLoadBalancer();
325 for (int iC = 0; iC < load.size(); ++iC) {
326 const auto& blockL = _lattices.template get<0>()->getBlock(iC);
327 auto& blockI = indicator->getBlockIndicatorF(iC);
328 blockL.forCoreSpatialLocations([&](LatticeR<DESCRIPTOR::d> latticeR) {
329 _block[iC]->set(blockL.getCellId(latticeR), blockI(latticeR));
330 });
331 }
332 }
333
334};
335
336template <typename COUPLER, typename... MAP>
338 COUPLER,
339 typename meta::map<MAP...>::template map_values<descriptors::extract_valued_descriptor_t>
340>;
341
342template <typename COUPLER, typename... MAP>
343auto constructSharedCoupling(COUPLER, MAP&&... map) {
344 return std::make_shared<SuperLatticeCoupling<
345 COUPLER,
346 typename meta::map<MAP...>::template map_values<descriptors::extract_valued_descriptor_t>
347 >>(COUPLER{}, std::forward<decltype(map)>(map)...);
348}
349
350}
351
352#endif
CellID getCellId(LatticeR< D > latticeR) const
Get 1D cell ID.
AbstractCouplingO< COUPLEES >::AbstractParameters & getParameters() override
Return reference to parameters of coupling operator.
void set(CellID iCell, bool state) override
Set whether iCell is covered by the present coupling.
void set(CellID iCell, bool state) override
Set whether iCell is covered by the present coupling.
AbstractCouplingO< COUPLEES >::AbstractParameters & getParameters() override
Return reference to parameters of coupling operator.
Coupling of COUPLEES using concrete OPERATOR with SCOPE on PLATFORM lattices.
Definition operator.h:142
Implementation of BlockLattice on a concrete PLATFORM.
Smart pointer for managing the various ways of passing functors around.
Definition functorPtr.h:60
Coupling operator COUPLER on named COUPLEES.
AbstractCouplingO< COUPLEES > & getBlock(int iC)
Return block-level abstract coupling operator.
void execute()
Execute coupling operation on all blocks.
void restrictTo(FunctorPtr< SuperIndicatorF< typename AbstractCouplingO< COUPLEES >::value_t, AbstractCouplingO< COUPLEES >::descriptor_t::d > > &&indicator)
Restrict coupling operation to indicated locations.
void setParameter(typename AbstractCouplingO< COUPLEES >::template FieldD< FIELD > &&field)
Set coupling parameter FIELD.
SuperLatticeCoupling(COUPLER, MAP &&... args)
Super class maintaining block lattices for a cuboid decomposition.
Plain old scalar vector.
Definition vector.h:47
Cell concept for concrete block lattices on CPU platforms.
Definition cell.h:87
Top level namespace for all of OpenLB.
auto callUsingConcretePlatform(Platform platform, typename CONCRETIZABLE::base_t *ptr, F f)
Dispatcher for concrete platform access.
Definition platform.h:88
std::uint32_t CellID
Type for sequential block-local cell indices.
Platform
OpenLB execution targets.
Definition platform.h:36
SuperLatticeCoupling(COUPLER, MAP &&...) -> SuperLatticeCoupling< COUPLER, typename meta::map< MAP... >::template map_values< descriptors::extract_valued_descriptor_t > >
auto constructSharedCoupling(COUPLER, MAP &&... map)
OperatorScope
Block-wide operator application scopes.
Definition operator.h:54
@ PerCell
Per-cell application, i.e. OPERATOR::apply is passed a CELL concept implementation.
@ PerCellWithParameters
Per-cell application with parameters, i.e. OPERATOR::apply is passed a CELL concept implementation an...
std::conditional_t< D==2, SuperIndicatorF2D< T >, SuperIndicatorF3D< T > > SuperIndicatorF
Definition aliases.h:208
Base of block-wide coupling operators executed by SuperLatticeCoupling.
Definition operator.h:115
typename COUPLEES::values_t::template get< 0 >::value_t value_t
Value type used for coupling parameters.
Definition operator.h:117
Dynamic access interface for FIELD-valued parameters.
Set of FIELD-valued parameters.
Mapping between KEYs and instances of type VALUEs.