예제 #1
0
    usage += "  see --help for all options\n"

    parser = OptionParser(usage)
    parser.add_option("--transition_charges", dest="transition_charges", type=str, default="", help="Path to .chromo file with excitation energies, transition charges and magnetic transition dipoles for building a Frenckel exciton model. [default: %default]")
    parser.add_option("--spectrum_file", dest="spectrum_file", type=str, default="exciton_spectrum.dat", help="Save excitonic absorption and circular dichroism spectra to this file [default: %default]")
    parser.add_option("--state", dest="state", type=int, default=0, help="Excitonic state for which the gradient should be calculated (0 for ground state). [default: %default]")
    parser.add_option("--plot_spectra", dest="plot_spectra", type=str, default="", help="Choose units ('nm', 'Hartree', 'cm-1' or 'eV') for plotting absorption and circular dichroism spectra. [default: %default]")
    
    (opts,args) = parser.parse_args()
    if len(args) < 1:
        print usage
        exit(-1)

    ff_file = args[0]  #"h2.ff" #"ethene.ff" #"pyrene_crystal_expanded.ff" #
    # read force field definition
    atomlist, atomtypes, partial_charges, lattice_vectors = read_force_field(ff_file)
    # read transition charge for exciton model (if available)
    if opts.transition_charges != "":
        chromophores = list(read_transition_charges(opts.transition_charges))
    else:
        chromophores = []
    pff = PeriodicForceField(atomlist, atomtypes, partial_charges, lattice_vectors, chromophores)
    coords = XYZ.atomlist2vector(atomlist)

    # evaluate force field once
    energy, grad = pff.getEnergyAndGradient(coords, state=opts.state)
    print "Total energy: %s" % energy
    print "|gradient|  : %s" % la.norm(grad)  
    # compute exciton spectrum
    en, T, M = pff.getTransitionDipoles(verbose=1)
    save_exciton_spectrum(opts.spectrum_file, en, T, M)
예제 #2
0
    def __init__(self, atomlist_full, inner_indeces, embedding="electrostatic", pff_file=None, verbose=0):
        """
        Parameters:
        ===========
        atomlist_full: list of tuples (Zi,[xi,yi,zi]) for all atoms (QM + MM)
        inner_indeces: list of the indeces which belong to the QM atoms
        """

        assert embedding in ["mechanical", "electrostatic"]
        if "-" in inner_indeces:
            # index list contains ranges such as "9-14"
            inner_indeces = parseAtomTags(inner_indeces)
        else:
            inner_indeces = list(eval(inner_indeces))
        inner_indeces = list(set(inner_indeces))  # remove duplicate indeces
        inner_indeces.sort()
        if verbose > 0:
            print("Indeces of QM atoms:")
            print(inner_indeces)
            print("number of QM atoms: %d" % len(inner_indeces))
        # counting in the partitioning file starts at 1
        inner_indeces = np.asarray(inner_indeces, dtype=int)-1

        Nat = len(atomlist_full)
        all_indeces = set(range(0, Nat))
        outer_indeces = list(all_indeces - set(inner_indeces))
        outer_indeces.sort()
        self.inner_indeces = inner_indeces
        self.outer_indeces = outer_indeces
        # sort atoms into inner and outer region
        self.atomlist_full = atomlist_full
        self.atomlist_inner = [self.atomlist_full[i] for i in self.inner_indeces]
        self.atomlist_outer = [self.atomlist_full[i] for i in self.outer_indeces]

        if (pff_file == None):
            #
            # prepare the drivers for the UFF calculations
            # E^MM(I+O)
            self.FF_full = Gaussian.UFF_handler(self.atomlist_full,
                                                embedding=embedding, verbose=verbose, unique_tmp=True)
            # E^MM(I)
            self.FF_inner = Gaussian.UFF_handler(self.atomlist_inner,
                                                 embedding=embedding, verbose=verbose, unique_tmp=True)
        else:
            # load definitions for periodic force field
            if verbose > 0:
                print("periodic MM calculations with DREIDING")
            atomlist_full_ff, atomtypes_full, charges_full, lattice_vectors = read_force_field(pff_file)
            atomtypes_inner = [atomtypes_full[i] for i in self.inner_indeces]
            charges_inner = [charges_full[i] for i in self.inner_indeces]
            if (len(atomlist_full_ff) != Nat):
                raise ValueError("Wrong number of atoms in '%s'. Expected %d atoms but got %d !" \
                                 % (pff_file, Nat, len(atomlist)))
            # prepare drivers for DREIDING calculations
            # E^MM(I+O)
            self.FF_full =  PeriodicForceField(self.atomlist_full, atomtypes_full, charges_full,
                                               lattice_vectors, [], verbose=verbose)
            # E^MM(I)
            self.FF_inner = PeriodicForceField(self.atomlist_inner, atomtypes_inner, charges_inner,
                                               lattice_vectors, [], verbose=verbose)

        self.charge = 0