コード例 #1
0
ファイル: test_Atoms.py プロジェクト: samk07/atomman
 def test_default(self):
     atoms = am.Atoms()
     assert atoms.natoms == 1
     assert atoms.natypes == 1
     assert atoms.atype[0] == 1
     assert np.allclose(atoms.pos[0], np.zeros(3))
     assert len(atoms) == atoms.natoms
コード例 #2
0
ファイル: test_Atoms.py プロジェクト: samk07/atomman
 def build_example(self):
     atoms = am.Atoms(pos=[[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]], atype=[2,1])
     atoms.test1 = np.array(['a', 'b'])
     atoms.prop(key='test2', value=[np.zeros((3,3))])
     atoms.view['test3'] = [1, 1]
     atoms.prop_atype('charge', [-1, 1])
     return atoms
コード例 #3
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()
コード例 #4
0
ファイル: test_Atoms.py プロジェクト: samk07/atomman
 def test_model(self):
     atoms = self.build_example()
     model = atoms.model(prop_unit={'atype':None, 'pos':'scaled',
                         'test1':None, 'test2':None, 'test3':'J',
                         'charge':'GPa'})
     atoms2 = am.Atoms(model=model)
     for prop in ['atype', 'pos', 'test2', 'test3', 'charge']:
         assert np.allclose(atoms.view[prop], atoms2.view[prop])
     assert atoms.test1[0] == atoms2.test1[0]
     assert atoms.test1[1] == atoms2.test1[1]
コード例 #5
0
ファイル: poscar.py プロジェクト: yfyh2013/atomman
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
コード例 #6
0
def vacancy(system, pos=None, ptd_id=None, scale=False, atol=None):
    """
    Returns a new System where a vacancy point defect has been inserted.
    
    Keyword Arguments:
    system -- base System that the defect is added to.
    pos -- position of the atom to be removed.
    ptd_id -- id of the atom to be removed.  Alternative to using pos.
    scale -- if pos is given, indicates if pos is absolute (False) or box-relative (True). Default is False.
    
    Adds atom property old_id if it doesn't already exist that tracks the original atom ids.
    """

    pos_list = system.atoms.view['pos']

    #if pos is supplied, use isclose and where to identify the id of the atom at pos
    if pos is not None:
        if atol is None:
            atol = uc.set_in_units(1e-3, 'angstrom')
        if scale:
            pos = system.unscale(pos)
        assert ptd_id is None, 'pos and ptd_id cannot both be supplied'
        ptd_id = np.where(np.isclose(pos_list, pos, atol=atol).all(axis=1))
        assert len(ptd_id) == 1 and len(
            ptd_id[0]) == 1, 'Unique atom at pos not identified'
        ptd_id = long(ptd_id[0][0])

    #test that ptd_id is a valid entry
    try:
        pos = pos_list[ptd_id]
    except:
        raise TypeError('Invalid ptd_id')

    #create new system and copy values over
    d_system = am.System(box=system.box,
                         pbc=system.pbc,
                         atoms=am.Atoms(natoms=system.natoms - 1))
    for prop in system.atoms_prop():
        view = system.atoms.view[prop]
        value = np.asarray(np.vstack((view[:ptd_id], view[ptd_id + 1:])),
                           dtype=system.atoms.dtype[prop])
        d_system.atoms_prop(key=prop, value=value)

    #add property old_id with each atom's original id
    if d_system.atoms_prop(key='old_id') is None:
        d_system.atoms_prop(key='old_id',
                            value=np.hstack((np.arange(0, ptd_id),
                                             np.arange(ptd_id + 1,
                                                       system.natoms))),
                            dtype='int32')

    return d_system
コード例 #7
0
def interstitial(system, atype=None, pos=None, scale=False, atol=None):
    """
    Returns a new System where a positional interstitial point defect has been inserted.
    
    Keyword Arguments:
    system -- base System that the defect is added to.
    atype -- atom type for the interstitial atom.
    pos -- position for adding the interstitial atom.
    scale -- if pos is given, indicates if pos is absolute (False) or box-relative (True). Default is False.
    
    Adds atom property old_id if it doesn't already exist that tracks the original atom ids.
    """

    pos_list = system.atoms.view['pos']

    if atol is None:
        atol = uc.set_in_units(1e-3, 'angstrom')
    if scale:
        pos = system.unscale(pos)

    #Use isclose and where to check that no atoms are already at pos
    ptd_id = np.where(np.isclose(pos_list, pos, atol=atol).all(axis=1))
    assert len(ptd_id) == 1 and len(ptd_id[0]) == 0, 'atom already at pos'

    assert isinstance(
        atype, (int, long)) and atype > 0, 'atype must be a positive integer'

    #create new system and copy values over
    d_system = am.System(box=system.box,
                         pbc=system.pbc,
                         atoms=am.Atoms(natoms=system.natoms + 1))
    for prop in system.atoms_prop():
        view = system.atoms.view[prop]
        value = np.asarray(np.vstack((view, np.zeros_like(view[0]))),
                           dtype=system.atoms.dtype[prop])
        d_system.atoms_prop(key=prop, value=value)
    d_system.atoms_prop(a_id=d_system.natoms - 1, key='atype', value=atype)
    d_system.atoms_prop(a_id=d_system.natoms - 1, key='pos', value=pos)

    #add property old_id with each atom's original id
    if d_system.atoms_prop(key='old_id') is None:
        d_system.atoms_prop(key='old_id',
                            value=np.arange(d_system.natoms),
                            dtype='int32')
    else:
        old_id = max(system.atoms_prop(key='old_id')) + 1
        d_system.atoms_prop(a_id=d_system.natoms - 1,
                            key='old_id',
                            value=old_id)

    return d_system
