Exemple #1
0
def from_ase(atoms, specorder=None):
    """
    Convert ASE Atoms object to NAPSystem object.
    """
    spcorder = []
    if specorder is not None:
        spcorder = specorder
    symbols = atoms.get_chemical_symbols()
    spos = atoms.get_scaled_positions()
    vels = atoms.get_velocities()
    cell = atoms.get_cell()
    celli = np.linalg.inv(cell)
    if spos is None:
        raise ValueError('ASE atoms object has no atom in it.')
    #...Initialize and remake self.specorder
    for s in symbols:
        if s not in spcorder:
            spcorder.append(s)
    nsys = NAPSystem(specorder=spcorder)
    # nsys = cls(specorder=spcorder)
    nsys.alc = 1.0
    nsys.a1[:] = atoms.cell[0]
    nsys.a2[:] = atoms.cell[1]
    nsys.a3[:] = atoms.cell[2]
    #...First, initialize arrays
    natm = len(atoms)
    sids = [0 for i in range(natm)]
    poss = np.array(spos)
    if vels is None:
        vels = np.zeros((natm, 3))
    else:
        vels = np.array(vels)
    frcs = np.zeros((natm, 3))

    #...Create arrays to be installed into nsys.atoms
    sids = [nsys.specorder.index(si) + 1 for si in symbols]
    nsys.atoms.sid = sids
    nsys.atoms[['x', 'y', 'z']] = poss
    for i in range(len(vels)):
        vels[i] = np.dot(celli, vels[i])
    nsys.atoms[['vx', 'vy', 'vz']] = vels
    nsys.atoms[['fx', 'fy', 'fz']] = frcs

    return nsys
Exemple #2
0
def read_pmd(fname='pmdini', specorder=None):
    nsys = NAPSystem()
    if specorder is not None:
        nsys.specorder = specorder
    incatm = 0
    with open(fname, 'r') as f:
        iline = 0
        symbol = None
        for line in f.readlines():
            if line[0] in ('#', '!'):  # comment line
                if 'specorder:' in line:  # overwrite specorder if specified in file
                    data = line.split()
                    specorder = [d for d in data[2:len(data)]]
                    if nsys.specorder and set(
                            nsys.specorder) != set(specorder):
                        print(' WARNING: specorders are inconsistent, ' +
                              'use one in the file.')
                    nsys.specorder = specorder
            else:
                if nsys.specorder is None or len(nsys.specorder) == 0:
                    raise ValueError(
                        'Specorder must be specified via the file or an argument.'
                    )
                iline = iline + 1
                data = line.split()
                # 1st: lattice constant
                if iline == 1:
                    nsys.alc = float(data[0])
                # 2nd-4th: cell vectors
                elif iline == 2:
                    nsys.a1 = np.array([float(x) for x in data])
                elif iline == 3:
                    nsys.a2 = np.array([float(x) for x in data])
                elif iline == 4:
                    nsys.a3 = np.array([float(x) for x in data])
                # 5th-7th: velocity of cell vectors
                elif 5 <= iline <= 7:
                    pass
                # 8th: num of atoms
                elif iline == 8:
                    natm = int(data[0])
                    sids = [0 for i in range(natm)]
                    # poss = [ np.zeros(3) for i in range(natm) ]
                    # vels = [ np.zeros(3) for i in range(natm) ]
                    # frcs = [ np.zeros(3) for i in range(natm) ]
                    poss = np.zeros((natm, 3))
                    vels = np.zeros((natm, 3))
                    frcs = np.zeros((natm, 3))
                # 9th-: atom positions
                else:
                    if incatm > natm:
                        break
                    fdata = [float(x) for x in data]
                    tag = fdata[0]
                    sid, ifmv, num = decode_tag(tag)
                    # poss[incatm][:] = fdata[1:4]
                    # vels[incatm][:] = fdata[4:7]
                    poss[incatm, :] = fdata[1:4]
                    vels[incatm, :] = fdata[4:7]
                    sids[incatm] = sid
                    incatm += 1
    nsys.atoms[['x', 'y', 'z']] = poss
    nsys.atoms[['vx', 'vy', 'vz']] = vels
    nsys.atoms[['fx', 'fy', 'fz']] = frcs
    nsys.atoms['sid'] = sids
    return nsys
