Ejemplo n.º 1
0
def test_vasp_parameter_override(init_relax_parameters):
    """Test of the override functionality works as intended."""
    init_relax_parameters[_DEFAULT_OVERRIDE_NAMESPACE] = AttributeDict()
    # Redefine to from 3 to 0.
    init_relax_parameters[_DEFAULT_OVERRIDE_NAMESPACE].isif = 0
    massager = ParametersMassage(init_relax_parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].isif == 0
Ejemplo n.º 2
0
def test_relax_parameters_shape(init_relax_parameters):
    """Test only shape relaxation."""
    del init_relax_parameters.relax.volume
    del init_relax_parameters.relax.positions
    massager = ParametersMassage(init_relax_parameters)
    parameters = massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE]
    assert parameters.isif == 5
Ejemplo n.º 3
0
def test_allowed_namespaces(init_relax_parameters):
    """Test if the massager raise exception if an unsupported namespace is supplied."""
    init_relax_parameters.not_allowed_namespace = 0.1
    matching_string = re.compile(
        r'^The supplied namespace: not_allowed_namespace is not supported.$')
    with pytest.raises(ValueError, match=matching_string):
        _ = ParametersMassage(init_relax_parameters)
Ejemplo n.º 4
0
def test_relax_parameters_cutoff(init_relax_parameters):
    """Test no provided cutoff yields no set ediffg."""
    del init_relax_parameters.relax.force_cutoff
    massager = ParametersMassage(init_relax_parameters)
    parameters = massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE]
    with pytest.raises(AttributeError):
        _ = parameters.ediffg
Ejemplo n.º 5
0
def test_skip_parameters_validate():  # pylint: disable=invalid-name
    """Test that it is possibly to completely by-pass parameters checking."""
    parameters = AttributeDict()
    parameters[_DEFAULT_OVERRIDE_NAMESPACE] = AttributeDict()
    parameters[_DEFAULT_OVERRIDE_NAMESPACE].not_valid = 200
    massager = ParametersMassage(parameters, skip_parameters_validation=True)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].not_valid == 200
Ejemplo n.º 6
0
def test_relax_parameters_nothing(init_relax_parameters):
    """Test if no relaxation parameters for volume, positions and shape are given."""
    del init_relax_parameters.relax.volume
    del init_relax_parameters.relax.positions
    del init_relax_parameters.relax.shape
    massager = ParametersMassage(init_relax_parameters)
    parameters = massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE]
    assert parameters == AttributeDict()
Ejemplo n.º 7
0
def test_pwcutoff_to_encut():
    """Test that the pwcutoff is converted to encut."""
    parameters = AttributeDict()
    parameters.electronic = AttributeDict()
    parameters.electronic.pwcutoff = 200
    massager = ParametersMassage(parameters)
    assert massager.parameters[
        _DEFAULT_OVERRIDE_NAMESPACE].encut == parameters.electronic.pwcutoff
Ejemplo n.º 8
0
def test_relax_parameters_all_set(init_relax_parameters):
    """Test all standard relaxation parameters are set."""
    massager = ParametersMassage(init_relax_parameters)
    parameters = massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE]
    assert parameters.ediffg == -0.01
    assert parameters.ibrion == 2
    assert parameters.nsw == 60
    assert parameters.isif == 3
Ejemplo n.º 9
0
def test_relax_multiple_cutoffs(init_relax_parameters):
    """Test if the massager raise exception if both energy and force cutoff is supplied."""
    init_relax_parameters.relax.energy_cutoff = 0.01
    matching_string = re.compile(
        r'^User supplied both a force and an energy cutoff for the relaxation. Please select.$'
    )
    with pytest.raises(ValueError, match=matching_string):
        _ = ParametersMassage(init_relax_parameters)
Ejemplo n.º 10
0
def test_unsupported_fail_override():
    """Test that any supplied unsupported parameters in the regular parameters dictionary yield error."""
    parameters = AttributeDict()
    parameters[_DEFAULT_OVERRIDE_NAMESPACE] = AttributeDict()
    parameters[_DEFAULT_OVERRIDE_NAMESPACE].not_valid = 200
    matching_string = re.compile(
        r'^The supplied key: not_valid is not a support VASP parameter.$')
    with pytest.raises(ValueError, match=matching_string):
        _ = ParametersMassage(parameters)
Ejemplo n.º 11
0
def test_catch_invalid_tags(init_relax_parameters):
    """Test to see if the massager accepts an invalid tag."""
    init_relax_parameters[_DEFAULT_OVERRIDE_NAMESPACE] = AttributeDict()
    init_relax_parameters[
        _DEFAULT_OVERRIDE_NAMESPACE].smear = 1  # This is an invalid tag
    matching_string = re.compile(
        r'^The supplied key: smear is not a support VASP parameter.$')
    with pytest.raises(ValueError, match=matching_string):
        _ = ParametersMassage(init_relax_parameters)