コード例 #8
0
ファイル: System.py プロジェクト: UoS-msam/atomman
    def __init__(self,
                 atoms=Atoms(),
                 box=Box(),
                 pbc=(True, True, True),
                 scale=False,
                 prop={}):
        """
        Initilize a System by joining an am.Atoms and am.Box instance.
        
        Keyword Arguments:
        atoms -- Instance of am.Atoms to include.
        box -- Instance of am.Box to include.
        pbc -- Tuple of three booleans where True indicates a given box dimension is periodic. Default is all True.
        scale -- If True, atoms' pos will be scaled relative to the box.  Default is False.
        prop -- Dictionary of free-form system-wide properties.
        """

        #Check parameter types
        assert isinstance(box, Box), 'Invalid box entry'
        assert isinstance(atoms, Atoms), 'Invalid atoms entry'
        assert isinstance(prop, dict), 'invalid prop dictionary'

        #Copy box
        self.__box = deepcopy(box)

        #Copy atoms
        data = deepcopy(atoms.data)

        #Reassign atom views to new data array
        view = OrderedDict()
        start = 0
        for k in atoms.view:
            vshape = atoms.view[k].shape
            view[k] = data[:, start:start + atoms.view[k][0].size]
            view[k].shape = vshape
            start = start + view[k][0].size

        #Save new atoms
        self.__atoms = am.Atoms(data=data, view=view, prop_dtype=atoms.dtype)

        #Rescale pos if needed
        if scale is True:
            self.atoms.view['pos'][:] = self.unscale(atoms.view['pos'])

        #Save pbc
        self.pbc = pbc

        #Save prop dict
        self.__prop = prop
コード例 #9
0
ファイル: test_displacement.py プロジェクト: samk07/atomman
def test_displacement():
    a = 3.18
    c = 5.17
    ucell = am.System(atoms=am.Atoms(pos=[[0.0, 0.0, 0.0], [1 / 3, 2 /
                                                            3, 0.5]]),
                      box=am.Box.hexagonal(a, c),
                      scale=True)
    system_0 = ucell.supersize(10, 10, 10)
    system_1 = deepcopy(system_0)

    system_1.atoms.pos[:] += 5
    system_1.wrap()

    assert not np.allclose(system_1.atoms.pos - system_0.atoms.pos, 5.0)
    assert np.allclose(am.displacement(system_0, system_1), 5.0)
コード例 #10
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
コード例 #11
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')
コード例 #12
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)
コード例 #13
0
def test_bcc():

    # Build bcc test system
    a = 2.865
    ucell = am.System(atoms=am.Atoms(pos=[[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]]),
                      box=am.Box.cubic(a),
                      scale=True)
    system = ucell.supersize(30, 30, 30)

    cutoff = 0.9 * a

    # Test all periodic boundaries
    system.pbc = [True, True, True]
    neighbors = system.neighborlist(cutoff=cutoff)
    assert np.isclose(neighbors.coord.mean(), 8.0)

    # Test no periodic boundaries
    system.pbc = [False, False, False]
    neighbors = system.neighborlist(cutoff=cutoff)
    assert np.isclose(neighbors.coord.mean(), 7.6066)
コード例 #14
0
    def test_1(self):
        atoms = am.Atoms(pos=[[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]], atype=[2, 1])
        assert atoms.natoms == 2
        assert atoms.natypes == 2
        assert atoms.atypes[0] == 1
        assert atoms.atypes[1] == 2

        atoms.test1 = np.array(['a', 'b'])
        assert atoms.prop(key='test1', index=0) == 'a'
        assert atoms.test1[1] == 'b'

        atoms.prop(key='test2', value=[np.zeros((3, 3))])
        assert np.allclose(atoms.view['test2'][0], np.zeros((3, 3)))
        assert np.allclose(atoms.test2[1], np.zeros((3, 3)))

        atoms.view['test3'] = [1, 1]
        assert atoms.view['test3'][0] == 1
        assert atoms.test3[1] == 1

        atoms.prop_atype('charge', [-1, 1])
        assert atoms.charge[0] == 1
        assert atoms.charge[1] == -1

        df = atoms.df()
        assert len(df) == 2
        assert 'atype' in df
        assert 'pos[0]' in df
        assert 'pos[1]' in df
        assert 'pos[2]' in df
        assert 'test1' in df
        assert 'test2[0][0]' in df
        assert 'test2[0][1]' in df
        assert 'test2[0][2]' in df
        assert 'test2[1][0]' in df
        assert 'test2[1][1]' in df
        assert 'test2[1][2]' in df
        assert 'test2[2][0]' in df
        assert 'test2[2][1]' in df
        assert 'test2[2][2]' in df
        assert 'charge' in df
