Exemplo n.º 1
0
 def test_set_abc(self):
     a = 4.3
     b = 3.2
     c = 8.1
     alpha = 110
     origin = [3.1, 1.4, 4.1]
     box = am.Box(a=a, b=b, c=c, alpha=alpha, origin=origin)
     assert np.isclose(box.a, a)
     assert np.isclose(box.b, b)
     assert np.isclose(box.c, c)
     assert np.isclose(box.alpha, alpha)
     assert np.isclose(box.beta , 90.0)
     assert np.isclose(box.gamma, 90.0)
     assert np.allclose(box.origin, origin)
     
     a = 24.5
     b = 236.2
     c = 42.5
     beta = 101
     box = am.Box(a=a, b=b, c=c, beta=beta)
     assert np.isclose(box.a, a)
     assert np.isclose(box.b, b)
     assert np.isclose(box.c, c)
     assert np.isclose(box.alpha, 90.0)
     assert np.isclose(box.beta , beta)
     assert np.isclose(box.gamma, 90.0)
     assert np.allclose(box.origin, np.zeros(3))
Exemplo n.º 2
0
    def test_set_hi_los(self):
        xlo = -1
        xhi = 5
        ylo = -2.1
        yhi = 5
        zlo = 0.1
        zhi = 3.1
        xy = 0.5
        box = am.Box(xlo=xlo,
                     xhi=xhi,
                     ylo=ylo,
                     yhi=yhi,
                     zlo=zlo,
                     zhi=zhi,
                     xy=xy)
        assert np.isclose(box.xlo, xlo)
        assert np.isclose(box.xhi, xhi)
        assert np.isclose(box.ylo, ylo)
        assert np.isclose(box.yhi, yhi)
        assert np.isclose(box.zlo, zlo)
        assert np.isclose(box.zhi, zhi)
        assert np.isclose(box.xz, 0.0)
        assert np.isclose(box.xy, xy)
        assert np.isclose(box.yz, 0.0)

        xlo = -143
        xhi = 125
        ylo = -124
        yhi = 364
        zlo = -172
        zhi = 235
        yz = 10
        box = am.Box(xlo=xlo,
                     xhi=xhi,
                     ylo=ylo,
                     yhi=yhi,
                     zlo=zlo,
                     zhi=zhi,
                     yz=yz)
        assert np.isclose(box.xlo, xlo)
        assert np.isclose(box.xhi, xhi)
        assert np.isclose(box.ylo, ylo)
        assert np.isclose(box.yhi, yhi)
        assert np.isclose(box.zlo, zlo)
        assert np.isclose(box.zhi, zhi)
        assert np.isclose(box.xz, 0.0)
        assert np.isclose(box.xy, 0.0)
        assert np.isclose(box.yz, yz)
Exemplo n.º 3
0
 def test_default(self):
     box = am.Box()
     assert np.allclose(box.avect, [1., 0., 0.])
     assert np.allclose(box.bvect, [0., 1., 0.])
     assert np.allclose(box.cvect, [0., 0., 1.])
     assert np.allclose(box.origin, [0., 0., 0.])
     assert np.allclose(box.vects, [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])
     assert np.isclose(box.a, 1.0)
     assert np.isclose(box.b, 1.0)
     assert np.isclose(box.c, 1.0)
     assert np.isclose(box.alpha, 90.0)
     assert np.isclose(box.beta , 90.0)
     assert np.isclose(box.gamma, 90.0)
     assert np.isclose(box.xlo, 0.0)
     assert np.isclose(box.xhi, 1.0)
     assert np.isclose(box.ylo, 0.0)
     assert np.isclose(box.yhi, 1.0)
     assert np.isclose(box.zlo, 0.0)
     assert np.isclose(box.zhi, 1.0)
     assert np.isclose(box.lx, 1.0)
     assert np.isclose(box.ly, 1.0)
     assert np.isclose(box.lz, 1.0)
     assert np.isclose(box.xy, 0.0)
     assert np.isclose(box.xz, 0.0)
     assert np.isclose(box.yz, 0.0)
     assert np.isclose(box.volume, 1.0)
Exemplo n.º 4
0
    def test_set_lengths(self):
        lx=42
        ly=57
        lz=112
        xz=15
        origin=[1,2,3]
        box = am.Box(lx=lx, ly=ly, lz=lz, xz=xz, origin=origin)
        assert np.isclose(box.lx, lx)
        assert np.isclose(box.ly, ly)
        assert np.isclose(box.lz, lz)
        assert np.isclose(box.xz, xz)
        assert np.isclose(box.xy, 0.0)
        assert np.isclose(box.yz, 0.0)
        assert np.allclose(box.origin, origin)

        lx=163
        ly=347
        lz=235
        xy=19
        box.set_lengths(lx=lx, ly=ly, lz=lz, xy=xy)
        assert np.isclose(box.lx, lx)
        assert np.isclose(box.ly, ly)
        assert np.isclose(box.lz, lz)
        assert np.isclose(box.xz, 0.0)
        assert np.isclose(box.xy, xy)
        assert np.isclose(box.yz, 0.0)
        assert np.allclose(box.origin, np.zeros(3))
