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
DipolarP3M.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 DP3M
25
26#include "Actor.hpp"
27
32
34
35#include <memory>
36#include <optional>
37#include <stdexcept>
38#include <string>
39#include <utility>
40
41#ifdef FFTW3_H
42#error "The FFTW3 library shouldn't be visible in this translation unit"
43#endif
44
45namespace ScriptInterface {
46namespace Dipoles {
47
48template <Arch Architecture>
49class DipolarP3M : public Actor<DipolarP3M<Architecture>, ::DipolarP3M> {
50 int m_tune_timings;
51 std::pair<std::optional<int>, std::optional<int>> m_tune_limits;
52 bool m_tune;
53 bool m_tune_verbose;
54
55public:
57 using Base::actor;
59 using Base::context;
60
61protected:
62 using Base::m_actor;
63
64public:
67 {"single_precision", AutoParameter::read_only,
68 [this]() { return not actor()->is_double_precision(); }},
69 {"alpha_L", AutoParameter::read_only,
70 [this]() { return actor()->dp3m_params.alpha_L; }},
71 {"r_cut_iL", AutoParameter::read_only,
72 [this]() { return actor()->dp3m_params.r_cut_iL; }},
74 [this]() { return actor()->dp3m_params.mesh; }},
75 {"mesh_off", AutoParameter::read_only,
76 [this]() { return actor()->dp3m_params.mesh_off; }},
78 [this]() { return actor()->dp3m_params.cao; }},
79 {"accuracy", AutoParameter::read_only,
80 [this]() { return actor()->dp3m_params.accuracy; }},
81 {"epsilon", AutoParameter::read_only,
82 [this]() { return actor()->dp3m_params.epsilon; }},
84 [this]() { return actor()->dp3m_params.a; }},
86 [this]() { return actor()->dp3m_params.alpha; }},
88 [this]() { return actor()->dp3m_params.r_cut; }},
89 {"is_tuned", AutoParameter::read_only,
90 [this]() { return actor()->is_tuned(); }},
91 {"verbose", AutoParameter::read_only,
92 [this]() { return m_tune_verbose; }},
93 {"timings", AutoParameter::read_only,
94 [this]() { return m_tune_timings; }},
95 {"tune_limits", AutoParameter::read_only,
96 [this]() {
97 auto const &[range_min, range_max] = m_tune_limits;
98 std::vector<Variant> retval = {
101 };
102 return retval;
103 }},
104 {"tune", AutoParameter::read_only, [this]() { return m_tune; }},
105 });
106 }
107
108 void do_construct(VariantMap const &params) override {
109 m_tune = get_value<bool>(params, "tune");
110 m_tune_timings = get_value<int>(params, "timings");
111 m_tune_verbose = get_value<bool>(params, "verbose");
112 m_tune_limits = {std::nullopt, std::nullopt};
113 if (params.contains("tune_limits")) {
114 auto const &variant = params.at("tune_limits");
115 std::size_t range_length = 0u;
116 if (is_type<std::vector<int>>(variant)) {
118 range_length = range.size();
119 if (range_length == 2u) {
120 m_tune_limits = {range[0u], range[1u]};
121 }
122 } else {
124 range_length = range.size();
125 if (range_length == 2u) {
126 if (not is_none(range[0u])) {
127 m_tune_limits.first = get_value<int>(range[0u]);
128 }
129 if (not is_none(range[1u])) {
130 m_tune_limits.second = get_value<int>(range[1u]);
131 }
132 }
133 }
134 context()->parallel_try_catch([&]() {
135 if (range_length != 2u) {
136 throw std::invalid_argument("Parameter 'tune_limits' needs 2 values");
137 }
138 if (m_tune_limits.first and *m_tune_limits.first <= 0) {
139 throw std::domain_error("Parameter 'tune_limits' must be > 0");
140 }
141 if (m_tune_limits.second and *m_tune_limits.second <= 0) {
142 throw std::domain_error("Parameter 'tune_limits' must be > 0");
143 }
144 });
145 }
146 auto const single_precision = get_value<bool>(params, "single_precision");
147 static_assert(Architecture == Arch::CPU, "GPU not implemented");
148 context()->parallel_try_catch([&]() {
149 auto p3m = P3MParameters{!get_value_or<bool>(params, "is_tuned", !m_tune),
150 get_value<double>(params, "epsilon"),
151 get_value<double>(params, "r_cut"),
154 get_value<int>(params, "cao"),
155 get_value<double>(params, "alpha"),
156 get_value<double>(params, "accuracy")};
157 make_handle(single_precision, std::move(p3m),
158 get_value<double>(params, "prefactor"), m_tune_timings,
159 m_tune_verbose, m_tune_limits);
160 });
161 }
162
163private:
164 template <typename FloatType, class... Args>
165 void make_handle_impl(Args &&...args) {
167 FFTBuffersLegacy>(std::forward<Args>(args)...);
168 }
169 template <class... Args>
170 void make_handle(bool single_precision, Args &&...args) {
171 if (single_precision) {
172 make_handle_impl<float, Args...>(std::forward<Args>(args)...);
173 } else {
174 make_handle_impl<double, Args...>(std::forward<Args>(args)...);
175 }
176 }
177};
178
179} // namespace Dipoles
180} // namespace ScriptInterface
181
182#endif // DP3M
Historic FFT backend based on FFTW3.
Buffers for FFTBackendLegacy.
void add_parameters(std::vector< AutoParameter > &&params)
virtual void parallel_try_catch(std::function< void()> const &cb) const =0
Common interface for magnetostatic 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.
P3M algorithm for long-range magnetic dipole-dipole interaction.
std::shared_ptr< DipolarP3M > new_dp3m_handle(P3MParameters &&p3m, Args &&...args)
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
static SteepestDescentParameters params
Currently active steepest descent instance.
Dipolar P3M solver.
Definition dp3m.hpp:54
Structure to hold P3M parameters and some dependent variables.
static constexpr const ReadOnly read_only