Skip to content

Commit 572fbfd

Browse files
Supplementary unittests for merge_traj function to detect issue #957 (#961)
The added unittest is to check that the process of extracting the configuration from model_devi.out to generate the first principles calculation task is correct. When issue #957 exists: ![j2vzixdu0g](https://user-images.githubusercontent.com/100290172/191417680-c3a20e89-e704-4dd9-aefd-5a05ae8c7406.jpg) When issue #957 is solved: ![uzvvdHkD29](https://user-images.githubusercontent.com/100290172/191417640-24f7bf6a-0d3d-4e29-bd9c-2e4f34e764d7.jpg)
1 parent 8f34e78 commit 572fbfd

File tree

10 files changed

+236
-9
lines changed

10 files changed

+236
-9
lines changed

dpgen/generator/run.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2197,7 +2197,13 @@ def _trust_limitation_check(sys_idx, lim):
21972197
cwd = os.getcwd()
21982198
os.chdir(fp_task_path)
21992199
if cluster_cutoff is None:
2200-
if model_devi_engine in ("lammps", "gromacs"):
2200+
if model_devi_engine == "lammps":
2201+
if model_devi_merge_traj:
2202+
conf_sys.to("lammps/lmp", "conf.dump")
2203+
else:
2204+
os.symlink(os.path.relpath(conf_name), 'conf.dump')
2205+
os.symlink(os.path.relpath(job_name), 'job.json')
2206+
elif model_devi_engine == "gromacs":
22012207
os.symlink(os.path.relpath(conf_name), 'conf.dump')
22022208
os.symlink(os.path.relpath(job_name), 'job.json')
22032209
elif model_devi_engine == "amber":
@@ -2246,7 +2252,7 @@ def _trust_limitation_check(sys_idx, lim):
22462252
if model_devi_engine == "lammps":
22472253
sys = None
22482254
if model_devi_merge_traj:
2249-
sys = conf_sys
2255+
sys = dpdata.System('conf.dump', fmt = "lammps/lmp", type_map = type_map)
22502256
else :
22512257
sys = dpdata.System('conf.dump', fmt = "lammps/dump", type_map = type_map)
22522258
sys.to_vasp_poscar('POSCAR')
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
f0c56f70-627b-445a-89de-3ad3e81f3785
1+
140c75e5-993c-4644-b877-cd3ceb2b254a

tests/dispatcher/loc/task0/test0

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5dc17ca2-0d58-4968-af22-41536e667668
1+
dfea7618-49df-42ac-b723-f7c04e349203

tests/dispatcher/loc/task0/test1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
814f28b0-38bd-493a-b400-d678c3fe1a0e
1+
99cee2e2-0de4-43ba-a296-805f4e551ace
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
d3c9fb33-4ffd-48c2-86bb-933fbe7fd512
1+
0d7eaf5f-0a04-492a-b9ae-c7d77781c928

tests/dispatcher/loc/task1/test0

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
8a4f3e52-3ace-45c5-8bd1-1bbbb4d9abd0
1+
b96519be-c495-4150-b634-39b61b54ffd9

tests/dispatcher/loc/task1/test1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
b8389a9b-bc75-4498-94bf-c565a4e387b6
1+
00bc5947-dfb6-47e4-909e-3c647b551c82

tests/generator/context.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from dpgen.generator.lib.parse_calypso import _parse_calypso_input,_parse_calypso_dis_mtx
1111

