ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
EKSpeciesNode.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 "EKSpeciesNode.hpp"
25
26#include "LatticeIndices.hpp"
27
29
30#include <utils/Vector.hpp>
31#include <utils/constants.hpp>
33
34#include <boost/mpi/collectives/all_reduce.hpp>
35#include <boost/serialization/vector.hpp>
36
37#include <cassert>
38#include <memory>
39#include <optional>
40#include <stdexcept>
41#include <string>
42
44
45static bool is_boundary_all_reduce(boost::mpi::communicator const &comm,
46 std::optional<bool> const &is_boundary) {
47 return boost::mpi::all_reduce(comm, is_boundary ? *is_boundary : false,
48 std::logical_or<>());
49}
50
51Variant EKSpeciesNode::do_call_method(std::string const &name,
52 VariantMap const &params) {
53 if (name == "override_index") {
54 // this hidden feature is used to iterate an EK slice without
55 // rebuilding a EKSpeciesNode for each node in the slice
56 auto const index = get_value<Utils::Vector3i>(params, "index");
57 if (not is_index_valid(index, m_grid_size)) {
58 return ES_ERROR;
59 }
60 m_index = index;
61 return ES_OK;
62 }
63 if (name == "set_density") {
64 auto const dens = get_value<double>(params, "value");
65 m_ek_species->set_node_density(m_index, dens * m_conv_dens);
66 m_ek_species->ghost_communication();
67 return {};
68 }
69 if (name == "get_density") {
70 auto const result = m_ek_species->get_node_density(m_index);
71 return Utils::Mpi::reduce_optional(context()->get_comm(), result) /
72 m_conv_dens;
73 }
74 if (name == "get_is_boundary") {
75 auto const result = m_ek_species->get_node_is_boundary(m_index);
76 return Utils::Mpi::reduce_optional(context()->get_comm(), result);
77 }
78 if (name == "get_node_density_at_boundary") {
79 auto const boundary_opt =
80 m_ek_species->get_node_is_density_boundary(m_index);
81 if (is_boundary_all_reduce(context()->get_comm(), boundary_opt)) {
82 auto const result = m_ek_species->get_node_density_at_boundary(m_index);
83 return Utils::Mpi::reduce_optional(context()->get_comm(), result) /
84 m_conv_dens;
85 }
86 return Variant{None{}};
87 }
88 if (name == "set_node_density_at_boundary") {
89 if (is_none(params.at("value"))) {
90 m_ek_species->remove_node_from_density_boundary(m_index);
91 } else {
92 auto const dens = get_value<double>(params, "value") * m_conv_dens;
93 m_ek_species->set_node_density_boundary(m_index, dens);
94 }
95 return {};
96 }
97 if (name == "get_node_flux_at_boundary") {
98 auto const boundary_opt = m_ek_species->get_node_is_flux_boundary(m_index);
99 if (is_boundary_all_reduce(context()->get_comm(), boundary_opt)) {
100 auto const result = m_ek_species->get_node_flux_at_boundary(m_index);
101 return Utils::Mpi::reduce_optional(context()->get_comm(), result) /
102 m_conv_flux;
103 }
104 return Variant{None{}};
105 }
106 if (name == "set_node_flux_at_boundary") {
107 if (is_none(params.at("value"))) {
108 m_ek_species->remove_node_from_flux_boundary(m_index);
109 } else {
110 auto const flux =
111 get_value<Utils::Vector3d>(params, "value") * m_conv_flux;
112 m_ek_species->set_node_flux_boundary(m_index, flux);
113 }
114 return {};
115 }
116
117 return {};
118}
119
120} // namespace ScriptInterface::walberla
121
122#endif // WALBERLA
Vector implementation and trait types for boost qvm interoperability.
bool is_index_valid(Utils::Vector3i const &index, Utils::Vector3i const &shape) const
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.
#define ES_OK
error code if no error occurred
Definition constants.hpp:78
#define ES_ERROR
error code if an error occurred
Definition constants.hpp:80
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.