Ejemplo n.º 12
0
def test_smearing_parameters():
    """Test smearing parameters."""
    parameters = AttributeDict()
    parameters.smearing = AttributeDict()
    parameters.smearing.gaussian = True
    massager = ParametersMassage(parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].ismear == 0
    parameters.smearing.gaussian = False
    parameters.smearing.fermi = True
    massager = ParametersMassage(parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].ismear == -1
    parameters.smearing.fermi = False
    parameters.smearing.tetra = True
    massager = ParametersMassage(parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].ismear == -5
    parameters.smearing.tetra = False
    parameters.smearing.mp = 4
    massager = ParametersMassage(parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].ismear == 4
Ejemplo n.º 13
0
def test_parameters_override(init_relax_parameters):
    """Test what happens if we override a parameters."""
    value = 1  # should from init_relax_parameters be 3, verified in test_relax_parameters_all_set
    init_relax_parameters[_DEFAULT_OVERRIDE_NAMESPACE] = AttributeDict()
    # Add this override to the incar namespace which is considered the override namespace before reaching
    # ParameterMassager
    init_relax_parameters[_DEFAULT_OVERRIDE_NAMESPACE].isif = value
    massager = ParametersMassage(init_relax_parameters)
    parameters = massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE]
    assert parameters.isif == value
Ejemplo n.º 14
0
def test_additional_override_namespaces(init_relax_parameters):  # pylint: disable=invalid-name
    """Test that we can supply additional override namespaces and that they are unmodified in the massager."""
    init_relax_parameters.myspace = AttributeDict({'myspaceparameter': 1})
    init_relax_parameters.yourspace = AttributeDict({'yourspaceparameter': 1})
    massager = ParametersMassage(init_relax_parameters,
                                 settings=AttributeDict({
                                     'additional_override_namespaces':
                                     ['myspace', 'yourspace']
                                 }))
    assert massager.parameters.myspace.myspaceparameter == 1
    assert massager.parameters.yourspace.yourspaceparameter == 1
Ejemplo n.º 15
0
def test_charge_parameters():
    """Test charge parameters."""
    parameters = AttributeDict()
    parameters.charge = AttributeDict()
    parameters.charge.from_wave = True
    massager = ParametersMassage(parameters)
    parameters.charge.from_wave = False
    parameters.charge.from_charge = True
    massager = ParametersMassage(parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].icharg == 1
    parameters.charge.from_charge = False
    parameters.charge.from_atomic = True
    massager = ParametersMassage(parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].icharg == 2
    parameters.charge.from_atomic = False
    parameters.charge.from_potential = True
    massager = ParametersMassage(parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].icharg == 4
    parameters.charge.from_potential = False
    parameters.charge.constant_charge = True
    massager = ParametersMassage(parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].icharg == 11
    parameters.charge.constant_charge = False
    parameters.charge.constant_atomic = True
    massager = ParametersMassage(parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].icharg == 12
Ejemplo n.º 16
0
def test_unsupported_parameters_in_unsupported_namespace():  # pylint: disable=invalid-name
    """Test that it is possibly to supply unsupported parameters in the incar namespace if the configuration is also
    supplied."""
    parameters = AttributeDict()
    parameters[_DEFAULT_OVERRIDE_NAMESPACE] = AttributeDict()
    parameters[_DEFAULT_OVERRIDE_NAMESPACE].not_valid = 200
    massager = ParametersMassage(parameters,
                                 unsupported_parameters={
                                     'not_valid': {
                                         'default': 1.0,
                                         'description': 'Something',
                                         'type': float,
                                         'values': [1.0, 2.0]
                                     }
                                 })
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].not_valid == 200
Ejemplo n.º 17
0
def test_relax_parameters_no_algo(init_relax_parameters):
    """Test no provided algo tag."""
    del init_relax_parameters.relax.algo
    massager = ParametersMassage(init_relax_parameters)
    with pytest.raises(AttributeError):
        _ = massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].ibrion
Ejemplo n.º 18
0
def test_relax_parameters_pos_shape(init_relax_parameters):
    """Test position and shape relxation combinations."""
    del init_relax_parameters.relax.volume
    massager = ParametersMassage(init_relax_parameters)
    parameters = massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE]
    assert parameters.isif == 4
Ejemplo n.º 19
0
def test_orbital_projections():  # pylint: disable=too-many-statements
    """Test the parameters associated with orbital projections."""
    parameters = AttributeDict()
    parameters.bands = AttributeDict()
    parameters.bands.decompose_wave = True
    massager = ParametersMassage(parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].lorbit == 5
    parameters.bands.decompose_wave = False
    parameters.bands.decompose_bands = True
    parameters.bands.decompose_auto = True
    massager = ParametersMassage(parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].lorbit == 14
    parameters.bands.decompose_auto = False
    massager = ParametersMassage(parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].lorbit == 10
    parameters.bands.lm = True
    massager = ParametersMassage(parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].lorbit == 11
    parameters.bands.phase = True
    massager = ParametersMassage(parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].lorbit == 12
    parameters.bands.lm = False
    massager = ParametersMassage(parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].lorbit == 12

    # Now do the once with a Wigner-Seitz radius supplied
    parameters.bands.wigner_seitz_radius = [2.0]
    parameters.bands.lm = False
    parameters.bands.phase = False
    massager = ParametersMassage(parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].lorbit == 0
    assert int(massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].rwigs[0]) == 2
    parameters.bands.lm = True
    massager = ParametersMassage(parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].lorbit == 1
    parameters.bands.phase = True
    massager = ParametersMassage(parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].lorbit == 2
    parameters.bands.lm = False
    massager = ParametersMassage(parameters)
    assert massager.parameters[_DEFAULT_OVERRIDE_NAMESPACE].lorbit == 2

    # Should raise ValueError if Wigner-Seitz radius is not defined as a list.
    parameters.bands.wigner_seitz_radius = 2.0
    with pytest.raises(ValueError):
        massager = ParametersMassage(parameters)