1212
param_file = 'param-mg-vasp.json'
13+
param_file_merge_traj = 'param-mg-vasp_merge_traj.json'
1314
param_file_v1 = 'param-mg-vasp-v1.json'
1415
param_file_v1_et = 'param-mg-vasp-v1-et.json'
1516
param_old_file = 'param-mg-vasp-old.json'
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
{
2+
"type_map": ["Mg", "Al"],
3+
"mass_map": [24, 27],
4+
5+
"init_data_prefix": "data",
6+
"init_data_sys": ["deepmd"
7+
],
8+
"init_batch_size": [16],
9+
"sys_configs": [
10+
["data/mg.fcc.02x02x02/01.scale_pert/sys-0032/scale*/000000/POSCAR"],
11+
["data/mg.fcc.02x02x02/01.scale_pert/sys-0032/scale*/000001/POSCAR"]
12+
],
13+
"_comment": "0 1 2 3",
14+
"_comment": "4 5 6 7",
15+
"sys_batch_size": [1, 1
16+
],
17+
18+
"_comment": " 00.train ",
19+
"numb_models": 4,
20+
"default_training_param" : {
21+
"_comment": " model parameters",
22+
"use_smooth": true,
23+
"sel_a": [90],
24+
"rcut_smth": 2.00,
25+
"rcut": 6.00,
26+
"filter_neuron": [25, 50, 100],
27+
"filter_resnet_dt": false,
28+
"n_axis_neuron": 12,
29+
"n_neuron": [240, 240, 240],
30+
"resnet_dt": true,
31+
"coord_norm": true,
32+
"type_fitting_net": false,
33+
34+
"_comment": " traing controls",
35+
"systems": [],
36+
"set_prefix": "set",
37+
"stop_batch": 400000,
38+
"batch_size": 1,
39+
"start_lr": 0.002,
40+
"decay_steps": 2000,
41+
"decay_rate": 0.95,
42+
"seed": 0,
43+
44+
"start_pref_e": 0.02,
45+
"limit_pref_e": 2,
46+
"start_pref_f": 1000,
47+
"limit_pref_f": 1,
48+
"start_pref_v": 0.0,
49+
"limit_pref_v": 0.0,
50+
51+
"_comment": " display and restart",
52+
"_comment": " frequencies counted in batch",
53+
"disp_file": "lcurve.out",
54+
"disp_freq": 2000,
55+
"numb_test": 10,
56+
"save_freq": 20000,
57+
"save_ckpt": "model.ckpt",
58+
"load_ckpt": "model.ckpt",
59+
"disp_training": true,
60+
"time_training": true,
61+
"profiling": false,
62+
"profiling_file": "timeline.json",
63+
64+
"_comment": "that's all"
65+
},
66+
67+
"_comment": " 01.model_devi ",
68+
"_comment": "model_devi_skip: the first x of the recorded frames",
69+
"model_devi_dt": 0.002,
70+
"model_devi_skip": 0,
71+
"model_devi_f_trust_lo": 0.050,
72+
"model_devi_f_trust_hi": 0.150,
73+
"model_devi_merge_traj": true,
74+
"model_devi_jobs": [
75+
{"sys_idx": [0,1], "temps": [50,100], "press": [1.0,2.0], "trj_freq": 10, "nsteps": 1000, "ensemble": "npt", "_idx": "00"}
76+
],
77+
78+
"_comment": " 02.fp ",
79+
"fp_style": "vasp",
80+
"shuffle_poscar": false,
81+
"fp_task_max": 100,
82+
"fp_task_min": 10,
83+
"fp_pp_path": ".",
84+
"fp_pp_files": ["vasp/potcars/POTCAR.mg", "vasp/potcars/POTCAR.al"],
85+
"_comment": " user provided vasp script ",
86+
"user_fp_params": {
87+
"PREC": "A",
88+
"ENCUT": 600,
89+
"ISYM": 0,
90+
"ALGO": "fast",
91+
"EDIFF": 1e-05,
92+
"LREAL": "A",
93+
"NPAR": 1,
94+
"KPAR": 1,
95+
"NELMIN": 4,
96+
"ISIF": 2,
97+
"ISMEAR": 1,
98+
"SIGMA": 0.25,
99+
"IBRION": -1,
100+
"NSW": 0,
101+
"LWAVE": false,
102+
"LCHARG": false,
103+
"PSTRESS": 0,
104+
"KSPACING": 0.16,
105+
"KGAMMA": false
106+
},
107+
"_comment": " that's all "
108+
}

