ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
dipoles.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-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#include "config/config.hpp"
21
23
24#ifdef DIPOLES
25
27
28#include "ParticleRange.hpp"
29#include "actor/traits.hpp"
31#include "actor/visitors.hpp"
32#include "communication.hpp"
33#include "errorhandling.hpp"
34#include "system/System.hpp"
35
36#include <utils/Vector.hpp>
37#include <utils/constants.hpp>
38#include <utils/demangle.hpp>
39
40#include <cassert>
41#include <optional>
42#include <stdexcept>
43
44namespace Dipoles {
45
47 impl = std::make_unique<Implementation>();
49}
50
52
54 if (impl->solver) {
55 std::visit([](auto &ptr) { ptr->sanity_checks(); }, *impl->solver);
56 }
57}
58
61 if (impl->solver) {
62 visit_try_catch([](auto &ptr) { ptr->init(); }, *impl->solver);
63 }
64}
65
67 if (impl->solver) {
68 visit_try_catch([](auto &ptr) { ptr->on_boxl_change(); }, *impl->solver);
69 }
70}
71
73 if (impl->solver) {
74 std::visit([](auto &ptr) { ptr->on_node_grid_change(); }, *impl->solver);
75 }
76}
77
79 if (impl->solver) {
80 visit_try_catch([](auto &ptr) { ptr->on_periodicity_change(); },
81 *impl->solver);
82 }
83}
84
86 if (impl->solver) {
87 visit_try_catch([](auto &ptr) { ptr->on_cell_structure_change(); },
88 *impl->solver);
89 }
90}
91
92double Solver::cutoff() const {
93#ifdef DP3M
94 if (impl->solver) {
95 if (auto dp3m = get_actor_by_type<DipolarP3M>(impl->solver)) {
96 return dp3m->dp3m.params.r_cut;
97 }
98 }
99#endif
100 return -1.;
101}
102
105#ifdef DP3M
106 if (impl->solver) {
107 if (auto dp3m = get_actor_by_type<DipolarP3M>(impl->solver)) {
108 dp3m->count_magnetic_particles();
109 }
110 }
111#endif
113 }
114}
115
118 explicit LongRangeForce(ParticleRange const &particles)
119 : m_particles(particles) {}
120
121#ifdef DP3M
122 void operator()(std::shared_ptr<DipolarP3M> const &actor) const {
123 actor->add_long_range_forces(m_particles);
124 }
125#endif // DP3M
126 void operator()(std::shared_ptr<DipolarLayerCorrection> const &actor) const {
127 actor->add_force_corrections(m_particles);
128 std::visit(*this, actor->base_solver);
129 }
130 void operator()(std::shared_ptr<DipolarDirectSum> const &actor) const {
131 actor->add_long_range_forces(m_particles);
132 }
133#ifdef DIPOLAR_DIRECT_SUM
134 void operator()(std::shared_ptr<DipolarDirectSumGpu> const &actor) const {
135 actor->add_long_range_forces();
136 }
137#endif
138#ifdef DIPOLAR_BARNES_HUT
139 void operator()(std::shared_ptr<DipolarBarnesHutGpu> const &actor) const {
140 actor->add_long_range_forces();
141 }
142#endif
143#ifdef SCAFACOS_DIPOLES
144 void operator()(std::shared_ptr<DipolarScafacos> const &actor) const {
145 actor->add_long_range_forces();
146 }
147#endif
148};
149
152 explicit LongRangeEnergy(ParticleRange const &particles)
153 : m_particles(particles) {}
154
155#ifdef DP3M
156 double operator()(std::shared_ptr<DipolarP3M> const &actor) const {
157 return actor->long_range_energy(m_particles);
158 }
159#endif // DP3M
160 double
161 operator()(std::shared_ptr<DipolarLayerCorrection> const &actor) const {
162 auto energy = std::visit(*this, actor->base_solver);
163 return energy + actor->energy_correction(m_particles);
164 }
165 double operator()(std::shared_ptr<DipolarDirectSum> const &actor) const {
166 return actor->long_range_energy(m_particles);
167 }
168#ifdef DIPOLAR_DIRECT_SUM
169 double operator()(std::shared_ptr<DipolarDirectSumGpu> const &actor) const {
170 actor->long_range_energy();
171 return 0.;
172 }
173#endif
174#ifdef DIPOLAR_BARNES_HUT
175 double operator()(std::shared_ptr<DipolarBarnesHutGpu> const &actor) const {
176 actor->long_range_energy();
177 return 0.;
178 }
179#endif
180#ifdef SCAFACOS_DIPOLES
181 double operator()(std::shared_ptr<DipolarScafacos> const &actor) const {
182 return actor->long_range_energy();
183 }
184#endif
185};
186
187#ifdef DIPOLE_FIELD_TRACKING
190 explicit LongRangeField(ParticleRange const &particles)
191 : m_particles(particles) {}
192
193 void operator()(std::shared_ptr<DipolarDirectSum> const &actor) const {
194 actor->dipole_field_at_part(m_particles);
195 }
196
197 template <typename T,
198 std::enable_if_t<!traits::has_dipole_fields<T>::value> * = nullptr>
199 void operator()(std::shared_ptr<T> const &) const {
200 runtimeErrorMsg() << "Dipoles field calculation not implemented by "
201 << "dipolar method " << Utils::demangle<T>();
202 }
203};
204#endif
205
207 if (impl->solver) {
208 runtimeWarningMsg() << "pressure calculated, but pressure not implemented.";
209 }
210}
211
212void Solver::calc_long_range_force(ParticleRange const &particles) const {
213 if (impl->solver) {
214 std::visit(LongRangeForce(particles), *impl->solver);
215 }
216}
217
218double Solver::calc_energy_long_range(ParticleRange const &particles) const {
219 if (impl->solver) {
220 return std::visit(LongRangeEnergy(particles), *impl->solver);
221 }
222 return 0.;
223}
224
225#ifdef DIPOLE_FIELD_TRACKING
226void Solver::calc_long_range_field(ParticleRange const &particles) const {
227 if (impl->solver) {
228 std::visit(LongRangeField(particles), *impl->solver);
229 }
230}
231#endif
232
233} // namespace Dipoles
234#endif // DIPOLES
Vector implementation and trait types for boost qvm interoperability.
A range of particles.
Dipoles::Solver dipoles
This file contains the defaults for ESPResSo.
This file contains the errorhandling code for severe errors, like a broken bond or illegal parameter ...
#define runtimeWarningMsg()
#define runtimeErrorMsg()
Solver const & get_dipoles()
Definition dipoles.cpp:51
System & get_system()
double operator()(std::shared_ptr< DipolarLayerCorrection > const &actor) const
Definition dipoles.cpp:161
ParticleRange const & m_particles
Definition dipoles.cpp:151
double operator()(std::shared_ptr< DipolarDirectSumGpu > const &actor) const
Definition dipoles.cpp:169
double operator()(std::shared_ptr< DipolarDirectSum > const &actor) const
Definition dipoles.cpp:165
LongRangeEnergy(ParticleRange const &particles)
Definition dipoles.cpp:152
double operator()(std::shared_ptr< DipolarBarnesHutGpu > const &actor) const
Definition dipoles.cpp:175
double operator()(std::shared_ptr< DipolarScafacos > const &actor) const
Definition dipoles.cpp:181
double operator()(std::shared_ptr< DipolarP3M > const &actor) const
Definition dipoles.cpp:156
LongRangeField(ParticleRange const &particles)
Definition dipoles.cpp:190
ParticleRange const & m_particles
Definition dipoles.cpp:189
void operator()(std::shared_ptr< DipolarDirectSum > const &actor) const
Definition dipoles.cpp:193
void operator()(std::shared_ptr< T > const &) const
Definition dipoles.cpp:199
void operator()(std::shared_ptr< DipolarDirectSum > const &actor) const
Definition dipoles.cpp:130
void operator()(std::shared_ptr< DipolarScafacos > const &actor) const
Definition dipoles.cpp:144
void operator()(std::shared_ptr< DipolarDirectSumGpu > const &actor) const
Definition dipoles.cpp:134
ParticleRange const & m_particles
Definition dipoles.cpp:117
void operator()(std::shared_ptr< DipolarLayerCorrection > const &actor) const
Definition dipoles.cpp:126
void operator()(std::shared_ptr< DipolarP3M > const &actor) const
Definition dipoles.cpp:122
LongRangeForce(ParticleRange const &particles)
Definition dipoles.cpp:118
void operator()(std::shared_ptr< DipolarBarnesHutGpu > const &actor) const
Definition dipoles.cpp:139
void sanity_checks() const
Definition dipoles.cpp:53
double cutoff() const
Definition dipoles.cpp:92
void on_cell_structure_change()
Definition dipoles.cpp:85
void calc_long_range_field(ParticleRange const &particles) const
Definition dipoles.cpp:226
std::unique_ptr< Implementation > impl
Pointer-to-implementation.
void calc_long_range_force(ParticleRange const &particles) const
Definition dipoles.cpp:212
double calc_energy_long_range(ParticleRange const &particles) const
Definition dipoles.cpp:218
void on_boxl_change()
Definition dipoles.cpp:66
void on_periodicity_change()
Definition dipoles.cpp:78
void calc_pressure_long_range() const
Definition dipoles.cpp:206
bool reinit_on_observable_calc
Whether to reinitialize the solver on observable calculation.
void on_observable_calc()
Definition dipoles.cpp:103
void on_dipoles_change()
Definition dipoles.cpp:59
void on_node_grid_change()
Definition dipoles.cpp:72
void visit_try_catch(Visitor &&visitor, Variant &actor)
Run a kernel on a variant and queue errors.