Пример #1
0
def append_and_write_COMs(result_dict, structure, file, suffix='.cif'):
    """
    Append all COMs in result dict to the ASE structure.

    Window COMs: He
    cage COM: Ne
    optimized pore COM: Ar

    """
    for molecule in result_dict:
        # check if the molecule has any windows:
        if result_dict[molecule][1]['diameters'] is None:
            continue
        # add cage COM
        cage_com = ase.Atom(symbol='Ne', position=result_dict[molecule][0])
        structure.append(cage_com)
        # add window COMs:
        for wCOM in result_dict[molecule][1]['centre_of_mass']:
            window_com = ase.Atom(symbol='He', position=wCOM)
            structure.append(window_com)
        # add optimized cage pore COM
        pore_com = ase.Atom(symbol='Ar', position=result_dict[molecule][2])
        structure.append(pore_com)
    # output to CIF
    output = file.replace(suffix, '_appended.cif')
    structure.write(output, format='cif')
    output = file.replace(suffix, '_appended.pdb')
    structure.write(output)
Пример #2
0
def randomCluster(n):
    atoms = ase.Atoms()
    atoms.append(ase.Atom('H', [0,0,0]))
    for i in range(n-1):
        farthest = 1e300
        a = numpy.random.normal(0, 1, 3)
        a = n * a/numpy.linalg.norm(a)
        A = numpy.array([0,0,0]) - a
        Au = A/numpy.linalg.norm(A)
        A = 2*n*Au
        for atom in atoms:
            b = atom.position
            B = b - a
            C = Au * numpy.dot(B, Au)
            D = b - (a + C)
            Dm = numpy.linalg.norm(D)
            Q = elements['H']['radius'] + elements[atom.symbol]['radius']
            if Dm > Q:
                continue
            if Dm == 0:
                V = Q
            else:            
                V = math.sqrt((Q*Q) - (Dm*Dm))
            farthest = min(numpy.linalg.norm(C)-V, farthest)
        p = a + Au * farthest                    
        atoms.append(ase.Atom('H', p))
    return atoms
Пример #3
0
    def broadened_linescan(self,
                           start,
                           end,
                           width,
                           threshold,
                           points=100,
                           nwidth=10,
                           bottom=0.0,
                           getlines=False):
        """ Make data linescan between start and end points with effective 'width' for data scanner.
        
        Not: only x- and y-coordinates of the start and end points matter.
        Line scan between start and end, but with such a way that you perform
        'nwidth' parallel line scans from width/2 distance from both sides of the original line.
        The result with given distance from the start is the maximum over all parallel values.
        
        Parameters:
        -----------
        start: position array
        end: position array
        width: width (in Angstrom) for data scanning 
        threshold: constant-data contour line threshold
        nwidth: how many parallel line scans are performed
        points: linear interpolation in output using this many points.
        getlines: if True, return ase.Atoms object where atoms are 'X's with 
                  starting and end-points of the line scans
                  
        Return: distance array and heights on that distance array
                (if getlines, return also the ase.Atoms object)
        """
        start, end = vec(start), vec(end)
        n = np.cross(end - start, vec([0, 0, 1]))
        n /= np.linalg.norm(n)
        start0, end0 = start - (width / 2) * n, end - (width / 2) * n
        atoms = ase.Atoms()

        # perform nwidth parallel scans
        hlist = []
        for shift in np.linspace(0, width, nwidth):
            l, h = self.linescan(start0 + shift * n,
                                 end0 + shift * n,
                                 threshold,
                                 points=points,
                                 bottom=bottom)
            atoms.append(ase.Atom('X', start0 + shift * n))
            atoms.append(ase.Atom('X', end0 + shift * n))
            hlist.append(h)
        hlist = np.array(hlist)

        # take maxima from these scans
        h = []
        for i in range(len(l)):
            h.append(max(hlist[:, i]))
        if getlines:
            return l, h, atoms
        else:
            return l, h
