Skip to content

Commit

Permalink
Merge pull request #83 from deepmodeling/devel-1.2.0
Browse files Browse the repository at this point in the history
Devel 1.2.0
  • Loading branch information
kevinwenminion authored Oct 11, 2024
2 parents 34f1acd + c69b55a commit 57e1936
Show file tree
Hide file tree
Showing 20 changed files with 261 additions and 168 deletions.
265 changes: 149 additions & 116 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apex/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import os
__version__ = '1.2.6'
__version__ = '1.2.9'
LOCAL_PATH = os.getcwd()


Expand Down
1 change: 1 addition & 0 deletions apex/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class Config:
group_size: int = None
pool_size: int = None
upload_python_packages: list = field(default_factory=list)
exclude_upload_files: list = field(default_factory=list)
lammps_image_name: str = None
lammps_run_command: str = None
vasp_image_name: str = None
Expand Down
3 changes: 3 additions & 0 deletions apex/core/calculator/ABACUS.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ def make_input_file(self, output_dir, task_type, task_param):
elif [relax_pos, relax_shape, relax_vol] == [False, True, True]:
self.modify_input(incar, "calculation", "cell-relax")
fix_atom = [True, True, True]
elif [relax_pos, relax_shape, relax_vol] == [True, False, True]:
self.modify_input(incar, "calculation", "cell-relax")
self.modify_input(incar, "fixed_axes", "shape")
elif [relax_pos, relax_shape, relax_vol] == [False, False, True]:
raise RuntimeError(
"relax volume but fix shape is not supported for ABACUS"
Expand Down
28 changes: 19 additions & 9 deletions apex/core/calculator/Lammps.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@
upload_packages.append(__file__)

# LAMMPS_INTER_TYPE = ['deepmd', 'eam_alloy', 'meam', 'eam_fs', 'meam_spline', 'snap', 'gap', 'rann', 'mace']

MULTI_MODELS_INTER_TYPE = ["meam", "snap", "gap"]

class Lammps(Task):
def __init__(self, inter_parameter, path_to_poscar):
self.inter = inter_parameter
self.inter_type = inter_parameter["type"]
self.type_map = inter_parameter["type_map"]
self.in_lammps = inter_parameter.get("in_lammps", "auto")
if self.inter_type in ["meam", "snap"]:
if self.inter_type in MULTI_MODELS_INTER_TYPE:
self.model = list(map(os.path.abspath, inter_parameter["model"]))
else:
self.model = os.path.abspath(inter_parameter["model"])
Expand Down Expand Up @@ -76,6 +76,16 @@ def set_model_param(self):
"param_type": self.type_map,
"deepmd_version": deepmd_version,
}
elif self.inter_type == "gap":
model_name = list(map(os.path.basename, self.model))
self.model_param = {
"type": self.inter_type,
"model_name": model_name,
"param_type": self.type_map,
"init_string": self.inter.get("init_string", None),
"atomic_num_list": self.inter.get("atomic_num_list", None),
"deepmd_version": deepmd_version,
}
else:
model_name = os.path.basename(self.model)
self.model_param = {
Expand All @@ -101,10 +111,10 @@ def symlink_force(self, target, link_name):

def make_potential_files(self, output_dir):
parent_dir = os.path.join(output_dir, "../../")
if self.inter_type in ["meam", "snap"]:
model_lib, model_file = map(os.path.basename, self.model[:2])
targets = [self.model[0], self.model[1]]
link_names = [model_lib, model_file]
if self.inter_type in MULTI_MODELS_INTER_TYPE:
model_file = map(os.path.basename, self.model)
targets = self.model
link_names = list(model_file)
else:
model_file = os.path.basename(self.model)
targets = [self.model]
Expand Down Expand Up @@ -516,19 +526,19 @@ def _prepare_result_dict(self, atom_numbs, type_map_list, type_list, box, coord,
return result_dict

def forward_files(self, property_type="relaxation"):
if self.inter_type in ["meam", "snap"]:
if self.inter_type in MULTI_MODELS_INTER_TYPE:
return ["conf.lmp", "in.lammps"] + list(map(os.path.basename, self.model))
else:
return ["conf.lmp", "in.lammps", os.path.basename(self.model)]

def forward_common_files(self, property_type="relaxation"):
if property_type not in ["eos"]:
if self.inter_type in ["meam", "snap"]:
if self.inter_type in MULTI_MODELS_INTER_TYPE:
return ["in.lammps"] + list(map(os.path.basename, self.model))
else:
return ["in.lammps", os.path.basename(self.model)]
else:
if self.inter_type in ["meam", "snap"]:
if self.inter_type in MULTI_MODELS_INTER_TYPE:
return list(map(os.path.basename, self.model))
else:
return [os.path.basename(self.model)]
Expand Down
8 changes: 5 additions & 3 deletions apex/core/calculator/VASP.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ def make_input_file(self, output_dir, task_type, task_param):

# revise INCAR based on the INCAR provided in the "interaction"
else:
approach = None
if prop_type == "phonon":
approach = task_param.get("approach", "linear")
approach = task_param.get("approach")
logging.info(f"No specification of INCAR for {prop_type} calculation, will auto-generate")
if approach == "linear":
incar = incar_upper(Incar.from_str(
Expand Down Expand Up @@ -131,14 +132,15 @@ def make_input_file(self, output_dir, task_type, task_param):
)
incar["ISIF"] = isif

elif cal_type == "static":
elif cal_type == "static" and not approach == "linear":
nsw = 0
if not ("NSW" in incar and incar.get("NSW") == nsw):
logging.info(
"%s setting NSW to %d" % (self.make_input_file.__name__, nsw)
)
incar["NSW"] = nsw

elif cal_type == "static" and approach == "linear":
pass
else:
raise RuntimeError("not supported calculation type for VASP")

Expand Down
25 changes: 16 additions & 9 deletions apex/core/calculator/lib/abacus_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/python3
import logging
import os, re
import os, re, glob

import dpdata
import numpy as np
Expand Down Expand Up @@ -410,16 +410,23 @@ def final_stru(abacus_path):
out_stru = bool(line.split()[1])
logf = os.path.join(abacus_path, "OUT.%s/running_%s.log" % (suffix, calculation))
if calculation in ["relax", "cell-relax"]:
if not out_stru:
if os.path.isfile(os.path.join(abacus_path, "OUT.%s/STRU_ION_D" % suffix)):
return "OUT.%s/STRU_ION_D" % suffix
else:
with open(logf) as f1:
lines = f1.readlines()
for i in range(1, len(lines)):
if lines[-i][36:41] == "istep":
max_step = int(lines[-i].split()[-1])
break
return "OUT.%s/STRU_ION%d_D" % (suffix, max_step)
# find the final name by STRU_ION*_D,
# for abacus version < v3.2.2, there has no STRU_ION_D file but has STRU_ION0_D STRU_ION1_D ... STRU_ION10_D ...
# so we need to find the last STRU_ION*_D file
stru_ions = glob.glob(
os.path.join(abacus_path, f"OUT.{suffix}/STRU_ION*_D")
)
if len(stru_ions) > 0:
# sort the file name by the number in the file name
stru_ions.sort(key=lambda x: int(x.split("_")[-2][3:]))
final_stru_ion = os.path.basename(stru_ions[-1])
return f"OUT.{suffix}/{final_stru_ion}"
else:
# if there has no STRU_ION_D, return the input STRU
return "STRU"
elif calculation == "md":
with open(logf) as f1:
lines = f1.readlines()
Expand Down
20 changes: 14 additions & 6 deletions apex/core/calculator/lib/lammps_utils.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
#!/usr/bin/env python3

import os
import random
import subprocess as sp
import sys
import re

import dpdata
from dpdata.periodic_table import Element
from packaging.version import Version

from apex.core.lib import util
from apex.core.constants import PERIOD_ELEMENTS_BY_SYMBOL
from dflow.python import upload_packages
upload_packages.append(__file__)

Expand Down Expand Up @@ -153,11 +152,20 @@ def inter_snap(param):


def inter_gap(param):
init_string = param["init_string"]
atomic_num_list = param["atomic_num_list"]
if init_string is None:
with open(param["model_name"][0], "r") as fp:
xml_contents = fp.read()
init_string = re.search(r'label="([^"]*)"', xml_contents).group(1)
if atomic_num_list is None:
atomic_num_list = [PERIOD_ELEMENTS_BY_SYMBOL.index(e) + 1 for e in param["param_type"]]

ret = ""
line = "pair_style quip \n"
line += "pair_coeff * * %s " % param["model_name"][0]
for ii in param["param_type"]:
line += ii + " "
line += f'pair_coeff * * {param["model_name"][0]} "Potential xml_label={init_string}" '
for ii in atomic_num_list:
line += str(ii) + " "
line += "\n"
ret += line
return ret
Expand Down
7 changes: 7 additions & 0 deletions apex/core/common_equi.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,14 @@ def make_equi(confs, inter_param, relax_param):
sys.to("abacus/stru", stru)
else:
raise FileNotFoundError("No file %s" % stru)
if not os.path.exists(os.path.join(ii, POSCAR)):
sys = dpdata.System(stru, fmt="abacus/stru")
sys.to("vasp/poscar", os.path.join(ii, POSCAR))

shutil.copyfile(stru, os.path.join(ii, "STRU.bk"))
abacus_utils.modify_stru_path(stru, "pp_orb/", inter_param)
orig_poscar = poscar
orig_POSCAR = POSCAR
poscar = os.path.abspath(stru)
POSCAR = "STRU"
if not os.path.exists(poscar):
Expand All @@ -105,6 +110,8 @@ def make_equi(confs, inter_param, relax_param):
if os.path.isfile(POSCAR):
os.remove(POSCAR)
os.symlink(os.path.relpath(poscar), POSCAR)
if inter_param["type"] == "abacus":
os.symlink(os.path.relpath(orig_poscar), orig_POSCAR)
os.chdir(cwd)
task_dirs.sort()
# generate task files
Expand Down
14 changes: 14 additions & 0 deletions apex/core/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
PERIOD_ELEMENTS_BY_SYMBOL = [
"H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne",
"Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca",
"Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn",
"Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr",
"Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn",
"Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd",
"Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb",
"Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg",
"Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac", "Th",
"Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm",
"Md", "No", "Lr", "Rf", "Db", "Sg", "Bh", "Hs", "Mt", "Ds",
"Rg", "Cn", "Nh", "Fl", "Mc", "Lv", "Ts", "Og"
]
2 changes: 1 addition & 1 deletion apex/core/property/Elastic.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def __init__(self, parameter, inter_param=None):
self.shear_deform = parameter["shear_deform"]
parameter.setdefault("conventional", False)
self.conventional = parameter["conventional"]
parameter.setdefault("ieee", True)
parameter.setdefault("ieee", False)
self.ieee = parameter["ieee"]
parameter.setdefault("cal_type", "relaxation")
self.cal_type = parameter["cal_type"]
Expand Down
6 changes: 3 additions & 3 deletions apex/core/property/Gamma.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,15 +248,15 @@ def make_confs(self, path_to_work, path_to_equi, refine=False):
task_list.append(output_task)
# print("# %03d generate " % ii, output_task)

logging.info(f"# {count} generate {output_task}, with{len(obtained_slab.sites)} atoms")
logging.info(f"# {count} generate {output_task}, with {len(obtained_slab.sites)} atoms")

# make confs
obtained_slab.to("POSCAR.tmp", "POSCAR")
vasp_utils.regulate_poscar("POSCAR.tmp", "POSCAR")
vasp_utils.sort_poscar("POSCAR", "POSCAR", ptypes)
if self.inter_param["type"] == "abacus":
abacus_utils.poscar2stru("POSCAR", self.inter_param, "STRU")
os.remove("POSCAR")
#os.remove("POSCAR")
# vasp.perturb_xz('POSCAR', 'POSCAR', self.pert_xz)
# record miller
dumpfn(self.plane_miller, "miller.json")
Expand Down Expand Up @@ -433,7 +433,7 @@ def __poscar_fix(self, poscar) -> None:

def __stru_fix(self, stru) -> None:
fix_dict = {"true": True, "false": False}
fix_xyz = [fix_dict[i] for i in self.addfix]
fix_xyz = [fix_dict[i] for i in self.add_fix]
abacus_utils.stru_fix_atom(stru, fix_atom=fix_xyz)

def __inLammpes_fix(self, inLammps) -> None:
Expand Down
4 changes: 2 additions & 2 deletions apex/core/property/Interstitial.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ def make_confs(self, path_to_work, path_to_equi, refine=False):
bcc_interstital_dict = {
'tetrahedral': {chl: [0.25, 0.5, 0]},
'octahedral': {chl: [0.5, 0.5, 0]},
'crowdion': {chl: [0.25, 0.25, 0]},
'crowdion': {chl: [0.25, 0.25, 0.25]},
'<111>dumbbell': {chl: [1 / 3, 1 / 3, 1 / 3],
center: [2 / 3, 2 / 3, 2 / 3]},
'<110>dumbbell': {chl: [1 / 4, 3 / 4, 1 / 2],
Expand Down Expand Up @@ -408,7 +408,7 @@ def make_confs(self, path_to_work, path_to_equi, refine=False):
output_task = os.path.join(self.path_to_work, "task.%06d" % ii)
os.chdir(output_task)
abacus_utils.poscar2stru("POSCAR", self.inter_param, "STRU")
os.remove("POSCAR")
#os.remove("POSCAR")
os.chdir(cwd)
return self.task_list

Expand Down
24 changes: 14 additions & 10 deletions apex/core/property/Phonon.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def __init__(self, parameter, inter_param=None):
self.BAND_POINTS = parameter["BAND_POINTS"]
parameter["BAND_CONNECTION"] = parameter.get('BAND_CONNECTION', True)
self.BAND_CONNECTION = parameter["BAND_CONNECTION"]
parameter["cal_type"] = parameter.get("cal_type", "relaxation")
parameter["cal_type"] = parameter.get("cal_type", "static")
default_cal_setting = {
"relax_pos": True,
"relax_shape": False,
Expand Down Expand Up @@ -485,6 +485,12 @@ def phonopy_band_string_2_band_list(band_str: str, band_label: str = None):
# return type -> list[list[dict[Any, Any]]]
return band_list

@staticmethod
def check_same_copy(src, dst):
if os.path.samefile(src, dst):
return
shutil.copyfile(src, dst)

def _compute_lower(self, output_file, all_tasks, all_res):
cwd = Path.cwd()
work_path = Path(output_file).parent.absolute()
Expand All @@ -497,10 +503,9 @@ def _compute_lower(self, output_file, all_tasks, all_res):
if not self.reprod:
os.chdir(work_path)
if self.inter_param["type"] == 'abacus':
shutil.copyfile("task.000000/band.conf", "band.conf")
shutil.copyfile("task.000000/STRU.ori", "STRU")
shutil.copyfile("task.000000/phonopy_disp.yaml", "phonopy_disp.yaml")
os.system('phonopy -f task.0*/OUT.ABACUS/running_scf.log')
self.check_same_copy("task.000000/band.conf", "band.conf")
self.check_same_copy("task.000000/STRU.ori", "STRU")
self.check_same_copy("task.000000/phonopy_disp.yaml", "phonopy_disp.yaml")
os.system('phonopy -f task.0*/OUT.ABACUS/running_scf.log')
if os.path.exists("FORCE_SETS"):
print('FORCE_SETS is created')
Expand All @@ -510,9 +515,8 @@ def _compute_lower(self, output_file, all_tasks, all_res):
os.system('phonopy-bandplot --gnuplot band.yaml > band.dat')

elif self.inter_param["type"] == 'vasp':
shutil.copyfile("task.000000/band.conf", "band.conf")
if not os.path.samefile("task.000000/POSCAR-unitcell", "POSCAR-unitcell"):
shutil.copyfile("task.000000/POSCAR-unitcell", "POSCAR-unitcell")
self.check_same_copy("task.000000/band.conf", "band.conf")
self.check_same_copy("task.000000/POSCAR-unitcell", "POSCAR-unitcell")

if self.approach == "linear":
os.chdir(all_tasks[0])
Expand All @@ -528,8 +532,8 @@ def _compute_lower(self, output_file, all_tasks, all_res):
shutil.copyfile("band.dat", work_path/"band.dat")

elif self.approach == "displacement":
shutil.copyfile("task.000000/band.conf", "band.conf")
shutil.copyfile("task.000000/phonopy_disp.yaml", "phonopy_disp.yaml")
self.check_same_copy("task.000000/band.conf", "band.conf")
self.check_same_copy("task.000000/phonopy_disp.yaml", "phonopy_disp.yaml")
os.system('phonopy -f task.0*/vasprun.xml')
if os.path.exists("FORCE_SETS"):
print('FORCE_SETS is created')
Expand Down
2 changes: 1 addition & 1 deletion apex/core/property/Surface.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def make_confs(self, path_to_work, path_to_equi, refine=False):
vasp_utils.perturb_xz("POSCAR", "POSCAR", self.pert_xz)
if self.inter_param["type"] == "abacus":
abacus_utils.poscar2stru("POSCAR", self.inter_param, "STRU")
os.remove("POSCAR")
#os.remove("POSCAR")
# record miller
dumpfn(all_slabs[ii].miller_index, "miller.json")

Expand Down
2 changes: 1 addition & 1 deletion apex/core/property/Vacancy.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def make_confs(self, path_to_work, path_to_equi, refine=False):
dss[ii].to("POSCAR", "POSCAR")
if self.inter_param["type"] == "abacus":
abacus_utils.poscar2stru("POSCAR", self.inter_param, "STRU")
os.remove("POSCAR")
#os.remove("POSCAR")
# np.savetxt('supercell.out', self.supercell, fmt='%d')
dumpfn(self.supercell, "supercell.json")
os.chdir(cwd)
Expand Down
Loading

0 comments on commit 57e1936

Please sign in to comment.