Exemple #1
0
    def do_proatomfns(self):
        self.do_atgrids_moldens()

        counter = 0
        old_populations = self.wavefn.nuclear_charges.astype(float)
        log("Iteration   Max change   Total charge")
        while True:
            # construct the pro-atom density functions, using the densities
            # from the previous iteration.
            self.proatomfns = []
            for i, number_i in enumerate(self.molecule.numbers):
                self.proatomfns.append(self.atom_table.records[number_i].get_atom_fn(old_populations[i]))

            populations = numpy.zeros(self.molecule.size, float)
            for i in xrange(self.molecule.size):
                integrand = self.atgrids[i].moldens*self._compute_atweights(self.atgrids[i], i)
                population = self._spherint(integrand)
                populations[i] = population

            # ordinary blablabla ...
            max_change = abs(populations-old_populations).max()
            log("%5i     % 10.5e   % 10.5e" % (
                counter, max_change, self.wavefn.nuclear_charges.sum() - populations.sum()
            ))
            if max_change < self.context.options.threshold:
                break
            counter += 1
            if counter > self.context.options.max_iter:
                raise RuntimeError("Iterative Hirshfeld failed to converge.")
            old_populations = populations
Exemple #2
0
 def dump_esp_test(self, filename, dipole_q, dipole_p, dipole_qp, dipole_qm,
                   mol_esp_cost, charges, dipoles):
     if self.active:
         filename = os.path.join(self.directory, filename)
         dump_esp_test(filename, dipole_q, dipole_p, dipole_qp, dipole_qm,
                       mol_esp_cost, charges, dipoles)
         log("Written %s" % filename)
Exemple #3
0
    def get_atom_fn(self, population=None):
        if population is None:
            population = float(self.number)
        else:
            population = float(population)
        if population < 0:
            raise ValueError("A negative number of electrons is not physical")

        if population < self.min_population:
            if self.number > 1 and population < self.min_population:
                log("Warning: unsafe extrapolation (below), number=%i, population=%f" % (self.number, population))
            ratio = population/self.min_population
            rhos = self.records[self.min_population]*ratio
        elif population > self.max_population:
            log("Warning: unsafe extrapolation (above), number=%i, population=%f" % (self.number, population))
            ratio = population/self.max_population
            rhos = self.records[self.max_population]*ratio
        else:
            high_population = int(numpy.ceil(population))
            low_population = int(numpy.floor(population))
            if low_population == high_population:
                rhos = self.records[low_population]
            else:
                low_ref = self.records[low_population]
                high_ref = self.records[high_population]
                if len(high_ref) > len(low_ref):
                    rhos = high_ref*(population - low_population)
                    rhos[:len(low_ref)] += low_ref*(high_population - population)
                else:
                    rhos = low_ref*(high_population - population)
                    rhos[:len(high_ref)] += high_ref*(population - low_population)

        result = CubicSpline(self.rgrid.rs[:len(rhos)], rhos)
        return result