Пример #4
0
def get_graphene_structure(acc=1.42, distance=3.35):
    """ Create ase.Atoms object for graphene
    """
    cell = np.array([[acc * 0.5 * np.sqrt(3), -acc * 1.5, 0.0],
                     [acc * 0.5 * np.sqrt(3), acc * 1.5, 0.0],
                     [0.0, 0.0, distance]])
    atoms = ase.Atoms(cell=cell, pbc=[True, True, True])
    scaled_positions = np.array([[1. / 3., 2. / 3., 0.5],
                                 [2. / 3., 1. / 3., 0.5]])
    positions = np.dot(scaled_positions, cell)
    atoms.append(ase.Atom(symbol="C", position=positions[0]))
    atoms.append(ase.Atom(symbol="C", position=positions[1]))
    atoms.wrap()
    return atoms
Пример #5
0
def _superpose_next_intercalated_layer(block, natoms_layer=None):
    """
    Parameters
    -----------
    block : ase.Atoms object
        structure on which a molecule is put on graphite
    natoms_layer : integer
        number of C atoms in a layer
    """
    ## vector for the displacement of the next block
    ibase = 0
    center_hex = _get_center_of_a_hexagon(block[:natoms_layer], ibase=ibase)
    disp = center_hex - block[0].position + block.cell[2, :]

    ## prepare the new cell
    block2 = block.copy()
    block2.cell[2, 2] *= 2

    ## displacement vector for the next block
    disp = block[natoms_layer].position - block[0].position
    disp[2] = block.cell[2, 2]

    ## superpose the next block
    for ia in range(len(block)):
        block2.append(
            ase.Atom(symbol=block[ia].symbol,
                     position=block[ia].position + disp))
    return block2
Пример #6
0
 def soaper(structure, positions):
     structure = structure.copy()
     for i in range(len(positions)):
         structure.append(
             ase.Atom(position=tuple(positions[i]),
                      symbol=tracer_atomic_number))
     return _soap(soap_cmd_line, structure, quip_path=quip_path)
Пример #7
0
    def create_ase_ts_geometry(self):

        mol_list = AllChem.MolToMolBlock(self.rdkit_ts).split('\n')
        ase_atoms = []
        for i, line in enumerate(mol_list):

            if i > 3:

                try:
                    atom0, atom1, bond, rest = line
                    atom0 = int(atom0)
                    atom0 = int(atom1)
                    bond = float(bond)

                except ValueError:
                    try:
                        x, y, z, symbol = line.split()[0:4]
                        x = float(x)
                        y = float(y)
                        z = float(z)

                        ase_atoms.append(
                            ase.Atom(symbol=symbol, position=(x, y, z)))

                    except:
                        continue

        self.ase_ts = ase.Atoms(ase_atoms)
Пример #8
0
def get_pubchem_structure(cid=24380):
    """
    Parameter
    -------------
    cid : integer
        PubChem ID

    Return
    ----------
    mol : Atoms object
    """
    c = pcp.Compound.from_cid(cid)
    mol = ase.Atoms()
    natoms = len(c.elements)
    mol.number_of_atoms = len(c.elements)
    for ia in range(natoms):
        el = c.elements[ia]
        coord = np.zeros(3)
        coord[0] = c.record['coords'][0]['conformers'][0]['x'][ia]
        coord[1] = c.record['coords'][0]['conformers'][0]['y'][ia]
        if c.coordinate_type.lower() == "2d":
            coord[2] = 0.
        else:
            coord[2] = c.record['coords'][0]['conformers'][0]['z'][ia]
        mol.append(ase.Atom(symbol=el, position=coord))
    mol.wrap()
    return mol