Exemplo n.º 5
0
def test_dmag_and_dvect():
    pos_0 = np.random.uniform(1.0, 10.0, size=(200, 3))
    pos_0[10] = [12.1234, 12.1234, 12.1234]
    pos_0[11] = [7.124, 132.15, 12.235]

    pos_1 = np.random.uniform(1.0, 10.0, size=(200, 3))
    pos_1[10] = [12.1234, 12.1234, 12.1234]
    pos_1[11] = [18.124, 1.15, 1.235]

    box = am.Box(vects=[[20.0, 0.0, 0.0], [0.0, 135.0, 0.0], [0.0, 0.0, 20.0]])

    # Test for all periodic boundaries
    pbc = [True, True, True]
    dvect = am.dvect(pos_0, pos_1, box, pbc)
    dmag = am.dmag(pos_0, pos_1, box, pbc)

    assert np.allclose(np.linalg.norm(dvect, axis=1), dmag)
    assert np.allclose(dvect[10], [0.0, 0.0, 0.0])
    assert np.allclose(dvect[11], [-9., 4., 9.])
    assert np.isclose(dmag[10], 0.0)
    assert np.isclose(dmag[11], 13.341664064126334)

    # Test for all nono-periodic boundaries
    pbc = [False, False, False]
    dvect = am.dvect(pos_0, pos_1, box, pbc)
    dmag = am.dmag(pos_0, pos_1, box, pbc)

    assert np.allclose(np.linalg.norm(dvect, axis=1), dmag)
    assert np.allclose(dvect[10], [0.0, 0.0, 0.0])
    assert np.allclose(dvect[11], [11., -131., -11.])
    assert np.isclose(dmag[10], 0.0)
    assert np.isclose(dmag[11], 131.92043056327552)
Exemplo n.º 6
0
def test_vectortocartesian():
    # Test 3 indices
    box = am.Box(a=3, b=4, c=5, alpha=90, beta=90, gamma=90)
    assert np.allclose(am.tools.miller.vectortocartesian([1, 2, 3], box),
                       np.array([3, 8, 15]))

    box = am.Box(a=3, b=4, c=5, alpha=90, beta=90, gamma=80)
    assert np.allclose(am.tools.miller.vectortocartesian([1, 1, 1], box),
                       np.array([[3.69459271, 3.93923101, 5.]]))
    # Test 4 indices
    box = am.Box(a=3, b=3, c=5, alpha=90, beta=90, gamma=120)
    assert np.allclose(am.tools.miller.vectortocartesian([-2, 1, 1, 1], box),
                       np.array([-9, 0, 5]))

    box = am.Box(a=3, b=4, c=5, alpha=90, beta=90, gamma=120)
    with pytest.raises(AssertionError):
        am.tools.miller.vectortocartesian([-2, 1, 1, 1], box)
Exemplo n.º 7
0
def test_vector_crystal_to_cartesian():
    # Test 3 indices
    box = am.Box(a=3, b=4, c=5, alpha=90, beta=90, gamma=90)
    assert np.allclose(vector_crystal_to_cartesian([1,2,3], box),
                       np.array([ 3, 8, 15]))

    box = am.Box(a=3, b=4, c=5, alpha=90, beta=90, gamma=80)
    assert np.allclose(vector_crystal_to_cartesian([1,1,1], box),
                       np.array([[3.69459271, 3.93923101, 5.        ]]))
    # Test 4 indices
    box = am.Box(a=3, b=3, c=5, alpha=90, beta=90, gamma=120)
    assert np.allclose(vector_crystal_to_cartesian([-2, 1, 1, 1], box),
                       np.array([-9, 0, 5]))
    
    box = am.Box(a=3, b=4, c=5, alpha=90, beta=90, gamma=120)
    with pytest.raises(ValueError):
        vector_crystal_to_cartesian([-2, 1, 1, 1], box)
Exemplo n.º 8
0
    def test_is_lammps_norm(self):
        vects = np.array([[123, 0, 0], [4, 142, 0], [7, -9, 145]])
        box = am.Box(vects=vects)
        assert box.is_lammps_norm()

        vects = np.array([[123, 1, 0], [4, 142, 0], [7, -9, 145]])
        box = am.Box(vects=vects)
        assert not box.is_lammps_norm()

        vects = np.array([[123, 0, 1], [4, 142, 0], [7, -9, 145]])
        box = am.Box(vects=vects)
        assert not box.is_lammps_norm()

        vects = np.array([[123, 0, 0], [4, 142, 1], [7, -9, 145]])
        box = am.Box(vects=vects)
        assert not box.is_lammps_norm()

        vects = np.array([[-123, 0, 0], [4, 142, 0], [7, -9, 145]])
        box = am.Box(vects=vects)
        assert not box.is_lammps_norm()

        vects = np.array([[123, 0, 0], [4, -142, 0], [7, -9, 145]])
        box = am.Box(vects=vects)
        assert not box.is_lammps_norm()

        vects = np.array([[123, 0, 0], [4, 142, 0], [7, -9, -145]])
        box = am.Box(vects=vects)
        assert not box.is_lammps_norm()
Exemplo n.º 9
0
    def fcc_edge(self):
        axes = np.array([[1, 0, -1], [1, 1, 1], [1, -2, 1]])

        alat = uc.set_in_units(4.0248, 'angstrom')

        C11 = uc.set_in_units(113.76, 'GPa')
        C12 = uc.set_in_units(61.71, 'GPa')
        C44 = uc.set_in_units(31.25, 'GPa')

        c = am.ElasticConstants(C11=C11, C12=C12, C44=C44)
        burgers = alat / 2 * np.array([1., 0., -1.])

        # initializing a new Stroh object using the data
        stroh = am.defect.Stroh(c, burgers, axes=axes)

        pos_test = uc.set_in_units(np.array([12.4, 13.5, -10.6]), 'angstrom')

        disp = stroh.displacement(pos_test)

        print("displacement =", uc.get_in_units(disp, 'angstrom'), 'angstrom')

        # monopole system
        box = am.Box(a=alat, b=alat, c=alat)
        atoms = am.Atoms(natoms=4,
                         prop={
                             'atype':
                             1,
                             'pos': [[0.0, 0.0, 0.0], [0.5, 0.5, 0.0],
                                     [0.0, 0.5, 0.5], [0.5, 0.0, 0.5]]
                         })
        ucell = am.System(atoms=atoms, box=box, scale=True)
        system = am.rotate_cubic(ucell, axes)

        shift = np.array(
            [0.12500000000000, 0.50000000000000, 0.00000000000000])
        new_pos = system.atoms_prop(key='pos', scale=True) + shift
        system.atoms_prop(key='pos', value=new_pos, scale=True)

        system.supersize((-7, 7), (-6, 6), (0, 1))
        disp = stroh.displacement(system.atoms_prop(key='pos'))

        system.atoms_prop(key='pos', value=system.atoms_prop(key='pos') + disp)

        system.pbc = (False, False, True)
        system.wrap()

        pos = system.atoms_prop(key='pos')
        x = uc.get_in_units(pos[:, 0], 'angstrom')
        y = uc.get_in_units(pos[:, 1], 'angstrom')

        plt.figure(figsize=(8, 8))
        plt.scatter(x, y, s=30)
        plt.xlim(min(x), max(x))
        plt.ylim(min(y), max(y))
        plt.xlabel('x-position (Angstrom)', fontsize='large')
        plt.ylabel('y-position (Angstrom)', fontsize='large')
        plt.show()
