Example #1
0
    def _get_mol_details(self, atoms):
        """returns the atomic configuration of the gaussian input file"""

        if 'allcheck' in self.route_self_params['geom'].lower():
            return ''

        mol_details = ''

        charge = sum(atoms.get_charges())
        mol_details += '%i %i\n' % (charge, self.multiplicity)

        if 'check' in self.route_self_params['geom'].lower():
            return mol_details

        symbols = atoms.get_chemical_symbols()
        coordinates = atoms.get_positions()

        for i in range(len(atoms)):
            mol_details += '%-10s' % symbols[i]
            for j in range(3):
                mol_details += '%20.10f' % coordinates[i, j]
            mol_details += '\n'
        mol_details += '\n'

        return mol_details
Example #2
0
    def _get_mol_details(self, atoms):
        """returns the atomic configuration of the gaussian input file"""

        if 'allcheck' in self.route_self_params['geom'].lower():
            return ''

        mol_details = ''

        charge = sum(atoms.get_charges())
        mol_details += '%i %i\n' % (charge, self.multiplicity)

        if 'check' in self.route_self_params['geom'].lower():
            return mol_details

        symbols = atoms.get_chemical_symbols()
        coordinates = atoms.get_positions()

        for i in range(len(atoms)):
            mol_details += '%-10s' % symbols[i]
            for j in range(3):
                mol_details += '%20.10f' % coordinates[i, j]
            mol_details += '\n'
        mol_details += '\n'

        return mol_details

        
Example #3
0
def get_localEnv(frame, centerIdx, cutoff, onlyDict=False):
    '''
    Get the local atomic environment around an atom in an atomic frame.

    :param frame: ase or quippy Atoms object
    :param centerIdx: int
    Index of the local environment center.
    :param cutoff: float
    Cutoff radius of the local environment.
    :return: ase Atoms object
    Local atomic environment. The center atom is in first position.
    '''
    import ase.atoms
    import quippy.atoms
    from ase.neighborlist import NeighborList
    from ase import Atoms as aseAtoms
    if isinstance(frame, quippy.atoms.Atoms):
        atoms = qp2ase(frame)
    elif isinstance(frame, ase.atoms.Atoms):
        atoms = frame
    else:
        raise ValueError

    n = len(atoms.get_atomic_numbers())
    nl = NeighborList([
        cutoff / 2.,
    ] * n,
                      skin=0.,
                      sorted=False,
                      self_interaction=False,
                      bothways=True)
    nl.build(atoms)

    cell = atoms.get_cell()
    pbc = atoms.get_pbc()
    pos = atoms.get_positions()
    positions = [
        pos[centerIdx],
    ]
    zList = atoms.get_atomic_numbers()
    numbers = [
        zList[centerIdx],
    ]

    indices, offsets = nl.get_neighbors(centerIdx)

    # print offsets,len(atom.get_atomic_numbers())
    for i, offset in zip(indices, offsets):
        positions.append(pos[i] + np.dot(offset, cell))
        numbers.append(zList[i])

    atomsParam = dict(numbers=numbers, cell=cell, positions=positions, pbc=pbc)

    if onlyDict:
        return atomsParam
    else:
        return aseAtoms(**atomsParam)