Пример #9
0
def _get_superposed_structure(gra,
                              mol,
                              distance=3.0,
                              tgra=3.35,
                              iax=2,
                              tol=1e-5):

    for j in range(3):
        if j == iax:
            continue
        if np.linalg.norm(gra.cell[j] - mol.cell[j]) > tol:
            print("Error")
            exit()

    ## get positions
    zgra_max = np.max(gra.positions[:, iax])
    zmol_min = np.min(mol.positions[:, iax])
    zmol_max = np.max(mol.positions[:, iax])
    tmol = zmol_max - zmol_min

    ## translate vector for the molecule
    disp_mol = np.array([0., 0., zgra_max - zmol_min + distance])

    ## adjust cell size
    zheight = gra.cell[iax, iax] - tgra + 2. * distance + tmol
    gra.cell[iax, iax] = zheight

    ## superpose
    gic = ase.Atoms(cell=gra.cell, pbc=[True, True, True])
    for atom in gra:
        gic.append(atom)
    for atom in mol:
        gic.append(
            ase.Atom(symbol=atom.symbol, position=atom.position + disp_mol))
    return gic
Пример #10
0
    def surrogate_features(self, observations: List[ObservationType],
                           focus: torch.Tensor, element: torch.Tensor,
                           distance: torch.Tensor, angle: torch.Tensor,
                           dihedral: torch.Tensor) -> torch.Tensor:

        features = torch.zeros(size=(len(observations), self.num_afeats),
                               dtype=torch.float32,
                               device=self.device)
        focus = to_numpy(focus)
        element = to_numpy(element)
        distance = to_numpy(distance)
        angle = to_numpy(angle)
        dihedral = to_numpy(dihedral)

        for i, observation in enumerate(observations):
            atoms, _ = self.observation_space.parse(observation)
            positions = [atom.position for atom in atoms]
            new_position = zmat.position_atom_helper(
                positions=positions,
                focus=int(round(focus[i, 0])),
                distance=distance[i, 0],
                angle=angle[i, 0],
                dihedral=dihedral[i, 0],
            )
            new_element = int(round(element[i, 0]))
            new_atom = ase.Atom(
                symbol=self.observation_space.bag_space.get_symbol(
                    new_element),
                position=new_position)
            atoms.append(new_atom)
            features[i] = self.embedding_fn(self.converter(atoms))[:, -1, :]

        return features
Пример #11
0
def remove_solvent(pw_struct, ASE_struct, mol_list):
    """
    Remove solvents and write desolvated structure to ASE_struct.

    Keyword Arguments:
        pw_struct (pyWindow Rebuilt Molecule) -
            structure to analyze molecules of
        ASE_struct (ASE.Atoms()) -
            structure to append non-solvent atoms to
        mol_list (list) -
            list of distinct molecules from pyWindow modularize

    Returns:
        ASE_struct_out (ASE.Atoms()) - structure with non-solvent atoms

    """
    # make deep copy of ASE_struct
    ASE_struct_out = copy.deepcopy(ASE_struct)
    for molecule in pw_struct.molecules:
        logging.info(f'Analysing molecule {molecule + 1} out of '
                     f'{len(pw_struct.molecules)}')
        mol = pw_struct.molecules[molecule]
        if is_solvent(molecule=mol) is False:
            logging.info(f'is NOT solvent with {mol.no_of_atoms} atoms')
            # append atoms to ASE_struct_out
            atom_ids = np.arange(1, mol.no_of_atoms + 1)
            coords = mol.coordinates
            atom_symbs = mol.atom_ids
            for i, j, k in zip(atom_ids, atom_symbs, coords):
                curr_atm = ase.Atom(symbol=j, position=k, index=i)
                ASE_struct_out.append(curr_atm)
    return ASE_struct_out
Пример #12
0
def ase_atoms_from_pw_out(pw_out_file):

    with open(pw_out_file, 'r') as f:
        contents = f.read()

    final_coords_str = re.search(
        "Begin final coordinates\n([\s\S]*)End final coordinates",
        contents).group(1)
    atoms = ase.Atoms()
    for line in final_coords_str.split("\n"):
        sp = line.split()
        if len(sp) == 4:
            atoms.append(ase.Atom(sp[0], np.array(sp[1:], dtype=float)))

    celldm1 = float(
        re.search("celldm\(1\)=(.*)celldm\(2\)=", contents).group(1))
    cell_str = re.search("crystal axes:.*\n([\s\S]*)reciprocal axes",
                         contents).group(1)
    cell = []
    for line in cell_str.split("\n"):
        sp = line.split()
        if len(sp) == 7:
            cell += sp[3:6]
    cell = np.array(cell, dtype=float).reshape((3, 3)) * celldm1 / ang_2_bohr

    atoms.cell = cell
    atoms.pbc = True

    return atoms
