Skip to content

Commit 0b4bdba

Browse files
Merge pull request #119 from deepmodeling/devel-1.3.0
Devel 1.3.0
2 parents 7343059 + 560cf51 commit 0b4bdba

20 files changed

Lines changed: 1856 additions & 230 deletions

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,4 @@ potential
3737
all_result.json
3838

3939
# dflow debug folders generated by examples or local runs
40-
**/dflow_debug/
40+
**/dflow_debug/

apex/config.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ class Config:
6767
vasp_run_command: str = None
6868
abacus_image_name: str = None
6969
abacus_run_command: str = None
70+
lammps_header_retry_attempts: int = 2
71+
lammps_header_retry_delay: float = 5
72+
lammps_transient_retry_attempts: int = 1
73+
lammps_retry_group_size: int = None
7074

7175
# common APEX config
7276
is_bohrium_dflow: bool = False
@@ -256,7 +260,11 @@ def basic_config_dict(self):
256260
"vasp_image_name": self.vasp_image_name,
257261
"vasp_run_command": self.vasp_run_command,
258262
"abacus_image_name": self.abacus_image_name,
259-
"abacus_run_command": self.abacus_run_command
263+
"abacus_run_command": self.abacus_run_command,
264+
"lammps_header_retry_attempts": self.lammps_header_retry_attempts,
265+
"lammps_header_retry_delay": self.lammps_header_retry_delay,
266+
"lammps_transient_retry_attempts": self.lammps_transient_retry_attempts,
267+
"lammps_retry_group_size": self.lammps_retry_group_size
260268
}
261269
return basic_config
262270

apex/core/property/Gamma.py

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def __init__(self, parameter, inter_param=None):
3636
self.reprod = parameter["reproduce"]
3737
if not self.reprod:
3838
if not ("init_from_suffix" in parameter and "output_suffix" in parameter):
39+
parameter["cal_type"] = parameter.get("cal_type", "relaxation")
3940
parameter["plane_miller"] = parameter.get("plane_miller", None)
4041
self.plane_miller = parameter["plane_miller"]
4142
parameter["slip_direction"] = parameter.get("slip_direction", None)
@@ -48,14 +49,18 @@ def __init__(self, parameter, inter_param=None):
4849
self.supercell_size = parameter["supercell_size"]
4950
parameter["vacuum_size"] = parameter.get("vacuum_size", 0)
5051
self.vacuum_size = parameter["vacuum_size"]
51-
parameter["add_fix"] = parameter.get(
52-
"add_fix", ["true", "true", "false"]
53-
) # standard method
52+
if parameter["cal_type"] == "static" and "add_fix" not in parameter:
53+
parameter["add_fix"] = None
54+
else:
55+
parameter["add_fix"] = parameter.get(
56+
"add_fix", ["true", "true", "false"]
57+
) # standard method
5458
self.add_fix = parameter["add_fix"]
5559
parameter["n_steps"] = parameter.get("n_steps", 10)
5660
self.n_steps = parameter["n_steps"]
5761
self.atom_num = None
58-
parameter["cal_type"] = parameter.get("cal_type", "relaxation")
62+
else:
63+
parameter["cal_type"] = parameter.get("cal_type", "relaxation")
5964
default_cal_setting = {
6065
"relax_pos": True,
6166
"relax_shape": False,
@@ -157,7 +162,18 @@ def make_confs(self, path_to_work, path_to_equi, refine=False):
157162

158163
equi_contcar = os.path.join(path_to_equi, CONTCAR)
159164
if not os.path.exists(equi_contcar):
160-
raise RuntimeError("please do relaxation first")
165+
raise RuntimeError(
166+
"Gamma requires a baseline relaxation before PropsMake. "
167+
"For static gamma scans, run a static baseline relaxation "
168+
"with relax_pos=false, relax_shape=false, and relax_vol=false."
169+
)
170+
equi_result = os.path.join(path_to_equi, "result.json")
171+
if not os.path.exists(equi_result):
172+
raise RuntimeError(
173+
"Gamma post-processing requires relaxation/relax_task/result.json. "
174+
"Please provide a static baseline relaxation result before "
175+
"running gamma PropsMake."
176+
)
161177
# print("we now only support gamma line calculation for BCC FCC and HCP metals")
162178
# print(
163179
# f"supported slip systems are:\n{SlabSlipSystem.hint_string()}"
@@ -451,6 +467,8 @@ def __inLammpes_fix(self, inLammps) -> None:
451467
)
452468
with open(inLammps, "r") as fin1:
453469
contents = fin1.readlines()
470+
lower_id = None
471+
upper_id = None
454472
for ii in range(len(contents)):
455473
upper = contents[ii].split()[:3] == ["variable", "N", "equal"]
456474
lower = re.search("min_style cg", contents[ii])
@@ -460,6 +478,13 @@ def __inLammpes_fix(self, inLammps) -> None:
460478
elif upper:
461479
upper_id = ii
462480
# print(upper_id)
481+
if lower_id is None or upper_id is None or lower_id >= upper_id:
482+
raise RuntimeError(
483+
"Gamma add_fix was requested, but in.lammps does not contain "
484+
"a compatible minimization block to patch. For static gamma "
485+
"calculations set add_fix to null, or use a relaxation-style "
486+
"LAMMPS input with min_style cg and variable N equal markers."
487+
)
463488
del contents[lower_id + 1:upper_id - 1]
464489
contents.insert(lower_id + 1, add_fix_str)
465490
with open(inLammps, "w") as fin2:

apex/core/property/Gruneisen.py

Lines changed: 14 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -794,8 +794,8 @@ def _ensure_mesh_yaml(self, task_dir: str) -> None:
794794
raise FileNotFoundError(f"POSCAR not found in {task_dir}")
795795
os.chdir(task_dir)
796796
cell_file = "POSCAR-unitcell" if self.inter_param["type"] == "vasp" else "POSCAR"
797-
command = (
798-
'phonopy --nomeshsym --dim="%s %s %s" -c %s band.conf'
797+
command = Phonon.phonopy_command(
798+
'--nomeshsym --dim="%s %s %s" -c %s band.conf'
799799
% (self.supercell_size[0], self.supercell_size[1], self.supercell_size[2], cell_file)
800800
)
801801
subprocess.check_call(command, shell=True)
@@ -868,16 +868,16 @@ def _ensure_vasp_volume_outputs(
868868
cwd = os.getcwd()
869869
try:
870870
os.chdir(helper_dir)
871-
subprocess.check_call(
872-
Phonon.phonopy_setup_command(
871+
Phonon.run_first_success(
872+
Phonon.phonopy_writefc_commands(
873873
'--dim="%s %s %s" -c POSCAR-unitcell --writefc'
874874
% (
875875
self.supercell_size[0],
876876
self.supercell_size[1],
877877
self.supercell_size[2],
878878
)
879879
),
880-
shell=True,
880+
required_file="FORCE_CONSTANTS",
881881
)
882882
finally:
883883
os.chdir(cwd)
@@ -888,8 +888,10 @@ def _ensure_vasp_volume_outputs(
888888
try:
889889
os.chdir(helper_dir)
890890
subprocess.check_call(
891-
'phonopy --dim="%s %s %s" -c POSCAR-unitcell band.conf'
892-
% (self.supercell_size[0], self.supercell_size[1], self.supercell_size[2]),
891+
Phonon.phonopy_command(
892+
'--dim="%s %s %s" -c POSCAR-unitcell band.conf'
893+
% (self.supercell_size[0], self.supercell_size[1], self.supercell_size[2])
894+
),
893895
shell=True,
894896
)
895897
self._write_band_dat()
@@ -954,14 +956,14 @@ def _ensure_abacus_volume_outputs(
954956
# Pass phonopy_disp.yaml explicitly so phonopy reads the supercell from the yaml
955957
# rather than falling into old-style POSCAR mode (which has no DIM).
956958
if not os.path.isfile("FORCE_CONSTANTS"):
957-
subprocess.check_call(
958-
Phonon.phonopy_setup_command("phonopy_disp.yaml --writefc"),
959-
shell=True,
959+
Phonon.run_first_success(
960+
Phonon.phonopy_writefc_commands("phonopy_disp.yaml --writefc"),
961+
required_file="FORCE_CONSTANTS",
960962
)
961963
if not os.path.isfile("FORCE_CONSTANTS"):
962964
raise FileNotFoundError(f"FORCE_CONSTANTS was not created in {helper_dir}")
963965
if not os.path.isfile("mesh.yaml"):
964-
subprocess.check_call("phonopy band.conf", shell=True)
966+
subprocess.check_call(Phonon.phonopy_command("band.conf"), shell=True)
965967
self._write_band_dat()
966968
finally:
967969
os.chdir(cwd)
@@ -973,28 +975,7 @@ def _write_band_dat() -> None:
973975
if not os.path.isfile("band.yaml"):
974976
logging.warning("band.yaml was not created; skipping band.dat export")
975977
return
976-
with open("band.dat", "w") as fp:
977-
result = subprocess.run(
978-
["phonopy-bandplot", "--gnuplot", "band.yaml"],
979-
stdout=fp,
980-
stderr=subprocess.PIPE,
981-
text=True,
982-
)
983-
if result.returncode == 0:
984-
return
985-
if os.path.isfile("band.dat") and os.path.getsize("band.dat") > 0:
986-
logging.warning(
987-
"phonopy-bandplot exited with code %s after writing band.dat; continuing. stderr: %s",
988-
result.returncode,
989-
result.stderr.strip(),
990-
)
991-
return
992-
raise subprocess.CalledProcessError(
993-
result.returncode,
994-
["phonopy-bandplot", "--gnuplot", "band.yaml"],
995-
output=None,
996-
stderr=result.stderr,
997-
)
978+
Phonon.write_band_dat()
998979

999980
def _attach_abacus_reference_energies(
1000981
self, task_infos: List[dict], task_result_map: Dict[str, str]

apex/core/property/Interstitial.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ def make_confs(self, path_to_work, path_to_equi, refine=False):
294294
with open("task.000000/POSCAR", "r") as fin:
295295
self.pos_line = fin.read().split("\n")
296296

297+
chl = None
297298
for idx, ii in enumerate(self.pos_line):
298299
ss = ii.split()
299300
if len(ss) > 3:
@@ -303,11 +304,19 @@ def make_confs(self, path_to_work, path_to_equi, refine=False):
303304
and abs(0.14 / self.supercell[2] - float(ss[2])) < TOL
304305
):
305306
chl = idx
307+
if chl is None:
308+
raise RuntimeError(
309+
f"Could not locate the generated interstitial anchor site "
310+
f"for {self.structure_type} special interstitial generation. "
311+
"Check the relaxed structure, supercell, or set special_list=[] "
312+
"to use the Voronoi generator."
313+
)
306314
shutil.rmtree("task.000000")
307315

308316
os.chdir(cwd)
309317
# specify interstitial structures
310318
if self.structure_type == 'bcc':
319+
center = None
311320
for idx, ii in enumerate(self.pos_line):
312321
ss = ii.split()
313322
if len(ss) > 3:
@@ -317,6 +326,13 @@ def make_confs(self, path_to_work, path_to_equi, refine=False):
317326
and abs(0.5 / self.supercell[2] - float(ss[2])) < TOL
318327
):
319328
center = idx
329+
if center is None:
330+
raise RuntimeError(
331+
"Could not locate the BCC center atom required for "
332+
"special interstitial dumbbell generation. Check the "
333+
"relaxed structure/supercell or set special_list=[] "
334+
"to use the Voronoi generator."
335+
)
320336
bcc_interstital_dict = {
321337
'tetrahedral': {chl: [0.25, 0.5, 0]},
322338
'octahedral': {chl: [0.5, 0.5, 0]},
@@ -331,6 +347,8 @@ def make_confs(self, path_to_work, path_to_equi, refine=False):
331347
total_task = self.__gen_tasks(bcc_interstital_dict)
332348

333349
elif self.structure_type == 'fcc':
350+
face = None
351+
corner = None
334352
for idx, ii in enumerate(self.pos_line):
335353
ss = ii.split()
336354
if len(ss) > 3:
@@ -347,6 +365,13 @@ def make_confs(self, path_to_work, path_to_equi, refine=False):
347365
and abs(1 / self.supercell[2] - float(ss[2])) < TOL
348366
):
349367
corner = idx
368+
if face is None or corner is None:
369+
raise RuntimeError(
370+
"Could not locate the FCC face/corner atoms required "
371+
"for special interstitial generation. Check the relaxed "
372+
"structure/supercell or set special_list=[] to use the "
373+
"Voronoi generator."
374+
)
350375

351376
fcc_interstital_dict = {
352377
'tetrahedral': {chl: [0.75, 0.25, 0.25]},
@@ -376,6 +401,7 @@ def make_confs(self, path_to_work, path_to_equi, refine=False):
376401
total_task = self.__gen_tasks(fcc_interstital_dict)
377402

378403
elif self.structure_type == 'hcp':
404+
center = None
379405
for idx, ii in enumerate(self.pos_line):
380406
ss = ii.split()
381407
if len(ss) > 3:
@@ -385,6 +411,13 @@ def make_confs(self, path_to_work, path_to_equi, refine=False):
385411
and abs(0.25 / self.supercell[2] - float(ss[2])) < TOL
386412
):
387413
center = idx
414+
if center is None:
415+
raise RuntimeError(
416+
"Could not locate the HCP center atom required for "
417+
"special interstitial generation. Check the relaxed "
418+
"structure/supercell or set special_list=[] to use the "
419+
"Voronoi generator."
420+
)
388421
hcp_interstital_dict = {
389422
'O': {chl: [0, 0, 0.5]},
390423
'BO': {chl: [0, 0, 0.25]},

0 commit comments

Comments
 (0)