コード例 #15
0
def test_hcp():

    # Build hcp test system
    a = 3.18
    c = 5.17
    ucell = am.System(atoms=am.Atoms(pos=[[0.0, 0.0, 0.0], [1 / 3, 2 /
                                                            3, 0.5]]),
                      box=am.Box.hexagonal(a, c),
                      scale=True)
    system = ucell.supersize(30, 30, 30)

    cutoff = 1.1 * a

    # Test all periodic boundaries
    system.pbc = [True, True, True]
    neighbors = system.neighborlist(cutoff=cutoff)
    assert np.isclose(neighbors.coord.mean(), 12.0)

    # Test no periodic boundaries
    system.pbc = [False, False, False]
    neighbors = system.neighborlist(cutoff=cutoff)
    assert np.isclose(neighbors.coord.mean(), 11.4411)
コード例 #16
0
ファイル: Bain.py プロジェクト: lmhale99/iprPy
    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
コード例 #17
0
def diatom_scan(lammps_command: str,
                potential: am.lammps.Potential,
                symbols: list,
                mpi_command: Optional[str] = None,
                rmin: float = uc.set_in_units(0.02, 'angstrom'),
                rmax: float = uc.set_in_units(6.0, 'angstrom'),
                rsteps: int = 300) -> dict:
    """
    Performs a diatom energy scan over a range of interatomic spaces, r.
    
    Parameters
    ----------
    lammps_command :str
        Command for running LAMMPS.
    potential : atomman.lammps.Potential
        The LAMMPS implemented potential to use.
    symbols : list
        The potential symbols associated with the two atoms in the diatom.
    mpi_command : str, optional
        The MPI command for running LAMMPS in parallel.  If not given, LAMMPS
        will run serially.
    rmin : float, optional
        The minimum r spacing to use (default value is 0.02 angstroms).
    rmax : float, optional
        The maximum r spacing to use (default value is 6.0 angstroms).
    rsteps : int, optional
        The number of r spacing steps to evaluate (default value is 300).
    
    Returns
    -------
    dict
        Dictionary of results consisting of keys:
        
        - **'r_values'** (*numpy.array of float*) - All interatomic spacings,
          r, explored.
        - **'energy_values'** (*numpy.array of float*) - The computed potential
          energies for each r value.
    """

    # Build lists of values
    r_values = np.linspace(rmin, rmax, rsteps)
    energy_values = np.empty(rsteps)

    # Define atype based on symbols
    symbols = aslist(symbols)
    if len(symbols) == 1:
        atype = [1, 1]
    elif len(symbols) == 2:
        atype = [1, 2]
    else:
        raise ValueError('symbols must have one or two values')

    # Initialize system (will shift second atom's position later...)
    box = am.Box.cubic(a=rmax + 1)
    atoms = am.Atoms(atype=atype, pos=[[0.1, 0.1, 0.1], [0.1, 0.1, 0.1]])
    system = am.System(atoms=atoms,
                       box=box,
                       pbc=[False, False, False],
                       symbols=symbols)

    # Add charges if required
    if potential.atom_style == 'charge':
        system.atoms.prop_atype('charge', potential.charges(system.symbols))

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

    # Define lammps variables
    lammps_variables = {}

    # Loop over values
    for i in range(rsteps):

        # Shift second atom's x position
        system.atoms.pos[1] = np.array([0.1 + r_values[i], 0.1, 0.1])

        # Save configuration
        system_info = system.dump('atom_data',
                                  f='diatom.dat',
                                  potential=potential)
        lammps_variables['atomman_system_pair_info'] = system_info

        # Write lammps input script
        lammps_script = 'run0.in'
        template = read_calc_file('iprPy.calculation.diatom_scan',
                                  'run0.template')
        with open(lammps_script, 'w') as f:
            f.write(filltemplate(template, lammps_variables, '<', '>'))

        # Run lammps and extract data
        try:
            output = lmp.run(lammps_command,
                             script_name=lammps_script,
                             mpi_command=mpi_command)
        except:
            energy_values[i] = np.nan
        else:
            energy = output.simulations[0]['thermo'].PotEng.values[-1]
            energy_values[i] = uc.set_in_units(energy, lammps_units['energy'])

    if len(energy_values[np.isfinite(energy_values)]) == 0:
        raise ValueError(
            'All LAMMPS runs failed. Potential likely invalid or incompatible.'
        )

    # Collect results
    results_dict = {}
    results_dict['r_values'] = r_values
    results_dict['energy_values'] = energy_values

    return results_dict