Example #4
0
def vibmodes(atoms,
             startdir=None,
             mask=None,
             workhere=False,
             save=None,
             give_output=0,
             pmap=pmap3,
             **kwargs):
    """
    Wrapper around vibmode, which used the atoms objects
    The hessian is calculated by derivatef
    qfunc.fwrapper is used as a wrapper to calulate the gradients
    """
    from pts.memoize import Memoize, DirStore
    coord = atoms.get_positions()

    if mask == None:
        mask = constraints2mask(atoms)

    if mask == None:  # (if still None)
        fun = Cartesian()
    else:
        fun = Masked(Cartesian(), mask, coord.flatten())

    xcenter = fun.pinv(coord)

    myfunc = QFunc(atoms, atoms.get_calculator())

    myfunc = Memoize(myfunc, DirStore("cache.d"))

    myfunc = compose(myfunc, fun)

    pmapc = pwrapper(pmap)
    func = fwrapper(myfunc, startdir=startdir, mask=mask, workhere=workhere)

    # the derivatives are needed
    hessian = derivatef(func, xcenter, pmap=pmapc, **kwargs)

    # save is assumend to be a filename, so far only the hessian is saved:
    if save is not None:
        savetxt(save, hessian)

    mass = mass_matrix(atoms.get_masses(), mask)

    freqs, modes = vibmod(mass, hessian)

    # the output will be printed on demand, with modes if wanted
    # the output for the freqs can easily be recreated later on, but
    # for the mode vectors the mass (not included in the direct output_
    # is needed
    if VERBOSE or give_output == 2:
        output(freqs, modes, mass, mask)
    elif give_output == 1:
        output(freqs)

    return freqs, modes
Example #5
0
def dft_d_pbc(atoms, scaling_factor=0.75, interactionlist=None, interactionmatrix=None, cutoff_radius=DF_CUTOFF_RADIUS):
    """Main function making the D-G06 DFT-D correction available for
    systems with periodic boundary conditions. Applies the lattice
    summation defined in "lattice_sum" to the intra- and inter-cell
    evaluation of the D-G06 correction carried out in "d_g06_cell".

        >>> HCldim = Atoms('Cl2')
        >>> x1 = ( 1.65, 0, -0.01)
        >>> x2 = (-1.65, 0,  0.01)
        >>> HCldim.set_positions([x1,x2])
        >>> HCldim.set_atomic_numbers([ 17, 17])
        >>> HCldim.set_cell([(10.0, 0.0, 0.0), (0.0, 10.0, 0.0), (0.0, 0.0, 3.3)])
        >>> HCldim.set_pbc([False,]*3)
        >>> dft_d_pbc(HCldim)
        (-0.016281380498314325, array([[-0.01672876,  0.        ,  0.00010139],
               [ 0.01672876,  0.        , -0.00010139]]))
        >>> iso_c, iso_g = dft_d_iso(HCldim)
	>>> pbc_c, pbc_g = dft_d_pbc(HCldim)
	>>> iso_c == pbc_c, iso_g == pbc_g
	(True, array([[ True,  True,  True],
	       [ True,  True,  True]], dtype=bool))
    """
    #
    # Obtain data about system
    atom_numbers = atoms.get_atomic_numbers()
    positions = atoms.get_positions()
    periodic_directions = atoms.get_pbc()
    elem_cell = atoms.get_cell()
    #
    # Number of atoms within a single copy
    N_atoms = len(positions)
    #
    # Check input i.e. if interactionlist and interactionmatrix are set properly
    interactionlist, interactionmatrix = check_interaction_group_input(N_atoms, interactionlist, interactionmatrix)
    #
    # Start with Calculation
    # Get DFT-D parameters
    params = [d_g06_parameters(ind_1) for ind_1 in atom_numbers]
    #
    # Define function "func" as "d_g06" for the lattice summation done in "lattice_sum"
    def func(t):
        return d_g06_cell(N_atoms, params, positions, interactionlist, interactionmatrix, cutoff_radius, t_vec=t)

    #
    # Call lattice summation with function "d_g06_cell"
    dispersion_correction, gradient_contribution = lattice_sum(
        func, positions, elem_cell, periodic_directions, cutoff_radius
    )
    #
    # Scale dispersion correction and forces according to used XC-functional
    dispersion_correction = dispersion_correction * scaling_factor
    gradient_contribution = gradient_contribution * scaling_factor
    #
    return dispersion_correction, gradient_contribution