Exemplo n.º 10
0
 def test_model(self):
     box = am.Box.cubic(5.42)
     model = box.model()
     assert np.allclose(uc.value_unit(model['box']['avect']), np.array([5.42, 0.0, 0.0]))
     assert np.allclose(uc.value_unit(model['box']['bvect']), np.array([0.0, 5.42, 0.0]))
     assert np.allclose(uc.value_unit(model['box']['cvect']), np.array([0.0, 0.0, 5.42]))
     assert np.allclose(uc.value_unit(model['box']['origin']), np.array([0.0, 0.0, 0.0]))
     box = am.Box(model=model)
     assert np.allclose(box.vects, np.array([[5.42, 0.0, 0.0],
                                             [0.0, 5.42, 0.0], 
                                             [0.0, 0.0, 5.42]]))
Exemplo n.º 11
0
    def load_model(self, model, name=None):
        """
        Loads record contents from a given model.

        Parameters
        ----------
        model : str or DataModelDict
            The model contents of the record to load.
        name : str, optional
            The name to assign to the record.  Often inferred from other
            attributes if not given.
        """
        # Load universal and subset content
        super().load_model(model, name=name)
        calc = self.model[self.modelroot]

        # Load calculation-specific content
        run_params = calc['calculation']['run-parameter']
        self.strainrange = run_params['strain-range']

        # Load phase-state info
        self.pressure_xx = uc.value_unit(calc['phase-state']['pressure-xx'])
        self.pressure_yy = uc.value_unit(calc['phase-state']['pressure-yy'])
        self.pressure_zz = uc.value_unit(calc['phase-state']['pressure-zz'])

        # Load results
        if self.status == 'finished':
            self.__initial_dump = {
                'filename': calc['initial-system']['artifact']['file'],
                'symbols': calc['initial-system']['symbols']
            }

            self.__final_dump = {
                'filename': calc['final-system']['artifact']['file'],
                'symbols': calc['final-system']['symbols']
            }

            lx = uc.value_unit(calc['measured-box-parameter']['lx'])
            ly = uc.value_unit(calc['measured-box-parameter']['ly'])
            lz = uc.value_unit(calc['measured-box-parameter']['lz'])
            xy = uc.value_unit(calc['measured-box-parameter']['xy'])
            xz = uc.value_unit(calc['measured-box-parameter']['xz'])
            yz = uc.value_unit(calc['measured-box-parameter']['yz'])
            self.__final_box = am.Box(lx=lx, ly=ly, lz=lz, xy=xy, xz=xz, yz=yz)

            self.__potential_energy = uc.value_unit(calc['cohesive-energy'])

            mps = calc['measured-phase-state']
            self.__measured_pressure_xx = uc.value_unit(mps['pressure-xx'])
            self.__measured_pressure_yy = uc.value_unit(mps['pressure-yy'])
            self.__measured_pressure_zz = uc.value_unit(mps['pressure-zz'])
            self.__measured_pressure_xy = uc.value_unit(mps['pressure-xy'])
            self.__measured_pressure_xz = uc.value_unit(mps['pressure-xz'])
            self.__measured_pressure_yz = uc.value_unit(mps['pressure-yz'])
Exemplo n.º 12
0
def load(poscar):
    """
    Reads a poscar-style coordination file for a system.
    Returns an atomman.System, and a list of elements if the file gives them. 
    """
    #Read in all lines of the file
    with uber_open_rmode(poscar) as f:
        lines = f.read().split('\n')

    #Interpret box information
    box_scale = float(lines[1])
    avect = np.array(lines[2].split(), dtype='float64') * box_scale
    bvect = np.array(lines[3].split(), dtype='float64') * box_scale
    cvect = np.array(lines[4].split(), dtype='float64') * box_scale
    box = am.Box(avect=avect, bvect=bvect, cvect=cvect)

    #Read in elements, number of types, and style info
    try:
        typenums = np.array(lines[5].split(), dtype='int32')
        elements = [None for n in xrange(len(typenums))]
        style = lines[6]
        start_i = 7
    except:
        elements = lines[5].split()
        typenums = np.array(lines[6].split(), dtype='int32')
        style = lines[7]
        start_i = 8

    #Build atype list
    atype = np.array([], dtype='int32')
    for i in xrange(len(typenums)):
        atype = np.hstack((atype, np.full(typenums[i], i + 1, dtype='int32')))

    #Check which coordinate style to use
    if style[0] in 'cCkK':
        scale = False
    else:
        scale = True

    #Read in positions
    natoms = np.sum(typenums)
    pos = np.empty((natoms, 3), dtype='float64')
    count = 0
    for i in xrange(start_i, len(lines)):
        terms = lines[i].split()
        if len(terms) > 0:
            pos[count, :] = np.array(terms, dtype='float64')
        count += 1

    atoms = am.Atoms(natoms=natoms, prop={'atype': atype, 'pos': pos})
    system = am.System(atoms=atoms, box=box, scale=scale)

    return system, elements
Exemplo n.º 13
0
def load(ase_atoms):
    """Convert an ase.Atoms into an atomman.System and list of elements."""

    assert has_ase, 'ase not imported'

    box = am.Box(vects=ase_atoms.get_cell())
    atoms = am.Atoms(natoms=len(ase_atoms))
    atoms.prop(key='pos', value=ase_atoms.get_positions())

    all_elements = np.array(ase_atoms.get_chemical_symbols())
    elements, atype = np.unique(all_elements, return_inverse=True)
    atype += 1

    atoms.prop(key='atype', value=atype)

    return am.System(atoms=atoms, box=box), elements
