Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: update abacus input parameters for test_make_fp.py #836

Merged
merged 15 commits into from
Aug 4, 2022
Merged
Show file tree
Hide file tree
Changes from 12 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
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,10 @@ The bold notation of key (such aas **type_map**) means that it's a necessary key
| **user_fp_params** | Dict | |Parameters for cp2k calculation. find detail in manual.cp2k.org. only the kind section must be set before use. we assume that you have basic knowledge for cp2k input.
| **external_input_path** | String | | Conflict with key:user_fp_params, use the template input provided by user, some rules should be followed, read the following text in detail.
| *fp_style == ABACUS*
| **user_fp_params** | Dict | |Parameters for ABACUS INPUT. find detail [Here](https://github.com/deepmodeling/abacus-develop/blob/develop/docs/input-main.md#out-descriptor). If `deepks_model` is set, the model file should be in the pseudopotential directory. You can also set `KPT` file by adding `k_points` that corresponds to a list of six integers in this dictionary.
| **user_fp_params** | Dict | |Parameters for ABACUS INPUT. find detail [Here](https://github.com/deepmodeling/abacus-develop/blob/develop/docs/input-main.md#out-descriptor). If `deepks_model` is set, the model file should be in the pseudopotential directory. You can also set `KPT` file by adding `k_points` that corresponds to a list of six integers in this dictionary. Any key beginning with "_" will be ignored.
| **fp_incar** | String | "./abacus/INPUT" | INPUT file for ABACUS. This is another way of providing input parameters. Users must choose one of these two ways. Any keyword beginning with "_" will be ignored
| **k_points** | List of integers | [2,2,2,0,0,0] | Monkhorst-Pack k-grids setting for generating KPT file of ABACUS
| **fp_kpt_file** | String | "./abacus/KPT" | KPT file for ABACUS. This is another way to provide KPT file for ABACUS and have lower priority than the above `k_points` key. They two have lower priority than kspacing and gamma_only in INPUT file of ABACUS.
| **fp_orb_files** | List | |List of atomic orbital files. The files should be in pseudopotential directory.
| **fp_dpks_descriptor** | String | |DeePKS descriptor file name. The file should be in pseudopotential directory.

Expand Down
3 changes: 0 additions & 3 deletions dpgen/generator/arginfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ def model_devi_lmp_args() -> List[Argument]:
doc_model_devi_f_avg_relative = 'Normalized the force model deviations by the RMS force magnitude along the trajectory. This key should not be used with use_relative.'
doc_model_devi_clean_traj = 'If type of model_devi_clean_traj is bool type then it denote whether to clean traj folders in MD since they are too large. If it is Int type, then the most recent n iterations of traj folders will be retained, others will be removed.'
doc_model_devi_nopbc = 'Assume open boundary condition in MD simulations.'
doc_model_devi_activation_func = 'Set activation functions for models, length of the list should be the same as numb_models, and two elements in the list of string respectively assign activation functions to the embedding and fitting nets within each model. Backward compatibility: the orginal "list of String" format is still supported, where embedding and fitting nets of one model use the same activation function, and the length of the list should be the same as numb_models.'
doc_shuffle_poscar = 'Shuffle atoms of each frame before running simulations. The purpose is to sample the element occupation of alloys.'
doc_use_relative = 'Calculate relative force model deviation.'
doc_epsilon = 'The level parameter for computing the relative force model deviation.'
Expand Down Expand Up @@ -196,8 +195,6 @@ def model_devi_lmp_args() -> List[Argument]:
bool, int], optional=False, doc=doc_model_devi_clean_traj),
Argument("model_devi_nopbc", bool, optional=True, default=False,
doc=doc_model_devi_nopbc),
Argument("model_devi_activation_func", list, optional=True,
doc=doc_model_devi_activation_func),
Argument("shuffle_poscar", bool, optional=True, default=False, doc=doc_shuffle_poscar),
Argument("use_relative", bool, optional=True, default=False, doc=doc_use_relative),
Argument("epsilon", float, optional=True, doc=doc_epsilon),
Expand Down
72 changes: 51 additions & 21 deletions dpgen/generator/lib/abacus_scf.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,69 +21,98 @@ def make_abacus_scf_input(fp_params):
ret = "INPUT_PARAMETERS\n"
ret += "calculation scf\n"
for key in fp_params:
if key == 'ntype':
if key == "ntype":
fp_params["ntype"] = int(fp_params["ntype"])
assert(fp_params['ntype'] >= 0 and type(fp_params["ntype"]) == int), "'ntype' should be a positive integer."
ret += "ntype %d\n" % fp_params['ntype']
#ret += "pseudo_dir ./\n"
elif key == "ecutwfc":
fp_params["ecutwfc"] = float(fp_params["ecutwfc"])
assert(fp_params["ecutwfc"] >= 0) , "'ntype' should be non-negative."
ret += "ecutwfc %f\n" % fp_params["ecutwfc"]
elif key == "dr2":
ret += "dr2 %e\n" % fp_params["dr2"]
elif key == "niter":
assert(fp_params['niter'] >= 0 and type(fp_params["niter"])== int), "'niter' should be a positive integer."
ret += "niter %d\n" % fp_params["niter"]
elif key == "kspacing":
fp_params["kspacing"] = float(fp_params["kspacing"])
assert(fp_params["kspacing"] >= 0) , "'ntype' should be non-negative."
ret += "kspacing %f\n" % fp_params["kspacing"]
elif key == "scf_thr":
fp_params["scf_thr"] = float(fp_params["scf_thr"])
ret += "scf_thr %e\n" % fp_params["scf_thr"]
elif key == "scf_nmax":
fp_params["scf_nmax"] = int(fp_params["scf_nmax"])
assert(fp_params['scf_nmax'] >= 0 and type(fp_params["scf_nmax"])== int), "'scf_nmax' should be a positive integer."
ret += "scf_nmax %d\n" % fp_params["scf_nmax"]
elif key == "basis_type":
assert(fp_params["basis_type"] in ["pw", "lcao", "lcao_in_pw"]) , "'basis_type' must in 'pw', 'lcao' or 'lcao_in_pw'."
ret+= "basis_type %s\n" % fp_params["basis_type"]
elif key == "dft_functional":
ret += "dft_functional %s\n" % fp_params["dft_functional"]
elif key == "gamma_only":
#assert(fp_params["gamma_only"] ==1 ) , "'gamma_only' should be 1. Multi-k algorithm will be supported after the KPT generator is completed."
if type(fp_params["gamma_only"])==str:
fp_params["gamma_only"] = int(eval(fp_params["gamma_only"]))
assert(fp_params["gamma_only"] == 0 or fp_params["gamma_only"] == 1), "'gamma_only' should be either 0 or 1."
ret+= "gamma_only %d\n" % fp_params["gamma_only"]
elif key == "mixing_type":
assert(fp_params["mixing_type"] in ["plain", "kerker", "pulay", "pulay-kerker", "broyden"])
ret += "mixing_type %s\n" % fp_params["mixing_type"]
elif key == "mixing_beta":
fp_params["mixing_beta"] = float(fp_params["mixing_beta"])
assert(fp_params["mixing_beta"] >= 0 and fp_params["mixing_beta"] < 1), "'mixing_beta' should between 0 and 1."
ret += "mixing_beta %f\n" % fp_params["mixing_beta"]
elif key == "symmetry":
if type(fp_params["symmetry"])==str:
fp_params["symmetry"] = int(eval(fp_params["symmetry"]))
assert(fp_params["symmetry"] == 0 or fp_params["symmetry"] == 1), "'symmetry' should be either 0 or 1."
ret += "symmetry %d\n" % fp_params["symmetry"]
elif key == "nbands":
fp_params["nbands"] = int(fp_params["nbands"])
assert(fp_params["nbands"] > 0 and type(fp_params["nbands"]) == int), "'nbands' should be a positive integer."
ret += "nbands %d\n" % fp_params["nbands"]
elif key == "nspin":
fp_params["nspin"] = int(fp_params["nspin"])
assert(fp_params["nspin"] == 1 or fp_params["nspin"] == 2 or fp_params["nspin"] == 4), "'nspin' can anly take 1, 2 or 4"
ret += "nspin %d\n" % fp_params["nspin"]
elif key == "ks_solver":
assert(fp_params["ks_solver"] in ["cg", "dav", "lapack", "genelpa", "hpseps", "scalapack_gvx"]), "'ks_sover' should in 'cgx', 'dav', 'lapack', 'genelpa', 'hpseps', 'scalapack_gvx'."
ret += "ks_solver %s\n" % fp_params["ks_solver"]
elif key == "smearing":
assert(fp_params["smearing"] in ["gaussian", "fd", "fixed", "mp", "mp2", "mv"]), "'smearing' should in 'gaussian', 'fd', 'fixed', 'mp', 'mp2', 'mv'. "
ret += "smearing %s\n" % fp_params["smearing"]
elif key == "sigma":
assert(fp_params["sigma"] >= 0), "'sigma' should be non-negative."
ret += "sigma %f\n" % fp_params["sigma"]
elif key == "force":
assert(fp_params["force"] == 0 or fp_params["force"] == 1), "'force' should be either 0 or 1."
ret += "force %d\n" % fp_params["force"]
elif key == "stress":
assert(fp_params["stress"] == 0 or fp_params["stress"] == 1), "'stress' should be either 0 or 1."
ret += "stress %d\n" % fp_params["stress"]
elif key == "smearing_method":
assert(fp_params["smearing_method"] in ["gaussian", "fd", "fixed", "mp", "mp2", "mv"]), "'smearing_method' should in 'gaussian', 'fd', 'fixed', 'mp', 'mp2', 'mv'. "
ret += "smearing_method %s\n" % fp_params["smearing_method"]
elif key == "smearing_sigma":
fp_params["smearing_sigma"] = float(fp_params["smearing_sigma"])
assert(fp_params["smearing_sigma"] >= 0), "'smearing_sigma' should be non-negative."
ret += "smearing_sigma %f\n" % fp_params["smearing_sigma"]
elif key == "cal_force":
if type(fp_params["cal_force"])==str:
fp_params["cal_force"] = int(eval(fp_params["cal_force"]))
assert(fp_params["cal_force"] == 0 or fp_params["cal_force"] == 1), "'cal_force' should be either 0 or 1."
ret += "cal_force %d\n" % fp_params["cal_force"]
elif key == "cal_stress":
if type(fp_params["cal_stress"])==str:
fp_params["cal_stress"] = int(eval(fp_params["cal_stress"]))
assert(fp_params["cal_stress"] == 0 or fp_params["cal_stress"] == 1), "'cal_stress' should be either 0 or 1."
ret += "cal_stress %d\n" % fp_params["cal_stress"]
#paras for deepks
elif key == "deepks_out_labels":
if type(fp_params["deepks_out_labels"])==str:
fp_params["deepks_out_labels"] = int(eval(fp_params["deepks_out_labels"]))
assert(fp_params["deepks_out_labels"] == 0 or fp_params["deepks_out_labels"] == 1), "'deepks_out_labels' should be either 0 or 1."
ret += "deepks_out_labels %d\n" % fp_params["deepks_out_labels"]
elif key == "deepks_descriptor_lmax":
fp_params["deepks_descriptor_lmax"] = int(fp_params["deepks_descriptor_lmax"])
assert(fp_params["deepks_descriptor_lmax"] >= 0), "'deepks_descriptor_lmax' should be a positive integer."
ret += "deepks_descriptor_lmax %d\n" % fp_params["deepks_descriptor_lmax"]
elif key == "deepks_scf":
if type(fp_params["deepks_scf"])==str:
fp_params["deepks_scf"] = int(eval(fp_params["deepks_scf"]))
assert(fp_params["deepks_scf"] == 0 or fp_params["deepks_scf"] == 1), "'deepks_scf' should be either 0 or 1."
ret += "deepks_scf %d\n" % fp_params["deepks_scf"]
elif key == "deepks_model":
ret += "deepks_model %s\n" % fp_params["deepks_model"]
elif key != "k_points": # "k_points key is used to generate KPT file."
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This elif is necessary. The k_points is also specified in fp_params, but can not be written in INPUT file.