Example #6
0
def vibmodes(atoms, startdir=None, mask=None, workhere=False, save=None, give_output = 0, pmap = pmap3, **kwargs):
    """
    Wrapper around vibmode, which used the atoms objects
    The hessian is calculated by derivatef
    qfunc.fwrapper is used as a wrapper to calulate the gradients
    """
    from pts.memoize import Memoize, DirStore
    coord = atoms.get_positions()

    if mask == None:
        mask = constraints2mask(atoms)

    if mask == None: # (if still None)
        fun = Cartesian()
    else:
        fun = Masked(Cartesian(), mask, coord.flatten())

    xcenter = fun.pinv(coord)

    myfunc = QFunc(atoms, atoms.get_calculator())

    myfunc = Memoize(myfunc, DirStore("cache.d"))

    myfunc = compose( myfunc, fun)

    pmapc = pwrapper(pmap)
    func = fwrapper(myfunc, startdir = startdir, mask = mask, workhere = workhere)

    # the derivatives are needed
    hessian = derivatef( func, xcenter, pmap = pmapc, **kwargs)

    # save is assumend to be a filename, so far only the hessian is saved:
    if save is not None:
        savetxt(save, hessian)

    mass = mass_matrix (atoms.get_masses(), mask)

    freqs, modes = vibmod(mass, hessian)

    # the output will be printed on demand, with modes if wanted
    # the output for the freqs can easily be recreated later on, but
    # for the mode vectors the mass (not included in the direct output_
    # is needed
    if VERBOSE or give_output == 2:
        output(freqs, modes, mass, mask)
    elif give_output == 1:
        output(freqs)


    return freqs, modes
Example #7
0
def dft_d_iso(atoms, scaling_factor=0.75, interactionlist=None, interactionmatrix=None, cutoff_radius=DF_CUTOFF_RADIUS):
    """Main function making the D-G06 DFT-D correction available for
    isolated systems. Consists in the application of an intra-cell
    evaluation of the D-G06 correction carried out in "d_g06_cell".

        >>> HCldim = Atoms('Cl2')
        >>> x1 = ( 1.65, 0, -0.01)
        >>> x2 = (-1.65, 0,  0.01)
        >>> HCldim.set_positions([x1,x2])
        >>> HCldim.set_atomic_numbers([ 17, 17])
        >>> dft_d_pbc(HCldim)
	(-0.016281380498314325, array([[-0.01672876,  0.        ,  0.00010139],
	       [ 0.01672876,  0.        , -0.00010139]]))
    """
    #
    # Obtain data about system
    atom_numbers = atoms.get_atomic_numbers()
    positions = atoms.get_positions()
    #
    # Number of atoms within a single copy
    N_atoms = len(positions)
    #
    # Check input i.e. if interactionlist and interactionmatrix are set properly
    interactionlist, interactionmatrix = check_interaction_group_input(N_atoms, interactionlist, interactionmatrix)
    interactionmatrix = np.array(interactionmatrix)
    #
    # Start with Calculation
    # Get DFT-D parameters
    params = [d_g06_parameters(ind_1) for ind_1 in atom_numbers]
    #
    # Define function "func" as "d_g06" for the lattice summation done in "lattice_sum"
    dispersion_correction, gradient_contribution = d_g06_cell(
        N_atoms, params, positions, interactionlist, interactionmatrix, cutoff_radius
    )
    #
    # Scale dispersion correction and forces according to used XC-functional
    dispersion_correction = dispersion_correction * scaling_factor
    gradient_contribution = gradient_contribution * scaling_factor
    #
    return dispersion_correction, gradient_contribution
