Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ potential
all_result.json

# dflow debug folders generated by examples or local runs
**/dflow_debug/
**/dflow_debug/
10 changes: 9 additions & 1 deletion apex/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ class Config:
vasp_run_command: str = None
abacus_image_name: str = None
abacus_run_command: str = None
lammps_header_retry_attempts: int = 2
lammps_header_retry_delay: float = 5
lammps_transient_retry_attempts: int = 1
lammps_retry_group_size: int = None

# common APEX config
is_bohrium_dflow: bool = False
Expand Down Expand Up @@ -256,7 +260,11 @@ def basic_config_dict(self):
"vasp_image_name": self.vasp_image_name,
"vasp_run_command": self.vasp_run_command,
"abacus_image_name": self.abacus_image_name,
"abacus_run_command": self.abacus_run_command
"abacus_run_command": self.abacus_run_command,
"lammps_header_retry_attempts": self.lammps_header_retry_attempts,
"lammps_header_retry_delay": self.lammps_header_retry_delay,
"lammps_transient_retry_attempts": self.lammps_transient_retry_attempts,
"lammps_retry_group_size": self.lammps_retry_group_size
}
return basic_config

Expand Down
35 changes: 30 additions & 5 deletions apex/core/property/Gamma.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def __init__(self, parameter, inter_param=None):
self.reprod = parameter["reproduce"]
if not self.reprod:
if not ("init_from_suffix" in parameter and "output_suffix" in parameter):
parameter["cal_type"] = parameter.get("cal_type", "relaxation")
parameter["plane_miller"] = parameter.get("plane_miller", None)
self.plane_miller = parameter["plane_miller"]
parameter["slip_direction"] = parameter.get("slip_direction", None)
Expand All @@ -48,14 +49,18 @@ def __init__(self, parameter, inter_param=None):
self.supercell_size = parameter["supercell_size"]
parameter["vacuum_size"] = parameter.get("vacuum_size", 0)
self.vacuum_size = parameter["vacuum_size"]
parameter["add_fix"] = parameter.get(
"add_fix", ["true", "true", "false"]
) # standard method
if parameter["cal_type"] == "static" and "add_fix" not in parameter:
parameter["add_fix"] = None
else:
parameter["add_fix"] = parameter.get(
"add_fix", ["true", "true", "false"]
) # standard method
self.add_fix = parameter["add_fix"]
parameter["n_steps"] = parameter.get("n_steps", 10)
self.n_steps = parameter["n_steps"]
self.atom_num = None
parameter["cal_type"] = parameter.get("cal_type", "relaxation")
else:
parameter["cal_type"] = parameter.get("cal_type", "relaxation")
default_cal_setting = {
"relax_pos": True,
"relax_shape": False,
Expand Down Expand Up @@ -157,7 +162,18 @@ def make_confs(self, path_to_work, path_to_equi, refine=False):

equi_contcar = os.path.join(path_to_equi, CONTCAR)
if not os.path.exists(equi_contcar):
raise RuntimeError("please do relaxation first")
raise RuntimeError(
"Gamma requires a baseline relaxation before PropsMake. "
"For static gamma scans, run a static baseline relaxation "
"with relax_pos=false, relax_shape=false, and relax_vol=false."
)
equi_result = os.path.join(path_to_equi, "result.json")
if not os.path.exists(equi_result):
raise RuntimeError(
"Gamma post-processing requires relaxation/relax_task/result.json. "
"Please provide a static baseline relaxation result before "
"running gamma PropsMake."
)
# print("we now only support gamma line calculation for BCC FCC and HCP metals")
# print(
# f"supported slip systems are:\n{SlabSlipSystem.hint_string()}"
Expand Down Expand Up @@ -451,6 +467,8 @@ def __inLammpes_fix(self, inLammps) -> None:
)
with open(inLammps, "r") as fin1:
contents = fin1.readlines()
lower_id = None
upper_id = None
for ii in range(len(contents)):
upper = contents[ii].split()[:3] == ["variable", "N", "equal"]
lower = re.search("min_style cg", contents[ii])
Expand All @@ -460,6 +478,13 @@ def __inLammpes_fix(self, inLammps) -> None:
elif upper:
upper_id = ii
# print(upper_id)
if lower_id is None or upper_id is None or lower_id >= upper_id:
raise RuntimeError(
"Gamma add_fix was requested, but in.lammps does not contain "
"a compatible minimization block to patch. For static gamma "
"calculations set add_fix to null, or use a relaxation-style "
"LAMMPS input with min_style cg and variable N equal markers."
)
del contents[lower_id + 1:upper_id - 1]
contents.insert(lower_id + 1, add_fix_str)
with open(inLammps, "w") as fin2:
Expand Down
47 changes: 14 additions & 33 deletions apex/core/property/Gruneisen.py
Original file line number Diff line number Diff line change
Expand Up @@ -794,8 +794,8 @@ def _ensure_mesh_yaml(self, task_dir: str) -> None:
raise FileNotFoundError(f"POSCAR not found in {task_dir}")
os.chdir(task_dir)
cell_file = "POSCAR-unitcell" if self.inter_param["type"] == "vasp" else "POSCAR"
command = (
'phonopy --nomeshsym --dim="%s %s %s" -c %s band.conf'
command = Phonon.phonopy_command(
'--nomeshsym --dim="%s %s %s" -c %s band.conf'
% (self.supercell_size[0], self.supercell_size[1], self.supercell_size[2], cell_file)
)
subprocess.check_call(command, shell=True)
Expand Down Expand Up @@ -868,16 +868,16 @@ def _ensure_vasp_volume_outputs(
cwd = os.getcwd()
try:
os.chdir(helper_dir)
subprocess.check_call(
Phonon.phonopy_setup_command(
Phonon.run_first_success(
Phonon.phonopy_writefc_commands(
'--dim="%s %s %s" -c POSCAR-unitcell --writefc'
% (
self.supercell_size[0],
self.supercell_size[1],
self.supercell_size[2],
)
),
shell=True,
required_file="FORCE_CONSTANTS",
)
finally:
os.chdir(cwd)
Expand All @@ -888,8 +888,10 @@ def _ensure_vasp_volume_outputs(
try:
os.chdir(helper_dir)
subprocess.check_call(
'phonopy --dim="%s %s %s" -c POSCAR-unitcell band.conf'
% (self.supercell_size[0], self.supercell_size[1], self.supercell_size[2]),
Phonon.phonopy_command(
'--dim="%s %s %s" -c POSCAR-unitcell band.conf'
% (self.supercell_size[0], self.supercell_size[1], self.supercell_size[2])
),
shell=True,
)
self._write_band_dat()
Expand Down Expand Up @@ -954,14 +956,14 @@ def _ensure_abacus_volume_outputs(
# Pass phonopy_disp.yaml explicitly so phonopy reads the supercell from the yaml
# rather than falling into old-style POSCAR mode (which has no DIM).
if not os.path.isfile("FORCE_CONSTANTS"):
subprocess.check_call(
Phonon.phonopy_setup_command("phonopy_disp.yaml --writefc"),
shell=True,
Phonon.run_first_success(
Phonon.phonopy_writefc_commands("phonopy_disp.yaml --writefc"),
required_file="FORCE_CONSTANTS",
)
if not os.path.isfile("FORCE_CONSTANTS"):
raise FileNotFoundError(f"FORCE_CONSTANTS was not created in {helper_dir}")
if not os.path.isfile("mesh.yaml"):
subprocess.check_call("phonopy band.conf", shell=True)
subprocess.check_call(Phonon.phonopy_command("band.conf"), shell=True)
self._write_band_dat()
finally:
os.chdir(cwd)
Expand All @@ -973,28 +975,7 @@ def _write_band_dat() -> None:
if not os.path.isfile("band.yaml"):
logging.warning("band.yaml was not created; skipping band.dat export")
return
with open("band.dat", "w") as fp:
result = subprocess.run(
["phonopy-bandplot", "--gnuplot", "band.yaml"],
stdout=fp,
stderr=subprocess.PIPE,
text=True,
)
if result.returncode == 0:
return
if os.path.isfile("band.dat") and os.path.getsize("band.dat") > 0:
logging.warning(
"phonopy-bandplot exited with code %s after writing band.dat; continuing. stderr: %s",
result.returncode,
result.stderr.strip(),
)
return
raise subprocess.CalledProcessError(
result.returncode,
["phonopy-bandplot", "--gnuplot", "band.yaml"],
output=None,
stderr=result.stderr,
)
Phonon.write_band_dat()

def _attach_abacus_reference_energies(
self, task_infos: List[dict], task_result_map: Dict[str, str]
Expand Down
33 changes: 33 additions & 0 deletions apex/core/property/Interstitial.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ def make_confs(self, path_to_work, path_to_equi, refine=False):
with open("task.000000/POSCAR", "r") as fin:
self.pos_line = fin.read().split("\n")

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

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

elif self.structure_type == 'fcc':
face = None
corner = None
for idx, ii in enumerate(self.pos_line):
ss = ii.split()
if len(ss) > 3:
Expand All @@ -347,6 +365,13 @@ def make_confs(self, path_to_work, path_to_equi, refine=False):
and abs(1 / self.supercell[2] - float(ss[2])) < TOL
):
corner = idx
if face is None or corner is None:
raise RuntimeError(
"Could not locate the FCC face/corner atoms required "
"for special interstitial generation. Check the relaxed "
"structure/supercell or set special_list=[] to use the "
"Voronoi generator."
)

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

elif self.structure_type == 'hcp':
center = None
for idx, ii in enumerate(self.pos_line):
ss = ii.split()
if len(ss) > 3:
Expand All @@ -385,6 +411,13 @@ def make_confs(self, path_to_work, path_to_equi, refine=False):
and abs(0.25 / self.supercell[2] - float(ss[2])) < TOL
):
center = idx
if center is None:
raise RuntimeError(
"Could not locate the HCP center atom required for "
"special interstitial generation. Check the relaxed "
"structure/supercell or set special_list=[] to use the "
"Voronoi generator."
)
hcp_interstital_dict = {
'O': {chl: [0, 0, 0.5]},
'BO': {chl: [0, 0, 0.25]},
Expand Down
Loading
Loading