コード例 #18
0
ファイル: testing.py プロジェクト: lmhale99/travis-test
from DataModelDict import DataModelDict as DM
import atomman as am

# Load dummy input
inputdict = DM('input.json')

# Build fcc unit cell
box = am.Box.cubic(3.2)
atoms = am.Atoms(pos=[[0.0, 0.0, 0.0], [0.0, 0.5, 0.5], [0.5, 0.0, 0.5], [0.5, 0.5, 0.0]])
ucell = am.System(atoms=atoms, box=box, scale=True)

# Modify system
system = ucell.supersize(3, 3, 3)

# Dump to json
system.dump('system_model', f='system.json', format='json')
コード例 #19
0
ファイル: isolated_atom.py プロジェクト: lmhale99/iprPy
def isolated_atom(lammps_command: str,
                  potential: am.lammps.Potential,
                  mpi_command: Optional[str] = None) -> dict:
    """
    Evaluates the isolated atom energy for each elemental model of a potential.
    
    Parameters
    ----------
    lammps_command :str
        Command for running LAMMPS.
    potential : atomman.lammps.Potential
        The LAMMPS implemented potential to use.
    mpi_command : str, optional
        The MPI command for running LAMMPS in parallel.  If not given, LAMMPS
        will run serially.
    
    Returns
    -------
    dict
        Dictionary of results consisting of keys:
        
        - **'energy'** (*dict*) - The computed potential energies for each
          symbol.
    """
    # Initialize dictionary
    energydict = {}

    # Initialize single atom system
    box = am.Box.cubic(a=1)
    atoms = am.Atoms(atype=1, pos=[[0.5, 0.5, 0.5]])
    system = am.System(atoms=atoms, box=box, pbc=[False, False, False])

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

    # Define lammps variables
    lammps_variables = {}

    # Loop over symbols
    for symbol in potential.symbols:
        system.symbols = symbol

        # Add charges if required
        if potential.atom_style == 'charge':
            system.atoms.prop_atype('charge',
                                    potential.charges(system.symbols))

        # Save configuration
        system_info = system.dump('atom_data',
                                  f='isolated.dat',
                                  potential=potential)
        lammps_variables['atomman_system_pair_info'] = system_info

        # Write lammps input script
        lammps_script = 'run0.in'
        template = read_calc_file('iprPy.calculation.isolated_atom',
                                  'run0.template')
        with open(lammps_script, 'w') as f:
            f.write(filltemplate(template, lammps_variables, '<', '>'))

        # Run lammps and extract data
        output = lmp.run(lammps_command,
                         script_name=lammps_script,
                         mpi_command=mpi_command)
        energy = output.simulations[0]['thermo'].PotEng.values[-1]
        energydict[symbol] = uc.set_in_units(energy, lammps_units['energy'])

    # Collect results
    results_dict = {}
    results_dict['energy'] = energydict

    return results_dict