Exemple #4
0
def make_density_profiles(program, num_lebedev, r_low, r_high, steps,
                          atom_numbers, max_ion, do_work, do_random):
    # generate lebedev grid
    lebedev_xyz, lebedev_weights = get_grid(num_lebedev)

    # define radii
    rgrid = RLogIntGrid(r_low, r_high, steps)
    agrid = ALebedevIntGrid(num_lebedev, do_random)

    f_pro = file("densities.txt", "w")
    print >> f_pro, rgrid.get_description()
    charges = []

    # run over all directories, run cubegen, load cube data
    pb = log.pb("Density profiles", len(atom_numbers) * (2 * max_ion + 1))
    for number in atom_numbers:
        symbol = periodic[number].symbol
        for charge in xrange(-max_ion, max_ion + 1):
            charge_label = charge_to_label(charge)
            pb()
            dirname = os.path.join("%03i%s" % (number, symbol), charge_label,
                                   "gs")
            # get the grid
            if not os.path.isdir(dirname): continue
            if do_work:
                work = Work(dirname)
            else:
                work = Work()
            grid = AtomicGrid.from_prefix("grid", work)
            if grid is None:
                center = numpy.zeros(3, float)
                grid = AtomicGrid.from_parameters("grid", work, center, rgrid,
                                                  agrid)
            # compute densities
            program.compute_density(grid, dirname)
            # this is spherical averaging, i.e. integral/(4*pi)
            radrhos = agrid.integrate(grid.moldens) / (4 * numpy.pi)
            print >> f_pro, "%3i %+2i" % (number, charge),
            # leave out near zeros to save space and time
            print >> f_pro, " ".join("%22.16e" % rho for rho in radrhos
                                     if rho > 1e-100)
            check = rgrid.integrate(4 * numpy.pi * rgrid.rs * rgrid.rs *
                                    radrhos)
            charges.append((number, symbol, charge, check))

    pb()
    f_pro.close()

    counter = 0
    for number, symbol, charge, real_charge in charges:
        log("Total charge error: %3i %2s %+2i    % 10.5e" %
            (number, symbol, charge, -real_charge + number - charge))
        counter += 1
Exemple #5
0
 def do_natural(dmat, label):
     orbitals_name = "%s_orbitals" % label
     occupations_name = "%s_occupations" % label
     orbitals = work.load(orbitals_name, (self.num_orbitals, self.num_orbitals))
     occupations = work.load(occupations_name)
     if orbitals is None or occupations is None:
         log("Computing the %s orbitals and occupation numbers ..." % label)
         occupations, orbitals = compute_naturals(dmat, self.num_orbitals)
         work.dump(orbitals_name, orbitals)
         work.dump(occupations_name, occupations)
     num = get_num_filled(occupations)
     return num, occupations, orbitals
Exemple #6
0
def select_ground_states(program, max_ion):
    log("Selecting ground states.")
    all_energies = program.get_energies()

    if 1 in all_energies:
        # Computation on a proton without electrons: solve manually.
        # crunch crunch ...
        all_energies[1][1] = {1: 0.0}

    f_au = file("chieta_au.txt", "w")
    f_ev = file("chieta_ev.txt", "w")

    print >> f_au, "All values below are in atomic units."
    print >> f_au, "             A         I          chi        eta     mult(neg,neut,pos)"
    print >> f_ev, "All values below are in electron volts."
    print >> f_ev, "             A         I          chi        eta     mult(neg,neut,pos)"

    for number, atom_energies in sorted(all_energies.iteritems()):
        energies = {}
        mult = {}
        symbol = periodic[number].symbol
        for charge in xrange(-max_ion, max_ion + 1):
            charge_label = charge_to_label(charge)
            if charge not in atom_energies:
                continue
            energies[charge] = min(atom_energies[charge].itervalues())
            mult[charge] = min(
                (energy, mult)
                for mult, energy in atom_energies[charge].iteritems())[1]
            newlink = os.path.join("%03i%s" % (number, symbol), charge_label,
                                   "gs")
            if os.path.isdir(os.path.dirname(newlink)):
                if os.path.exists(newlink): os.remove(newlink)
                os.symlink("mult%i" % mult[charge], newlink)

        if -1 in energies and 0 in energies and 1 in energies:
            chi = (energies[+1] - energies[-1]) / 2
            eta = (energies[+1] + energies[-1] - 2 * energies[0])
            values = [
                energies[0] - energies[-1], energies[+1] - energies[0], chi,
                eta
            ]
            print >> f_au, "% 3s" % symbol, "%2i" % number, " ".join(
                "% 10.5f" % v
                for v in values), "    ", mult[-1], mult[0], mult[1]
            print >> f_ev, "% 3s" % symbol, "%2i" % number, " ".join(
                "% 10.5f" % (v / electronvolt)
                for v in values), "    ", mult[-1], mult[0], mult[1]

    f_au.close()
    f_ev.close()
