import numpy as np
default_config = {
"GLOBAL": {"PROJECT": "DPGEN"},
"FORCE_EVAL": {
"METHOD": "QS",
"STRESS_TENSOR": "ANALYTICAL",
"DFT": {
"BASIS_SET_FILE_NAME": "./cp2k_basis_pp_file/BASIS_MOLOPT",
"POTENTIAL_FILE_NAME": "./cp2k_basis_pp_file/GTH_POTENTIALS",
"CHARGE": 0,
"UKS": "F",
"MULTIPLICITY": 1,
"MGRID": {"CUTOFF": 400, "REL_CUTOFF": 50, "NGRIDS": 4},
"QS": {"EPS_DEFAULT": "1.0E-12"},
"SCF": {"SCF_GUESS": "ATOMIC", "EPS_SCF": "1.0E-6", "MAX_SCF": 50},
"XC": {"XC_FUNCTIONAL": {"_": "PBE"}},
},
"SUBSYS": {
"CELL": {"A": "10 .0 .0", "B": ".0 10 .0", "C": ".0 .0 10"},
"COORD": {"@include": "coord.xyz"},
"KIND": {
"_": ["H", "C", "N"],
"POTENTIAL": ["GTH-PBE-q1", "GTH-PBE-q4", "GTH-PBE-q5"],
"BASIS_SET": ["DZVP-MOLOPT-GTH", "DZVP-MOLOPT-GTH", "DZVP-MOLOPT-GTH"],
},
},
"PRINT": {"FORCES": {"_": "ON"}, "STRESS_TENSOR": {"_": "ON"}},
},
}
[docs]
def update_dict(old_d, update_d):
"""A method to recursive update dict
:old_d: old dictionary
:update_d: some update value written in dictionary form.
"""
import collections.abc
for k, v in update_d.items():
if (
k in old_d
and isinstance(old_d[k], dict)
and isinstance(update_d[k], collections.abc.Mapping)
):
update_dict(old_d[k], update_d[k])
else:
old_d[k] = update_d[k]
[docs]
def iterdict(d, out_list, flag=None, indent=0):
"""
:doc: a recursive expansion of dictionary into cp2k input
:k: current key
:v: current value
:d: current dictionary under expansion
:flag: used to record dictionary state. if flag is None,
it means we are in top level dict. flag is a string.
:indent: intent for current section.
"""
for k, v in d.items():
k = str(k) # cast key into string
# if value is dictionary
if isinstance(v, dict):
# flag == None, it is now in top level section of cp2k
if flag is None:
out_list.append("&" + k)
out_list.append("&END " + k)
iterdict(v, out_list, k, indent + 2)
# flag is not None, now it has name of section
else:
index = out_list.index(" " * (indent - 2) + "&END " + flag)
out_list.insert(index, " " * indent + "&" + k + " #" + flag)
out_list.insert(index + 1, " " * indent + "&END " + k + " #" + flag)
# the flag now contains its parent section name, separed by "#".
iterdict(v, out_list, k + " #" + flag, indent + 2)
elif isinstance(v, list):
# print("we have encountered the repeat section!")
index = out_list.index(" " * (indent - 2) + "&" + flag)
# delete the current constructed repeat section
del out_list[index : index + 2]
# do a loop over key and corresponding list
k_tmp_list = []
v_list_tmp_list = []
for k_tmp, v_tmp in d.items():
k_tmp_list.append(str(k_tmp))
v_list_tmp_list.append(v_tmp)
for repeat_keyword in zip(*v_list_tmp_list):
out_list.insert(index, " " * (indent - 2) + "&" + flag)
out_list.insert(index + 1, " " * (indent - 2) + "&END " + flag)
for idx, k_tmp in enumerate(k_tmp_list):
if k_tmp == "_":
out_list[index] = (
" " * (indent - 2)
+ "&"
+ flag.split(" #")[0]
+ " "
+ repeat_keyword[idx]
)
else:
out_list.insert(
index + 1,
" " * (indent) + k_tmp + " " + repeat_keyword[idx],
)
break
else:
v = str(v)
if flag is None:
out_list.append(k + " " + v)
print(k, ":", v)
else:
if k == "_":
index = out_list.index(" " * (indent - 2) + "&" + flag)
out_list[index] = (
" " * (indent - 2) + "&" + flag.split(" #")[0] + " " + v
)
else:
index = out_list.index(" " * (indent - 2) + "&END " + flag)
out_list.insert(index, " " * indent + k + " " + v)
[docs]
def make_cp2k_xyz(sys_data):
# get structral information
atom_names = sys_data["atom_names"]
atom_types = sys_data["atom_types"]
# write coordinate to xyz file used by cp2k input
coord_list = sys_data["coords"][0]
u = np.array(atom_names)
atom_list = u[atom_types]
x = "\n"
for kind, coord in zip(atom_list, coord_list):
x += str(kind) + " " + str(coord[:])[1:-1] + "\n"
return x