Пример #13
0
def ase_atoms(crystal, **kwargs):
    """
    Convert a :class:`crystals.Crystal` object into an :class:`ase.Atoms` object.
    Keyword arguments are passed to :class:`ase.Atoms` constructor.

    Parameters
    ----------
    crystal : :class:`Crystal`
        Crystal to be converted.

    Returns
    -------
    atoms : ase.Atoms
        Group of atoms ready for ASE's routines.

    Raises
    ------
    ImportError : If ASE is not installed
    """
    if not WITH_ASE:
        raise ImportError("ASE is not installed/importable.")

    return ase.Atoms(
        symbols=[
            ase.Atom(
                symbol=atom.element,
                position=atom.coords_cartesian,
                magmom=atom.magmom,
                mass=atom.mass,
            ) for atom in crystal
        ],
        cell=np.array(crystal.lattice_vectors),
        **kwargs,
    )
Пример #14
0
    def get_ase_mol(self):
        """
        A method for creating an ase atoms object from an rdkit mol
        """

        if not self.rdkit_molecule:
            self.get_rdkit_mol()

        mol_list = rdkit.Chem.AllChem.MolToMolBlock(
            self.rdkit_molecule).split('\n')
        ase_atoms = []
        for i, line in enumerate(mol_list):
            if i > 3:
                try:
                    atom0, atom1, bond, rest = line
                    atom0 = int(atom0)
                    atom0 = int(atom1)
                    bond = float(bond)
                except ValueError:
                    try:
                        x, y, z, symbol = line.split()[0:4]
                        x = float(x)
                        y = float(y)
                        z = float(z)
                        ase_atoms.append(
                            ase.Atom(symbol=symbol, position=(x, y, z)))
                    except BaseException:
                        continue

        self._ase_molecule = ase.Atoms(ase_atoms)

        return self.ase_molecule
Пример #15
0
def get_stacking_graphene(na=1, nb=1, nc=1, distance=3.35):
    """ Get ase.Atoms object for an AB stacking graphite
    """
    graphene = get_graphene_structure(distance=distance)

    ## make a supercell along x and y directions
    sc = make_supercell(graphene, [[na, 0, 0], [0, nb, 0], [0, 0, 1]])
    natoms_layer = len(sc)

    ## make a supercell along z direction
    graphite = ase.Atoms(cell=[sc.cell[0], sc.cell[1], sc.cell[2] * nc],
                         pbc=[True, True, True])
    elements = ['C', 'C']
    for iz in range(nc):

        ## displacment to form AB stacking
        disp = np.zeros(3)
        if iz % 2 == 1:
            disp += (graphene.cell[0, :] + graphene.cell[1, :] * 2.) * 2. / 3.
        disp += sc.cell[2, :] * iz

        ## add atoms at the layer
        for ia in range(len(sc)):
            graphite.append(
                ase.Atom(symbol=elements[iz % 2],
                         position=sc.positions[ia, :] + disp,
                         tag=iz % 2 + 1))
    ##
    graphite.wrap()
    return graphite
def plot_centres_xsf(structure,w90_calc):
    a = structure.get_ase()
    new_a = a.copy()
    out = w90_calc.out.output_parameters.get_dict()['wannier_functions_output']
    coords = [i['coordinates'] for i in out]
    for c in coords:
        new_a.append(ase.Atom('X',c))
    new_a.write('./wannier.xsf')