Exemple #7
0
 def do_natural(dmat, label):
     orbitals_name = "%s_orbitals" % label
     occupations_name = "%s_occupations" % label
     orbitals = work.load(orbitals_name,
                          (self.num_orbitals, self.num_orbitals))
     occupations = work.load(occupations_name)
     if orbitals is None or occupations is None:
         log("Computing the %s orbitals and occupation numbers ..." %
             label)
         occupations, orbitals = compute_naturals(
             dmat, self.num_orbitals)
         work.dump(orbitals_name, orbitals)
         work.dump(occupations_name, occupations)
     num = get_num_filled(occupations)
     return num, occupations, orbitals
Exemple #8
0
        def do_one_kind(kind):
            # first check for restricted
            orbitals = getattr(self.wavefn, "%s_orbitals" % kind)
            if kind!="alpha" and self.wavefn.alpha_orbitals is orbitals:
                # simply make references to alpha data and return
                log("Cloning alpha results (%s)" % kind)
                for i in xrange(self.molecule.size):
                    setattr(self.atgrids[i], "%s_overlap_matrix_orb" % kind, self.atgrids[i].alpha_overlap_matrix_orb)
                return

            # then try to load the matrices
            some_failed = False
            num_orbitals = self.wavefn.num_orbitals
            for i in xrange(self.molecule.size):
                matrix = self.atgrids[i].load("%s_%s_overlap_matrix_orb" % (self.prefix, kind))
                if matrix is None:
                    some_failed = True
                else:
                    matrix = matrix.reshape((num_orbitals, num_orbitals))
                setattr(self.atgrids[i], "%s_overlap_matrix_orb" % kind, matrix)

            if some_failed:
                self.do_atgrids_orbitals()
                self.do_atgrids_atweights()

                pb = log.pb("Computing atomic overlap matrices (%s)" % kind, self.molecule.size)
                for i in xrange(self.molecule.size):
                    pb()
                    if getattr(self.atgrids[i], "%s_overlap_matrix_orb" % kind) is None:
                        orbitals = getattr(self.atgrids[i], "%s_orbitals" % kind)
                        w = self.atgrids[i].atweights
                        matrix = numpy.zeros((num_orbitals,num_orbitals), float)
                        for j1 in xrange(num_orbitals):
                            for j2 in xrange(j1+1):
                                integrand = orbitals[j1]*orbitals[j2]*w
                                value = self._spherint(integrand)
                                matrix[j1,j2] = value
                                matrix[j2,j1] = value
                        setattr(self.atgrids[i], "%s_overlap_matrix_orb" % kind, matrix)
                        self.atgrids[i].dump("%s_%s_overlap_matrix_orb" % (self.prefix, kind), matrix)
                pb()

            filename = "%s_%s_overlap_matrices_orb.txt" % (self.prefix, kind)
            overlap_matrices = [
                getattr(grid, "%s_overlap_matrix_orb" % kind)
                for grid in self.atgrids
            ]
            self.output.dump_overlap_matrices(filename, overlap_matrices)
Exemple #9
0
def estimate_errors(atom_tables, fns_fchk):
    from hipart.context import Context, Options
    from hipart.schemes import HirshfeldScheme
    from hipart.log import log
    import numpy, time

    configs = []
    ref_config = None
    # The loops below one jobs for each grid configuration, i.e. combination
    # of radial and angular grid.
    for size, atom_table in sorted(atom_tables.iteritems()):
        for lebedev in 26, 50, 110, 230, 434, 770, 1454, 2702:
            all_charges = []
            start = time.clock()
            for fn_fchk in fns_fchk:
                log.begin("Config size=%i lebedev=%i fchk=%s" %
                          (size, lebedev, fn_fchk))
                # Make a new working environment for every sample
                options = Options(lebedev=lebedev,
                                  do_work=False,
                                  do_output=False,
                                  do_random=True)
                context = Context(fn_fchk, options)
                scheme = HirshfeldScheme(context, atom_table)
                scheme.do_charges()
                all_charges.append(scheme.charges)
                del scheme
                log.end()
            cost = time.clock() - start
            log("cost=%.2e" % cost)
            config = Config(size, lebedev, numpy.concatenate(all_charges),
                            cost)
            configs.append(config)
            if ref_config is None or (ref_config.size <= config.size and
                                      ref_config.lebedev <= config.lebedev):
                ref_config = config

    # Compute the errors
    ref_charges = configs[-1].charges
    for config in configs:
        config.error = (ref_charges - config.charges).std()

    # Log all
    log.begin("All configs")
    for config in configs:
        log(str(config))
    log.end()
    return configs