tests/generator/test_make_fp.py

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from .context import detect_multiplicity
1111
from .context import parse_cur_job
1212
from .context import param_file
13+
from .context import param_file_merge_traj
1314
from .context import param_old_file
1415
from .context import param_pwscf_file
1516
from .context import param_pwscf_old_file
@@ -219,7 +220,7 @@ def _write_lammps_dump(sys, dump_file, f_idx = 0) :
219220
bd, tilt = _box2dumpbox(np.zeros(3), cell)
220221
atype = sys['atom_types']
221222
natoms = len(sys['atom_types'])
222-
with open(dump_file, 'w') as fp:
223+
with open(dump_file, 'a') as fp:
223224
fp.write('ITEM: TIMESTEP\n')
224225
fp.write('0\n')
225226
fp.write('ITEM: NUMBER OF ATOMS\n')
@@ -271,6 +272,52 @@ def _make_fake_md(idx, md_descript, atom_types, type_map, ele_temp = None) :
271272
with open(os.path.join(task_dir, 'job.json'), 'w') as fp:
272273
json.dump({"ele_temp": ele_temp[sidx][midx]}, fp)
273274

275+
def _make_fake_md_merge_traj(idx, md_descript, atom_types, type_map, ele_temp = None) :
276+
"""
277+
md_descript: list of dimension
278+
[n_sys][n_MD][n_frame]
279+
ele_temp: list of dimension
280+
[n_sys][n_MD]
281+
"""
282+
natoms = len(atom_types)
283+
ntypes = len(type_map)
284+
atom_types = np.array(atom_types, dtype = int)
285+
atom_numbs = [np.sum(atom_types == ii) for ii in range(ntypes)]
286+
sys = dpdata.System()
287+
sys.data['atom_names'] = type_map
288+
sys.data['atom_numbs'] = atom_numbs
289+
sys.data['atom_types'] = atom_types
290+
for sidx,ss in enumerate(md_descript) :
291+
for midx,mm in enumerate(ss) :
292+
nframes = len(mm)
293+
cells = np.random.random([nframes,3,3])
294+
coords = np.random.random([nframes,natoms,3])
295+
sys.data['coords'] = coords
296+
sys.data['cells'] = cells
297+
task_dir = os.path.join('iter.%06d' % idx,
298+
'01.model_devi',
299+
'task.%03d.%06d' % (sidx, midx))
300+
cwd = os.getcwd()
301+
os.makedirs(task_dir,exist_ok = True)
302+
for ii in range(nframes):
303+
_write_lammps_dump(sys,os.path.join(task_dir,'all.lammpstrj'),ii)
304+
file_content = """\
305+
0.000000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00
306+
1.000000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 2.899999999999999800e-02 0.000000000000000000e+00 0.000000000000000000e+00
307+
2.000000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 5.799999999999999600e-02 0.000000000000000000e+00 0.000000000000000000e+00
308+
3.000000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 8.699999999999999400e-02 0.000000000000000000e+00 0.000000000000000000e+00
309+
4.000000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.159999999999999920e-01 0.000000000000000000e+00 0.000000000000000000e+00
310+
5.000000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.449999999999999900e-01 0.000000000000000000e+00 0.000000000000000000e+00
311+
6.000000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.739999999999999880e-01 0.000000000000000000e+00 0.000000000000000000e+00
312+
7.000000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 2.029999999999999860e-01 0.000000000000000000e+00 0.000000000000000000e+00
313+
8.000000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 2.319999999999999840e-01 0.000000000000000000e+00 0.000000000000000000e+00
314+
9.000000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 2.610000000000000098e-01 0.000000000000000000e+00 0.000000000000000000e+00
315+
"""
316+
with open(os.path.join(task_dir, 'model_devi.out') , 'w') as fp:
317+
fp.write(file_content)
318+
if ele_temp is not None:
319+
with open(os.path.join(task_dir, 'job.json'), 'w') as fp:
320+
json.dump({"ele_temp": ele_temp[sidx][midx]}, fp)
274321

275322
def _check_poscars(testCase, idx, fp_task_max, type_map) :
276323
fp_path = os.path.join('iter.%06d' % idx, '02.fp')
@@ -297,6 +344,40 @@ def _check_poscars(testCase, idx, fp_task_max, type_map) :
297344
sys1 = dpdata.System(poscar_file, fmt = 'vasp/poscar')
298345
test_atom_names(testCase, sys0, sys1)
299346