Copy link
Contributor Author

@hongriTianqi hongriTianqi Aug 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This k_points tag has been upgraded to the same level as 'user_fp_param'. Users may also use 'fp_kpt_file' to read KPT file now.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got that. I have no other questions.

elif key[0] == "_":
pass
elif key == "calculation":
pass
else:
ret += "%s %s\n" % (key, str(fp_params[key]))
return ret

Expand Down Expand Up @@ -153,6 +182,7 @@ def get_abacus_input_parameters(INPUT):
parameter_name = line.split()[0]
parameter_value = line.split()[1]
input_parameters[parameter_name] = parameter_value
fp.close()
return input_parameters

def get_mass_from_STRU(geometry_inlines, inlines, atom_names):
Expand Down Expand Up @@ -286,4 +316,4 @@ def make_kspacing_kpoints_stru(stru, kspacing) :
if __name__ == "__main__":
fp_params = {"k_points": [1, 1, 1, 0, 0, 0]}
ret = make_abacus_scf_kpt(fp_params)
print(ret)
print(ret)
83 changes: 76 additions & 7 deletions dpgen/generator/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
from dpgen.generator.lib.vasp import incar_upper
from dpgen.generator.lib.pwscf import make_pwscf_input
from dpgen.generator.lib.abacus_scf import make_abacus_scf_stru, make_abacus_scf_input, make_abacus_scf_kpt
from dpgen.generator.lib.abacus_scf import get_abacus_input_parameters
#from dpgen.generator.lib.pwscf import cvt_1frame
from dpgen.generator.lib.pwmat import make_pwmat_input_dict
from dpgen.generator.lib.pwmat import write_input_dict
Expand Down Expand Up @@ -2561,7 +2562,8 @@ def make_fp_abacus_scf(iter_index,
fp_pp_files = jdata['fp_pp_files']
fp_orb_files = None
fp_dpks_descriptor = None
assert('user_fp_params' in jdata.keys())
# get paramters for writting INPUT file
fp_params = {}
if 'user_fp_params' in jdata.keys() :
fp_params = jdata['user_fp_params']
# for lcao
Expand All @@ -2574,20 +2576,59 @@ def make_fp_abacus_scf(iter_index,
assert('fp_dpks_descriptor' in jdata and type(jdata['fp_dpks_descriptor']) == str)
fp_dpks_descriptor = jdata['fp_dpks_descriptor']
#user_input = True
ret_input = make_abacus_scf_input(fp_params)
elif 'fp_incar' in jdata.keys():
fp_input_path = jdata['fp_incar']
assert(os.path.exists(fp_input_path))
fp_input_path = os.path.abspath(fp_input_path)
fp_params = get_abacus_input_parameters(fp_input_path)
ret_input = make_abacus_scf_input(fp_params)
else:
raise RuntimeError("Key 'user_fp_params' and its value have to be specified in parameter json file.")
raise RuntimeError("Set 'user_fp_params' or 'fp_incar' in json file to make INPUT of ABACUS")
# get paramters for writting KPT file
if 'kspacing' not in fp_params.keys():
if 'gamma_only' in fp_params.keys():
if fp_params["gamma_only"]==1:
gamma_param = {"k_points":[1,1,1,0,0,0]}
ret_kpt = make_abacus_scf_kpt(gamma_param)
else:
if 'k_points' in jdata.keys() :
ret_kpt = make_abacus_scf_kpt(jdata)
elif 'fp_kpt_file' in jdata.keys():
fp_kpt_path = jdata['fp_kpt_file']
assert(os.path.exists(fp_kpt_path))
fp_kpt_path = os.path.abspath(fp_kpt_path)
fk = open(fp_kpt_path)
ret_kpt = fk.read()
fk.close()
else:
raise RuntimeError("Cannot find any k-points information")
else:
if 'k_points' in jdata.keys() :
ret_kpt = make_abacus_scf_kpt(jdata)
elif 'fp_kpt_file' in jdata.keys():
fp_kpt_path = jdata['fp_kpt_file']
assert(os.path.exists(fp_kpt_path))
fp_kpt_path = os.path.abspath(fp_kpt_path)
fk = open(fp_kpt_path)
ret_kpt = fk.read()
fk.close()
else:
gamma_param = {"k_points":[1,1,1,0,0,0]}
ret_kpt = make_abacus_scf_kpt(gamma_param)
warnings.warn("Cannot find k-points information, gamma_only will be generated.")

cwd = os.getcwd()
for ii in fp_tasks:
os.chdir(ii)
sys_data = dpdata.System('POSCAR').data
if 'mass_map' in jdata:
sys_data['atom_masses'] = jdata['mass_map']
ret_input = make_abacus_scf_input(fp_params)
with open('INPUT', 'w') as fp:
fp.write(ret_input)
ret_kpt = make_abacus_scf_kpt(fp_params)
with open("KPT", "w") as fp:
fp.write(ret_kpt)
if 'kspacing' not in fp_params.keys():
with open("KPT", "w") as fp:
fp.write(ret_kpt)
ret_stru = make_abacus_scf_stru(sys_data, fp_pp_files, fp_orb_files, fp_dpks_descriptor, fp_params)
with open("STRU", "w") as fp:
fp.write(ret_stru)
Expand Down Expand Up @@ -3022,7 +3063,35 @@ def run_fp (iter_index,
backward_files = ['output']
run_fp_inner(iter_index, jdata, mdata, forward_files, backward_files, _qe_check_fin, log_file = 'output')
elif fp_style == "abacus/scf":
forward_files = ["INPUT", "STRU", "KPT"] + fp_pp_files
fp_params = {}
if 'user_fp_params' in jdata.keys() :
fp_params = jdata['user_fp_params']
elif 'fp_incar' in jdata.keys():
fp_input_path = jdata['fp_incar']
assert(os.path.exists(fp_input_path))
fp_input_path = os.path.abspath(fp_input_path)
fp_params = get_abacus_input_parameters(fp_input_path)

forward_files = ["INPUT", "STRU"]
if 'kspacing' not in fp_params.keys():
if 'gamma_only' in fp_params.keys():
if type(fp_params["gamma_only"])==str:
fp_params["gamma_only"] = int(eval(fp_params["gamma_only"]))
assert(fp_params["gamma_only"] == 0 or fp_params["gamma_only"] == 1),\
"'gamma_only' should be either 0 or 1."
if fp_params["gamma_only"]==1:
forward_files += ["KPT"]
else:
if 'k_points' in jdata.keys() :
forward_files += ["KPT"]
elif 'fp_kpt_file' in jdata.keys():
forward_files += ["KPT"]
else:
raise RuntimeError("Cannot find any k-points information")
else:
forward_files += ["KPT"]
hongriTianqi marked this conversation as resolved.
Show resolved Hide resolved
forward_files += fp_pp_files

if "fp_orb_files" in jdata:
forward_files += jdata["fp_orb_files"]
if "fp_dpks_descriptor" in jdata:
Expand Down
22 changes: 22 additions & 0 deletions tests/generator/abacus/INPUT.diy
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
ntype 2
ecutwfc 80
scf_thr 1e-7
scf_nmax 50
basis_type pw
gamma_only 1
dft_functional pbe
mixing_type pulay
mixing_beta 0.4
symmetry 1
nbands 5
nspin 1
ks_solver cg
smearing_method fixed
smearing_sigma 0.001
cal_force 1
cal_stress 1
deepks_out_labels 0
deepks_descriptor_lmax 0
deepks_scf 0
deepks_model model.ptg
_kspacing 0.04
4 changes: 4 additions & 0 deletions tests/generator/abacus/KPT
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
K_POINTS
0
Gamma
2 2 2 0 0 0
1 change: 1 addition & 0 deletions tests/generator/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
param_pwmat_file = 'param-pyridine-pwmat.json'
param_abacus_file = 'param-pyridine-abacus.json'
param_abacus_post_file = 'param-methane-abacus.json'
param_diy_abacus_post_file = 'param-methane-abacus-diy.json'
param_amber_file = "param-amber.json"
param_multiple_trust_file = 'param-mg-vasp-multi-trust.json'

Expand Down
Loading