pwact 0.1.19__tar.gz → 0.1.21__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 (64) hide show
  1. {pwact-0.1.19 → pwact-0.1.21}/PKG-INFO +1 -1
  2. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/explore/select_image.py +59 -17
  3. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/init_bulk/aimd.py +1 -2
  4. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/init_bulk/duplicate_scale.py +1 -1
  5. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/init_bulk/relabel.py +1 -2
  6. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/init_bulk/relax.py +1 -2
  7. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/label/labeling.py +2 -3
  8. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/test/test.py +2 -2
  9. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/user_input/cmd_infos.py +9 -0
  10. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/user_input/scf_param.py +23 -3
  11. {pwact-0.1.19 → pwact-0.1.21}/pwact/data_format/configop.py +12 -12
  12. {pwact-0.1.19 → pwact-0.1.21}/pwact/main.py +29 -2
  13. {pwact-0.1.19 → pwact-0.1.21}/pwact/utils/app_lib/common.py +17 -7
  14. {pwact-0.1.19 → pwact-0.1.21}/pwact/utils/app_lib/cp2k.py +98 -31
  15. pwact-0.1.21/pwact/utils/app_lib/cp2k_dp.py +194 -0
  16. {pwact-0.1.19 → pwact-0.1.21}/pwact/utils/app_lib/pwmat.py +49 -18
  17. {pwact-0.1.19 → pwact-0.1.21}/pwact.egg-info/PKG-INFO +1 -1
  18. {pwact-0.1.19 → pwact-0.1.21}/pwact.egg-info/SOURCES.txt +1 -0
  19. {pwact-0.1.19 → pwact-0.1.21}/setup.py +1 -1
  20. {pwact-0.1.19 → pwact-0.1.21}/LICENSE +0 -0
  21. {pwact-0.1.19 → pwact-0.1.21}/README.md +0 -0
  22. {pwact-0.1.19 → pwact-0.1.21}/pwact/__init__.py +0 -0
  23. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/__init__.py +0 -0
  24. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/environment.py +0 -0
  25. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/explore/__init__.py +0 -0
  26. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/explore/run_model_md.py +0 -0
  27. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/init_bulk/__init__.py +0 -0
  28. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/init_bulk/init_bulk_run.py +0 -0
  29. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/label/__init__.py +0 -0
  30. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/slurm/__init__.py +0 -0
  31. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/slurm/slurm.py +0 -0
  32. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/slurm/slurm_tool.py +0 -0
  33. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/test/__init__.py +0 -0
  34. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/train/__init__.py +0 -0
  35. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/train/dp_kpu.py +0 -0
  36. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/train/train_model.py +0 -0
  37. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/user_input/__init__.py +0 -0
  38. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/user_input/init_bulk_input.py +0 -0
  39. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/user_input/iter_input.py +0 -0
  40. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/user_input/resource.py +0 -0
  41. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/user_input/train_param/__init__.py +0 -0
  42. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/user_input/train_param/model_param.py +0 -0
  43. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/user_input/train_param/nep_param.py +0 -0
  44. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/user_input/train_param/nn_feature_type.py +0 -0
  45. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/user_input/train_param/optimizer_param.py +0 -0
  46. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/user_input/train_param/train_param.py +0 -0
  47. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/user_input/train_param/work_file_param.py +0 -0
  48. {pwact-0.1.19 → pwact-0.1.21}/pwact/active_learning/user_input/workdir.py +0 -0
  49. {pwact-0.1.19 → pwact-0.1.21}/pwact/bin/__init__.py +0 -0
  50. {pwact-0.1.19 → pwact-0.1.21}/pwact/data_format/__init__.py +0 -0
  51. {pwact-0.1.19 → pwact-0.1.21}/pwact/utils/__init__.py +0 -0
  52. {pwact-0.1.19 → pwact-0.1.21}/pwact/utils/app_lib/__init__.py +0 -0
  53. {pwact-0.1.19 → pwact-0.1.21}/pwact/utils/app_lib/lammps.py +0 -0
  54. {pwact-0.1.19 → pwact-0.1.21}/pwact/utils/constant.py +0 -0
  55. {pwact-0.1.19 → pwact-0.1.21}/pwact/utils/file_operation.py +0 -0
  56. {pwact-0.1.19 → pwact-0.1.21}/pwact/utils/format_input_output.py +0 -0
  57. {pwact-0.1.19 → pwact-0.1.21}/pwact/utils/json_operation.py +0 -0
  58. {pwact-0.1.19 → pwact-0.1.21}/pwact/utils/pre_al_data_util.py +0 -0
  59. {pwact-0.1.19 → pwact-0.1.21}/pwact/utils/process_tool.py +0 -0
  60. {pwact-0.1.19 → pwact-0.1.21}/pwact/utils/slurm_script.py +0 -0
  61. {pwact-0.1.19 → pwact-0.1.21}/pwact.egg-info/dependency_links.txt +0 -0
  62. {pwact-0.1.19 → pwact-0.1.21}/pwact.egg-info/entry_points.txt +0 -0
  63. {pwact-0.1.19 → pwact-0.1.21}/pwact.egg-info/top_level.txt +0 -0
  64. {pwact-0.1.19 → pwact-0.1.21}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pwact
3
- Version: 0.1.19
3
+ Version: 0.1.21
4
4
  Summary: PWACT is an open-source automated active learning platform based on PWMLFF for efficient data sampling.
5
5
  Home-page: https://github.com/LonxunQuantum/PWact
6
6
  Author: LonxunQuantum