Exemple #3
0
def read_CHGCAR(fname='CHGCAR', specorder=None):
    """
    Read CHGCAR file and get information of cell, atoms, and volumetric data.

    Parameters
    ----------
    fname : str
         File name to be read.
    """
    nsys = NAPSystem()
    with open(fname, 'r') as f:
        # 1st line: comment
        f.readline()
        # 2nd: lattice constant
        nsys.alc = float(f.readline().split()[0])
        # 3rd-5th: cell vectors
        nsys.a1 = np.array([float(x) for x in f.readline().split()])
        nsys.a2 = np.array([float(x) for x in f.readline().split()])
        nsys.a3 = np.array([float(x) for x in f.readline().split()])
        # 6th: species names or number of each species
        buff = f.readline().split()
        if not buff[0].isdigit():
            spcs = copy.deepcopy(buff)
            buff = f.readline().split()
            if specorder is None:
                nsys.specorder = spcs
            else:
                nsys.specorder = specorder
                for s in spcs:
                    if s not in nsys.specorder:
                        nsys.specorder.append(s)
        num_species = np.array([int(n) for n in buff])
        try:
            spcs
        except NameError:
            spcs = nsys.specorder
        #...Check number of species in POSCAR file and in specorder
        if len(num_species) > len(nsys.specorder):
            msg = '''
ers of species in POSCAR is greater than the one in specorder, which should be the same or less.
er of species in POSCAR = {0:d}
need to specify the species order correctly with --specorder option.
            '''.format(len(num_species))
            raise ValueError(msg)
        natm = np.sum(num_species)
        sids = [0 for i in range(natm)]
        poss = np.zeros((natm, 3))
        vels = np.zeros((natm, 3))
        frcs = np.zeros((natm, 3))
        #print("Number of atoms = {0:5d}".format(natm))
        # 7th or 8th line: comment
        c7 = f.readline()
        if c7[0] in ('s', 'S'):
            c7 = f.readline()
        if c7[0] in ('c', 'C'):  # positions are in Cartesian coordinate
            hi = nsys.get_hmat_inv()
            coord = 'cartesian'
        else:  # such as "Direct"
            coord = 'scaled'

        #...Atom positions
        for i in range(natm):
            buff = f.readline().split()
            sid = 1
            m = 0
            sindex = 0
            for n in num_species:
                m += n
                if i < m:
                    if spcs and nsys.specorder:
                        sid = nsys.specorder.index(spcs[sindex]) + 1
                    break
                sid += 1
                sindex += 1
            sids[i] = sid
            pos = [float(buff[0]), float(buff[1]), float(buff[2])]
            if coord == 'cartesian':
                x1, x2, x3 = cartesian_to_scaled(hi, pos[0], pos[1], pos[2])
            elif coord == 'scaled':
                x1, x2, x3 = pos[0], pos[1], pos[2]
            poss[i][:] = [x1, x2, x3]

        #...Up to here, code should be the same as read_POSCAR, in case of CHGCAR lines follow
        nsys.atoms[['x', 'y', 'z']] = poss
        nsys.atoms[['vx', 'vy', 'vz']] = vels
        nsys.atoms[['fx', 'fy', 'fz']] = frcs
        nsys.atoms['sid'] = sids

        #...Read volumetric data
        f.readline()  # should be one blank line
        ndiv = [int(x) for x in f.readline().split()]
        ndata = ndiv[0] * ndiv[1] * ndiv[2]
        voldata = np.zeros(ndata)
        inc = 0
        while True:
            line = [float(d) for d in f.readline().split()]
            for d in line:
                voldata[inc] = d
                inc += 1
            if inc >= ndata:
                break
        #...Stop reading CHGCAR file here, ignoring the rest of file
        nsys.ndiv = copy.copy(ndiv)
        nsys.voldata = np.reshape(voldata, ndiv, order='F')
    return nsys
Exemple #4
0
def read_xsf(fname="xsf", specorder=None):
    from nappy.elements import get_symbol_from_number
    nsys = NAPSystem()
    if specorder is None:
        nsys.specorder = []
    else:
        nsys.specorder = specorder
    f = open(fname, 'r')
    mode = 'None'
    ixyz = 0
    iatm = 0
    natm = -1
    for line in f.readlines():
        if 'CRYSTAL' in line:
            mode = 'CRYSTAL'
            continue
        elif 'PRIMVEC' in line:
            mode = 'PRIMVEC'
            continue
        elif 'PRIMCOORD' in line:
            mode = 'PRIMCOORD'
            # Before going further, create inversed h-matrix
            hi = nsys.get_hmat_inv()
            # print 'Inversed h-matrix:'
            # print hi
            continue

        if mode == 'CRYSTAL':
            pass
        elif mode == 'PRIMVEC':
            if ixyz == 0:
                arr = [float(x) for x in line.split()]
                nsys.a1[0] = arr[0]
                nsys.a1[1] = arr[1]
                nsys.a1[2] = arr[2]
            elif ixyz == 1:
                arr = [float(x) for x in line.split()]
                nsys.a2[0] = arr[0]
                nsys.a2[1] = arr[1]
                nsys.a2[2] = arr[2]
            elif ixyz == 2:
                arr = [float(x) for x in line.split()]
                nsys.a3[0] = arr[0]
                nsys.a3[1] = arr[1]
                nsys.a3[2] = arr[2]
            ixyz += 1
        elif mode == 'PRIMCOORD':
            data = line.split()
            if len(data) == 1:
                natm = int(data[0])
                sids = [0 for i in range(natm)]
                poss = np.zeros((natm, 3))
                vels = np.zeros((natm, 3))
                frcs = np.zeros((natm, 3))
                continue
            elif len(data) == 2:
                natm = int(data[0])
                nspcs = int(data[1])
                sids = [0 for i in range(natm)]
                poss = np.zeros((natm, 3))
                vels = np.zeros((natm, 3))
                frcs = np.zeros((natm, 3))
                continue
            elif len(data) == 4 or len(data) == 7:
                if iatm >= natm:
                    continue
                symbol = get_symbol_from_number(int(data[0]))
                if symbol not in nsys.specorder:
                    nsys.specorder.append(symbol)
                sid = nsys.specorder.index(symbol) + 1
                sids[iatm] = sid
                # ai.set_sid(sid)
                xc = float(data[1])
                yc = float(data[2])
                zc = float(data[3])
                xi, yi, zi = cartesian_to_scaled(hi, xc, yc, zc)
                poss[iatm, :] = [xi, yi, zi]
                # print 'iatm,symbol,sid,xc,yc,zc = ',iatm,symbol,sid,xc,yc,zc
            else:
                continue
            iatm += 1
    nsys.alc = 1.0
    nsys.atoms[['x', 'y', 'z']] = poss
    nsys.atoms[['vx', 'vy', 'vz']] = vels
    nsys.atoms[['fx', 'fy', 'fz']] = frcs
    nsys.atoms['sid'] = sids
    f.close()
    return nsys
Exemple #5
0
def read_lammps_data(fname="data.lammps", atom_style='atomic', specorder=None):
    nsys = NAPSystem()
    if specorder is None:
        nsys.specorder = []
    else:
        nsys.specorder = specorder
    f = open(fname, 'r')
    mode = 'None'
    iatm = 0
    symbol = None
    nsys.alc = 1.0
    xy = 0.0
    xz = 0.0
    yz = 0.0
    for line in f.readlines():
        data = line.split()
        if mode == 'None':
            if 'atoms' in line:
                natm = int(data[0])
                sids = [0 for i in range(natm)]
                poss = np.zeros((natm, 3))
                vels = np.zeros((natm, 3))
                frcs = np.zeros((natm, 3))
            elif 'atom types' in line:
                nspcs = int(data[0])
            elif 'xlo' in line:
                xlo = float(data[0])
                xhi = float(data[1])
            elif 'ylo' in line:
                ylo = float(data[0])
                yhi = float(data[1])
            elif 'zlo' in line:
                zlo = float(data[0])
                zhi = float(data[1])
            elif 'xy' in line:
                xy = float(data[0])
                xz = float(data[1])
                yz = float(data[2])
            elif 'Atoms' in line:
                mode = 'Atoms'
                #...Cell info (xhi,xlo,...) should already be read
                # nsys.a1 = np.array([xhi-xlo,xy,xz],dtype=float)
                # nsys.a2 = np.array([0.0,yhi-ylo,yz],dtype=float)
                # nsys.a3 = np.array([0.0,0.0,zhi-zlo],dtype=float)
                nsys.a1 = np.array([xhi - xlo, 0.0, 0.0], dtype=float)
                nsys.a2 = np.array([xy, yhi - ylo, 0.0], dtype=float)
                nsys.a3 = np.array([xz, yz, zhi - zlo], dtype=float)
                hmat = nsys.get_hmat()
                hmati = np.linalg.inv(hmat)
                continue
        elif mode == 'Atoms':
            if len(data) >= 5 and iatm < natm:
                idat = 0
                # ai = Atom()
                idat += 1
                # ai.set_sid(int(data[idat]))
                sid = int(data[idat])
                sids[iatm] = sid
                if nsys.specorder:
                    symbol = nsys.specorder[sid - 1]
                # if symbol and ai.symbol != symbol:
                #     ai.set_symbol(symbol)
                # if atom_style == 'charge':
                #     idat += 1
                #     chg = float(data[idat])
                #     # ai.set_aux('charge',chg)
                #     if aux_names and 'charge' not in aux_names:

                idat += 1
                x0 = float(data[idat])
                idat += 1
                y0 = float(data[idat])
                idat += 1
                z0 = float(data[idat])
                x = hmati[0, 0] * x0 + hmati[0, 1] * y0 + hmati[0, 2] * z0
                y = hmati[1, 0] * x0 + hmati[1, 1] * y0 + hmati[1, 2] * z0
                z = hmati[2, 0] * x0 + hmati[2, 1] * y0 + hmati[2, 2] * z0
                x = pbc(x)
                y = pbc(y)
                z = pbc(z)
                poss[iatm, :] = [x, y, z]
                iatm += 1
    f.close()
    nsys.atoms[['x', 'y', 'z']] = poss
    nsys.atoms[['vx', 'vy', 'vz']] = vels
    nsys.atoms[['fx', 'fy', 'fz']] = frcs
    nsys.atoms['sid'] = sids
    return nsys
Exemple #6
0
def read_dump(fname="dump", specorder=None):
    nsys = NAPSystem()
    f = open(fname, 'r')
    mode = 'None'
    ixyz = 0
    iatm = 0
    natm = -1
    symbol = None
    if specorder is None:
        nsys.specorder = []
    else:
        nsys.specorder = specorder
    nsys.alc = 1.0
    xy = 0.0
    xz = 0.0
    yz = 0.0
    aux_exists = {
        'x': -1,
        'y': -1,
        'z': -1,
        'xu': -1,
        'yu': -1,
        'zu': -1,
        'fx': -1,
        'fy': -1,
        'fz': -1,
        'ekin': -1,
        'epot': -1,
        'sxx': -1,
        'syy': -1,
        'szz': -1,
        'syz': -1,
        'sxz': -1,
        'sxy': -1,
        'chg': -1,
        'chi': -1
    }
    ivx = -1
    ivy = -1
    ivz = -1
    ifx = -1
    ify = -1
    ifz = -1
    for line in f.readlines():
        data = line.split()
        if 'ITEM' in line:
            if 'NUMBER OF ATOMS' in line:
                mode = 'NUMBER OF ATOMS'
                continue
            elif 'BOX BOUNDS' in line:
                mode = 'BOX BOUNDS'
                continue
            elif 'ATOMS' in line:
                mode = 'ATOMS'
                aux_names = [name for i, name in enumerate(data) if i > 1]
                aux_names.remove('id')
                aux_names.remove('type')
                if ('x' not in aux_names and 'xu' not in aux_names) or \
                   ('y' not in aux_names and 'zu' not in aux_names) or \
                   ('z' not in aux_names and 'zu' not in aux_names):
                    raise ValueError(
                        'Not enough coordinate info.\nCheck the dump file format.'
                    )
                try:
                    ix = aux_names.index('x') + 2
                except Exception:
                    ix = aux_names.index('xu') + 2
                try:
                    iy = aux_names.index('y') + 2
                except Exception:
                    iy = aux_names.index('yu') + 2
                try:
                    iz = aux_names.index('z') + 2
                    # iauxstart = 5
                except Exception:
                    iz = aux_names.index('zu') + 2
                    # iauxstart = 5
                try:
                    ivx = aux_names.index('vx') + 2
                    ivy = aux_names.index('vy') + 2
                    ivz = aux_names.index('vz') + 2
                    # iauxstart = 8
                except Exception:
                    pass
                try:
                    ifx = aux_names.index('fx') + 2
                    ify = aux_names.index('fy') + 2
                    ifz = aux_names.index('fz') + 2
                except Exception:
                    pass
                # for s in ('x','xu','y','yu','z','zu','vx','vy','vz'):
                #     if s in aux_names:
                #         aux_names.remove(s)
                if len(aux_names) > 0:
                    auxs = np.zeros((natm, len(aux_names)))
                continue
            elif 'TIMESTEP' in line:
                mode = 'TIMESTEP'
                continue

        if mode == 'TIMESTEP':
            timestep = int(data[0])
        elif mode == 'NUMBER OF ATOMS':
            natm = int(data[0])
            sids = [0 for i in range(natm)]
            # poss = [ np.zeros(3) for i in range(natm) ]
            # vels = [ np.zeros(3) for i in range(natm) ]
            # frcs = [ np.zeros(3) for i in range(natm) ]
            poss = np.zeros((natm, 3))
            vels = np.zeros((natm, 3))
            frcs = np.zeros((natm, 3))
        elif mode == 'BOX BOUNDS':
            if ixyz == 0:
                xlo_bound = float(data[0])
                xhi_bound = float(data[1])
                if len(data) > 2:
                    xy = float(data[2])
            elif ixyz == 1:
                ylo_bound = float(data[0])
                yhi_bound = float(data[1])
                if len(data) > 2:
                    xz = float(data[2])
            elif ixyz == 2:
                zlo_bound = float(data[0])
                zhi_bound = float(data[1])
                if len(data) > 2:
                    yz = float(data[2])
            ixyz += 1
            if ixyz > 2:
                xlo = xlo_bound - min(0.0, xy, xz, xy + xz)
                xhi = xhi_bound - max(0.0, xy, xz, xy + xz)
                ylo = ylo_bound - min(0.0, yz)
                yhi = yhi_bound - max(0.0, yz)
                zlo = zlo_bound
                zhi = zhi_bound
                #...Original definition of lattice vectors could be different
                #   from this, because the definition in dump format
                #   requires y,z-components of vector a1 to be zero.
                nsys.a1 = np.array([xhi - xlo, 0., 0.], dtype=float)
                nsys.a2 = np.array([xy, yhi - ylo, 0.], dtype=float)
                nsys.a3 = np.array([xz, yz, zhi - zlo], dtype=float)
                hmat = nsys.get_hmat()
                hmati = nsys.get_hmat_inv()
        elif mode == 'ATOMS':
            if iatm < natm:
                symbol = None
                if data[1].isdigit():
                    sid = int(data[1])
                    sids[iatm] = sid
                    symbol = nsys.specorder[sid - 1]
                else:
                    symbol = data[1]
                    if symbol not in nsys.specorder:
                        nsys.specorder.append(symbol)
                    sid = nsys.specorder.index(symbol) + 1
                    sids[iatm] = sid
                r0 = [float(data[ix]), float(data[iy]), float(data[iz])]
                if ivx > 0 and ivy > 0 and ivz > 0:
                    v0 = [float(data[ivx]), float(data[ivy]), float(data[ivz])]
                else:
                    v0 = [0., 0., 0.]
                if ifx > 0 and ify > 0 and ifz > 0:
                    f0 = [float(data[ifx]), float(data[ify]), float(data[ifz])]
                else:
                    f0 = [0., 0., 0.]
                sr = np.dot(hmati, r0)
                sv = np.dot(hmati, v0)
                sr[0] = pbc(sr[0])
                sr[1] = pbc(sr[1])
                sr[2] = pbc(sr[2])
                # poss[iatm][:] = sr[:]
                # vels[iatm][:] = sv[:]
                poss[iatm, :] = sr[:]
                vels[iatm, :] = sv[:]
                frcs[iatm, :] = f0[:]

                if len(aux_names) > 0:
                    # auxs[iatm,:] = [ float(x) for x in data[iauxstart:] ]
                    auxs[iatm, :] = [float(x) for x in data[2:]]

            iatm += 1

    nsys.atoms[['x', 'y', 'z']] = poss
    nsys.atoms[['vx', 'vy', 'vz']] = vels
    nsys.atoms[['fx', 'fy', 'fz']] = frcs
    nsys.atoms['sid'] = sids
    for ia in range(len(aux_names)):
        name = aux_names[ia]
        if name in ('x', 'xu', 'y', 'yu', 'z', 'zu', 'vx', 'vy', 'vz', 'fx',
                    'fy', 'fz'):
            continue
        aux = auxs[:, ia]
        nsys.atoms[name] = aux.tolist()
    f.close()
    return nsys
Exemple #7
0
def read_POSCAR(fname='POSCAR', specorder=None):
    nsys = NAPSystem()
    with open(fname, 'r') as f:
        # 1st line: comment
        f.readline()
        # 2nd: lattice constant
        nsys.alc = float(f.readline().split()[0])
        # 3rd-5th: cell vectors
        nsys.a1 = np.array([float(x) for x in f.readline().split()])
        nsys.a2 = np.array([float(x) for x in f.readline().split()])
        nsys.a3 = np.array([float(x) for x in f.readline().split()])
        # 6th: species names or number of each species
        buff = f.readline().split()
        if not buff[0].isdigit():
            spcs = copy.deepcopy(buff)
            buff = f.readline().split()
            if specorder is None:
                nsys.specorder = spcs
            else:
                nsys.specorder = specorder
                for s in spcs:
                    if s not in nsys.specorder:
                        nsys.specorder.append(s)
        num_species = np.array([int(n) for n in buff])
        try:
            spcs
        except NameError:
            spcs = nsys.specorder
        #...Check number of species in POSCAR file and in specorder
        if len(num_species) > len(nsys.specorder):
            msg = '''
ers of species in POSCAR is greater than the one in specorder, which should be the same or less.
er of species in POSCAR = {0:d}
need to specify the species order correctly with --specorder option.
            '''.format(len(num_species))
            raise ValueError(msg)
        natm = np.sum(num_species)
        sids = [0 for i in range(natm)]
        # poss = [ np.zeros(3) for i in range(natm) ]
        # vels = [ np.zeros(3) for i in range(natm) ]
        # frcs = [ np.zeros(3) for i in range(natm) ]
        poss = np.zeros((natm, 3))
        vels = np.zeros((natm, 3))
        frcs = np.zeros((natm, 3))
        #print("Number of atoms = {0:5d}".format(natm))
        # 7th or 8th line: comment
        c7 = f.readline()
        if c7[0] in ('s', 'S'):
            c7 = f.readline()
        if c7[0] in ('c', 'C'):  # positions are in Cartesian coordinate
            hi = nsys.get_hmat_inv()
            coord = 'cartesian'
        else:  # such as "Direct"
            coord = 'scaled'

        #...Atom positions
        for i in range(natm):
            buff = f.readline().split()
            sid = 1
            m = 0
            sindex = 0
            for n in num_species:
                m += n
                if i < m:
                    if spcs and nsys.specorder:
                        sid = nsys.specorder.index(spcs[sindex]) + 1
                    break
                sid += 1
                sindex += 1
            sids[i] = sid
            pos = [float(buff[0]), float(buff[1]), float(buff[2])]
            if coord == 'cartesian':
                x1, x2, x3 = cartesian_to_scaled(hi, pos[0], pos[1], pos[2])
            elif coord == 'scaled':
                x1, x2, x3 = pos[0], pos[1], pos[2]
            poss[i, :] = [x1, x2, x3]

    nsys.atoms[['x', 'y', 'z']] = poss
    nsys.atoms[['vx', 'vy', 'vz']] = vels
    nsys.atoms[['fx', 'fy', 'fz']] = frcs
    nsys.atoms['sid'] = sids
    return nsys
Exemple #8
0
def to_given_vector(infile,specorder,a1new,a2new,a3new):
    psys = NAPSystem(fname=infile,specorder=specorder)
    psys.assign_pbc()
    psys.a1 = psys.a1 *psys.alc
    psys.a2 = psys.a2 *psys.alc
    psys.a3 = psys.a3 *psys.alc
    psys.alc = 1.0
    print('a1  = ',psys.a1)
    print('a2  = ',psys.a2)
    print('a3  = ',psys.a3)
    
    pos = psys.get_real_positions()
    spos = psys.get_scaled_positions()
    for i in range(min(len(psys.atoms),10)):
        a = psys.atoms[i]
        print('{0:5d} {1:s}'.format(a.id,a.symbol)
              +' {0:12.5f} {1:12.5f} {2:12.5f}'.format(spos[i,0],
                                                       spos[i,1],
                                                       spos[i,2])
              +' {0:12.5f} {1:12.5f} {2:12.5f}'.format(pos[i,0],
                                                       pos[i,1],
                                                       pos[i,2]))
    
    # print(psys.get_scaled_positions())
    # print(psys.get_real_positions())
    # sa1new = np.zeros(3,dtype=float)
    # sa2new = np.zeros(3,dtype=float)
    # sa3new = np.zeros(3,dtype=float)
    #tmp = raw_input('Input new a1 vector: ')
    #a1new[:] = [ float(x) for x in tmp.split(',') ]
    # sa1new[:] = [ 0.5, 0.5, 0.0]
    #tmp = raw_input('Input new a2 vector: ')
    #a2new[:] = [ float(x) for x in tmp.split(',') ]
    # sa2new[:] = [ 0.0, 1.0, 0.0 ]
    #tmp = raw_input('Input new a3 vector: ')
    #a3new[:] = [ float(x) for x in tmp.split(',') ]
    # sa3new[:] = [ 0.5, 0.5, 1.0 ]
    hmat = psys.get_hmat()
    a1new = np.dot(hmat,sa1new)
    a2new = np.dot(hmat,sa2new)
    a3new = np.dot(hmat,sa3new)
    print('new a1 in hmat_orig =',sa1new)
    print('new a2 in hmat_orig =',sa2new)
    print('new a3 in hmat_orig =',sa3new)
    print('new a1 =',a1new)
    print('new a2 =',a2new)
    print('new a3 =',a3new)
    psnew = NAPSystem(specorder=specorder)
    psnew.set_lattice(psys.alc,a1new,a2new,a3new)

    # Expand the original system for the search of atoms to be included 
    # in the new system.
    # First, compute how much we have to expand the original system
    hi = np.linalg.inv(hmat)
    icsa1new = [0,0,0]
    icsa2new = [0,0,0]
    icsa3new = [0,0,0]
    for i in range(3):
        if sa1new[i] < 0.0:
            icsa1new[i] = int(sa1new[i]-1.0)
        else:
            icsa1new[i] = int(sa1new[i]+1.0)
        if sa2new[i] < 0.0: 
            icsa2new[i] = int(sa2new[i]-1.0) 
        else:
            icsa2new[i] = int(sa2new[i]+1.0)
        if sa3new[i] < 0.0:
            icsa3new[i] = int(sa3new[i]-1.0) 
        else:
            icsa3new[i] = int(sa3new[i]+1.0)
    print(icsa1new)
    print(icsa2new)
    print(icsa3new)
    for i in range(3):
        if icsa1new[i] == 0:
            raise RuntimeError('icsa1new[i] == 0')
        if icsa2new[i] == 0:
            raise RuntimeError('icsa2new[i] == 0')
        if icsa3new[i] == 0:
            raise RuntimeError('icsa3new[i] == 0')
    irange1 = (min(icsa1new[0],icsa2new[0],icsa3new[0]),
               max(icsa1new[0],icsa2new[0],icsa3new[0]))
    irange2 = (min(icsa1new[1],icsa2new[1],icsa3new[1]),
               max(icsa1new[1],icsa2new[1],icsa3new[1]))
    irange3 = (min(icsa1new[2],icsa2new[2],icsa3new[2]),
               max(icsa1new[2],icsa2new[2],icsa3new[2]))

    print('irange1: ',irange1)
    print('irange2: ',irange2)
    print('irange3: ',irange3)
    expos = []
    symbols = psys.get_symbols()
    print('symbols :',symbols)
    exsymbols = []
    print('Expanding the original system...')
    for n3 in range(min(0,irange3[0]),irange3[1]):
        for n2 in range(min(0,irange2[0]),irange2[1]):
            for n1 in range(min(0,irange1[0]),irange1[1]):
                for ia in range(len(spos)):
                    sposi = copy.deepcopy(spos[ia])
                    sposi[0] += n1
                    sposi[1] += n2
                    sposi[2] += n3
                    posi = np.dot(hmat,sposi)
                    symbol = symbols[ia]
                    # print(ia,n1,n2,n3,symbol,sposi)
                    expos.append(posi)
                    exsymbols.append(symbol)

    print('Extracting the atoms inside the new unit vectors...')
    hmat= psnew.get_hmat()
    hi = np.linalg.inv(hmat)
    for ia,posi in enumerate(expos):
        sposi = np.dot(hi,posi)
        if 0.0 <= sposi[0] < 1.0 and \
           0.0 <= sposi[1] < 1.0 and \
           0.0 <= sposi[2] < 1.0:
            atom = Atom()
            symbol = exsymbols[ia]
            print('{0:5d} {1:s}'.format(ia,symbol)
                  +' {0:12.5f} {1:12.5f} {2:12.5f}'.format(sposi[0],
                                                           sposi[1],
                                                           sposi[2]))
            
            atom.set_symbol(symbol)
            atom.set_pos(sposi[0],sposi[1],sposi[2])
            psnew.add_atom(atom)
            
    tmp = None
    #tmp = raw_input('Input periodic shift vector if you want: ')
    tmp = ' 0.5, 0.0, 0.5'
    if tmp:
        shift = [ float(x) for x in tmp.split(',')]
        for a in psnew.atoms:
            a.pos[0] += shift[0]
            a.pos[1] += shift[1]
            a.pos[2] += shift[2]
        psnew.assign_pbc()
    psnew.write_POSCAR(infile+'.new')
    print('Check '+infile+'.new')