Loading [MathJax]/extensions/TeX/AMSmath.js
ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
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 }
131 std::ranges::copy(vec, 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.
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)
T get_value(Variant const &v)
Extract value of specific type T from a Variant.
std::unordered_map< std::string, Variant > VariantMap
Definition Variant.hpp:69
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:67
bool is_none(Variant const &v)
Definition Variant.hpp:115
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