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
CoulombP3M.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2022 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#include "config/config.hpp"
23
24#ifdef P3M
25
26#include "Actor.hpp"
27
30
32
33#include <memory>
34#include <optional>
35#include <stdexcept>
36#include <string>
37#include <utility>
38
39namespace ScriptInterface {
40namespace Coulomb {
41
42template <Arch Architecture>
43class CoulombP3M : public Actor<CoulombP3M<Architecture>, ::CoulombP3M> {
44 int m_tune_timings;
45 bool m_tune;
46 bool m_tune_verbose;
47 bool m_check_complex_residuals;
48 bool m_single_precision;
49 std::pair<std::optional<int>, std::optional<int>> m_tune_limits;
50
51public:
53 using Base::actor;
55 using Base::context;
56
57protected:
58 using Base::m_actor;
60
61public:
64 {"single_precision", AutoParameter::read_only,
65 [this]() { return not actor()->is_double_precision(); }},
66 {"alpha_L", AutoParameter::read_only,
67 [this]() { return actor()->p3m_params.alpha_L; }},
68 {"r_cut_iL", AutoParameter::read_only,
69 [this]() { return actor()->p3m_params.r_cut_iL; }},
71 [this]() { return actor()->p3m_params.mesh; }},
72 {"mesh_off", AutoParameter::read_only,
73 [this]() { return actor()->p3m_params.mesh_off; }},
75 [this]() { return actor()->p3m_params.cao; }},
76 {"accuracy", AutoParameter::read_only,
77 [this]() { return actor()->p3m_params.accuracy; }},
78 {"epsilon", AutoParameter::read_only,
79 [this]() { return actor()->p3m_params.epsilon; }},
81 [this]() { return actor()->p3m_params.a; }},
83 [this]() { return actor()->p3m_params.alpha; }},
85 [this]() { return actor()->p3m_params.r_cut; }},
86 {"is_tuned", AutoParameter::read_only,
87 [this]() { return actor()->is_tuned(); }},
88 {"verbose", AutoParameter::read_only,
89 [this]() { return m_tune_verbose; }},
90 {"timings", AutoParameter::read_only,
91 [this]() { return m_tune_timings; }},
92 {"tune_limits", AutoParameter::read_only,
93 [this]() {
94 auto const &[range_min, range_max] = m_tune_limits;
95 std::vector<Variant> retval = {
98 };
99 return retval;
100 }},
101 {"tune", AutoParameter::read_only, [this]() { return m_tune; }},
102 {"check_complex_residuals", AutoParameter::read_only,
103 [this]() { return m_check_complex_residuals; }},
104 });
105 }
106
107 void do_construct(VariantMap const &params) override {
108 m_tune = get_value<bool>(params, "tune");
109 m_tune_timings = get_value<int>(params, "timings");
110 m_tune_verbose = get_value<bool>(params, "verbose");
111 m_tune_limits = {std::nullopt, std::nullopt};
112 if (params.contains("tune_limits")) {
113 auto const &variant = params.at("tune_limits");
114 std::size_t range_length = 0u;
115 if (is_type<std::vector<int>>(variant)) {
117 range_length = range.size();
118 if (range_length == 2u) {
119 m_tune_limits = {range[0u], range[1u]};
120 }
121 } else {
123 range_length = range.size();
124 if (range_length == 2u) {
125 if (not is_none(range[0u])) {
126 m_tune_limits.first = get_value<int>(range[0u]);
127 }
128 if (not is_none(range[1u])) {
129 m_tune_limits.second = get_value<int>(range[1u]);
130 }
131 }
132 }
133 context()->parallel_try_catch([&]() {
134 if (range_length != 2u) {
135 throw std::invalid_argument("Parameter 'tune_limits' needs 2 values");
136 }
137 if (m_tune_limits.first and *m_tune_limits.first <= 0) {
138 throw std::domain_error("Parameter 'tune_limits' must be > 0");
139 }
140 if (m_tune_limits.second and *m_tune_limits.second <= 0) {
141 throw std::domain_error("Parameter 'tune_limits' must be > 0");
142 }
143 });
144 }
145 m_check_complex_residuals =
146 get_value<bool>(params, "check_complex_residuals");
147 auto const single_precision = get_value<bool>(params, "single_precision");
148 context()->parallel_try_catch([&]() {
150 throw std::invalid_argument(
151 "P3M GPU only implemented in single-precision mode");
152 }
153 auto p3m = P3MParameters{!get_value_or<bool>(params, "is_tuned", !m_tune),
154 get_value<double>(params, "epsilon"),
155 get_value<double>(params, "r_cut"),
158 get_value<int>(params, "cao"),
159 get_value<double>(params, "alpha"),
160 get_value<double>(params, "accuracy")};
161 make_handle(single_precision, std::move(p3m),
162 get_value<double>(params, "prefactor"), m_tune_timings,
163 m_tune_verbose, m_tune_limits, m_check_complex_residuals);
164 });
166 }
167
168private:
169 template <typename FloatType, class... Args>
170 void make_handle_impl(Args &&...args) {
171 m_actor =
172 new_coulomb_p3m<FloatType, Architecture>(std::forward<Args>(args)...);
173 }
174 template <class... Args>
175 void make_handle(bool single_precision, Args &&...args) {
176 if (single_precision) {
177 make_handle_impl<float, Args...>(std::forward<Args>(args)...);
178 } else {
179 make_handle_impl<double, Args...>(std::forward<Args>(args)...);
180 }
181 }
182};
183
184} // namespace Coulomb
185} // namespace ScriptInterface
186
187#endif // P3M
void add_parameters(std::vector< AutoParameter > &&params)
virtual void parallel_try_catch(std::function< void()> const &cb) const =0
Common interface for electrostatic actors.
void do_construct(VariantMap const &params) override
Type to indicate no value in Variant.
Context * context() const
Responsible context.
This file contains the defaults for ESPResSo.
bool is_type(Variant const &v)
Check is a Variant holds a specific type.
Definition Variant.hpp:111
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
P3M algorithm for long-range Coulomb interaction.
static SteepestDescentParameters params
Currently active steepest descent instance.
P3M solver.
Definition p3m.hpp:56
Structure to hold P3M parameters and some dependent variables.
static constexpr const ReadOnly read_only