Exemplo n.º 14
0
    def test_atomic_no_imageflags(self):
        
        box = am.Box(vects=[[1.25694013, 0.        , 0.        ],
                            [1.17551244, 4.01690452, 0.        ],
                            [0.23122344, 0.0768582 , 0.76391945]])
        pos = [[0.53342537, 0.70899278, 0.21800393],
               [0.8766086 , 0.98893671, 0.57889022],
               [0.78898178, 0.44740662, 0.49997271],
               [0.78302097, 0.06197394, 0.77049739]]
        atoms = am.Atoms(pos=pos, atype=1)
        symbols = 'Al'
        pbc = (True, True, True)

        system = am.System(atoms=atoms, box=box, scale=True, 
                           symbols=symbols, pbc=pbc)

        self.load_dump(system, atom_style='atomic', units='metal')
Exemplo n.º 15
0
def load(cif):
    """Reads in a CIF crystal file and returns an atomman.System and list of elements."""
    
    assert has_diffpy, 'diffpy.Structure not imported'
    
    dps = diffpy.Structure.structure.Structure()
    
    #load from an open file-like object
    if hasattr(cif, 'read'):
        dps.readStr(cif.read())
    
    #load using a file name
    elif os.path.isfile(cif):
        dps.read(cif)
    
    #load from a string
    else:
        dps.readStr(cif)
    
    all_elements = dps.element
    elements, all_atype = np.unique(all_elements, return_inverse=True)
    all_atype += 1
    all_pos = dps.xyz
    
    atype = []
    pos = []
    for a1, p1 in zip(all_atype, all_pos):
        noMatch = True
        for a2, p2 in zip(atype, pos):
            if a1 == a2 and np.allclose(p1, p2):
                noMatch = False
                break
        if noMatch:
            atype.append(a1)
            pos.append(p1)
    
    atoms = am.Atoms(natoms=len(pos), prop={'atype':atype, 'pos':pos})    
    
    box = am.Box(a=dps.lattice.a, 
                 b=dps.lattice.b, 
                 c=dps.lattice.c, 
                 alpha=dps.lattice.alpha, 
                 beta=dps.lattice.beta, 
                 gamma=dps.lattice.gamma)
    
    return am.System(atoms=atoms, box=box, pbc=(True,True,True), scale=True), list(elements)
Exemplo n.º 16
0
 def test_set_vectors(self):
     avect = [3.2, 0.0, 0.0]
     bvect = [0.1, 3.2, 0.0]
     cvect = [-0.2, 0.15, 3.2]
     origin = [3.1, 1.4, 4.1]
     box = am.Box(avect=avect, bvect=bvect, cvect=cvect, origin=origin)
     assert np.allclose(box.avect, avect)
     assert np.allclose(box.bvect, bvect)
     assert np.allclose(box.cvect, cvect)
     assert np.allclose(box.origin, origin)
     
     avect = [6.2, 0.0, 0.0]
     bvect = [0.0, 4.2, 0.0]
     cvect = [0.0, 0.1, 5.2]
     box.set_vectors(avect=avect, bvect=bvect, cvect=cvect)
     assert np.allclose(box.avect, avect)
     assert np.allclose(box.bvect, bvect)
     assert np.allclose(box.cvect, cvect)
     assert np.allclose(box.origin, np.zeros(3))
Exemplo n.º 17
0
    def process_results(self, results_dict):
        """
        Processes calculation results and saves them to the object's results
        attributes.

        Parameters
        ----------
        results_dict: dict
            The dictionary returned by the calc() method.
        """
        self.__initial_dump = {
            'filename': results_dict['dumpfile_initial'],
            'symbols': results_dict['symbols_initial']
        }
        self.__final_dump = {
            'filename': results_dict['dumpfile_final'],
            'symbols': results_dict['symbols_final']
        }
        lx = results_dict['lx'] / (self.system_mods.a_mults[1] -
                                   self.system_mods.a_mults[0])
        ly = results_dict['ly'] / (self.system_mods.b_mults[1] -
                                   self.system_mods.b_mults[0])
        lz = results_dict['lz'] / (self.system_mods.c_mults[1] -
                                   self.system_mods.c_mults[0])
        xy = results_dict['xy'] / (self.system_mods.b_mults[1] -
                                   self.system_mods.b_mults[0])
        xz = results_dict['xz'] / (self.system_mods.c_mults[1] -
                                   self.system_mods.c_mults[0])
        yz = results_dict['yz'] / (self.system_mods.c_mults[1] -
                                   self.system_mods.c_mults[0])
        self.__final_box = am.Box(lx=lx, ly=ly, lz=lz, xy=xy, xz=xz, yz=yz)
        self.__potential_energy = results_dict['E_pot']
        self.__measured_pressure_xx = results_dict['measured_pxx']
        self.__measured_pressure_yy = results_dict['measured_pyy']
        self.__measured_pressure_zz = results_dict['measured_pzz']
        self.__measured_pressure_xy = results_dict['measured_pxy']
        self.__measured_pressure_xz = results_dict['measured_pxz']
        self.__measured_pressure_yz = results_dict['measured_pyz']
