2121#include " source_io/module_output/output_log.h"
2222#include " source_io/module_parameter/parameter.h"
2323
24- #include < numeric >
24+ #include < algorithm >
2525#include < unordered_map>
2626
2727using namespace ModuleESolver ;
@@ -35,6 +35,9 @@ void ESolver_NEP::before_all_runners(BaseCell& basecell, const Input_para& inp)
3535 nep_force.create (ucell.nat , 3 );
3636 nep_virial.create (3 , 3 );
3737 atype.resize (ucell.nat );
38+ nep_cell.resize (9 );
39+ nep_coord.resize (3 * ucell.nat );
40+ nep_virial_sum.resize (9 );
3841 _e.resize (ucell.nat );
3942 _f.resize (3 * ucell.nat );
4043 _v.resize (9 * ucell.nat );
@@ -55,51 +58,54 @@ void ESolver_NEP::runner(BaseCell& basecell, const int istep)
5558
5659 // note that NEP are column major, thus a transpose is needed
5760 // cell
58- std::vector<double > cell (9 , 0.0 );
59- cell[0 ] = ucell.latvec .e11 * ucell.lat0_angstrom ;
60- cell[1 ] = ucell.latvec .e21 * ucell.lat0_angstrom ;
61- cell[2 ] = ucell.latvec .e31 * ucell.lat0_angstrom ;
62- cell[3 ] = ucell.latvec .e12 * ucell.lat0_angstrom ;
63- cell[4 ] = ucell.latvec .e22 * ucell.lat0_angstrom ;
64- cell[5 ] = ucell.latvec .e32 * ucell.lat0_angstrom ;
65- cell[6 ] = ucell.latvec .e13 * ucell.lat0_angstrom ;
66- cell[7 ] = ucell.latvec .e23 * ucell.lat0_angstrom ;
67- cell[8 ] = ucell.latvec .e33 * ucell.lat0_angstrom ;
61+ nep_cell[0 ] = ucell.latvec .e11 * ucell.lat0_angstrom ;
62+ nep_cell[1 ] = ucell.latvec .e21 * ucell.lat0_angstrom ;
63+ nep_cell[2 ] = ucell.latvec .e31 * ucell.lat0_angstrom ;
64+ nep_cell[3 ] = ucell.latvec .e12 * ucell.lat0_angstrom ;
65+ nep_cell[4 ] = ucell.latvec .e22 * ucell.lat0_angstrom ;
66+ nep_cell[5 ] = ucell.latvec .e32 * ucell.lat0_angstrom ;
67+ nep_cell[6 ] = ucell.latvec .e13 * ucell.lat0_angstrom ;
68+ nep_cell[7 ] = ucell.latvec .e23 * ucell.lat0_angstrom ;
69+ nep_cell[8 ] = ucell.latvec .e33 * ucell.lat0_angstrom ;
6870
6971 // coord
70- std::vector<double > coord (3 * ucell.nat , 0.0 );
71- int iat = 0 ;
72+ nep_coord.resize (3 * ucell.nat );
7273 const int nat = ucell.nat ;
73- for (int it = 0 ; it < ucell.ntype ; ++it)
74+ #pragma omp parallel for schedule(static) if (nat >= 256)
75+ for (int iat = 0 ; iat < nat; ++iat)
7476 {
75- for (int ia = 0 ; ia < ucell.atoms [it].na ; ++ia)
76- {
77- coord[iat] = ucell.atoms [it].tau [ia].x * ucell.lat0_angstrom ;
78- coord[iat + nat] = ucell.atoms [it].tau [ia].y * ucell.lat0_angstrom ;
79- coord[iat + 2 * nat] = ucell.atoms [it].tau [ia].z * ucell.lat0_angstrom ;
80- iat++;
81- }
77+ const int it = atom_type_index[iat];
78+ const int ia = atom_local_index[iat];
79+ nep_coord[iat] = ucell.atoms [it].tau [ia].x * ucell.lat0_angstrom ;
80+ nep_coord[iat + nat] = ucell.atoms [it].tau [ia].y * ucell.lat0_angstrom ;
81+ nep_coord[iat + 2 * nat] = ucell.atoms [it].tau [ia].z * ucell.lat0_angstrom ;
8282 }
83- assert (ucell.nat == iat);
8483
8584#ifdef __NEP
8685 nep_potential = 0.0 ;
8786 nep_force.zero_out ();
8887 nep_virial.zero_out ();
8988
90- nep.compute (atype, cell, coord , _e, _f, _v);
89+ nep.compute (atype, nep_cell, nep_coord , _e, _f, _v);
9190
9291 // unit conversion
9392 const double fact_e = 1.0 / ModuleBase::Ry_to_eV;
9493 const double fact_f = 1.0 / (ModuleBase::Ry_to_eV * ModuleBase::ANGSTROM_AU );
9594 const double fact_v = 1.0 / (ucell.omega * ModuleBase::Ry_to_eV);
9695
9796 // potential energy
98- nep_potential = fact_e * std::accumulate (_e.begin (), _e.end (), 0.0 );
97+ double energy_sum = 0.0 ;
98+ #pragma omp parallel for reduction(+:energy_sum) schedule(static) if (nat >= 256)
99+ for (int i = 0 ; i < nat; ++i)
100+ {
101+ energy_sum += _e[i];
102+ }
103+ nep_potential = fact_e * energy_sum;
99104 GlobalV::ofs_running << " #TOTAL ENERGY# " << std::setprecision (11 ) << nep_potential * ModuleBase::Ry_to_eV << " eV"
100105 << std::endl;
101106
102107 // forces
108+ #pragma omp parallel for schedule(static) if (nat >= 256)
103109 for (int i = 0 ; i < nat; ++i)
104110 {
105111 nep_force (i, 0 ) = _f[i] * fact_f;
@@ -108,22 +114,44 @@ void ESolver_NEP::runner(BaseCell& basecell, const int istep)
108114 }
109115
110116 // virial
111- std::vector<double > v_sum (9 , 0.0 );
112- for (int j = 0 ; j < 9 ; ++j)
117+ double v0 = 0.0 ;
118+ double v1 = 0.0 ;
119+ double v2 = 0.0 ;
120+ double v3 = 0.0 ;
121+ double v4 = 0.0 ;
122+ double v5 = 0.0 ;
123+ double v6 = 0.0 ;
124+ double v7 = 0.0 ;
125+ double v8 = 0.0 ;
126+ #pragma omp parallel for reduction(+:v0, v1, v2, v3, v4, v5, v6, v7, v8) schedule(static) if (nat >= 256)
127+ for (int i = 0 ; i < nat; ++i)
113128 {
114- for (int i = 0 ; i < nat; ++i)
115- {
116- int index = j * nat + i;
117- v_sum[j] += _v[index];
118- }
129+ v0 += _v[i];
130+ v1 += _v[nat + i];
131+ v2 += _v[2 * nat + i];
132+ v3 += _v[3 * nat + i];
133+ v4 += _v[4 * nat + i];
134+ v5 += _v[5 * nat + i];
135+ v6 += _v[6 * nat + i];
136+ v7 += _v[7 * nat + i];
137+ v8 += _v[8 * nat + i];
119138 }
139+ nep_virial_sum[0 ] = v0;
140+ nep_virial_sum[1 ] = v1;
141+ nep_virial_sum[2 ] = v2;
142+ nep_virial_sum[3 ] = v3;
143+ nep_virial_sum[4 ] = v4;
144+ nep_virial_sum[5 ] = v5;
145+ nep_virial_sum[6 ] = v6;
146+ nep_virial_sum[7 ] = v7;
147+ nep_virial_sum[8 ] = v8;
120148
121149 // virial -> stress
122150 for (int i = 0 ; i < 3 ; ++i)
123151 {
124152 for (int j = 0 ; j < 3 ; ++j)
125153 {
126- nep_virial (i, j) = v_sum [3 * i + j] * fact_v;
154+ nep_virial (i, j) = nep_virial_sum [3 * i + j] * fact_v;
127155 }
128156 }
129157#else
0 commit comments