Beispiel #1
0
    def calculate(self, atoms):
        '''
        Blocking/Non-blocking calculate method

        If we are in blocking mode we just run, wait for
        the job to end and read in the results. Easy ...

        The non-blocking mode is a little tricky.
        We need to start the job and guard against it reading
        back possible old data from the directory - the queuing
        system may not even started the job when we get control
        back from the starting script. Thus anything we read
        after invocation is potentially garbage - even if it
        is a converged calculation data.

        We handle it by custom run function above which
        raises an exception after submitting the job.
        This skips post-run processing in the calculator, preserves
        the state of the data and signals here that we need to wait
        for results.
        '''

        with work_dir(self.working_dir):
            self.prepare_calc_dir()
            self.calc_running = True
            #print('Run VASP.calculate')
            try:
                Vasp.calculate(self, atoms)
                self.calc_running = False
                #print('VASP.calculate returned')
            except _NonBlockingRunException as e:
                # We have nothing else to docs
                # until the job finishes
                #print('Interrupted ', self.working_dir, os.getcwd())
                pass
Beispiel #2
0
    def calculate(self, atoms):
        '''
        Blocking/Non-blocking calculate method

        If we are in blocking mode we just run, wait for 
        the job to end and read in the results. Easy ...
        
        The non-blocking mode is a little tricky. 
        We need to start the job and guard against it reading 
        back possible old data from the directory - the queuing 
        system may not even started the job when we get control 
        back from the starting script. Thus anything we read 
        after invocation is potentially garbage - even if it 
        is a converged calculation data.

        We handle it by custom run function above which 
        raises an exception after submitting the job.
        This skips post-run processing in the calculator, preserves 
        the state of the data and signals here that we need to wait
        for results.
        '''
        
        with work_dir(self.working_dir) :
            self.prepare_calc_dir()
            self.calc_running=True
            #print('Run VASP.calculate')
            try :
                Vasp.calculate(self, atoms)
                self.calc_running=False
                #print('VASP.calculate returned')
            except _NonBlockingRunException as e:
                # We have nothing else to docs
                # until the job finishes
                #print('Interrupted ', self.working_dir, os.getcwd())
                pass
Beispiel #3
0
    def vasp_vol_relax():
        Al = bulk('Al', 'fcc', a=4.5, cubic=True)
        calc = Vasp(xc='LDA',
                    isif=7,
                    nsw=5,
                    ibrion=1,
                    ediffg=-1e-3,
                    lwave=False,
                    lcharg=False)
        calc.calculate(Al)

        # Explicitly parse atomic position output file from Vasp
        CONTCAR_Al = io.read('CONTCAR', format='vasp')

        print('Stress after relaxation:\n', calc.read_stress())

        print('Al cell post relaxation from calc:\n',
              calc.get_atoms().get_cell())
        print('Al cell post relaxation from atoms:\n', Al.get_cell())
        print('Al cell post relaxation from CONTCAR:\n', CONTCAR_Al.get_cell())

        # All the cells should be the same.
        assert (calc.get_atoms().get_cell() == CONTCAR_Al.get_cell()).all()
        assert (Al.get_cell() == CONTCAR_Al.get_cell()).all()

        return Al
def test_not_atoms(bad_atoms):
    """Check that passing in objects which are not
    actually Atoms objects raises a setup error """

    with pytest.raises(CalculatorSetupError):
        check_atoms_type(bad_atoms)
    with pytest.raises(CalculatorSetupError):
        check_atoms(bad_atoms)

    # Test that error is also raised properly when launching
    # from calculator
    calc = Vasp()
    with pytest.raises(CalculatorSetupError):
        calc.calculate(atoms=bad_atoms)