Example #8
0
    def initialize_sdc(self, atoms=None):
        """ Initialization of all parameters in the sedc-module.

        Here we initialize all parameters in order to successfully calculate
        with sdc_recode module. The priority of parameters is user > default >
        dummy. The bare minimum of required parameters is:

        * atoms             [ ASE atoms-object of the system treated        ]
        * sedc_n_groups     [ integer, number of differently treated groups ]
        * sedc_groups       [ array of integers, number of atoms per group  ]
        * sedc_pbc_switches [ np.array of 6-dim vectors specifying the VdW
                              contributions in A,B,C in positive and
                              negative direction                            ]

        This has to be done after the creation of our calculator-object,
        because otherwise we do not have the atoms-module to calculate most of
        the required properties.

        """
        for arg in self.valid_args:
            if hasattr(self, arg):
                # In order to avoid lengthy np-initialization in aims-script
                if (arg == 'sedc_pbc_g_switches'):
                    setattr(sdc.sdc_recode, arg,
                            eval('np.transpose(self.' + arg + ')'))
                elif (arg == 'sedc_tssurf_vfree_div_vbulk'):
                    tmp_array = \
                        np.array(([1] * atoms.get_number_of_atoms()),
                                np.float64)
                    species = []
                    n_species = 0
                    for atom in atoms:
                        species_i = atom.number
                        if species_i not in species:
                            species.append(species_i)
                            n_species += 1
                    species.sort()
                    for i,a in enumerate(atoms):
                        for ss, s in enumerate(species):
                            if s==a.number:
                                tmp_array[i] = \
                                    self.sedc_tssurf_vfree_div_vbulk[ss]
                    sdc.sdc_recode.sedc_tssurf_vfree_div_vbulk = \
                            tmp_array
                else:
                    setattr(sdc.sdc_recode, arg, eval('self.' + arg))
            elif arg in self.default_parameters:
                setattr(sdc.sdc_recode, arg, self.default_parameters[arg])
            else:
                if (arg == 'internal_cart_coord'):
                    sdc.sdc_recode.internal_cart_coord = \
                        atoms.get_positions().transpose().copy()
                elif (arg == 'sedc_cart_coord'):
                    sdc.sdc_recode.sedc_cart_coord = \
                        atoms.get_positions().transpose().copy()
                elif (arg == 'sedc_cell_vectors'):
                    sdc.sdc_recode.sedc_cell_vectors = \
                        atoms.get_cell().transpose().copy()
                elif (arg == 'sedc_species'):
                    sdc.sdc_recode.sedc_species = \
                        atoms.get_atomic_numbers().copy()
                elif (arg == 'sedc_n_ions'):
                    sdc.sdc_recode.sedc_n_ions = \
                        atoms.get_number_of_atoms()
                elif (arg == 'sedc_pbc_g_fold'):
                    sdc.sdc_recode.sedc_pbc_g_fold = [0] * self.sedc_n_groups
                elif (arg == 'sedc_ts_veff_div_vfree'):
                    if not self.hirshvolrat_is_set:
                        sdc.sdc_recode.sedc_ts_veff_div_vfree = \
                            np.array(([1] * atoms.get_number_of_atoms()),
                                     np.float64)
                elif (arg == 'sedc_tssurf_vfree_div_vbulk'):
                    sdc.sdc_recode.sedc_tssurf_vfree_div_vbulk = \
                        np.array(([1] * atoms.get_number_of_atoms()),
                                np.float64)
                elif (arg == 'sedc_skip_atom'):
                    sdc.sdc_recode.sedc_skip_atom = \
                        np.array(([-1] * atoms.get_number_of_atoms()),
                                 np.float64)
                elif (arg == 'sedc_pbc_g_only_intra'):
                    sdc.sdc_recode.sedc_pbc_g_only_intra = \
                        [0] * self.sedc_n_groups
                elif (arg == 'sedc_pbc_g_cells'):
                    sdc.sdc_recode.sedc_pbc_g_cells = \
                        np.tile(atoms.get_cell().transpose().copy(),
                                (1, self.sedc_n_groups))
                elif (arg == 'sedc_pbc_g_skip'):
                    sdc.sdc_recode.sedc_pbc_g_skip = [0] * self.sedc_n_groups
                else:
                    print("You've been sloppy my friend. :) Variable:", arg, \
                          " does not exist!")
Example #9
0
import numpy as np
from ase import io, atoms

Temp = '300'
atoms = io.read('POSCAR')
pos = atoms.get_positions()
disp = np.loadtxt('thermal_displacements.yaml', skiprows=6, usecols=(2, 3, 4))
pos += disp
atoms.set_positions(pos)
io.write('POSCAR' + Temp, atoms, direct=True)