Exemple #10
0
def make_density_profiles(program, num_lebedev, r_low, r_high, steps, atom_numbers, max_ion, do_work, do_random):
    # generate lebedev grid
    lebedev_xyz, lebedev_weights = get_grid(num_lebedev)

    # define radii
    rgrid = RLogIntGrid(r_low, r_high, steps)
    agrid = ALebedevIntGrid(num_lebedev, do_random)

    f_pro = file("densities.txt", "w")
    print >> f_pro, rgrid.get_description()
    charges = []

    # run over all directories, run cubegen, load cube data
    pb = log.pb("Density profiles", len(atom_numbers)*(2*max_ion+1))
    for number in atom_numbers:
        symbol = periodic[number].symbol
        for charge in xrange(-max_ion, max_ion+1):
            charge_label = charge_to_label(charge)
            pb()
            dirname = os.path.join("%03i%s" % (number, symbol), charge_label, "gs")
            # get the grid
            if not os.path.isdir(dirname): continue
            if do_work:
                work = Work(dirname)
            else:
                work = Work()
            grid = AtomicGrid.from_prefix("grid", work)
            if grid is None:
                center = numpy.zeros(3,float)
                grid = AtomicGrid.from_parameters("grid", work, center, rgrid, agrid)
            # compute densities
            program.compute_density(grid, dirname)
            # this is spherical averaging, i.e. integral/(4*pi)
            radrhos = agrid.integrate(grid.moldens)/(4*numpy.pi)
            print >> f_pro, "%3i %+2i" % (number, charge),
            # leave out near zeros to save space and time
            print >> f_pro, " ".join("%22.16e" % rho for rho in radrhos if rho > 1e-100)
            check = rgrid.integrate(4*numpy.pi*rgrid.rs*rgrid.rs*radrhos)
            charges.append((number, symbol, charge, check))


    pb()
    f_pro.close()

    counter = 0
    for number, symbol, charge, real_charge in charges:
        log("Total charge error: %3i %2s %+2i    % 10.5e" % (number, symbol, charge, -real_charge+number-charge))
        counter += 1
Exemple #11
0
def estimate_errors(atom_tables, fns_fchk):
    from hipart.context import Context, Options
    from hipart.schemes import HirshfeldScheme
    from hipart.log import log
    import numpy, time

    configs = []
    ref_config = None
    # The loops below one jobs for each grid configuration, i.e. combination
    # of radial and angular grid.
    for size, atom_table in sorted(atom_tables.iteritems()):
        for lebedev in 26, 50, 110, 230, 434, 770, 1454, 2702:
            all_charges = []
            start = time.clock()
            for fn_fchk in fns_fchk:
                log.begin("Config size=%i lebedev=%i fchk=%s" % (size, lebedev, fn_fchk))
                # Make a new working environment for every sample
                options = Options(lebedev=lebedev, do_work=False,
                                  do_output=False, do_random=True)
                context = Context(fn_fchk, options)
                scheme = HirshfeldScheme(context, atom_table)
                scheme.do_charges()
                all_charges.append(scheme.charges)
                del scheme
                log.end()
            cost = time.clock() - start
            log("cost=%.2e" % cost)
            config = Config(size, lebedev, numpy.concatenate(all_charges), cost)
            configs.append(config)
            if ref_config is None or (ref_config.size <= config.size and ref_config.lebedev <= config.lebedev):
                ref_config = config

    # Compute the errors
    ref_charges = configs[-1].charges
    for config in configs:
        config.error = (ref_charges - config.charges).std()

    # Log all
    log.begin("All configs")
    for config in configs:
        log(str(config))
    log.end()
    return configs
Exemple #12
0
def estimate_errors(atom_tables, fn_fchk):
    from hipart.context import Context, Options
    from hipart.schemes import HirshfeldScheme
    from hipart.log import log
    import numpy, time

    configs = []
    # The loops below run 40 jobs for each grid configuration, i.e. combination
    # of radial and angular grid. Due to the random rotations of the angular
    # integration grids, the resulting charges will differ in each run. The
    # standard devation on each charge over the 40 runs is computed, and then
    # the error over all atoms is averaged. This error is used as 'the' error on
    # the charges. The cost is the cpu time consumed for computing this error.
    for size, atom_table in sorted(atom_tables.iteritems()):
        for lebedev in 26, 50, 110, 170, 266, 434:
            log.begin("Config size=%i lebedev=%i" % (size, lebedev))
            start = time.clock()
            all_charges = []
            for counter in xrange(40):
                log.begin("Sample counter=%i" % counter)
                # Make a new working environment for every sample
                options = Options(lebedev=lebedev,
                                  do_work=False,
                                  do_output=False)
                context = Context(fn_fchk, options)
                scheme = HirshfeldScheme(context, atom_table)
                scheme.do_charges()
                all_charges.append(scheme.charges)
                del scheme
                log.end()
            all_charges = numpy.array(all_charges)
            error = all_charges.std(axis=0).mean()
            cost = time.clock() - start
            log("error=%.2e cost=%.2e" % (error, cost))
            configs.append(Config(size, lebedev, error, cost))
            log.end()
    log.begin("All configs")
    for config in configs:
        log(str(config))
    log.end()
    return configs
Exemple #13
0
def select_ground_states(program, max_ion):
    log("Selecting ground states.")
    all_energies = program.get_energies()

    if 1 in all_energies:
        # Computation on a proton without electrons: solve manually.
        # crunch crunch ...
        all_energies[1][1] = {1: 0.0}

    f_au = file("chieta_au.txt", "w")
    f_ev = file("chieta_ev.txt", "w")

    print >> f_au, "All values below are in atomic units."
    print >> f_au, "             A         I          chi        eta     mult(neg,neut,pos)"
    print >> f_ev, "All values below are in electron volts."
    print >> f_ev, "             A         I          chi        eta     mult(neg,neut,pos)"

    for number, atom_energies in sorted(all_energies.iteritems()):
        energies = {}
        mult = {}
        symbol = periodic[number].symbol
        for charge in xrange(-max_ion, max_ion+1):
            charge_label = charge_to_label(charge)
            if charge not in atom_energies:
                continue
            energies[charge] = min(atom_energies[charge].itervalues())
            mult[charge] = min((energy, mult) for mult, energy in atom_energies[charge].iteritems())[1]
            newlink = os.path.join("%03i%s" % (number, symbol), charge_label, "gs")
            if os.path.isdir(os.path.dirname(newlink)):
                if os.path.exists(newlink): os.remove(newlink)
                os.symlink("mult%i" % mult[charge], newlink)

        if -1 in energies and 0 in energies and 1 in energies:
            chi = (energies[+1] - energies[-1])/2
            eta = (energies[+1] + energies[-1] - 2*energies[0])
            values = [energies[0] - energies[-1], energies[+1] - energies[0], chi, eta]
            print >> f_au, "% 3s" % symbol, "%2i" % number, " ".join("% 10.5f" % v for v in values), "    ", mult[-1],mult[0],mult[1]
            print >> f_ev, "% 3s" % symbol, "%2i" % number, " ".join("% 10.5f" % (v/electronvolt) for v in values), "    ", mult[-1],mult[0],mult[1]

    f_au.close()
    f_ev.close()
