22#include <blockforest/communication/UniformBufferedScheme.h>
23#include <field/AddToStorage.h>
24#include <field/FlagField.h>
25#include <field/FlagUID.h>
26#include <field/GhostLayerField.h>
27#include <field/communication/PackInfo.h>
28#include <field/vtk/FlagFieldCellFilter.h>
29#include <field/vtk/VTKWriter.h>
30#include <stencil/D3Q27.h>
31#include <waLBerlaDefinitions.h>
32#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
33#include <gpu/AddGPUFieldToStorage.h>
34#include <gpu/HostFieldAllocator.h>
35#include <gpu/communication/MemcpyPackInfo.h>
36#include <gpu/communication/UniformGPUScheme.h>
39#include "../BoundaryHandling.hpp"
40#include "../BoundaryPackInfo.hpp"
41#include "../utils/boundary.hpp"
42#include "../utils/types_conversion.hpp"
44#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
70template <std::size_t FluxCount = 13,
typename FloatType = double,
73#if not defined(WALBERLA_BUILD_WITH_CUDA)
75 "waLBerla was compiled without CUDA support");
77 using ContinuityKernel =
79 using DiffusiveFluxKernelUnthermalized =
80 typename detail::KernelTrait<FloatType,
81 Architecture>::DiffusiveFluxKernel;
82 using DiffusiveFluxKernelThermalized =
typename detail::KernelTrait<
83 FloatType, Architecture>::DiffusiveFluxKernelThermalized;
84 using AdvectiveFluxKernel =
85 typename detail::KernelTrait<FloatType,
86 Architecture>::AdvectiveFluxKernel;
87 using FrictionCouplingKernel =
88 typename detail::KernelTrait<FloatType,
89 Architecture>::FrictionCouplingKernel;
90 using DiffusiveFluxKernelElectrostaticUnthermalized =
91 typename detail::KernelTrait<
92 FloatType, Architecture>::DiffusiveFluxKernelElectrostatic;
93 using DiffusiveFluxKernelElectrostaticThermalized =
94 typename detail::KernelTrait<
95 FloatType, Architecture>::DiffusiveFluxKernelElectrostaticThermalized;
97 using DiffusiveFluxKernel = std::variant<DiffusiveFluxKernelUnthermalized,
98 DiffusiveFluxKernelThermalized>;
99 using DiffusiveFluxKernelElectrostatic =
100 std::variant<DiffusiveFluxKernelElectrostaticUnthermalized,
101 DiffusiveFluxKernelElectrostaticThermalized>;
120 template <
typename FT, lbmpy::Arch AT = lbmpy::Arch::CPU>
struct FieldTrait {
124 template <
class Field>
125 using PackInfo = field::communication::PackInfo<Field>;
126 template <
class Stencil>
128 blockforest::communication::UniformBufferedScheme<Stencil>;
129 template <
class Stencil>
131 blockforest::communication::UniformBufferedScheme<Stencil>;
133 using FlagField = walberla::FlagField<walberla::uint8_t>;
134#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
138 template <
class Field>
139 using MemcpyPackInfo = gpu::communication::MemcpyPackInfo<Field>;
142 template <
typename Stencil>
143 class UniformGPUScheme
144 :
public gpu::communication::UniformGPUScheme<Stencil> {
146 explicit UniformGPUScheme(
auto const &bf)
147 : gpu::communication::UniformGPUScheme<Stencil>(
153 template <
class Field>
using PackInfo = MemcpyPackInfo<Field>;
154 template <
class Stencil>
156 template <
class Stencil>
158 blockforest::communication::UniformBufferedScheme<Stencil>;
160 using GPUField = gpu::GPUField<FloatType>;
181#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
187 return numeric_cast<FloatType>(t);
195 return std::is_same_v<FloatType, double>;
199 FloatType m_diffusion;
204 bool m_friction_coupling;
216#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
217 std::optional<BlockDataID> m_density_cpu_field_id;
218 std::optional<BlockDataID> m_flux_cpu_field_id;
233 std::unique_ptr<DiffusiveFluxKernelElectrostatic>
237#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
238 std::shared_ptr<gpu::HostFieldAllocator<FloatType>> m_host_field_allocator;
256 template <
typename Field>
258 auto const &blocks =
m_lattice->get_blocks();
259 auto const n_ghost_layers =
m_lattice->get_ghost_layers();
261 return field::addToStorage<Field>(blocks, tag, FloatType{value},
262 field::fzyx, n_ghost_layers);
264#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
266 auto field_id = gpu::addGPUFieldToStorage<GPUField>(
267 blocks, tag, Field::F_SIZE, field::fzyx, n_ghost_layers);
268 if constexpr (std::is_same_v<Field, _DensityField>) {
270 auto field =
block->template getData<GPUField>(field_id);
273 }
else if constexpr (std::is_same_v<Field, _FluxField>) {
275 auto field =
block->template getData<GPUField>(field_id);
277 std::array<FloatType, FluxCount>{});
287 auto const [lc, uc] =
m_lattice->get_local_grid_range(
true);
295 auto const [lc, uc] =
m_lattice->get_local_grid_range(
true);
303 typename stencil::D3Q27>;
306 typename stencil::D3Q27>;
311 template <
class Field>
318 double density,
bool advection,
bool friction_coupling,
319 bool thermalized,
unsigned int seed)
321 m_valency(
FloatType_c(valency)), m_ext_efield(ext_efield),
322 m_advection(advection), m_friction_coupling(friction_coupling),
326 auto const &blocks =
m_lattice->get_blocks();
327 auto const n_ghost_layers =
m_lattice->get_ghost_layers();
332 add_to_storage<_FluxField>(
"flux field",
FloatType_c(0.0));
337#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
338 m_host_field_allocator =
339 std::make_shared<gpu::HostFieldAllocator<FloatType>>();
345 set_diffusion_kernels();
350 blocks,
"flag field density", n_ghost_layers);
354 blocks,
"flag field flux", n_ghost_layers);
361 std::make_shared<BoundaryFullCommunicator>(blocks);
365 auto flux_boundary_packinfo = std::make_shared<
378 [[nodiscard]]
double get_kT() const noexcept
override {
return m_kT; }
386 return m_friction_coupling;
392 return static_cast<bool>(
395 [[nodiscard]]
unsigned int get_seed() const noexcept
override {
404 return {
static_cast<uint64_t
>(kernel->getTime_step())};
409 auto visitor = [m_diffusion = m_diffusion](
auto &kernel) {
410 kernel.setD(m_diffusion);
418 std::visit([m_kT = m_kT](
auto &kernel) { kernel.setKt(m_kT); },
425 [m_valency = m_valency](
auto &kernel) { kernel.setZ(m_valency); },
432 m_friction_coupling = friction_coupling;
438 auto const kernel_electrostatic =
439 std::get_if<DiffusiveFluxKernelElectrostaticThermalized>(
442 if (!kernel or !kernel_electrostatic) {
443 throw std::runtime_error(
"This EK instance is unthermalized");
446 static_cast<uint32_t
>(std::numeric_limits<uint_t>::max()));
447 kernel->setTime_step(
static_cast<uint32_t
>(counter));
448 kernel_electrostatic->setTime_step(
static_cast<uint32_t
>(counter));
452 m_ext_efield = field;
455 [
this](
auto &kernel) {
466 (*m_full_communication)();
481 void set_diffusion_kernels() {
482 auto kernel = DiffusiveFluxKernelUnthermalized(
484 m_diffusive_flux = std::make_unique<DiffusiveFluxKernel>(std::move(kernel));
486 auto kernel_electrostatic = DiffusiveFluxKernelElectrostaticUnthermalized(
493 std::make_unique<DiffusiveFluxKernelElectrostatic>(
494 std::move(kernel_electrostatic));
501 auto kernel = DiffusiveFluxKernelThermalized(
503 grid_dim[0], grid_dim[1], grid_dim[2], seed, 0);
505 auto kernel_electrostatic = DiffusiveFluxKernelElectrostaticThermalized(
514 for (
auto &
block : *blocks) {
515 kernel.configure(blocks, &
block);
516 kernel_electrostatic.configure(blocks, &
block);
519 m_diffusive_flux = std::make_unique<DiffusiveFluxKernel>(std::move(kernel));
521 std::make_unique<DiffusiveFluxKernelElectrostatic>(
522 std::move(kernel_electrostatic));
525 void kernel_boundary_density() {
527 (*m_boundary_density)(&
block);
531 void kernel_boundary_flux() {
533 (*m_boundary_flux)(&
block);
537 void kernel_continuity() {
539 (*m_continuity).run(&
block);
543 void kernel_diffusion() {
545 std::visit([&
block](
auto &kernel) { kernel.run(&
block); },
551 kernel->setTime_step(kernel->getTime_step() + 1u);
553 auto *kernel_electrostatic =
554 std::get_if<DiffusiveFluxKernelElectrostaticThermalized>(
556 kernel_electrostatic->setTime_step(kernel_electrostatic->getTime_step() +
561 void kernel_advection(std::size_t
const velocity_id) {
563 BlockDataID(velocity_id));
569 void kernel_friction_coupling(std::size_t
const force_id,
570 double const lb_density) {
571 auto kernel = FrictionCouplingKernel(
579 void kernel_diffusion_electrostatic(std::size_t
const potential_id) {
580 auto const phiID = BlockDataID(potential_id);
581 std::visit([phiID](
auto &kernel) { kernel.setPhiID(phiID); },
585 std::visit([&
block](
auto &kernel) { kernel.run(&
block); },
589 if (
auto *kernel_electrostatic =
590 std::get_if<DiffusiveFluxKernelElectrostaticThermalized>(
592 kernel_electrostatic->setTime_step(kernel_electrostatic->getTime_step() +
597 kernel->setTime_step(kernel->getTime_step() + 1u);
601 void kernel_migration() {}
603 void update_boundary_fields() {
611 auto &vtk_handle = it.second;
612 if (vtk_handle->enabled) {
613 vtk::writeFiles(vtk_handle->ptr)();
614 vtk_handle->execution_count++;
620 void integrate(std::size_t potential_id, std::size_t velocity_id,
621 std::size_t force_id,
double lb_density)
override {
624 update_boundary_fields();
630 if (potential_id == walberla::BlockDataID{}) {
631 throw std::runtime_error(
"Walberla EK: electrostatic potential enabled "
632 "but no field accessible. potential id is " +
633 std::to_string(potential_id));
635 kernel_diffusion_electrostatic(potential_id);
641 kernel_boundary_flux();
644 if (force_id == walberla::BlockDataID{}) {
645 throw std::runtime_error(
"Walberla EK: friction coupling enabled but "
646 "no force field accessible. force_id is " +
647 std::to_string(force_id) +
648 ". Hint: LB may be inactive.");
650 kernel_friction_coupling(force_id, lb_density);
654 if (velocity_id == walberla::BlockDataID{}) {
655 throw std::runtime_error(
"Walberla EK: advection enabled but no "
656 "velocity field accessible. velocity_id is " +
657 std::to_string(velocity_id) +
658 ". Hint: LB may be inactive.");
660 kernel_advection(velocity_id);
661 kernel_boundary_flux();
666 kernel_boundary_density();
674 static_assert(std::is_same_v<std::size_t, walberla::uint_t>);
690 [[nodiscard]] std::optional<double>
692 bool consider_ghosts =
false)
const override {
698 auto const density_field =
703 [[nodiscard]] std::vector<double>
706 std::vector<double> out;
708 uint_t values_size = 0u;
711 if (
auto const ci =
get_interval(lattice, lower_corner, upper_corner)) {
712 out = std::vector<double>(ci->numCells());
716 lattice, lower_corner, upper_corner, block_offset,
block)) {
717 auto const density_field =
720 assert(values.size() == bci->numCells());
722 values_size += bci->numCells();
724 auto kernel = [&values, &out](
unsigned const block_index,
725 unsigned const local_index,
727 out[local_index] = double_c(values[block_index]);
733 assert(values_size == ci->numCells());
740 std::vector<double>
const &
density)
override {
743 if (
auto const ci =
get_interval(lattice, lower_corner, upper_corner)) {
744 assert(
density.size() == ci->numCells());
748 lattice, lower_corner, upper_corner, block_offset,
block)) {
749 auto const density_field =
751 std::vector<FloatType> values(bci->numCells());
753 auto kernel = [&values, &
density](
unsigned const block_index,
754 unsigned const local_index,
756 values[block_index] = numeric_cast<FloatType>(
density[local_index]);
766 [[nodiscard]] std::optional<Utils::Vector3d>
768 bool consider_ghosts =
false)
const override {
774 auto const flux_field =
782 std::vector<double> out;
784 uint_t values_size = 0;
787 if (
auto const ci =
get_interval(lattice, lower_corner, upper_corner)) {
788 out = std::vector<double>(3u * ci->numCells());
792 lattice, lower_corner, upper_corner, block_offset,
block)) {
793 auto const flux_field =
796 assert(values.size() == 3u * bci->numCells());
798 values_size += 3u * bci->numCells();
801 auto kernel = [&values, &out,
this](
unsigned const block_index,
802 unsigned const local_index,
807 for (uint_t f = 0u; f < 3u; ++f) {
808 out[3u * local_index + f] = double_c(vec[f]);
811 for (uint_t f = 0u; f < 3u; ++f) {
812 out[3u * local_index + f] =
813 double_c(values[3u * block_index + f]);
821 assert(values_size == 3u * ci->numCells());
843 node, to_vector3<FloatType>(
flux), *bc);
847 [[nodiscard]] std::optional<Utils::Vector3d>
849 bool consider_ghosts =
false)
const override {
880 [[nodiscard]] std::optional<double>
882 bool consider_ghosts =
false)
const override {
892 std::vector<std::optional<double>>
const &
density)
override {
894 if (
auto const ci =
get_interval(lattice, lower_corner, upper_corner)) {
896 auto const lower_cell = ci->min();
897 auto const upper_cell = ci->max();
899 assert(
density.size() == ci->numCells());
900 for (
auto x = lower_cell.x(); x <= upper_cell.x(); ++x) {
901 for (
auto y = lower_cell.y(); y <= upper_cell.y(); ++y) {
902 for (
auto z = lower_cell.z(); z <= upper_cell.z(); ++z) {
905 auto const &opt = *it;
919 [[nodiscard]] std::vector<std::optional<double>>
923 std::vector<std::optional<double>> out;
925 if (
auto const ci =
get_interval(lattice, lower_corner, upper_corner)) {
927 auto const lower_cell = ci->min();
928 auto const upper_cell = ci->max();
929 auto const n_values = ci->numCells();
930 out.reserve(n_values);
931 for (
auto x = lower_cell.x(); x <= upper_cell.x(); ++x) {
932 for (
auto y = lower_cell.y(); y <= upper_cell.y(); ++y) {
933 for (
auto z = lower_cell.z(); z <= upper_cell.z(); ++z) {
936 out.emplace_back(double_c(
939 out.emplace_back(std::nullopt);
944 assert(out.size() == n_values);
951 std::vector<std::optional<Utils::Vector3d>>
const &
flux)
override {
954 if (
auto const ci =
get_interval(lattice, lower_corner, upper_corner)) {
956 auto const lower_cell = ci->min();
957 auto const upper_cell = ci->max();
958 auto it =
flux.begin();
959 assert(
flux.size() == ci->numCells());
960 for (
auto x = lower_cell.x(); x <= upper_cell.x(); ++x) {
961 for (
auto y = lower_cell.y(); y <= upper_cell.y(); ++y) {
962 for (
auto z = lower_cell.z(); z <= upper_cell.z(); ++z) {
965 auto const &opt = *it;
968 node, to_vector3<FloatType>(*opt), *bc);
979 [[nodiscard]] std::vector<std::optional<Utils::Vector3d>>
983 std::vector<std::optional<Utils::Vector3d>> out;
985 if (
auto const ci =
get_interval(lattice, lower_corner, upper_corner)) {
987 auto const lower_cell = ci->min();
988 auto const upper_cell = ci->max();
989 auto const n_values = ci->numCells();
990 out.reserve(n_values);
991 for (
auto x = lower_cell.x(); x <= upper_cell.x(); ++x) {
992 for (
auto y = lower_cell.y(); y <= upper_cell.y(); ++y) {
993 for (
auto z = lower_cell.z(); z <= upper_cell.z(); ++z) {
999 out.emplace_back(std::nullopt);
1004 assert(out.size() == n_values);
1009 [[nodiscard]] std::vector<bool>
1012 std::vector<bool> out;
1014 if (
auto const ci =
get_interval(lattice, lower_corner, upper_corner)) {
1016 auto const lower_cell = ci->min();
1017 auto const upper_cell = ci->max();
1018 auto const n_values = ci->numCells();
1019 out.reserve(n_values);
1020 for (
auto x = lower_cell.x(); x <= upper_cell.x(); ++x) {
1021 for (
auto y = lower_cell.y(); y <= upper_cell.y(); ++y) {
1022 for (
auto z = lower_cell.z(); z <= upper_cell.z(); ++z) {
1029 assert(out.size() == n_values);
1044 [[nodiscard]] std::optional<bool>
1046 bool consider_ghosts)
const override {
1050 return std::nullopt;
1055 [[nodiscard]] std::optional<bool>
1057 bool consider_ghosts)
const override {
1060 return std::nullopt;
1065 [[nodiscard]] std::optional<bool>
1067 bool consider_ghosts =
false)
const override {
1070 return std::nullopt;
1077 const std::vector<int> &raster_flat,
1078 const std::vector<double> &data_flat)
override {
1087 const std::vector<int> &raster_flat,
1088 const std::vector<double> &data_flat)
override {
1106 [[nodiscard]]
bool is_gpu() const noexcept
override {
1113 vtk_obj.addCellExclusionFilter(fluid_filter);
1117 template <
typename Field_T, u
int_t F_SIZE_ARG,
typename OutputType>
1118 class VTKWriter :
public vtk::BlockCellDataWriter<OutputType, F_SIZE_ARG> {
1120 VTKWriter(ConstBlockDataID
const &block_id, std::string
const &
id,
1121 FloatType unit_conversion)
1122 : vtk::BlockCellDataWriter<OutputType, F_SIZE_ARG>(id),
1128 WALBERLA_ASSERT_NOT_NULLPTR(this->block_);
1137#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
1138 template <
typename OutputType =
float>
1143 using Base::evaluate;
1146 OutputType
evaluate(cell_idx_t
const x, cell_idx_t
const y,
1147 cell_idx_t
const z, cell_idx_t
const)
override {
1148 WALBERLA_ASSERT_NOT_NULLPTR(this->
m_field);
1154 template <
typename OutputType =
float>
1159 using Base::evaluate;
1162 OutputType
evaluate(cell_idx_t
const x, cell_idx_t
const y,
1163 cell_idx_t
const z, cell_idx_t
const)
override {
1164 WALBERLA_ASSERT_NOT_NULLPTR(this->
m_field);
1171#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
1172 template <
typename OutputType =
float>
1173 class FluxVTKWriter :
public VTKWriter<FluxFieldCpu, 3u, OutputType> {
1177 using Base::evaluate;
1180 OutputType
evaluate(cell_idx_t
const x, cell_idx_t
const y,
1181 cell_idx_t
const z, cell_idx_t
const f)
override {
1182 WALBERLA_ASSERT_NOT_NULLPTR(this->
m_field);
1189 template <
typename OutputType =
float>
1194 using Base::evaluate;
1197 OutputType
evaluate(cell_idx_t
const x, cell_idx_t
const y,
1198 cell_idx_t
const z, cell_idx_t
const f)
override {
1199 WALBERLA_ASSERT_NOT_NULLPTR(this->
m_field);
1210 int flag_observables)
override {
1211#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
1212 auto const allocate_cpu_field_if_empty =
1213 [&]<
typename Field>(
auto const &blocks, std::string name,
1214 std::optional<BlockDataID> &cpu_field) {
1215 if (not cpu_field) {
1216 cpu_field = field::addToStorage<Field>(
1217 blocks, name, FloatType{0}, field::fzyx,
1218 m_lattice->get_ghost_layers(), m_host_field_allocator);
1223 auto const unit_conversion =
FloatType_c(units.at(
"density"));
1224#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
1226 auto const &blocks =
m_lattice->get_blocks();
1227 allocate_cpu_field_if_empty.template operator()<DensityFieldCpu>(
1228 blocks,
"density_cpu", m_density_cpu_field_id);
1229 vtk_obj.addBeforeFunction(
1230 gpu::fieldCpyFunctor<DensityFieldCpu, DensityField>(
1233 *m_density_cpu_field_id,
"density", unit_conversion));
1238#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
1243 auto const unit_conversion =
FloatType_c(units.at(
"flux"));
1244#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
1246 auto const &blocks =
m_lattice->get_blocks();
1247 allocate_cpu_field_if_empty.template operator()<FluxFieldCpu>(
1248 blocks,
"flux_cpu", m_flux_cpu_field_id);
1249 vtk_obj.addBeforeFunction(gpu::fieldCpyFunctor<FluxFieldCpu, FluxField>(
1252 *m_flux_cpu_field_id,
"flux", unit_conversion));
1257#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
Vector implementation and trait types for boost qvm interoperability.
Interface of a lattice-based electrokinetic model.
std::map< std::string, std::shared_ptr< VTKHandle > > m_vtk_auto
VTK writers that are executed automatically.
std::unordered_map< std::string, double > units_map
Class that runs and controls the BlockForest in waLBerla.
auto const & get_grid_dimensions() const
walberla::blockforest::StructuredBlockForest Lattice_T
std::pair< Utils::Vector3i, Utils::Vector3i > get_local_grid_range(bool with_halo=false) const
Utils::Vector3i get_block_corner(IBlock const &block, bool lower) const
Boundary class optimized for sparse data.
VTKWriter< DensityField, 1u, OutputType > Base
OutputType evaluate(cell_idx_t const x, cell_idx_t const y, cell_idx_t const z, cell_idx_t const) override
OutputType evaluate(cell_idx_t const x, cell_idx_t const y, cell_idx_t const z, cell_idx_t const f) override
VTKWriter< FluxField, 3u, OutputType > Base
VTKWriter(ConstBlockDataID const &block_id, std::string const &id, FloatType unit_conversion)
ConstBlockDataID const m_block_id
void configure() override
FloatType const m_conversion
Class that runs and controls the EK on waLBerla.
~EKinWalberlaImpl() override=default
void set_slice_flux_boundary(Utils::Vector3i const &lower_corner, Utils::Vector3i const &upper_corner, std::vector< std::optional< Utils::Vector3d > > const &flux) override
void set_kT(double kT) override
std::optional< double > get_node_density_at_boundary(Utils::Vector3i const &node, bool consider_ghosts=false) const override
double get_kT() const noexcept override
std::unique_ptr< DiffusiveFluxKernelElectrostatic > m_diffusive_flux_electrostatic
walberla::FlagField< walberla::uint8_t > FlagField
void set_friction_coupling(bool friction_coupling) override
void set_rng_state(uint64_t counter) override
void integrate(std::size_t potential_id, std::size_t velocity_id, std::size_t force_id, double lb_density) override
bool set_node_density_boundary(Utils::Vector3i const &node, double density) override
void set_slice_density(Utils::Vector3i const &lower_corner, Utils::Vector3i const &upper_corner, std::vector< double > const &density) override
BlockDataID m_density_field_id
std::shared_ptr< FullCommunicator > m_full_communication
std::bitset< GhostComm::SIZE > m_pending_ghost_comm
std::vector< double > get_slice_density(Utils::Vector3i const &lower_corner, Utils::Vector3i const &upper_corner) const override
void update_density_boundary_from_shape(const std::vector< int > &raster_flat, const std::vector< double > &data_flat) override
void update_flux_boundary_from_shape(const std::vector< int > &raster_flat, const std::vector< double > &data_flat) override
std::vector< bool > get_slice_is_boundary(Utils::Vector3i const &lower_corner, Utils::Vector3i const &upper_corner) const override
void set_ext_efield(Utils::Vector3d const &field) override
bool set_node_density(Utils::Vector3i const &node, double density) override
double get_diffusion() const noexcept override
void set_valency(double valency) override
bool is_thermalized() const noexcept override
auto add_to_storage(std::string const tag, FloatType value)
Convenience function to add a field with a custom allocator.
std::optional< double > get_node_density(Utils::Vector3i const &node, bool consider_ghosts=false) const override
std::size_t get_density_id() const noexcept override
unsigned int get_seed() const noexcept override
BlockDataID m_flag_field_flux_id
std::unique_ptr< ContinuityKernel > m_continuity
double get_valency() const noexcept override
typename FieldTrait< FloatType, Architecture >::FluxField FluxField
void clear_flux_boundaries() override
std::shared_ptr< BoundaryModelFlux > m_boundary_flux
void set_slice_density_boundary(Utils::Vector3i const &lower_corner, Utils::Vector3i const &upper_corner, std::vector< std::optional< double > > const &density) override
void reset_flux_boundary_handling(std::shared_ptr< BlockStorage > const &blocks)
bool get_advection() const noexcept override
std::optional< Utils::Vector3d > get_node_flux_vector(Utils::Vector3i const &node, bool consider_ghosts=false) const override
typename FieldTrait< FloatType, Architecture >::template BoundaryCommScheme< typename stencil::D3Q27 > BoundaryFullCommunicator
typename FieldTrait< FloatType, Architecture >::template RegularCommScheme< typename stencil::D3Q27 > FullCommunicator
void reallocate_density_boundary_field()
std::optional< uint64_t > get_rng_state() const override
void set_advection(bool advection) override
BlockDataID m_flag_field_density_id
bool remove_node_from_density_boundary(Utils::Vector3i const &node) override
typename FieldTrait< FloatType, Architecture >::template PackInfo< Field > PackInfo
bool get_friction_coupling() const noexcept override
Utils::Vector3d get_ext_efield() const noexcept override
stencil::D3Q27 Stencil
Stencil for collision and streaming operations.
LatticeWalberla const & get_lattice() const noexcept override
bool remove_node_from_flux_boundary(Utils::Vector3i const &node) override
bool is_double_precision() const noexcept override
void integrate_vtk_writers() override
typename FieldTrait< FloatType, Architecture >::DensityField DensityField
FloatType FloatType_c(T t)
bool is_gpu() const noexcept override
void clear_density_boundaries() override
std::optional< bool > get_node_is_flux_boundary(Utils::Vector3i const &node, bool consider_ghosts) const override
void ghost_communication() override
LatticeWalberla::Lattice_T BlockStorage
Lattice model (e.g.
void ghost_communication_boundary()
void reset_density_boundary_handling(std::shared_ptr< BlockStorage > const &blocks)
std::vector< std::optional< Utils::Vector3d > > get_slice_flux_at_boundary(Utils::Vector3i const &lower_corner, Utils::Vector3i const &upper_corner) const override
ResourceObserver m_mpi_cart_comm_observer
std::vector< std::optional< double > > get_slice_density_at_boundary(Utils::Vector3i const &lower_corner, Utils::Vector3i const &upper_corner) const override
BlockDataID m_flux_field_id
void register_vtk_field_writers(walberla::vtk::VTKOutput &vtk_obj, LatticeModel::units_map const &units, int flag_observables) override
std::optional< Utils::Vector3d > get_node_flux_at_boundary(Utils::Vector3i const &node, bool consider_ghosts=false) const override
std::vector< double > get_slice_flux_vector(Utils::Vector3i const &lower_corner, Utils::Vector3i const &upper_corner) const override
typename FieldTrait< FloatType >::DensityField _DensityField
std::shared_ptr< BoundaryFullCommunicator > m_boundary_communicator
std::optional< bool > get_node_is_density_boundary(Utils::Vector3i const &node, bool consider_ghosts) const override
std::unique_ptr< DiffusiveFluxKernel > m_diffusive_flux
void set_diffusion(double diffusion) override
std::size_t stencil_size() const noexcept override
FlagUID const Boundary_flag
Flag for boundary cells.
bool set_node_flux_boundary(Utils::Vector3i const &node, Utils::Vector3d const &flux) override
void reallocate_flux_boundary_field()
typename FieldTrait< FloatType >::FluxField _FluxField
std::optional< bool > get_node_is_boundary(Utils::Vector3i const &node, bool consider_ghosts=false) const override
std::unique_ptr< BoundaryModelDensity > m_boundary_density
EKinWalberlaImpl(std::shared_ptr< LatticeWalberla > lattice, double diffusion, double kT, double valency, Utils::Vector3d const &ext_efield, double density, bool advection, bool friction_coupling, bool thermalized, unsigned int seed)
std::shared_ptr< LatticeWalberla > m_lattice
Block forest.
FlagUID const Domain_flag
Flag for domain cells, i.e.
void register_vtk_field_filters(walberla::vtk::VTKOutput &vtk_obj) override
Base class for LB field VTK writers.
void setup_boundary_handle(std::shared_ptr< LatticeWalberla > lattice, std::shared_ptr< Boundary_T > boundary)
static double * block(double *p, std::size_t index, std::size_t size)
auto get_vector(GhostLayerField< double, uint_t{13u}> const *flux_field, Cell const &cell)
void initialize(GhostLayerField< double, uint_t{13u}> *flux_field, std::array< double, 13 > const &values)
void initialize(GhostLayerField< double, 1u > *scalar_field, double const &value)
void set(GhostLayerField< double, 1u > *scalar_field, double const &value, Cell const &cell)
auto get(GhostLayerField< double, 1u > const *scalar_field, Cell const &cell)
static FUNC_PREFIX double *RESTRICT const double *RESTRICT const int64_t const int64_t const int64_t const int64_t const int64_t const int64_t const int64_t const int64_t const int64_t const int64_t const uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t seed
\file PackInfoPdfDoublePrecision.cpp \author pystencils
auto to_vector3d(Vector3< T > const &v) noexcept
std::vector< double > fill_3D_scalar_array(std::vector< double > const &vec_flat, Utils::Vector3i const &grid_size)
void set_boundary_from_grid(BoundaryModel &boundary, LatticeWalberla const &lattice, std::vector< int > const &raster_flat, std::vector< DataType > const &data_flat)
void copy_block_buffer(CellInterval const &bci, CellInterval const &ci, Utils::Vector3i const &block_offset, Utils::Vector3i const &lower_corner, auto &&kernel)
Synchronize data between a sliced block and a container.
std::optional< BlockAndCell > get_block_and_cell(::LatticeWalberla const &lattice, signed_integral_vector auto const &node, bool consider_ghost_layers)
Cell to_cell(signed_integral_vector auto const &xyz)
ResourceObserver get_mpi_cart_comm_observer()
Get an observer on waLBerla's MPI Cartesian communicator status.
std::optional< walberla::cell::CellInterval > get_block_interval(::LatticeWalberla const &lattice, Utils::Vector3i const &lower_corner, Utils::Vector3i const &upper_corner, Utils::Vector3i const &block_offset, IBlock const &block)
std::optional< walberla::cell::CellInterval > get_interval(::LatticeWalberla const &lattice, Utils::Vector3i const &lower_corner, Utils::Vector3i const &upper_corner)
std::vector< Utils::Vector3d > fill_3D_vector_array(std::vector< double > const &vec_flat, Utils::Vector3i const &grid_size)
Observer to monitor the lifetime of a shared resource.
blockforest::communication::UniformBufferedScheme< Stencil > RegularCommScheme
GhostLayerField< FT, FluxCount > FluxField
field::communication::PackInfo< Field > PackInfo
GhostLayerField< FT, 1 > DensityField
blockforest::communication::UniformBufferedScheme< Stencil > BoundaryCommScheme
GhostCommFlags
Ghost communication operations.
@ DENS
density communication
@ FLB
flux boundary communication