347+
def _check_poscars_merge_traj(testCase, idx, fp_task_max, type_map ) :
348+
fp_path = os.path.join('iter.%06d' % idx, '02.fp')
349+
candi_files = glob.glob(os.path.join(fp_path, 'candidate.shuffled.*.out'))
350+
candi_files.sort()
351+
sys_idx = [str(os.path.basename(ii).split('.')[2]) for ii in candi_files]
352+
for sidx,ii in zip(sys_idx, candi_files) :
353+
md_task = []
354+
f_idx = []
355+
with open(ii) as fp:
356+
for ii in fp :
357+
md_task.append(ii.split()[0])
358+
f_idx.append(ii.split()[1])
359+
md_task = md_task[:fp_task_max]
360+
f_idx = f_idx[:fp_task_max]
361+
cc = 0
362+
label_0 = 0
363+
label_1 = 0
364+
365+
for tt,ff in zip(md_task, f_idx) :
366+
traj_file = os.path.join(tt, 'all.lammpstrj')
367+
poscar_file = os.path.join(fp_path,
368+
'task.%03d.%06d' % (int(sidx), cc),
369+
'POSCAR')
370+
cc += 1
371+
sys0 = dpdata.System(traj_file, fmt = 'lammps/dump', type_map = type_map)
372+
sys1 = dpdata.System(poscar_file, fmt = 'vasp/poscar')
373+
new_coords_0 = float(sys1["coords"][0][0][0])
374+
new_coords_1 = float(sys1["coords"][0][1][0])
375+
if (label_0 == new_coords_0 and label_1 == new_coords_1):
376+
raise RuntimeError("The exact same POSCAR is generated under different first-principles calculation catalogs")
377+
label_0 = new_coords_0
378+
label_1 = new_coords_1
379+
test_atom_names(testCase, sys0[int(int(ff)/10)], sys1)
380+
300381
def _check_kpoints_exists(testCase, idx) :
301382
fp_path = os.path.join('iter.%06d' % idx, '02.fp')
302383
tasks = glob.glob(os.path.join(fp_path, 'task.*'))
@@ -710,6 +791,37 @@ def test_make_fp_vasp(self):
710791
# checked elsewhere
711792
# _check_potcar(self, 0, jdata['fp_pp_path'], jdata['fp_pp_files'])
712793
shutil.rmtree('iter.000000')
794+
795+
def test_make_fp_vasp_merge_traj(self):
796+
setUpModule()
797+
if os.path.isdir('iter.000000') :
798+
shutil.rmtree('iter.000000')
799+
with open (param_file_merge_traj, 'r') as fp :
800+
jdata = json.load (fp)
801+
with open (machine_file, 'r') as fp:
802+
mdata = json.load (fp)
803+
md_descript = []
804+
nsys = 2
805+
nmd = 3
806+
n_frame = 10
807+
for ii in range(nsys) :
808+
tmp = []
809+
for jj in range(nmd) :
810+
tmp.append(np.arange(0, 0.29, 0.29/10))
811+
md_descript.append(tmp)
812+
atom_types = [0, 1, 0, 1]
813+
type_map = jdata['type_map']
814+
815+
_make_fake_md_merge_traj(0, md_descript, atom_types, type_map)
816+
make_fp(0, jdata, {"fp_user_forward_files" : ["vdw_kernel.bindat"] })
817+
_check_poscars_merge_traj(self, 0, jdata['fp_task_max'], jdata['type_map'])
818+
#_check_incar_exists(self, 0)
819+
_check_incar(self, 0)
820+
_check_kpoints_exists(self, 0)
821+
_check_kpoints(self,0)
822+
# checked elsewhere
823+
# _check_potcar(self, 0, jdata['fp_pp_path'], jdata['fp_pp_files'])
824+
shutil.rmtree('iter.000000')
713825

714826
def test_make_fp_vasp_old(self):
715827
setUpModule()

0 commit comments

Comments
 (0)