2
2
import numpy as np
3
3
from emmet .core .vasp .calc_types .enums import TaskType
4
4
5
+ _vasp_defaults = {
6
+ "AEXX" : 0.0 ,
7
+ "AGGAC" : 1.0 ,
8
+ "AGGAX" : 1.0 ,
9
+ "ALDAX" : 1.0 ,
10
+ "AMGGAX" : 1.0 ,
11
+ "ALDAC" : 1.0 ,
12
+ "AMGGAC" : 1.0 ,
13
+ "DEPER" : 0.3 ,
14
+ "EBREAK" : 0.0 ,
15
+ "GGA_COMPAT" : True ,
16
+ "ICHARG" : 2 ,
17
+ "ICORELEVEL" : 0 ,
18
+ "IMAGES" : 0 ,
19
+ "INIWAV" : 1 ,
20
+ "ISTART" : 0 ,
21
+ "IVDW" : 0 ,
22
+ "LASPH" : True ,
23
+ "LBERRY" : False ,
24
+ "LCALCEPS" : False ,
25
+ "LCALCPOL" : False ,
26
+ "LDAU" : False ,
27
+ "LDAUU" : [],
28
+ "LDAUJ" : [],
29
+ "LDAUL" : [],
30
+ "LDAUTYPE" : 2 ,
31
+ "LEPSILON" : False ,
32
+ "LHFCALC" : False ,
33
+ "LHYPERFINE" : False ,
34
+ "LKPOINTS_OPT" : False ,
35
+ "LKPROJ" : False ,
36
+ "LMP2LT" : False ,
37
+ "LNONCOLLINEAR" : False ,
38
+ "LOCPROJ" : None ,
39
+ "LRPA" : False ,
40
+ "LSMP2LT" : False ,
41
+ "LSORBIT" : False ,
42
+ "LSPECTRAL" : False ,
43
+ "LSUBROT" : False ,
44
+ "ML_LMLFF" : False ,
45
+ "WEIMIN" : 0.001 ,
46
+ }
47
+
48
+ _categories = {
49
+ "hybrid" : ("AEXX" , "AGGAC" , "AGGAX" , "ALDAX" , "AMGGAX" , "ALDAC" , "AMGGAC" , "LHFCALC" ),
50
+ "ldau" : ("LDAUU" , "LDAUJ" , "LDAUL" , "LDAUTYPE" ),
51
+ "misc" : (
52
+ "DEPER" ,
53
+ "IMAGES" ,
54
+ "IVDW" ,
55
+ "LSPECTRAL" ,
56
+ "LHYPERFINE" ,
57
+ "LASPH" ,
58
+ "LKPOINTS_OPT" ,
59
+ "LRPA" ,
60
+ "LCALCEPS" ,
61
+ "EBREAK" ,
62
+ "LOCPROJ" ,
63
+ "GGA_COMPAT" ,
64
+ "LEPSILON" ,
65
+ "LKPROJ" ,
66
+ "ICORELEVEL" ,
67
+ "ML_LMLFF" ,
68
+ "LSUBROT" ,
69
+ "LMP2LT" ,
70
+ "LBERRY" ,
71
+ "LSMP2LT" ,
72
+ "LCALCPOL" ,
73
+ ),
74
+ "ncl" : ("LNONCOLLINEAR" , "LSORBIT" ),
75
+ }
76
+
5
77
6
78
def _check_incar (
7
79
reasons ,
@@ -324,16 +396,8 @@ def _check_fft_params(
324
396
def _check_hybrid_functional_params (reasons , parameters , valid_input_set ):
325
397
valid_lhfcalc = valid_input_set .incar .get ("LHFCALC" , False )
326
398
327
- default_values = {
328
- "AEXX" : 0.0 ,
329
- "AGGAC" : 1.0 ,
330
- "AGGAX" : 1.0 ,
331
- "ALDAX" : 1.0 ,
332
- "AMGGAX" : 1.0 ,
333
- "ALDAC" : 1.0 ,
334
- "AMGGAC" : 1.0 ,
335
- "LHFCALC" : False ,
336
- }
399
+ default_values = {key : _vasp_defaults [key ] for key in _categories ["hybrid" ]}
400
+
337
401
if valid_lhfcalc :
338
402
default_values ["AEXX" ] = 0.25
339
403
default_values ["AGGAC" ] = 0.0
@@ -344,13 +408,13 @@ def _check_hybrid_functional_params(reasons, parameters, valid_input_set):
344
408
default_values ["ALDAC" ] = 0.0
345
409
default_values ["AMGGAC" ] = 0.0
346
410
347
- for hybrid_key in default_values :
411
+ for key in _categories [ "hybrid" ] :
348
412
_check_required_params (
349
413
reasons ,
350
414
parameters ,
351
- hybrid_key ,
352
- default_values [hybrid_key ],
353
- valid_input_set .incar .get (hybrid_key , default_values [hybrid_key ]),
415
+ key ,
416
+ default_values [key ],
417
+ valid_input_set .incar .get (key , default_values [key ]),
354
418
allow_close = True ,
355
419
)
356
420
@@ -560,15 +624,14 @@ def _check_lmaxmix_and_lmaxtau(reasons, warnings, parameters, incar, valid_input
560
624
561
625
562
626
def _check_magnetism_params (reasons , parameters , valid_input_set ):
563
- # LNONCOLLINEAR.
564
- default_lnoncollinear = False
565
- valid_lnoncollinear = valid_input_set .incar .get ("LNONCOLLINEAR" , default_lnoncollinear )
566
- _check_required_params (reasons , parameters , "LNONCOLLINEAR" , default_lnoncollinear , valid_lnoncollinear )
567
-
568
- # LSORBIT.
569
- default_lsorbit = False
570
- valid_lsorbit = valid_input_set .incar .get ("LSORBIT" , default_lsorbit )
571
- _check_required_params (reasons , parameters , "LSORBIT" , default_lsorbit , valid_lsorbit )
627
+ for key in _categories ["ncl" ]:
628
+ _check_required_params (
629
+ reasons ,
630
+ parameters ,
631
+ key ,
632
+ _vasp_defaults [key ],
633
+ valid_input_set .incar .get ("LNONCOLLINEAR" , _vasp_defaults [key ]),
634
+ )
572
635
573
636
574
637
def _check_misc_params (
@@ -582,106 +645,46 @@ def _check_misc_params(
582
645
vasp_minor_version ,
583
646
structure ,
584
647
):
585
- # DEPER.
586
- valid_deper = valid_input_set .incar .get ("DEPER" , 0.3 )
587
- _check_required_params (reasons , parameters , "DEPER" , 0.3 , valid_deper , allow_close = True )
588
-
589
- # EBREAK.
590
- valid_ebreak = valid_input_set .incar .get ("EBREAK" , 0.0 )
591
- _check_required_params (reasons , parameters , "EBREAK" , 0.0 , valid_ebreak , allow_close = True )
592
-
593
- # GGA_COMPAT.
594
- valid_gga_compat = valid_input_set .incar .get ("GGA_COMPAT" , True )
595
- _check_required_params (reasons , parameters , "GGA_COMPAT" , True , valid_gga_compat )
596
-
597
- # ICORELEVEL.
598
- valid_icorelevel = valid_input_set .incar .get ("ICORELEVEL" , 0 )
599
- _check_required_params (reasons , parameters , "ICORELEVEL" , 0 , valid_icorelevel )
600
-
601
- # IMAGES.
602
- valid_images = valid_input_set .incar .get ("IMAGES" , 0 )
603
- _check_required_params (reasons , parameters , "IMAGES" , 0 , valid_images )
604
-
605
- # IVDW.
606
- valid_ivdw = valid_input_set .incar .get ("IVDW" , 0 )
607
- _check_required_params (reasons , parameters , "IVDW" , 0 , valid_ivdw )
608
-
609
- # LBERRY.
610
- valid_lberry = valid_input_set .incar .get ("LBERRY" , False )
611
- _check_required_params (reasons , parameters , "LBERRY" , False , valid_lberry )
612
-
613
- # LCALCEPS.
614
- valid_lcalceps = valid_input_set .incar .get ("LCALCEPS" , False )
615
- _check_required_params (reasons , parameters , "LCALCEPS" , False , valid_lcalceps )
616
-
617
- # LCALCPOL.
618
- valid_lcalcpol = valid_input_set .incar .get ("LCALCPOL" , False )
619
- _check_required_params (reasons , parameters , "LCALCPOL" , False , valid_lcalcpol )
620
-
621
- # LEPSILON.
622
- valid_lepsilon = valid_input_set .incar .get ("LEPSILON" , False )
623
- _check_required_params (reasons , parameters , "LEPSILON" , False , valid_lepsilon )
624
-
625
- # LHYPERFINE.
626
- valid_lhyperfine = valid_input_set .incar .get ("LHYPERFINE" , False )
627
- _check_required_params (reasons , parameters , "LHYPERFINE" , False , valid_lhyperfine )
628
-
629
- # LKPOINTS_OPT.
630
- valid_lkpoints_opt = valid_input_set .incar .get ("LKPOINTS_OPT" , False )
631
- _check_required_params (reasons , parameters , "LKPOINTS_OPT" , False , valid_lkpoints_opt )
632
-
633
- # LKPROJ.
634
- valid_lkproj = valid_input_set .incar .get ("LKPROJ" , False )
635
- _check_required_params (reasons , parameters , "LKPROJ" , False , valid_lkproj )
636
-
637
- # LMP2LT.
638
- valid_lmp2lt = valid_input_set .incar .get ("LMP2LT" , False )
639
- _check_required_params (reasons , parameters , "LMP2LT" , False , valid_lmp2lt )
640
-
641
- # LOCPROJ.
642
- valid_locproj = valid_input_set .incar .get ("LOCPROJ" , None )
643
- _check_required_params (reasons , parameters , "LOCPROJ" , None , valid_locproj )
644
-
645
- # LRPA.
646
- valid_lrpa = valid_input_set .incar .get ("LRPA" , False )
647
- _check_required_params (reasons , parameters , "LRPA" , False , valid_lrpa )
648
-
649
- # LSMP2LT.
650
- valid_lsmp2lt = valid_input_set .incar .get ("LSMP2LT" , False )
651
- _check_required_params (reasons , parameters , "LSMP2LT" , False , valid_lsmp2lt )
652
-
653
- # LSPECTRAL.
654
- valid_lspectral = valid_input_set .incar .get ("LSPECTRAL" , False )
655
- _check_required_params (reasons , parameters , "LSPECTRAL" , False , valid_lspectral )
656
-
657
- # LSUBROT.
658
- valid_lsubrot = valid_input_set .incar .get ("LSUBROT" , False )
659
- _check_required_params (reasons , parameters , "LSUBROT" , False , valid_lsubrot )
660
-
661
- # ML_LMLFF.
662
- valid_ml_lmlff = valid_input_set .incar .get ("ML_LMLFF" , False )
663
- _check_required_params (reasons , parameters , "ML_LMLFF" , False , valid_ml_lmlff )
648
+ for key in _categories ["misc" ]:
649
+ valid_deper = valid_input_set .incar .get (key , _vasp_defaults [key ])
650
+ _check_required_params (
651
+ reasons ,
652
+ parameters ,
653
+ key ,
654
+ _vasp_defaults [key ],
655
+ valid_deper ,
656
+ allow_close = False if isinstance (key , int ) else True ,
657
+ )
664
658
665
659
# WEIMIN.
666
- valid_weimin = valid_input_set .incar .get ("WEIMIN" , 0.001 )
667
- _check_relative_params (reasons , parameters , "WEIMIN" , 0.001 , valid_weimin , "less than or equal to" )
660
+ _check_relative_params (
661
+ reasons ,
662
+ parameters ,
663
+ "WEIMIN" ,
664
+ _vasp_defaults ["WEIMIN" ],
665
+ valid_input_set .incar .get ("WEIMIN" , _vasp_defaults ["WEIMIN" ]),
666
+ "less than or equal to" ,
667
+ )
668
668
669
- # EFERMI. Only available for VASP >= 6.4. Should not be set to a numerical value, as this may change the number of electrons.
669
+ """
670
+ EFERMI. Only available for VASP >= 6.4. Should not be set to a numerical
671
+ value, as this may change the number of electrons.
672
+ """
670
673
if (vasp_major_version >= 6 ) and (vasp_minor_version >= 4 ):
671
- # must check EFERMI in the *incar*, as it is saved as a numerical value after VASP guesses it in the vasprun.xml `parameters`
672
- # (which would always cause this check to fail, even if the user set EFERMI properly in the INCAR).
674
+ """
675
+ Must check EFERMI in the *incar*, as it is saved as a numerical
676
+ value after VASP guesses it in the vasprun.xml `parameters`
677
+ (which would always cause this check to fail, even if the user
678
+ set EFERMI properly in the INCAR).
679
+ """
673
680
cur_efermi = incar .get ("EFERMI" , "LEGACY" )
674
681
allowed_efermis = ["LEGACY" , "MIDGAP" ]
675
682
if cur_efermi not in allowed_efermis :
676
683
reasons .append (f"INPUT SETTINGS --> EFERMI: should be one of { allowed_efermis } ." )
677
684
678
685
# IWAVPR.
679
686
if "IWAVPR" in incar .keys ():
680
- reasons .append ("INPUT SETTINGS --> VASP discourages users from setting the IWAVPR tag (as of July 2023)." )
681
-
682
- # LASPH.
683
- valid_lasph = valid_input_set .incar .get ("LASPH" , True )
684
- _check_required_params (reasons , parameters , "LASPH" , False , valid_lasph )
687
+ reasons .append ("INPUT SETTINGS --> VASP discourages users from setting " "the IWAVPR tag (as of July 2023)." )
685
688
686
689
# LCORR.
687
690
cur_ialgo = parameters .get ("IALGO" , 38 )
@@ -693,7 +696,9 @@ def _check_misc_params(
693
696
# cur_lorbit = incar.get("LORBIT") if "LORBIT" in incar.keys() else parameters.get("LORBIT", None)
694
697
if (cur_ispin == 2 ) and (len (calcs_reversed [0 ]["output" ]["outcar" ]["magnetization" ]) != structure .num_sites ):
695
698
reasons .append (
696
- "INPUT SETTINGS --> LORBIT: magnetization values were not written to the OUTCAR. This is usually due to LORBIT being set to None or False for calculations with ISPIN=2."
699
+ "INPUT SETTINGS --> LORBIT: magnetization values were not written "
700
+ "to the OUTCAR. This is usually due to LORBIT being set to None or "
701
+ "False for calculations with ISPIN=2."
697
702
)
698
703
699
704
if parameters .get ("LORBIT" , - np .inf ) >= 11 and parameters .get ("ISYM" , 2 ) and (vasp_major_version < 6 ):
@@ -704,15 +709,15 @@ def _check_misc_params(
704
709
)
705
710
706
711
# RWIGS.
707
- if True in (
712
+ if any (
708
713
x != - 1.0 for x in parameters .get ("RWIGS" , [- 1 ])
709
714
): # do not allow RWIGS to be changed, as this affects outputs like the magmom on each atom
710
715
reasons .append (
711
716
"INPUT SETTINGS --> RWIGS: should not be set. This is because it will change some outputs like the magmom on each site."
712
717
)
713
718
714
719
# VCA.
715
- if True in (x != 1.0 for x in parameters .get ("VCA" , [1 ])): # do not allow VCA calculations
720
+ if any (x != 1.0 for x in parameters .get ("VCA" , [1 ])): # do not allow VCA calculations
716
721
reasons .append ("INPUT SETTINGS --> VCA: should not be set" )
717
722
718
723
@@ -751,21 +756,22 @@ def _check_precision_params(reasons, parameters, valid_input_set):
751
756
752
757
def _check_startup_params (reasons , parameters , incar , valid_input_set ):
753
758
# ICHARG.
754
- if valid_input_set .incar .get ("ICHARG" , 2 ) < 10 :
759
+ if valid_input_set .incar .get ("ICHARG" , _vasp_defaults [ "ICHARG" ] ) < 10 :
755
760
valid_icharg = 9 # should be <10 (SCF calcs)
756
- _check_relative_params (reasons , parameters , "ICHARG" , 2 , valid_icharg , "less than or equal to" )
761
+ _check_relative_params (
762
+ reasons , parameters , "ICHARG" , _vasp_defaults ["ICHARG" ], valid_icharg , "less than or equal to"
763
+ )
757
764
else :
758
765
valid_icharg = valid_input_set .incar .get ("ICHARG" )
759
- _check_required_params (reasons , parameters , "ICHARG" , 2 , valid_icharg )
766
+ _check_required_params (reasons , parameters , "ICHARG" , _vasp_defaults [ "ICHARG" ] , valid_icharg )
760
767
761
768
# INIWAV.
762
- default_iniwav = 1
763
- valid_iniwav = valid_input_set .incar .get ("INIWAV" , default_iniwav )
764
- _check_required_params (reasons , parameters , "INIWAV" , default_iniwav , valid_iniwav )
769
+ valid_iniwav = valid_input_set .incar .get ("INIWAV" , _vasp_defaults ["INIWAV" ])
770
+ _check_required_params (reasons , parameters , "INIWAV" , _vasp_defaults ["INIWAV" ], valid_iniwav )
765
771
766
772
# ISTART.
767
773
valid_istarts = [0 , 1 , 2 ]
768
- _check_allowed_params (reasons , parameters , "ISTART" , 0 , valid_istarts )
774
+ _check_allowed_params (reasons , parameters , "ISTART" , _vasp_defaults [ "ISTART" ] , valid_istarts )
769
775
770
776
771
777
def _check_symmetry_params (reasons , parameters , valid_input_set ):
@@ -801,30 +807,20 @@ def _check_symmetry_params(reasons, parameters, valid_input_set):
801
807
802
808
803
809
def _check_u_params (reasons , incar , parameters , valid_input_set ):
804
- if parameters .get ("LDAU" , False ):
805
- valid_ldauu = valid_input_set .incar .get ("LDAUU" , [])
806
- cur_ldauu = incar .get ("LDAUU" , [])
807
- if cur_ldauu != valid_ldauu :
808
- reasons .append (f"INPUT SETTINGS --> LDAUU: set to { cur_ldauu } , but should be set to { valid_ldauu } ." )
809
-
810
- valid_ldauj = valid_input_set .incar .get ("LDAUJ" , [])
811
- cur_ldauj = incar .get ("LDAUJ" , [])
812
- if cur_ldauj != valid_ldauj :
813
- reasons .append (f"INPUT SETTINGS --> LDAUJ: set to { cur_ldauj } , but should be set to { valid_ldauj } ." )
814
-
815
- valid_ldaul = valid_input_set .incar .get ("LDAUL" , [])
816
- cur_ldaul = incar .get ("LDAUL" , [])
817
- if cur_ldaul != valid_ldaul :
818
- reasons .append (f"INPUT SETTINGS --> LDAUL: set to { cur_ldaul } , but should be set to { valid_ldaul } ." )
819
-
820
- valid_ldautype = valid_input_set .incar .get ("LDAUTYPE" , [2 ])
821
- if isinstance (valid_ldautype , list ):
822
- valid_ldautype = valid_ldautype [0 ]
823
- cur_ldautype = parameters .get ("LDAUTYPE" , [2 ])[0 ]
824
- if cur_ldautype != valid_ldautype :
825
- reasons .append (
826
- f"INPUT SETTINGS --> LDAUTYPE: set to { cur_ldautype } , but should be set to { valid_ldautype } ."
827
- )
810
+ if parameters .get ("LDAU" , _vasp_defaults ["LDAU" ]):
811
+ for key in _categories ["ldau" ]:
812
+ valid_val = valid_input_set .incar .get (key , _vasp_defaults [key ])
813
+
814
+ # TODO: ADK: is LDAUTYPE usually specified as a list??
815
+ if key == "LDAUTYPE" :
816
+ cur_val = parameters .get (key , _vasp_defaults [key ])
817
+ cur_val = cur_val [0 ] if isinstance (cur_val , list ) else cur_val
818
+ valid_val = valid_val [0 ] if isinstance (valid_val , list ) else valid_val
819
+ else :
820
+ cur_val = incar .get (key , _vasp_defaults [key ])
821
+
822
+ if cur_val != valid_val :
823
+ reasons .append (f"INPUT SETTINGS --> { key } : set to { cur_val } , " f"but should be set to { valid_val } ." )
828
824
829
825
830
826
def _check_write_params (reasons , parameters , valid_input_set ):
@@ -855,7 +851,7 @@ def _check_required_params(
855
851
):
856
852
cur_val = parameters .get (input_tag , default_val )
857
853
858
- if allow_close and isinstance (cur_val , ( int , float ) ):
854
+ if allow_close and isinstance (cur_val , float ):
859
855
if not np .isclose (cur_val , required_val , rtol = 1e-05 , atol = 1e-05 ): # need to be careful of this
860
856
msg = f"INPUT SETTINGS --> { input_tag } : set to { cur_val } , but should be { required_val } ."
861
857
if extra_comments_upon_failure != "" :
0 commit comments