39#include <boost/mpi/collectives/gather.hpp>
40#include <boost/variant.hpp>
48#include <unordered_map>
59 get_cell_structure().use_verlet_list = get_value<bool>(v);
61 [
this]() {
return get_cell_structure().use_verlet_list; }},
65 auto const error_msg = std::string(
"Parameter 'node_grid'");
67 auto const new_node_grid = get_value<Utils::Vector3i>(v);
70 if (n_nodes_new != n_nodes_old) {
71 std::stringstream reason;
72 reason <<
": MPI world size " << n_nodes_old <<
" incompatible "
73 <<
"with new node grid [" << new_node_grid <<
"]";
74 throw std::invalid_argument(error_msg + reason.str());
86 []() { return ::communicator.node_grid; }},
89 auto const new_skin = get_value<double>(v);
91 if (
context()->is_head_node()) {
92 throw std::domain_error(
"Parameter 'skin' must be >= 0");
96 get_cell_structure().set_verlet_skin(new_skin);
98 [
this]() {
return get_cell_structure().get_verlet_skin(); }},
101 return cs_type_to_name.at(get_cell_structure().decomposition_type());
105 if (get_cell_structure().decomposition_type() !=
109 auto const hd = get_hybrid_decomposition();
110 auto const ns_types = hd.get_n_square_types();
111 return Variant{std::vector<int>(ns_types.begin(), ns_types.end())};
115 if (get_cell_structure().decomposition_type() !=
119 auto const hd = get_hybrid_decomposition();
120 return Variant{hd.get_cutoff_regular()};
123 [
this]() {
return get_system().nonbonded_ias->maximal_cutoff(); }},
126 [
this]() {
return get_system().get_interaction_range(); }},
132 if (
name ==
"initialize") {
133 auto const cs_name = get_value<std::string>(
params,
"name");
134 auto const cs_type = cs_name_to_type.at(cs_name);
135 initialize(cs_type,
params);
138 if (
name ==
"resort") {
139 auto const global_flag = get_value_or<bool>(
params,
"global_flag",
true);
140 return mpi_resort_particles(global_flag);
142 if (
name ==
"get_state") {
144 auto const cs_type = get_cell_structure().decomposition_type();
146 auto const rd = get_regular_decomposition();
147 state[
"cell_grid"] =
Variant{rd.cell_grid};
148 state[
"cell_size"] =
Variant{rd.cell_size};
150 auto const hd = get_hybrid_decomposition();
151 state[
"cell_grid"] =
Variant{hd.get_cell_grid()};
152 state[
"cell_size"] =
Variant{hd.get_cell_size()};
153 mpi_resort_particles(
true);
154 state[
"parts_per_decomposition"] =
155 Variant{std::unordered_map<std::string, Variant>{
156 {
"regular", hd.count_particles_in_regular()},
157 {
"n_square", hd.count_particles_in_n_square()}}};
159 state[
"verlet_reuse"] = get_cell_structure().get_verlet_reuse();
163 if (
name ==
"get_pairs") {
164 std::vector<Variant> out;
167 system.on_observable_calc();
168 std::vector<std::pair<int, int>> pair_list;
169 auto const distance = get_value<double>(
params,
"distance");
170 if (boost::get<std::string>(&
params.at(
"types")) !=
nullptr) {
171 auto const key = get_value<std::string>(
params,
"types");
173 throw std::invalid_argument(
"Unknown argument types='" + key +
"'");
177 auto const types = get_value<std::vector<int>>(
params,
"types");
181 std::transform(pair_list.begin(), pair_list.end(),
182 std::back_inserter(out),
183 [](std::pair<int, int>
const &pair) {
184 return std::vector<int>{pair.first, pair.second};
189 if (name ==
"get_neighbors") {
190 std::vector<std::vector<int>> neighbors_global;
191 context()->parallel_try_catch([
this, &neighbors_global, &
params]() {
192 auto &system = get_system();
193 system.on_observable_calc();
194 auto const dist = get_value<double>(
params,
"distance");
195 auto const pid = get_value<int>(
params,
"pid");
197 std::vector<int> neighbors_local;
199 neighbors_local = *ret;
201 boost::mpi::gather(context()->get_comm(), neighbors_local,
202 neighbors_global, 0);
204 std::vector<int> neighbors;
205 for (
auto const &neighbors_local : neighbors_global) {
206 if (not neighbors_local.empty()) {
207 neighbors = neighbors_local;
213 if (name ==
"non_bonded_loop_trace") {
215 system.on_observable_calc();
216 std::vector<Variant> out;
220 std::transform(pair_list.begin(), pair_list.end(), std::back_inserter(out),
222 return std::vector<Variant>{pair.id1, pair.id2,
223 pair.pos1, pair.pos2,
224 pair.vec21, pair.node};
228 if (name ==
"tune_skin") {
230 system.tune_verlet_skin(
231 get_value<double>(
params,
"min_skin"),
232 get_value<double>(
params,
"max_skin"), get_value<double>(
params,
"tol"),
233 get_value<int>(
params,
"int_steps"),
234 get_value_or<bool>(
params,
"adjust_max_skin",
false));
237 if (name ==
"get_max_range") {
243std::vector<int> CellSystem::mpi_resort_particles(
bool global_flag)
const {
245 cell_structure.resort_particles(global_flag);
247 auto const size =
static_cast<int>(cell_structure.local_particles().size());
248 std::vector<int> n_part_per_node;
249 boost::mpi::gather(context()->get_comm(), size, n_part_per_node, 0);
250 return n_part_per_node;
254 VariantMap
const &
params) {
255 auto const verlet = get_value_or<bool>(
params,
"use_verlet_lists",
true);
257 m_cell_structure->use_verlet_list = verlet;
259 auto const cutoff_regular = get_value<double>(
params,
"cutoff_regular");
260 auto const ns_types =
261 get_value_or<std::vector<int>>(
params,
"n_square_types", {});
262 auto n_square_types = std::set<int>{ns_types.begin(), ns_types.end()};
263 m_cell_structure->set_hybrid_decomposition(cutoff_regular, n_square_types);
265 system.set_cell_structure_topology(cs_type);
CellStructureType
Cell structure topology.
@ HYBRID
Hybrid decomposition.
@ REGULAR
Regular decomposition.
Vector implementation and trait types for boost qvm interoperability.
double maximal_cutoff_bonded()
Calculate the maximal cutoff of bonded interactions, required to determine the cell size for communic...
Data structures for bonded interactions.
std::vector< PairInfo > non_bonded_loop_trace(System::System const &system, int const rank)
Returns pairs of particle ids, positions and distance as seen by the non-bonded loop.
std::vector< std::pair< int, int > > get_pairs_of_types(System::System const &system, double const distance, std::vector< int > const &types)
Get pairs closer than distance if both their types are in types.
boost::optional< std::vector< int > > get_short_range_neighbors(System::System const &system, int const pid, double const distance)
Get ids of particles that are within a certain distance of another particle.
std::vector< std::pair< int, int > > get_pairs(System::System const &system, double const distance)
Get pairs closer than distance from the cells.
This file contains everything related to the global cell structure / cell system.
void add_parameters(std::vector< AutoParameter > &¶ms)
Variant do_call_method(std::string const &name, VariantMap const ¶ms) override
virtual void parallel_try_catch(std::function< void()> const &cb) const =0
virtual boost::mpi::communicator const & get_comm() const =0
VariantMap get_parameters() const
Get current parameters.
boost::string_ref name() const
Context * context() const
Responsible context.
auto const & get_system() const
Communicator communicator
This file contains the asynchronous MPI communication.
std::unordered_map< std::string, Variant > VariantMap
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.
constexpr const None none
None-"literal".
void gather_buffer(std::vector< T, Allocator > &buffer, boost::mpi::communicator const &comm, int root=0)
Gather buffer with different size on each node.
T product(Vector< T, N > const &v)
Various procedures concerning interactions between particles.
static auto & get_cell_structure()
void clear_particle_node()
Invalidate particle_node.
Particles creation and deletion.
static SteepestDescentParameters params
Currently active steepest descent instance.
Utils::Vector3i node_grid
void set_node_grid(Utils::Vector3i const &value)
Set new Cartesian topology.
static constexpr const ReadOnly read_only