Exemplo n.º 18
0
    def ucell(self, a_scale, c_scale):
        """
        Generates a bct unit cell for intermediate structures based on the 
        given bcc and fcc lattice constants.

        For the scaling parameters, values of a_scale = c_scale = 0 corresponds
        to the given fcc lattice, and values of a_scale = c_scale = 1
        corresponds to the given bcc lattice.

        Parameters
        ----------
        a_scale : float
            Scaling parameter for the bct structure's a lattice parameter.
        c_scale : float
            Scaling parameter for the bct structure's c lattice parameter.

        Returns
        -------
        ucell : atomman.System
            The corresponding bct unit cell.
        """
        # Set the ideal constants based on a_fcc and a_bcc
        a_0 = self.a_fcc * 2**0.5 / 2
        c_0 = self.a_fcc
        a_1 = c_1 = self.a_bcc
        
        # Compute the bct lattice constants using the scale parameters
        a = a_0 * (1 - a_scale) + a_1 * a_scale
        c = c_0 * (1 - c_scale) + c_1 * c_scale
        
        # Generate box, atoms and system for the bct unit cell
        box = am.Box().tetragonal(a=a, c=c)
        atoms = am.Atoms(pos=[[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]])
        ucell = am.System(atoms=atoms, box=box, symbols=self.symbol, scale=True)
        
        return ucell
Exemplo n.º 19
0
 def boxhexagonal(self):
     return am.Box(a=3, b=3, c=8, alpha=90, beta=90, gamma=120)
Exemplo n.º 20
0
def calc_cij(lammps_command,
             system,
             potential,
             symbols,
             p_xx=0.0,
             p_yy=0.0,
             p_zz=0.0,
             delta=1e-5,
             cycle=0):
    """Runs cij_script and returns current Cij, stress, Ecoh, and new system guess."""

    #Get lammps units
    lammps_units = lmp.style.unit(potential.units)

    #Define lammps variables
    lammps_variables = {}
    lammps_variables['atomman_system_info'] = lmp.sys_gen(
        units=potential.units,
        atom_style=potential.atom_style,
        ucell=system,
        size=np.array([[0, 3], [0, 3], [0, 3]]))
    lammps_variables['atomman_pair_info'] = potential.pair_info(symbols)
    lammps_variables['delta'] = delta
    lammps_variables['steps'] = 2

    #Write lammps input script
    template_file = 'cij.template'
    lammps_script = 'cij.in'
    with open(template_file) as f:
        template = f.read()
    with open(lammps_script, 'w') as f:
        f.write(iprPy.tools.filltemplate(template, lammps_variables, '<', '>'))

    #Run lammps
    output = lmp.run(lammps_command, lammps_script)
    shutil.move('log.lammps', 'cij-' + str(cycle) + '-log.lammps')

    #Extract LAMMPS thermo data. Each term ranges i=0-12 where i=0 is undeformed
    #The remaining values are for -/+ strain pairs in the six unique directions
    lx = uc.set_in_units(np.array(output.finds('Lx')), lammps_units['length'])
    ly = uc.set_in_units(np.array(output.finds('Ly')), lammps_units['length'])
    lz = uc.set_in_units(np.array(output.finds('Lz')), lammps_units['length'])
    xy = uc.set_in_units(np.array(output.finds('Xy')), lammps_units['length'])
    xz = uc.set_in_units(np.array(output.finds('Xz')), lammps_units['length'])
    yz = uc.set_in_units(np.array(output.finds('Yz')), lammps_units['length'])

    pxx = uc.set_in_units(np.array(output.finds('Pxx')),
                          lammps_units['pressure'])
    pyy = uc.set_in_units(np.array(output.finds('Pyy')),
                          lammps_units['pressure'])
    pzz = uc.set_in_units(np.array(output.finds('Pzz')),
                          lammps_units['pressure'])
    pxy = uc.set_in_units(np.array(output.finds('Pxy')),
                          lammps_units['pressure'])
    pxz = uc.set_in_units(np.array(output.finds('Pxz')),
                          lammps_units['pressure'])
    pyz = uc.set_in_units(np.array(output.finds('Pyz')),
                          lammps_units['pressure'])
    try:
        pe = uc.set_in_units(np.array(output.finds('v_peatom')),
                             lammps_units['energy'])
        assert len(pe) > 0
    except:
        pe = uc.set_in_units(np.array(output.finds('peatom')),
                             lammps_units['energy'])

    #Set the six non-zero strain values
    strains = np.array([(lx[2] - lx[1]) / lx[0], (ly[4] - ly[3]) / ly[0],
                        (lz[6] - lz[5]) / lz[0], (yz[8] - yz[7]) / lz[0],
                        (xz[10] - xz[9]) / lz[0], (xy[12] - xy[11]) / ly[0]])

    #calculate cij using stress changes associated with each non-zero strain
    cij = np.empty((6, 6))
    for i in xrange(6):
        delta_stress = np.array([
            pxx[2 * i + 1] - pxx[2 * i + 2], pyy[2 * i + 1] - pyy[2 * i + 2],
            pzz[2 * i + 1] - pzz[2 * i + 2], pyz[2 * i + 1] - pyz[2 * i + 2],
            pxz[2 * i + 1] - pxz[2 * i + 2], pxy[2 * i + 1] - pxy[2 * i + 2]
        ])

        cij[i] = delta_stress / strains[i]

    for i in xrange(6):
        for j in xrange(i):
            cij[i, j] = cij[j, i] = (cij[i, j] + cij[j, i]) / 2

    C = am.ElasticConstants(Cij=cij)

    if np.allclose(C.Cij, 0.0):
        raise RuntimeError('Divergence of elastic constants to <= 0')
    try:
        S = C.Sij
    except:
        raise RuntimeError('singular C:\n' + str(C.Cij))

    #extract the current stress state
    stress = -1 * np.array([[pxx[0], pxy[0], pxz[0]], [pxy[0], pyy[0], pyz[0]],
                            [pxz[0], pyz[0], pzz[0]]])

    s_xx = stress[0, 0] + p_xx
    s_yy = stress[1, 1] + p_yy
    s_zz = stress[2, 2] + p_zz

    new_a = system.box.a / (S[0, 0] * s_xx + S[0, 1] * s_yy + S[0, 2] * s_zz +
                            1)
    new_b = system.box.b / (S[1, 0] * s_xx + S[1, 1] * s_yy + S[1, 2] * s_zz +
                            1)
    new_c = system.box.c / (S[2, 0] * s_xx + S[2, 1] * s_yy + S[2, 2] * s_zz +
                            1)

    if new_a <= 0 or new_b <= 0 or new_c <= 0:
        raise RuntimeError('Divergence of box dimensions to <= 0')

    newbox = am.Box(a=new_a, b=new_b, c=new_c)
    system_new = deepcopy(system)
    system_new.box_set(vects=newbox.vects, scale=True)

    return {'C': C, 'stress': stress, 'ecoh': pe[0], 'system_new': system_new}
