Source code for dpgen.generator.lib.make_calypso
#!/usr/bin/env python3
import os
import shutil
import json
import glob
import numpy as np
from dpgen.generator.lib.utils import create_path
[docs]def make_calypso_input(nameofatoms,numberofatoms,
numberofformula,volume,
distanceofion,psoratio,popsize,
maxstep,icode,split,vsc,
maxnumatom,ctrlrange,pstress,fmax):
ret = "################################ The Basic Parameters of CALYPSO ################################\n"
ret+= "# A string of one or several words contain a descriptive name of the system (max. 40 characters).\n"
assert nameofatoms is not None
ret+= "SystemName = %s\n"%(''.join(nameofatoms))
ret+= "# Number of different atomic species in the simulation.\n"
ret+= "NumberOfSpecies = %d\n"%(len(nameofatoms))
ret+= "# Element symbols of the different chemical species.\n"
ret+= "NameOfAtoms = %s\n"%(' '.join(nameofatoms))
ret+= "# Number of atoms for each chemical species in one formula unit. \n"
assert numberofatoms is not None and len(numberofatoms) == len(nameofatoms)
ret+= "NumberOfAtoms = %s\n"%(' '.join(list(map(str,numberofatoms))))
ret+= "# The range of formula unit per cell in your simulation. \n"
assert numberofformula is not None and len(numberofformula) == 2 and type(numberofformula) is list
ret+= "NumberOfFormula = %s\n"%(' '.join(list(map(str,numberofformula))))
ret+= "# The volume per formula unit. Unit is in angstrom^3.\n"
if volume is None:
ret+= "# volume not found, CALYPSO will set one!\n"
else:
ret+= "Volume = %s\n"%(volume)
ret+= "# Minimal distance between atoms of each chemical species. Unit is in angstrom.\n"
assert len(distanceofion) == len(nameofatoms) #"check distance of ions and the number of atoms"
assert len(distanceofion[0]) == len(nameofatoms)
ret+= "@DistanceOfIon \n"
for temp in distanceofion:
ret+="%4s \n"%(' '.join(list(map(str,temp))))
ret+= "@End\n"
ret+= "# It determines which algorithm should be adopted in the simulation.\n"
ret+= "Ialgo = 2\n"
ret+= "# Ialgo = 1 for Global PSO\n"
ret+= "# Ialgo = 2 for Local PSO (default value)\n"
ret+= "# The proportion of the structures generated by PSO.\n"
assert (0 <= psoratio <= 1 )
ret+= "PsoRatio = %s\n"%(psoratio)
ret+= "# The population size. Normally, it has a larger number for larger systems.\n"
assert popsize is not None and type(popsize) is int
ret+= "PopSize = %d\n"%(popsize)
assert maxstep is not None and type(maxstep) is int
ret+= "# The Max step for iteration\n"
ret+= "MaxStep = %d\n"%(maxstep)
ret+= "#It determines which method should be adopted in generation the random structure. \n"
ret+= "GenType= 1 \n"
ret+= "# 1 under symmetric constraints\n"
ret+= "# 2 grid method for large system\n"
ret+= "# 3 and 4 core grow method \n"
ret+= "# 0 combination of all method\n"
ret+= "# If GenType=3 or 4, it determined the small unit to grow the whole structure\n"
ret+= "# It determines which local optimization method should be interfaced in the simulation.\n"
assert icode is not None and type(icode) is int
ret+= "ICode= %d\n"%(icode)
ret+= "# ICode= 1 interfaced with VASP\n"
ret+= "# ICode= 2 interfaced with SIESTA\n"
ret+= "# ICode= 3 interfaced with GULP\n"
ret+= "# The number of lbest for local PSO\n"
ret+= "NumberOfLbest=4\n"
ret+= "# The Number of local optimization for each structure.\n"
ret+= "NumberOfLocalOptim= 3\n"
ret+= "# The command to perform local optimiztion calculation (e.g., VASP, SIESTA) on your computer.\n"
ret+= "Command = sh submit.sh\n"
ret+= "MaxTime = 9000 \n"
ret+= "# If True, a previous calculation will be continued.\n"
ret+= "PickUp = F\n"
ret+= "# At which step will the previous calculation be picked up.\n"
ret+= "PickStep = 1\n"
ret+= "# If True, the local optimizations performed by parallel\n"
ret+= "Parallel = F\n"
ret+= "# The number node for parallel \n"
ret+= "NumberOfParallel = 4\n"
assert split is not None
ret+= "Split = %s\n"%(split)
assert pstress is not None and (type(pstress) is int or type(pstress) is float)
ret+= "PSTRESS = %f\n"%(pstress)
assert fmax is not None or type(fmax) is float
ret+= "fmax = %f\n"%(fmax)
ret+= "################################ End of The Basic Parameters of CALYPSO #######################\n"
if vsc == 'T':
assert len(ctrlrange) == len(nameofatoms) #'check distance of ions and the number of atoms'
ret+= "##### The Parameters For Variational Stoichiometry ##############\n"
ret+= "## If True, Variational Stoichiometry structure prediction is performed\n"
ret+= "VSC = %s\n"%(vsc)
ret+= "# The Max Number of Atoms in unit cell\n"
ret+= "MaxNumAtom = %s\n"%(maxnumatom)
ret+= "# The Variation Range for each type atom \n"
ret+= "@CtrlRange\n"
for ttemp in ctrlrange:
ret+="%4s \n"%(' '.join(list(map(str,ttemp))))
ret+= "@end\n"
ret+= "###################End Parameters for VSC ##########################\n"
return ret
def _make_model_devi_buffet(jdata,calypso_run_opt_path):
calypso_input_path = jdata.get('calypso_input_path')
if jdata.get('vsc', False):
# [input.dat.Li.250, input.dat.Li.300]
one_ele_inputdat_list = list(
set(glob.glob(
f"{jdata.get('calypso_input_path')}/input.dat.{jdata.get('type_map')[0]}.*"
))
)
# [input.dat.La, input.dat.H, input.dat.LaH,] only one pressure
if len(one_ele_inputdat_list) == 0:
os.system(f"cp {calypso_input_path}/input.dat.* {calypso_run_opt_path[0]}")
# different pressure, 250GPa and 300GPa
# [input.dat.La.250, input.dat.H.250, input.dat.LaH.250, input.dat.La.300, input.dat.H.300, input.dat.LaH.300,]
else:
pressures_list = [temp.split('.')[-1] for temp in one_ele_inputdat_list]
pressures_list = list(map(int, pressures_list))
# calypso_run_opt_path = ['gen_struc_analy.000','gen_struc_analy.001']
for press_idx, temp_calypso_run_opt_path in enumerate(calypso_run_opt_path):
cur_press = pressures_list[press_idx]
os.system(f"cp {calypso_input_path}/input.dat.*.{cur_press} {temp_calypso_run_opt_path}")
elif not jdata.get('vsc', False):
shutil.copyfile(os.path.join(calypso_input_path,'input.dat'),os.path.join(calypso_run_opt_path[0], 'input.dat'))
if not os.path.exists(os.path.join(calypso_run_opt_path[0], 'input.dat')):
raise FileNotFoundError('input.dat')
def _make_model_devi_native_calypso(iter_index,model_devi_jobs, calypso_run_opt_path):
for iiidx, jobbs in enumerate(model_devi_jobs):
if iter_index in jobbs.get('times'):
cur_job = model_devi_jobs[iiidx]
work_path = os.path.dirname(calypso_run_opt_path[0])
# cur_job.json
with open(os.path.join(work_path, 'cur_job.json'), 'w') as outfile:
json.dump(cur_job, outfile, indent = 4)
# Crystal Parameters
nameofatoms = cur_job.get('NameOfAtoms')
numberofatoms = cur_job.get('NumberOfAtoms')
numberofformula = cur_job.get('NumberOfFormula',[1,1])
volume = cur_job.get('Volume')
distanceofion = cur_job.get('DistanceOfIon')
psoratio = cur_job.get('PsoRatio', 0.6)
popsize = cur_job.get('PopSize', 30)
maxstep = cur_job.get('MaxStep', 5)
icode = cur_job.get('ICode',1)
split = cur_job.get('Split','T')
# Cluster
# 2D
# VSC Control
maxnumatom = None
ctrlrange = None
vsc = cur_job.get('VSC','F')
if vsc == 'T':
maxnumatom = cur_job.get('MaxNumAtom')
ctrlrange = cur_job.get('CtrlRange')
# Optimization
fmax = cur_job.get('fmax',0.01)
# pstress is a List which contains the target stress
pstress = cur_job.get('PSTRESS',[0.001])
# pressures
for press_idx, temp_calypso_run_opt_path in enumerate(calypso_run_opt_path):
# cur_press
cur_press = pstress[press_idx]
file_c = make_calypso_input(nameofatoms,numberofatoms,
numberofformula,volume,
distanceofion,psoratio,popsize,
maxstep,icode,split,vsc,
maxnumatom,ctrlrange,cur_press,fmax)
with open(os.path.join(temp_calypso_run_opt_path, 'input.dat'), 'w') as cin :
cin.write(file_c)
[docs]def write_model_devi_out(devi, fname):
assert devi.shape[1] == 8
#assert devi.shape[1] == 7
header = '%5s' % 'step'
for item in 'vf':
header += '%16s%16s%16s' % (f'max_devi_{item}', f'min_devi_{item}',f'avg_devi_{item}')
header += '%16s'%str('min_dis')
np.savetxt(fname,
devi,
fmt=['%5d'] + ['%17.6e' for _ in range(7)],
delimiter='',
header=header)
return devi