#pragma once #include #include #include namespace kel { namespace lbm { namespace sch { using namespace saw::schema; template struct Descriptor { static constexpr uint64_t D = DV; static constexpr uint64_t Q = QV; }; 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; }; } template class df_info{}; template class df_info> { public: using Descriptor = sch::Descriptor<1,3>; static constexpr uint64_t D = 1u; static constexpr uint64_t Q = 3u; static constexpr std::array,Q> directions = {{ { 0}, {-1}, { 1} }}; static constexpr std::array::type, Q> weights = { 2./3., 1./6., 1./6. }; static constexpr std::array opposite_index = { 0,2,1 }; static constexpr typename saw::native_data_type::type inv_cs2 = 3.0; static constexpr typename saw::native_data_type::type cs2 = 1./3.; }; /** * D2Q5 Descriptor */ template class df_info> { public: using Descriptor = sch::Descriptor<2,5>; static constexpr uint64_t D = 2u; static constexpr uint64_t Q = 5u; static constexpr std::array, Q> directions = {{ { 0, 0}, {-1, 0}, { 1, 0}, { 0,-1}, { 0, 1}, }}; static constexpr std::array::type,Q> weights = { 1./3., 1./6., 1./6., 1./6., 1./6. }; static constexpr std::array opposite_index = { 0, 2, 1, 4, 3 }; static constexpr typename saw::native_data_type::type inv_cs2 = 3.0; static constexpr typename saw::native_data_type::type cs2 = 1./3.; }; template class df_info> { public: using Descriptor = sch::Descriptor<2,9>; static constexpr uint64_t D = 2u; static constexpr uint64_t Q = 9u; static constexpr std::array, Q> directions = {{ { 0, 0}, {-1, 0}, { 1, 0}, { 0,-1}, { 0, 1}, {-1,-1}, { 1, 1}, {-1, 1}, { 1,-1} }}; static constexpr std::array::type,Q> weights = { 4./9., 1./9., 1./9., 1./9., 1./9., 1./36., 1./36., 1./36., 1./36. }; static constexpr std::array opposite_index = { 0, 2, 1, 4, 3, 6, 5, 8, 7 }; static constexpr typename saw::native_data_type::type inv_cs2 = 3.0; static constexpr typename saw::native_data_type::type cs2 = 1./3.; }; /* template class df_info> { public: using Descriptor = sch::Descriptor<3,27>; static constexpr uint64_t D = 3u; static constexpr uint64_t Q = 27u; static constexpr std::array, Q> directions = {{ { 0, 0, 0}, {-1, 0, 0}, { 1, 0, 0}, // Expand into 2D { 0, -1, 0}, {-1, -1, 0}, { 1, -1, 0}, { 0, 1, 0}, {-1, 1, 0}, { 1, 1, 0}, // Expand into 3D { 0, 0, -1}, {-1, 0, -1}, { 1, 0, -1}, { 0, -1, -1}, {-1, -1, -1}, { 1, -1, -1}, { 0, 1, -1}, {-1, 1, -1}, { 1, 1, -1}, { 0, 0, 1}, {-1, 0, 1}, { 1, 0, 1}, { 0, -1, 1}, {-1, -1, 1}, { 1, -1, 1}, { 0, 1, 1}, {-1, 1, 1}, { 1, 1, 1} }}; static constexpr std::array::type,Q> weights = { 8./27., 1./9., 1./9., 1./9., 1./9., 1./36., 1./36., 1./36., 1./36. }; static constexpr std::array opposite_index = { 0, 2, 1, 4, 3, 6, 5, 8, 7 }; static constexpr typename saw::native_data_type::type inv_cs2 = 3.0; static constexpr typename saw::native_data_type::type cs2 = 1./3.; }; */ 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; } }; 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(); } }; }