Exemplo n.º 21
0
def rotate_cubic(system, axes):
    """
    Rotate a cubic system according to the specified crystallographic axes.
    Returns an orthogonal system whose box lengths are:
        a * sqrt(i^2+j^2+k^2)
    where a is the original cubic box length, and ijk are the crystallographic
    indicies for the specific direction.  
    """
    # rotate system generically
    system = rotate(system, axes)

    # test for cubic
    a = system.box.a
    try:
        assert np.isclose(a, system.box.b), str(a) + ' ' + str(system.box.b)
        assert np.isclose(a, system.box.c), str(a) + ' ' + str(system.box.c)
        assert np.isclose(90.0, system.box.alpha), str(system.box.alpha)
        assert np.isclose(90.0, system.box.beta), str(system.box.beta)
        assert np.isclose(90.0, system.box.gamma), str(system.box.gamma)
    except:
        raise ValueError('Cubic system not given')

    # Test for integer axes values
    try:
        for ax_val in axes.flat:
            assert np.isclose(ax_val, int(ax_val))
    except:
        raise ValueError('axes values must be integers')

    # Get magnitudes of the axes
    mag = np.linalg.norm(axes, axis=1)

    # compute number of atoms for the new system
    natoms = system.natoms * mag[0] * mag[1] * mag[2]
    if np.isclose(int(round(natoms)), natoms):
        natoms = int(round(natoms))
    else:
        raise ValueError(
            'not an integer number of atoms associated with the axes.')

    # create a new box with scaled lattice parameters
    box = am.Box(a=a * mag[0],
                 b=a * mag[1],
                 c=a * mag[2],
                 origin=system.box.origin)

    # supersize the rotated box
    m = int(ceil(max(mag)))
    system = am.tools.supersize(system, (-m, m), (-m, m), (-m, m))

    # filter atoms for only those in the new box
    data = system.atoms.data

    # round x-positions near xlo, xhi and only keep data for atoms where xlo
    # <= x < xhi
    data[np.where(np.isclose(data.T[1], box.xlo, atol=1e-8, rtol=0)),
         1] = box.xlo
    data = data[data.T[1] >= box.xlo]
    data[np.where(np.isclose(data.T[1], box.xhi, atol=1e-8, rtol=0)),
         1] = box.xhi
    data = data[data.T[1] < box.xhi]

    # round y-positions near ylo, yhi and only keep data for atoms where ylo
    # <= y < yhi
    data[np.where(np.isclose(data.T[2], box.ylo, atol=1e-8, rtol=0)),
         2] = box.ylo
    data = data[data.T[2] >= box.ylo]
    data[np.where(np.isclose(data.T[2], box.yhi, atol=1e-8, rtol=0)),
         2] = box.yhi
    data = data[data.T[2] < box.yhi]

    # round z-positions near zlo, zhi and only keep data for atoms where zlo
    # <= z < zhi
    data[np.where(np.isclose(data.T[3], box.zlo, atol=1e-8, rtol=0)),
         3] = box.zlo
    data = data[data.T[3] >= box.zlo]
    data[np.where(np.isclose(data.T[3], box.zhi, atol=1e-8, rtol=0)),
         3] = box.zhi
    data = data[data.T[3] < box.zhi]

    # deepcopy the data array to guarantee that it is new and separate
    data = deepcopy(data)

    # rebuild views
    start = 0
    view = OrderedDict()
    for k in system.atoms.view:
        vshape = (len(data), ) + system.atoms.view[k].shape[1:]
        view[k] = data[:, start:start + system.atoms.view[k][0].size]
        view[k].shape = vshape
        start = start + system.atoms.view[k][0].size

    # create atoms from natoms, data, view and dtype
    atoms = am.Atoms(natoms=natoms,
                     data=data,
                     view=view,
                     prop_dtype=system.atoms.dtype)

    # return new system
    return am.System(box=box, atoms=atoms)
Exemplo n.º 22
0
 def boxcubic(self):
     return am.Box(a=3, b=3, c=3, alpha=90, beta=90, gamma=90)
