Пример #1
0
def hex_to_ortho(cell, tol=1e-5):
    try:
        assert np.isclose(cell.box.a, cell.box.b, rtol=tol)
        assert not np.isclose(cell.box.a, cell.box.c, rtol=tol)
        assert np.isclose(cell.box.alpha, 90.0, rtol=tol)
        assert np.isclose(cell.box.beta, 90.0, rtol=tol)
        assert np.isclose(cell.box.gamma, 120.0, rtol=tol) or np.isclose(cell.box.gamma, 60.0, rtol=tol)
    except:
        raise ValueError('Not a standard hexagonal box')
    
    newcell = am.supersize(cell, 1, 2, 1) 
    newcell.normalize(style='lammps')
    
    new_b = cell.box.b * 3.**0.5
    newcell.box_set(origin=[0.0, 0.0, 0.0], scale=True)
    newcell.box_set(a=cell.box.a, b=new_b, c=cell.box.c, 
                    alpha=90.0, beta=90.0, gamma=90.0, 
                    origin=cell.box.origin)
    newcell.wrap()     
    return newcell
Пример #2
0
def hex_to_ortho(cell, tol=1e-5):
    try:
        assert np.isclose(cell.box.a, cell.box.b, rtol=tol)
        assert not np.isclose(cell.box.a, cell.box.c, rtol=tol)
        assert np.isclose(cell.box.alpha, 90.0, rtol=tol)
        assert np.isclose(cell.box.beta, 90.0, rtol=tol)
        assert np.isclose(cell.box.gamma, 120.0, rtol=tol) or np.isclose(cell.box.gamma, 60.0, rtol=tol)
    except:
        raise ValueError('Not a standard hexagonal box')
    
    newcell = am.supersize(cell, 1, 2, 1) 
    newcell.normalize(style='lammps')
    
    new_b = cell.box.b * 3.**0.5
    newcell.box_set(origin=[0.0, 0.0, 0.0], scale=True)
    newcell.box_set(a=cell.box.a, b=new_b, c=cell.box.c, 
                    alpha=90.0, beta=90.0, gamma=90.0, 
                    origin=cell.box.origin)
    newcell.wrap()     
    return newcell
Пример #3
0
def trig_to_hex(cell, tol=1e-5):    
    try:
        assert np.isclose(cell.box.a, cell.box.b, rtol=tol)
        assert np.isclose(cell.box.a, cell.box.c, rtol=tol)
        assert np.isclose(cell.box.alpha, cell.box.beta, rtol=tol)
        assert np.isclose(cell.box.alpha, cell.box.beta, rtol=tol)
        assert cell.box.alpha < 120.0
    except:
        raise ValueError('Not a standard trigonal box')
    
    newcell = am.supersize(cell, 3, 1, 1) 

    newcell.box_set(avect = cell.box.bvect - cell.box.avect,
                    bvect = cell.box.avect - cell.box.cvect,
                    cvect = cell.box.avect + cell.box.bvect + cell.box.cvect,
                    origin= cell.box.origin)
    newcell.wrap()   
    return newcell

    
    

    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
Пример #4
0
def trig_to_hex(cell, tol=1e-5):    
    try:
        assert np.isclose(cell.box.a, cell.box.b, rtol=tol)
        assert np.isclose(cell.box.a, cell.box.c, rtol=tol)
        assert np.isclose(cell.box.alpha, cell.box.beta, rtol=tol)
        assert np.isclose(cell.box.alpha, cell.box.beta, rtol=tol)
        assert cell.box.alpha < 120.0
    except:
        raise ValueError('Not a standard trigonal box')
    
    newcell = am.supersize(cell, 3, 1, 1) 

    newcell.box_set(avect = cell.box.bvect - cell.box.avect,
                    bvect = cell.box.avect - cell.box.cvect,
                    cvect = cell.box.avect + cell.box.bvect + cell.box.cvect,
                    origin= cell.box.origin)
    newcell.wrap()   
    return newcell

    
    

    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
Пример #5
0
 def supersize(self, a_size, b_size, c_size):
     system = am.supersize(self, a_size, b_size, c_size)
     self.__box = system.box
     self.__atoms = system.atoms
     self.__pbc = system.pbc
     self.__prop = system.prop
Пример #6
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.  
    """
    
    
    axes = np.asarray(axes)

    #rotate system generically
    system = am.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.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(data=data, view=view, prop_dtype=system.atoms.dtype)
    
    assert natoms == atoms.natoms, 'natom mismatch after rotation!'
    
    #return new system
    return am.System(box=box, atoms=atoms)
Пример #7
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.  
    """

    axes = np.asarray(axes)

    #rotate system generically
    system = am.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.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(data=data, view=view, prop_dtype=system.atoms.dtype)

    assert natoms == atoms.natoms, 'natom mismatch after rotation!'

    #return new system
    return am.System(box=box, atoms=atoms)