Ejemplo n.º 20
0
    def init_inputs(self):  # pylint: disable=too-many-branches, too-many-statements
        """Make sure all the required inputs are there and valid, create input dictionary for calculation."""
        self.ctx.inputs = AttributeDict()
        self.ctx.inputs.parameters = self._init_parameters()
        # Set the code
        self.ctx.inputs.code = self.inputs.code

        # Set the structure (poscar)
        self.ctx.inputs.structure = self.inputs.structure

        # Set the kpoints (kpoints)
        self.ctx.inputs.kpoints = self.inputs.kpoints

        # Set settings
        unsupported_parameters = None
        skip_parameters_validation = False
        if self.inputs.get('settings'):
            self.ctx.inputs.settings = self.inputs.settings
            # Also check if the user supplied additional tags that is not in the supported file.
            settings_dict = self.ctx.inputs.settings.get_dict()
            unsupported_parameters = settings_dict.get('unsupported_parameters', unsupported_parameters)
            skip_parameters_validation = settings_dict.get('skip_parameters_validation', skip_parameters_validation)

        # Perform inputs massage to accommodate generalization in higher lying workchains
        # and set parameters.
        try:
            parameters_massager = ParametersMassage(self.ctx.inputs.parameters,
                                                    unsupported_parameters,
                                                    skip_parameters_validation=skip_parameters_validation)
        except Exception as exception:  # pylint: disable=broad-except
            return self.exit_codes.ERROR_IN_PARAMETER_MASSAGER.format(exception=exception)  # pylint: disable=no-member
        try:
            # Only set if they exists
            # Set any INCAR tags
            self.ctx.inputs.parameters = parameters_massager.parameters.incar
            # Set any dynamics input (currently only for selective dynamics, e.g. custom write to POSCAR)
            self.ctx.inputs.dynamics = parameters_massager.parameters.dynamics
            # Here we could set additional override flags, but those are not relevant for this VASP plugin
        except AttributeError:
            pass

        # Set options
        # Options is very special, not storable and should be
        # wrapped in the metadata dictionary, which is also not storable
        # and should contain an entry for options
        if 'options' in self.inputs:
            options = {}
            options.update(self.inputs.options)
            self.ctx.inputs.metadata = {'options': options}
            # Override the parser name if it is supplied by the user.
            parser_name = self.ctx.inputs.metadata['options'].get('parser_name')
            if parser_name:
                self.ctx.inputs.metadata['options']['parser_name'] = parser_name
            # Set MPI to True, unless the user specifies otherwise
            withmpi = self.ctx.inputs.metadata['options'].get('withmpi', True)
            self.ctx.inputs.metadata['options']['withmpi'] = withmpi

        # Make sure we also bring along any label and description set on the WorkChain to the CalcJob, it if does
        # not exists, set to empty string.
        if 'metadata' in self.inputs:
            label = self.inputs.metadata.get('label', '')
            description = self.inputs.metadata.get('description', '')
            if 'metadata' not in self.ctx.inputs:
                self.ctx.inputs.metadata = {}
            self.ctx.inputs.metadata['label'] = label
            self.ctx.inputs.metadata['description'] = description

        # Verify and set potentials (potcar)
        if not self.inputs.potential_family.value:
            self.report('An empty string for the potential family name was detected.')  # pylint: disable=not-callable
            return self.exit_codes.ERROR_NO_POTENTIAL_FAMILY_NAME  # pylint: disable=no-member
        try:
            self.ctx.inputs.potential = get_data_class('vasp.potcar').get_potcars_from_structure(
                structure=self.inputs.structure,
                family_name=self.inputs.potential_family.value,
                mapping=self.inputs.potential_mapping.get_dict())
        except ValueError as err:
            return compose_exit_code(self.exit_codes.ERROR_POTENTIAL_VALUE_ERROR.status, str(err))  # pylint: disable=no-member
        except NotExistent as err:
            return compose_exit_code(self.exit_codes.ERROR_POTENTIAL_DO_NOT_EXIST.status, str(err))  # pylint: disable=no-member

        try:
            self._verbose = self.inputs.verbose.value
        except AttributeError:
            pass
        # Set the charge density (chgcar)
        if 'chgcar' in self.inputs:
            self.ctx.inputs.charge_density = self.inputs.chgcar

        # Set the wave functions (wavecar)
        if 'wavecar' in self.inputs:
            self.ctx.inputs.wavefunctions = self.inputs.wavecar

        return self.exit_codes.NO_ERROR  # pylint: disable=no-member