Пример #17
0
    def migration_prep(self):
        sz = 16
        perf_atoms = self.set_bcc_convention(size=[sz, sz, sz])
        vect = np.array([1, 1, 1]) * self.pot['lattice']

        pos1 = vect * sz * 0.5
        pos2 = vect * sz * 0.5 + 0.5 * vect
        pos3 = vect * 0.0

        dellist = []
        atoms = perf_atoms.copy()
        for atom in atoms:
            if np.isclose(pos1 - atom.position, np.array([0, 0, 0])).all() or \
                    np.isclose(pos2 - atom.position,
                               np.array([0, 0, 0])).all() or \
                    np.isclose(pos3 - atom.position,
                               np.array([0, 0, 0])).all():
                dellist.append(atom.index)
        print(dellist)
        del atoms[dellist]

        atoms1 = atoms.copy()
        atoms2 = atoms.copy()

        atoms1.append(ase.Atom('Nb', pos1))
        # atoms1.append(ase.Atom('Nb', pos3))
        # set this atom to be other type so we can fix it in lammps
        atoms1.append(ase.Atom('W', pos3))
        atoms2.append(ase.Atom('Nb', pos2))
        # atoms2.append(ase.Atom('Nb', pos3))
        atoms2.append(ase.Atom('W', pos3))

        # for vasp
        self.write_poscar_fix(atoms1, "posi")  # change it manually then
        self.write_poscar_fix(atoms2, "posf")

        # for md
        system, elements = am.convert.ase_Atoms.load(atoms1)
        lmp.atom_data.dump(system, "init.txt")
        shutil.copy("init.txt", "init0.txt")

        system, elements = am.convert.ase_Atoms.load(atoms2)
        lmp.atom_data.dump(system, "final.txt")
        shutil.copy("final.txt", "init1.txt")
Пример #18
0
 def get_atoms_obj(self):
     """
     Builds NP in the form of a Cu NP ase.Atoms object
     - stores under self.atoms_obj property
     - returns atoms_obj
     """
     if self._atoms_obj is None:
         self._atoms_obj = ase.Atoms(
             [ase.Atom('Cu', (i.x, i.y, i.z)) for i in self.atoms])
     return self._atoms_obj
Пример #19
0
 def Atoms(self):
     """
     convert to ase object
     """
     import ase
     mu = pb.Molecule(self.m)
     m2 = ase.Atoms([])
     for ai in mu.atoms:
         m2.append(ase.Atom(ai.atomicnum, ai.coords))
     return m2
Пример #20
0
 def to_ase(self):
     cell = self.content['cell']
     atoms = [
         ase.Atom(site[0], tuple(site[1]))
         for site in self.content['positions']
     ]
     aseobj = ase.Atoms(atoms)
     aseobj.set_cell(cell)
     aseobj.set_pbc(self.content['periodicity'])
     return aseobj
Пример #21
0
def plot_centres_xsf(structure, w90_calc, filename='./wannier.xsf'):
    """
    Plots Wannier function centres in .xsf format
    """
    a = structure.get_ase()
    new_a = a.copy()
    out = w90_calc.out.output_parameters.get_dict()['wannier_functions_output']
    coords = [i['wf_centres'] for i in out]
    for c in coords:
        new_a.append(ase.Atom('X', c))
    new_a.write(filename)
Пример #22
0
def read_bopfox(filename):
    f = open(filename,'r')
    lines = f.readlines()
    f.close()
    line_index = 0
    newlines = []
    # strip out comment lines
    for line in lines:
        l = line.strip()
        if len(l) < 1:
          continue
        if l.startswith("/"):
          continue
        if l.startswith("#"):
          continue
        newlines.append(l)
    lines = newlines
    a = ase.Atoms()
    box = numpy.zeros((3,3))
    coord = "cartesian"
    scale = 1.0
    while line_index < len(lines):
        l = lines[line_index]
        if "magnetisation" in l:
            break
        if "=" in l:
            key = l.split("=")[0].strip()
            if key == "StrucName":
                pass
            elif key == "aLat":
                scale = float(l.split("=")[1].strip())
            elif key == "a1":
                box[0] = [float(i) for i in l.split("=")[1].strip().split()]
            elif key == "a2":
                box[1] = [float(i) for i in l.split("=")[1].strip().split()]
            elif key == "a3":
                box[2] = [float(i) for i in l.split("=")[1].strip().split()]
            elif key == "coord":
                coord = l.split("=")[1].strip()
        else:
            atomdata = l.strip().split()
            symbol = atomdata[0]
            x, y, z = float(atomdata[1]), float(atomdata[2]), float(atomdata[3])
            a.append(ase.Atom(symbol, (x, y, z)))
        line_index += 1
    a.cell = box * scale
    if coord == "direct":
        for i in range(len(a)):
            a.positions[i] = numpy.dot(a.positions[i], a.cell)
    else: 
        for i in range(len(a)):
            a.positions[i] *= scale
    return a
