Skip to content

Commit 0b7bd20

Browse files
authored
Merge pull request brucefan1983#1158 from brucefan1983/add-efield-nep-charge
Add efield nep charge
2 parents 1702649 + 380d87a commit 0b7bd20

8 files changed

Lines changed: 126 additions & 14 deletions

File tree

src/force/nep_charge.cu

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2124,3 +2124,5 @@ void NEP_Charge::compute(
21242124
const GPU_Vector<int>& NEP_Charge::get_NN_radial_ptr() { return nep_data.NN_radial; }
21252125

21262126
const GPU_Vector<int>& NEP_Charge::get_NL_radial_ptr() { return nep_data.NL_radial; }
2127+
2128+
GPU_Vector<float>& NEP_Charge::get_charge_reference() { return nep_data.charge; }

src/force/nep_charge.cuh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ public:
137137

138138
const GPU_Vector<int>& get_NL_radial_ptr();
139139

140+
GPU_Vector<float>& get_charge_reference();
141+
140142
private:
141143
ParaMB paramb;
142144
ANN annmb;

src/force/potential.cuh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ public:
7575
return dummy_NL; // Return the const reference to NL_radial
7676
}
7777

78+
virtual GPU_Vector<float>& get_charge_reference()
79+
{
80+
static GPU_Vector<float> dummy_charge;
81+
return dummy_charge;
82+
}
83+
7884
protected:
7985
void find_properties_many_body(
8086
Box& box,

src/main_gpumd/add_efield.cu

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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

165214
void Add_Efield::finalize() { num_calls_ = 0; }

src/main_gpumd/add_efield.cuh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@
1919

2020
class Atom;
2121
class Group;
22+
class Force;
2223

2324
class Add_Efield
2425
{
2526
public:
2627
void parse(const char** param, int num_param, const std::vector<Group>& group);
27-
void compute(const int step, const std::vector<Group>& groups, Atom& atom);
28+
void compute(const int step, const std::vector<Group>& groups, Atom& atom, Force& force);
2829
void finalize();
2930

3031
private:
@@ -33,4 +34,5 @@ private:
3334
std::vector<double> efield_table_[10];
3435
int grouping_method_[10];
3536
int group_id_[10];
37+
bool is_nep_charge = false;
3638
};

src/main_gpumd/run.cu

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ void Run::perform_a_run()
293293
electron_stop.compute(time_step, atom);
294294
add_force.compute(step, group, atom);
295295
add_random_force.compute(step, atom);
296-
add_efield.compute(step, group, atom);
296+
add_efield.compute(step, group, atom, force);
297297

298298
integrate.compute2(time_step, double(step) / number_of_steps, group, box, atom, thermo, force);
299299

src/utilities/read_file.cu

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,53 @@ int is_valid_real(const char* s, double* result)
5656
return 1;
5757
}
5858
}
59+
60+
static std::string get_potential_file_name()
61+
{
62+
std::ifstream input_run("run.in");
63+
if (!input_run.is_open()) {
64+
PRINT_INPUT_ERROR("Cannot open run.in.");
65+
}
66+
std::string potential_file_name;
67+
std::string line;
68+
while (std::getline(input_run, line)) {
69+
std::vector<std::string> tokens = get_tokens(line);
70+
if (tokens.size() != 0) {
71+
if (tokens[0] == "potential") {
72+
potential_file_name = tokens[1];
73+
break;
74+
}
75+
}
76+
}
77+
78+
input_run.close();
79+
return potential_file_name;
80+
}
81+
82+
bool check_is_nep_charge()
83+
{
84+
bool is_nep_charge = false;
85+
std::string potential_file_name = get_potential_file_name();
86+
87+
std::ifstream input_potential(potential_file_name);
88+
if (!input_potential.is_open()) {
89+
PRINT_INPUT_ERROR("Cannot open potential file.");
90+
}
91+
std::string line;
92+
std::getline(input_potential, line);
93+
std::vector<std::string> tokens = get_tokens(line);
94+
if (tokens[0].size() >= 12) {
95+
if (tokens[0].substr(0, 11) == "nep4_charge") {
96+
is_nep_charge = true;
97+
}
98+
}
99+
if (tokens[0].size() >= 16) {
100+
if (tokens[0].substr(0, 15) == "nep4_zbl_charge") {
101+
is_nep_charge = true;
102+
}
103+
}
104+
input_potential.close();
105+
106+
return is_nep_charge;
107+
}
108+

src/utilities/read_file.cuh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@
1717

1818
int is_valid_int(const char*, int*);
1919
int is_valid_real(const char*, double*);
20+
bool check_is_nep_charge();

0 commit comments

Comments
 (0)