@@ -38,21 +38,25 @@ def dict_merge(dct, merge_dct):
3838 dct [k ] = merge_dct [k ]
3939
4040
41- def get_kinds_section (structure : StructureData , basis_pseudo : str , magnetization_tags = None ):
42- """ Write the &KIND sections given the structure and the settings_dict"""
41+ def get_kinds_section (structure : StructureData , basis_pseudo = None , magnetization_tags = None , use_sirius = False ):
42+ """Write the &KIND sections given the structure and the settings_dict. """
4343 kinds = []
44- with open (pathlib .Path (__file__ ).parent / basis_pseudo , 'rb' ) as fhandle :
45- atom_data = yaml .safe_load (fhandle )
44+ if not use_sirius :
45+ with open (pathlib .Path (__file__ ).parent / basis_pseudo , 'rb' ) as fhandle :
46+ atom_data = yaml .safe_load (fhandle )
4647 ase_structure = structure .get_ase ()
4748 symbol_tag = {
4849 (symbol , str (tag )) for symbol , tag in zip (ase_structure .get_chemical_symbols (), ase_structure .get_tags ())
4950 }
5051 for symbol , tag in symbol_tag :
5152 new_atom = {
5253 '_' : symbol if tag == '0' else symbol + tag ,
53- 'BASIS_SET' : atom_data ['basis_set' ][symbol ],
54- 'POTENTIAL' : atom_data ['pseudopotential' ][symbol ],
5554 }
55+ if use_sirius :
56+ new_atom ['POTENTIAL' ] = f'UPF { symbol } .json'
57+ else :
58+ new_atom ['BASIS_SET' ] = atom_data ['basis_set' ][symbol ]
59+ new_atom ['POTENTIAL' ] = atom_data ['pseudopotential' ][symbol ]
5660 if magnetization_tags :
5761 new_atom ['MAGNETIZATION' ] = magnetization_tags [tag ]
5862 kinds .append (new_atom )
@@ -126,6 +130,12 @@ def get_file_section():
126130 }
127131
128132
133+ def get_upf_pseudos_section (structure : StructureData , pseudo_family ):
134+ """Provide the pseudos section to the input."""
135+ pseudos_group = orm .load_group (pseudo_family )
136+ return pseudos_group .get_pseudos (structure = structure )
137+
138+
129139class Cp2kCommonRelaxInputGenerator (CommonRelaxInputGenerator ):
130140 """Input generator for the `Cp2kRelaxWorkChain`."""
131141
@@ -150,7 +160,7 @@ def define(cls, spec):
150160 super ().define (spec )
151161 spec .input (
152162 'protocol' ,
153- valid_type = ChoiceType (('fast' , 'moderate' , 'precise' , 'verification-pbe-v1' )),
163+ valid_type = ChoiceType (('fast' , 'moderate' , 'precise' , 'verification-pbe-v1' , 'verification-pbe-v1-sirius' )),
154164 default = 'moderate' ,
155165 help = 'The protocol to use for the automated input generation. This value indicates the level of precision '
156166 'of the results and computational cost that the input parameters will be selected for.' ,
@@ -190,52 +200,66 @@ def _construct_builder(self, **kwargs) -> engine.ProcessBuilder:
190200 kpoints_distance = protocol_dict .pop ('kpoints_distance' , None )
191201 kpoints = self ._get_kpoints (kpoints_distance , structure , reference_workchain )
192202 mesh , _ = kpoints .get_kpoints_mesh ()
193- if mesh != [1 , 1 , 1 ]:
203+ if 'sirius' in protocol :
204+ parameters ['FORCE_EVAL' ]['PW_DFT' ]['PARAMETERS' ]['NGRIDK' ] = f'{ mesh [0 ]} { mesh [1 ]} { mesh [2 ]} '
205+ elif mesh != [1 , 1 , 1 ]:
194206 builder .cp2k .kpoints = kpoints
195207
196208 magnetization_tags = None
197209
198210 # Metal or insulator.
199- # If metal then add smearing, unoccupied orbitals, and employ diagonalization.
200- if electronic_type == ElectronicType .METAL :
201- parameters ['FORCE_EVAL' ]['DFT' ]['SCF' ]['SMEAR' ] = {
202- '_' : 'ON' ,
203- 'METHOD' : 'FERMI_DIRAC' ,
204- 'ELECTRONIC_TEMPERATURE' : '[K] 710.5' ,
205- }
206- parameters ['FORCE_EVAL' ]['DFT' ]['SCF' ]['DIAGONALIZATION' ] = {
207- 'EPS_ADAPT' : '1' ,
208- }
209- parameters ['FORCE_EVAL' ]['DFT' ]['SCF' ]['MIXING' ] = {
210- 'METHOD' : 'BROYDEN_MIXING' ,
211- 'ALPHA' : '0.1' ,
212- 'BETA' : '1.5' ,
213- }
214- parameters ['FORCE_EVAL' ]['DFT' ]['SCF' ]['ADDED_MOS' ] = 20
215- parameters ['FORCE_EVAL' ]['DFT' ]['SCF' ]['CHOLESKY' ] = 'OFF'
216-
217- # If insulator then employ OT.
218- elif electronic_type == ElectronicType .INSULATOR :
219- parameters ['FORCE_EVAL' ]['DFT' ]['SCF' ]['OT' ] = {
220- 'PRECONDITIONER' : 'FULL_SINGLE_INVERSE' ,
221- 'MINIMIZER' : 'CG' ,
222- }
223-
224- # Magnetic calculation.
225- if spin_type == SpinType .NONE :
226- parameters ['FORCE_EVAL' ]['DFT' ]['UKS' ] = False
227- if magnetization_per_site is not None :
228- import warnings
229- warnings .warn ('`magnetization_per_site` will be ignored as `spin_type` is set to SpinType.NONE' )
230-
231- elif spin_type == SpinType .COLLINEAR :
232- parameters ['FORCE_EVAL' ]['DFT' ]['UKS' ] = True
233- structure , magnetization_tags = tags_and_magnetization (structure , magnetization_per_site )
234- parameters ['FORCE_EVAL' ]['DFT' ]['MULTIPLICITY' ] = guess_multiplicity (structure , magnetization_per_site )
211+ if 'sirius' not in protocol : # It is not possible to disable smearing for sirius.
212+ # If metal then add smearing, unoccupied orbitals, and employ diagonalization.
213+ if electronic_type == ElectronicType .METAL :
214+ parameters ['FORCE_EVAL' ]['DFT' ]['SCF' ]['SMEAR' ] = {
215+ '_' : 'ON' ,
216+ 'METHOD' : 'FERMI_DIRAC' ,
217+ 'ELECTRONIC_TEMPERATURE' : '[K] 710.5' ,
218+ }
219+ parameters ['FORCE_EVAL' ]['DFT' ]['SCF' ]['DIAGONALIZATION' ] = {
220+ 'EPS_ADAPT' : '1' ,
221+ }
222+ parameters ['FORCE_EVAL' ]['DFT' ]['SCF' ]['MIXING' ] = {
223+ 'METHOD' : 'BROYDEN_MIXING' ,
224+ 'ALPHA' : '0.1' ,
225+ 'BETA' : '1.5' ,
226+ }
227+ parameters ['FORCE_EVAL' ]['DFT' ]['SCF' ]['ADDED_MOS' ] = 20
228+ parameters ['FORCE_EVAL' ]['DFT' ]['SCF' ]['CHOLESKY' ] = 'OFF'
229+
230+ # If insulator then employ OT.
231+ elif electronic_type == ElectronicType .INSULATOR :
232+ parameters ['FORCE_EVAL' ]['DFT' ]['SCF' ]['OT' ] = {
233+ 'PRECONDITIONER' : 'FULL_SINGLE_INVERSE' ,
234+ 'MINIMIZER' : 'CG' ,
235+ }
236+
237+ # Magnetic calculation. Changing this configuration has no effect on sirius calculations.
238+ if spin_type == SpinType .NONE :
239+ parameters ['FORCE_EVAL' ]['DFT' ]['UKS' ] = False
240+ if magnetization_per_site is not None :
241+ import warnings
242+ warnings .warn ('`magnetization_per_site` will be ignored as `spin_type` is set to SpinType.NONE' )
243+
244+ elif spin_type == SpinType .COLLINEAR :
245+ parameters ['FORCE_EVAL' ]['DFT' ]['UKS' ] = True
246+ structure , magnetization_tags = tags_and_magnetization (structure , magnetization_per_site )
247+ parameters ['FORCE_EVAL' ]['DFT' ]['MULTIPLICITY' ] = guess_multiplicity (structure , magnetization_per_site )
235248
236249 # Starting magnetization.
237250 basis_pseudo = protocol_dict .pop ('basis_pseudo' )
238- dict_merge (parameters , get_kinds_section (structure , basis_pseudo , magnetization_tags ))
251+ if 'sirius' in protocol :
252+ dict_merge (
253+ parameters ,
254+ get_kinds_section (structure , basis_pseudo = None , magnetization_tags = magnetization_tags , use_sirius = True )
255+ )
256+ else :
257+ dict_merge (
258+ parameters ,
259+ get_kinds_section (
260+ structure , basis_pseudo = basis_pseudo , magnetization_tags = magnetization_tags , use_sirius = False
261+ )
262+ )
239263
240264 # Relaxation type.
241265 if relax_type == RelaxType .POSITIONS :
@@ -281,7 +305,10 @@ def _construct_builder(self, **kwargs) -> engine.ProcessBuilder:
281305 builder .handler_overrides = orm .Dict (dict = {'restart_incomplete_calculation' : True })
282306
283307 # Files.
284- builder .cp2k .file = get_file_section ()
308+ if 'sirius' in protocol :
309+ builder .cp2k .pseudos_upf = get_upf_pseudos_section (structure , basis_pseudo )
310+ else :
311+ builder .cp2k .file = get_file_section ()
285312
286313 # Input structure.
287314 builder .cp2k .structure = structure
0 commit comments