26#ifndef BLOCK_LATTICE_H
27#define BLOCK_LATTICE_H
48#ifdef PLATFORM_CPU_SIMD
52#ifdef PLATFORM_GPU_CUDA
69template<
typename T,
typename DESCRIPTOR>
class SuperLattice;
70template<
typename T,
typename DESCRIPTOR>
struct Dynamics;
71template<
typename T,
typename DESCRIPTOR, Platform PLATFORM>
class ConcreteBlockLattice;
74template<
typename T,
typename DESCRIPTOR>
79template <Platform PLATFORM>
85template<
typename T,
typename DESCRIPTOR>
122 template<
typename FIELD_TYPE>
125 return callUsingConcretePlatform<ConcretizableBlockLattice<T,DESCRIPTOR>>(
128 [&](
const auto* lattice) ->
bool {
129 return lattice->template hasData<FIELD_TYPE>();
133 template<
typename FIELD_TYPE>
134 const auto&
getData(FIELD_TYPE field = FIELD_TYPE{})
const
136 return *callUsingConcretePlatform<ConcretizableBlockLattice<T,DESCRIPTOR>>(
139 [&](
const auto* lattice) ->
const auto* {
140 return &(lattice->template getData<FIELD_TYPE>().asAbstract());
145 template<
typename FIELD_TYPE>
146 auto&
getData(FIELD_TYPE field = FIELD_TYPE{})
148 return *callUsingConcretePlatform<ConcretizableBlockLattice<T,DESCRIPTOR>>(
151 [&](
auto* lattice) ->
auto* {
152 return &(lattice->template getData<FIELD_TYPE>().asAbstract());
157 template<
typename FIELD>
164 template<
typename FIELD>
193 template <
typename... R>
200 template <
typename... R>
225 template<
typename DYNAMICS>
233 template <
typename... R>
248 template <
template<
typename,
typename>
typename DYNAMICS>
265 template <
typename DYNAMICS>
278 template <
typename FIELD>
280 callUsingConcretePlatform<ConcretizableBlockLattice<T,DESCRIPTOR>>(
284 lattice->template setParameter<FIELD>(value);
288 template <
typename PARAMETER,
typename FIELD>
290 callUsingConcretePlatform<ConcretizableBlockLattice<T,DESCRIPTOR>>(
294 lattice->template setParameter<PARAMETER>(fieldArray);
297 template <
typename PARAMETER, Platform PLATFORM,
typename FIELD>
299 callUsingConcretePlatform<ConcretizableBlockLattice<T,DESCRIPTOR>>(
303 lattice->template setParameter<PARAMETER>(fieldArray);
332 template <
typename STAGE=stage::PostStream>
337 template <
typename STAGE=stage::PostStream>
342 template <
typename STAGE=stage::PostStream>
351 template <
typename STAGE>
364 template <
typename FIELD>
372 template <
typename FIELD>
379 template <
typename FIELD>
463template<
typename T,
typename DESCRIPTOR, Platform PLATFORM=Platform::CPU_SISD>
471 std::map<std::type_index, std::unique_ptr<Communicatable>> _communicatables;
477 std::map<std::type_index,
487#ifdef PLATFORM_CPU_SIMD
488 static_assert(PLATFORM !=
Platform::CPU_SIMD || std::is_same_v<T,double> || std::is_same_v<T,float>,
489 "SIMD blocks must use either single or double precision as fundamental type");
494 static_assert(DESCRIPTOR::template provides<descriptors::POPULATION>(),
495 "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;
550 return _dynamicsMap.
get(std::forward<
decltype(promise)>(promise));
556 return _dynamicsMap.
get(iCell);
561 _dynamicsMap.set(iCell, std::forward<
decltype(promise)>(promise));
562 auto cell = this->
get(iCell);
567 _dynamicsMap.set(iCell, dynamics);
570 template <
typename FIELD>
573 _data.template forEachCastable<AbstractedConcreteParameters<T,DESCRIPTOR>>([&](
auto* parameters) {
574 auto& params = parameters->asAbstract();
575 if (params.template provides<FIELD>()) {
576 params.template set<FIELD>(value);
582 template <
typename PARAMETER, Platform _PLATFORM,
typename FIELD>
586 static_assert(PLATFORM == _PLATFORM,
"FieldArrayD must be available on PLATFORM");
589 for (
unsigned iD=0; iD < fieldArray.
d; ++iD) {
591 fieldArrayPointers[iD] = fieldArray[iD].deviceData();
593 fieldArrayPointers[iD] = fieldArray[iD].data();
596 setParameter<PARAMETER>(std::move(fieldArrayPointers));
599 template <
typename PARAMETER,
typename FIELD>
603 setParameter<PARAMETER>(fieldArray);
609 auto [postProcessorsOfPriority, _] = _postProcessors[stage].try_emplace(promise.priority(),
this);
610 return std::get<1>(*postProcessorsOfPriority).contains(
611 std::forward<
decltype(promise)>(promise));
619 auto [postProcessorsOfPriority, _] = _postProcessors[stage].try_emplace(promise.priority(),
this);
620 std::get<1>(*postProcessorsOfPriority).add(this->getCellId(latticeR),
621 std::forward<
decltype(promise)>(promise));
630 if (indicator(loc)) {
640 auto [postProcessorsOfPriority, _] = _postProcessors[stage].try_emplace(promise.priority(),
this);
641 std::get<1>(*postProcessorsOfPriority).add(std::forward<
decltype(promise)>(promise));
663 auto& pops = getField<descriptors::POPULATION>();
665 return &pops[iPop][iCell];
682 bool*
getBlock(std::size_t iBlock, std::size_t& sizeBlock,
bool loadingMode)
override;
694template <
typename T,
typename DESCRIPTOR, Platform SOURCE, Platform TARGET>
697template <
typename T,
typename DESCRIPTOR, Platform PLATFORM>
702#ifdef PARALLEL_MODE_MPI
703 MPI_Comm _mpiCommunicator;
706#ifdef PARALLEL_MODE_MPI
710 std::vector<std::unique_ptr<SendTask>> _sendTasks;
711 std::vector<std::unique_ptr<RecvTask>> _recvTasks;
719#ifdef PARALLEL_MODE_MPI
727#ifdef PARALLEL_MODE_MPI
729 void send()
override;
731 void wait()
override;
733 void copy()
override;
737 class HomogeneousCopyTask;
739 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.
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.
Dynamics< T, DESCRIPTOR > * get(DynamicsPromise< T, DESCRIPTOR > &&promise)
Returns a pointer to dynamics matching the promise.
Representation of a block geometry.
Platform-abstracted block lattice for external access and inter-block interaction.
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.
void addPostProcessor(PostProcessor< T, DESCRIPTOR > *postProcessor)
Schedule legacy post processor for application in STAGE.
ConstCell< T, DESCRIPTOR > get(LatticeR< DESCRIPTOR::d > loc) const
Get ConstCell interface for location loc.
LatticeStatistics< T > * _statistics
void addLatticeCoupling(LatticeCouplingGenerator< T, DESCRIPTOR > const &lcGen, std::vector< BlockStructureD< DESCRIPTOR::d > * > partners)
Add a non-local post-processing step (legacy)
void defineDynamics(LatticeR< DESCRIPTOR::d > latticeR, Dynamics< T, DESCRIPTOR > *dynamics)
Assign dynamics to latticeR via pointer (legacy)
void setParameter(AbstractFieldArrayD< T, DESCRIPTOR, FIELD > &fieldArray)
void iniEquilibrium(BlockIndicatorF< T, DESCRIPTOR::d > &indicator, AnalyticalF< DESCRIPTOR::d, T, T > &rho, AnalyticalF< DESCRIPTOR::d, T, T > &u)
Initialize by equilibrium on a domain described by an indicator.
void setParameter(FieldD< T, DESCRIPTOR, FIELD > value)
Set value of parameter FIELD for any dynamics that provide it.
BlockLattice(Vector< int, DESCRIPTOR::d > size, int padding, Platform platform)
virtual Dynamics< T, DESCRIPTOR > * getDynamics(DynamicsPromise< T, DESCRIPTOR > &&)=0
Return pointer to dynamics yielded by promise.
void defineRho(BlockIndicatorF< T, DESCRIPTOR::d > &indicator, AnalyticalF< DESCRIPTOR::d, T, T > &rho)
Define rho on a domain described by an indicator.
virtual void addPostProcessor(std::type_index stage, PostProcessor< T, DESCRIPTOR > *postProcessor)=0
Schedule legacy post processor for application in stage.
virtual void setProcessingContext(ProcessingContext)=0
Set processing context.
void defineRhoU(BlockIndicatorF< T, DESCRIPTOR::d > &indicator, AnalyticalF< DESCRIPTOR::d, T, T > &rho, AnalyticalF< DESCRIPTOR::d, T, T > &u)
Define rho and u on a domain described by an indicator.
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.
void setParameter(FieldArrayD< T, DESCRIPTOR, PLATFORM, FIELD > &fieldArray)
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.
virtual void addPostProcessor(std::type_index stage, const PostProcessorGenerator< T, DESCRIPTOR > &ppGen)=0
Schedule legacy post processor in stage.
auto & getField(FIELD field=FIELD{})
Return abstract interface for FIELD array.
void defineU(BlockIndicatorF< T, DESCRIPTOR::d > &indicator, AnalyticalF< DESCRIPTOR::d, T, T > &u)
Define u on a domain described by an indicator.
const auto & getData(FIELD_TYPE field=FIELD_TYPE{}) const
Return abstract interface for concrete FIELD_TYPE data.
void iniRegularized(BlockIndicatorF< T, DESCRIPTOR::d > &indicator, AnalyticalF< DESCRIPTOR::d, T, T > &rho, AnalyticalF< DESCRIPTOR::d, T, T > &u, AnalyticalF< DESCRIPTOR::d, T, T > &pi)
Initialize by non- and equilibrium on a domain described by an indicator.
virtual void collide()=0
Execute the collide step on the non-overlapping block cells.
virtual Communicatable & getCommunicatable(std::type_index)=0
void defineDynamics(LatticeR< DESCRIPTOR::d > latticeR, DynamicsPromise< T, DESCRIPTOR > &&promise)
Assign promised DYNAMICS to latticeR.
void defineField(BlockIndicatorF< T, DESCRIPTOR::d > &indicator, AnalyticalF< DESCRIPTOR::d, T, T > &field)
Define a field on a domain described by an indicator.
virtual void setDynamics(CellID iCell, Dynamics< T, DESCRIPTOR > *)=0
bool statisticsEnabled() const
std::enable_if_t< sizeof...(R)==DESCRIPTOR::d, Cell< T, DESCRIPTOR > > get(R... latticeR)
Get Cell interface for componentwise location latticeR.
void stripeOffDensityOffset(T offset)
Subtract the given offset from all densities.
void initialize()
Initialize the lattice cells to become ready for simulation.
virtual void addPostProcessor(std::type_index stage, PostProcessorPromise< T, DESCRIPTOR > &&promise)=0
Schedule post processor for application to entire block in stage.
void executeCoupling()
Execute couplings steps (legacy)
void setStatisticsEnabled(bool state)
bool hasData()
Return whether FIELD_TYPE is available / has been allocated.
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.
Dynamics< T, DESCRIPTOR > * getDynamics()
Return pointer to DYNAMICS (legacy)
virtual void stream()=0
Apply the streaming step to the entire block.
void definePopulations(BlockIndicatorF< T, DESCRIPTOR::d > &indicator, AnalyticalF< DESCRIPTOR::d, T, T > &Pop)
Define a population on a domain described by an indicator.
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.
void addPostProcessor(BlockIndicatorF< T, DESCRIPTOR::d > &indicator, const PostProcessorGenerator< T, DESCRIPTOR > &ppGen)
Schedule legacy post processor for application to indicated cells in STAGE.
LatticeStatistics< T > & getStatistics()
Return a handle to the LatticeStatistics object.
void addPostProcessor(const PostProcessorGenerator< T, DESCRIPTOR > &ppGen)
Schedule legacy post processor for application in STAGE.
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 addPostProcessor(std::type_index stage, BlockIndicatorF< T, DESCRIPTOR::d > &indicator, const PostProcessorGenerator< T, DESCRIPTOR > &ppGen)=0
Schedule legacy post processor for application to indicated cells in stage.
virtual Vector< T *, DESCRIPTOR::q > getPopulationPointers(CellID iCell)=0
Returns pointers to host-side population locations of iCell.
Map of post processors of a single priority and stage.
void forCoreSpatialLocations(F f) const
bool isPadding(LatticeR< D > latticeR) const
Return whether location is valid.
CellID getCellId(LatticeR< D > latticeR) const
Get 1D cell ID.
Highest-level interface to Cell data.
static constexpr unsigned d
const auto & getData() const
void collide() override
Apply collision step of non-overlap interior.
bool hasCommunicatable(std::type_index field) const override
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.
std::size_t getNblock() const override
Number of data blocks for the serializable interface.
ConcreteBlockLattice(Vector< int, DESCRIPTOR::d > size, int padding=0)
void setDynamics(CellID iCell, Dynamics< T, DESCRIPTOR > *dynamics) override
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 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.
void setParameter(AbstractFieldArrayD< T, DESCRIPTOR, FIELD > &abstractFieldArray)
Dynamics< T, DESCRIPTOR > * getDynamics(CellID iCell) override
Get reference to dynamics of cell by index.
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.
Communicatable & getCommunicatable(std::type_index field) override
static constexpr Platform platform
void setParameter(FieldArrayD< T, DESCRIPTOR, _PLATFORM, FIELD > &fieldArray)
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.
Dynamics< T, DESCRIPTOR > * getDynamics(DynamicsPromise< T, DESCRIPTOR > &&promise) override
Return pointer to dynamics yielded by promise.
Highest-level interface to read-only Cell data.
Storage of any FIELD_TYPE data on PLATFORM.
void setProcessingContext(ProcessingContext context)
auto & getRegistry()
Expose FieldTypeRegistry for device-support.
Factory for instances of a specific Dynamics type.
SoA storage for instances of a single FIELD.
Wrapper for a local heterogeneous block communication request.
Base class for all LoadBalancer.
Factory for instances of a specific POST_PROCESSOR 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.
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
std::conditional_t< DESCRIPTOR::d==2, LatticeCouplingGenerator2D< T, DESCRIPTOR >, LatticeCouplingGenerator3D< T, DESCRIPTOR > > LatticeCouplingGenerator
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 >
std::conditional_t< DESCRIPTOR::d==2, PostProcessor2D< T, DESCRIPTOR >, PostProcessor3D< T, DESCRIPTOR > > PostProcessor
@ PerBlock
Per-block application, i.e. OPERATOR::apply is passed a ConcreteBlockLattice.
std::conditional_t< DESCRIPTOR::d==2, PostProcessorGenerator2D< T, DESCRIPTOR >, PostProcessorGenerator3D< T, DESCRIPTOR > > PostProcessorGenerator
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.