Пример #23
0
    def setElsProps(self):
        for e in self.setting['elements']:
            a = ase.Atom(e)
            mass = a.mass / _Nav
            number = a.number

            form = pt.formula(a.symbol)
            e_ = form.structure[0][1]
            crys = e_.crystal_structure['symmetry'] 
            a_ = e_.crystal_structure['a'] 
            self.elsProps.append({'ase':a, 'mass': mass, 'structure': crys,
                'a':a_ , 'number':number})
    def check_dissociated(self, cutoff=1.2):
        """Check if adsorbate dissociates"""
        dissociated = False
        if not len(self.B) > self.nslab + 1:  # only one adsorbate
            return dissociated

        adsatoms = [atom for atom in self.B[self.nslab:]]
        ads0, ads1 = set(atom.symbol for atom in adsatoms)
        bond_dist = get_ads_dist(self.B, ads0, ads1)

        Cradii = [
            cradii[atom.number]
            for atom in [ase.Atom(ads0), ase.Atom(ads1)]
        ]
        bond_dist0 = sum(Cradii)

        if bond_dist > cutoff * bond_dist0:
            print('DISSOCIATED: {} Ang > 1.2 * {} Ang'.format(
                bond_dist, bond_dist0))
            dissociated = True

            return dissociated
Пример #25
0
def plot_centres_xsf(structure, w90_calc, filename='./wannier.xsf'):
    """
    Plots Wannier function centres in .xsf format
    """
    # Disabling the import-error since this is an optional requirement
    import ase  # pylint: disable=import-error

    a = structure.get_ase()
    new_a = a.copy()
    out = w90_calc.out.output_parameters.get_dict()['wannier_functions_output']
    coords = [i['wf_centres'] for i in out]
    for c in coords:
        new_a.append(ase.Atom('X', c))
    new_a.write(filename)
Пример #26
0
def _structure_to_atoms(self) -> Atoms:
    """
    Returns the structure as an ASE Atoms object.

    Returns
    -------
    atomic configuration
    """
    import ase
    conf = ase.Atoms(pbc=self.pbc)
    conf.set_cell(self.cell)
    for symbol, position in zip(self.chemical_symbols, self.positions):
        conf.append(ase.Atom(symbol, position))
    return conf
def launch(box_size, dimer_separation, firstdimer_elements,
           seconddimer_elements, structure_group_label,
           structure_group_description, dryrun):
    """
    Script for creating surface structures for a given size and matrix element. Generates
    a set of structures with varying vacuum thickness
    """
    if not dryrun:
        structure_group = Group.objects.get_or_create(
            label=structure_group_label,
            description=structure_group_description)[0]
    else:
        structure_group = None

    box_size = float(box_size)
    extras = {'box_size': box_size}
    base_structure = ase.Atoms(cell=([box_size, box_size, box_size]), pbc=True)

    seperation_distances = get_displacements_array(dimer_separation)

    firstdimer_elements = prep_elementlist(firstdimer_elements)
    seconddimer_elements = prep_elementlist(seconddimer_elements)

    previous_firstdimer_elements = [
    ]  # to avoid duplication in generated structures
    for firstdimer_element in firstdimer_elements:
        dimer_structure = base_structure.copy()

        # create and store single atom version
        first_atom = ase.Atom(firstdimer_element)
        dimer_structure.append(first_atom)
        extras['firstdimer_element'] = firstdimer_element
        extras['second_element'] = ""
        extras['atomatom_distance'] = ""
        store_asestructure(dimer_structure, extras, structure_group, dryrun)

        dimer_structure.append(first_atom)  #This will be changed later
        for seconddimer_element in seconddimer_elements:
            dimer_structure[1].symbol = seconddimer_element

            if seconddimer_element in previous_firstdimer_elements:
                continue
            extras['second_element'] = seconddimer_element
            for distance in seperation_distances:
                dimer_structure[1].position[0] = distance
                extras['atomatom_distance'] = distance
                store_asestructure(dimer_structure, extras, structure_group,
                                   dryrun)

        previous_firstdimer_elements += [firstdimer_element]