コード例 #20
0
ファイル: system_model.py プロジェクト: yfyh2013/atomman
def load(model, key='atomic-system', index=0):
    """Read in a data model containing a crystal-structure and return a System unit cell."""

    if isinstance(model, (str, unicode)) and os.path.isfile(model):
        with open(model) as f:
            model = f.read()

    #Pull system model out of data model using key and index
    a_sys = DataModelDict(model).finds(key)
    if len(a_sys) == 0:
        raise KeyError(key + ' not found in model')
    try:
        a_sys = a_sys[index]
    except:
        raise IndexError('Invalid index ' + str(index) + ' for model key ' +
                         key)

    #identify the crystal system
    c_system = a_sys['cell'].keys()[0]
    cell = a_sys['cell'][c_system]

    if c_system == 'cubic':
        a = b = c = uc.value_unit(cell['a'])
        alpha = beta = gamma = 90.0

    elif c_system == 'hexagonal':
        a = b = uc.value_unit(cell['a'])
        c = uc.value_unit(cell['c'])
        alpha = beta = 90.0
        gamma = 120.0

    elif c_system == 'tetragonal':
        a = b = uc.value_unit(cell['a'])
        c = uc.value_unit(cell['c'])
        alpha = beta = gamma = 90.0

    elif c_system == 'trigonal' or c_system == 'rhombohedral':
        a = b = c = uc.value_unit(cell['a'])
        alpha = beta = gamma = cell['alpha']

    elif c_system == 'orthorhombic':
        a = uc.value_unit(cell['a'])
        b = uc.value_unit(cell['b'])
        c = uc.value_unit(cell['c'])
        alpha = beta = gamma = 90.0

    elif c_system == 'monoclinic':
        a = uc.value_unit(cell['a'])
        b = uc.value_unit(cell['b'])
        c = uc.value_unit(cell['c'])
        alpha = gamma = 90.0
        beta = cell['beta']

    elif c_system == 'triclinic':
        a = uc.value_unit(cell['a'])
        b = uc.value_unit(cell['b'])
        c = uc.value_unit(cell['c'])
        alpha = cell['alpha']
        beta = cell['beta']
        gamma = cell['gamma']

    box = am.Box(a=a, b=b, c=c, alpha=alpha, beta=beta, gamma=gamma)

    #create list of atoms and list of elements
    atoms = []
    scale = None

    prop = DataModelDict()

    all_atypes = np.array(a_sys.finds('component'))
    all_symbols = np.array(a_sys.finds('symbol'))
    all_elements = np.array(a_sys.finds('element'))

    if len(all_atypes) == 0:
        if len(all_symbols) != 0:
            symbols, atypes = np.unique(all_symbols, return_inverse)
        elif len(all_elements) != 0:
            symbols, atypes = np.unique(all_elements, return_inverse)
        else:
            raise ValueError('No atom components, symbols or elements listed')

    else:
        atypes = all_atypes
        symbols = [None for i in xrange(max(all_atypes))]

        if len(all_elements) != 0 and len(all_symbols) == 0:
            all_symbols = all_elements

        if len(all_symbols) != 0:
            assert len(all_symbols) == len(atypes)
            sym_dict = {}
            for atype, symbol in zip(atypes, all_symbols):
                if atype not in sym_dict:
                    sym_dict[atype] = symbol
                else:
                    assert sym_dict[atype] == symbol

            for atype, symbol in sym_dict.iteritems():
                symbols[atype - 1] = symbol

    prop['atype'] = atypes
    prop['pos'] = np.zeros((len(prop['atype']), 3), dtype='float64')
    count = 0

    pos_units = []
    for atom in a_sys.iteraslist('atom'):

        #read in pos for atom and unit info
        prop['pos'][count] = uc.value_unit(atom['position'])
        pos_units.append(atom['position'].get('unit', None))

        #Add per-atom properties
        for property in atom.iteraslist('property'):
            if property['name'] not in prop:
                value = uc.value_unit(property)
                prop[property['name']] = np.zeros(
                    (len(prop['atype']), len(value)), dtype=value.dtype)

            prop[property['name']][count] = uc.value_unit(property)
        count += 1

    pos_unit = np.unique(pos_units)
    assert len(pos_unit) == 1, 'Mixed units for positions'
    if pos_unit[0] == 'scaled': scale = True
    else: scale = False

    atoms = am.Atoms(natoms=len(prop['atype']), prop=prop)
    system = am.System(box=box, atoms=atoms, scale=scale)

    return system, symbols
コード例 #21
0
    lmpS.create_in(in_data, potential, fix)
    output = lmp.run(lammps_exe, in_name, return_style='object')
    status = parseLogs.get_vars2('log.lammps')
    Lx = status['Lx']
    Ly = status['Ly']
    Lz = status['Lz']
    Vol = Lx * Ly * Lz
    Atoms = status['Atoms']
    PotEng = status['PotEng'] / Atoms

    print Lx, Ly, Lz, Vol, PotEng

    avect = [4.050, 0.000, 0.000]
    bvect = [0.000, 4.050, 0.000]
    cvect = [0.0000001, 0.000, 4.050]
    origin = [0.000, 0.000, 0.000]

    prop = {
        'atype': 1,
        'pos': [[0.0, 0.0, 0.0], [0.5, 0.5, 0.0], [0.5, 0.0, 0.5],
                [0.0, 0.5, 0.5]]
    }
    atoms = am.Atoms(natoms=4, prop=prop)
    box = am.Box(avect=avect, bvect=bvect, cvect=cvect, origin=origin)

    fcc_cell = am.System(box=box, atoms=atoms, scale=True)
    print(fcc_cell)

    sys_info = lmp.atom_data.dump(fcc_cell, 'atom.dat')