Exemplo n.º 23
0
def quick_a_Cij(lammps_command,
                system,
                potential,
                symbols,
                mpi_command=None,
                p_xx=0.0,
                p_yy=0.0,
                p_zz=0.0,
                delta=1e-5,
                tol=1e-10,
                diverge_scale=3.):
    """
    Quickly refines static orthorhombic system by evaluating the elastic constants and the virial pressure.
    
    Arguments:
    lammps_command -- directory location for lammps executable
    system -- atomman.System to statically deform and evaluate a,b,c and Cij at a given pressure
    potential -- atomman.lammps.Potential representation of a LAMMPS implemented potential
    symbols -- list of element-model symbols for the Potential that correspond to the System's atypes
    
    Keyword Arguments:
    p_xx, p_yy, p_zz -- tensile pressures to equilibriate to.  Default is 0.0 for all. 
    delta -- the strain range to use in calculating the elastic constants. Default is 1e-5.    
    tol -- the relative tolerance criterion for identifying box size convergence. Default is 1e-10.
    diverge_scale -- identifies a divergent system if x / diverge_scale < x < x * diverge_scale is not True for x = a,b,c.
    """

    #initial parameter setup
    converged = False  #flag for if values have converged

    #define boxes for iterating
    system_current = deepcopy(
        system)  #system with box parameters being evaluated
    system_old = None  #system with previous box parameters evaluated

    for cycle in xrange(100):

        #Run LAMMPS and evaluate results based on system_old
        results = calc_cij(lammps_command, system_current, potential, symbols,
                           p_xx, p_yy, p_zz, delta, cycle)
        system_new = results['system_new']

        #Test if box has converged to a single size
        if np.allclose(system_new.box.vects,
                       system_current.box.vects,
                       rtol=tol,
                       atol=0):
            converged = True
            break

        #Test if box has converged to two sizes
        elif system_old is not None and np.allclose(
                system_new.box.vects, system_old.box.vects, rtol=tol, atol=0):
            #Run LAMMPS Cij script using average between alat0 and alat1
            box = am.Box(a=(system_new.box.a + system_old.box.a) / 2.,
                         b=(system_new.box.b + system_old.box.b) / 2.,
                         c=(system_new.box.c + system_old.box.c) / 2.)
            system_current.box_set(vects=box.vects, scale=True)
            results = calc_cij(lammps_command, system_current, potential,
                               symbols, p_xx, p_yy, p_zz, delta, cycle + 1)

            converged = True
            break

        #Test if values have diverged from initial guess
        elif system_new.box.a < system.box.a / diverge_scale or system_new.box.a > system.box.a * diverge_scale:
            raise RuntimeError('Divergence of box dimensions')
        elif system_new.box.b < system.box.b / diverge_scale or system_new.box.b > system.box.b * diverge_scale:
            raise RuntimeError('Divergence of box dimensions')
        elif system_new.box.c < system.box.c / diverge_scale or system_new.box.c > system.box.c * diverge_scale:
            raise RuntimeError('Divergence of box dimensions')
        elif results['ecoh'] == 0.0:
            raise RuntimeError('Divergence: cohesive energy is 0')

        #if not converged or diverged, update system_old and system_current
        else:
            system_old, system_current = system_current, system_new

    #Return values if converged
    if converged:
        return results
    else:
        raise RuntimeError('Failed to converge after 100 cycles')
Exemplo n.º 24
0
def supersize(system, a_size, b_size, c_size):
    """
    Builds a large system based on a seed system and multipliers.
    
    Keyword Arguments:
    system -- atomman.System to use as the seed.
    a_size -- int or tuple of 2 ints for multiplying along the avect direction.
    b_size -- int or tuple of 2 ints for multiplying along the bvect direction.
    c_size -- int or tuple of 2 ints for multiplying along the cvect direction.
    
    The multiplier values *_size are taken to be integer tuples (m, n) where m <= 0 and n >= 0.
    The system multiplication works such that if n = -m, then the seed system's origin will be at the center of the new system.
    If only one integer is given, then it is assigned to m or n depending on its sign, and the other value is taken to be 0.  
    """
    #initial parameter setup
    sizes = [a_size, b_size, c_size]
    mults = np.array([0, 0, 0], dtype=int)
    vects = system.box.vects
    origin = system.box.origin
    spos = system.atoms_prop(key='pos', scale=True)

    for i in xrange(3):
        #check values in sizes
        if isinstance(sizes[i], (int, long)):
            if sizes[i] > 0:
                sizes[i] = (0, sizes[i])
            elif sizes[i] < 0:
                sizes[i] = (sizes[i], 0)
        elif isinstance(sizes[i], tuple):
            assert len(sizes[i]) == 2, 'Invalid system multipliers'
            assert isinstance(
                sizes[i][0],
                (int, long)) and sizes[i][0] <= 0, 'Invalid system multipliers'
            assert isinstance(
                sizes[i][1],
                (int, long)) and sizes[i][1] >= 0, 'Invalid system multipliers'
        else:
            raise TypeError('Invalid system multipliers')

        #calculate multipliers and scale box and first set of positions accordingly
        mults[i] = sizes[i][1] - sizes[i][0]
        assert mults[i] != 0, 'Cannot multiply system dimension by zero'
        spos[:, i] /= mults[i]
        origin += vects[i] * sizes[i][0]
        vects[i] *= mults[i]

    #initilize new Box and Atoms
    box = atomman.Box(vects=vects, origin=origin)
    natoms = system.natoms * mults[0] * mults[1] * mults[2]
    atoms = atomman.Atoms(natoms=natoms)

    #Copy over all property values using numpy broadcasting
    for prop in system.atoms_prop():
        o_values = system.atoms_prop(key=prop)
        n_values = np.empty(
            (mults[0] * mults[1] * mults[2], ) + o_values.shape,
            dtype=o_values.dtype)
        n_values[:] = system.atoms_prop(key=prop)
        n_shape = n_values.shape
        n_shape = (n_shape[0] * n_shape[1], ) + n_shape[2:]
        atoms.prop(key=prop, value=n_values.reshape(n_shape))

    #Expand spos using broadcasting
    n_spos = np.empty((mults[0] * mults[1] * mults[2], ) + spos.shape)
    n_spos[:] = spos
    n_shape = n_spos.shape
    n_shape = (n_shape[0] * n_shape[1], ) + n_shape[2:]
    n_spos = n_spos.reshape(n_shape)

    #use broadcasting to create arrays to add to spos
    test = np.empty(mults[0] * system.natoms)
    test.shape = (system.natoms, mults[0])
    test[:] = np.arange(mults[0])
    x = test.T.flatten()

    test = np.empty(mults[1] * len(x))
    test.shape = (len(x), mults[1])
    test[:] = np.arange(mults[1])
    y = test.T.flatten()
    test.shape = (mults[1], len(x))
    test[:] = x
    x = test.flatten()

    test = np.empty(mults[2] * len(x))
    test.shape = (len(x), mults[2])
    test[:] = np.arange(mults[2])
    z = test.T.flatten()
    test.shape = (mults[2], len(x))
    test[:] = x
    x = test.flatten()
    test[:] = y
    y = test.flatten()

    #xyz is displacement values to add to spos
    xyz = np.hstack(
        (x[:, np.newaxis], y[:, np.newaxis], z[:, np.newaxis])) * np.array(
            [1. / mults[0], 1. / mults[1], 1. / mults[2]])

    #save pos values, return new System
    atoms.prop(key='pos', value=n_spos + xyz)

    return atomman.System(box=box, atoms=atoms, scale=True)
