7
7
from emmet .core .vasp .calc_types .enums import TaskType
8
8
9
9
from pymatgen .io .validation .common import BaseValidator , BasicValidator
10
- from pymatgen .io .validation .vasp_defaults import InputCategory
10
+ from pymatgen .io .validation .vasp_defaults import InputCategory , VaspParam
11
11
12
12
from typing import TYPE_CHECKING
13
13
@@ -116,7 +116,7 @@ def check(self) -> None:
116
116
simple_validator .check_parameter (
117
117
reasons = self .reasons ,
118
118
warnings = self .warnings ,
119
- input_tag = working_params .defaults [key ]. get ( "alias" ) or key ,
119
+ input_tag = working_params .defaults [key ][ "alias" ] ,
120
120
current_values = working_params .parameters [key ],
121
121
reference_values = working_params .valid_values [key ],
122
122
operations = working_params .defaults [key ]["operation" ],
@@ -125,9 +125,6 @@ def check(self) -> None:
125
125
severity = working_params .defaults [key ]["severity" ],
126
126
)
127
127
128
- if key == "LCHIMAG" :
129
- print (self .reasons )
130
-
131
128
class UpdateParameterValues :
132
129
"""
133
130
Update a set of parameters according to supplied rules and defaults.
@@ -148,24 +145,8 @@ class UpdateParameterValues:
148
145
to `GetParams` called `update_{tag}_params`. For example, the "dft plus u"
149
146
tag has an update function called `update_dft_plus_u_params`. If no such update method
150
147
exists, that tag is skipped.
151
-
152
- Attrs
153
- ---------
154
- _default_schema : dict[str,Any]
155
- The schema of an entry in the dict of default values (`self.defaults`).
156
- This pads any missing entries in the set of parameters defaults with
157
- sensible default values.
158
148
"""
159
149
160
- _default_schema : dict [str , Any ] = {
161
- "value" : None ,
162
- "tag" : None ,
163
- "operation" : None ,
164
- "comment" : None ,
165
- "tolerance" : 1.0e-4 ,
166
- "severity" : "reason" ,
167
- }
168
-
169
150
def __init__ (
170
151
self ,
171
152
parameters : dict [str , Any ],
@@ -203,7 +184,7 @@ def __init__(
203
184
"""
204
185
205
186
self .parameters = copy .deepcopy (parameters )
206
- self .defaults = { k : v . __dict__ () for k , v in defaults . items ()}
187
+ self .defaults = copy . deepcopy ( defaults )
207
188
self .input_set = input_set
208
189
self .vasp_version = vasp_version
209
190
self .structure = structure
@@ -238,9 +219,9 @@ def update_parameters_and_defaults(self) -> None:
238
219
# add defaults to parameters from the defaults as needed
239
220
self .add_defaults_to_parameters ()
240
221
241
- for key in self .defaults :
242
- for attr in self . _default_schema :
243
- self .defaults [key ][ attr ] = self . defaults [ key ]. get ( attr , self . _default_schema [ attr ] )
222
+ for key , v in self .defaults . items () :
223
+ if isinstance ( v , dict ) :
224
+ self .defaults [key ] = VaspParam ( ** { "name" : key , ** v } )
244
225
245
226
def add_defaults_to_parameters (self , valid_values_source : dict | None = None ) -> None :
246
227
"""
@@ -351,11 +332,12 @@ def update_precision_params(self) -> None:
351
332
"HIGH" : - 4e-4 ,
352
333
}
353
334
self .parameters ["ROPT" ] = [abs (value ) for value in self .parameters .get ("ROPT" , [ropt_default [cur_prec ]])]
354
- self .defaults ["ROPT" ] = {
355
- "value" : [abs (ropt_default [cur_prec ]) for _ in self .parameters ["ROPT" ]],
356
- "tag" : "startup" ,
357
- "operation" : ["<=" for _ in self .parameters ["ROPT" ]],
358
- }
335
+ self .defaults ["ROPT" ] = VaspParam (
336
+ name = "ROPT" ,
337
+ value = [abs (ropt_default [cur_prec ]) for _ in self .parameters ["ROPT" ]],
338
+ tag = "startup" ,
339
+ operation = ["<=" for _ in self .parameters ["ROPT" ]],
340
+ )
359
341
360
342
def update_misc_special_params (self ) -> None :
361
343
"""Update miscellaneous parameters that do not fall into another category."""
@@ -383,11 +365,7 @@ def update_misc_special_params(self) -> None:
383
365
384
366
# LCORR.
385
367
if self .parameters ["IALGO" ] != 58 :
386
- self .defaults ["LCORR" ].update (
387
- {
388
- "operation" : "==" ,
389
- }
390
- )
368
+ self .defaults ["LCORR" ]["operation" ] = "=="
391
369
392
370
if (
393
371
self .parameters ["ISPIN" ] == 2
@@ -470,15 +448,16 @@ def update_fft_params(self) -> None:
470
448
for key in grid_keys :
471
449
self .valid_values [key ] = int (self .valid_values [key ] * self ._fft_grid_tolerance )
472
450
473
- self .defaults [key ] = {
474
- "value" : self .valid_values [key ],
475
- "tag" : "fft" ,
476
- "operation" : ">=" ,
477
- "comment" : (
451
+ self .defaults [key ] = VaspParam (
452
+ name = key ,
453
+ value = self .valid_values [key ],
454
+ tag = "fft" ,
455
+ operation = ">=" ,
456
+ comment = (
478
457
"This likely means the number FFT grid points was modified by the user. "
479
458
"If not, please create a GitHub issue."
480
459
),
481
- }
460
+ )
482
461
483
462
def update_density_mixing_params (self ) -> None :
484
463
"""
@@ -586,16 +565,17 @@ def update_smearing_params(self, bandgap_tol=1.0e-4) -> None:
586
565
self .parameters ["ELECTRONIC ENTROPY" ] = round (self .parameters ["ELECTRONIC ENTROPY" ] * convert_eV_to_meV , 3 )
587
566
self .valid_values ["ELECTRONIC ENTROPY" ] = 0.001 * convert_eV_to_meV
588
567
589
- self .defaults ["ELECTRONIC ENTROPY" ] = {
590
- "value" : 0.0 ,
591
- "tag" : "smearing" ,
592
- "comment" : (
568
+ self .defaults ["ELECTRONIC ENTROPY" ] = VaspParam (
569
+ name = "ELECTRONIC ENTROPY" ,
570
+ value = 0.0 ,
571
+ tag = "smearing" ,
572
+ comment = (
593
573
"The entropy term (T*S) in the energy is suggested to be less than "
594
574
f"{ round (self .valid_values ['ELECTRONIC ENTROPY' ], 1 )} meV/atom "
595
575
f"in the VASP wiki. Thus, SIGMA should be decreased."
596
576
),
597
- " operation" : "<=" ,
598
- }
577
+ operation = "<=" ,
578
+ )
599
579
600
580
def _get_default_nbands (self ):
601
581
"""
@@ -673,16 +653,17 @@ def update_electronic_params(self):
673
653
674
654
# NBANDS.
675
655
min_nbands = int (np .ceil (self ._NELECT / 2 ) + 1 )
676
- self .defaults ["NBANDS" ] = {
677
- "value" : self ._get_default_nbands (),
678
- "operation" : [">=" , "<=" ],
679
- "tag" : "electronic" ,
680
- "comment" : (
656
+ self .defaults ["NBANDS" ] = VaspParam (
657
+ name = "NBANDS" ,
658
+ value = self ._get_default_nbands (),
659
+ tag = "electronic" ,
660
+ operation = [">=" , "<=" ],
661
+ comment = (
681
662
"Too many or too few bands can lead to unphysical electronic structure "
682
663
"(see https://github.com/materialsproject/custodian/issues/224 "
683
664
"for more context.)"
684
- ),
685
- }
665
+ )
666
+ )
686
667
self .valid_values ["NBANDS" ] = [min_nbands , 4 * self .defaults ["NBANDS" ]["value" ]]
687
668
self .parameters ["NBANDS" ] = [self .parameters ["NBANDS" ] for _ in range (2 )]
688
669
@@ -734,10 +715,7 @@ def update_ionic_params(self):
734
715
# every MP-compliant input set, but often have comparable or even better results) will also be accepted
735
716
# I am **NOT** confident that this should be the final check. Perhaps I need convincing (or perhaps it does indeed need to be changed...)
736
717
# TODO: -somehow identify if a material is a vdW structure, in which case force-convergence should maybe be more strict?
737
- self .defaults ["EDIFFG" ] = {
738
- "value" : 10 * self .valid_values ["EDIFF" ],
739
- "category" : "ionic" ,
740
- }
718
+ self .defaults ["EDIFFG" ] = VaspParam (name = "EDIFFG" , value = 10 * self .valid_values ["EDIFF" ], tag = "ionic" )
741
719
742
720
self .valid_values ["EDIFFG" ] = self .input_set .incar .get ("EDIFFG" , self .defaults ["EDIFFG" ]["value" ])
743
721
self .defaults ["EDIFFG" ][
0 commit comments