@@ -118,7 +118,51 @@ def select_image(
118
118
  print("Image select result:\n {}\n\n".format(summary_info))
119
119
  return summary
120
120
 
121
-
121
+ def print_select_image(
122
+ md_dir:str,
123
+ save_dir:str,
124
+ devi_name:str,
125
+ lower:float,
126
+ higer:float
127
+ ):
128
+ #1. get model_deviation file
129
+ model_deviation_patten = "{}/{}".format(get_sub_md_sys_template_name(), devi_name)
130
+ model_devi_files = search_files(md_dir, model_deviation_patten)
131
+ model_devi_files = sorted(model_devi_files)
132
+ md_sys_dict = sort_model_devi_files(model_devi_files)
133
+
134
+ error_pd =None
135
+ accurate_pd =None
136
+ rand_candi =None
137
+ remove_candi =None
138
+
139
+ for md in md_sys_dict.keys():
140
+ sys_dict = md_sys_dict[md]
141
+ for sys_idx, sys in enumerate(sys_dict.keys()):
142
+ devi_files = sys_dict[sys]
143
+ tmp_devi_pd, _base_kpu = read_pd_files(devi_files)
144
+ if len(_base_kpu) > 0: # for kpu upper and lower
145
+ _lower = np.mean(_base_kpu)*lower
146
+ _higer = _lower * higer
147
+ else:
148
+ _lower = lower
149
+ _higer = higer
150
+ tmp_error_pd, tmp_accurate_pd, tmp_rand_candi, tmp_remove_candi = select_pd(tmp_devi_pd, _lower, _higer, 10000000)
151
+ error_pd = pd.concat([error_pd, tmp_error_pd]) if error_pd is not None else tmp_error_pd
152
+ accurate_pd = pd.concat([accurate_pd, tmp_accurate_pd]) if error_pd is not None else tmp_accurate_pd
153
+ rand_candi = pd.concat([rand_candi, tmp_rand_candi]) if error_pd is not None else tmp_rand_candi
154
+ remove_candi = pd.concat([remove_candi, tmp_remove_candi]) if error_pd is not None else tmp_remove_candi
155
+ summary_info, summary = count_info(save_dir, error_pd, accurate_pd, rand_candi, remove_candi)
156
+
157
+ # summary_info, summary = select_image(save_dir=self.select_dir,
158
+ # devi_pd=devi_pd,
159
+ # lower=self.input_param.strategy.lower_model_deiv_f,
160
+ # higer=self.input_param.strategy.upper_model_deiv_f,
161
+ # max_select=self.input_param.strategy.max_select)
162
+ print("Image select result (lower {} upper {}):\n {}\n\n".format(lower, higer, summary_info))
163
+ return summary
164
+
165
+
122
166
  def select_pd(devi_pd:DataFrame, lower:float, higer:float, max_select:float):
123
167
  accurate_pd = devi_pd[devi_pd[EXPLORE_FILE_STRUCTURE.devi_columns[0]] < lower]
124
168
  candidate_pd = devi_pd[(devi_pd[EXPLORE_FILE_STRUCTURE.devi_columns[0]] >= lower) & (devi_pd[EXPLORE_FILE_STRUCTURE.devi_columns[0]] < higer)]
@@ -169,41 +213,39 @@ def read_pd_files(model_devi_files:list[str]):
169
213
 
170
214
  def count_info(save_dir, error_pd, accurate_pd, rand_candi, remove_candi):
171
215
  #5. save select info
172
- if not os.path.exists(save_dir):
173
- os.makedirs(save_dir)
174
216
  total_num = error_pd.shape[0] + accurate_pd.shape[0] + rand_candi.shape[0] + remove_candi.shape[0]
175
217
  cand_num = rand_candi.shape[0] + remove_candi.shape[0]
176
218
  summary = "Total structures {} accurate {} rate {:.2f}% selected {} rate {:.2f}% error {} rate {:.2f}%\n"\
177
219
  .format(total_num, accurate_pd.shape[0], accurate_pd.shape[0]/total_num*100, \
178
220
  cand_num, cand_num/total_num*100, \
179
221
  error_pd.shape[0], error_pd.shape[0]/total_num*100)
180
-
181
- accurate_pd.to_csv(os.path.join(save_dir, EXPLORE_FILE_STRUCTURE.accurate))
182
222
  candi_info = ""
183
- rand_candi.to_csv(os.path.join(save_dir, EXPLORE_FILE_STRUCTURE.candidate))
184
-
185
223
  if remove_candi.shape[0] == 0:
186
224
  candi_info += "Candidate configurations: {}\n Select details in file {}\n".format(
187
225
  cand_num, EXPLORE_FILE_STRUCTURE.candidate)
188
226
  else:
189
- remove_candi.to_csv(os.path.join(save_dir, EXPLORE_FILE_STRUCTURE.candidate_delete))
190
227
  candi_info += "Candidate configurations: {}, randomly select {}, delete {}\n Select details in file {}\n Delete details in file {}.\n".format(
191
228
  cand_num, rand_candi.shape[0], remove_candi.shape[0],\
192
229
  EXPLORE_FILE_STRUCTURE.candidate, EXPLORE_FILE_STRUCTURE.candidate_delete)
193
-
194
- error_pd.to_csv(os.path.join(save_dir, EXPLORE_FILE_STRUCTURE.failed))
195
-
196
230
  summary_info = ""
197
-
198
231
  summary_info += summary
199
232
  summary_info += "\nSelect by model deviation force:\n"
200
233
  summary_info += "Accurate configurations: {}, details in file {}\n".\
201
234
  format(accurate_pd.shape[0], EXPLORE_FILE_STRUCTURE.accurate)
202
-
203
235
  summary_info += candi_info
204
-
205
236
  summary_info += "Error configurations: {}, details in file {}\n".\
206
237
  format(error_pd.shape[0], EXPLORE_FILE_STRUCTURE.failed)
207
-
208
- write_to_file(os.path.join(save_dir, EXPLORE_FILE_STRUCTURE.select_summary), summary_info, "w")
209
- return summary_info, summary
238
+
239
+ if save_dir is not None:
240
+ if not os.path.exists(save_dir):
241
+ os.makedirs(save_dir)
242
+ accurate_pd.to_csv(os.path.join(save_dir, EXPLORE_FILE_STRUCTURE.accurate))
243
+ rand_candi.to_csv(os.path.join(save_dir, EXPLORE_FILE_STRUCTURE.candidate))
244
+ if remove_candi.shape[0] > 0:
245
+ remove_candi.to_csv(os.path.join(save_dir, EXPLORE_FILE_STRUCTURE.candidate_delete))
246
+ error_pd.to_csv(os.path.join(save_dir, EXPLORE_FILE_STRUCTURE.failed))
247
+ write_to_file(os.path.join(save_dir, EXPLORE_FILE_STRUCTURE.select_summary), summary_info, "w")
248
+
249
+ return summary_info, summary
250
+
251
+
@@ -161,8 +161,7 @@ class AIMD(object):
161
161
  flag_symm=flag_symm,
162
162
  save_dir = aimd_dir,
163
163
  pseudo_names=pseudo_names,
164
- basis_set_file_name=self.input_param.dft_input.basis_set_file,# these for cp2k
165
- potential_file_name=self.input_param.dft_input.potential_file
164
+ gaussian_base_param = self.input_param.dft_input.gaussian_base_param
166
165
  )
167
166
 
168
167
  def make_aimd_slurm_job_files(self, aimd_dir_list:list[str],use_dftb: bool=False):
@@ -34,7 +34,7 @@ def duplicate_scale(resource: Resource, input_param:InitBulkParam):
34
34
  super_cell_config = os.path.join(super_cell_scale_dir, DFT_STYLE.get_super_cell_config(resource.dft_style))
35
35
 
36
36
  if not os.path.exists(super_cell_config):
37
- do_super_cell(config=config_file,
37
+ do_super_cell(config_file=config_file,
38
38
  input_format=config_format,
39
39
  supercell_matrix=init_config.super_cell,
40
40
  pbc=init_config.pbc,
@@ -161,8 +161,7 @@ class Relabel(object):
161
161
  flag_symm=flag_symm,
162
162
  save_dir = save_dir,
163
163
  pseudo_names=pseudo_names,
164
- basis_set_file_name=self.input_param.dft_input.basis_set_file,# these for cp2k
165
- potential_file_name=self.input_param.dft_input.potential_file
164
+ gaussian_base_param=self.input_param.dft_input.gaussian_base_param,# these for cp2k
166
165
  )
167
166
  scf_lsit.append(save_dir)
168
167
  return scf_lsit
@@ -117,8 +117,7 @@ class Relax(object):
117
117
  dft_style=self.input_param.dft_style,
118
118
  save_dir=relax_path,
119
119
  pseudo_names=pseudo_names,
120
- basis_set_file_name=self.input_param.dft_input.basis_set_file,# these for cp2k
121
- potential_file_name=self.input_param.dft_input.potential_file,
120
+ gaussian_base_param=self.input_param.dft_input.gaussian_base_param,# these for cp2k
122
121
  # xc_functional=self.input_param.dft_input.xc_functional,
123
122
  # potential=self.input_param.dft_input.potential,
124
123
  # basis_set=self.input_param.dft_input.basis_set
@@ -191,9 +191,8 @@ class Labeling(object):
191
191
  flag_symm=self.input_param.scf.scf_input_list[0].flag_symm,
192
192
  save_dir=scf_dir,
193
193
  pseudo_names=pseudo_names,
194
- is_scf = True,
195
- basis_set_file_name =self.input_param.scf.basis_set_file,
196
- potential_file_name =self.input_param.scf.potential_file
194
+ gaussian_base_param=self.input_param.scf.gaussian_base_param,# these for cp2k
195
+ is_scf = True
197
196
  )