コード例 #22
0
ファイル: rotate.py プロジェクト: chaomy/Config_tools
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)
コード例 #23
0
def dumbbell(system,
             atype=None,
             pos=None,
             ptd_id=None,
             db_vect=None,
             scale=False,
             atol=None):
    """
    Returns a new System where a dumbbell interstitial point defect has been inserted.
    
    Keyword Arguments:
    system -- base System that the defect is added to.    
    atype -- atom type for the atom in the dumbbell pair being added to the system.
    pos -- position of the system atom where the dumbbell pair is added.
    ptd_id -- id of the system atom where the dumbbell pair is added.  Alternative to using pos.
    db_vect -- vector associated with the dumbbell interstitial.
    scale -- indicates if pos and db_vect are absolute (False) or box-relative (True). Default is False.
    
    Adds atom property old_id if it doesn't already exist that tracks the original atom ids.
    """

    pos_list = system.atoms.view['pos']

    #if pos is supplied, use isclose and where to identify the id of the atom at pos
    if pos is not None:
        if atol is None:
            atol = uc.set_in_units(1e-3, 'angstrom')
        if scale:
            pos = system.unscale(pos)
        assert ptd_id is None, 'pos and ptd_id cannot both be supplied'
        ptd_id = np.where(np.isclose(pos_list, pos, atol=atol).all(axis=1))
        assert len(ptd_id) == 1 and len(
            ptd_id[0]) == 1, 'Unique atom at pos not identified'
        ptd_id = long(ptd_id[0][0])

    #test that ptd_id is a valid entry
    try:
        pos = pos_list[ptd_id]
    except:
        raise TypeError('Invalid ptd_id')

    assert isinstance(
        atype, (int, long)) and atype > 0, 'atype must be a positive integer'

    #unscale db_vect if scale is True
    if scale:
        db_vect = system.unscale(db_vect)

    #create new system and copy values over
    d_system = am.System(box=system.box,
                         pbc=system.pbc,
                         atoms=am.Atoms(natoms=system.natoms + 1))
    for prop in system.atoms_prop():
        view = system.atoms.view[prop]
        value = np.asarray(np.vstack(
            (view[:ptd_id], view[ptd_id + 1:], view[ptd_id],
             np.zeros_like(view[0]))),
                           dtype=system.atoms.dtype[prop])
        d_system.atoms_prop(key=prop, value=value)

    d_system.atoms_prop(a_id=d_system.natoms - 1, key='atype', value=atype)
    d_system.atoms_prop(a_id=d_system.natoms - 2,
                        key='pos',
                        value=pos - db_vect)
    d_system.atoms_prop(a_id=d_system.natoms - 1,
                        key='pos',
                        value=pos + db_vect)

    #add property old_id with each atom's original id
    if d_system.atoms_prop(a_id=0, key='old_id') is None:
        d_system.atoms_prop(key='old_id',
                            value=np.hstack((np.arange(0, ptd_id),
                                             np.arange(ptd_id + 1,
                                                       system.natoms), ptd_id,
                                             system.natoms)),
                            dtype='int32')
    else:
        old_id = max(system.atoms_prop(key='old_id')) + 1
        d_system.atoms_prop(a_id=d_system.natoms - 1,
                            key='old_id',
                            value=old_id)

    return d_system