Пример #28
0
def read_aims(filename):
    f = open(filename)

    atoms = ase.Atoms()

    l = 0
    cell = numpy.zeros((3, 3))
    for line in f:
        line = line[:line.find('#')]
        line = line.strip()
        if len(line) == 0: continue
        fields = line.split()

        if fields[0] == 'lattice_vector':
            cell[l, 0] = float(fields[1])
            cell[l, 1] = float(fields[2])
            cell[l, 2] = float(fields[3])
            l += 1
            if l == 3:
                atoms.set_cell(cell)
                print cell

        if fields[0] == 'atom':
            pos = numpy.array(
                (float(fields[1]), float(fields[2]), float(fields[3])))
            element = fields[4]
            atoms.append(ase.Atom(element, position=pos))

        if fields[0] == 'atom_frac':
            scaled_pos = numpy.array(
                (float(fields[1]), float(fields[2]), float(fields[3])))
            pos = numpy.dot(cell, scaled_pos)
            element = fields[4]
            atoms.append(ase.Atom(element, position=pos))
    f.close()
    return atoms
Пример #29
0
def get_gic_structure(nprim=[2, 2, 1],
                      molecule=None,
                      distance=3.0,
                      layer_distance=3.35,
                      set_nemdtag=True):
    """ Create a graphene intercalation compund
    Parameters
    -------------
    distance : float, unit=[A]
        distance between the molecule and graphite layer
    """
    ## make a graphtie structure
    graphite = get_stacking_graphene(na=nprim[0],
                                     nb=nprim[1],
                                     nc=nprim[2],
                                     distance=layer_distance)

    ## center of a hexagonal lattice in the top layer
    natoms_layer = int(len(graphite) / nprim[2])
    center_hex = _get_center_of_a_hexagon(graphite[-natoms_layer:])

    ## get the center of the molecule
    center_mol = np.zeros(3)
    for j in range(3):
        center_mol[j] += np.average(molecule.get_positions()[:, j])

    ## put a molecule on the center of the hexagonal lattice
    ## Be careful for the z-position
    disp = center_hex + np.array([0, 0, distance]) - center_mol
    intercalate = graphite.copy()
    intercalate.cell[2, 2] += distance * 2.0 - layer_distance
    for ia in range(len(molecule)):
        intercalate.append(
            ase.Atom(symbol=molecule[ia].symbol,
                     position=molecule[ia].position + disp))
    ## If the number of graphene layers is even, the position of the next layers
    ## should be adjusted.
    if nprim[2] % 2 == 0:
        intercalate = _superpose_next_intercalated_layer(
            intercalate, natoms_layer=natoms_layer)

    ##
    _set_element_center(intercalate, element="Fe")

    ## set tag for NEMD simulation
    if set_nemdtag:
        set_tags4md_structure(intercalate)
    return intercalate
Пример #30
0
def _get_ase_atoms(cjson_atoms):
    elements = cjson_atoms.get('elements', {})
    number = elements.get('number')
    if number is None:
        symbol = elements.get('symbol')
        if symbol is None:
            raise Exception('Atomic numbers are missing.')
        number = list(map(lambda sym: ase.data.atomic_numbers[sym], symbol))
    n_atoms = len(number)
    positions = cjson_atoms.get('coords', {}).get('3d', [])
    if len(positions) != 3 * n_atoms:
        raise Exception('Atomic positions are missing.')
    atoms = []
    for i in range(n_atoms):
        atoms.append(ase.Atom(number[i], positions[i * 3:i * 3 + 3]))
    return atoms