35template <
typename FloatType, lbmpy::Arch Architecture>
36std::optional<Utils::Vector3d>
39 assert(not(consider_ghosts and m_pending_ghost_comm.test(GhostComm::UBB)));
41 if (!bc or !m_boundary->node_is_boundary(node))
44 return {
to_vector3d(m_boundary->get_node_value_at_boundary(node))};
47template <
typename FloatType, lbmpy::Arch Architecture>
51 m_pending_ghost_comm.set(GhostComm::UBB);
57 m_boundary->set_node_value_at_boundary(
58 node, to_vector3<FloatType>(
velocity), *bc);
60 return bc.has_value();
63template <
typename FloatType, lbmpy::Arch Architecture>
64std::vector<std::optional<Utils::Vector3d>>
68 std::vector<std::optional<Utils::Vector3d>> out;
70 get_lattice(), lower_corner, upper_corner,
71 [&](
auto const &,
auto const &bci,
auto const &ci,
72 auto const &block_offset) {
74 out.resize(ci.numCells());
76 auto kernel = [&out,
this](
unsigned const,
unsigned const local_index,
78 if (m_boundary->node_is_boundary(node)) {
80 to_vector3d(m_boundary->get_node_value_at_boundary(node));
82 out[local_index] = std::nullopt;
91template <
typename FloatType, lbmpy::Arch Architecture>
94 std::vector<std::optional<Utils::Vector3d>>
const &
velocity) {
96 m_pending_ghost_comm.set(GhostComm::UBB);
97 auto const &lattice = get_lattice();
99 lattice, lower_corner, upper_corner,
100 [&](
auto &
block,
auto const &bci,
auto const &ci,
101 auto const &block_offset) {
104 auto kernel = [&,
this](
unsigned const,
unsigned const local_index,
107 assert(bc->block->getAABB() ==
block.getAABB());
108 auto const &opt =
velocity[local_index];
110 m_boundary->set_node_value_at_boundary(
111 node, to_vector3<FloatType>(*opt), *bc);
113 m_boundary->remove_node_from_boundary(node, *bc);
121template <
typename FloatType, lbmpy::Arch Architecture>
122std::optional<Utils::Vector3d>
126 if (!bc or !m_boundary->node_is_boundary(node))
129 return get_node_last_applied_force(node,
true);
132template <
typename FloatType, lbmpy::Arch Architecture>
140 m_boundary->remove_node_from_boundary(node, *bc);
142 return bc.has_value();
145template <
typename FloatType, lbmpy::Arch Architecture>
149 assert(not(consider_ghosts and m_pending_ghost_comm.test(GhostComm::UBB)));
154 return {m_boundary->node_is_boundary(node)};
157template <
typename FloatType, lbmpy::Arch Architecture>
162 std::vector<bool> out;
164 get_lattice(), lower_corner, upper_corner,
165 [&](
auto const &,
auto const &bci,
auto const &ci,
166 auto const &block_offset) {
168 out.resize(ci.numCells());
170 auto kernel = [&out,
this](
unsigned const,
unsigned const local_index,
172 out[local_index] = m_boundary->node_is_boundary(node);
180template <
typename FloatType, lbmpy::Arch Architecture>
182 m_boundary->boundary_update();
190template <
typename FloatType, lbmpy::Arch Architecture>
192 if (not m_has_boundaries) {
193 m_has_boundaries =
true;
194 setup_streaming_communicator();
196 m_has_boundaries =
true;
199template <
typename FloatType, lbmpy::Arch Architecture>
201 reset_boundary_handling(get_lattice().get_blocks());
202 m_pending_ghost_comm.set(GhostComm::UBB);
203 ghost_communication();
204 m_has_boundaries =
false;
205 setup_streaming_communicator();
214template <
typename FloatType, lbmpy::Arch Architecture>
216 std::vector<int>
const &raster_flat, std::vector<double>
const &data_flat) {
218 m_pending_ghost_comm.set(GhostComm::UBB);
219 auto const &grid_size = get_lattice().get_grid_dimensions();
222 ghost_communication();
223 reallocate_ubb_field();
227template <
typename FloatType, lbmpy::Arch Architecture>
231 auto const &grid_size = get_lattice().get_grid_dimensions();
232 node[2] = index % grid_size[2];
233 int tmp = index / grid_size[2];
234 node[1] = tmp % grid_size[1];
235 node[0] = tmp / grid_size[1];
243template <
typename FloatType, lbmpy::Arch Architecture>
244Utils::Vector3i LBWalberlaImpl<FloatType, Architecture>::get_neighbor_node(
247 auto const &grid_size = get_lattice().get_grid_dimensions();
248 auto constexpr neighbor_offset = Kernels::DynamicUBB::neighborOffset;
249 for (
int i = 0; i < neighbor.size(); i++) {
251 (node[i] - neighbor_offset[i][dir] + grid_size[i]) % grid_size[i];
262template <
typename FloatType, lbmpy::Arch Architecture>
265 std::vector<int>
const &raster_flat)
const {
267 auto const &grid_size = get_lattice().get_grid_dimensions();
268 for (
auto &
block : *get_lattice().get_blocks()) {
269 auto const offset = get_lattice().get_block_corner(
block,
true);
270 auto const &force_field = m_boundary->get_force_vector(&
block);
271 auto const &index_field = m_boundary->get_index_vector(&
block);
272 for (
int i = 0; i < raster_flat.size(); i++) {
273 if (raster_flat[i] != 0) {
274 auto node = flat_index_to_node(i);
275 if (get_lattice().node_in_local_halo(node)) {
277 node = (node - offset + grid_size) % grid_size;
278 for (
int j = 0; j < index_field.size(); j++) {
279 auto neighbor_node = get_neighbor_node(node, index_field[j].dir);
280 if (index_field[j].x == neighbor_node[0] &&
281 index_field[j].y == neighbor_node[1] &&
282 index_field[j].z == neighbor_node[2]) {
283 force[0] += force_field[j].F_0;
284 force[1] += force_field[j].F_1;
285 force[2] += force_field[j].F_2;
292 return zero_centered_to_md(force);
295template <
typename FloatType, lbmpy::Arch Architecture>
298 Vector3<double> force(0.);
299 for (
auto &
block : *get_lattice().get_blocks()) {
300 force += m_boundary->get_total_force(&
block);
Vector implementation and trait types for boost qvm interoperability.
DEVICE_QUALIFIER constexpr size_type size() const noexcept
Class that runs and controls the LB on waLBerla.
std::vector< std::optional< Utils::Vector3d > > get_slice_velocity_at_boundary(Utils::Vector3i const &lower_corner, Utils::Vector3i const &upper_corner) const override
std::optional< Utils::Vector3d > get_node_velocity_at_boundary(Utils::Vector3i const &node, bool consider_ghosts=false) const override
void reallocate_ubb_field() override
Utils::Vector3d get_boundary_force_from_shape(std::vector< int > const &raster_flat) const override
Total force exerted by the fluid on a subset of boundary nodes.
bool remove_node_from_boundary(Utils::Vector3i const &node) override
std::optional< Utils::Vector3d > get_node_boundary_force(Utils::Vector3i const &node) const override
void set_slice_velocity_at_boundary(Utils::Vector3i const &lower_corner, Utils::Vector3i const &upper_corner, std::vector< std::optional< Utils::Vector3d > > const &velocity) override
Utils::Vector3d get_boundary_force() const override
std::vector< bool > get_slice_is_boundary(Utils::Vector3i const &lower_corner, Utils::Vector3i const &upper_corner) const override
void update_boundary_from_shape(std::vector< int > const &raster_flat, std::vector< double > const &data_flat) override
Set boundary conditions from a rasterized shape.
std::optional< bool > get_node_is_boundary(Utils::Vector3i const &node, bool consider_ghosts=false) const override
void on_boundary_add()
Lazily enable boundary mode on first boundary addition.
bool set_node_velocity_at_boundary(Utils::Vector3i const &node, Utils::Vector3d const &velocity) override
void clear_boundaries() override
static double * block(double *p, std::size_t index, std::size_t size)
\file PackInfoPdfDoublePrecision.cpp \author pystencils
auto to_vector3d(Vector3< T > const &v) noexcept
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.
void for_each_block_in_slice(::LatticeWalberla const &lattice, Utils::Vector3i const &lower_corner, Utils::Vector3i const &upper_corner, auto &&visitor)
Iterate over all local blocks that overlap a given 3D slice, invoking a visitor for each such block.
std::optional< BlockAndCell > get_block_and_cell(::LatticeWalberla const &lattice, signed_integral_vector auto const &node, bool consider_ghost_layers)
std::vector< Utils::Vector3d > fill_3D_vector_array(std::vector< double > const &vec_flat, Utils::Vector3i const &grid_size)
static Utils::Vector3d velocity(Particle const &p_ref, Particle const &p_vs)
Velocity of the virtual site.