Beispiel #5
0
def vasp_vol_relax():
    Al = bulk("Al", "fcc", a=4.5, cubic=True)
    calc = Vasp(xc="LDA", isif=7, nsw=5, ibrion=1, ediffg=-1e-3, lwave=False, lcharg=False)
    calc.calculate(Al)

    # Explicitly parse atomic position output file from Vasp
    CONTCAR_Al = io.read("CONTCAR", format="vasp")

    print("Stress after relaxation:\n", calc.read_stress())

    print("Al cell post relaxation from calc:\n", calc.get_atoms().get_cell())
    print("Al cell post relaxation from atoms:\n", Al.get_cell())
    print("Al cell post relaxation from CONTCAR:\n", CONTCAR_Al.get_cell())

    # All the cells should be the same.
    assert (calc.get_atoms().get_cell() == CONTCAR_Al.get_cell()).all()
    assert (Al.get_cell() == CONTCAR_Al.get_cell()).all()

    return Al
def vasp_vol_relax():
    Al = bulk('Al', 'fcc', a=4.5, cubic=True)
    calc = Vasp(xc='LDA', isif=7, nsw=5,
                ibrion=1, ediffg=-1e-3, lwave=False, lcharg=False)
    calc.calculate(Al)

    # Explicitly parse atomic position output file from Vasp
    CONTCAR_Al = io.read('CONTCAR', format='vasp')

    print 'Stress after relaxation:\n', calc.read_stress()

    print 'Al cell post relaxation from calc:\n', calc.get_atoms().get_cell()
    print 'Al cell post relaxation from atoms:\n', Al.get_cell()
    print 'Al cell post relaxation from CONTCAR:\n', CONTCAR_Al.get_cell()

    # All the cells should be the same.
    assert (calc.get_atoms().get_cell() == CONTCAR_Al.get_cell()).all()
    assert (Al.get_cell() == CONTCAR_Al.get_cell()).all()

    return Al
def test_vasp_charge():
    """
    Run VASP tests to ensure that determining number of electrons from
    user-supplied charge works correctly. This is conditional on the existence
    of the VASP_COMMAND or VASP_SCRIPT environment variables.

    """

    from ase.build import bulk
    from ase.calculators.vasp import Vasp
    from ase.test import must_raise
    from ase.test.vasp import installed

    assert installed()

    system = bulk('Al', 'fcc', a=4.5, cubic=True)

    # Dummy calculation to let VASP determine default number of electrons
    calc = Vasp(xc='LDA', nsw=-1, ibrion=-1, nelm=1, lwave=False, lcharg=False)
    calc.calculate(system)
    default_nelect_from_vasp = calc.get_number_of_electrons()
    assert default_nelect_from_vasp == 12

    # Make sure that no nelect was written into INCAR yet (as it wasn't necessary)
    calc = Vasp()
    calc.read_incar()
    assert calc.float_params['nelect'] is None

    # Compare VASP's output nelect from before minus charge to default nelect
    # determined by us minus charge
    charge = -2
    calc = Vasp(xc='LDA', nsw=-1, ibrion=-1, nelm=1, lwave=False, lcharg=False,
                charge=charge)
    calc.initialize(system)
    calc.write_input(system)
    calc.read_incar()
    assert calc.float_params['nelect'] == default_nelect_from_vasp - charge

    # Test that conflicts between explicitly given nelect and charge are detected
    with must_raise(ValueError):
        calc = Vasp(xc='LDA', nsw=-1, ibrion=-1, nelm=1, lwave=False, lcharg=False,
                    nelect=default_nelect_from_vasp-charge+1,
                    charge=charge)
        calc.calculate(system)

    # Test that nothing is written if charge is 0 and nelect not given
    calc = Vasp(xc='LDA', nsw=-1, ibrion=-1, nelm=1, lwave=False, lcharg=False,
                charge=0)
    calc.initialize(system)
    calc.write_input(system)
    calc.read_incar()
    assert calc.float_params['nelect'] is None

    # Test that explicitly given nelect still works as expected
    calc = Vasp(xc='LDA', nsw=-1, ibrion=-1, nelm=1, lwave=False, lcharg=False,
                nelect=15)
    calc.calculate(system)
    assert calc.get_number_of_electrons() == 15
