25#ifndef SUPER_LATTICE_COUPLING_H
26#define SUPER_LATTICE_COUPLING_H
37template <
typename COUPLER,
typename COUPLEES, Platform PLATFORM>
41 template <
typename VALUED_DESCRIPTOR>
43 typename VALUED_DESCRIPTOR::descriptor_t,
52 std::unique_ptr<ConcreteBlockMask<typename COUPLEES::values_t::template get<0>::value_t,
58 auto cells = _lattices.exchange_values([&](
auto name) ->
auto {
59 return cpu::Cell{*_lattices.get(name), iCell};
61 COUPLER().apply(cells);
65 template <
typename LATTICES>
70 std::type_index
id()
const override {
71 return typeid(COUPLER);
81 _mask = std::make_unique<ConcreteBlockMask<typename COUPLEES::values_t::template get<0>::value_t,
83 _lattices.template get<0>()->template getData<CollisionSubdomainMask>()
86 _mask->set(iCell, state);
92 auto* lattice = _lattices.template get<0>();
94 #ifdef PARALLEL_MODE_OMP
95 #pragma omp parallel for schedule(static) collapse(1)
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))) {
106 if (_mask->operator[](lattice->getCellId(iX,iY))) {
113 #ifdef PARALLEL_MODE_OMP
114 #pragma omp parallel for schedule(static) collapse(1)
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) {
132template <
typename COUPLER,
typename COUPLEES, Platform PLATFORM>
136 template <
typename VALUED_DESCRIPTOR>
138 typename VALUED_DESCRIPTOR::descriptor_t,
145 typename COUPLER::parameters::template decompose_into<
149 std::unique_ptr<ConcreteBlockMask<typename COUPLEES::values_t::template get<0>::value_t,
155 auto cells = _lattices.exchange_values([&](
auto name) ->
auto {
156 return cpu::Cell{*_lattices.get(name), iCell};
158 COUPLER().apply(cells, _parameters);
162 template <
typename LATTICES>
167 std::type_index
id()
const override {
168 return typeid(COUPLER);
178 _mask = std::make_unique<ConcreteBlockMask<typename COUPLEES::values_t::template get<0>::value_t,
180 _lattices.template get<0>()->template getData<CollisionSubdomainMask>()
183 _mask->set(iCell, state);
189 auto* lattice = _lattices.template get<0>();
191 #ifdef PARALLEL_MODE_OMP
192 #pragma omp parallel for schedule(static) collapse(1)
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))) {
203 if (_mask->operator[](lattice->getCellId(iX,iY))) {
210 #ifdef PARALLEL_MODE_OMP
211 #pragma omp parallel for schedule(static) collapse(1)
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) {
231template <
typename COUPLER,
typename COUPLEES>
234 template <
typename VALUED_DESCRIPTOR>
236 typename VALUED_DESCRIPTOR::descriptor_t>*;
242 std::vector<std::unique_ptr<AbstractCouplingO<COUPLEES>>> _block;
244 template <Platform PLATFORM>
245 auto constructConcreteBlockCoupling(
int iC)
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));
254 return std::make_unique<ConcreteBlockCouplingO<COUPLEES,PLATFORM,COUPLER,COUPLER::scope>>(block);
258 template <
typename... MAP>
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));
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");
278 _block.emplace_back(constructConcreteBlockCoupling<platform.value>(iC));
286 auto& load = _lattices.template get<0>()->getLoadBalancer();
287 #ifdef PARALLEL_MODE_OMP
290 for (
int iC = 0; iC < load.size(); ++iC) {
291 _block[iC]->execute();
296 template <
typename FIELD>
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));
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);
329 _block[iC]->set(blockL.getCellId(latticeR), blockI(latticeR));
336template <
typename COUPLER,
typename... MAP>
339 typename meta::map<MAP...>::template map_values<descriptors::extract_valued_descriptor_t>
342template <
typename COUPLER,
typename... MAP>
346 typename meta::map<MAP...>::template map_values<descriptors::extract_valued_descriptor_t>
347 >>(COUPLER{}, std::forward<decltype(map)>(map)...);
CellID getCellId(LatticeR< D > latticeR) const
Get 1D cell ID.
Coupling of COUPLEES using concrete OPERATOR with SCOPE on PLATFORM lattices.
Implementation of BlockLattice on a concrete PLATFORM.
Smart pointer for managing the various ways of passing functors around.
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.
Cell concept for concrete block lattices on CPU platforms.
Top level namespace for all of OpenLB.
auto callUsingConcretePlatform(Platform platform, typename CONCRETIZABLE::base_t *ptr, F f)
Dispatcher for concrete platform access.
std::uint32_t CellID
Type for sequential block-local cell indices.
Platform
OpenLB execution targets.
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.
@ 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
Base of block-wide coupling operators executed by SuperLatticeCoupling.
typename COUPLEES::values_t::template get< 0 >::value_t value_t
Value type used for coupling parameters.
Dynamic access interface for FIELD-valued parameters.
Set of FIELD-valued parameters.
Mapping between KEYs and instances of type VALUEs.