#pragma once #include "macroscopic.hpp" #include "component.hpp" #include "equilibrium.hpp" namespace kel { namespace lbm { namespace cmpt { struct PSM {}; } /** * PSM collision operator for LBM */ template class component { private: saw::data> relaxation_; saw::data> frequency_; public: component( saw::data> relaxation__ ): relaxation_{relaxation__} { saw::data> one; frequency_ = one / relaxation_; } template void apply(const saw::data& field, const saw::data& macros, saw::data> index, saw::data time_step) const { using dfi = df_info; bool is_even = ((time_step.get() % 2) == 0); auto& dfs_old_f = (is_even) ? field.template get<"dfs_old">() : field.template get<"dfs">(); auto& porous = field.template get<"porosity">(); auto& rho_f = macros.template get<"density">(); auto& vel_f = macros.template get<"velocity">(); saw::data>& rho = rho_f.at(index); saw::data>& vel = vel_f.at(index); compute_rho_u(dfs_old_f.at(index),rho,vel); auto eq = equilibrium(rho,vel); saw::data> one; one.at({}) = 1.0; auto flip_porous = one - porous; auto& dfs = dfs_old_f.at(index); auto dfs_cpy = dfs; for(uint64_t i = 0u; i < Descriptor::Q; ++i){ uint64_t i_opp = dfi::opposite_index[i]; dfs.at({i}) = dfs_cpy.at({i}) + frequency_ * (eq.at(i) - dfs_cpy.at({i})) * flip_porous + (dfs_cpy.at({i_opp}) - dfs_cpy.at({i}) ) * porous; } } }; } }