@@ -18,8 +18,10 @@ Add electric field to a group of atoms.
1818------------------------------------------------------------------------------*/
1919
2020#include " add_efield.cuh"
21+ #include " force/force.cuh"
2122#include " model/atom.cuh"
2223#include " model/group.cuh"
24+ #include " utilities/gpu_vector.cuh"
2325#include " utilities/gpu_macro.cuh"
2426#include " utilities/read_file.cuh"
2527#include < iostream>
@@ -48,7 +50,30 @@ static void __global__ add_efield(
4850 }
4951}
5052
51- void Add_Efield::compute (const int step, const std::vector<Group>& groups, Atom& atom)
53+ // for NEP-charge
54+ static void __global__ add_efield (
55+ const int group_size,
56+ const int group_size_sum,
57+ const int * g_group_contents,
58+ const double Ex,
59+ const double Ey,
60+ const double Ez,
61+ const float * g_charge,
62+ double * g_fx,
63+ double * g_fy,
64+ double * g_fz)
65+ {
66+ const int tid = blockIdx .x * blockDim .x + threadIdx .x ;
67+ if (tid < group_size) {
68+ const int atom_id = g_group_contents[group_size_sum + tid];
69+ const double charge = g_charge[atom_id];
70+ g_fx[atom_id] += charge * Ex;
71+ g_fy[atom_id] += charge * Ey;
72+ g_fz[atom_id] += charge * Ez;
73+ }
74+ }
75+
76+ void Add_Efield::compute (const int step, const std::vector<Group>& groups, Atom& atom, Force& force)
5277{
5378 for (int call = 0 ; call < num_calls_; ++call) {
5479 const int step_mod_table_length = step % table_length_[call];
@@ -58,17 +83,33 @@ void Add_Efield::compute(const int step, const std::vector<Group>& groups, Atom&
5883 const int num_atoms_total = atom.force_per_atom .size () / 3 ;
5984 const int group_size = groups[grouping_method_[call]].cpu_size [group_id_[call]];
6085 const int group_size_sum = groups[grouping_method_[call]].cpu_size_sum [group_id_[call]];
61- add_efield<<<(group_size - 1 ) / 64 + 1 , 64 >>> (
62- group_size,
63- group_size_sum,
64- groups[grouping_method_[call]].contents .data (),
65- Ex,
66- Ey,
67- Ez,
68- atom.charge .data (),
69- atom.force_per_atom .data (),
70- atom.force_per_atom .data () + num_atoms_total,
71- atom.force_per_atom .data () + num_atoms_total * 2 );
86+ if (is_nep_charge) {
87+ GPU_Vector<float >& nep_charge = force.potentials [0 ]->get_charge_reference ();
88+ add_efield<<<(group_size - 1 ) / 64 + 1 , 64 >>> (
89+ group_size,
90+ group_size_sum,
91+ groups[grouping_method_[call]].contents .data (),
92+ Ex,
93+ Ey,
94+ Ez,
95+ nep_charge.data (),
96+ atom.force_per_atom .data (),
97+ atom.force_per_atom .data () + num_atoms_total,
98+ atom.force_per_atom .data () + num_atoms_total * 2 );
99+ }
100+ else {
101+ add_efield<<<(group_size - 1 ) / 64 + 1 , 64 >>> (
102+ group_size,
103+ group_size_sum,
104+ groups[grouping_method_[call]].contents .data (),
105+ Ex,
106+ Ey,
107+ Ez,
108+ atom.charge .data (),
109+ atom.force_per_atom .data (),
110+ atom.force_per_atom .data () + num_atoms_total,
111+ atom.force_per_atom .data () + num_atoms_total * 2 );
112+ }
72113 GPU_CHECK_KERNEL
73114 }
74115}
@@ -160,6 +201,14 @@ void Add_Efield::parse(const char** param, int num_param, const std::vector<Grou
160201 if (num_calls_ > 10 ) {
161202 PRINT_INPUT_ERROR (" add_efield cannot be used more than 10 times in one run." );
162203 }
204+
205+ is_nep_charge = check_is_nep_charge ();
206+ if (is_nep_charge) {
207+ printf (" using the charge values predicted by the NEP-Charge model.\n " );
208+ } else {
209+ printf (" using the charge values specified in model.xyz.\n " );
210+ }
211+
163212}
164213
165214void Add_Efield::finalize () { num_calls_ = 0 ; }
0 commit comments