22#include < limits>
33#include " module_hamilt_pw/hamilt_pwdft/parallel_grid.h"
44// #include "module_base/global_variable.h" // GlobalV reference removed
5+ inline void xyz2zxy (const double * const xyz, const int nx, const int ny, const int nz, double * const zxy)
6+ {
7+ for (int ix = 0 ; ix < nx; ix++)
8+ {
9+ for (int iy = 0 ; iy < ny; iy++)
10+ {
11+ for (int iz = 0 ; iz < nz; iz++)
12+ {
13+ zxy[(iz * nx + ix) * ny + iy] = xyz[(ix * ny + iy) * nz + iz];
14+ }
15+ }
16+ }
17+ }
518
619bool ModuleIO::read_cube (
720 const Parallel_Grid& pgrid,
@@ -12,133 +25,66 @@ bool ModuleIO::read_cube(
1225 const int natom)
1326{
1427 ModuleBase::TITLE (" ModuleIO" , " read_cube" );
28+
29+ // check if the file exists
1530 std::ifstream ifs (fn.c_str ());
1631 if (!ifs)
1732 {
18- std::string tmp_warning_info = " !!! Couldn't find the charge file of " ;
19- tmp_warning_info += fn;
33+ std::string tmp_warning_info = " !!! Couldn't find the file: " + fn;
2034 ofs_running << tmp_warning_info << std::endl;
2135 return false ;
2236 }
2337 else
2438 {
25- ofs_running << " Find the file, try to read charge from file ." << std::endl;
39+ ofs_running << " Find the file " << fn << " , try to read it ." << std::endl;
2640 }
2741
28- // skip the first 3 lines
29- for (int i = 0 ;i < 3 ;++i) { ifs.ignore (std::numeric_limits<std::streamsize>::max (), ' \n ' ); }
30-
31- int nx_read = 0 ;
32- int ny_read = 0 ;
33- int nz_read = 0 ;
34- std::string temp;
35-
36- ifs >> nx_read;
37- ifs >> temp >> temp >> temp;
38- ifs >> ny_read;
39- ifs >> temp >> temp >> temp;
40- ifs >> nz_read;
41- ifs >> temp >> temp >> temp;
42-
42+ // read the full grid data
4343 const int & nx = pgrid.nx ;
4444 const int & ny = pgrid.ny ;
4545 const int & nz = pgrid.nz ;
46+ const int & nxyz = nx * ny * nz;
47+ std::vector<double > data_zxy_full (nxyz); // [iz][ix][iy]
48+ if (my_rank == 0 )
49+ {
50+ const CubeInfo& cube_info = ModuleIO::read_cube (fn);
4651
47- // skip this line and the next natom lines
48- for (int i = 0 ;i < natom + 1 ;++i) { ifs.ignore (std::numeric_limits<std::streamsize>::max (), ' \n ' ); }
49-
50- #ifdef __MPI
51- if (nx == nx_read && ny == ny_read && nz == nz_read)
52- ModuleIO::read_cube_core_match (ifs, pgrid, (my_rank == 0 ), data, nx * ny, nz);
53- else
54- ModuleIO::read_cube_core_mismatch (ifs, pgrid, (my_rank == 0 ), data, nx, ny, nz, nx_read, ny_read, nz_read);
55- #else
56-
57- if (nx == nx_read && ny == ny_read && nz == nz_read)
58- ModuleIO::read_cube_core_match (ifs, pgrid, (my_rank == 0 ), data, nx * ny, nz);
59- else
60- ModuleIO::read_cube_core_mismatch (ifs, pgrid, (my_rank == 0 ), data, nx, ny, nz, nx_read, ny_read, nz_read);
61- #endif
62-
63- return true ;
64- }
52+ const int & nx_read = cube_info.nvoxel [0 ];
53+ const int & ny_read = cube_info.nvoxel [1 ];
54+ const int & nz_read = cube_info.nvoxel [2 ];
6555
66- void ModuleIO::read_cube_core_match (
67- std::ifstream& ifs,
68- const Parallel_Grid& pgrid,
69- const bool flag_read_rank,
70- double *const data,
71- const int nxy,
72- const int nz)
73- {
74- #ifdef __MPI
75- if (flag_read_rank)
76- {
77- std::vector<std::vector<double >> read_rho (nz, std::vector<double >(nxy));
78- for (int ixy = 0 ; ixy < nxy; ixy++)
79- for (int iz = 0 ; iz < nz; iz++)
80- ifs >> read_rho[iz][ixy];
81- for (int iz = 0 ; iz < nz; iz++)
82- pgrid.zpiece_to_all (read_rho[iz].data (), iz, data);
83- }
84- else
85- {
86- std::vector<double > zpiece (nxy);
87- for (int iz = 0 ; iz < nz; iz++)
88- pgrid.zpiece_to_all (zpiece.data (), iz, data);
56+ // if mismatch, trilinear interpolate
57+ if (nx == nx_read && ny == ny_read && nz == nz_read)
58+ {
59+ xyz2zxy (cube_info.data .data (), nx, ny, nz, data_zxy_full.data ());
60+ }
61+ else
62+ {
63+ std::vector<double > data_xyz_full (nxyz);
64+ trilinear_interpolate (cube_info.data .data (), nx_read, ny_read, nz_read, nx, ny, nz, data_xyz_full.data ());
65+ xyz2zxy (data_xyz_full.data (), nx, ny, nz, data_zxy_full.data ());
66+ }
8967 }
90- #else
91- for (int ixy = 0 ; ixy < nxy; ixy++)
92- for (int iz = 0 ; iz < nz; iz++)
93- ifs >> data[iz * nxy + ixy];
94- #endif
95- }
9668
97- void ModuleIO::read_cube_core_mismatch (
98- std::ifstream &ifs,
99- const Parallel_Grid& pgrid,
100- const bool flag_read_rank,
101- double *const data,
102- const int nx,
103- const int ny,
104- const int nz,
105- const int nx_read,
106- const int ny_read,
107- const int nz_read)
108- {
109- #ifdef __MPI
69+ // distribute
70+ #ifdef __MPI
11071 const int nxy = nx * ny;
111- if (flag_read_rank)
112- {
113- std::vector<std::vector<double >> read_rho (nz, std::vector<double >(nxy));
114- ModuleIO::trilinear_interpolate (ifs, nx_read, ny_read, nz_read, nx, ny, nz, read_rho);
115- for (int iz = 0 ; iz < nz; iz++)
116- pgrid.zpiece_to_all (read_rho[iz].data (), iz, data);
117- }
118- else
119- {
120- std::vector<double > zpiece (nxy);
121- for (int iz = 0 ; iz < nz; iz++)
122- pgrid.zpiece_to_all (zpiece.data (), iz, data);
123- }
72+ for (int iz = 0 ;iz < nz;++iz) { pgrid.zpiece_to_all (data_zxy_full.data () + iz * nxy, iz, data); }
12473#else
125- ModuleIO::trilinear_interpolate (ifs, nx_read, ny_read, nz_read, nx, ny, nz, data );
74+ std::memcpy (data_zxy_full. data (), data, nxyz * sizeof ( double ) );
12675#endif
76+ return true ;
12777}
12878
129- void ModuleIO::trilinear_interpolate (std::ifstream& ifs,
130- const int & nx_read,
131- const int & ny_read,
132- const int & nz_read,
133- const int & nx,
134- const int & ny,
135- const int & nz,
136- #ifdef __MPI
137- std::vector<std::vector<double >> &data
138- #else
139- double * data
140- #endif
141- )
79+ void ModuleIO::trilinear_interpolate (
80+ const double * const data_in,
81+ const int & nx_read,
82+ const int & ny_read,
83+ const int & nz_read,
84+ const int & nx,
85+ const int & ny,
86+ const int & nz,
87+ double * data_out)
14288{
14389 ModuleBase::TITLE (" ModuleIO" , " trilinear_interpolate" );
14490
@@ -153,7 +99,7 @@ void ModuleIO::trilinear_interpolate(std::ifstream& ifs,
15399 {
154100 for (int iz = 0 ; iz < nz_read; iz++)
155101 {
156- ifs >> read_rho[iz][ix * ny_read + iy];
102+ read_rho[iz][ix * ny_read + iy] = data_in[(ix * ny_read + iy) * nz_read + iz ];
157103 }
158104 }
159105 }
@@ -189,11 +135,7 @@ void ModuleIO::trilinear_interpolate(std::ifstream& ifs,
189135 + read_rho[highz][lowx * ny_read + highy] * (1 - dx) * dy * dz
190136 + read_rho[highz][highx * ny_read + highy] * dx * dy * dz;
191137
192- #ifdef __MPI
193- data[iz][ix * ny + iy] = result;
194- #else
195- data[iz * nx * ny + ix * ny + iy] = result;
196- #endif
138+ data_out[(ix * ny + iy) * nz + iz] = result; // x > y > z order, consistent with the cube file
197139 }
198140 }
199141 }
@@ -203,4 +145,45 @@ void ModuleIO::trilinear_interpolate(std::ifstream& ifs,
203145 delete[] read_rho[iz];
204146 }
205147 delete[] read_rho;
148+ }
149+
150+ ModuleIO::CubeInfo ModuleIO::read_cube (const std::string& file)
151+ {
152+ std::ifstream ifs (file);
153+
154+ if (!ifs) { return ModuleIO::CubeInfo ({}, 0 , {}, {}, {}, {}, {}, {}, {}, false ); }
155+
156+ std::vector<std::string> comment (2 );
157+ for (auto & c : comment) { std::getline (ifs, c); }
158+
159+ int natom;
160+ ifs >> natom;
161+ std::vector<double > cell_pos (3 );
162+ for (auto & cp : cell_pos) { ifs >> cp; }
163+
164+ std::vector<int > nvoxel (3 );
165+ std::vector<std::vector<double >> axis_vecs (3 );
166+ for (int i = 0 ;i < 3 ;++i)
167+ {
168+ std::vector<double > vec (3 );
169+ ifs >> nvoxel[i] >> vec[0 ] >> vec[1 ] >> vec[2 ];
170+ axis_vecs.push_back (vec);
171+ }
172+
173+ std::vector<int > itype (natom);
174+ std::vector<double > charge (natom);
175+ std::vector<std::vector<double >> atom_pos (natom);
176+ for (int i = 0 ;i < natom;++i)
177+ {
178+ std::vector<double > apos (3 );
179+ ifs >> itype[i] >> charge[i] >> apos[0 ] >> apos[1 ] >> apos[2 ];
180+ atom_pos.push_back (apos);
181+ }
182+
183+ const int nxyz = nvoxel[0 ] * nvoxel[1 ] * nvoxel[2 ];
184+ std::vector<double > data (nxyz);
185+ for (int i = 0 ;i < nxyz;++i) { ifs >> data[i]; }
186+
187+ ifs.close ();
188+ return ModuleIO::CubeInfo (comment, natom, cell_pos, nvoxel, axis_vecs, itype, charge, atom_pos, data, true );
206189}
0 commit comments