Skip to content

Commit 1de729f

Browse files
committed
add some comments
1 parent d089214 commit 1de729f

File tree

4 files changed

+61
-28
lines changed

4 files changed

+61
-28
lines changed

source/module_cell/module_neighbor/sltk_grid.cpp

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ void Grid::init(std::ofstream& ofs_in, const UnitCell& ucell, const double radiu
2121
this->pbc = boundary;
2222
this->sradius2 = radius_in * radius_in;
2323
this->sradius = radius_in;
24+
// 20241210 zhanghaochong
25+
// Considering the possibility that a Grid instance might have its init method called again without
26+
// being destructed or destroyed, it would be better to destroy the member variables here to prevent
27+
// issues, even though such a scenario reflects poor programming practices.
28+
this->clear_atoms();
2429

2530
ModuleBase::GlobalFunc::OUT(ofs_in, "PeriodicBoundary", this->pbc);
2631
ModuleBase::GlobalFunc::OUT(ofs_in, "Radius(unit:lat0)", sradius);
@@ -116,21 +121,21 @@ void Grid::Check_Expand_Condition(const UnitCell& ucell)
116121
double a23_norm = sqrt(a23_1 * a23_1 + a23_2 * a23_2 + a23_3 * a23_3);
117122
double extend_v = a23_norm * sradius;
118123
double extend_d1 = extend_v / ucell.omega * ucell.lat0 * ucell.lat0 * ucell.lat0;
119-
int extend_d11 = std::ceil(extend_d1);
124+
int extend_d11 = static_cast<int>(std::ceil(extend_d1));
120125

121126
double a31_1 = ucell.latvec.e32 * ucell.latvec.e13 - ucell.latvec.e33 * ucell.latvec.e12;
122127
double a31_2 = ucell.latvec.e31 * ucell.latvec.e13 - ucell.latvec.e33 * ucell.latvec.e11;
123128
double a31_3 = ucell.latvec.e31 * ucell.latvec.e12 - ucell.latvec.e32 * ucell.latvec.e11;
124129
double a31_norm = sqrt(a31_1 * a31_1 + a31_2 * a31_2 + a31_3 * a31_3);
125130
double extend_d2 = a31_norm * sradius / ucell.omega * ucell.lat0 * ucell.lat0 * ucell.lat0;
126-
int extend_d22 = std::ceil(extend_d2);
131+
int extend_d22 = static_cast<int>(std::ceil(extend_d2));
127132

128133
double a12_1 = ucell.latvec.e12 * ucell.latvec.e23 - ucell.latvec.e13 * ucell.latvec.e22;
129134
double a12_2 = ucell.latvec.e11 * ucell.latvec.e23 - ucell.latvec.e13 * ucell.latvec.e21;
130135
double a12_3 = ucell.latvec.e11 * ucell.latvec.e22 - ucell.latvec.e12 * ucell.latvec.e21;
131136
double a12_norm = sqrt(a12_1 * a12_1 + a12_2 * a12_2 + a12_3 * a12_3);
132137
double extend_d3 = a12_norm * sradius / ucell.omega * ucell.lat0 * ucell.lat0 * ucell.lat0;
133-
int extend_d33 = std::ceil(extend_d3);
138+
int extend_d33 = static_cast<int>(std::ceil(extend_d3));
134139
// 2016-09-05, LiuXh
135140

136141
glayerX = extend_d11 + 1;
@@ -148,7 +153,8 @@ void Grid::setMemberVariables(std::ofstream& ofs_in, // output data to ofs
148153
const UnitCell& ucell)
149154
{
150155
ModuleBase::TITLE("SLTK_Grid", "setMemberVariables");
151-
156+
// 20241210 zhanghaochong
157+
// To prevent the possibility of someone calling setMemberVariables twice.
152158
this->clear_atoms();
153159

154160
// random selection, in order to estimate again.
@@ -170,19 +176,19 @@ void Grid::setMemberVariables(std::ofstream& ofs_in, // output data to ofs
170176
{
171177
for (int iz = -glayerZ_minus; iz < glayerZ; iz++)
172178
{
173-
for (int i = 0; i < ucell.ntype; i++)
179+
for (int j_type = 0; j_type < ucell.ntype; j_type++)
174180
{
175-
for (int j = 0; j < ucell.atoms[i].na; j++)
181+
for (int k_natom = 0; k_natom < ucell.atoms[j_type].na; k_natom++)
176182
{
177-
double x = ucell.atoms[i].tau[j].x + vec1[0] * ix + vec2[0] * iy + vec3[0] * iz;
178-
double y = ucell.atoms[i].tau[j].y + vec1[1] * ix + vec2[1] * iy + vec3[1] * iz;
179-
double z = ucell.atoms[i].tau[j].z + vec1[2] * ix + vec2[2] * iy + vec3[2] * iz;
180-
x_min = std::min(x_min, x);
181-
x_max = std::max(x_max, x);
182-
y_min = std::min(y_min, y);
183-
y_max = std::max(y_max, y);
184-
z_min = std::min(z_min, z);
185-
z_max = std::max(z_max, z);
183+
double x = ucell.atoms[j_type].tau[k_natom].x + vec1[0] * ix + vec2[0] * iy + vec3[0] * iz;
184+
double y = ucell.atoms[j_type].tau[k_natom].y + vec1[1] * ix + vec2[1] * iy + vec3[1] * iz;
185+
double z = ucell.atoms[j_type].tau[k_natom].z + vec1[2] * ix + vec2[2] * iy + vec3[2] * iz;
186+
this->x_min = std::min(this->x_min, x);
187+
this->x_max = std::max(this->x_max, x);
188+
this->y_min = std::min(this->y_min, y);
189+
this->y_max = std::max(this->y_max, y);
190+
this->z_min = std::min(this->z_min, z);
191+
this->z_max = std::max(this->z_max, z);
186192
}
187193
}
188194
}
@@ -194,11 +200,17 @@ void Grid::setMemberVariables(std::ofstream& ofs_in, // output data to ofs
194200

195201
this->box_edge_length = sradius + 0.1; // To avoid edge cases, the size of the box is slightly increased.
196202

203+
// 20241210 zhanghaochong +1 maybe unnecessary.
197204
this->box_nx = std::ceil((this->x_max - this->x_min) / box_edge_length) + 1;
198205
this->box_ny = std::ceil((this->y_max - this->y_min) / box_edge_length) + 1;
199206
this->box_nz = std::ceil((this->z_max - this->z_min) / box_edge_length) + 1;
200207
ModuleBase::GlobalFunc::OUT(ofs_in, "BoxNumber", box_nx, box_ny, box_nz);
201208

209+
210+
// 20241210 zhanghaochong
211+
// atoms_in_box and all_adj_info vector part must not undergo any push_back or erase operations during
212+
// use. After resizing during initialization, they size should not be modified.
213+
202214
atoms_in_box.resize(this->box_nx);
203215
for (int i = 0; i < this->box_nx; i++)
204216
{
@@ -216,14 +228,14 @@ void Grid::setMemberVariables(std::ofstream& ofs_in, // output data to ofs
216228
{
217229
for (int iz = -glayerZ_minus; iz < glayerZ; iz++)
218230
{
219-
for (int i = 0; i < ucell.ntype; i++)
231+
for (int j_type = 0; j_type < ucell.ntype; j_type++)
220232
{
221-
for (int j = 0; j < ucell.atoms[i].na; j++)
233+
for (int k_natom = 0; k_natom < ucell.atoms[j_type].na; k_natom++)
222234
{
223-
double x = ucell.atoms[i].tau[j].x + vec1[0] * ix + vec2[0] * iy + vec3[0] * iz;
224-
double y = ucell.atoms[i].tau[j].y + vec1[1] * ix + vec2[1] * iy + vec3[1] * iz;
225-
double z = ucell.atoms[i].tau[j].z + vec1[2] * ix + vec2[2] * iy + vec3[2] * iz;
226-
FAtom atom(x, y, z, i, j, ix, iy, iz);
235+
double x = ucell.atoms[j_type].tau[k_natom].x + vec1[0] * ix + vec2[0] * iy + vec3[0] * iz;
236+
double y = ucell.atoms[j_type].tau[k_natom].y + vec1[1] * ix + vec2[1] * iy + vec3[1] * iz;
237+
double z = ucell.atoms[j_type].tau[k_natom].z + vec1[2] * ix + vec2[2] * iy + vec3[2] * iz;
238+
FAtom atom(x, y, z, j_type, k_natom, ix, iy, iz);
227239
int box_i_x, box_i_y, box_i_z;
228240
this->getBox(box_i_x, box_i_y, box_i_z, x, y, z);
229241
this->atoms_in_box[box_i_x][box_i_y][box_i_z].push_back(atom);
@@ -299,7 +311,7 @@ void Grid::Construct_Adjacent_final(const FAtom& fatom1,
299311
// dr == 0 means the same atom
300312
// the atom itself is neighbour atom, but the order itself must on last in the list.
301313
// so we will add itself on find atom function, and skip here.
302-
// I dont know why, but if we add self here, test 701_LJ_MD_Anderson will assert
314+
303315
if (dr != 0.0 && dr <= this->sradius2)
304316
{
305317
all_adj_info[fatom1.type][fatom1.natom].push_back(fatom2);

source/module_cell/module_neighbor/sltk_grid.h

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
#include <stdexcept>
1010
#include <tuple>
1111
#include <unordered_map>
12-
13-
typedef std::vector<FAtom> AtomMap;
12+
#include <vector>
13+
#include <list>
1414

1515
class Grid
1616
{
@@ -49,17 +49,33 @@ class Grid
4949
by = std::floor((y - y_min) / box_edge_length);
5050
bz = std::floor((z - z_min) / box_edge_length);
5151
}
52+
53+
// 20241210 zhanghaochong
54+
// Here, instances of all atoms are stored as a single copy in the atoms_in_box structure,
55+
// which is a quadruple nested combination of vector and list. The all_adj_info structure only
56+
// stores pointers that reference the memory of atoms_in_box. Please note that vector is !NOT! a
57+
// memory-stable data structure. During operations such as resize or push_back, the addresses of
58+
// existing data within the vector may change. Therefore, if atoms_in_box undergoes resize, push_back,
59+
// or erase after all_adj_info has been set to point to it, the pointers in all_adj_info will
60+
// result in memory leaks.
61+
// Therefore, atoms_in_box and all_adj_info vector part must not undergo any push_back or erase operations during
62+
// use. After resizing during initialization, they should not be modified.
63+
5264
// Stores the atoms after box partitioning.
53-
std::vector<std::vector<std::vector<AtomMap>>> atoms_in_box;
65+
std::vector<std::vector<std::vector< std::list<FAtom> >>> atoms_in_box;
5466

5567
// Stores the adjacent information of atoms. [ntype][natom][adj list]
56-
std::vector<std::vector< std::vector<FAtom *> >> all_adj_info;
68+
std::vector<std::vector< std::list<FAtom *> >> all_adj_info;
69+
// There are two main benefits to storing atomic information in a single copy and using pointers for
70+
// the other. On one hand, the construction and copying cost of the fatom class during computation
71+
// should not be underestimated. On the other hand, it saves memory. If we need to deal with millions
72+
// of atoms, just storing the atoms themselves would consume a significant amount of memory.
73+
5774
void clear_atoms()
5875
{
5976
// we have to clear the all_adj_info
6077
// because the pointers point to the memory in vector atoms_in_box
6178
all_adj_info.clear();
62-
6379
atoms_in_box.clear();
6480
}
6581
void clear_adj_info()

source/module_cell/module_neighbor/sltk_grid_driver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ void Grid_Driver::Find_atom(const UnitCell& ucell,
3333
// store result in member adj_info when parameter adjs is NULL
3434
AdjacentAtomInfo* local_adjs = adjs == nullptr ? &this->adj_info : adjs;
3535
local_adjs->clear();
36-
const std::vector<FAtom*>& all_atom = all_adj_info[ntype][nnumber];
36+
const std::list<FAtom*>& all_atom = all_adj_info[ntype][nnumber];
3737

3838
for (const FAtom* atom: all_atom)
3939
{

source/module_cell/module_neighbor/sltk_grid_driver.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ class Grid_Driver : public Grid
6262
// by default.
6363
// 2. And store results into parameter adjs when adjs is
6464
// NOT NULL
65+
// Find_atom store results in Grid_Driver::adj_info still kept mainly for compatibility purposes.
66+
// Grid_Driver::adj_info is a poor design and is NOT thread-safe.
67+
// Please try to use the AdjacentAtomInfo* adjs parameter passing method to obtain the neighboring
68+
// atom list results.
6569
//==========================================================
6670
void Find_atom(const UnitCell& ucell,
6771
const int ntype,
@@ -70,6 +74,7 @@ class Grid_Driver : public Grid
7074

7175
// cartesian_posi and ucell is deprecated 20241204 zhanghaochong
7276
// this interface is deprecated, please use Find_atom above
77+
// This interface is still kept mainly for compatibility purposes.
7378
void Find_atom(const UnitCell& ucell,
7479
const ModuleBase::Vector3<double>& cartesian_posi,
7580
const int& ntype,

0 commit comments

Comments
 (0)