eOn 3.2.0
Long-timescale dynamics: aKMC, NEB, parallel replica
☾
Toggle main menu visibility
Loading...
Searching...
No Matches
GroupSchedule.h
Go to the documentation of this file.
1
/*
2
** This file is part of eOn.
3
**
4
** SPDX-License-Identifier: BSD-3-Clause
5
**
6
** Copyright (c) 2010--present, eOn Development Team
7
** All rights reserved.
8
**
9
** Repo:
10
** https://github.com/TheochemUI/eOn
11
*/
12
#pragma once
13
14
#include "
eon/PbcSimd.h
"
15
16
#include <algorithm>
17
#include <cstddef>
18
#include <cstdint>
19
#include <limits>
20
#include <map>
21
#include <vector>
22
23
namespace
eonc
{
24
39
class
GroupSchedule
{
40
public
:
41
explicit
GroupSchedule
(
int
groups
) :
groups_
{std::max(
groups
, 1)} {}
42
43
[[nodiscard]]
int
groups
() const noexcept {
return
groups_
; }
44
47
[[nodiscard]]
int
defaultHome
(std::int64_t key,
long
position)
const
{
48
const
std::int64_t base = key >= 0 ? key : position;
49
return
static_cast<
int
>
(((base %
groups_
) +
groups_
) %
groups_
);
50
}
51
53
[[nodiscard]] std::vector<int>
assign
(
const
std::vector<std::int64_t> &keys) {
54
const
long
m =
static_cast<
long
>
(keys.size());
55
const
long
cap = (m +
groups_
- 1) /
groups_
;
56
std::vector<long> load(
static_cast<
size_t
>
(
groups_
), 0);
57
std::vector<int> route(
static_cast<
size_t
>
(m), -1);
58
for
(
long
j = 0; j < m; ++j) {
59
const
int
home =
homeOf
(keys[
static_cast<
size_t
>
(j)], j);
60
if
(load[
static_cast<
size_t
>
(home)] < cap) {
61
route[
static_cast<
size_t
>
(j)] = home;
62
++load[
static_cast<
size_t
>
(home)];
63
}
64
}
65
for
(
long
j = 0; j < m; ++j) {
66
if
(route[
static_cast<
size_t
>
(j)] >= 0)
67
continue
;
68
const
auto
least = std::min_element(load.begin(), load.end());
69
const
int
g =
static_cast<
int
>
(least - load.begin());
70
route[
static_cast<
size_t
>
(j)] = g;
71
++*least;
72
}
73
for
(
long
j = 0; j < m; ++j)
74
home_
[keys[
static_cast<
size_t
>
(j)]] = route[
static_cast<
size_t
>
(j)];
75
return
route;
76
}
77
79
void
record
(std::int64_t key,
const
double
*positions,
long
n3,
80
const
double
*cell =
nullptr
) {
81
auto
&stored =
last_
[key];
82
stored.assign(positions, positions + n3);
83
if
(cell)
84
cells_
[key].assign(cell, cell + 9);
85
else
86
cells_
.erase(key);
87
}
88
92
[[nodiscard]]
int
nearest
(
const
double
*positions,
long
n3,
93
const
double
*cell =
nullptr
)
const
{
94
double
best = std::numeric_limits<double>::infinity();
95
int
group = 0;
96
for
(
const
auto
&[key, stored] :
last_
) {
97
if
(
static_cast<
long
>
(stored.size()) != n3)
98
continue
;
99
const
auto
recordedCell =
cells_
.find(key);
100
if
(cell && recordedCell !=
cells_
.end() &&
101
!std::equal(recordedCell->second.begin(), recordedCell->second.end(),
102
cell))
103
continue
;
104
std::vector<double> differences(
static_cast<
size_t
>
(n3));
105
for
(
long
i = 0; i < n3; ++i) {
106
differences[
static_cast<
size_t
>
(i)] =
107
stored[
static_cast<
size_t
>
(i)] - positions[i];
108
}
109
if
(cell &&
110
std::any_of(cell, cell + 9, [](
double
x) {
return
x != 0.0; }))
111
pbc::closestDisplacements
(differences.data(), differences.size(), cell);
112
double
d2 = 0.0;
113
for
(
double
d : differences)
114
d2 += d * d;
115
const
auto
home =
home_
.find(key);
116
if
(d2 < best && home !=
home_
.end()) {
117
best = d2;
118
group = home->second;
119
}
120
}
121
return
group;
122
}
123
125
void
settle
(std::int64_t key,
int
group) {
home_
[key] = group; }
126
127
private
:
128
[[nodiscard]]
int
homeOf
(std::int64_t key,
long
position)
const
{
129
const
auto
it =
home_
.find(key);
130
return
it !=
home_
.end() ? it->second :
defaultHome
(key, position);
131
}
132
133
int
groups_
;
134
std::map<std::int64_t, int>
home_
;
135
std::map<std::int64_t, std::vector<double>>
last_
;
136
std::map<std::int64_t, std::vector<double>>
cells_
;
137
};
138
139
}
// namespace eonc
PbcSimd.h
eonc::GroupSchedule::cells_
std::map< std::int64_t, std::vector< double > > cells_
Definition
GroupSchedule.h:136
eonc::GroupSchedule::groups
int groups() const noexcept
Definition
GroupSchedule.h:43
eonc::GroupSchedule::assign
std::vector< int > assign(const std::vector< std::int64_t > &keys)
Groups for a batch of systems with these keys.
Definition
GroupSchedule.h:53
eonc::GroupSchedule::nearest
int nearest(const double *positions, long n3, const double *cell=nullptr) const
The group for a single request: the home of the recorded geometry nearest to positions (root-mean-squ...
Definition
GroupSchedule.h:92
eonc::GroupSchedule::homeOf
int homeOf(std::int64_t key, long position) const
Definition
GroupSchedule.h:128
eonc::GroupSchedule::home_
std::map< std::int64_t, int > home_
Definition
GroupSchedule.h:134
eonc::GroupSchedule::defaultHome
int defaultHome(std::int64_t key, long position) const
The home of a key never seen: key mod G for a key of zero or more, the batch position mod G otherwise...
Definition
GroupSchedule.h:47
eonc::GroupSchedule::settle
void settle(std::int64_t key, int group)
A single request's group becomes the home of the single-request key.
Definition
GroupSchedule.h:125
eonc::GroupSchedule::last_
std::map< std::int64_t, std::vector< double > > last_
Definition
GroupSchedule.h:135
eonc::GroupSchedule::groups_
int groups_
Definition
GroupSchedule.h:133
eonc::GroupSchedule::record
void record(std::int64_t key, const double *positions, long n3, const double *cell=nullptr)
Remember the geometry a key was last evaluated at.
Definition
GroupSchedule.h:79
eonc::GroupSchedule::GroupSchedule
GroupSchedule(int groups)
Definition
GroupSchedule.h:41
eonc::pbc::closestDisplacements
void closestDisplacements(double *data, size_t coordinates, const double *rowMajorCell)
Definition
MinimumImage.cpp:7
eonc
RAII resource manager for the ARTn C library with global synchronization.
Definition
ARTnSaddleSearch.cpp:23
include
eon
potentials
Rgpot
GroupSchedule.h
Generated by
1.17.0
Generated by
Doxygen 1.17.0
Analytics by
Antics
provided by
TurtleTech ehf