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
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/demangle.hpp>
37
38#include <cassert>
39#include <optional>
40#include <stdexcept>
41
42namespace Dipoles {
43
45 impl = std::make_unique<Implementation>();
47}
48
50
52 if (impl->solver) {
53 std::visit([](auto &ptr) { ptr->sanity_checks(); }, *impl->solver);
54 }
55}
56
59 if (impl->solver) {
60 visit_try_catch([](auto &ptr) { ptr->init(); }, *impl->solver);
61 }
62}
63
65 if (impl->solver) {
66 visit_try_catch([](auto &ptr) { ptr->on_boxl_change(); }, *impl->solver);
67 }
68}
69
71 if (impl->solver) {
72 std::visit([](auto &ptr) { ptr->on_node_grid_change(); }, *impl->solver);
73 }
74}
75
77 if (impl->solver) {
78 visit_try_catch([](auto &ptr) { ptr->on_periodicity_change(); },
79 *impl->solver);
80 }
81}
82
84 if (impl->solver) {
85 visit_try_catch([](auto &ptr) { ptr->on_cell_structure_change(); },
86 *impl->solver);
87 }
88}
89
90double Solver::cutoff() const {
91#ifdef DP3M
92 if (impl->solver) {
93 if (auto dp3m = get_actor_by_type<DipolarP3M>(impl->solver)) {
94 return dp3m->dp3m_params.r_cut;
95 }
96 }
97#endif
98 return -1.;
99}
100
103#ifdef DP3M
104 if (impl->solver) {
105 if (auto dp3m = get_actor_by_type<DipolarP3M>(impl->solver)) {
106 dp3m->count_magnetic_particles();
107 }
108 }
109#endif
111 }
112}
113
116 explicit LongRangeForce(ParticleRange const &particles)
117 : m_particles(particles) {}
118
119#ifdef DP3M
120 void operator()(std::shared_ptr<DipolarP3M> const &actor) const {
121 actor->add_long_range_forces(m_particles);
122 }
123#endif // DP3M
124 void operator()(std::shared_ptr<DipolarLayerCorrection> const &actor) const {
125 actor->add_force_corrections(m_particles);
126 std::visit(*this, actor->base_solver);
127 }
128 void operator()(std::shared_ptr<DipolarDirectSum> const &actor) const {
129 actor->add_long_range_forces(m_particles);
130 }
131#ifdef DIPOLAR_DIRECT_SUM
132 void operator()(std::shared_ptr<DipolarDirectSumGpu> const &actor) const {
133 actor->add_long_range_forces();
134 }
135#endif
136#ifdef SCAFACOS_DIPOLES
137 void operator()(std::shared_ptr<DipolarScafacos> const &actor) const {
138 actor->add_long_range_forces();
139 }
140#endif
141};
142
145 explicit LongRangeEnergy(ParticleRange const &particles)
146 : m_particles(particles) {}
147
148#ifdef DP3M
149 double operator()(std::shared_ptr<DipolarP3M> const &actor) const {
150 return actor->long_range_energy(m_particles);
151 }
152#endif // DP3M
153 double
154 operator()(std::shared_ptr<DipolarLayerCorrection> const &actor) const {
155 auto energy = std::visit(*this, actor->base_solver);
156 return energy + actor->energy_correction(m_particles);
157 }
158 double operator()(std::shared_ptr<DipolarDirectSum> const &actor) const {
159 return actor->long_range_energy(m_particles);
160 }
161#ifdef DIPOLAR_DIRECT_SUM
162 double operator()(std::shared_ptr<DipolarDirectSumGpu> const &actor) const {
163 actor->long_range_energy();
164 return 0.;
165 }
166#endif
167#ifdef SCAFACOS_DIPOLES
168 double operator()(std::shared_ptr<DipolarScafacos> const &actor) const {
169 return actor->long_range_energy();
170 }
171#endif
172};
173
174#ifdef DIPOLE_FIELD_TRACKING
177 explicit LongRangeField(ParticleRange const &particles)
178 : m_particles(particles) {}
179
180 void operator()(std::shared_ptr<DipolarDirectSum> const &actor) const {
181 actor->dipole_field_at_part(m_particles);
182 }
183
184 template <typename T,
185 std::enable_if_t<!traits::has_dipole_fields<T>::value> * = nullptr>
186 void operator()(std::shared_ptr<T> const &) const {
187 runtimeErrorMsg() << "Dipoles field calculation not implemented by "
188 << "dipolar method " << Utils::demangle<T>();
189 }
190};
191#endif
192
194 if (impl->solver) {
195 runtimeWarningMsg() << "pressure calculated, but pressure not implemented.";
196 }
197}
198
199void Solver::calc_long_range_force(ParticleRange const &particles) const {
200 if (impl->solver) {
201 std::visit(LongRangeForce(particles), *impl->solver);
202 }
203}
204
205double Solver::calc_energy_long_range(ParticleRange const &particles) const {
206 if (impl->solver) {
207 return std::visit(LongRangeEnergy(particles), *impl->solver);
208 }
209 return 0.;
210}
211
212#ifdef DIPOLE_FIELD_TRACKING
213void Solver::calc_long_range_field(ParticleRange const &particles) const {
214 if (impl->solver) {
215 std::visit(LongRangeField(particles), *impl->solver);
216 }
217}
218#endif
219
220} // namespace Dipoles
221#endif // DIPOLES
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:49
System & get_system()
double operator()(std::shared_ptr< DipolarLayerCorrection > const &actor) const
Definition dipoles.cpp:154
ParticleRange const & m_particles
Definition dipoles.cpp:144
double operator()(std::shared_ptr< DipolarDirectSumGpu > const &actor) const
Definition dipoles.cpp:162
double operator()(std::shared_ptr< DipolarDirectSum > const &actor) const
Definition dipoles.cpp:158
LongRangeEnergy(ParticleRange const &particles)
Definition dipoles.cpp:145
double operator()(std::shared_ptr< DipolarScafacos > const &actor) const
Definition dipoles.cpp:168
double operator()(std::shared_ptr< DipolarP3M > const &actor) const
Definition dipoles.cpp:149
LongRangeField(ParticleRange const &particles)
Definition dipoles.cpp:177
ParticleRange const & m_particles
Definition dipoles.cpp:176
void operator()(std::shared_ptr< DipolarDirectSum > const &actor) const
Definition dipoles.cpp:180
void operator()(std::shared_ptr< T > const &) const
Definition dipoles.cpp:186
void operator()(std::shared_ptr< DipolarDirectSum > const &actor) const
Definition dipoles.cpp:128
void operator()(std::shared_ptr< DipolarScafacos > const &actor) const
Definition dipoles.cpp:137
void operator()(std::shared_ptr< DipolarDirectSumGpu > const &actor) const
Definition dipoles.cpp:132
ParticleRange const & m_particles
Definition dipoles.cpp:115
void operator()(std::shared_ptr< DipolarLayerCorrection > const &actor) const
Definition dipoles.cpp:124
void operator()(std::shared_ptr< DipolarP3M > const &actor) const
Definition dipoles.cpp:120
LongRangeForce(ParticleRange const &particles)
Definition dipoles.cpp:116
void sanity_checks() const
Definition dipoles.cpp:51
double cutoff() const
Definition dipoles.cpp:90
void on_cell_structure_change()
Definition dipoles.cpp:83
void calc_long_range_field(ParticleRange const &particles) const
Definition dipoles.cpp:213
std::unique_ptr< Implementation > impl
Pointer-to-implementation.
void calc_long_range_force(ParticleRange const &particles) const
Definition dipoles.cpp:199
double calc_energy_long_range(ParticleRange const &particles) const
Definition dipoles.cpp:205
void on_boxl_change()
Definition dipoles.cpp:64
void on_periodicity_change()
Definition dipoles.cpp:76
void calc_pressure_long_range() const
Definition dipoles.cpp:193
bool reinit_on_observable_calc
Whether to reinitialize the solver on observable calculation.
void on_observable_calc()
Definition dipoles.cpp:101
void on_dipoles_change()
Definition dipoles.cpp:57
void on_node_grid_change()
Definition dipoles.cpp:70
void visit_try_catch(Visitor &&visitor, Variant &actor)
Run a kernel on a variant and queue errors.