ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
LBFluidNode.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2021-2023 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#include "config/config.hpp"
21
22#ifdef WALBERLA
23
24#include "LBFluidNode.hpp"
25
26#include <utils/Vector.hpp>
27#include <utils/matrix.hpp>
29
30#include <boost/mpi/collectives/all_reduce.hpp>
31#include <boost/mpi/communicator.hpp>
32
33#include <optional>
34#include <string>
35#include <vector>
36
38
39static bool is_boundary_all_reduce(boost::mpi::communicator const &comm,
40 std::optional<bool> const &is_boundary) {
41 return boost::mpi::all_reduce(comm, is_boundary ? *is_boundary : false,
42 std::logical_or<>());
43}
44
45Variant LBFluidNode::do_call_method(std::string const &name,
46 VariantMap const &params) {
47 if (name == "set_velocity_at_boundary") {
48 if (is_none(params.at("value"))) {
49 m_lb_fluid->remove_node_from_boundary(m_index);
50 } else {
51 auto const u =
52 get_value<Utils::Vector3d>(params, "value") * m_conv_velocity;
53 m_lb_fluid->set_node_velocity_at_boundary(m_index, u);
54 }
55 m_lb_fluid->ghost_communication();
56 m_lb_fluid->reallocate_ubb_field();
57 return {};
58 }
59 if (name == "get_velocity_at_boundary") {
60 auto const boundary_opt = m_lb_fluid->get_node_is_boundary(m_index);
61 if (is_boundary_all_reduce(context()->get_comm(), boundary_opt)) {
62 auto const result = m_lb_fluid->get_node_velocity_at_boundary(m_index);
63 return Utils::Mpi::reduce_optional(context()->get_comm(), result) /
64 m_conv_velocity;
65 }
66 return Variant{None{}};
67 }
68 if (name == "get_density") {
69 auto const result = m_lb_fluid->get_node_density(m_index);
70 return Utils::Mpi::reduce_optional(context()->get_comm(), result) /
71 m_conv_dens;
72 }
73 if (name == "set_density") {
74 auto const dens = get_value<double>(params, "value");
75 m_lb_fluid->set_node_density(m_index, dens * m_conv_dens);
76 m_lb_fluid->ghost_communication();
77 return {};
78 }
79 if (name == "get_population") {
80 auto const result = m_lb_fluid->get_node_population(m_index);
81 return Utils::Mpi::reduce_optional(context()->get_comm(), result);
82 }
83 if (name == "set_population") {
84 auto const pop = get_value<std::vector<double>>(params, "value");
85 m_lb_fluid->set_node_population(m_index, pop);
86 m_lb_fluid->ghost_communication();
87 return {};
88 }
89 if (name == "get_velocity") {
90 auto const result = m_lb_fluid->get_node_velocity(m_index);
91 return Utils::Mpi::reduce_optional(context()->get_comm(), result) /
92 m_conv_velocity;
93 }
94 if (name == "set_velocity") {
95 auto const u =
96 get_value<Utils::Vector3d>(params, "value") * m_conv_velocity;
97 m_lb_fluid->set_node_velocity(m_index, u);
98 m_lb_fluid->ghost_communication();
99 return {};
100 }
101 if (name == "get_is_boundary") {
102 auto const result = m_lb_fluid->get_node_is_boundary(m_index);
103 return Utils::Mpi::reduce_optional(context()->get_comm(), result);
104 }
105 if (name == "get_boundary_force") {
106 auto const boundary_opt = m_lb_fluid->get_node_is_boundary(m_index);
107 if (is_boundary_all_reduce(context()->get_comm(), boundary_opt)) {
108 auto result = m_lb_fluid->get_node_boundary_force(m_index);
109 return Utils::Mpi::reduce_optional(context()->get_comm(), result) /
110 m_conv_force;
111 }
112 return Variant{None{}};
113 }
114 if (name == "get_pressure_tensor" or name == "get_pressure_tensor_neq") {
115 auto const result = m_lb_fluid->get_node_pressure_tensor(m_index);
116 auto value = std::optional<std::vector<double>>{};
117 if (result) {
118 value = (*result / m_conv_press).as_vector();
119 }
120 auto vec = Utils::Mpi::reduce_optional(context()->get_comm(), value);
121 if (context()->is_head_node()) {
122 if (name == "get_pressure_tensor_neq") {
123 auto constexpr c_sound_sq = 1. / 3.;
124 auto const density = m_lb_fluid->get_density();
125 auto const diagonal_term = density * c_sound_sq / m_conv_press;
126 vec[0] -= diagonal_term;
127 vec[4] -= diagonal_term;
128 vec[8] -= diagonal_term;
129 }
130 auto tensor = Utils::Matrix<double, 3, 3>{};
131 std::copy(vec.begin(), vec.end(), tensor.m_data.begin());
132 return std::vector<Variant>{tensor.row<0>().as_vector(),
133 tensor.row<1>().as_vector(),
134 tensor.row<2>().as_vector()};
135 }
136 return {};
137 }
138 if (name == "get_last_applied_force") {
139 auto const result = m_lb_fluid->get_node_last_applied_force(m_index);
140 return Utils::Mpi::reduce_optional(context()->get_comm(), result) /
141 m_conv_force;
142 }
143 if (name == "set_last_applied_force") {
144 auto const f = get_value<Utils::Vector3d>(params, "value");
145 m_lb_fluid->set_node_last_applied_force(m_index, f * m_conv_force);
146 m_lb_fluid->ghost_communication();
147 return {};
148 }
149 if (name == "get_lattice_speed") {
150 return 1. / m_conv_velocity;
151 }
152
153 return {};
154}
155
156} // namespace ScriptInterface::walberla
157
158#endif // WALBERLA
Vector implementation and trait types for boost qvm interoperability.
float f[3]
float u[3]
Type to indicate no value in Variant.
boost::string_ref name() const
Context * context() const
Responsible context.
Variant do_call_method(std::string const &name, VariantMap const &params) override
This file contains the defaults for ESPResSo.
Matrix implementation and trait types for boost qvm interoperability.
static bool is_boundary_all_reduce(boost::mpi::communicator const &comm, std::optional< bool > const &is_boundary)
std::unordered_map< std::string, Variant > VariantMap
Definition Variant.hpp:82
boost::make_recursive_variant< None, bool, int, std::size_t, double, std::string, ObjectRef, Utils::Vector3b, Utils::Vector3i, Utils::Vector2d, Utils::Vector3d, Utils::Vector4d, std::vector< int >, std::vector< double >, std::vector< boost::recursive_variant_ >, std::unordered_map< int, boost::recursive_variant_ >, std::unordered_map< std::string, boost::recursive_variant_ > >::type Variant
Possible types for parameters.
Definition Variant.hpp:80
bool is_none(Variant const &v)
Definition Variant.hpp:128
T reduce_optional(boost::mpi::communicator const &comm, std::optional< T > const &result)
Reduce an optional on the head node.
static SteepestDescentParameters params
Currently active steepest descent instance.
Matrix representation with static size.
Definition matrix.hpp:65