198
197
 
199
198
  def make_scf_slurm_job_files(self, scf_sub_list:list[str]):
@@ -4,7 +4,7 @@ import os
4
4
  import shutil
5
5
  import glob
6
6
  import json
7
- from pwdata.main import Config
7
+ from pwdata.config import Config
8
8
  def make_kspacing_kpoints(config, format, kspacing):
9
9
  config = Config(format=format, data_path=config)
10
10
  # with open(config, "r") as fp:
@@ -17,7 +17,7 @@ def make_kspacing_kpoints(config, format, kspacing):
17
17
  # box.append(vector)
18
18
  # box = np.array(box)
19
19
  # rbox = _reciprocal_box(box)
20
- box = config.images.lattice
20
+ box = config.images[0].lattice
21
21
  rbox = _reciprocal_box(box)
22
22
  kpoints = [
23
23
  max(1, round(2 * np.pi * np.linalg.norm(ii) / kspacing)) for ii in rbox
@@ -39,6 +39,8 @@ def cmd_infos(cmd_type=None):
39
39
  cmd_info = cmd_info_run_iter()
40
40
  elif cmd_type == "kill":
41
41
  cmd_info = cmd_info_kill()
42
+ elif cmd_type == "filter":
43
+ cmd_info = cmd_info_filter()
42
44
  print(cmd_info)
43
45
 
44
46
 
@@ -64,3 +66,10 @@ def cmd_info_kill():
64
66
  cmd_info += "'pwact kill init_bulk' for 'init_bulk' tasks\n"
65
67
  cmd_info += "'pwact kill run' for 'run' tasks\n\n"
66
68
  return cmd_info
69
+
70
+ def cmd_info_filter():
71
+ cmd_info = ""
72
+ cmd_info += "filter" + "\n"
73
+ cmd_info += "you could use this method to test the selection results corresponding to the upper and lower limit settings\n"
74
+ cmd_info += "example:\n"
75
+ cmd_info += "'pwact filter -i iter.0000/explore/select -l 0.01 -h 0.02 -s filter_test_result'\n\n"
@@ -62,8 +62,25 @@ class SCFParam(object):
62
62
  # else:
63
63
  # pass
64
64
  # for cp2k
65
- self.basis_set_file = get_parameter("basis_set_file", json_dict, None)
66
- self.potential_file = get_parameter("potential_file", json_dict, None)
65
+ gaussian_param = get_parameter("gaussian_param", json_dict, None)
66
+ if gaussian_param is not None:
67
+ self.basis_set_file = os.path.abspath(get_parameter("basis_set_file", gaussian_param, None))
68
+ self.potential_file = os.path.abspath(get_parameter("potential_file", gaussian_param, None))
69
+ basis_set_list = get_parameter("basis_set_list", gaussian_param, None)
70
+ potential_list = get_parameter("potential_list", gaussian_param, None)
71
+ atom_list = get_parameter("atom_list", gaussian_param, None)
72
+ self.gaussian_base_param = {}
73
+ self.gaussian_base_param["ELEMENT"] = atom_list
74
+ self.gaussian_base_param["BASIS_SET"] = basis_set_list
75
+ self.gaussian_base_param["POTENTIAL"] = potential_list
76
+ self.gaussian_base_param["BASIS_SET_FILE_NAME"] = os.path.basename(self.basis_set_file)
77
+ self.gaussian_base_param["POTENTIAL_FILE_NAME"] = os.path.basename(self.potential_file)
78
+ else:
79
+ self.basis_set_file = None# os.path.abspath(get_parameter("basis_set_file", json_dict, None))
80
+ self.potential_file = None#os.path.abspath(get_parameter("potential_file", json_dict, None))
81
+ self.gaussian_base_param = None
82
+ # for cp2k and pwmat gaussion
83
+
67
84
 
68
85
  def _set_pseudo(self, pseudo, style:str):
69
86
  res_pseudo = []
@@ -158,7 +175,7 @@ class DFTInput(object):
158
175
  self.flag_symm = flag_symm
159
176
  self.use_dftb = False
160
177
  self.use_skf = False
161
-
178
+ self.use_gaussion = False
162
179
  # check etot input file
163
180
  if self.dft_style == DFT_STYLE.pwmat:
164
181
  key_values, etot_lines = read_and_check_etot_input(self.input_file)
@@ -177,6 +194,9 @@ class DFTInput(object):
177
194
  if key_values["DFTB_DETAIL"].replace(",", " ").split()[0] != "3": # not chardb
178
195
  self.use_skf = True
179
196
 
197
+ if "USE_GAUSSIAN" in key_values.keys() and key_values["USE_GAUSSIAN"]is not None and key_values["USE_GAUSSIAN"] == "T":
198
+ self.use_gaussion
199
+
180
200
  def get_input_content(self):
181
201
  if self.dft_style == DFT_STYLE.pwmat:
182
202
  return read_and_check_etot_input(self.input_file)
@@ -2,7 +2,7 @@ import os
2
2
  from pwact.utils.constant import ELEMENTTABLE, DFT_STYLE, ELEMENTTABLE_2, CP2K, PWDATA
3
3
  from pwact.utils.app_lib.cp2k import make_cp2k_xyz
4
4
  from pwact.utils.file_operation import write_to_file
5
- from pwdata.main import Config
5
+ from pwdata.config import Config
6
6
  from pwdata import perturb_structure, make_supercell, scale_cell
7
7
  '''
8
8
  description:
@@ -14,7 +14,7 @@ author: wuxingxing
14
14
  '''
15
15
  def get_atom_type(config_path, format:str=None):
16
16
  if isinstance(config_path, str):
17
- image = Config.read(format=format, data_path=config_path, atom_names=None)
17
+ image = Config(format=format, data_path=config_path, atom_names=None).images[0]
18
18
  else:
19
19
  image = config_path
20
20
  atomic_number_list = []
@@ -25,7 +25,7 @@ def get_atom_type(config_path, format:str=None):
25
25
  return atomic_name_list, atomic_number_list
26
26
 
27
27
  def load_config(config, format, atom_names=None):
28
- config = Config.read(format=format, data_path=config, atom_names=atom_names)
28
+ config = Config(format=format, data_path=config, atom_names=atom_names)
29
29
  return config
30
30
 
31
31
  '''
@@ -38,9 +38,7 @@ author: wuxingxing
38
38
  def save_config(config, input_format:str = None, wrap = False, direct = True, sort = True, \
39
39
  save_format:str=None, save_path:str=None, save_name:str=None, atom_names: list[str] = None):
40
40
  if isinstance(config, str):
41
- config = Config.read(format=input_format, data_path=config, atom_names=atom_names)
42
- if isinstance(config, list): # for lammps dump traj, config will be list
43
- config = config[0]
41
+ config = Config(format=input_format, data_path=config, atom_names=atom_names).images[0]
44
42
  if save_format == PWDATA.cp2k_scf:
45
43
  # make coord.xyz used by cp2k for every task
46
44
  config = config._set_cartesian() if config.cartesian is False else config._set_cartesian()
@@ -86,9 +84,9 @@ def read_cp2k_xyz(config_file:str):
86
84
  coord.appnd([float(elements[1]), float(elements[2]), float(elements[3])])
87
85
  return atom_type_name, atom_names, coord
88
86
 
89
- def do_super_cell(config, input_format:str=None, supercell_matrix:list[int]=None, pbc:list[int]=[1, 1, 1], direct = True, sort = True, \
87
+ def do_super_cell(config_file, input_format:str=None, supercell_matrix:list[int]=None, pbc:list[int]=[1, 1, 1], direct = True, sort = True, \
90
88
  save_format:str=None, save_path:str=None, save_name:str=None):
91
- config = Config.read(format=input_format, data_path=config, atom_names=None)
89
+ config = Config(format=input_format, data_path=config_file, atom_names=None)
92
90
  # Make a supercell
93
91
  supercell = make_supercell(config, supercell_matrix, pbc)
94
92
  # Write out the structure
@@ -101,7 +99,7 @@ def do_super_cell(config, input_format:str=None, supercell_matrix:list[int]=None
101
99
 
102
100
  def do_scale(config, input_format:str=None, scale_factor:float=None,
103
101
  direct:bool=True, sort:bool=True, save_format:str=None, save_path:str=None, save_name:str=None):
104
- config = Config.read(format=input_format, data_path=config)
102
+ config = Config(format=input_format, data_path=config)
105
103
  scaled_struct = scale_cell(config, scale_factor)
106
104
  scaled_struct.to(output_path = save_path,
107
105
  data_name = save_name,
@@ -113,7 +111,7 @@ def do_scale(config, input_format:str=None, scale_factor:float=None,
113
111
 
114
112
  def do_pertub(config, input_format:str=None, pert_num:int=None, cell_pert_fraction:float=None, atom_pert_distance:float=None, \
115
113
  direct:bool=True, sort:bool=True, save_format:str=None, save_path:str=None, save_name:str=None):
116
- config = Config.read(format=input_format, data_path=config)
114
+ config = Config(format=input_format, data_path=config)
117
115
 
118
116
  if not os.path.exists(save_path):
119
117
  os.makedirs(save_path)
@@ -166,10 +164,12 @@ def extract_pwdata(data_list:list[str],
166
164
  tmp_config = Config(data_format, data_path)
167
165
  # if not isinstance(tmp_config, list):
168
166
  # tmp_config = [tmp_config]
169
- image_data.append(tmp_config)
167
+ image_data.images.extend(tmp_config.images)
170
168
  else:
171
169
  image_data = Config(data_format, data_path)
172
-
170
+
171
+ if not isinstance(image_data.images, list):
172
+ image_data.images = [image_data.images]
173
173
 
174
174
  # if not isinstance(image_data, list):
175
175
  # image_data = [image_data]
@@ -23,7 +23,7 @@ from pwact.active_learning.init_bulk.init_bulk_run import init_bulk_run, scancel
23
23
  from pwact.active_learning.environment import check_envs
24
24
 
25
25
  from pwact.data_format.configop import extract_pwdata
26
- from pwact.active_learning.explore.select_image import select_image
26
+ from pwact.active_learning.explore.select_image import select_image, print_select_image
27
27
  from pwact.utils.process_tool import kill_process
28
28
  def run_iter():
29
29
  system_json = json.load(open(sys.argv[2]))
@@ -299,6 +299,26 @@ def kill_job():
299
299
 
300
300
  # for run iters jobs
301
301
 
302
+ def filter_test(input_cmds):
303
+ parser = argparse.ArgumentParser()
304
+ parser.add_argument('-i', '--md_dir', help="specify input dir such as 'iter.0000/temp_run_iter_work/explore/md'", type=str, required=True)
305
+ parser.add_argument('-l', '--lower', help="specify lower limit value", type=float, required=True)
306
+ parser.add_argument('-u', '--upper', help="specify upper limit value", type=float, required=True)
307
+ parser.add_argument('-s', '--save', action='store_true', help="if '-s' is set, save the detailed information of the selected configs to CSV files")
308
+
309
+ args = parser.parse_args(input_cmds)
310
+ if not os.path.exists(args.md_dir):
311
+ raise Exception("ERROR! The input md_dir {} not found!".format(args.md_dir))
312
+
313
+ save_dir = os.path.join(os.getcwd(), "filter_test_result") if args.save else None
314
+ summary = print_select_image(
315
+ md_dir=args.md_dir,
316
+ save_dir=save_dir,
317
+ devi_name=EXPLORE_FILE_STRUCTURE.get_devi_name(UNCERTAINTY.committee),
318
+ lower=args.lower,
319
+ higer=args.upper
320
+ )
321
+
302
322
  def main():
303
323
  environment_check()
304
324
  if len(sys.argv) == 1 or "-h".upper() == sys.argv[1].upper() or \
@@ -343,7 +363,14 @@ def main():
343
363
  cmd_infos("kill")
344
364
  else:
345
365
  kill_job()
346
-
366
+
367
+ elif "filter_test".upper() == sys.argv[1].upper() or "filter".upper() == sys.argv[1].upper():
368
+ if len(sys.argv) == 2 or "-h".upper() == sys.argv[2].upper() or \
369
+ "help".upper() == sys.argv[2].upper() or "-help".upper() == sys.argv[2].upper() or "--help".upper() == sys.argv[2].upper():
370
+ cmd_infos("filter")
371
+ else:
372
+ filter_test(sys.argv[2:])
373
+
347
374
  else:
348
375
  print("ERROR! The input cmd {} can not be recognized, please check.".format(sys.argv[1]))
349
376
  print("\n\n\nYou can enter the following command.\n\n\n")
@@ -46,8 +46,11 @@ def link_pseudo_by_atom(
46
46
  link_file(pseudo_path, os.path.join(target_dir, pseudo_name))
47
47
  pseudo_find.append(pseudo_path)
48
48
  break
49
- assert len(pseudo_find) == len(atom_order), "the pwmat pseudo files {} not same as atom type '{}'".format(pseudo_find, atom_order)
50
-
49
+ # assert len(pseudo_find) == len(atom_order), "the pwmat pseudo files {} not same as atom type '{}'".format(pseudo_find, atom_order)
50
+ if basis_set_file is not None and potential_file is not None: # these 2 files for pwmat gaussian base
51
+ link_file(basis_set_file, os.path.join(target_dir, os.path.basename(basis_set_file)))
52
+ link_file(potential_file, os.path.join(target_dir, os.path.basename(potential_file)))
53
+
51
54
  elif dft_style == DFT_STYLE.vasp:
52
55
  # merge file to where? to save dir
53
56
  for atom_name in atom_order:
@@ -98,8 +101,11 @@ def set_input_script(
98
101
  save_dir:str=None,
99
102
  pseudo_names:list[str]=None,
100
103
  is_scf = False, # if is_scf, the pwmat etot.input will set the 'out.mlmd = T'
101
- basis_set_file_name=None,
102
- potential_file_name=None,
104
+ gaussian_base_param = None
105
+ # basis_set_file_name=None,
106
+ # potential_file_name=None,
107
+ # basis_set_list=None,
108
+ # potential_list=None
103
109
  # xc_functional=None,
104
110
  # potential=None,
105
111
  # basis_set=None
@@ -114,7 +120,8 @@ def set_input_script(
114
120
  flag_symm=flag_symm,
115
121
  pseudo_names=pseudo_names,
116
122
  is_scf = is_scf,
117
- is_skf_file = is_skf_file
123
+ is_skf_file = is_skf_file,
124
+ gaussian_base_param=gaussian_base_param
118
125
  )
119
126
  write_to_file(target_file, script, "w")
120
127
  elif dft_style == DFT_STYLE.vasp:
@@ -127,10 +134,13 @@ def set_input_script(
127
134
  cell = file_read_last_line(os.path.join(save_dir, CP2K.cell_txt), type_name="float")
128
135
  del_file(os.path.join(save_dir, CP2K.cell_txt))
129
136
  # inp file, cell cood add to inp file
137
+ # set kind_dict
138
+
130
139
  script = make_cp2k_input_from_external(
131
140
  cell=cell,
132
- coord_file_name = os.path.join(os.path.basename(config)),
133
- exinput_path=input_file
141
+ coord_file = config,
142
+ exinput_path=input_file,
143
+ gaussian_base_param = gaussian_base_param
134
144
  )
135
145
  write_to_file(target_file, script, "w")
136
146
 
@@ -6,7 +6,7 @@ description:
6
6
  return {*}
7
7
  author: wuxingxing
8
8
  '''
9
-
9
+ import os
10
10
  import numpy as np
11
11
  default_config = {
12
12
  "GLOBAL": {"PROJECT": "AL_PWMLFF"},
@@ -186,8 +186,8 @@ param {*} exinput_path
186
186
  return {*}
187
187
  author: wuxingxing
188
188
  '''
189
- def make_cp2k_input_from_external(cell, coord_file_name, exinput_path):
190
-
189
+ def make_cp2k_input_from_external(cell, coord_file, exinput_path, gaussian_base_param:dict):
190
+ coord_file_name = os.path.basename(coord_file)
191
191
  # insert the cell information
192
192
  # covert cell to cell string
193
193
  cell = np.reshape(cell, [3, 3])
@@ -201,10 +201,37 @@ def make_cp2k_input_from_external(cell, coord_file_name, exinput_path):
201
201
  end_subsys = 0
202
202
  start_coord = 0
203
203
  end_coord = 0
204
+ start_kind = -1
205
+ end_kind = -1
204
206
  start_global = 0
205
207
  end_global = 0
206
208
  print_level_line = -1
209
+ start_dft = 0
210
+ end_dft = 0
211
+ basis_set_file_name = -1
212
+ potential_file_name = -1
207
213
 
214
+ # delete the BASIS_SET_FILE_NAME and POTENTIAL_FILE_NAME line
215
+ for line_idx, line in enumerate(exinput):
216
+ line = line.upper()
217
+ if "&DFT" in line:
218
+ start_dft = line_idx
219
+ if "&END DFT" in line:
220
+ end_dft = line_idx
221
+ if "BASIS_SET_FILE_NAME" in line:
222
+ basis_set_file_name = line_idx
223
+ if "POTENTIAL_FILE_NAME" in line:
224
+ potential_file_name = line_idx
225
+ if start_dft == end_dft:
226
+ raise Exception("{} extarcted error! Can not find DFT set!".format(exinput_path))
227
+ basis_set_file_name, potential_file_name = sorted([basis_set_file_name, potential_file_name], reverse=True)
228
+ if basis_set_file_name != -1:
229
+ exinput.pop(basis_set_file_name)
230
+ if potential_file_name != -1:
231
+ exinput.pop(potential_file_name)
232
+ exinput.insert(start_dft+1, " BASIS_SET_FILE_NAME {}\n".format(gaussian_base_param["BASIS_SET_FILE_NAME"]))
233
+ exinput.insert(start_dft+2, " POTENTIAL_FILE_NAME {}\n".format(gaussian_base_param["POTENTIAL_FILE_NAME"]))
234
+
208
235
  for line_idx, line in enumerate(exinput):
209
236
  line = line.upper()
210
237
  if "&GLOBAL" in line:
@@ -225,8 +252,14 @@ def make_cp2k_input_from_external(cell, coord_file_name, exinput_path):
225
252
  start_coord = line_idx
226
253
  if "&END COORD" in line:
227
254
  end_coord = line_idx
255
+ if "&KIND" in line and start_kind == -1:
256
+ start_kind = line_idx
257
+ if "&END KIND" in line:
258
+ end_kind = line_idx
259
+
228
260
  if start_global == end_global:
229
261
  raise Exception("ERROR! the input cp2k inp file does not have 'GLOBAL' block! Please check the file {}\n".format(exinput_path))
262
+
230
263
  temp_exinput = exinput[:start_subsys+1]
231
264
  # add coord
232
265
  temp_exinput.append(" &COORD\n")
@@ -241,11 +274,16 @@ def make_cp2k_input_from_external(cell, coord_file_name, exinput_path):
241
274
  # temp_exinput.append(" PERIODIC XYZ\n")
242
275
  temp_exinput.append(" &END CELL\n")
243
276
 
277
+ kind_input = get_kind(coord_file=coord_file, gassion_base_param=gaussian_base_param)
278
+ temp_exinput.append(kind_input)
279
+
244
280
  del_content_index = []
245
281
  if start_cell != end_cell:
246
282
  del_content_index.extend(list(range(start_cell, end_cell+1)))
247
283
  if start_coord != end_coord:
248
284
  del_content_index.extend(list(range(start_coord, end_coord+1)))
285
+ if start_kind != end_kind:
286
+ del_content_index.extend(list(range(start_kind, end_kind+1)))
249
287
  del_content_index = sorted(del_content_index)
250
288
  for index in range(start_subsys+1, end_subsys):
251
289
  if index not in del_content_index:
@@ -259,34 +297,63 @@ def make_cp2k_input_from_external(cell, coord_file_name, exinput_path):
259
297
  temp_exinput[print_level_line] = " PRINT_LEVEL medium\n"
260
298
  return "".join(temp_exinput)
261
299
 
300
+ def get_kind(coord_file:str, gassion_base_param:dict):
301
+ atom_list = get_atom_type_from_config(coord_file)
302
+ kind_line = "\n"
303
+ for idx, atom in enumerate(gassion_base_param["ELEMENT"]):
304
+ if atom not in atom_list:
305
+ continue
306
+ kind_line += " &KIND {}\n".format(atom)
307
+ kind_line += " ELEMENT {}\n".format(atom)
308
+ kind_line += " BASIS_SET {}\n".format(gassion_base_param["BASIS_SET"][idx])
309
+ kind_line += " POTENTIAL {}\n".format(gassion_base_param["POTENTIAL"][idx])
310
+ kind_line += " &END KIND\n"
311
+ return kind_line
312
+
313
+ def get_atom_type_from_config(coord_file:str):
314
+ res = []
315
+ with open(coord_file, 'r') as rf:
316
+ lines = rf.readlines()
317
+ for line in lines:
318
+ try:
319
+ atom_type, x, y, z = line.strip().split()
320
+ x = float(x)
321
+ y = float(y)
322
+ z = float(z)
323
+ if atom_type not in res:
324
+ res.append(atom_type)
325
+ except:
326
+ continue
327
+ return res
328
+
262
329
  # if __name__=="__main__":
263
- # import dpdata
264
- # poscar = "/data/home/wuxingxing/datas/al_dir/si_4_vasp/init_bulk/collection/init_config_0/0.9_scale.poscar"
265
- # sys_data = dpdata.System(poscar).data
330
+ # import dpdata
331
+ # poscar = "/data/home/wuxingxing/datas/al_dir/si_4_vasp/init_bulk/collection/init_config_0/0.9_scale.poscar"
332
+ # sys_data = dpdata.System(poscar).data
266
333
 
267
- # from pwdata.main import Configs
268
- # from pwdata.calculators.const import ELEMENTTABLE_2
269
- # image = Configs.read(format="pwmat", data_path="/data/home/wuxingxing/datas/al_dir/si_exp/init_bulk/atom.config")
270
- # image = image._set_cartesian() if image.cartesian is False else image._set_cartesian()
271
- # potential = {"Si":"GTH-PBE"}
272
- # basis_set = {"Si":"DZVP-MOLOPT-SR-GTH-q4"}
273
- # atom_types_image = []
274
- # for atom in image.atom_types_image:
275
- # atom_types_image.append(ELEMENTTABLE_2[atom])
276
- # coord_xyz = make_cp2k_xyz(
277
- # atom_types = atom_types_image,
278
- # coord_list = image.position
279
- # )
280
- # with open("/data/home/wuxingxing/datas/al_dir/si_exp/init_bulk/coord.xyz", "w") as fp:
281
- # fp.write(coord_xyz)
334
+ # from pwdata.config import Configs
335
+ # from pwdata.calculators.const import ELEMENTTABLE_2
336
+ # image = Configs.read(format="pwmat", data_path="/data/home/wuxingxing/datas/al_dir/si_exp/init_bulk/atom.config")
337
+ # image = image._set_cartesian() if image.cartesian is False else image._set_cartesian()
338
+ # potential = {"Si":"GTH-PBE"}
339
+ # basis_set = {"Si":"DZVP-MOLOPT-SR-GTH-q4"}
340
+ # atom_types_image = []
341
+ # for atom in image.atom_types_image:
342
+ # atom_types_image.append(ELEMENTTABLE_2[atom])
343
+ # coord_xyz = make_cp2k_xyz(
344
+ # atom_types = atom_types_image,
345
+ # coord_list = image.position
346
+ # )
347
+ # with open("/data/home/wuxingxing/datas/al_dir/si_exp/init_bulk/coord.xyz", "w") as fp:
348
+ # fp.write(coord_xyz)
282
349
 
283
- # make_cp2k_input(
284
- # cell = image.lattice,
285
- # atom_names=["Si"],
286
- # basis_set_file_name="BASIS_SET_FILE",
287
- # potential_file_name="POTENTIAL_FILE",
288
- # xc_functional="PBE",
289
- # potential=potential,
290
- # basis_set=basis_set,
291
- # coord_content=coord_xyz
292
- # )
350
+ # make_cp2k_input(
351
+ # cell = image.lattice,
352
+ # atom_names=["Si"],
353
+ # basis_set_file_name="BASIS_SET_FILE",
354
+ # potential_file_name="POTENTIAL_FILE",
355
+ # xc_functional="PBE",
356
+ # potential=potential,
357
+ # basis_set=basis_set,
358
+ # coord_content=coord_xyz
359
+ # )
@@ -0,0 +1,194 @@
1
+ import numpy as np
2
+
3
+ default_config = {
4
+ "GLOBAL": {"PROJECT": "DPGEN"},
5
+ "FORCE_EVAL": {
6
+ "METHOD": "QS",
7
+ "STRESS_TENSOR": "ANALYTICAL",
8
+ "DFT": {
9
+ "BASIS_SET_FILE_NAME": "./cp2k_basis_pp_file/BASIS_MOLOPT",
10
+ "POTENTIAL_FILE_NAME": "./cp2k_basis_pp_file/GTH_POTENTIALS",
11
+ "CHARGE": 0,
12
+ "UKS": "F",
13
+ "MULTIPLICITY": 1,
14
+ "MGRID": {"CUTOFF": 400, "REL_CUTOFF": 50, "NGRIDS": 4},
15
+ "QS": {"EPS_DEFAULT": "1.0E-12"},
16
+ "SCF": {"SCF_GUESS": "ATOMIC", "EPS_SCF": "1.0E-6", "MAX_SCF": 50},
17
+ "XC": {"XC_FUNCTIONAL": {"_": "PBE"}},
18
+ },
19
+ "SUBSYS": {
20
+ "CELL": {"A": "10 .0 .0", "B": ".0 10 .0", "C": ".0 .0 10"},
21
+ "COORD": {"@include": "coord.xyz"},
22
+ "KIND": {
23
+ "_": ["H", "C", "N"],
24
+ "POTENTIAL": ["GTH-PBE-q1", "GTH-PBE-q4", "GTH-PBE-q5"],
25
+ "BASIS_SET": ["DZVP-MOLOPT-GTH", "DZVP-MOLOPT-GTH", "DZVP-MOLOPT-GTH"],
26
+ },
27
+ },
28
+ "PRINT": {"FORCES": {"_": "ON"}, "STRESS_TENSOR": {"_": "ON"}},
29
+ },
30
+ }
31
+
32
+
33
+ def update_dict(old_d, update_d):
34
+ """A method to recursive update dict
35
+ :old_d: old dictionary
36
+ :update_d: some update value written in dictionary form.
37
+ """
38
+ import collections.abc
39
+
40
+ for k, v in update_d.items():
41
+ if (
42
+ k in old_d
43
+ and isinstance(old_d[k], dict)
44
+ and isinstance(update_d[k], collections.abc.Mapping)
45
+ ):
46
+ update_dict(old_d[k], update_d[k])
47
+ else:
48
+ old_d[k] = update_d[k]
49
+
50
+
51
+ def iterdict(d, out_list, flag=None, indent=0):
52
+ """
53
+ :doc: a recursive expansion of dictionary into cp2k input
54
+ :k: current key
55
+ :v: current value
56
+ :d: current dictionary under expansion
57
+ :flag: used to record dictionary state. if flag is None,
58
+ it means we are in top level dict. flag is a string.
59
+ :indent: intent for current section.
60
+ """
61
+ for k, v in d.items():
62
+ k = str(k) # cast key into string
63
+ # if value is dictionary
64
+ if isinstance(v, dict):
65
+ # flag == None, it is now in top level section of cp2k
66
+ if flag is None:
67
+ out_list.append("&" + k)
68
+ out_list.append("&END " + k)
69
+ iterdict(v, out_list, k, indent + 2)
70
+ # flag is not None, now it has name of section
71
+ else:
72
+ index = out_list.index(" " * (indent - 2) + "&END " + flag)
73
+ out_list.insert(index, " " * indent + "&" + k + " #" + flag)
74
+ out_list.insert(index + 1, " " * indent + "&END " + k + " #" + flag)
75
+ # the flag now contains its parent section name, separed by "#".
76
+ iterdict(v, out_list, k + " #" + flag, indent + 2)
77
+ elif isinstance(v, list):
78
+ # print("we have encountered the repeat section!")
79
+ index = out_list.index(" " * (indent - 2) + "&" + flag)
80
+ # delete the current constructed repeat section
81
+ del out_list[index : index + 2]
82
+ # do a loop over key and corresponding list
83
+ k_tmp_list = []
84
+ v_list_tmp_list = []
85
+ for k_tmp, v_tmp in d.items():
86
+ k_tmp_list.append(str(k_tmp))
87
+ v_list_tmp_list.append(v_tmp)
88
+ for repeat_keyword in zip(*v_list_tmp_list):
89
+ out_list.insert(index, " " * (indent - 2) + "&" + flag)
90
+ out_list.insert(index + 1, " " * (indent - 2) + "&END " + flag)
91
+ for idx, k_tmp in enumerate(k_tmp_list):
92
+ if k_tmp == "_":
93
+ out_list[index] = (
94
+ " " * (indent - 2)
95
+ + "&"
96
+ + flag.split(" #")[0]
97
+ + " "
98
+ + repeat_keyword[idx]
99
+ )
100
+ else:
101
+ out_list.insert(
102
+ index + 1,
103
+ " " * (indent) + k_tmp + " " + repeat_keyword[idx],
104
+ )
105
+ break
106
+
107
+ else:
108
+ v = str(v)
109
+ if flag is None:
110
+ out_list.append(k + " " + v)
111
+ print(k, ":", v)
112
+ else:
113
+ if k == "_":
114
+ index = out_list.index(" " * (indent - 2) + "&" + flag)
115
+ out_list[index] = (
116
+ " " * (indent - 2) + "&" + flag.split(" #")[0] + " " + v
117
+ )
118
+
119
+ else:
120
+ index = out_list.index(" " * (indent - 2) + "&END " + flag)
121
+ out_list.insert(index, " " * indent + k + " " + v)
122
+
123
+
124
+ def make_cp2k_input(sys_data, fp_params):
125
+ # covert cell to cell string
126
+ cell = sys_data["cells"][0]
127
+ cell = np.reshape(cell, [3, 3])
128
+ cell_a = np.array2string(cell[0, :])
129
+ cell_a = cell_a[1:-1]
130
+ cell_b = np.array2string(cell[1, :])
131
+ cell_b = cell_b[1:-1]
132
+ cell_c = np.array2string(cell[2, :])
133
+ cell_c = cell_c[1:-1]
134
+
135
+ # get update from user
136
+ user_config = fp_params
137
+ # get update from cell
138
+ cell_config = {
139
+ "FORCE_EVAL": {"SUBSYS": {"CELL": {"A": cell_a, "B": cell_b, "C": cell_c}}}
140
+ }
141
+ update_dict(default_config, user_config)
142
+ update_dict(default_config, cell_config)
143
+ # output list
144
+ input_str = []
145
+ iterdict(default_config, input_str)
146
+ string = "\n".join(input_str)
147
+ return string
148
+
149
+
150
+ def make_cp2k_xyz(sys_data):
151
+ # get structral information
152
+ atom_names = sys_data["atom_names"]
153
+ atom_types = sys_data["atom_types"]
154
+
155
+ # write coordinate to xyz file used by cp2k input
156
+ coord_list = sys_data["coords"][0]
157
+ u = np.array(atom_names)
158
+ atom_list = u[atom_types]
159
+ x = "\n"
160
+ for kind, coord in zip(atom_list, coord_list):
161
+ x += str(kind) + " " + str(coord[:])[1:-1] + "\n"
162
+ return x
163
+
164
+
165
+ def make_cp2k_input_from_external(sys_data, exinput_path):
166
+ # read the input content as string
167
+ with open(exinput_path) as f:
168
+ exinput = f.readlines()
169
+
170
+ # find the ABC cell string
171
+ for line_idx, line in enumerate(exinput):
172
+ if "ABC" in line:
173
+ delete_cell_idx = line_idx
174
+ delete_cell_line = line
175
+
176
+ # remove the useless CELL line
177
+ exinput.remove(delete_cell_line)
178
+
179
+ # insert the cell information
180
+ # covert cell to cell string
181
+ cell = sys_data["cells"][0]
182
+ cell = np.reshape(cell, [3, 3])
183
+ cell_a = np.array2string(cell[0, :])
184
+ cell_a = cell_a[1:-1]
185
+ cell_b = np.array2string(cell[1, :])
186
+ cell_b = cell_b[1:-1]
187
+ cell_c = np.array2string(cell[2, :])
188
+ cell_c = cell_c[1:-1]
189
+
190
+ exinput.insert(delete_cell_idx, "A " + cell_a + "\n")
191
+ exinput.insert(delete_cell_idx + 1, "B " + cell_b + "\n")
192
+ exinput.insert(delete_cell_idx + 2, "C " + cell_c + "\n")
193
+
194
+ return "".join(exinput)
@@ -1,8 +1,9 @@
1
1
  import os
2
2
  import numpy as np
3
3
  import subprocess
4
- from pwact.utils.constant import PWMAT, VASP
4
+ from pwact.utils.constant import PWMAT, VASP, PWDATA, get_atomic_name_from_number
5
5
  from pwact.utils.file_operation import del_file, copy_file
6
+ from pwdata import Config
6
7
  # '''
7
8
  # description:
8
9
  # lammps dump file to poscar format or pwmat format
@@ -100,16 +101,17 @@ def _reciprocal_box(box):
100
101
  # return ret
101
102
 
102
103
  def _make_kspacing_kpoints(config, kspacing):
103
- with open(config, "r") as fp:
104
- lines = fp.read().split("\n")
105
- box = []
106
- for idx, ii in enumerate(lines):
107
- if "LATTICE" in ii.upper():
108
- for kk in range(idx + 1, idx + 1 + 3):
109
- vector = [float(jj) for jj in lines[kk].split()[0:3]]
110
- box.append(vector)
111
- box = np.array(box)
112
- rbox = _reciprocal_box(box)
104
+ config = Config(data_path=config, format="pwmat/config")
105
+ lattice = config.images[0].lattice
106
+ # box = []
107
+ # for idx, ii in enumerate(lines):
108
+ # if "LATTICE" in ii.upper():
109
+ # for kk in range(idx + 1, idx + 1 + 3):
110
+ # vector = [float(jj) for jj in lines[kk].split()[0:3]]
111
+ # box.append(vector)
112
+ # box = np.array(box)
113
+ # rbox = _reciprocal_box(box)
114
+ rbox = _reciprocal_box(lattice)
113
115
  kpoints = [
114
116
  round(2 * np.pi * np.linalg.norm(ii) / kspacing) for ii in rbox
115
117
  ]
@@ -321,13 +323,19 @@ def set_etot_input_by_file(
321
323
  atom_config:str=None,
322
324
  pseudo_names:list[str]=None,
323
325
  is_scf = False, # if True, job is scf, and 'OUT.MLMD = T' to etot.input
324
- is_skf_file = False # if True, set in.skf to etot.input file
326
+ is_skf_file = False, # if True, set in.skf to etot.input file
327
+ gaussian_base_param:dict=None
325
328
  ):
326
329
  key_values, etot_lines = read_and_check_etot_input(etot_input_file)
330
+ is_gaussian = False
331
+ if "USE_GAUSSIAN" in key_values.keys() and key_values["USE_GAUSSIAN"] is not None and key_values["USE_GAUSSIAN"] == "T":
332
+ is_gaussian = True
333
+
327
334
  is_skf = False
328
335
  if "USE_DFTB" in key_values.keys() and key_values["USE_DFTB"] is not None and key_values["USE_DFTB"] == "T":
329
336
  if key_values["DFTB_DETAIL"].replace(",", " ").split()[0] != "3": # not chardb
330
337
  is_skf = True
338
+
331
339
  index = 0
332
340
  new_etot_lines = []
333
341
  while index < len(etot_lines):
@@ -340,18 +348,26 @@ def set_etot_input_by_file(
340
348
  pass
341
349
  elif "IN.PSP" in etot_lines[index].upper(): # to avoid the new_etot_lines add 'IN.PSP' and 'in.skf' 'in.atom' in etot_lines
342
350
  pass
351
+ elif "IN.BASIS" in etot_lines[index].upper(): # to avoid the new_etot_lines add 'IN.BASIS' in etot_lines
352
+ pass
343
353
  # etot_lines.remove(etot_lines[index])
344
354
  else:
345
355
  new_etot_lines.append(etot_lines[index])
346
356
  index += 1
347
357
  new_etot_lines.append("\nIN.ATOM = {}\n".format(os.path.basename(atom_config)))
358
+ atom_type_numbers = Config(format=PWDATA.pwmat_config, data_path=atom_config).images[0].atom_type
359
+ atom_type_names = get_atomic_name_from_number(atom_type_numbers)
348
360
  # if dftb and need in_skf
349
361
  if is_skf and is_skf_file:
350
362
  new_etot_lines.append("IN.SKF = ./{}/\n".format(PWMAT.in_skf))
351
363
  # is not for dftb, reset the IN.PSP
352
364
  if "USE_DFTB" not in key_values.keys() or key_values["USE_DFTB"] is None and key_values["USE_DFTB"] == "F":
353
- for pseudo_i, pseudo in enumerate(pseudo_names):
354
- new_etot_lines.append("IN.PSP{} = {}\n".format(pseudo_i + 1, pseudo))
365
+ if is_gaussian is False:
366
+ for pseudo_i, pseudo in enumerate(pseudo_names):
367
+ new_etot_lines.append("IN.PSP{} = {}\n".format(pseudo_i + 1, pseudo))
368
+ else: # pwmat gaussian
369
+ psp_line = set_gassion_psp(atom_type_names, gaussian_base_param)
370
+ new_etot_lines.append(psp_line)
355
371
  key_list = list(key_values)
356
372
  # set OUT.MLMD
357
373
  if "OUT.MLMD" not in key_list:
@@ -359,11 +375,11 @@ def set_etot_input_by_file(
359
375
  new_etot_lines.append("OUT.MLMD = T\n")
360
376
  # # set OUT.WG OUT.RHO OUT.VR
361
377
  if "OUT.WG" not in key_list:
362
- etot_lines.append("OUT.WG = F\n")
378
+ new_etot_lines.append("OUT.WG = F\n")
363
379
  if "OUT.RHO" not in key_list:
364
- etot_lines.append("OUT.RHO = F\n")
380
+ new_etot_lines.append("OUT.RHO = F\n")
365
381
  if "OUT.VR" not in key_list:
366
- etot_lines.append("OUT.VR = F\n")
382
+ new_etot_lines.append("OUT.VR = F\n")
367
383
  # if MP_N123 is not in etot.input file then using 'kespacing' generates it
368
384
  if "MP_N123" not in key_list:
369
385
  kspacing = PWMAT.kspacing_default if kspacing is None else kspacing
@@ -378,6 +394,20 @@ def set_etot_input_by_file(
378
394
 
379
395
  return "".join(new_etot_lines)
380
396
 
397
+ def set_gassion_psp(atom_list, gaussian_base_param:dict):
398
+ psp_num = 1
399
+ psp_line = "\n"
400
+ base_line = "\n"
401
+ for idx, atom in enumerate(gaussian_base_param["ELEMENT"]):
402
+ if atom not in atom_list:
403
+ continue
404
+ psp_line += "IN.PSP{} = {} {} {}\n".format(psp_num, atom, gaussian_base_param["POTENTIAL"][idx], gaussian_base_param["POTENTIAL_FILE_NAME"])
405
+ base_line += "IN.BASIS{} = {} {} {}\n".format(psp_num, atom, gaussian_base_param["BASIS_SET"][idx],gaussian_base_param["BASIS_SET_FILE_NAME"])
406
+ psp_num += 1
407
+ psp_line += base_line
408
+ return psp_line
409
+
410
+
381
411
  def is_alive_atomic_energy(movement_list:list):
382
412
  if len(movement_list) < 1:
383
413
  return False
@@ -443,7 +473,8 @@ bool_keys=[
443
473
  'OUT.MLMD',
444
474
  'NUM_BLOCKED_PSI',
445
475
  'OUT.RHOATOM',
446
- "USE_DFTB"
476
+ "USE_DFTB",
477
+ "USE_GAUSSIAN"
447
478
  ]
448
479
 
449
480
  char_keys=['PRECISION',
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pwact
3
- Version: 0.1.19
3
+ Version: 0.1.21
4
4
  Summary: PWACT is an open-source automated active learning platform based on PWMLFF for efficient data sampling.
5
5
  Home-page: https://github.com/LonxunQuantum/PWact
6
6
  Author: LonxunQuantum
@@ -57,5 +57,6 @@ pwact/utils/slurm_script.py
57
57
  pwact/utils/app_lib/__init__.py
58
58
  pwact/utils/app_lib/common.py
59
59
  pwact/utils/app_lib/cp2k.py
60
+ pwact/utils/app_lib/cp2k_dp.py
60
61
  pwact/utils/app_lib/lammps.py
61
62
  pwact/utils/app_lib/pwmat.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.1.19",
8
+ version="0.1.21",
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 PWMLFF for efficient data sampling.",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes