def capped_uff_nanotube(cnt,NcapN=0, NcapS=0, optimize_uff=1, out_xyz="/tmp/cnt.xyz"):
    """
    build capped nanotube and optimize it with UFF
    """
    nC,nT = cnt.NrCapAtoms()
    print "Expected number of Thomson points nT = %s" % nT
    print "If the caps have holes or very close atoms, you should try increasing"
    print "or reducing the number of Thomson points (by changing the options NcapN or NcapS)"
    if NcapN == 0:
        NcapN = nT
    if NcapS == 0:
        NcapS = nT

    """
    Different number of Thomson points are tested to find
    a pair (NcapN,NcapS) 
    """
    dcap = []
    dnmin=0
    dnmax=1
    ntrial=5
    for dnN in range(dnmin, dnmax):
        for dnS in range(dnmin, dnmax):
            # try for 5 times
            for n in range(0, ntrial):
                dcap.append( (dnN,dnS) )
    dcap = sorted(dcap, key=lambda (a,b): abs(a)+abs(b))

    for (dnN,dnS) in dcap:
        print "north cap: %s points, south cap: %s points" % (NcapN+dnN,NcapS+dnS)
        atomlist_carbons = capped_nanotube(cnt,NcapN+dnN,NcapS+dnS)
        if optimize_uff == 1:
            print "CNT will be optimized further with the Universal Force Field of G09"
            tmp_dir="/tmp"
            com_file = join(tmp_dir, "cnt_uff_opt.com")
            chk_file = join(tmp_dir, "cnt_uff_opt.chk")
            fchk_file = chk_file.replace(".chk", ".fchk")
            Gaussian.write_input(com_file, atomlist_carbons, \
                route="# UFF Opt", \
                title="Optimize (%s,%s)-Nanotube with UFF" % (cnt.n1,cnt.n2), chk=chk_file,mem=1000)
            try:
                Gaussian.run(com_file)
                # format checkpoint file
                Gaussian.formchk(chk_file, fchk_file)
                Data = Checkpoint.parseCheckpointFile(fchk_file)
                pos = Data["_Current_cartesian_coordinates"]
                atomlist_uff = XYZ.vector2atomlist(pos, atomlist_carbons)
                atomlist_carbons = atomlist_uff
            except Gaussian.GaussianError:
                print "UFF-optimization failed!"
                continue
        if check_connectivity(atomlist_carbons) == True:
            # no holes, correct connectivity
            break
        XYZ.write_xyz("/tmp/trials.xyz", [atomlist_carbons], mode="a")
    else:
        print ""

    XYZ.write_xyz(expandvars(expanduser(out_xyz)), [atomlist_carbons])
    print "Geometry of capped CNT written to %s" % out_xyz
def run_gaussian(atomlist, directory="."):
    """
    run Gaussian input script in `neb.gjf` and read energy and gradient
    from checkpoing file `grad.fchk`.

    Parameters
    ----------
    atomlist:  list of tuples with atomic numbers and cartesian positions (Zat,[x,y,z])
               for each atom
    directory: directory where the calculation should be performed

    Returns
    -------
    en    :  total energies of ground state (in Hartree)
    grad  :  gradient of total energy (in a.u.)
    """
    # create directory if it does not exist already
    os.system("mkdir -p %s" % directory)
    os.system("cp neb.gjf %s/neb.gjf" % directory)
    # update geometry
    XYZ.write_xyz("%s/geometry.xyz" % directory, [atomlist])
    # remove number of atoms and comment
    os.system("cd %s; tail -n +3 geometry.xyz > geom" % directory)
    # calculate electronic structure
    ret = os.system(r"cd %s; g09 < neb.gjf > neb.out" % directory)
    ret &= os.system(r"cd %s; formchk grad.chk >> neb.out" % directory)
    assert ret == 0, "Return status = %s, error in Gaussian calculation, see %s/neb.out!" % (
        ret, directory)
    # read checkpoint files
    data = Checkpoint.parseCheckpointFile("%s/grad.fchk" % directory)

    en = data["_Total_Energy"]
    grad = data["_Cartesian_Gradient"]

    return en, grad
Exemple #3
0
def wigner_from_G09_hessian(g09_file, Nsample=100, zero_threshold=1.0e-9):
    """
    create Wigner ensemble based on hessian matrix from Gaussian 09 calculation
    """
    suffix = g09_file.split(".")[-1]
    if suffix in ["out", "log"]:
        print("Reading Gaussian 09 log file %s" % g09_file)
        atomlist = Gaussian.read_geometry(g09_file)
        forces = Gaussian.read_forces(g09_file)
        hess = Gaussian.read_force_constants(g09_file)
    elif suffix in ["fchk"]:
        print("Reading formatted Gaussian 09 checkpoint file %s" % g09_file)
        Data = Checkpoint.parseCheckpointFile(g09_file)
        # cartesian coordinates
        pos = Data["_Current_cartesian_coordinates"]
        atnos = Data["_Atomic_numbers"]
        # forces
        frc = -Data["_Cartesian_Gradient"]
        atomlist = []
        forces = []
        for i, Zi in enumerate(atnos):
            atomlist.append((Zi, tuple(pos[3 * i:3 * (i + 1)])))
            forces.append((Zi, tuple(frc[3 * i:3 * (i + 1)])))
        # Hessian
        hess = Data["_Cartesian_Force_Constants"]

    masses = np.array(AtomicData.atomlist2masses(atomlist))

    x0 = XYZ.atomlist2vector(atomlist)
    x0 = shift_to_com(x0, masses)

    grad = -XYZ.atomlist2vector(forces)

    grad_nrm = la.norm(grad)
    print("  gradient norm = %s" % grad_nrm)
    #    assert grad_nrm < 1.0e-3, "Gradient norm too large for minimum!"
    vib_freq, vib_modes = vibrational_analysis(hess,
                                               masses,
                                               zero_threshold=zero_threshold)
    Aw, Bw = wigner_distribution(x0,
                                 hess,
                                 masses,
                                 zero_threshold=zero_threshold)
    gw = GaussianWavepacket.Gaussian(Aw, Bw)
    qs, ps = gw.sample(Nsample)
    mx = np.outer(masses, np.ones(Nsample)) * qs
    avg_com = np.mean(np.sum(mx[::3, :], axis=0)), np.mean(
        np.sum(mx[1::3, :], axis=0)), np.mean(np.sum(mx[2::3, :], axis=0))
    print(avg_com)

    geometries = [
        XYZ.vector2atomlist(qs[:, i], atomlist) for i in range(0, Nsample)
    ]

    return geometries
Exemple #4
0
    parser = optparse.OptionParser(usage)
    parser.add_option("--n1", dest="n1", help="Chiral index n1 [default: %default]", default=6, type=int)
    parser.add_option("--n2", dest="n2", help="Chiral index n2 [default: %default]", default=5, type=int)
    parser.add_option("--L", dest="L", help="Length of CNT in bohr [default: %default]", default=100.0, type=int)
    parser.add_option("--NcapN", dest="NcapN", help="Number of Thomson points on the northern cap, if set to 0 the number is estimated from the density of carbon atoms in graphene [default: %default]", default=0, type=int)
    parser.add_option("--NcapS", dest="NcapS", help="Number of Thomson points on the southern cap, if set to 0 the number is estimated from the density of carbon atoms in graphene [default: %default]", default=0, type=int)
    parser.add_option("--out_xyz", dest="out_xyz", help="Save the CNT geometry to this xyz-file [default: %default]", default="/tmp/cnt.xyz")
    parser.add_option("--optimize_uff", dest="optimize_uff", help="Optimize the built CNT with the UFF force field. This requires that the program g09 is installed. [default: %default]", default=1, type=int)

    (opts,args) = parser.parse_args()

    atomlist_carbons = capped_nanotube(opts.n1,opts.n2,opts.L,NcapN=opts.NcapN, NcapS=opts.NcapS)
    if opts.optimize_uff == 1:
        print("CNT will be optimized further with the Universal Force Field of G09")
        tmp_dir="/tmp"
        com_file = join(tmp_dir, "cnt_uff_opt.com")
        chk_file = join(tmp_dir, "cnt_uff_opt.chk")
        fchk_file = chk_file.replace(".chk", ".fchk")
        Gaussian.write_input(com_file, atomlist_carbons, \
            route="# UFF Opt", title="Optimize (%s,%s)-Nanotube with UFF" % (opts.n1,opts.n2), chk=chk_file,mem=1000)
        Gaussian.run(com_file)
        # format checkpoint file
        Gaussian.formchk(chk_file, fchk_file)
        Data = Checkpoint.parseCheckpointFile(fchk_file)
        pos = Data["_Current_cartesian_coordinates"]
        atomlist_uff = XYZ.vector2atomlist(pos, atomlist_carbons)
        atomlist_carbons = atomlist_uff

    XYZ.write_xyz(opts.out_xyz, [atomlist_carbons])
    print("Geometry of capped CNT written to %s" % opts.out_xyz)