コード例 #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)
コード例 #25
0
ファイル: atom_dump.py プロジェクト: yfyh2013/atomman
def load(data, prop_info=None):
    """
    Read a LAMMPS-style dump file and return a System.
    
    Argument:
    data = file name, file-like object or string to read data from.
    
    Keyword Argument:
    prop_info -- DataModelDict for relating the per-atom properties to/from the dump file and the System. Will create a default json instance <data>.json if prop_info is not given and <data>.json doesn't already exist.
    """

    #read in prop_info if supplied
    if prop_info is not None:
        if isinstance(prop_info, (str, unicode)) and os.path.isfile(prop_info):
            with open(prop_info) as f:
                prop_info = f.read()
        prop_info = DataModelDict(prop_info)

    #check for default prop_info file
    else:
        try:
            with open(data + '.json') as fj:
                prop_info = DataModelDict(fj)
        except:
            prop_info = None
            box_unit = None

    #read box_unit if specified in prop_info
    if prop_info is not None:
        prop_info = prop_info.find('LAMMPS-dump-atoms_prop-relate')
        box_unit = prop_info['box_prop'].get('unit', None)

    with uber_open_rmode(data) as f:
        pbc = None
        box = None
        natoms = None
        system = None

        readnatoms = False
        readatoms = False
        readtimestep = False
        acount = 0
        bcount = 3

        #loop over all lines in file
        for line in f:
            terms = line.split()
            if len(terms) > 0:

                #read atomic values if time to do so
                if readatoms:
                    #sort values by a_id and save to prop_vals
                    a_id = long(terms[id_index]) - 1
                    prop_vals[a_id] = terms
                    acount += 1

                    #save values to sys once all atoms read in
                    if acount == natoms:
                        readatoms = False

                        #cycle over the defined atoms_prop in prop_info
                        for prop, p_keys in prop_info['atoms_prop'].iteritems(
                        ):
                            #set default keys
                            dtype = p_keys.get('dtype', None)
                            shape = p_keys.get('shape', None)
                            shape = (natoms, ) + np.empty(shape).shape

                            value = np.empty(shape)

                            #cycle over the defined LAMMPS-attributes in prop_info
                            for attr, a_keys in prop_info[
                                    'LAMMPS-attribute'].iteritems():

                                #cycle over list of relations for each LAMMPS-attribute
                                for relation in a_keys.iteraslist('relation'):

                                    #if atoms prop and relation prop match
                                    if relation['prop'] == prop:
                                        #get unit and scale info
                                        unit = relation.get('unit', None)

                                        if unit == 'scaled':
                                            unit = None
                                            scale = True
                                        else:
                                            scale = False

                                        #find index of attribute in name_list
                                        a_index = name_list.index(attr)
                                        #check if relation has index listed
                                        try:
                                            index = relation['index']
                                            if isinstance(index, list):
                                                index = (
                                                    Ellipsis, ) + tuple(index)
                                            else:
                                                index = (Ellipsis, ) + (
                                                    index, )

                                            value[index] = prop_vals[:,
                                                                     a_index]
                                        #scalar if no index
                                        except:
                                            value[:] = prop_vals[:, a_index]
                            #test if values are ints if dtype not specified
                            if dtype is None and np.allclose(
                                    np.asarray(value, dtype=int), value):
                                value = np.asarray(value, dtype=int)
                            else:
                                value = np.asarray(value, dtype=dtype)

                            #save prop values to system
                            system.atoms_prop(key=prop,
                                              value=uc.set_in_units(
                                                  value, unit),
                                              scale=scale)

                #read number of atoms if time to do so
                elif readnatoms:
                    natoms = int(terms[0])
                    readnatoms = False

                elif readtimestep:
                    timestep = int(terms[0])
                    readtimestep = False

                #read x boundary condition values if time to do so
                elif bcount == 0:
                    xlo = uc.set_in_units(float(terms[0]), box_unit)
                    xhi = uc.set_in_units(float(terms[1]), box_unit)
                    if len(terms) == 3:
                        xy = uc.set_in_units(float(terms[2]), box_unit)
                    bcount += 1

                #read y boundary condition values if time to do so
                elif bcount == 1:
                    ylo = uc.set_in_units(float(terms[0]), box_unit)
                    yhi = uc.set_in_units(float(terms[1]), box_unit)
                    if len(terms) == 3:
                        xz = uc.set_in_units(float(terms[2]), box_unit)
                    bcount += 1

                #read z boundary condition values if time to do so
                elif bcount == 2:
                    zlo = uc.set_in_units(float(terms[0]), box_unit)
                    zhi = uc.set_in_units(float(terms[1]), box_unit)
                    if len(terms) == 3:
                        yz = uc.set_in_units(float(terms[2]), box_unit)
                        xlo = xlo - min((0.0, xy, xz, xy + xz))
                        xhi = xhi - max((0.0, xy, xz, xy + xz))
                        ylo = ylo - min((0.0, yz))
                        yhi = yhi - max((0.0, yz))
                        box = am.Box(xlo=xlo,
                                     xhi=xhi,
                                     ylo=ylo,
                                     yhi=yhi,
                                     zlo=zlo,
                                     zhi=zhi,
                                     xy=xy,
                                     xz=xz,
                                     yz=yz)
                    else:
                        box = am.Box(xlo=xlo,
                                     xhi=xhi,
                                     ylo=ylo,
                                     yhi=yhi,
                                     zlo=zlo,
                                     zhi=zhi)
                    bcount += 1

                #if not time to read value, check the ITEM: header information
                else:

                    #only consider ITEM: lines
                    if terms[0] == 'ITEM:':

                        #ITEM: TIMESTEP indicates it is time to read the timestep
                        if terms[1] == 'TIMESTEP':
                            readtimestep = True

                        #ITEM: NUMBER indicates it is time to read natoms
                        elif terms[1] == 'NUMBER':
                            readnatoms = True

                        #ITEM: BOX gives pbc and indicates it is time to read box parameters
                        elif terms[1] == 'BOX':
                            pbc = [True, True, True]
                            for i in xrange(3):
                                if terms[i + len(terms) - 3] != 'pp':
                                    pbc[i] = False
                            bcount = 0

                        #ITEM: ATOMS gives list of per-Atom property names and indicates it is time to read atomic values
                        elif terms[1] == 'ATOMS':
                            assert box is not None, 'Box information not found'
                            assert natoms is not None, 'Number of atoms not found'

                            #read list of property names
                            name_list = terms[2:]
                            id_index = name_list.index('id')

                            #create empty array for reading property values
                            prop_vals = np.empty((natoms, len(name_list)))

                            #create and save default prop_info Data Model if needed
                            if prop_info is None:
                                prop_info = __prop_info_default_load(name_list)
                                if isinstance(
                                        data,
                                    (str, unicode)) and len(data) < 80:
                                    with open(data + '.json', 'w') as fj:
                                        prop_info.json(fp=fj, indent=4)
                                prop_info = prop_info.find(
                                    'LAMMPS-dump-atoms_prop-relate')

                            #create system and flag that it is time to read data
                            system = am.System(atoms=am.Atoms(natoms=natoms),
                                               box=box,
                                               pbc=pbc)
                            system.prop['timestep'] = timestep
                            readatoms = True
    if system is None:
        raise ValueError('Failed to properly load dump file ' + str(data)[:50])

    return system