Exemplo n.º 25
0
 def boxrhombohedral(self):
     return am.Box(a=3, b=3, c=3, alpha=84, beta=84, gamma=84)
Exemplo n.º 26
0
 def boxorthorhombic(self):
     return am.Box(a=3, b=4, c=5, alpha=90, beta=90, gamma=90)
Exemplo n.º 27
0
 def boxtriclinic(self):
     return am.Box(a=3, b=4, c=5, alpha=74, beta=87, gamma=105)
Exemplo n.º 28
0
 def boxmonoclinic(self):
     return am.Box(a=3, b=4, c=5, alpha=90, beta=105, gamma=90)
Exemplo n.º 29
0
    def make_screw_plate_old(self,
                             size=[40, 60, 3],
                             rad=[100, 115],
                             move=[0., 0., 0.],
                             filename="lmp_init.txt",
                             opt=None):
        alat = uc.set_in_units(self.pot['lattice'], 'angstrom')
        C11 = uc.set_in_units(self.pot['c11'], 'GPa')
        C12 = uc.set_in_units(self.pot['c12'], 'GPa')
        C44 = uc.set_in_units(self.pot['c44'], 'GPa')

        axes = np.array([[1, -2, 1], [1, 0, -1], [1, 1, 1]])

        unitx = alat * np.sqrt(6)
        unity = alat * np.sqrt(2)
        sizex = size[0]
        sizey = size[1]

        sizez = size[2]
        c = am.ElasticConstants(C11=C11, C12=C12, C44=C44)
        burgers = 0.5 * alat * -np.array([1., 1., 1.])

        # initializing a new Stroh object using the data
        stroh = am.defect.Stroh(c, burgers, axes=axes)

        # monopole system
        box = am.Box(a=alat, b=alat, c=alat)
        atoms = am.Atoms(natoms=2,
                         prop={
                             'atype': 2,
                             'pos': [[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]]
                         })
        ucell = am.System(atoms=atoms, box=box, scale=True)
        system = am.rotate_cubic(ucell, axes)

        # shftx = 0.5 * alat * np.sqrt(6.) / 3.
        shftx = 0.0
        shfty = -1. / 3. * alat * np.sqrt(2) / 2.
        # shfty = 2. / 3. * alat * np.sqrt(2) / 2.

        center = [0.5 * unitx * sizex, 0.5 * unity * sizey]
        new_pos = system.atoms_prop(key='pos') + np.array([shftx, shfty, 0.0])
        system.atoms_prop(key='pos', value=new_pos)
        system.supersize((0, sizex), (0, sizey), (0, sizez))

        # to make a plate #
        radius2 = rad[0] * rad[0]
        radiusout2 = rad[1] * rad[1]

        elements = []
        for atom in system.atoms:
            elements.append('Nb')

        ase_atoms = am.convert.ase_Atoms.dump(system, elements)
        pos = ase_atoms.get_positions()
        delindex = []
        for i in range(len(pos)):
            atom = ase_atoms[i]
            dx = pos[i, 0] - center[0]
            dy = pos[i, 1] - center[1]
            r = dx * dx + dy * dy

            if r > radiusout2:
                delindex.append(atom.index)
            if r < radius2:
                atom.symbol = 'W'
        del ase_atoms[delindex]

        (system, elements) = am.convert.ase_Atoms.load(ase_atoms)

        # use neb, it's to generate init configuration
        if opt in ['neb']:
            system_init = copy.deepcopy(system)

            shift = np.array([-0.5, -0.5, 0.0])
            new_pos = system_init.atoms_prop(key='pos', scale=True) + shift
            system_init.atoms_prop(key='pos', value=new_pos, scale=True)

            disp = stroh.displacement(system_init.atoms_prop(key='pos'))
            system_init.atoms_prop(key='pos',
                                   value=system_init.atoms_prop(key='pos') +
                                   disp)

            shift = np.array([0.5, 0.50, 0.0])
            new_pos = system_init.atoms_prop(key='pos', scale=True) + shift
            system_init.atoms_prop(key='pos', value=new_pos, scale=True)

            # for lammps read structure
            lmp.atom_data.dump(system_init, "init.txt")

        # for dd map plot
        ase.io.write("lmp_perf.cfg", images=ase_atoms, format='cfg')
        lmp.atom_data.dump(system, "lmp_perf.txt")

        shift = np.array([-0.5, -0.5, 0.0])
        new_pos = system.atoms_prop(key='pos', scale=True) + shift
        system.atoms_prop(key='pos', value=new_pos, scale=True)

        new_pos = system.atoms_prop(key='pos') + move
        system.atoms_prop(key='pos', value=new_pos)

        disp = stroh.displacement(system.atoms_prop(key='pos'))

        # pull
        pull = False
        if pull is True:
            core_rows = [disp[:, 2].argsort()[-3:][::-1]]
            print(disp[core_rows])
            exclus = np.arange(len(disp), dtype=int)
            unitburger = np.mean(disp[core_rows][:, 2])
            print(unitburger)
            exclus = np.delete(exclus, core_rows)
            disp[core_rows] -= 1. / 3. * unitburger
            # disp[exclus] -= 1. / 3. * unitburger

        system.atoms_prop(key='pos', value=system.atoms_prop(key='pos') + disp)

        new_pos = system.atoms_prop(key='pos') - move
        system.atoms_prop(key='pos', value=new_pos)

        shift = np.array([0.500000, 0.500000, 0.000000])
        new_pos = system.atoms_prop(key='pos', scale=True) + shift
        system.atoms_prop(key='pos', value=new_pos, scale=True)

        new_pos = system.atoms_prop(key='pos', scale=False)

        # for lammps read structure
        lmp.atom_data.dump(system, filename)

        dis_atoms = am.convert.ase_Atoms.dump(system, elements)
        return (ase_atoms, dis_atoms)
Exemplo n.º 30
0
 def boxtetragonal(self):
     return am.Box(a=3, b=3, c=8, alpha=90, beta=90, gamma=90)