26#ifndef BLOCK_LATTICE_H
27#define BLOCK_LATTICE_H
47#ifdef PLATFORM_CPU_SIMD
51#ifdef PLATFORM_GPU_CUDA
68template<
typename T,
typename DESCRIPTOR>
class SuperLattice;
69template<
typename T,
typename DESCRIPTOR>
struct Dynamics;
70template<
typename T,
typename DESCRIPTOR, Platform PLATFORM>
class ConcreteBlockLattice;
73template<
typename T,
typename DESCRIPTOR>
80template <Platform PLATFORM>
85template<
typename T,
typename DESCRIPTOR>
class BlockLattice { };
88template<concepts::BaseType T,
typename DESCRIPTOR>
89requires (!concepts::LatticeDescriptor<DESCRIPTOR>)
90class BlockLattice<T,DESCRIPTOR> { };
93template<concepts::BaseType T, concepts::LatticeDescriptor DESCRIPTOR>
137 template <Platform PLATFORM>
142 throw std::runtime_error(
"Invalid PLATFORM");
147 template<
typename FIELD_TYPE>
153 [&](
const auto* lattice) ->
bool {
154 return lattice->template hasData<FIELD_TYPE>();
158 template<
typename FIELD_TYPE>
159 const auto&
getData(FIELD_TYPE field = FIELD_TYPE{})
const
164 [&](
const auto* lattice) ->
const auto* {
165 return &(lattice->template getData<FIELD_TYPE>().asAbstract());
170 template<
typename FIELD_TYPE>
171 auto&
getData(FIELD_TYPE field = FIELD_TYPE{})
176 [&](
auto* lattice) ->
auto* {
177 return &(lattice->template getData<FIELD_TYPE>().asAbstract());
182 template<
typename FIELD>
189 template<
typename FIELD>
209 return get(this->getCellId(loc));
214 return get(this->getCellId(loc));
218 template <
typename... R>
222 return get(this->getCellId(latticeR...));
225 template <
typename... R>
229 return get(this->getCellId(latticeR...));
236 return _statisticsEnabled;
239 _statisticsEnabled = state;
243 return _introspectable && !std::is_same_v<T,Expr>;
246 _introspectable = state;
255 template <
typename... R>
259 return getDynamics(this->getCellId(latticeR...));
266 setDynamics(this->getCellId(latticeR),
270 template <
template<
typename...>
typename DYNAMICS>
273 setDynamics(this->getCellId(latticeR),
278 template <
typename DYNAMICS>
279 void defineDynamics();
281 template <
typename DYNAMICS>
295 template <
typename FIELD>
301 lattice->template setParameter<FIELD>(value);
305 template <
typename PARAMETER,
typename _DESCRIPTOR,
typename FIELD>
311 lattice->template setParameter<PARAMETER>(fieldArray);
314 template <
typename PARAMETER,
typename _DESCRIPTOR, Platform PLATFORM,
typename FIELD>
320 lattice->template setParameter<PARAMETER>(fieldArray);
355 template <
typename STAGE>
357 postProcess(
typeid(STAGE));
368 template <
typename FIELD>
376 template <
typename FIELD>
383 template <
typename FIELD>
448 void stripeOffDensityOffset(T offset);
458template<
typename T,
typename DESCRIPTOR, Platform PLATFORM=Platform::CPU_SISD>
466 std::map<std::type_index, std::unique_ptr<Communicatable>> _communicatables;
473 std::map<std::type_index,
483#ifdef PLATFORM_CPU_SIMD
484 static_assert(PLATFORM !=
Platform::CPU_SIMD || std::is_same_v<T,double> || std::is_same_v<T,float>,
485 "SIMD blocks must use either single or double precision as fundamental type");
490 static_assert(DESCRIPTOR::template provides<descriptors::POPULATION>(),
491 "Lattice DESCRIPTOR must provide POPULATION field");
503 template<
typename FIELD_TYPE>
505 template<
typename FIELD_TYPE>
507 template<
typename FIELD_TYPE>
510 template<
typename FIELD>
511 const auto&
getField(FIELD field = FIELD())
const;
512 template<
typename FIELD>
513 auto&
getField(FIELD field = FIELD());
516 return _communicatables.find(field) != _communicatables.end();
519 return *_communicatables.at(field).get();
542 _customCollisionO = op;
552 return _dynamicsMap.
get(iCell);
557 _dynamicsMap.
set(iCell, std::forward<
decltype(promise)>(promise));
558 auto cell = this->
get(iCell);
562 template <
typename FIELD>
565 _data.template forEachCastable<AbstractedConcreteParameters<T,DESCRIPTOR>>([&](
auto* parameters) {
566 auto& params = parameters->asAbstract();
567 if (params.template provides<FIELD>()) {
568 params.template set<FIELD>(value);
574 template <
typename PARAMETER,
typename _DESCRIPTOR, Platform _PLATFORM,
typename FIELD>
577 static_assert(DESCRIPTOR::template size<PARAMETER>() == DESCRIPTOR::template size<FIELD>(),
578 "PARAMETER field size must match FIELD size");
580 static_assert(PLATFORM == _PLATFORM,
"FieldArrayD must be available on PLATFORM");
583 for (
unsigned iD=0; iD < fieldArray.
d; ++iD) {
585 fieldArrayPointers[iD] = fieldArray[iD].deviceData();
587 fieldArrayPointers[iD] = fieldArray[iD].data();
593 template <
typename PARAMETER,
typename _DESCRIPTOR,
typename FIELD>
609 throw std::bad_cast();
620 auto [postProcessorsOfPriority, _] = _postProcessors[stage].try_emplace(promise.priority(),
this);
621 return std::get<1>(*postProcessorsOfPriority).contains(
622 std::forward<
decltype(promise)>(promise));
629 auto [postProcessorsOfPriority, _] = _postProcessors[stage].try_emplace(promise.priority(),
this);
630 std::get<1>(*postProcessorsOfPriority).add(this->getCellId(latticeR),
631 std::forward<
decltype(promise)>(promise));
639 if (!indicator.isEmpty()) {
640 auto [postProcessorsOfPriority, _] = _postProcessors[stage].try_emplace(promise.priority(),
this);
641 std::get<1>(*postProcessorsOfPriority).add(std::forward<
decltype(promise)>(promise));
645 if (indicator(loc)) {
656 auto [postProcessorsOfPriority, _] = _postProcessors[stage].try_emplace(promise.priority(),
this);
657 std::get<1>(*postProcessorsOfPriority).add(std::forward<
decltype(promise)>(promise));
675 return &pops[iPop][iCell];
696 bool*
getBlock(std::size_t iBlock, std::size_t& sizeBlock,
bool loadingMode)
override;
704template <
typename DESCRIPTOR>
707template <typename DESCRIPTOR>
708class ConcreteBlockLattice<Expr,DESCRIPTOR,Platform::GPU_CUDA>;
714template <typename T, typename DESCRIPTOR, Platform SOURCE, Platform TARGET>
715class HeterogeneousCopyTask;
717template <typename T, typename DESCRIPTOR, Platform PLATFORM>
722#ifdef PARALLEL_MODE_MPI
723 MPI_Comm _mpiCommunicator;
726#ifdef PARALLEL_MODE_MPI
730 std::vector<std::unique_ptr<SendTask>> _sendTasks;
731 std::vector<std::unique_ptr<RecvTask>> _recvTasks;
739#ifdef PARALLEL_MODE_MPI
747#ifdef PARALLEL_MODE_MPI
748 void receive()
override;
749 void send()
override;
750 void unpack()
override;
751 void wait()
override;
753 void copy()
override;
759 std::vector<std::unique_ptr<CopyTask>> _copyTasks;
Representation of the 2D block geometry view – header file.
Definition of a LB cell – header file.
Platform-agnostic interface to concrete host-side field arrays.
virtual Platform getPlatform() const =0
Returns Platform of concrete FieldArrayD.
AnalyticalF are applications from DD to XD, where X is set by the constructor.
Configurable overlap communication neighborhood of a block.
Map between cell indices and concrete dynamics.
void set(std::size_t iCell, DynamicsPromise< T, DESCRIPTOR > &&promise)
Assigns promised dynamics to cell index and updates block masks.
Dynamics< T, DESCRIPTOR > * get(DynamicsPromise< T, DESCRIPTOR > &&promise)
Returns a pointer to dynamics matching the promise.
Representation of a block geometry.
Stub to filter construction on non-lattice descriptors.
virtual void addPostProcessor(std::type_index stage, LatticeR< DESCRIPTOR::d > latticeR, PostProcessorPromise< T, DESCRIPTOR > &&promise)=0
Schedule post processor for application to latticeR in stage.
ConstCell< T, DESCRIPTOR > get(LatticeR< DESCRIPTOR::d > loc) const
Get ConstCell interface for location loc.
LatticeStatistics< T > * _statistics
bool isIntrospectable() const
void setParameter(FieldD< T, DESCRIPTOR, FIELD > value)
Set value of parameter FIELD for any dynamics that provide it.
virtual void writeOperatorAsCSV(std::ostream &) const =0
Prints CSV-structured list of all used operators.
const Platform _platform
Platform used by the derived concrete lattice.
virtual void setProcessingContext(ProcessingContext)=0
Set processing context.
bool _statisticsEnabled
True if statistics are gathered during collide.
virtual void addPostProcessor(std::type_index stage, BlockIndicatorF< T, DESCRIPTOR::d > &indicator, PostProcessorPromise< T, DESCRIPTOR > &&promise)=0
Schedule post processor for application to indicated cells in stage.
Platform getPlatform() const
Return platform used to process lattice.
bool _introspectable
True for lattice that can be introspected.
virtual void writeDescription(std::ostream &) const =0
Prints human-readable summary of all used dynamics and post processors.
virtual bool hasPostProcessor(std::type_index stage, PostProcessorPromise< T, DESCRIPTOR > &&promise)=0
Returns true if stage contains post processor.
void postProcess()
Execute post processors of STAGE.
auto & getField(FIELD field=FIELD{})
Return abstract interface for FIELD array.
const auto & getData(FIELD_TYPE field=FIELD_TYPE{}) const
Return abstract interface for concrete FIELD_TYPE data.
virtual void collide()=0
Execute the collide step on the non-overlapping block cells.
virtual Communicatable & getCommunicatable(std::type_index)=0
ConcreteBlockLattice< T, DESCRIPTOR, PLATFORM > & asConcrete()
void defineDynamics(LatticeR< DESCRIPTOR::d > latticeR, DynamicsPromise< T, DESCRIPTOR > &&promise)
Assign promised DYNAMICS to latticeR.
bool statisticsEnabled() const
std::enable_if_t< sizeof...(R)==DESCRIPTOR::d, Cell< T, DESCRIPTOR > > get(R... latticeR)
Get Cell interface for componentwise location latticeR.
virtual void addPostProcessor(std::type_index stage, PostProcessorPromise< T, DESCRIPTOR > &&promise)=0
Schedule post processor for application to entire block in stage.
void setStatisticsEnabled(bool state)
bool hasData()
Return whether FIELD_TYPE is available / has been allocated.
void setParameter(FieldArrayD< T, _DESCRIPTOR, PLATFORM, FIELD > &fieldArray)
const auto & getField(FIELD field=FIELD{}) const
Return abstract interface for FIELD array.
virtual void setDynamics(CellID iCell, DynamicsPromise< T, DESCRIPTOR > &&)=0
Set dynamics at iCell to promised dynamics.
Cell< T, DESCRIPTOR > get(LatticeR< DESCRIPTOR::d > loc)
Get Cell interface for location loc.
virtual bool hasCommunicatable(std::type_index) const =0
void defineDynamics(LatticeR< DESCRIPTOR::d > latticeR)
Assign DYNAMICS to latticeR.
virtual void stream()=0
Apply the streaming step to the entire block.
void setIntrospectability(bool state)
std::enable_if_t< sizeof...(R)==DESCRIPTOR::d, ConstCell< T, DESCRIPTOR > > get(R... latticeR) const
Get ConstCell interface for componentwise location latticeR.
Cell< T, DESCRIPTOR > get(CellID iCell)
Get Cell interface for index iCell.
virtual Dynamics< T, DESCRIPTOR > * getDynamics(CellID iCell)=0
Return pointer to dynamics at iCell.
std::enable_if_t< sizeof...(R)==DESCRIPTOR::d, Dynamics< T, DESCRIPTOR > * > getDynamics(R... latticeR)
Return pointer to dynamics assigned to latticeR.
virtual void postProcess(std::type_index stage=typeid(stage::PostStream))=0
Execute post processors of stage.
ConstCell< T, DESCRIPTOR > get(CellID iCell) const
Get ConstCell interface for index iCell.
auto & getData(FIELD_TYPE field=FIELD_TYPE{})
Return abstract interface for concrete FIELD_TYPE data.
virtual void writeDynamicsAsCSV(std::ostream &) const =0
Prints CSV-structured list of all used dynamics.
virtual Vector< T *, DESCRIPTOR::q > getPopulationPointers(CellID iCell)=0
Returns pointers to host-side population locations of iCell.
void setParameter(AbstractFieldArrayD< T, _DESCRIPTOR, FIELD > &fieldArray)
Map of post processors of a single priority and stage.
void forCoreSpatialLocations(F f) const
static constexpr unsigned d
Wrapper for a local homogeneous CPU block communication request.
Implementation of BlockLattice on a concrete PLATFORM.
void collide() override
Apply collision step of non-overlap interior.
bool hasCommunicatable(std::type_index field) const override
void writeOperatorAsCSV(std::ostream &clout) const override
Prints CSV-structured list of all used operators.
void setParameter(AbstractFieldArrayD< T, _DESCRIPTOR, FIELD > &abstractFieldArray)
bool hasPostProcessor(std::type_index stage, PostProcessorPromise< T, DESCRIPTOR > &&promise) override
Returns true if stage contains post processor.
void postLoad() override
Reinit population structure after deserialization.
bool * getBlock(std::size_t iBlock, std::size_t &sizeBlock, bool loadingMode) override
Return a pointer to the memory of the current block and its size for the serializable interface.
void writeDescription(std::ostream &clout) const override
Prints human-readable summary of all used dynamics and post processors.
std::size_t getNblock() const override
Number of data blocks for the serializable interface.
ConcreteBlockLattice(Vector< int, DESCRIPTOR::d > size, int padding=0)
auto & getDataRegistry()
Return reference to Data's FieldTypeRegistry.
void stream() override
Perform propagation step on the whole block.
BlockDynamicsMap< T, DESCRIPTOR, PLATFORM > & getDynamicsMap()
Vector< T *, DESCRIPTOR::q > getPopulationPointers(CellID iCell) override
Return pointers to population values of cell index iCell.
std::size_t getSerializableSize() const override
Binary size for the serializer.
void writeDynamicsAsCSV(std::ostream &clout) const override
Prints CSV-structured list of all used dynamics.
void addPostProcessor(std::type_index stage, BlockIndicatorF< T, DESCRIPTOR::d > &indicator, PostProcessorPromise< T, DESCRIPTOR > &&promise) override
Schedule post processor for application to indicated cells in stage.
Dynamics< T, DESCRIPTOR > * getDynamics(CellID iCell) override
Get reference to dynamics of cell by index.
void setParameter(FieldArrayD< T, _DESCRIPTOR, _PLATFORM, FIELD > &fieldArray)
void setProcessingContext(ProcessingContext context) override
Set processing context.
void addPostProcessor(std::type_index stage, LatticeR< DESCRIPTOR::d > latticeR, PostProcessorPromise< T, DESCRIPTOR > &&promise) override
Schedule post processor for application to latticeR in stage.
void addPostProcessor(std::type_index stage, PostProcessorPromise< T, DESCRIPTOR > &&promise) override
Schedule post processor for application to entire block in stage.
void setDynamics(CellID iCell, DynamicsPromise< T, DESCRIPTOR > &&promise) override
Set dynamics at iCell to promised dynamics.
ConcreteData< T, DESCRIPTOR, PLATFORM > & getData()
Communicatable & getCommunicatable(std::type_index field) override
static constexpr Platform platform
const auto & getField(FIELD field=FIELD()) const
void setParameter(FieldD< T, DESCRIPTOR, FIELD > value)
void setCollisionO(std::function< void(ConcreteBlockLattice &)> &&op)
Replace default collision logic of BlockDynamicsMap.
Storage of any FIELD_TYPE data on PLATFORM.
void setProcessingContext(ProcessingContext context) override
Set processing context of all managed fields.
auto & getRegistry()
Expose FieldTypeRegistry for device-support.
Highest-level interface to read-only Cell data.
Factory for instances of a specific Dynamics type.
SoA storage for instances of a single FIELD.
Base class for all LoadBalancer.
Factory for instances of a specific OPERATOR type.
Base class for serializable objects of constant size. For dynamic size use BufferSerializable.
Communication-free negotation of unique tags for inter-cuboid communication.
Super class maintaining block lattices for a cuboid decomposition.
Interface for post-processing steps – header file.
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.
ProcessingContext
OpenLB processing contexts.
@ Simulation
Data available on host for e.g. functor evaluation.
std::conditional_t< D==2, BlockF2D< T >, BlockF3D< T > > BlockF
Platform
OpenLB execution targets.
@ CPU_SIMD
Basic scalar CPU.
@ GPU_CUDA
Vector CPU (AVX2 / AVX-512 collision)
std::conditional_t< D==2, BlockIndicatorF2D< T >, BlockIndicatorF3D< T > > BlockIndicatorF
std::conditional_t< D==2, IndicatorF2D< T >, IndicatorF3D< T > > IndicatorF
DynamicsPromise(meta::id< DYNAMICS >) -> DynamicsPromise< typename DYNAMICS::value_t, typename DYNAMICS::descriptor_t >
@ PerBlock
Per-block application, i.e. OPERATOR::apply is passed a ConcreteBlockLattice.
void initialize(int *argc, char ***argv, bool multiOutput, bool verbose)
Initialize OpenLB.
Interface for post-processing steps – header file.
Describe FieldArray of a FIELD in Data.
Generic communicator for the overlap neighborhood of a block.
Curried ConcreteBlockLattice template for use in callUsingConcretePlatform.
Interface for per-cell dynamics.
Communication after propagation.