Skip to content

Commit e518b3f

Browse files
mohanchenabacus_fixer
andauthored
Refactor module_neighlist (#7498)
* update module_neighlist * remove magic numbers * update * update * update * update, add page_allocator * update --------- Co-authored-by: abacus_fixer <mohanchen@pku.eud.cn>
1 parent 289e5d0 commit e518b3f

22 files changed

Lines changed: 1557 additions & 746 deletions

source/source_cell/module_neighlist/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ add_library(
33
OBJECT
44
bin_manager.cpp
55
neighbor_search.cpp
6+
page_allocator.cpp
7+
unitcell_lite.cpp
68
)
79

810
if(ENABLE_COVERAGE)
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#ifndef ATOM_PROVIDER_H
2+
#define ATOM_PROVIDER_H
3+
4+
#include "source_base/vector3.h"
5+
#include "source_base/matrix3.h"
6+
7+
/**
8+
* @brief Interface for providing atom and lattice information.
9+
*
10+
* This abstract interface defines the minimum set of methods needed by
11+
* the neighbor search module to access atom positions and lattice parameters.
12+
* Any class implementing this interface can be used with NeighborSearch.
13+
*
14+
* @see UnitCell
15+
* @see UnitCellLite
16+
*/
17+
class AtomProvider
18+
{
19+
public:
20+
/**
21+
* @brief Default destructor.
22+
*/
23+
virtual ~AtomProvider() = default;
24+
25+
/**
26+
* @brief Get the lattice constant.
27+
* @return Lattice constant in Bohr.
28+
*/
29+
virtual double get_lat0() const = 0;
30+
31+
/**
32+
* @brief Get the volume of the unit cell.
33+
* @return Unit cell volume in Bohr^3.
34+
*/
35+
virtual double get_omega() const = 0;
36+
37+
/**
38+
* @brief Get the lattice vectors.
39+
* @return Const reference to the 3x3 lattice vector matrix.
40+
*/
41+
virtual const ModuleBase::Matrix3& get_latvec() const = 0;
42+
43+
/**
44+
* @brief Get the total number of atoms.
45+
* @return Total atom count.
46+
*/
47+
virtual int get_natom() const = 0;
48+
49+
/**
50+
* @brief Get the number of atoms of a specific type.
51+
* @param i Type index.
52+
* @return Number of atoms of type i.
53+
*/
54+
virtual int get_na(int i) const = 0;
55+
56+
/**
57+
* @brief Get the number of atom types.
58+
* @return Number of atom types.
59+
*/
60+
virtual int get_ntype() const = 0;
61+
62+
/**
63+
* @brief Get the Cartesian coordinates of a specific atom.
64+
*
65+
* Returns the position of the j-th atom of type i.
66+
*
67+
* @param i Type index.
68+
* @param j Atom index within type i.
69+
* @return Cartesian position vector.
70+
*/
71+
virtual ModuleBase::Vector3<double> get_tau(int i, int j) const = 0;
72+
};
73+
74+
#endif // ATOM_PROVIDER_H
Lines changed: 124 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,131 @@
11
#include <limits>
22
#include <cmath>
33
#include <algorithm>
4+
#include <cassert>
45
#include "bin_manager.h"
56

7+
// ========== Bin class implementation ==========
68

9+
int Bin::get_id_x() const {
10+
return id_x_;
11+
}
12+
13+
int Bin::get_id_y() const {
14+
return id_y_;
15+
}
16+
17+
int Bin::get_id_z() const {
18+
return id_z_;
19+
}
20+
21+
const std::vector<NeighborAtom>& Bin::get_atoms() const {
22+
return atoms_;
23+
}
24+
25+
void Bin::set_id(int ix, int iy, int iz) {
26+
id_x_ = ix;
27+
id_y_ = iy;
28+
id_z_ = iz;
29+
}
30+
31+
void Bin::clear_atoms() {
32+
atoms_.clear();
33+
}
34+
35+
void Bin::add_atom(const NeighborAtom& atom) {
36+
atoms_.push_back(atom);
37+
}
38+
39+
// ========== BinManager getter methods ==========
40+
41+
int BinManager::get_nbinx() const {
42+
return nbinx_;
43+
}
44+
45+
int BinManager::get_nbiny() const {
46+
return nbiny_;
47+
}
48+
49+
int BinManager::get_nbinz() const {
50+
return nbinz_;
51+
}
52+
53+
int BinManager::get_total_bins() const {
54+
return static_cast<int>(bins_.size());
55+
}
56+
57+
int BinManager::get_bin_atom_count(int bin_index) const {
58+
if (bin_index < 0 || bin_index >= static_cast<int>(bins_.size())) {
59+
return 0;
60+
}
61+
return static_cast<int>(bins_[bin_index].get_atoms().size());
62+
}
63+
64+
// ========== BinManager main methods ==========
765

866
void BinManager::init_bins(
967
double sr,
1068
const std::vector<NeighborAtom>& inside_atoms,
1169
const std::vector<NeighborAtom>& ghost_atoms
1270
)
1371
{
14-
sradius = sr;
72+
sradius_ = sr;
1573
if(inside_atoms.empty() && ghost_atoms.empty())
1674
{
17-
x_min=y_min=z_min=0;
18-
x_max=y_max=z_max=0;
19-
nbinx=nbiny=nbinz=1;
20-
bins.clear();
21-
bins.resize(1);
75+
x_min_ = y_min_ = z_min_ = 0;
76+
x_max_ = y_max_ = z_max_ = 0;
77+
nbinx_ = nbiny_ = nbinz_ = 1;
78+
bins_.clear();
79+
bins_.resize(1);
2280
return;
2381
}
2482

25-
x_min = y_min = z_min = std::numeric_limits<double>::max();
26-
27-
x_max = y_max = z_max = std::numeric_limits<double>::lowest();
28-
83+
x_min_ = y_min_ = z_min_ = std::numeric_limits<double>::max();
84+
x_max_ = y_max_ = z_max_ = std::numeric_limits<double>::lowest();
2985

3086
auto update_bounds = [&](const std::vector<NeighborAtom>& atoms)
3187
{
3288
for (const auto& atom : atoms)
3389
{
34-
x_min = std::min(x_min, atom.position_x);
35-
x_max = std::max(x_max, atom.position_x);
90+
x_min_ = std::min(x_min_, atom.position_x);
91+
x_max_ = std::max(x_max_, atom.position_x);
3692

37-
y_min = std::min(y_min, atom.position_y);
38-
y_max = std::max(y_max, atom.position_y);
93+
y_min_ = std::min(y_min_, atom.position_y);
94+
y_max_ = std::max(y_max_, atom.position_y);
3995

40-
z_min = std::min(z_min, atom.position_z);
41-
z_max = std::max(z_max, atom.position_z);
96+
z_min_ = std::min(z_min_, atom.position_z);
97+
z_max_ = std::max(z_max_, atom.position_z);
4298
}
4399
};
44100

45101
update_bounds(inside_atoms);
46102
update_bounds(ghost_atoms);
47103

48-
bin_sizex = bin_sizey = bin_sizez = sradius;
104+
bin_sizex_ = bin_sizey_ = bin_sizez_ = sradius_;
49105

50-
nbinx = std::ceil((x_max - x_min) / bin_sizex);
51-
nbiny = std::ceil((y_max - y_min) / bin_sizey);
52-
nbinz = std::ceil((z_max - z_min) / bin_sizez);
106+
nbinx_ = std::ceil((x_max_ - x_min_) / bin_sizex_);
107+
nbiny_ = std::ceil((y_max_ - y_min_) / bin_sizey_);
108+
nbinz_ = std::ceil((z_max_ - z_min_) / bin_sizez_);
53109

54-
nbinx = std::max(1, nbinx);
55-
nbiny = std::max(1, nbiny);
56-
nbinz = std::max(1, nbinz);
110+
nbinx_ = std::max(1, nbinx_);
111+
nbiny_ = std::max(1, nbiny_);
112+
nbinz_ = std::max(1, nbinz_);
57113

58-
int nbins = nbinx * nbiny * nbinz;
114+
int nbins = nbinx_ * nbiny_ * nbinz_;
59115

60-
bins.clear();
116+
bins_.clear();
117+
bins_.resize(nbins);
61118

62-
bins.resize(nbins);
63-
64-
for (int ix = 0; ix < nbinx; ++ix)
119+
for (int ix = 0; ix < nbinx_; ++ix)
65120
{
66-
for (int iy = 0; iy < nbiny; ++iy)
121+
for (int iy = 0; iy < nbiny_; ++iy)
67122
{
68-
for (int iz = 0; iz < nbinz; ++iz)
123+
for (int iz = 0; iz < nbinz_; ++iz)
69124
{
70-
int idx = ix * nbiny * nbinz + iy * nbinz + iz;
71-
72-
bins[idx].id_x = ix;
73-
bins[idx].id_y = iy;
74-
bins[idx].id_z = iz;
125+
int idx = bin_index(ix, iy, iz);
75126

76-
bins[idx].atoms.clear();
127+
bins_[idx].set_id(ix, iy, iz);
128+
bins_[idx].clear_atoms();
77129
}
78130
}
79131
}
@@ -87,58 +139,63 @@ void BinManager::do_binning(
87139
auto bin_atom = [&](const NeighborAtom& atom)
88140
{
89141
int ix = std::min(
90-
std::max(int((atom.position_x - x_min) / bin_sizex), 0),
91-
nbinx - 1
142+
std::max(int((atom.position_x - x_min_) / bin_sizex_), 0),
143+
nbinx_ - 1
92144
);
93145

94146
int iy = std::min(
95-
std::max(int((atom.position_y - y_min) / bin_sizey), 0),
96-
nbiny - 1
147+
std::max(int((atom.position_y - y_min_) / bin_sizey_), 0),
148+
nbiny_ - 1
97149
);
98150

99151
int iz = std::min(
100-
std::max(int((atom.position_z - z_min) / bin_sizez), 0),
101-
nbinz - 1
152+
std::max(int((atom.position_z - z_min_) / bin_sizez_), 0),
153+
nbinz_ - 1
102154
);
103155

104-
int idx = ix * nbiny * nbinz + iy * nbinz + iz;
156+
int idx = bin_index(ix, iy, iz);
105157

106-
bins[idx].atoms.push_back(atom);
158+
bins_[idx].add_atom(atom);
107159
};
108160

109161
for (const auto& atom : inside_atoms) bin_atom(atom);
110-
111162
for (const auto& atom : ghost_atoms) bin_atom(atom);
112163
}
113164

165+
int BinManager::bin_index(int ix, int iy, int iz) const {
166+
return ix * nbiny_ * nbinz_ + iy * nbinz_ + iz;
167+
}
168+
114169
void BinManager::build_atom_neighbors(
115170
NeighborList& neighbor_list,
116171
std::vector<NeighborAtom>& atoms
117172
)
118173
{
119-
assert(atoms.size() == neighbor_list.numneigh.size());
174+
assert(atoms.size() == static_cast<size_t>(neighbor_list.get_nlocal()));
120175

121-
double sradius2 = sradius * sradius;
176+
double sradius2 = sradius_ * sradius_;
122177

123178
neighbor_list.reset();
124179

180+
std::vector<int> neigh_tmp;
181+
125182
for (int i = 0; i < atoms.size(); i++)
126183
{
127-
std::vector<int> neigh_tmp;
184+
neigh_tmp.clear();
128185

129186
int ix = std::min(
130-
std::max(int((atoms[i].position_x - x_min) / bin_sizex), 0),
131-
nbinx - 1
187+
std::max(int((atoms[i].position_x - x_min_) / bin_sizex_), 0),
188+
nbinx_ - 1
132189
);
133190

134191
int iy = std::min(
135-
std::max(int((atoms[i].position_y - y_min) / bin_sizey), 0),
136-
nbiny - 1
192+
std::max(int((atoms[i].position_y - y_min_) / bin_sizey_), 0),
193+
nbiny_ - 1
137194
);
138195

139196
int iz = std::min(
140-
std::max(int((atoms[i].position_z - z_min) / bin_sizez), 0),
141-
nbinz - 1
197+
std::max(int((atoms[i].position_z - z_min_) / bin_sizez_), 0),
198+
nbinz_ - 1
142199
);
143200

144201
for (int dx = -1; dx <= 1; dx++)
@@ -151,14 +208,14 @@ void BinManager::build_atom_neighbors(
151208
int jy = iy + dy;
152209
int jz = iz + dz;
153210

154-
if (jx < 0 || jx >= nbinx ||
155-
jy < 0 || jy >= nbiny ||
156-
jz < 0 || jz >= nbinz)
211+
if (jx < 0 || jx >= nbinx_ ||
212+
jy < 0 || jy >= nbiny_ ||
213+
jz < 0 || jz >= nbinz_)
157214
continue;
158215

159-
int nidx = jx * nbiny * nbinz + jy * nbinz + jz;
216+
int nidx = bin_index(jx, jy, jz);
160217

161-
for (const NeighborAtom& natom : bins[nidx].atoms)
218+
for (const NeighborAtom& natom : bins_[nidx].get_atoms())
162219
{
163220
double dx = atoms[i].position_x - natom.position_x;
164221
double dy = atoms[i].position_y - natom.position_y;
@@ -173,30 +230,29 @@ void BinManager::build_atom_neighbors(
173230
}
174231
}
175232
}
176-
}
233+
}
234+
177235
int n = neigh_tmp.size();
178236

179-
//std::cout<<n<<std::endl;
237+
int* ptr = neighbor_list.allocator_.allocate(n);
180238

181-
int* ptr = neighbor_list.allocator.allocate(n);
182-
183239
for (int k = 0; k < n; k++)
184240
{
185241
assert(ptr != nullptr);
186242
ptr[k] = neigh_tmp[k];
187243
}
188244

189-
neighbor_list.firstneigh[i] = ptr;
190-
neighbor_list.numneigh[i] = n;
245+
neighbor_list.firstneigh_[i] = ptr;
246+
neighbor_list.numneigh_[i] = n;
191247
}
192248
}
193249

194250
void BinManager::clear()
195251
{
196-
for (auto& bin : bins)
252+
for (auto& bin : bins_)
197253
{
198-
bin.atoms.clear();
254+
bin.clear_atoms();
199255
}
200256

201-
bins.clear();
257+
bins_.clear();
202258
}

0 commit comments

Comments
 (0)