ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
LBVTK.impl.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2019-2026 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#pragma once
21
22/**
23 * @file
24 * Out-of-class VTK writer registration definition for
25 * @ref walberla::LBWalberlaImpl.
26 */
27
28#include <memory>
29#include <optional>
30#include <string>
31
32namespace walberla {
33
34/**
35 * @brief Base class for LB field VTK writers.
36 * Provides unit conversion and field access for cell-based VTK output.
37 * On GPU builds, the GPU field is copied to a CPU mirror before writing.
38 * @tparam FloatType Internal LB precision (float or double).
39 * @tparam Field_T waLBerla field type to read from.
40 * @tparam F_SIZE_ARG Number of components per cell (1, 3, or 9).
41 * @tparam OutputType VTK output precision (default: float).
42 */
43template <typename FloatType, typename Field_T, uint_t F_SIZE_ARG,
44 typename OutputType>
45class VTKWriter : public vtk::BlockCellDataWriter<OutputType, F_SIZE_ARG> {
46public:
47 VTKWriter(ConstBlockDataID const &block_id, std::string const &id,
48 FloatType unit_conversion)
49 : vtk::BlockCellDataWriter<OutputType, F_SIZE_ARG>(id),
51
52protected:
53 void configure() override {
55 m_field = this->block_->template getData<Field_T>(m_block_id);
56 }
57
59 Field_T const *m_field;
60 FloatType const m_conversion;
61};
62
63template <typename FloatType, typename PdfField, typename OutputType = float>
64class DensityVTKWriter : public VTKWriter<FloatType, PdfField, 1u, OutputType> {
65public:
67 using Base::Base;
68 using Base::evaluate;
69
70protected:
72 cell_idx_t const z, cell_idx_t const) override {
74 auto const density =
75 lbm::accessor::Density::get(this->m_field, 1., {x, y, z});
77 }
78};
79
80template <typename FloatType, typename VectorField, typename OutputType = float>
82 : public VTKWriter<FloatType, VectorField, 3u, OutputType> {
83public:
85 using Base::Base;
86 using Base::evaluate;
87
88protected:
90 cell_idx_t const z, cell_idx_t const f) override {
92 auto const velocity = lbm::accessor::Vector::get(this->m_field, {x, y, z});
94 }
95};
96
97template <typename FloatType, typename PdfField, typename OutputType = float>
99 : public VTKWriter<FloatType, PdfField, 9u, OutputType> {
100public:
102 using Base::Base;
103 using Base::evaluate;
104
110
111protected:
113 cell_idx_t const z, cell_idx_t const f) override {
115 auto const pressure =
116 lbm::accessor::PressureTensor::get(this->m_field, 1., {x, y, z});
117 auto const revert_factor =
118 (f == 0 or f == 4 or f == 8) ? FloatType{1} : m_off_diag_factor;
119 return numeric_cast<OutputType>(this->m_conversion * revert_factor *
120 pressure[uint_c(f)]);
121 }
122 FloatType const m_off_diag_factor;
123};
124
125template <typename FloatType, lbmpy::Arch Architecture>
127 walberla::vtk::VTKOutput &vtk_obj, LatticeModel::units_map const &units,
128 int flag_observables) {
129#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
130 auto const allocate_cpu_field_if_empty =
131 [&]<typename Field>(auto const &blocks, std::string name,
132 std::optional<BlockDataID> &cpu_field) {
133 if (not cpu_field) {
134 cpu_field = field::addToStorage<Field>(
135 blocks, name, FloatType{0}, field::fzyx,
136 m_lattice->get_ghost_layers(), m_host_field_allocator);
137 }
138 };
139#endif
140 if (flag_observables & static_cast<int>(OutputVTK::density)) {
141 auto const unit_conversion =
142 FloatType_c(zero_centered_to_md(units.at("density")));
143#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
144 if constexpr (Architecture == lbmpy::Arch::GPU) {
145 auto const &blocks = m_lattice->get_blocks();
147 blocks, "pdfs_cpu", m_pdf_cpu_field_id);
148 vtk_obj.addBeforeFunction(gpu::fieldCpyFunctor<PdfFieldCpu, PdfField>(
149 blocks, *m_pdf_cpu_field_id, m_pdf_field_id));
150 }
151#endif
152 vtk_obj.addCellDataWriter(
154 m_pdf_field_id, "density", unit_conversion));
155 }
156 if (flag_observables & static_cast<int>(OutputVTK::velocity_vector)) {
157 auto const unit_conversion = FloatType_c(units.at("velocity"));
158#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
159 if constexpr (Architecture == lbmpy::Arch::GPU) {
160 auto const &blocks = m_lattice->get_blocks();
162 blocks, "vel_cpu", m_vel_cpu_field_id);
163 vtk_obj.addBeforeFunction(
164 gpu::fieldCpyFunctor<VectorFieldCpu, VectorField>(
165 blocks, *m_vel_cpu_field_id, m_velocity_field_id));
166 }
167#endif
168 vtk_obj.addCellDataWriter(
170 m_velocity_field_id, "velocity_vector", unit_conversion));
171 }
172 if (flag_observables & static_cast<int>(OutputVTK::pressure_tensor)) {
173 auto const unit_conversion =
174 FloatType_c(zero_centered_to_md(units.at("pressure")));
175#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
176 if constexpr (Architecture == lbmpy::Arch::GPU) {
177 auto const &blocks = m_lattice->get_blocks();
179 blocks, "pdfs_cpu", m_pdf_cpu_field_id);
180 vtk_obj.addBeforeFunction(gpu::fieldCpyFunctor<PdfFieldCpu, PdfField>(
181 blocks, *m_pdf_cpu_field_id, m_pdf_field_id));
182 }
183#endif
184 vtk_obj.addCellDataWriter(
186 m_pdf_field_id, "pressure_tensor", unit_conversion,
187 pressure_tensor_correction_factor()));
188 }
189}
190
191} // namespace walberla
std::unordered_map< std::string, double > units_map
OutputType evaluate(cell_idx_t const x, cell_idx_t const y, cell_idx_t const z, cell_idx_t const) override
void register_vtk_field_writers(walberla::vtk::VTKOutput &vtk_obj, LatticeModel::units_map const &units, int flag_observables) override
OutputType evaluate(cell_idx_t const x, cell_idx_t const y, cell_idx_t const z, cell_idx_t const f) override
PressureTensorVTKWriter(ConstBlockDataID const &block_id, std::string const &id, FloatType unit_conversion, FloatType off_diag_factor)
Base class for LB field VTK writers.
ConstBlockDataID const m_block_id
FloatType const m_conversion
void configure() override
Field_T const * m_field
VTKWriter(ConstBlockDataID const &block_id, std::string const &id, FloatType unit_conversion)
OutputType evaluate(cell_idx_t const x, cell_idx_t const y, cell_idx_t const z, cell_idx_t const f) override
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
double get(GhostLayerField< double, uint_t{19u}> const *pdf_field, double const density, Cell const &cell)
auto get(GhostLayerField< double, uint_t{19u}> const *pdf_field, double const density, Cell const &cell)
auto get(GhostLayerField< double, uint_t{3u}> const *vec_field, Cell const &cell)
\file PackInfoPdfDoublePrecision.cpp \author pystencils
static Utils::Vector3d velocity(Particle const &p_ref, Particle const &p_vs)
Velocity of the virtual site.
Definition relative.cpp:64