30#if defined(__CUDACC__)
37#include <blockforest/communication/UniformBufferedScheme.h>
38#include <domain_decomposition/BlockDataID.h>
39#include <field/AddToStorage.h>
40#include <field/GhostLayerField.h>
41#include <field/vtk/VTKWriter.h>
42#include <stencil/D3Q27.h>
43#include <waLBerlaDefinitions.h>
44#if defined(__CUDACC__)
45#include <gpu/AddGPUFieldToStorage.h>
46#include <gpu/FieldAccessor.h>
47#include <gpu/FieldIndexing.h>
48#include <gpu/GPUField.h>
49#include <gpu/HostFieldAllocator.h>
50#include <gpu/Kernel.h>
51#include <gpu/communication/UniformGPUScheme.h>
55#pragma clang diagnostic push
56#pragma clang diagnostic ignored "-Wfloat-conversion"
57#pragma clang diagnostic ignored "-Wimplicit-float-conversion"
58#elif defined(__GNUC__) or defined(__GNUG__)
59#pragma GCC diagnostic push
60#pragma GCC diagnostic ignored "-Wfloat-conversion"
64#pragma clang diagnostic pop
65#elif defined(__GNUC__) or defined(__GNUG__)
66#pragma GCC diagnostic pop
83template <
typename FloatType, lbmpy::Arch Architecture>
86 template <
typename T> FloatType FloatType_c(T t) {
87 return numeric_cast<FloatType>(t);
91 template <
typename FT, lbmpy::Arch AT = lbmpy::Arch::CPU>
struct FieldTrait {
95#if defined(__CUDACC__)
105 BlockDataID m_potential_field_id;
112#if defined(__CUDACC__)
113 m_potential_field_id = gpu::addGPUFieldToStorage<PotentialField>(
114 blocks,
"potential field", 1u, field::fzyx,
116 for (
auto &
block : *blocks) {
117 auto field =
block.template getData<PotentialField>(m_potential_field_id);
121 m_potential_field_id = field::addToStorage<PotentialField>(
122 blocks,
"potential field", FloatType{0}, field::fzyx,
129 [[nodiscard]]
bool is_gpu() const noexcept
override {
134 return std::is_same_v<FloatType, double>;
138 return static_cast<std::size_t
>(m_potential_field_id);
141 [[nodiscard]] std::optional<double>
143 bool consider_ghosts =
false)
override {
149 auto const potential_field =
150 bc->block->template getData<PotentialField>(m_potential_field_id);
161 auto potential_field =
162 bc->block->template getData<PotentialField>(m_potential_field_id);
168 [[nodiscard]] std::vector<double>
171 std::vector<double> out;
173 uint_t values_size{0u};
176 if (
auto const ci =
get_interval(lattice, lower_corner, upper_corner)) {
177 out = std::vector<double>(ci->numCells());
178 for (
auto &
block : *lattice.get_blocks()) {
179 auto const block_offset = lattice.get_block_corner(
block,
true);
181 lattice, lower_corner, upper_corner, block_offset,
block)) {
182 auto const potential_field =
183 block.template getData<PotentialField>(m_potential_field_id);
185 assert(values.size() == bci->numCells());
187 values_size += bci->numCells();
189 auto kernel = [&values, &out](
unsigned const block_index,
190 unsigned const local_index,
192 out[local_index] = double_c(values[block_index]);
198 assert(values_size == ci->numCells());
205 std::vector<double>
const &
potential)
override {
207 if (
auto const ci =
get_interval(lattice, lower_corner, upper_corner)) {
208 assert(
potential.size() == ci->numCells());
209 for (
auto &
block : *lattice.get_blocks()) {
210 auto const block_offset = lattice.get_block_corner(
block,
true);
212 lattice, lower_corner, upper_corner, block_offset,
block)) {
213 auto potential_field =
214 block.template getData<PotentialField>(m_potential_field_id);
215 std::vector<FloatType> values(bci->numCells());
217 auto kernel = [&values, &
potential](
unsigned const block_index,
218 unsigned const local_index,
220 values[block_index] =
221 numeric_cast<FloatType>(
potential[local_index]);
239 for (
auto const &vtk_handle :
m_vtk_auto | std::views::values) {
240 if (vtk_handle->enabled) {
241 vtk::writeFiles(vtk_handle->ptr)();
242 vtk_handle->execution_count++;
248 template <
typename VecType, u
int_t F_SIZE_ARG,
typename OutputType>
249 class VTKWriter :
public vtk::BlockCellDataWriter<OutputType, F_SIZE_ARG> {
251 VTKWriter(ConstBlockDataID
const &block_id, std::string
const &
id,
252 FloatType unit_conversion)
253 : vtk::BlockCellDataWriter<OutputType, F_SIZE_ARG>(id),
257 void configure()
override { WALBERLA_ASSERT_NOT_NULLPTR(this->block_); }
260 cell_idx_t
const z) {
261 return (
static_cast<std::size_t
>(x) *
m_dims[2] *
m_dims[1] +
262 static_cast<std::size_t
>(y) *
m_dims[2] +
263 static_cast<std::size_t
>(z)) *
277 template <
typename OutputType =
float>
279 :
public VTKWriter<std::vector<FloatType>, 1u, OutputType> {
283 using Base::evaluate;
286 OutputType
evaluate(cell_idx_t
const x, cell_idx_t
const y,
287 cell_idx_t
const z, cell_idx_t
const)
override {
288 WALBERLA_ASSERT(!this->
m_content.empty());
297 int flag_observables)
override {
299 auto const unit_conversion = FloatType_c(units.at(
"potential"));
301 WALBERLA_ASSERT_NOT_NULLPTR(blocks);
302 auto potential_writer = make_shared<PotentialVTKWriter<float>>(
303 m_potential_field_id,
"potential", unit_conversion);
304 auto before_function = [
this, blocks, potential_writer]() {
305 for (
auto &
block : *blocks) {
306 auto *potential_field =
307 block.template getData<PotentialField>(m_potential_field_id);
308 auto const bci = potential_field->xyzSize();
309 potential_writer->set_content(
311 potential_writer->set_dims(Vector3<uint_t>(
312 uint_c(bci.xSize()), uint_c(bci.ySize()), uint_c(bci.zSize())));
315 vtk_obj.addBeforeFunction(std::move(before_function));
316 vtk_obj.addCellDataWriter(potential_writer);
Vector implementation and trait types for boost qvm interoperability.
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
auto get_ghost_layers() const
OutputType evaluate(cell_idx_t const x, cell_idx_t const y, cell_idx_t const z, cell_idx_t const) override
VTKWriter(ConstBlockDataID const &block_id, std::string const &id, FloatType unit_conversion)
void configure() override
void set_content(VecType content)
std::size_t get_first_index(cell_idx_t const x, cell_idx_t const y, cell_idx_t const z)
void set_dims(Vector3< uint_t > dims)
bool is_double_precision() const noexcept override
~PoissonSolverNone() override=default
bool is_gpu() const noexcept override
std::size_t get_potential_field_id() const noexcept override
void set_slice_potential(Utils::Vector3i const &lower_corner, Utils::Vector3i const &upper_corner, std::vector< double > const &potential) override
std::vector< double > get_slice_potential(Utils::Vector3i const &lower_corner, Utils::Vector3i const &upper_corner) const override
PoissonSolverNone(std::shared_ptr< LatticeWalberla > lattice)
void reset_charge_field() override
void integrate_vtk_writers() override
void add_charge_to_field(std::size_t id, double valency) override
FieldTrait< FloatType, Architecture >::PotentialField PotentialField
bool set_node_potential(Utils::Vector3i const &node, double potential) override
void setup_fft(bool) override
std::optional< double > get_node_potential(Utils::Vector3i const &node, bool consider_ghosts=false) override
void register_vtk_field_writers(walberla::vtk::VTKOutput &vtk_obj, LatticeModel::units_map const &units, int flag_observables) override
void ghost_communication() override
LatticeWalberla const & get_lattice() const noexcept override
static double * block(double *p, std::size_t index, std::size_t size)
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)
\file PackInfoPdfDoublePrecision.cpp \author pystencils
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)
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)
field::GhostLayerField< FT, 1u > PotentialField