Beispiel #8
0
Should be removed along with the net_charge parameter itself at some point.
"""

from ase.build import bulk
from ase.calculators.vasp import Vasp
from ase.test import must_raise, must_warn
from ase.test.vasp import installed

assert installed()

system = bulk('Al', 'fcc', a=4.5, cubic=True)

# Dummy calculation to let VASP determine default number of electrons
calc = Vasp(xc='LDA', nsw=-1, ibrion=-1, nelm=1, lwave=False, lcharg=False)
calc.calculate(system)
default_nelect_from_vasp = calc.get_number_of_electrons()
assert default_nelect_from_vasp == 12

# Compare VASP's output nelect from before + net charge to default nelect
# determined by us + net charge
with must_warn(FutureWarning):
    net_charge = -2
    calc = Vasp(xc='LDA',
                nsw=-1,
                ibrion=-1,
                nelm=1,
                lwave=False,
                lcharg=False,
                net_charge=net_charge)
    calc.initialize(system)
Beispiel #9
0
    os.environ['VASP_COMMAND'] = "srun --cpu_bind=cores vasp_std"

#####
from numpy import loadtxt
temp = loadtxt('temperature.txt')

### minimal tags to run
from ase.calculators.vasp import Vasp
calc = Vasp(xc='PBE', setups='minimal', kpts=kpts)

### good tags to set
calc.set(prec='Accurate',
         ediff=1E-8 * len(atoms),
         encut=450,
         algo='Fast',
         ispin=1,
         nelm=200,
         lmaxmix=4)
calc.set(lreal='Auto')

################ molecular dynamics  ###########

### vasp settings
calc.set(isym=0, ibrion=0)  # turn on MD
calc.set(nsw=10000, potim=1.0)  # 10000 steps, 2.0 fs step

#calc.set(smass=-3, tebeg = 300 )#  NVE, tebeg sets the intial random velocities
calc.set(smass=0, tebeg=temp[0], teend=temp[1])  # Nose thermostat, NVT

calc.calculate(atoms)
Beispiel #10
0
def test_vasp_net_charge():
    """
    Run VASP tests to ensure that determining number of electrons from
    user-supplied net charge (via the deprecated net_charge parameter) works
    correctly. This is conditional on the existence of the VASP_COMMAND or
    VASP_SCRIPT environment variables.

    This is mainly a slightly reduced duplicate of the vasp_charge test, but with
    flipped signs and with checks that ensure FutureWarning is emitted.

    Should be removed along with the net_charge parameter itself at some point.
    """

    from ase.build import bulk
    from ase.calculators.vasp import Vasp
    from ase.test import must_raise, must_warn
    from ase.test.vasp import installed

    assert installed()

    system = bulk('Al', 'fcc', a=4.5, cubic=True)

    # Dummy calculation to let VASP determine default number of electrons
    calc = Vasp(xc='LDA', nsw=-1, ibrion=-1, nelm=1, lwave=False, lcharg=False)
    calc.calculate(system)
    default_nelect_from_vasp = calc.get_number_of_electrons()
    assert default_nelect_from_vasp == 12

    # Compare VASP's output nelect from before + net charge to default nelect
    # determined by us + net charge
    with must_warn(FutureWarning):
        net_charge = -2
        calc = Vasp(xc='LDA',
                    nsw=-1,
                    ibrion=-1,
                    nelm=1,
                    lwave=False,
                    lcharg=False,
                    net_charge=net_charge)
        calc.initialize(system)
        calc.write_input(system)
        calc.read_incar()
    assert calc.float_params['nelect'] == default_nelect_from_vasp + net_charge

    # Test that conflicts between explicitly given nelect and net charge are
    # detected
    with must_raise(ValueError):
        with must_warn(FutureWarning):
            calc = Vasp(xc='LDA',
                        nsw=-1,
                        ibrion=-1,
                        nelm=1,
                        lwave=False,
                        lcharg=False,
                        nelect=default_nelect_from_vasp + net_charge + 1,
                        net_charge=net_charge)
            calc.calculate(system)

    # Test that conflicts between charge and net_charge are detected
    with must_raise(ValueError):
        with must_warn(FutureWarning):
            calc = Vasp(xc='LDA',
                        nsw=-1,
                        ibrion=-1,
                        nelm=1,
                        lwave=False,
                        lcharg=False,
                        charge=-net_charge - 1,
                        net_charge=net_charge)
            calc.calculate(system)

    # Test that nothing is written if net charge is 0 and nelect not given
    with must_warn(FutureWarning):
        calc = Vasp(xc='LDA',
                    nsw=-1,
                    ibrion=-1,
                    nelm=1,
                    lwave=False,
                    lcharg=False,
                    net_charge=0)
        calc.initialize(system)
        calc.write_input(system)
        calc.read_incar()
    assert calc.float_params['nelect'] is None
Beispiel #11
0
    def run_task(self, fw_spec):
        # if encode is given, use it as input structure
        if 'encode' in self:
            atoms = encode_to_atoms(self['encode'])

        # else, read the input structure from the output of the previous step
        else:
            job_info_array = fw_spec['_job_info']
            prev_job_info = job_info_array[-1]
            atoms = read(os.path.join(prev_job_info['launch_dir'], 'OUTCAR'))

        if 'pert_step' in self:
            atom_ucalc = Element(self['atom_ucalc'])
            elem_list_sorted, indices = np.unique(atoms.get_chemical_symbols(),
                                                  return_index=True)
            elem_list = elem_list_sorted[np.argsort(indices)]

            self['calc_params']['ldaul'] = []
            self['calc_params']['ldauu'] = []
            self['calc_params']['ldauj'] = []
            for atom in elem_list:
                if atom == self['dummy_atom']:
                    if atom_ucalc.is_transition_metal:
                        self['calc_params']['ldaul'].append(2)
                    elif atom_ucalc.is_lanthanoid or atom_ucalc.is_actinoid:
                        self['calc_params']['ldaul'].append(3)
                    else:
                        raise ValueError(
                            f"Cannot calculate U for the element {self['atom_ucalc']}"
                        )

                    self['calc_params']['ldauu'].append(self['pert_value'])
                    self['calc_params']['ldauj'].append(self['pert_value'])
                else:
                    self['calc_params']['ldaul'].append(-1)
                    self['calc_params']['ldauu'].append(0)
                    self['calc_params']['ldauj'].append(0)

            self['calc_params']['ldau'] = True
            self['calc_params']['ldautype'] = 3

            job_info_array = fw_spec['_job_info']
            prev_job_info = job_info_array[-1]
            shutil.copy(os.path.join(prev_job_info['launch_dir'], 'WAVECAR'),
                        '.')

            # if pert_step is NSC, copy CHGCAR from previous step
            if self['pert_step'] == 'NSC':
                shutil.copy(
                    os.path.join(prev_job_info['launch_dir'], 'CHGCAR'), '.')
                self['calc_params']['icharg'] = 11

        # if magnetic calculation
        if 'magmoms' in self:
            if self['magmoms'] == 'previous':
                assert 'encode' not in self
                magmoms = atoms.get_magnetic_moments().round()
            else:
                magmoms = np.array(self['magmoms'])

            if magmoms.any():
                # add the necessary VASP parameters
                self['calc_params']['lorbit'] = 11
                self['calc_params']['ispin'] = 2
                atoms.set_initial_magnetic_moments(magmoms)

        # convert any lists from the parameter settings into arrays
        keys = self['calc_params']
        for k, v in keys.items():
            if isinstance(v, list):
                keys[k] = np.asarray(v)

        # initialize and run VASP
        calc = Vasp(**self['calc_params'])
        calc.calculate(atoms)

        # save information about convergence
        with open('is_converged', 'w') as f1:
            for filename in os.listdir('.'):
                if filename.endswith('.out'):
                    with open(filename, 'r') as f2:
                        if calc.converged is False and 'fatal error in bracketing' not in f2.read(
                        ):
                            f1.write('NONCONVERGED')
                        else:
                            f1.write('converged')