Exemple #14
0
def pareto_front(configs):
    from hipart.log import log
    # take a copy of the list, so that we can modify locally.
    configs = list(configs)
    # eliminate all configs that are not pareto-optimal
    configs.sort(key=(lambda c: c.error))
    i = 0
    while i < len(configs):
        ref_cost = configs[i].cost
        j = len(configs) -1
        while j > i:
            if configs[j].cost >= configs[i].cost:
                del configs[j]
            j -= 1
        i += 1
    # print the pareto front.
    log.begin("Pareto front")
    for config in configs:
        log(str(config))
        config.optimal = True
    log.end()
Exemple #15
0
def pareto_front(configs):
    from hipart.log import log
    # take a copy of the list, so that we can modify locally.
    configs = list(configs)
    # eliminate all configs that are not pareto-optimal
    configs.sort(key=(lambda c: c.error))
    i = 0
    while i < len(configs):
        ref_cost = configs[i].cost
        j = len(configs) - 1
        while j > i:
            if configs[j].cost >= configs[i].cost:
                del configs[j]
            j -= 1
        i += 1
    # print the pareto front.
    log.begin("Pareto front")
    for config in configs:
        log(str(config))
        config.optimal = True
    log.end()
Exemple #16
0
def estimate_errors(atom_tables, fn_fchk):
    from hipart.context import Context, Options
    from hipart.schemes import HirshfeldScheme
    from hipart.log import log
    import numpy, time

    configs = []
    # The loops below run 40 jobs for each grid configuration, i.e. combination
    # of radial and angular grid. Due to the random rotations of the angular
    # integration grids, the resulting charges will differ in each run. The
    # standard devation on each charge over the 40 runs is computed, and then
    # the error over all atoms is averaged. This error is used as 'the' error on
    # the charges. The cost is the cpu time consumed for computing this error.
    for size, atom_table in sorted(atom_tables.iteritems()):
        for lebedev in 26, 50, 110, 170, 266, 434:
            log.begin("Config size=%i lebedev=%i" % (size, lebedev))
            start = time.clock()
            all_charges = []
            for counter in xrange(40):
                log.begin("Sample counter=%i" % counter)
                # Make a new working environment for every sample
                options = Options(lebedev=lebedev, do_work=False,
                                  do_output=False)
                context = Context(fn_fchk, options)
                scheme = HirshfeldScheme(context, atom_table)
                scheme.do_charges()
                all_charges.append(scheme.charges)
                del scheme
                log.end()
            all_charges = numpy.array(all_charges)
            error = all_charges.std(axis=0).mean()
            cost = time.clock() - start
            log("error=%.2e cost=%.2e" % (error, cost))
            configs.append(Config(size, lebedev, error, cost))
            log.end()
    log.begin("All configs")
    for config in configs:
        log(str(config))
    log.end()
    return configs
Exemple #17
0
    def get_atom_fn(self, population=None):
        if population is None:
            population = float(self.number)
        else:
            population = float(population)
        if population < 0:
            raise ValueError("A negative number of electrons is not physical")

        if population < self.min_population:
            if self.number > 1 and population < self.min_population:
                log("Warning: unsafe extrapolation (below), number=%i, population=%f"
                    % (self.number, population))
            ratio = population / self.min_population
            rhos = self.records[self.min_population] * ratio
        elif population > self.max_population:
            log("Warning: unsafe extrapolation (above), number=%i, population=%f"
                % (self.number, population))
            ratio = population / self.max_population
            rhos = self.records[self.max_population] * ratio
        else:
            high_population = int(numpy.ceil(population))
            low_population = int(numpy.floor(population))
            if low_population == high_population:
                rhos = self.records[low_population]
            else:
                low_ref = self.records[low_population]
                high_ref = self.records[high_population]
                if len(high_ref) > len(low_ref):
                    rhos = high_ref * (population - low_population)
                    rhos[:len(low_ref)] += low_ref * (high_population -
                                                      population)
                else:
                    rhos = low_ref * (high_population - population)
                    rhos[:len(high_ref)] += high_ref * (population -
                                                        low_population)

        result = CubicSpline(self.rgrid.rs[:len(rhos)], rhos)
        return result
Exemple #18
0
    def do_atgrids_atweights(self):
        self.do_atgrids()

        log("Trying to load weight functions")
        success = self._load_atgrid_atweights()
        if not success:
            log("Could not load all weight functions from workdir. Computing them.")
            self._prepare_atweights()
            self._compute_atgrid_atweights()
            log("Writing results to workdir")
            self._dump_atgrid_atweights()
Exemple #19
0
def run_jobs(program, dirnames):
    pb = log.pb("Atomic computations", len(dirnames))
    failed = []
    for dirname in dirnames:
        pb()
        succes = program.run(dirname)
        if not succes:
            failed.append(dirname)
    pb()
    if len(failed) == len(dirnames):
        log("Could not execute any job. Is %s in the PATH?" % program.executable)
        sys.exit(-1)
    if len(failed) > 0:
        log("Some jobs failed:")
        for dirname in failed:
            log("  %s" % dirname)
Exemple #20
0
def run_jobs(program, dirnames):
    pb = log.pb("Atomic computations", len(dirnames))
    failed = []
    for dirname in dirnames:
        pb()
        succes = program.run(dirname)
        if not succes:
            failed.append(dirname)
    pb()
    if len(failed) == len(dirnames):
        log("Could not execute any job. Is %s in the PATH?" %
            program.executable)
        sys.exit(-1)
    if len(failed) > 0:
        log("Some jobs failed:")
        for dirname in failed:
            log("  %s" % dirname)
Exemple #21
0
    def do_proatomfns(self):
        self.do_atgrids_moldens()

        log("Generating initial guess for the pro-atoms")
        self.proatomfns = []
        for i in xrange(self.molecule.size):
            densities = self.atgrids[i].moldens
            profile = self.agrid.minimum(densities)
            profile[profile < 1e-6] = 1e-6
            self.proatomfns.append(CubicSpline(self.rgrid.rs, profile))

        counter = 0
        old_populations = self.wavefn.nuclear_charges.copy()
        log("Iteration   Max change   Total charge")
        while True:
            new_proatomfns = []
            populations = numpy.zeros(self.molecule.size, float)
            for i in xrange(self.molecule.size):
                integrand = self.atgrids[i].moldens*self._compute_atweights(self.atgrids[i], i)
                radfun = self.agrid.integrate(integrand)
                rs = self.rgrid.rs[:len(radfun)]
                populations[i] = self.rgrid.integrate(radfun*rs*rs)
                # add negligible tails to maintain a complete partitioning
                radfun[radfun < 1e-40] = 1e-40
                new_proatomfn = CubicSpline(self.rgrid.rs, radfun/4*numpy.pi)
                new_proatomfns.append(new_proatomfn)

            # ordinary blablabla ...
            max_change = abs(populations-old_populations).max()
            log("%5i     % 10.5e   % 10.5e" % (
                counter, max_change, self.wavefn.nuclear_charges.sum() - populations.sum()
            ))
            if max_change < self.context.options.threshold:
                break
            counter += 1
            if counter > self.context.options.max_iter:
                raise RuntimeError("Iterative Stockholder Analysis failed to converge.")
            old_populations = populations
            self.proatomfns = new_proatomfns
Exemple #22
0
 def dump_atom_matrix(self, filename, matrix, name):
     if self.active:
         filename = os.path.join(self.directory, filename)
         dump_atom_matrix(filename, matrix, name, self.numbers)
         log("Written %s" % filename)
Exemple #23
0
 def dump_atom_fields(self, filename, table, labels, name):
     if self.active:
         filename = os.path.join(self.directory, filename)
         dump_atom_fields(filename, table, labels, name, self.numbers)
         log("Written %s" % filename)
Exemple #24
0
 def dump_overlap_matrices(self, filename, overlap_matrices):
     if self.active:
         filename = os.path.join(self.directory, filename)
         dump_overlap_matrices(filename, overlap_matrices, self.numbers)
         log("Written %s" % filename)
Exemple #25
0
 def dump_esp_test(self, filename, dipole_q, dipole_p, dipole_qp, dipole_qm, mol_esp_cost, charges, dipoles):
     if self.active:
         filename = os.path.join(self.directory, filename)
         dump_esp_test(filename, dipole_q, dipole_p, dipole_qp, dipole_qm, mol_esp_cost, charges, dipoles)
         log("Written %s" % filename)
Exemple #26
0
 def __init__(self, executable, options):
     self.executable = executable
     self.qc = options.qc
     log("Computing atomic database with program Gaussian (%s,qc=%s)" %
         (self.executable, self.qc))
Exemple #27
0
 def log(self):
     log("Data read from: %s (%s)" % (self.filename, ",".join(self.options)))
     log("Restricted: %s" % self.restricted)
     log("Orbitals present: %s" % (self.alpha_orbital_energies is not None))
     log("Spin density present: %s" % (self.spin_density_matrix is not None))
     log("Number of alpha electrons: %i" % self.num_alpha)
     log("Number of beta electrons: %i" % self.num_beta)
     log("Number of electrons: %i" % self.num_electrons)
     log("Total charge: %i" % self.charge)
     log("Number of atoms: %i" % self.molecule.size)
     log("Chemical formula: %s" % self.molecule.chemical_formula)
Exemple #28
0
 def dump_overlap_matrices(self, filename, overlap_matrices):
     if self.active:
         filename = os.path.join(self.directory, filename)
         dump_overlap_matrices(filename, overlap_matrices, self.numbers)
         log("Written %s" % filename)
Exemple #29
0
 def dump_atom_fields(self, filename, table, labels, name):
     if self.active:
         filename = os.path.join(self.directory, filename)
         dump_atom_fields(filename, table, labels, name, self.numbers)
         log("Written %s" % filename)
Exemple #30
0
 def dump_atom_matrix(self, filename, matrix, name):
     if self.active:
         filename = os.path.join(self.directory, filename)
         dump_atom_matrix(filename, matrix, name, self.numbers)
         log("Written %s" % filename)
Exemple #31
0
 def dump_atom_scalars(self, filename, scalars, name):
     if self.active:
         filename = os.path.join(self.directory, filename)
         dump_atom_scalars(filename, scalars, name, self.numbers)
         log("Written %s" % filename)
Exemple #32
0
 def log(self):
     log("Data read from: %s (%s)" %
         (self.filename, ",".join(self.options)))
     log("Restricted: %s" % self.restricted)
     log("Orbitals present: %s" % (self.alpha_orbital_energies is not None))
     log("Spin density present: %s" %
         (self.spin_density_matrix is not None))
     log("Number of alpha electrons: %i" % self.num_alpha)
     log("Number of beta electrons: %i" % self.num_beta)
     log("Number of electrons: %i" % self.num_electrons)
     log("Total charge: %i" % self.charge)
     log("Number of atoms: %i" % self.molecule.size)
     log("Chemical formula: %s" % self.molecule.chemical_formula)
Exemple #33
0
 def __init__(self, executable, options):
     self.executable = executable
     self.qc = options.qc
     log("Computing atomic database with program Gaussian (%s,qc=%s)" % (self.executable,self.qc))
Exemple #34
0
 def dump_atom_scalars(self, filename, scalars, name):
     if self.active:
         filename = os.path.join(self.directory, filename)
         dump_atom_scalars(filename, scalars, name, self.numbers)
         log("Written %s" % filename)
Exemple #35
0
 def dump_esp_cost(self, filename, esp_cost):
     if self.active:
         filename = os.path.join(self.directory, filename)
         esp_cost.write_to_file(filename)
         log("Written %s" % filename)
Exemple #36
0
 def dump_esp_cost(self, filename, esp_cost):
     if self.active:
         filename = os.path.join(self.directory, filename)
         esp_cost.write_to_file(filename)
         log("Written %s" % filename)
Exemple #37
0
 def do_molgrid_molpot(self):
     self.do_molgrid()
     log("This may take a minute. Hang on.")
     self.wavefn.compute_potential(self.molgrid)