コード例 #26
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)
コード例 #27
0
def sys_gen(units = 'metal',
            atom_style = 'atomic',
            pbc = (True, True, True),
            ucell = am.System(atoms = am.Atoms(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]]})),                              
            axes = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]),
            shift = np.array([0.1, 0.1, 0.1]),
            size = np.array([[-3,3], [-3,3], [-3,3]], dtype=np.int)):
    """
    Generates the LAMMPS input command lines associated with having LAMMPS create a system.
    
    Keyword Arguments:
    units -- LAMMPS units option to use. Default is 'metal'.
    atom_style -- LAMMPS atom_style option to use. Default is 'atomic'.
    pbc -- list or tuple of three booleans indicating which directions are periodic. Default is (True, True, True).
    ucell -- a small system (i.e. crystallographic unit cell) from which the returned system is generated from. Default is an fcc unit cell with cell lengths = 1.
    axes -- crystallographic axes to rotate the ucell by.  For a cubic ucell, the dimensions of the rotated system will increase to ensure that all directions can be periodic.  Default is [[1,0,0],[0,1,0],[0,0,1]].
    shift -- box-scaled vector to shift all atoms by. Default is [0.1, 0.1, 0.1]. (The LAMMPS algorithm for generating systems sometimes has issues at boundaries.)
    size -- system multipliers to expand the system by.  Default is [[-3,3], [-3,3], [-3,3]], i.e. 6x6x6 supercell of ucell where Cartesian (0,0,0) is in the center of the returned System's Box.
    """
    size = np.asarray(size)
    shift = np.asarray(shift)
    axes = np.asarray(axes)
    
    boundary = ''
    for i in xrange(3):
        if pbc[i]:
            boundary += 'p '
        else:
            boundary += 'm '
    
    ntypes = ucell.natypes
    pos_basis = ''
    type_basis = ''
    for i in xrange(ucell.natoms):
        pos = ucell.atoms_prop(a_id=i, key='pos', scale = True)
        pos_basis += '        basis %f %f %f' %(pos[0], pos[1], pos[2])
        if i < ucell.natoms - 1:
            pos_basis += ' &\n'
        if ucell.atoms_prop(a_id=i, key='atype') > 1:
            type_basis += ' &\n             basis %i %i'%(i+1,  ucell.atoms_prop(a_id=i, key='atype'))
    
    vects = ucell.box.vects

    #Test if box is cubic
    if vects[1][0] == 0.0 and vects[2][0] == 0.0 and vects[2][1] == 0.0:
        region_box = 'region box block %i %i %i %i %i %i' % (size[0,0], size[0,1], size[1,0], size[1,1], size[2,0], size[2,1])
        ortho = True
    else:
        assert np.allclose(axes[0], [1,0,0]) and np.allclose(axes[1], [0,1,0]) and np.allclose(axes[2], [0,0,1]), 'Rotation of non-orthogonal box not suppported'
        ortho = False
        size_xy = vects[1][0] * (size[0,1] - size[0,0]) / ucell.box.a
        size_xz = vects[2][0] * (size[0,1] - size[0,0]) / ucell.box.a
        size_yz = vects[2][1] * (size[1,1] - size[1,0]) / ucell.box.b
        region_box = 'region box prism %i %i %i %i %i %i %f %f %f' % (size[0,0], size[0,1], size[1,0], 
                                                                      size[1,1], size[2,0], size[2,1], 
                                                                      size_xy,   size_xz,   size_yz)
        
    #Adjust crystal spacing for systems to be (nearly) perfectly periodic across boundaries
    spacing = np.zeros(3)
    for i in xrange(3):
        spacing[i] = vects[i][i] * ((axes[i,0]**2+axes[i,1]**2+axes[i,2]**2)**0.5)

    
    newline = '\n'
    script = newline.join(['#Atomic system info generated by AtomMan package',
                           '',
                           'units ' + units,
                           'atom_style ' + atom_style,
                           ''
                           'boundary ' + boundary,
                           '',
                           'lattice custom 1.0 &',
                           '        a1 %.12f %.12f %.12f &'      % (vects[0][0], vects[0][1], vects[0][2]),
                           '        a2 %.12f %.12f %.12f &'      % (vects[1][0], vects[1][1], vects[1][2]),
                           '        a3 %.12f %.12f %.12f &'      % (vects[2][0], vects[2][1], vects[2][2]),
                           '        origin %f %f %f &'           % (shift[0], shift[1], shift[2]),
                           '        spacing %.12f %.12f %.12f &' % (spacing[0], spacing[1], spacing[2]),
                           '        orient x %i %i %i &'         % (axes[0,0], axes[0,1], axes[0,2]),
                           '        orient y %i %i %i &'         % (axes[1,0], axes[1,1], axes[1,2]),
                           '        orient z %i %i %i &'         % (axes[2,0], axes[2,1], axes[2,2]),
                           pos_basis,
                           '',
                           region_box,
                           'create_box %i box' %(ntypes),
                           'create_atoms 1 box' + type_basis]) 
    return script