#pragma once #include #include #include #include "descriptor/d1q3.hpp" #include "descriptor/d2q5.hpp" #include "descriptor/d2q9.hpp" #include "descriptor/d3q19.hpp" #include "descriptor/d3q27.hpp" namespace kel { namespace lbm { namespace sch { using namespace saw::schema; template struct Cell { using Descriptor = Desc; static constexpr uint64_t SC = SC_V; static constexpr uint64_t DC = DC_V; static constexpr uint64_t QC = QC_V; static constexpr uint64_t Size = SC + Desc::D * DC + Desc::Q * QC; }; template struct CellField{ using Descriptor = Desc; }; template struct CellField< Desc, Struct< Member... > > { using Descriptor = Desc; }; template struct CellFieldStruct { using Descriptor = Desc; // using MetaSchema = FixedArray; }; } /* namespace impl { template struct df_ct_helper { template static constexpr uint64_t apply_i(const std::array,Desc::Q>& dirs, const std::array& inp){ if constexpr ( i < Desc::Q ){ for(uint64_t j = 0u; j < Desc::D; ++j){ } } return 0u; } }; } */ template class cell_schema_builder { private: saw::schema_factory factory_struct_; public: cell_schema_builder() = default; cell_schema_builder(saw::schema_factory inp): factory_struct_{inp} {} /* template constexpr auto require() const noexcept { return {factory_struct_.add_maybe()}; } */ }; } } namespace saw { template struct meta_schema> { using MetaSchema = schema::Void; using Schema = kel::lbm::sch::Cell; }; template struct meta_schema> { using MetaSchema = schema::FixedArray; using Schema = kel::lbm::sch::CellField; }; template struct meta_schema>> { using MetaSchema = schema::FixedArray; using Schema = kel::lbm::sch::CellFieldStruct>; }; template class data, Encode> final { public: using Schema = kel::lbm::sch::Cell; using MetaSchema = typename meta_schema::MetaSchema; private: data, Encode> inner_; public: data() = default; data& operator()(const data& index){ return inner_.at(index); } const data& operator()(const data& index)const{ return inner_.at(index); } const data, Encode> copy() const { return *this; } }; /* * Create a cellfield */ template class data, Encode> final { public: using Schema = kel::lbm::sch::CellField; using MetaSchema = typename meta_schema::MetaSchema; private: data, Encode> inner_; public: data() = default; data(const data& inner_meta__): inner_{inner_meta__} {} const data meta() const { return inner_.dims(); } template data get_dim_size() const { static_assert(i < Desc::D, "Not enough dimensions"); return inner_.template get_dim_size(); } const data& operator()(const data, Encode>& index)const{ return inner_.at(index); } data& operator()(const data, Encode>& index){ return inner_.at(index); } const data& at(const data, Encode>& index)const{ return inner_.at(index); } data& at(const data, Encode>& index){ return inner_.at(index); } data internal_size() const { return inner_.internal_size(); } data* internal_data() { return inner_.internal_data(); } }; /** * Is basically a struct, but additionally has members for meta() calls. It technically is a Field of a struct, but organized through a struct of fields. */ template class data>, Encode> final { public: using Schema = kel::lbm::sch::CellFieldStruct>; /// @TODO Add MetaSchema to Schema using MetaSchema = typename meta_schema::MetaSchema; private: static_assert(sizeof...(CellFieldsT) > 0u, ""); data, Encode> inner_; template saw::error_or helper_constructor(const data>& grid_size){ using MemT = saw::parameter_pack_type::type; { inner_.template get() = {grid_size}; } if constexpr (sizeof...(CellFieldsT) > (i+1u)){ return helper_constructor(grid_size); } return saw::make_void(); } public: data() = delete; data(const data>& grid_size__){ auto eov = helper_constructor<0u>(grid_size__); (void)eov; } const data meta() const { using MemT = saw::parameter_pack_type<0u,CellFieldsT...>::type; return inner_.template get().meta(); } template auto& get() { return inner_.template get(); } template const auto& get() const { return inner_.template get(); } }; }