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/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.