pwact 0.3.4__tar.gz → 0.4.0.dev0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. {pwact-0.3.4 → pwact-0.4.0.dev0}/PKG-INFO +1 -1
  2. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/explore/run_model_md.py +66 -41
  3. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/explore/select_image.py +2 -1
  4. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/label/labeling.py +7 -3
  5. pwact-0.4.0.dev0/pwact/active_learning/test/uma_md.py +110 -0
  6. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/user_input/iter_input.py +55 -10
  7. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/data_format/configop.py +14 -11
  8. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/utils/app_lib/common.py +87 -1
  9. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/utils/app_lib/lammps.py +89 -0
  10. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/utils/file_operation.py +5 -0
  11. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/utils/format_input_output.py +6 -0
  12. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/utils/slurm_script.py +1 -1
  13. pwact-0.4.0.dev0/pwact/utils/tmp.py +161 -0
  14. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact.egg-info/PKG-INFO +1 -1
  15. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact.egg-info/SOURCES.txt +1 -0
  16. {pwact-0.3.4 → pwact-0.4.0.dev0}/setup.py +1 -1
  17. pwact-0.3.4/pwact/utils/tmp.py +0 -63
  18. {pwact-0.3.4 → pwact-0.4.0.dev0}/LICENSE +0 -0
  19. {pwact-0.3.4 → pwact-0.4.0.dev0}/README.md +0 -0
  20. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/__init__.py +0 -0
  21. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/__init__.py +0 -0
  22. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/environment.py +0 -0
  23. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/explore/__init__.py +0 -0
  24. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/init_bulk/__init__.py +0 -0
  25. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/init_bulk/aimd.py +0 -0
  26. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/init_bulk/direct.py +0 -0
  27. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/init_bulk/duplicate_scale.py +0 -0
  28. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/init_bulk/explore.py +0 -0
  29. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/init_bulk/init_bulk_run.py +0 -0
  30. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/init_bulk/relabel.py +0 -0
  31. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/init_bulk/relax.py +0 -0
  32. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/label/__init__.py +0 -0
  33. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/slurm/__init__.py +0 -0
  34. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/slurm/slurm.py +0 -0
  35. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/slurm/slurm_tool.py +0 -0
  36. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/test/__init__.py +0 -0
  37. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/test/test.py +0 -0
  38. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/train/__init__.py +0 -0
  39. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/train/dp_kpu.py +0 -0
  40. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/train/train_model.py +0 -0
  41. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/user_input/__init__.py +0 -0
  42. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/user_input/cmd_infos.py +0 -0
  43. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/user_input/init_bulk_input.py +0 -0
  44. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/user_input/resource.py +0 -0
  45. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/user_input/scf_param.py +0 -0
  46. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/user_input/train_param/__init__.py +0 -0
  47. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/user_input/train_param/model_param.py +0 -0
  48. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/user_input/train_param/nep_param.py +0 -0
  49. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/user_input/train_param/nn_feature_type.py +0 -0
  50. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/user_input/train_param/optimizer_param.py +0 -0
  51. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/user_input/train_param/train_param.py +0 -0
  52. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/user_input/train_param/work_file_param.py +0 -0
  53. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/active_learning/user_input/workdir.py +0 -0
  54. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/bin/__init__.py +0 -0
  55. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/data_format/__init__.py +0 -0
  56. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/main.py +0 -0
  57. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/utils/__init__.py +0 -0
  58. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/utils/app_lib/__init__.py +0 -0
  59. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/utils/app_lib/cp2k.py +0 -0
  60. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/utils/app_lib/cp2k_dp.py +0 -0
  61. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/utils/app_lib/do_direct_sample.py +0 -0
  62. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/utils/app_lib/do_eqv2model.py +0 -0
  63. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/utils/app_lib/pwmat.py +0 -0
  64. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/utils/constant.py +0 -0
  65. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/utils/draw/__init__.py +0 -0
  66. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/utils/draw/hist_model_devi.py +0 -0
  67. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/utils/json_operation.py +0 -0
  68. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/utils/pre_al_data_util.py +0 -0
  69. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact/utils/process_tool.py +0 -0
  70. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact.egg-info/dependency_links.txt +0 -0
  71. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact.egg-info/entry_points.txt +0 -0
  72. {pwact-0.3.4 → pwact-0.4.0.dev0}/pwact.egg-info/top_level.txt +0 -0
  73. {pwact-0.3.4 → pwact-0.4.0.dev0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pwact
3
- Version: 0.3.4
3
+ Version: 0.4.0.dev0
4
4
  Summary: PWACT is an open-source automated active learning platform based on MatPL for efficient data sampling.
5
5
  Home-page: https://github.com/LonxunQuantum/PWact
6
6
  Author: LonxunQuantum
@@ -24,10 +24,10 @@ from pwact.utils.constant import AL_STRUCTURE, TEMP_STRUCTURE, EXPLORE_FILE_STRU
24
24
  FORCEFILED, ENSEMBLE, LAMMPS, LAMMPS_CMD, UNCERTAINTY, DFT_STYLE, SLURM_OUT, SLURM_JOB_TYPE, PWDATA, MODEL_TYPE
25
25
 
26
26
  from pwact.utils.format_input_output import get_iter_from_iter_name, get_sub_md_sys_template_name,\
27
- make_md_sys_name, get_md_sys_template_name, make_temp_press_name, make_temp_name, make_train_name
27
+ make_md_sys_name, get_md_sys_template_name, make_temp_press_name, make_temp_name, make_lmps_name, make_train_name
28
28
  from pwact.utils.file_operation import write_to_file, add_postfix_dir, link_file, read_data, search_files, copy_dir, copy_file, del_file, del_dir, del_file_list, del_file_list_by_patten, mv_file
29
29
  from pwact.utils.draw.hist_model_devi import draw_hist_list
30
- from pwact.utils.app_lib.lammps import make_lammps_input
30
+ from pwact.utils.app_lib.lammps import make_lammps_input, make_lammps_input_from_lmp_in_file
31
31
  from pwact.data_format.configop import save_config, get_atom_type
32
32
 
33
33
  from pwdata import Config
@@ -94,30 +94,40 @@ class Explore(object):
94
94
  def make_md_work(self):
95
95
  md_work_list = []
96
96
  for md_index, md in enumerate(self.md_job):
97
- for sys_index in md.sys_idx:
97
+ for sys_id, sys_index in enumerate(md.sys_idx):
98
98
  char_len = 3 if len(md.sys_idx) < 1000 else len(str(len(md.sys_idx)))
99
99
  md_sys_name = make_md_sys_name(md_index, sys_index, char_len)
100
100
  md_sys_dir = os.path.join(self.md_dir, md_sys_name)
101
101
  if not os.path.exists(md_sys_dir):
102
102
  os.makedirs(md_sys_dir)
103
- for temp_index, temp in enumerate(md.temp_list):
104
- if ENSEMBLE.nvt in md.ensemble:#for nvt ensemble
105
- temp_name = make_temp_name(md_index, sys_index, temp_index, char_len)
106
- temp_dir = os.path.join(md_sys_dir, temp_name)
107
- # mkdir: md.000.sys.000/md.000.sys.000.t.000
108
- if not os.path.exists(temp_dir):
103
+ if md.use_lmps_in:
104
+ # for lmp_id, lmps_idx in enumerate(md.lmp_in_idx):
105
+ temp_name = make_lmps_name(md_index, sys_index, sys_id, char_len)
106
+ temp_dir = os.path.join(md_sys_dir, temp_name)
107
+ # mkdir: md.000.sys.000/md.000.sys.000.lmps.000
108
+ if not os.path.exists(temp_dir):
109
109
  os.makedirs(temp_dir)
110
- self.set_md_files(len(md_work_list), temp_dir, sys_index, temp_index, None, md)
111
- md_work_list.append(temp_dir)
112
- elif ENSEMBLE.npt in md.ensemble: # for npt ensemble
113
- for press_index, press in enumerate(md.press_list):
114
- temp_press_name = make_temp_press_name(md_index, sys_index, temp_index, press_index, char_len)
115
- temp_press_dir = os.path.join(md_sys_dir, temp_press_name)
116
- # mkdir: md.000.sys.000/md.000.sys.000.p.000.t.000
117
- if not os.path.exists(temp_press_dir):
118
- os.makedirs(temp_press_dir)
119
- self.set_md_files(len(md_work_list), temp_press_dir, sys_index, temp_index, press_index, md)
120
- md_work_list.append(temp_press_dir)
110
+ self.set_md_files(len(md_work_list), temp_dir, sys_index, sys_id, None, md)
111
+ md_work_list.append(temp_dir)
112
+ else:
113
+ for temp_index, temp in enumerate(md.temp_list):
114
+ if ENSEMBLE.nvt in md.ensemble:#for nvt ensemble
115
+ temp_name = make_temp_name(md_index, sys_index, temp_index, char_len)
116
+ temp_dir = os.path.join(md_sys_dir, temp_name)
117
+ # mkdir: md.000.sys.000/md.000.sys.000.t.000
118
+ if not os.path.exists(temp_dir):
119
+ os.makedirs(temp_dir)
120
+ self.set_md_files(len(md_work_list), temp_dir, sys_index, temp_index, None, md)
121
+ md_work_list.append(temp_dir)
122
+ elif ENSEMBLE.npt in md.ensemble: # for npt ensemble
123
+ for press_index, press in enumerate(md.press_list):
124
+ temp_press_name = make_temp_press_name(md_index, sys_index, temp_index, press_index, char_len)
125
+ temp_press_dir = os.path.join(md_sys_dir, temp_press_name)
126
+ # mkdir: md.000.sys.000/md.000.sys.000.p.000.t.000
127
+ if not os.path.exists(temp_press_dir):
128
+ os.makedirs(temp_press_dir)
129
+ self.set_md_files(len(md_work_list), temp_press_dir, sys_index, temp_index, press_index, md)
130
+ md_work_list.append(temp_press_dir)
121
131
 
122
132
  self.make_md_slurm_jobs(md_work_list)
123
133
 
@@ -218,33 +228,48 @@ class Explore(object):
218
228
 
219
229
  #3. set lammps input file
220
230
  input_lammps_file = os.path.join(md_dir, LAMMPS.input_lammps)
221
- press=md_detail.press_list[press_index] if press_index is not None else None
222
231
  # get atom type
223
232
  atom_type_list, atomic_number_list = get_atom_type(md_detail.config_file_list[sys_index], md_detail.config_file_format[sys_index])
224
233
  atom_type_file = os.path.join(md_dir, LAMMPS.atom_type_file)
225
234
  write_to_file(atom_type_file, " ".join(atom_type_list), "w")
226
235
  restart_file = search_files(md_dir, "lmps.restart.*")
227
236
  restart = 1 if len(restart_file) > 0 else 0
228
- lmp_input_content = make_lammps_input(
229
- md_file=LAMMPS.lammps_sys_config, #save_file
230
- md_type = self.input_param.strategy.md_type,
231
- forcefiled = md_model_paths,
232
- atom_type = atomic_number_list,
233
- ensemble = md_detail.ensemble,
234
- nsteps = md_detail.nsteps,
235
- dt = md_detail.md_dt,
236
- neigh_modify = md_detail.neigh_modify,
237
- trj_freq = md_detail.trj_freq,
238
- mass = md_detail.mass,
239
- temp = md_detail.temp_list[temp_index],
240
- tau_t=md_detail.taut, # for fix
241
- press=press,
242
- tau_p=md_detail.taup if press is not None else None, # for fix
243
- boundary=True, #true is 'p p p', false is 'f f f'
244
- merge_traj=md_detail.merge_traj,
245
- restart = restart,
246
- model_deviation_file = EXPLORE_FILE_STRUCTURE.model_devi
247
- )
237
+ if md_detail.use_lmps_in: # lammps.in file from user input
238
+ lmp_input_content = make_lammps_input_from_lmp_in_file(
239
+ md_file=LAMMPS.lammps_sys_config, #save_file
240
+ md_type = self.input_param.strategy.md_type,
241
+ forcefiled = md_model_paths,
242
+ lmp_in_file = md_detail.lmp_in_file_list[sys_index],
243
+ atom_type = atomic_number_list,
244
+ trj_freq = md_detail.trj_freq,
245
+ boundary=True, #true is 'p p p', false is 'f f f'
246
+ merge_traj=md_detail.merge_traj,
247
+ restart = restart,
248
+ model_deviation_file = EXPLORE_FILE_STRUCTURE.model_devi
249
+ )
250
+
251
+ else: # lammps.in from param.json
252
+ press=md_detail.press_list[press_index] if press_index is not None else None
253
+ lmp_input_content = make_lammps_input(
254
+ md_file=LAMMPS.lammps_sys_config, #save_file
255
+ md_type = self.input_param.strategy.md_type,
256
+ forcefiled = md_model_paths,
257
+ atom_type = atomic_number_list,
258
+ ensemble = md_detail.ensemble,
259
+ nsteps = md_detail.nsteps,
260
+ dt = md_detail.md_dt,
261
+ neigh_modify = md_detail.neigh_modify,
262
+ trj_freq = md_detail.trj_freq,
263
+ mass = md_detail.mass,
264
+ temp = md_detail.temp_list[temp_index],
265
+ tau_t=md_detail.taut, # for fix
266
+ press=press,
267
+ tau_p=md_detail.taup if press is not None else None, # for fix
268
+ boundary=True, #true is 'p p p', false is 'f f f'
269
+ merge_traj=md_detail.merge_traj,
270
+ restart = restart,
271
+ model_deviation_file = EXPLORE_FILE_STRUCTURE.model_devi
272
+ )
248
273
  write_to_file(input_lammps_file, lmp_input_content, "w")
249
274
  if md_detail.merge_traj is False:
250
275
  traj_dir = os.path.join(md_dir, "traj")
@@ -114,7 +114,8 @@ def select_image(
114
114
  rand_candi = pd.concat([rand_candi, tmp_rand_candi])
115
115
  remove_candi = pd.concat([remove_candi, tmp_remove_candi])
116
116
  right_md, error_md = count_mdstop_info(model_devi_files)
117
- md_run_info = "A total of {} MD trajectories were run. with {} trajectories correctly executed and {} trajectories normally completed. \nFor detailed information, refer to File {}.".format(len(right_md) + len(error_md), len(right_md), len(error_md), EXPLORE_FILE_STRUCTURE.md_traj_error_record)
117
+ md_run_info = "A total of {} MD trajectories were run. with {} trajectories correctly executed and {} trajectories normally completed. \nFor detailed information, refer to File {}."\
118
+ .format(len(right_md) + len(error_md), len(right_md), len(error_md), EXPLORE_FILE_STRUCTURE.md_traj_error_record)
118
119
 
119
120
  summary_info, summary = count_info(save_dir, error_pd, accurate_pd, rand_candi, remove_candi, md_run_info)
120
121
  print("Image select result:\n {}\n\n".format(summary_info))
@@ -32,10 +32,11 @@ from pwact.utils.constant import DFT_TYPE, VASP, PWDATA, AL_STRUCTURE, TEMP_STRU
32
32
  from pwact.utils.slurm_script import get_slurm_job_run_info, split_job_for_group, set_slurm_script_content
33
33
  from pwact.utils.format_input_output import get_iter_from_iter_name, get_md_sys_template_name
34
34
  from pwact.utils.file_operation import write_to_file, copy_file, copy_dir, search_files, mv_file, add_postfix_dir, del_dir, del_file_list_by_patten, link_file
35
- from pwact.utils.app_lib.common import link_pseudo_by_atom, set_input_script
35
+ from pwact.utils.app_lib.common import link_pseudo_by_atom, set_input_script, check_convergence
36
36
 
37
37
  from pwact.data_format.configop import extract_pwdata, save_config, get_atom_type
38
38
  from pwdata import Config
39
+
39
40
  class Labeling(object):
40
41
  @staticmethod
41
42
  def kill_job(root_dir:str, itername:str):
@@ -381,8 +382,9 @@ class Labeling(object):
381
382
 
382
383
  # scf files to pwdata format
383
384
  scf_configs = self.collect_scf_configs()
384
- if len(scf_configs) > 0:
385
- extract_pwdata(input_data_list=scf_configs,
385
+ cvg_files, uncvg_files, cvg_infos, cvg_detail_infos = check_convergence(scf_configs, self.resource.dft_style)
386
+ if len(cvg_files) > 0:
387
+ extract_pwdata(input_data_list=cvg_files,
386
388
  intput_data_format =DFT_STYLE.get_format_by_postfix(os.path.basename(scf_configs[0])),
387
389
  save_data_path =self.result_dir,
388
390
  save_data_name = INIT_BULK.get_save_format(self.input_param.data_format),
@@ -391,6 +393,8 @@ class Labeling(object):
391
393
  )
392
394
  # copy to main dir
393
395
  copy_dir(self.result_dir, self.real_result_dir)
396
+ print(cvg_detail_infos)
397
+ write_to_file(os.path.join(self.input_param.root_dir, EXPLORE_FILE_STRUCTURE.iter_select_file), cvg_detail_infos, mode='a')
394
398
 
395
399
  def do_post_bigmodel(self):
396
400
  # copy the bigmodel labeled.xyz to result
@@ -0,0 +1,110 @@
1
+ from ase.io import read
2
+ from ase.units import fs
3
+ from ase.md.velocitydistribution import MaxwellBoltzmannDistribution
4
+ from ase.md.nvtberendsen import NVTBerendsen
5
+ from ase.md.npt import NPT
6
+ from ase.optimize import LBFGS
7
+ import numpy as np
8
+ from sevenn.sevennet_calculator import SevenNetCalculator
9
+
10
+ traj_name = "tmp.traj"
11
+ xyz_name = "traj.xyz"
12
+
13
+ calc = SevenNetCalculator()
14
+ fmax = 0.1
15
+ run_step = 10000
16
+
17
+ T = 300
18
+ P = 1.01325
19
+ P_in_ev_per_ang3 = P / 1602176.6208
20
+ atoms = read("POSCAR")
21
+ if not NPT._isuppertriangular(atoms.get_cell()):
22
+ a, b, c, alpha, beta, gamma = atoms.cell.cellpar()
23
+ angles = np.radians((alpha, beta, gamma))
24
+ sin_a, sin_b, _sin_g = np.sin(angles)
25
+ cos_a, cos_b, cos_g = np.cos(angles)
26
+ cos_p = (cos_g - cos_a * cos_b) / (sin_a * sin_b)
27
+ cos_p = np.clip(cos_p, -1, 1)
28
+ sin_p = (1 - cos_p**2) ** 0.5
29
+ new_basis = [
30
+ (a * sin_b * sin_p, a * sin_b * cos_p, a * cos_b),
31
+ (0, b * sin_a, b * cos_a),
32
+ (0, 0, c),
33
+ ]
34
+ atoms.set_cell(new_basis, scale_atoms=True)
35
+
36
+ atoms.calc = calc
37
+ opt = LBFGS(atoms)
38
+
39
+ def atoms2xyzstr(atoms):
40
+ num_atom = atoms.get_global_number_of_atoms()
41
+ vol = atoms.get_volume()
42
+ pos = atoms.positions
43
+ forces = atoms.get_forces()
44
+ energy = atoms.get_potential_energy()
45
+ cell = atoms.cell
46
+ virial = -atoms.get_stress(voigt=False) * vol
47
+ xyzstr = "%d\n" % num_atom
48
+ xyz_head = 'Lattice="%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f" Properties=species:S:1:pos:R:3:forces:R:3 energy=%.8f'
49
+ xyz_format = (cell[0,0],cell[0,1],cell[0,2],cell[1,0],cell[1,1],cell[1,2],cell[2,0],cell[2,1],cell[2,2],energy)
50
+ if virial is not None:
51
+ xyz_head += ' virial="%.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f"'
52
+ xyz_format += (
53
+ virial[0,0], virial[0,1], virial[0,2],
54
+ virial[1,0], virial[1,1], virial[1,2],
55
+ virial[2,0], virial[2,1], virial[2,2]
56
+ )
57
+ xyz_head += '\n'
58
+ xyzstr += xyz_head % xyz_format
59
+ for i in range(num_atom):
60
+ xyzstr += "%2s %14.8f %14.8f %14.8f %14.8f %14.8f %14.8f\n" %\
61
+ (atoms[i].symbol,pos[i,0],pos[i,1],pos[i,2],forces[i,0],forces[i,1],forces[i,2])
62
+ return xyzstr
63
+
64
+ def domd():
65
+ opt.run(fmax=fmax)
66
+ MaxwellBoltzmannDistribution(atoms, temperature_K=T)
67
+
68
+ '''
69
+ print("Beginning Nose-Hoover NVT equilibration")
70
+ dyn_nvt = NPT(
71
+ atoms=atoms,
72
+ timestep=.5*fs,
73
+ temperature_K=600,
74
+ externalstress=P_in_ev_per_ang3,
75
+ ttime=25*fs,
76
+ pfactor=None,
77
+ logfile="nvt.log",
78
+ loginterval=200
79
+ )
80
+ dyn_nvt.run(200000)
81
+ '''
82
+
83
+ print("Beginning Nose-Hoover NPT equilibration")
84
+ dyn_npt = NPT(
85
+ atoms=atoms,
86
+ timestep=.5*fs,
87
+ temperature_K=T,
88
+ externalstress=P_in_ev_per_ang3,
89
+ mask=np.eye(3),
90
+ ttime=25*fs,
91
+ pfactor=50*fs, #None nvt
92
+ trajectory=traj_name,
93
+ logfile="npt.log",
94
+ loginterval=100
95
+ )
96
+ dyn_npt.run(run_step)
97
+
98
+ def dolabel():
99
+ traj = read(traj_name, index=":")
100
+ output_file = xyz_name
101
+ f = open(output_file, "w")
102
+ for i in range(len(traj)):
103
+ atoms = traj[i]
104
+ atoms.calc = calc
105
+ f.write(atoms2xyzstr(atoms))
106
+ f.close()
107
+
108
+ if __name__=="__main__":
109
+ domd()
110
+ dolabel()
@@ -1,6 +1,7 @@
1
1
  import os
2
2
  import glob
3
- from pwact.utils.file_operation import check_model_type
3
+ import subprocess
4
+ from pwact.utils.file_operation import check_model_type, search_file_by_shell
4
5
  from pwact.utils.json_operation import get_parameter, get_required_parameter
5
6
  from pwact.utils.constant import MODEL_CMD, FORCEFILED, UNCERTAINTY, PWDATA
6
7
  from pwact.active_learning.user_input.train_param.train_param import InputParam as TrainParam
@@ -141,10 +142,9 @@ class SysConfig(object):
141
142
  sys_config_list = glob.glob(sys_config)
142
143
  self.sys_config = sorted(sys_config_list)
143
144
 
144
-
145
-
146
145
  class ExploreParam(object):
147
146
  def __init__(self, json_dict, max_select:int=None) -> None:
147
+ # sys_configs
148
148
  sys_config_prefix = get_parameter("sys_config_prefix", json_dict, None)
149
149
  sys_configs = get_required_parameter("sys_configs", json_dict)
150
150
  if isinstance(sys_configs, str) or isinstance(sys_configs, dict):
@@ -158,9 +158,21 @@ class ExploreParam(object):
158
158
  elif isinstance(sys_config, dict):
159
159
  config = os.path.join(sys_config_prefix, sys_config["config"]) if sys_config_prefix is not None else sys_config["config"]
160
160
  config_format = get_parameter("format", sys_config, PWDATA.pwmat_config)
161
- if not os.path.exists(config):
161
+ if len(glob.glob(config)) < 1:
162
162
  raise Exception("ERROR! The sys_config {} file does not exist!".format(config))
163
163
  self.sys_configs.append(SysConfig(config, config_format))
164
+
165
+ # lammps.in files
166
+ lmps_prefix = get_parameter("lmps_prefix", json_dict, None)
167
+ lmps_in = get_parameter("lmps_in", json_dict, [])
168
+ if isinstance(lmps_in, str) or isinstance(lmps_in, dict):
169
+ lmps_in = [lmps_in]
170
+ self.lmps_in:list[str]=[]
171
+ for lmp_in_file in lmps_in:
172
+ lmp_file = os.path.join(lmps_prefix, lmp_in_file) if lmps_prefix is not None else lmp_in_file
173
+ if not os.path.exists(lmp_file):
174
+ raise Exception("ERROR! The lammps.in file {} does not exist!".format(lmp_file))
175
+ self.lmps_in.append(lmp_file)
164
176
 
165
177
  # set md deatils
166
178
  self.md_job_list = self.set_md_details(json_dict["md_jobs"], max_select)
@@ -173,7 +185,7 @@ class ExploreParam(object):
173
185
  if not isinstance(md_dict, list):
174
186
  md_dict = [md_dict]
175
187
  for md_exp_id, md_exp in enumerate(md_dict):
176
- iter_exp_md.append(MdDetail(md_exp_id, md_exp, max_select, self.sys_configs))
188
+ iter_exp_md.append(MdDetail(md_exp_id, md_exp, max_select, self.sys_configs, self.lmps_in))
177
189
  iter_md.append(iter_exp_md)
178
190
  return iter_md
179
191
 
@@ -182,11 +194,16 @@ class ExploreParam(object):
182
194
  return res
183
195
 
184
196
  class MdDetail(object):
185
- def __init__(self, md_index: int, json_dict:dict, max_select:int=None, sys_configs:list[SysConfig]=None) -> None:
197
+ def __init__(self, md_index: int,
198
+ json_dict:dict,
199
+ max_select:int=None,
200
+ sys_configs:list[SysConfig]=None,
201
+ lmps_in:list[str]=None) -> None:
186
202
  self.md_index = md_index
187
- self.nsteps = get_required_parameter("nsteps", json_dict)
188
- self.md_dt = get_parameter("md_dt", json_dict, 0.001) #fs
189
203
  self.trj_freq = get_parameter("trj_freq", json_dict, 10)
204
+
205
+ self.nsteps = get_parameter("nsteps", json_dict, None)
206
+ self.md_dt = get_parameter("md_dt", json_dict, 0.001) #fs
190
207
 
191
208
  self.ensemble = get_parameter("ensemble", json_dict, "nve")
192
209
 
@@ -199,7 +216,8 @@ class MdDetail(object):
199
216
 
200
217
  if not isinstance(self.temp_list, list):
201
218
  self.temp_list = [self.temp_list]
202
-
219
+
220
+ #sys_idx
203
221
  sys_idx = get_required_parameter("sys_idx", json_dict)
204
222
 
205
223
  if not isinstance(sys_idx, list):
@@ -212,7 +230,8 @@ class MdDetail(object):
212
230
  _select_sys = max_select
213
231
  if not isinstance(_select_sys, list):
214
232
  _select_sys = [_select_sys]
215
-
233
+
234
+ #select_sys
216
235
  select_sys = []
217
236
  if len(_select_sys) > 0:
218
237
  if len(_select_sys) == 1:
@@ -222,20 +241,46 @@ class MdDetail(object):
222
241
  select_sys = _select_sys
223
242
  else:
224
243
  raise Exception("The length of the 'select_sys' array needs to be consistent with'sys_idx'" )
244
+
245
+ # from lammps.in
246
+ _lmps_in_idx = get_parameter("lmps_in_idx", json_dict, [])
247
+ lmps_in_idx = []
248
+ if not isinstance(_lmps_in_idx, list):
249
+ _lmps_in_idx = [_lmps_in_idx]
250
+ # check lammps.in file
251
+ if len(_lmps_in_idx) > 0:
252
+ if len(_lmps_in_idx) == 1:
253
+ for i in range(0, len(sys_idx)):
254
+ lmps_in_idx.append(_lmps_in_idx[0])
255
+ elif len(_lmps_in_idx) == len(sys_idx):
256
+ lmps_in_idx = _lmps_in_idx
257
+ else:
258
+ raise Exception("The length of the 'lmps_in_idx' array needs to be consistent with'sys_idx'" )
259
+ self.use_lmps_in = True
260
+ else:
261
+ self.use_lmps_in = False
262
+
225
263
  # reset select_sys and sys_idx by sys_configs
226
264
  self.sys_idx = []
227
265
  self.select_sys = []
266
+ self.lmp_in_idx = []
228
267
  self.config_file_list = []
268
+ self.lmp_in_file_list = []
229
269
  self.config_file_format = []
230
270
  file_id = 0
231
271
  for index, sys_id in enumerate(sys_idx):
232
272
  systems = sys_configs[sys_id].sys_config
273
+ if self.use_lmps_in:
274
+ lmp_in_file = lmps_in[lmps_in_idx[index]]
233
275
  system_format = sys_configs[sys_id].format
234
276
  for system in systems:
235
277
  self.config_file_list.append(system)
236
278
  self.config_file_format.append(system_format)
237
279
  self.sys_idx.append(file_id)
238
280
  self.select_sys.append(select_sys[index])
281
+ if self.use_lmps_in:
282
+ self.lmp_in_idx.append(lmps_in_idx[index])
283
+ self.lmp_in_file_list.append(lmp_in_file)
239
284
  file_id += 1
240
285
 
241
286
  self.kspacing = get_parameter("temps", json_dict, None)
@@ -153,17 +153,20 @@ def extract_pwdata(input_data_list:list[str],
153
153
  save_data_path = os.path.join(os.getcwd(), save_data_path)
154
154
  image_data = None
155
155
  for dir in input_data_list:
156
- if image_data is not None:
157
- tmp_config = Config(format=intput_data_format, data_path=dir)
158
- # if not isinstance(tmp_config, list):
159
- # tmp_config = [tmp_config]
160
- image_data.images.extend(tmp_config.images)
161
- else:
162
- image_data = Config(format=intput_data_format, data_path=dir)
163
-
164
- if not isinstance(image_data.images, list):
165
- image_data.images = [image_data.images]
166
-
156
+ try:
157
+ if image_data is not None:
158
+ tmp_config = Config(format=intput_data_format, data_path=dir)
159
+ # if not isinstance(tmp_config, list):
160
+ # tmp_config = [tmp_config]
161
+ image_data.images.extend(tmp_config.images)
162
+ else:
163
+ image_data = Config(format=intput_data_format, data_path=dir)
164
+
165
+ if not isinstance(image_data.images, list):
166
+ image_data.images = [image_data.images]
167
+ except Exception as e:
168
+ print("Warning! Read the traj file error {}".format(dir))
169
+ pass
167
170
  # if not isinstance(image_data, list):
168
171
  # image_data = [image_data]
169
172
  if interval > 1:
@@ -158,4 +158,90 @@ def set_input_script(
158
158
  # )
159
159
 
160
160
  else:
161
- pass
161
+ pass
162
+
163
+ def is_convergence(file_path, format):
164
+ def _is_cvg_vasp(file_path:str):
165
+ with open(file_path, 'r') as rf:
166
+ outcar_contents = rf.readlines()
167
+ nelm = None
168
+ ediff = None
169
+ for idx, ii in enumerate(outcar_contents):
170
+ if 'NELM =' in ii:
171
+ nelm = int(ii.split()[2][:-1])
172
+ if 'EDIFF = ' in ii:
173
+ ediff = float(ii.split()[-1])
174
+
175
+ with open(os.path.join(os.path.dirname(os.path.abspath(file_path)), "OSZICAR"), 'r') as rf:
176
+ oszi_contents = rf.readlines()
177
+ _split = oszi_contents[-2].split()
178
+ real_nelm = int(_split[1])
179
+ real_ediff1 = abs(float(_split[3]))
180
+ real_ediff2 = abs(float(_split[4]))
181
+
182
+ if real_nelm < nelm:
183
+ return True
184
+ elif real_ediff1 <= ediff and real_ediff2 <=ediff:
185
+ return True
186
+ else:
187
+ False
188
+
189
+ def _is_cvg_pwmat(file_path:str):
190
+ with open(os.path.join(os.path.dirname(os.path.abspath(file_path)), "REPORT"), 'r') as rf:
191
+ report_contents = rf.readlines()
192
+ e_error = None
193
+ rho_error = None
194
+ etot_idx = -1
195
+ drho_idx = -1
196
+ for idx, ii in enumerate(report_contents):
197
+ if e_error is None and 'E_ERROR =' in ii:
198
+ e_error = abs(float(ii.split()[-1]))
199
+ if rho_error is None and 'RHO_ERROR =' in ii:
200
+ rho_error = abs(float(ii.split()[-1]))
201
+ if 'E_tot(eV) =' in ii:
202
+ etot_idx = idx
203
+ if 'dv_ave, drho_tot =' in ii:
204
+ drho_idx = idx
205
+ if 'niter reached' in ii:
206
+ break
207
+ elif 'ending_scf_reason = tol' in ii:
208
+ return True
209
+
210
+ if e_error >= abs(float(report_contents[etot_idx].split()[-1])) or \
211
+ rho_error >= abs(float(report_contents[drho_idx].split()[-1])):
212
+ return True
213
+ return False
214
+
215
+ def _is_cvg_cp2k(file_path:str):
216
+ with open(os.path.join(os.path.dirname(os.path.abspath(file_path)), "dft.log"), 'r') as rf:
217
+ report_contents = rf.readlines()
218
+ for idx, ii in enumerate(report_contents):
219
+ if 'SCF run NOT converged' in ii:
220
+ return False
221
+ return True
222
+
223
+ if format == DFT_STYLE.vasp:
224
+ return _is_cvg_vasp(file_path)
225
+ elif format == DFT_STYLE.pwmat:
226
+ return _is_cvg_pwmat(file_path)
227
+ elif format == DFT_STYLE.cp2k:
228
+ return _is_cvg_cp2k(file_path)
229
+ else: # for other format
230
+ return True
231
+
232
+ def check_convergence(file_path:list[str], format:str):
233
+ cvg_files = []
234
+ uncvg_files = []
235
+ cvg_infos = ""
236
+ cvg_detail_infos=""
237
+ for file in file_path:
238
+ if is_convergence(file, format):
239
+ cvg_files.append(file)
240
+ else:
241
+ uncvg_files.append(file)
242
+ cvg_infos += "Number of converged files: {}, number of non-converged files: {}\n".format(len(cvg_files), len(uncvg_files))
243
+ cvg_detail_infos += cvg_infos
244
+ if len(uncvg_files) > 0:
245
+ cvg_detail_infos += "List of non-converged files:\n{}".format("\n".join(uncvg_files))
246
+ return cvg_files, uncvg_files, cvg_infos, cvg_detail_infos
247
+
@@ -236,3 +236,92 @@ def get_all_dumped_forces(file_name):
236
236
  return ret
237
237
 
238
238
 
239
+ def make_lammps_input_from_lmp_in_file(
240
+ md_file,
241
+ md_type,
242
+ forcefiled,
243
+ lmp_in_file,
244
+ atom_type,
245
+ trj_freq,
246
+ boundary, #true is 'p p p', false is 'f f f', default is true
247
+ merge_traj,
248
+ max_seed=100000,
249
+ restart=0,
250
+ model_deviation_file = "model_deviation.out"
251
+ ):
252
+ with open(lmp_in_file, 'r') as rf:
253
+ lmp_content = rf.readlines()
254
+ runline_idx = find_first_run_cmd_line(lmp_content)
255
+ if runline_idx is None:
256
+ raise Exception("Error! The input lmp.in file: {} is missing the 'RUN' command, please modify it!".format(lmp_in_file))
257
+ # remove the units boundary atom_stype lines
258
+ # units metal
259
+ # boundary p p p
260
+ # atom_style atomic
261
+ # remove mass pair_style pair_coeff dump
262
+ lmp_content = remove_lmps_lines(lmp_content)
263
+ lmp_content.insert(0, "variable DUMP_FREQ equal %d\n" % trj_freq)
264
+ lmp_content.insert(1, "variable restart equal %d\n" % restart)
265
+
266
+ md_script = ""
267
+ md_script += "units metal\n"
268
+ if boundary:
269
+ md_script += "boundary p p p\n"
270
+ else:
271
+ md_script += "boundary f f f\n"
272
+ md_script += "atom_style atomic\n"
273
+ md_script += "\n"
274
+ lmp_content.insert(2, md_script)
275
+
276
+ md_script = (
277
+ 'if "${restart} > 0" then "read_restart lmps.restart.*" else "read_data %s"\n'
278
+ % md_file
279
+ )
280
+ lmp_content.insert(3, md_script)
281
+
282
+ md_script = make_mass(atom_type)
283
+ dump_info = "out_freq ${{DUMP_FREQ}} out_file {} ".format(model_deviation_file)
284
+ md_script += make_pair_style(md_type, forcefiled, atom_type, dump_info)
285
+ #put_freq ${freq} out_file error
286
+ md_script += "\n"
287
+ lmp_content.insert(4, md_script)
288
+ # md_script += "thermo_style custom step temp pe ke etotal press vol lx ly lz xy xz yz\n"
289
+ # md_script += "thermo ${THERMO_FREQ}\n"
290
+
291
+ if merge_traj is True:
292
+ dump_line = "dump 1 all custom ${DUMP_FREQ} all.lammpstrj id type x y z fx fy fz\n"
293
+ dump_line += 'if "${restart} > 0" then "dump_modify 1 append yes"\n'
294
+ else:
295
+ dump_line = "dump 1 all custom ${DUMP_FREQ} traj/*.lammpstrj id type x y z fx fy fz\n"
296
+
297
+ dump_line += "restart 10000 lmps.restart\n"
298
+ dump_line += "\n"
299
+
300
+ dump_line += 'if "${restart} == 0" then "velocity all create ${TEMP} %d"' % (
301
+ random.randrange(max_seed - 1) + 1
302
+ )
303
+
304
+ dump_line += "\n"
305
+ lmp_content.insert(runline_idx, dump_line)
306
+
307
+ return "".join(lmp_content)
308
+
309
+ def remove_lmps_lines(lmps_lines):
310
+ removes = ["dump_freq", "units", "boundary", "restart","atom_style", "read_data", "mass", "pair_style", "pair_coeff", "dump"]
311
+ new_lines = [
312
+ line for line in lmps_lines
313
+ if line.lstrip().startswith('#')
314
+ or not any(
315
+ keyword.lower() in line.lower()
316
+ for keyword in removes
317
+ )
318
+ ]
319
+ return new_lines
320
+
321
+ def find_first_run_cmd_line(lmps_lines):
322
+ for i, line in enumerate(lmps_lines):
323
+ if 'run' in line.lower():
324
+ # 计算倒数行数(从1开始计数)
325
+ return -(len(lmps_lines) - i)
326
+ return None
327
+
@@ -288,6 +288,11 @@ def search_files(search_root_dir:str, template:str):
288
288
  file_list = glob.glob(os.path.join(search_root_dir, template))
289
289
  return file_list
290
290
 
291
+ def search_file_by_shell(search_patten:str):
292
+ result = subprocess.run(["ls"], capture_output=True, text=True)
293
+ filtered = [line for line in result.stdout.split("\n") if "pattern" in line]
294
+ return filtered
295
+
291
296
  def str_list_format(input_value):
292
297
  input_list = []
293
298
  if isinstance(input_value, str):
@@ -36,6 +36,12 @@ def make_temp_name(md_index:int, sys_index:int, temp_index:int, len_char:int = N
36
36
  return "md."+(md_name % md_index)+".sys."+(sys_name % sys_index)+\
37
37
  ".t."+ (sys_name % temp_index)
38
38
 
39
+ def make_lmps_name(md_index:int, sys_index:int, lmps_index:int, len_char:int = None):
40
+ md_name = "%03d"
41
+ sys_name = "%03d" if len_char is None else "%0{}d".format(len_char)
42
+ return "md."+(md_name % md_index)+".sys."+(sys_name % sys_index)+\
43
+ ".lmps."+ (sys_name % lmps_index)
44
+
39
45
  def get_sub_md_sys_template_name():
40
46
  return "md.*.sys.*/md.*.sys.*"
41
47
 
@@ -196,7 +196,7 @@ def set_slurm_script_content(
196
196
  script = ""
197
197
  if gpu_per_node is None or gpu_per_node == 0:
198
198
  script += CPU_SCRIPT_HEAD.format(job_name, number_node, cpu_per_node, queue_name)
199
- script += "export CUDA_VISIBLE_DEVICES=''\n"
199
+ # script += "export CUDA_VISIBLE_DEVICES=''\n"
200
200
  else:
201
201
  script += GPU_SCRIPT_HEAD.format(job_name, number_node, cpu_per_node, gpu_per_node, queue_name)
202
202
 
@@ -0,0 +1,161 @@
1
+ from pwdata import Config
2
+ import os, sys, glob
3
+ import numpy as np
4
+
5
+ def count_pwdata(work_dir):
6
+
7
+ dir_list = glob.glob(os.path.join(work_dir, "*"))
8
+ res = []
9
+ for dir in dir_list:
10
+ # train
11
+ train_num = np.load(os.path.join(dir, "train/energies.npy")).shape[0]
12
+ res.append(train_num)
13
+
14
+ if os.path.exists(os.path.join(dir, "valid/energies.npy")):
15
+ test_num = np.load(os.path.join(dir, "valid/energies.npy")).shape[0]
16
+ res.append(test_num)
17
+ print("{} {} {}".format( dir, train_num, test_num))
18
+ else:
19
+ print("{} {}".format(dir, train_num))
20
+ print(np.sum(res))
21
+
22
+ def count_outmlmd():
23
+ work_dir = "/data/home/wuxingxing/datas/debugs/dengjiapei/run_iter/iter.0000/label/scf"
24
+ mlmds = glob.glob(os.path.join(work_dir, "*/*/*/OUT.MLMD"))
25
+ print(len(mlmds))
26
+
27
+ def save_mlmd():
28
+ work_dir = "/data/home/wuxingxing/datas/debugs/dengjiapei/run_iter"
29
+ data_list = glob.glob(os.path.join(work_dir, "iter.*/label/scf/*/*/*/OUT.MLMD"))
30
+ datasets_path = "/data/home/wuxingxing/datas/debugs/dengjiapei/run_iter/mlmd_pwdata"
31
+ # data_name = datasets_path
32
+ image_data = None
33
+ for data_path in data_list:
34
+ if image_data is not None:
35
+ tmp_config = Config("pwmat/movement", data_path)
36
+ # if not isinstance(tmp_config, list):
37
+ # tmp_config = [tmp_config]
38
+ image_data.images.extend(tmp_config.images)
39
+ else:
40
+ image_data = Config("pwmat/movement", data_path)
41
+
42
+ if not isinstance(image_data.images, list):
43
+ image_data.images = [image_data.images]
44
+
45
+ # if not isinstance(image_data, list):
46
+ # image_data = [image_data]
47
+ image_data.to(
48
+ output_path=datasets_path,
49
+ save_format="pwmlff/npy",
50
+ train_ratio = 0.8,
51
+ train_data_path="train",
52
+ valid_data_path="valid",
53
+ random=True,
54
+ seed = 2024,
55
+ retain_raw = False
56
+ )
57
+ print(len(image_data.images))
58
+
59
+ def find_outcar_files(directory):
60
+ outcar_files = []
61
+ for root, dirs, files in os.walk(directory):
62
+ for file in files:
63
+ if file == 'OUTCAR' or file == "REPORT":
64
+ outcar_files.append(os.path.join(root, file))
65
+
66
+
67
+ return outcar_files
68
+
69
+ def is_convergence(file_path, format):
70
+ def _is_cvg_vasp(file_path:str):
71
+ with open(file_path, 'r') as rf:
72
+ outcar_contents = rf.readlines()
73
+ nelm = None
74
+ ediff = None
75
+ for idx, ii in enumerate(outcar_contents):
76
+ if 'NELM =' in ii:
77
+ nelm = int(ii.split()[2][:-1])
78
+ if 'EDIFF = ' in ii:
79
+ ediff = float(ii.split()[-1])
80
+
81
+ with open(os.path.join(os.path.dirname(os.path.abspath(file_path)), "OSZICAR"), 'r') as rf:
82
+ oszi_contents = rf.readlines()
83
+ _split = oszi_contents[-2].split()
84
+ real_nelm = int(_split[1])
85
+ real_ediff1 = abs(float(_split[3]))
86
+ real_ediff2 = abs(float(_split[4]))
87
+
88
+ if real_nelm < nelm:
89
+ return True
90
+ elif real_ediff1 <= ediff and real_ediff2 <=ediff:
91
+ return True
92
+ else:
93
+ False
94
+
95
+ def _is_cvg_pwmat(file_path:str):
96
+ with open(file_path, 'r') as rf:
97
+ report_contents = rf.readlines()
98
+ e_error = None
99
+ rho_error = None
100
+ etot_idx = -1
101
+ drho_idx = -1
102
+ for idx, ii in enumerate(report_contents):
103
+ if e_error is None and 'E_ERROR =' in ii:
104
+ e_error = abs(float(ii.split()[-1]))
105
+ if rho_error is None and 'RHO_ERROR =' in ii:
106
+ rho_error = abs(float(ii.split()[-1]))
107
+ if 'E_tot(eV) =' in ii:
108
+ etot_idx = idx
109
+ if 'dv_ave, drho_tot =' in ii:
110
+ drho_idx = idx
111
+ if 'niter reached' in ii:
112
+ break
113
+ elif 'ending_scf_reason = tol' in ii:
114
+ return True
115
+
116
+ if e_error >= abs(float(report_contents[etot_idx].split()[-1])) or \
117
+ rho_error >= abs(float(report_contents[drho_idx].split()[-1])):
118
+ return True
119
+ return False
120
+
121
+ if format == "vasp":
122
+ return _is_cvg_vasp(file_path)
123
+ elif format == "pwmat":
124
+ return _is_cvg_pwmat(file_path)
125
+ elif format == "cp2k":
126
+ return True
127
+
128
+ def check_convergence(file_path:list[str], format:str):
129
+ cvg_files = []
130
+ uncvg_files = []
131
+ cvg_infos = ""
132
+ cvg_detail_infos=""
133
+ for file in file_path:
134
+ if is_convergence(file, format):
135
+ cvg_files.append(file)
136
+ else:
137
+ uncvg_files.append(file)
138
+
139
+ cvg_infos += "Number of converged files: {}, number of non-converged files: {}".format(len(cvg_files), len(uncvg_files))
140
+ cvg_detail_infos += cvg_infos
141
+ cvg_detail_infos += "\nList of non-converged files:\n{}".format("\n".join(uncvg_files))
142
+ return cvg_files, uncvg_files, cvg_infos, cvg_detail_infos
143
+
144
+ def cvt_config():
145
+ pwdata = "/data/home/wuxingxing/datas/pwmat_mlff_workdir/auag/pwdata/Ag4Au44"
146
+ image = Config.read(data_path=pwdata, format="pwmlff/npy")[0][0]
147
+ image.to(data_path="/share/public/PWMLFF_test_data/pwact_examples/25-pwact-demo/structures/AuAg", data_name="ag4au44-atom.config", format="pwmat/config")
148
+
149
+ if __name__=="__main__":
150
+ # count_pwdata(work_dir = "/data/home/wuxingxing/datas/debugs/dengjiapei/run_iter/mlmd_pwdata")
151
+ # count_outmlmd()
152
+ # save_mlmd()
153
+ # cvt_config()
154
+ os.chdir("/share/public/PWMLFF_test_data/pwact_examples/25-pwact-demo/si_pwmat/run_iter_lmps/iter.0000/temp_run_iter_work/02.label/scf")
155
+ current_dir = os.getcwd()
156
+ outcar_files = find_outcar_files(current_dir)
157
+ cvg_files, uncvg_files, cvg_infos, cvg_detail_infos = check_convergence(outcar_files, "pwmat")
158
+ print(cvg_detail_infos)
159
+ print(cvg_infos)
160
+
161
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pwact
3
- Version: 0.3.4
3
+ Version: 0.4.0.dev0
4
4
  Summary: PWACT is an open-source automated active learning platform based on MatPL for efficient data sampling.
5
5
  Home-page: https://github.com/LonxunQuantum/PWact
6
6
  Author: LonxunQuantum
@@ -28,6 +28,7 @@ pwact/active_learning/slurm/slurm.py
28
28
  pwact/active_learning/slurm/slurm_tool.py
29
29
  pwact/active_learning/test/__init__.py
30
30
  pwact/active_learning/test/test.py
31
+ pwact/active_learning/test/uma_md.py
31
32
  pwact/active_learning/train/__init__.py
32
33
  pwact/active_learning/train/dp_kpu.py
33
34
  pwact/active_learning/train/train_model.py
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="pwact",
8
- version="0.3.4",
8
+ version="0.4.0.dev",
9
9
  author="LonxunQuantum",
10
10
  author_email="lonxun@pwmat.com",
11
11
  description="PWACT is an open-source automated active learning platform based on MatPL for efficient data sampling.",
@@ -1,63 +0,0 @@
1
- from pwdata import Config
2
- import os, sys, glob
3
- import numpy as np
4
-
5
- def count_pwdata(work_dir):
6
-
7
- dir_list = glob.glob(os.path.join(work_dir, "*"))
8
- res = []
9
- for dir in dir_list:
10
- # train
11
- train_num = np.load(os.path.join(dir, "train/energies.npy")).shape[0]
12
- res.append(train_num)
13
-
14
- if os.path.exists(os.path.join(dir, "valid/energies.npy")):
15
- test_num = np.load(os.path.join(dir, "valid/energies.npy")).shape[0]
16
- res.append(test_num)
17
- print("{} {} {}".format( dir, train_num, test_num))
18
- else:
19
- print("{} {}".format(dir, train_num))
20
- print(np.sum(res))
21
-
22
- def count_outmlmd():
23
- work_dir = "/data/home/wuxingxing/datas/debugs/dengjiapei/run_iter/iter.0000/label/scf"
24
- mlmds = glob.glob(os.path.join(work_dir, "*/*/*/OUT.MLMD"))
25
- print(len(mlmds))
26
-
27
- def save_mlmd():
28
- work_dir = "/data/home/wuxingxing/datas/debugs/dengjiapei/run_iter"
29
- data_list = glob.glob(os.path.join(work_dir, "iter.*/label/scf/*/*/*/OUT.MLMD"))
30
- datasets_path = "/data/home/wuxingxing/datas/debugs/dengjiapei/run_iter/mlmd_pwdata"
31
- # data_name = datasets_path
32
- image_data = None
33
- for data_path in data_list:
34
- if image_data is not None:
35
- tmp_config = Config("pwmat/movement", data_path)
36
- # if not isinstance(tmp_config, list):
37
- # tmp_config = [tmp_config]
38
- image_data.images.extend(tmp_config.images)
39
- else:
40
- image_data = Config("pwmat/movement", data_path)
41
-
42
- if not isinstance(image_data.images, list):
43
- image_data.images = [image_data.images]
44
-
45
- # if not isinstance(image_data, list):
46
- # image_data = [image_data]
47
- image_data.to(
48
- output_path=datasets_path,
49
- save_format="pwmlff/npy",
50
- train_ratio = 0.8,
51
- train_data_path="train",
52
- valid_data_path="valid",
53
- random=True,
54
- seed = 2024,
55
- retain_raw = False
56
- )
57
- print(len(image_data.images))
58
-
59
-
60
- if __name__=="__main__":
61
- count_pwdata(work_dir = "/data/home/wuxingxing/datas/debugs/dengjiapei/run_iter/mlmd_pwdata")
62
- # count_outmlmd()
63
- # save_mlmd()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes