def setUp(self):
     self.box_dimension = 3
     self.nr_particles = 10
     self.k = 42
     self.nr_dof = self.box_dimension * self.nr_particles
     self.origin = np.zeros(self.nr_dof)
     self.potential = Harmonic(self.origin, self.k, bdim=self.box_dimension, com=True)
     self.temp = 1
     self.nr_steps = 6e4
     self.mc = MC(self.potential, self.origin, self.temp, self.nr_steps)
     self.take_step_A = RandomCoordsDisplacement(42, 4, single=True, nparticles=self.nr_particles, bdim=self.box_dimension, min_acc_ratio=0.2, max_acc_ratio=0.2)
     self.take_step_B = RandomCoordsDisplacement(44, 0.1, single=True, nparticles=self.nr_particles, bdim=self.box_dimension, min_acc_ratio=0.2, max_acc_ratio=0.2)
     self.step = TakeStepProbabilities(46)
     self.weight_A = 22
     self.weight_B = 78
     self.step.add_step(self.take_step_A, self.weight_A)
     self.step.add_step(self.take_step_B, self.weight_B)
     self.mc.set_takestep(self.step)
     self.frequency_step_A = self.weight_A / (self.weight_A + self.weight_B)
     self.frequency_step_B = self.weight_B / (self.weight_A + self.weight_B)
     self.metropolis = MetropolisTest(50)
     self.mc.add_accept_test(self.metropolis)
     self.hist_min = 0
     self.hist_max = 1e4
     self.eq_steps = self.nr_steps / 2
     self.mc.set_report_steps(self.eq_steps)
     self.measure_energy = RecordEnergyHistogram(self.hist_min, self.hist_max, (self.hist_max - self.hist_min)/14, self.eq_steps)
     self.mc.add_action(self.measure_energy)
     self.true_energy = self.box_dimension * (self.nr_particles - 1) / 2
Beispiel #2
0
    def __init__(self,
                 potential,
                 coords,
                 temperature,
                 stepsize,
                 niter,
                 hEmin=0,
                 hEmax=100,
                 hbinsize=0.01,
                 radius=2.5,
                 acceptance=0.5,
                 adjustf=0.9,
                 adjustf_niter=1e4,
                 adjustf_navg=100,
                 bdim=3,
                 single=False,
                 seeds=None):
        #construct base class
        super(Metropolis_MCrunner, self).__init__(potential, coords,
                                                  temperature, niter)

        #get/set seeds
        if not seeds:
            i32max = np.iinfo(np.int32).max
            seeds = dict(takestep=np.random.randint(i32max),
                         metropolis=np.random.randint(i32max))
        self.seeds = seeds
        #construct takestep: random step
        self.step = RandomCoordsDisplacement(self.seeds['takestep'],
                                             stepsize,
                                             report_interval=adjustf_navg,
                                             factor=adjustf,
                                             min_acc_ratio=acceptance,
                                             max_acc_ratio=acceptance,
                                             single=single,
                                             nparticles=int(
                                                 len(coords) / bdim),
                                             bdim=bdim)
        #construct early configuration test: check within spherical container
        self.conftest = CheckSphericalContainer(radius, bdim)
        #construct accept test: Metropolis
        self.metropolis = MetropolisTest(self.seeds['metropolis'])
        #construct action: energy histogram
        self.binsize = hbinsize
        self.histogram = RecordEnergyHistogram(hEmin, hEmax, self.binsize,
                                               adjustf_niter)
        #set up pele:MC
        self.set_takestep(self.step)
        self.set_report_steps(
            adjustf_niter
        )  #set number of iterations for which steps are adapted
        self.add_accept_test(self.metropolis)
        self.add_conf_test(self.conftest)
        self.add_action(self.histogram)
Beispiel #3
0
    def __init__(
        self,
        potential,
        coords,
        temperature,
        stepsize,
        niter,
        hEmin=0,
        hEmax=100,
        hbinsize=0.01,
        radius=2.5,
        acceptance=0.5,
        adjustf=0.9,
        adjustf_niter=1e4,
        adjustf_navg=100,
        bdim=3,
        single=False,
        seeds=None,
    ):
        # construct base class
        super(Metropolis_MCrunner, self).__init__(potential, coords, temperature, niter)

        # get/set seeds
        if not seeds:
            i32max = np.iinfo(np.int32).max
            seeds = dict(takestep=np.random.randint(i32max), metropolis=np.random.randint(i32max))
        self.seeds = seeds
        # construct takestep: random step
        self.step = RandomCoordsDisplacement(
            self.seeds["takestep"],
            stepsize,
            report_interval=adjustf_navg,
            factor=adjustf,
            min_acc_ratio=acceptance,
            max_acc_ratio=acceptance,
            single=single,
            nparticles=int(len(coords) / bdim),
            bdim=bdim,
        )
        # construct early configuration test: check within spherical container
        self.conftest = CheckSphericalContainer(radius, bdim)
        # construct accept test: Metropolis
        self.metropolis = MetropolisTest(self.seeds["metropolis"])
        # construct action: energy histogram
        self.binsize = hbinsize
        self.histogram = RecordEnergyHistogram(hEmin, hEmax, self.binsize, adjustf_niter)
        # set up pele:MC
        self.set_takestep(self.step)
        self.set_report_steps(adjustf_niter)  # set number of iterations for which steps are adapted
        self.add_accept_test(self.metropolis)
        self.add_conf_test(self.conftest)
        self.add_action(self.histogram)
class TestTakeStepProbabilityHarmoinc(unittest.TestCase):
    
    def setUp(self):
        self.box_dimension = 3
        self.nr_particles = 10
        self.k = 42
        self.nr_dof = self.box_dimension * self.nr_particles
        self.origin = np.zeros(self.nr_dof)
        self.potential = Harmonic(self.origin, self.k, bdim=self.box_dimension, com=True)
        self.temp = 1
        self.nr_steps = 6e4
        self.mc = MC(self.potential, self.origin, self.temp, self.nr_steps)
        self.take_step_A = RandomCoordsDisplacement(42, 4, single=True, nparticles=self.nr_particles, bdim=self.box_dimension, min_acc_ratio=0.2, max_acc_ratio=0.2)
        self.take_step_B = RandomCoordsDisplacement(44, 0.1, single=True, nparticles=self.nr_particles, bdim=self.box_dimension, min_acc_ratio=0.2, max_acc_ratio=0.2)
        self.step = TakeStepProbabilities(46)
        self.weight_A = 22
        self.weight_B = 78
        self.step.add_step(self.take_step_A, self.weight_A)
        self.step.add_step(self.take_step_B, self.weight_B)
        self.mc.set_takestep(self.step)
        self.frequency_step_A = self.weight_A / (self.weight_A + self.weight_B)
        self.frequency_step_B = self.weight_B / (self.weight_A + self.weight_B)
        self.metropolis = MetropolisTest(50)
        self.mc.add_accept_test(self.metropolis)
        self.hist_min = 0
        self.hist_max = 1e4
        self.eq_steps = self.nr_steps / 2
        self.mc.set_report_steps(self.eq_steps)
        self.measure_energy = RecordEnergyHistogram(self.hist_min, self.hist_max, (self.hist_max - self.hist_min)/14, self.eq_steps)
        self.mc.add_action(self.measure_energy)
        self.true_energy = self.box_dimension * (self.nr_particles - 1) / 2
    
    def test_basic_harmonic(self):
        self.mc.run()
        self.assertAlmostEqual(self.frequency_step_A, self.take_step_A.get_count() / self.nr_steps, delta=1e-2)
        self.assertAlmostEqual(self.frequency_step_B, self.take_step_B.get_count() / self.nr_steps, delta=1e-2)
        self.assertAlmostEqual(self.take_step_A.get_stepsize(), self.take_step_B.get_stepsize(), delta=1e-2)
        mean_energy, var_energy = self.measure_energy.get_mean_variance()
        self.assertAlmostEqual(mean_energy, self.true_energy, delta=3e-1)
 def __init__(self, boxdim=2, nr_particles=100, hard_phi=0.4,
              nr_steps=1e6, epsilon=1, alpha=0.1, verbose=False):
     # Settings.
     np.random.seed(42)
     # Input parameters.
     self.boxdim = boxdim
     self.nr_particles = nr_particles
     self.hard_phi = hard_phi
     self.nr_steps = nr_steps
     self.epsilon = epsilon
     self.alpha = alpha
     self.verbose = verbose
     # Derived quantities.
     self.hard_radii = np.ones(self.nr_particles)
     def volume_nball(radius, n):
         return np.power(np.pi, n / 2) * np.power(radius, n) / gamma(n / 2 + 1)
     self.box_length = np.power(np.sum(np.asarray([volume_nball(r, self.boxdim) for r in self.hard_radii])) / self.hard_phi, 1 / self.boxdim)
     self.box_vector = np.ones(self.boxdim) * self.box_length
     # HS-WCA potential.
     self.potential = HS_WCA(use_periodic=True, use_cell_lists=True,
                             ndim=self.boxdim, eps=self.epsilon,
                             sca=self.alpha, radii=self.hard_radii,
                             boxvec=self.box_vector)
     # Initial configuration by minimization.
     self.nr_dof = self.boxdim * self.nr_particles
     self.x = np.random.uniform(-0.5 * self.box_length, 0.5 * self.box_length, self.nr_dof)
     optimizer = LBFGS_CPP(self.x, self.potential)
     optimizer.run()
     if not optimizer.get_result().success:
         print ("warning: minimization has not converged")
     self.x = optimizer.get_result().coords.copy()
     # Potential and MC rules.
     self.temperature = 1
     self.mc = MC(self.potential, self.x, self.temperature, self.nr_steps)
     self.step = RandomCoordsDisplacement(42, 1, single=True, nparticles=self.nr_particles, bdim=self.boxdim)
     if self.verbose:
         print ("initial MC stepsize")
         print self.step.get_stepsize()
     self.mc.set_takestep(self.step)
     self.eq_steps = self.nr_steps / 2
     self.mc.set_report_steps(self.eq_steps)
     self.gr_quench = RecordPairDistHistogram(self.box_vector, 50, self.eq_steps, self.nr_particles, optimizer=optimizer)
     self.gr = RecordPairDistHistogram(self.box_vector, 50, self.eq_steps, self.nr_particles)
     self.mc.add_action(self.gr_quench)
     self.mc.add_action(self.gr)
     self.test = MetropolisTest(44)
     self.mc.add_accept_test(self.test)
class ComputeGR():
    def __init__(self, boxdim=2, nr_particles=100, hard_phi=0.4,
                 nr_steps=1e6, epsilon=1, alpha=0.1, verbose=False):
        # Settings.
        np.random.seed(42)
        # Input parameters.
        self.boxdim = boxdim
        self.nr_particles = nr_particles
        self.hard_phi = hard_phi
        self.nr_steps = nr_steps
        self.epsilon = epsilon
        self.alpha = alpha
        self.verbose = verbose
        # Derived quantities.
        self.hard_radii = np.ones(self.nr_particles)
        def volume_nball(radius, n):
            return np.power(np.pi, n / 2) * np.power(radius, n) / gamma(n / 2 + 1)
        self.box_length = np.power(np.sum(np.asarray([volume_nball(r, self.boxdim) for r in self.hard_radii])) / self.hard_phi, 1 / self.boxdim)
        self.box_vector = np.ones(self.boxdim) * self.box_length
        # HS-WCA potential.
        self.potential = HS_WCA(use_periodic=True, use_cell_lists=True,
                                ndim=self.boxdim, eps=self.epsilon,
                                sca=self.alpha, radii=self.hard_radii,
                                boxvec=self.box_vector)
        # Initial configuration by minimization.
        self.nr_dof = self.boxdim * self.nr_particles
        self.x = np.random.uniform(-0.5 * self.box_length, 0.5 * self.box_length, self.nr_dof)
        optimizer = LBFGS_CPP(self.x, self.potential)
        optimizer.run()
        if not optimizer.get_result().success:
            print ("warning: minimization has not converged")
        self.x = optimizer.get_result().coords.copy()
        # Potential and MC rules.
        self.temperature = 1
        self.mc = MC(self.potential, self.x, self.temperature, self.nr_steps)
        self.step = RandomCoordsDisplacement(42, 1, single=True, nparticles=self.nr_particles, bdim=self.boxdim)
        if self.verbose:
            print ("initial MC stepsize")
            print self.step.get_stepsize()
        self.mc.set_takestep(self.step)
        self.eq_steps = self.nr_steps / 2
        self.mc.set_report_steps(self.eq_steps)
        self.gr_quench = RecordPairDistHistogram(self.box_vector, 50, self.eq_steps, self.nr_particles, optimizer=optimizer)
        self.gr = RecordPairDistHistogram(self.box_vector, 50, self.eq_steps, self.nr_particles)
        self.mc.add_action(self.gr_quench)
        self.mc.add_action(self.gr)
        self.test = MetropolisTest(44)
        self.mc.add_accept_test(self.test)
    def run(self):
        self.mc.set_print_progress()
        if not self.verbose:
            self.mc.disable_input_warnings()
        self.mc.run()
        if self.verbose:
            print ("adapted MC stepsize")
            print self.step.get_stepsize()
    def show_result(self):
        r = self.gr.get_hist_r()
        number_density = self.nr_particles / np.prod(self.box_vector)
        gr = self.gr.get_hist_gr(number_density, self.nr_particles)
        grq = self.gr_quench.get_hist_gr(number_density, self.nr_particles)
        plt.plot(r, gr, "o-", label="Equilibrium")
        plt.plot(r, grq, "x-", label="Quench")
        plt.xlabel(r"Distance $r$")
        plt.ylabel(r"Radial distr. function $g(r)$")
        plt.legend()
        plt.show()
Beispiel #7
0
class Metropolis_MCrunner(_BaseMCRunner):
    """This class is derived from the _base_MCrunner abstract
     method and performs Metropolis Monte Carlo. This particular implementation of the algorithm: 
     * runs niter steps per run call 
     * takes steps by sampling a random vector in a n dimensional hypersphere (n is the number of coordinates);
     * adjust the step size for the first adjustf_niter steps (averaging the acceptance for adjust_navg steps
       and adjusting the stepsize by a factor of 'adjustf') to meet some target acceptance 'acceptance'.
     * configuration test: accept if within a spherical box of radius 'radius'
     * acceptance test: metropolis for some particular temperature
     * record energy histogram (the energy histogram is resizable, but the bounds are defined by hEmin and hEmax,
       furthermore the bin size is set with hbinsize. Care must be taken because the array is resizable, if the step size
       is small and extremely high or low energies are sampled the memory for the histogram will be reallocated and this 
       might cause a badalloc error, if trying to allocate a huge array. If you are sampling unwanted extremely high or low energies
       then you might want to add a pele::EnergyWindow test that guarantees to keep you within a specific energy range and/or 
       make the stepsize larger or you might want to re-think about your simulation. Generally you shouldn't be 
       spanning energies that differ by several orders of magnitude, if that is the case, resizable or not resizable arrays are
       not the problem, you'd be incurring in memory issues no matter what you do, unless you write to disk at every iteration)
     * NOTE: some of the modules (e.g. take step and acceptance tests) require to be seeded. Users are free to do this as they think
     * is best, here we generate a random integer in [0,i32max) where i32max is the largest signed integer, for each seed. Each module
     * has a separate rng engine, therefore it's best if each receives a different randomly sampled seed
    """
    def __init__(self,
                 potential,
                 coords,
                 temperature,
                 stepsize,
                 niter,
                 hEmin=0,
                 hEmax=100,
                 hbinsize=0.01,
                 radius=2.5,
                 acceptance=0.5,
                 adjustf=0.9,
                 adjustf_niter=1e4,
                 adjustf_navg=100,
                 bdim=3,
                 single=False,
                 seeds=None):
        #construct base class
        super(Metropolis_MCrunner, self).__init__(potential, coords,
                                                  temperature, niter)

        #get/set seeds
        if not seeds:
            i32max = np.iinfo(np.int32).max
            seeds = dict(takestep=np.random.randint(i32max),
                         metropolis=np.random.randint(i32max))
        self.seeds = seeds
        #construct takestep: random step
        self.step = RandomCoordsDisplacement(self.seeds['takestep'],
                                             stepsize,
                                             report_interval=adjustf_navg,
                                             factor=adjustf,
                                             min_acc_ratio=acceptance,
                                             max_acc_ratio=acceptance,
                                             single=single,
                                             nparticles=int(
                                                 len(coords) / bdim),
                                             bdim=bdim)
        #construct early configuration test: check within spherical container
        self.conftest = CheckSphericalContainer(radius, bdim)
        #construct accept test: Metropolis
        self.metropolis = MetropolisTest(self.seeds['metropolis'])
        #construct action: energy histogram
        self.binsize = hbinsize
        self.histogram = RecordEnergyHistogram(hEmin, hEmax, self.binsize,
                                               adjustf_niter)
        #set up pele:MC
        self.set_takestep(self.step)
        self.set_report_steps(
            adjustf_niter
        )  #set number of iterations for which steps are adapted
        self.add_accept_test(self.metropolis)
        self.add_conf_test(self.conftest)
        self.add_action(self.histogram)

    def set_control(self, T):
        """set temperature, canonical control parameter"""
        self.temperature = T
        self.set_temperature(T)

    def get_stepsize(self):
        return self.step.get_stepsize()

    def dump_histogram(self, fname):
        """write histogram to fname"""
        Emin, Emax = self.histogram.get_bounds_val()
        histl = self.histogram.get_histogram()
        hist = np.array(histl)
        Energies, step = np.linspace(Emin,
                                     Emax,
                                     num=len(hist),
                                     endpoint=False,
                                     retstep=True)
        assert (abs(step - self.binsize) < self.binsize / 100)
        np.savetxt(fname, np.column_stack((Energies, hist)), delimiter='\t')
        mean, variance = self.histogram.get_mean_variance()
        return mean, variance

    def get_histogram(self):
        """returns a energy list and a histogram list"""
        Emin, Emax = self.histogram.get_bounds_val()
        histl = self.histogram.get_histogram()
        hist = np.array(histl)
        Energies, step = np.linspace(Emin,
                                     Emax,
                                     num=len(hist),
                                     endpoint=False,
                                     retstep=True)
        mean, variance = self.histogram.get_mean_variance()
        assert (abs(step - self.binsize) < self.binsize / 100)
        return Energies, hist, mean, variance

    def show_histogram(self):
        """shows the histogram"""
        hist = self.histogram.get_histogram()
        val = [i * self.binsize for i in xrange(len(hist))]
        plt.hist(val, weights=hist, bins=len(hist))
        plt.show()
Beispiel #8
0
class Metropolis_MCrunner(_BaseMCRunner):
    """This class is derived from the _base_MCrunner abstract
     method and performs Metropolis Monte Carlo. This particular implementation of the algorithm: 
     * runs niter steps per run call 
     * takes steps by sampling a random vector in a n dimensional hypersphere (n is the number of coordinates);
     * adjust the step size for the first adjustf_niter steps (averaging the acceptance for adjust_navg steps
       and adjusting the stepsize by a factor of 'adjustf') to meet some target acceptance 'acceptance'.
     * configuration test: accept if within a spherical box of radius 'radius'
     * acceptance test: metropolis for some particular temperature
     * record energy histogram (the energy histogram is resizable, but the bounds are defined by hEmin and hEmax,
       furthermore the bin size is set with hbinsize. Care must be taken because the array is resizable, if the step size
       is small and extremely high or low energies are sampled the memory for the histogram will be reallocated and this 
       might cause a badalloc error, if trying to allocate a huge array. If you are sampling unwanted extremely high or low energies
       then you might want to add a pele::EnergyWindow test that guarantees to keep you within a specific energy range and/or 
       make the stepsize larger or you might want to re-think about your simulation. Generally you shouldn't be 
       spanning energies that differ by several orders of magnitude, if that is the case, resizable or not resizable arrays are
       not the problem, you'd be incurring in memory issues no matter what you do, unless you write to disk at every iteration)
     * NOTE: some of the modules (e.g. take step and acceptance tests) require to be seeded. Users are free to do this as they think
     * is best, here we generate a random integer in [0,i32max) where i32max is the largest signed integer, for each seed. Each module
     * has a separate rng engine, therefore it's best if each receives a different randomly sampled seed
    """

    def __init__(
        self,
        potential,
        coords,
        temperature,
        stepsize,
        niter,
        hEmin=0,
        hEmax=100,
        hbinsize=0.01,
        radius=2.5,
        acceptance=0.5,
        adjustf=0.9,
        adjustf_niter=1e4,
        adjustf_navg=100,
        bdim=3,
        single=False,
        seeds=None,
    ):
        # construct base class
        super(Metropolis_MCrunner, self).__init__(potential, coords, temperature, niter)

        # get/set seeds
        if not seeds:
            i32max = np.iinfo(np.int32).max
            seeds = dict(takestep=np.random.randint(i32max), metropolis=np.random.randint(i32max))
        self.seeds = seeds
        # construct takestep: random step
        self.step = RandomCoordsDisplacement(
            self.seeds["takestep"],
            stepsize,
            report_interval=adjustf_navg,
            factor=adjustf,
            min_acc_ratio=acceptance,
            max_acc_ratio=acceptance,
            single=single,
            nparticles=int(len(coords) / bdim),
            bdim=bdim,
        )
        # construct early configuration test: check within spherical container
        self.conftest = CheckSphericalContainer(radius, bdim)
        # construct accept test: Metropolis
        self.metropolis = MetropolisTest(self.seeds["metropolis"])
        # construct action: energy histogram
        self.binsize = hbinsize
        self.histogram = RecordEnergyHistogram(hEmin, hEmax, self.binsize, adjustf_niter)
        # set up pele:MC
        self.set_takestep(self.step)
        self.set_report_steps(adjustf_niter)  # set number of iterations for which steps are adapted
        self.add_accept_test(self.metropolis)
        self.add_conf_test(self.conftest)
        self.add_action(self.histogram)

    def set_control(self, T):
        """set temperature, canonical control parameter"""
        self.temperature = T
        self.set_temperature(T)

    def get_stepsize(self):
        return self.step.get_stepsize()

    def dump_histogram(self, fname):
        """write histogram to fname"""
        Emin, Emax = self.histogram.get_bounds_val()
        histl = self.histogram.get_histogram()
        hist = np.array(histl)
        Energies, step = np.linspace(Emin, Emax, num=len(hist), endpoint=False, retstep=True)
        assert abs(step - self.binsize) < self.binsize / 100
        np.savetxt(fname, np.column_stack((Energies, hist)), delimiter="\t")
        mean, variance = self.histogram.get_mean_variance()
        return mean, variance

    def get_histogram(self):
        """returns a energy list and a histogram list"""
        Emin, Emax = self.histogram.get_bounds_val()
        histl = self.histogram.get_histogram()
        hist = np.array(histl)
        Energies, step = np.linspace(Emin, Emax, num=len(hist), endpoint=False, retstep=True)
        mean, variance = self.histogram.get_mean_variance()
        assert abs(step - self.binsize) < self.binsize / 100
        return Energies, hist, mean, variance

    def show_histogram(self):
        """shows the histogram"""
        hist = self.histogram.get_histogram()
        val = [i * self.binsize for i in xrange(len(hist))]
        plt.hist(val, weights=hist, bins=len(hist))
        plt.show()
Beispiel #9
0
    def __init__(self,
                 boxdim=2,
                 nr_particles=100,
                 hard_phi=0.4,
                 nr_steps=1e6,
                 epsilon=1,
                 alpha=0.1,
                 verbose=False):
        # Settings.
        np.random.seed(42)
        # Input parameters.
        self.boxdim = boxdim
        self.nr_particles = nr_particles
        self.hard_phi = hard_phi
        self.nr_steps = nr_steps
        self.epsilon = epsilon
        self.alpha = alpha
        self.verbose = verbose
        # Derived quantities.
        self.hard_radii = np.ones(self.nr_particles)

        def volume_nball(radius, n):
            return np.power(np.pi, n / 2) * np.power(radius,
                                                     n) / gamma(n / 2 + 1)

        self.box_length = np.power(
            np.sum(
                np.asarray(
                    [volume_nball(r, self.boxdim)
                     for r in self.hard_radii])) / self.hard_phi,
            1 / self.boxdim)
        self.box_vector = np.ones(self.boxdim) * self.box_length
        # HS-WCA potential.
        self.potential = HS_WCA(use_periodic=True,
                                use_cell_lists=True,
                                ndim=self.boxdim,
                                eps=self.epsilon,
                                sca=self.alpha,
                                radii=self.hard_radii,
                                boxvec=self.box_vector)
        # Initial configuration by minimization.
        self.nr_dof = self.boxdim * self.nr_particles
        self.x = np.random.uniform(-0.5 * self.box_length,
                                   0.5 * self.box_length, self.nr_dof)
        optimizer = LBFGS_CPP(self.x, self.potential)
        optimizer.run()
        if not optimizer.get_result().success:
            print("warning: minimization has not converged")
        self.x = optimizer.get_result().coords.copy()
        # Potential and MC rules.
        self.temperature = 1
        self.mc = MC(self.potential, self.x, self.temperature, self.nr_steps)
        self.step = RandomCoordsDisplacement(42,
                                             1,
                                             single=True,
                                             nparticles=self.nr_particles,
                                             bdim=self.boxdim)
        if self.verbose:
            print("initial MC stepsize")
            print self.step.get_stepsize()
        self.mc.set_takestep(self.step)
        self.eq_steps = self.nr_steps / 2
        self.mc.set_report_steps(self.eq_steps)
        self.gr_quench = RecordPairDistHistogram(self.box_vector,
                                                 50,
                                                 self.eq_steps,
                                                 self.nr_particles,
                                                 optimizer=optimizer)
        self.gr = RecordPairDistHistogram(self.box_vector, 50, self.eq_steps,
                                          self.nr_particles)
        self.mc.add_action(self.gr_quench)
        self.mc.add_action(self.gr)
        self.test = MetropolisTest(44)
        self.mc.add_accept_test(self.test)
Beispiel #10
0
class ComputeGR():
    def __init__(self,
                 boxdim=2,
                 nr_particles=100,
                 hard_phi=0.4,
                 nr_steps=1e6,
                 epsilon=1,
                 alpha=0.1,
                 verbose=False):
        # Settings.
        np.random.seed(42)
        # Input parameters.
        self.boxdim = boxdim
        self.nr_particles = nr_particles
        self.hard_phi = hard_phi
        self.nr_steps = nr_steps
        self.epsilon = epsilon
        self.alpha = alpha
        self.verbose = verbose
        # Derived quantities.
        self.hard_radii = np.ones(self.nr_particles)

        def volume_nball(radius, n):
            return np.power(np.pi, n / 2) * np.power(radius,
                                                     n) / gamma(n / 2 + 1)

        self.box_length = np.power(
            np.sum(
                np.asarray(
                    [volume_nball(r, self.boxdim)
                     for r in self.hard_radii])) / self.hard_phi,
            1 / self.boxdim)
        self.box_vector = np.ones(self.boxdim) * self.box_length
        # HS-WCA potential.
        self.potential = HS_WCA(use_periodic=True,
                                use_cell_lists=True,
                                ndim=self.boxdim,
                                eps=self.epsilon,
                                sca=self.alpha,
                                radii=self.hard_radii,
                                boxvec=self.box_vector)
        # Initial configuration by minimization.
        self.nr_dof = self.boxdim * self.nr_particles
        self.x = np.random.uniform(-0.5 * self.box_length,
                                   0.5 * self.box_length, self.nr_dof)
        optimizer = LBFGS_CPP(self.x, self.potential)
        optimizer.run()
        if not optimizer.get_result().success:
            print("warning: minimization has not converged")
        self.x = optimizer.get_result().coords.copy()
        # Potential and MC rules.
        self.temperature = 1
        self.mc = MC(self.potential, self.x, self.temperature, self.nr_steps)
        self.step = RandomCoordsDisplacement(42,
                                             1,
                                             single=True,
                                             nparticles=self.nr_particles,
                                             bdim=self.boxdim)
        if self.verbose:
            print("initial MC stepsize")
            print self.step.get_stepsize()
        self.mc.set_takestep(self.step)
        self.eq_steps = self.nr_steps / 2
        self.mc.set_report_steps(self.eq_steps)
        self.gr_quench = RecordPairDistHistogram(self.box_vector,
                                                 50,
                                                 self.eq_steps,
                                                 self.nr_particles,
                                                 optimizer=optimizer)
        self.gr = RecordPairDistHistogram(self.box_vector, 50, self.eq_steps,
                                          self.nr_particles)
        self.mc.add_action(self.gr_quench)
        self.mc.add_action(self.gr)
        self.test = MetropolisTest(44)
        self.mc.add_accept_test(self.test)

    def run(self):
        self.mc.set_print_progress()
        if not self.verbose:
            self.mc.disable_input_warnings()
        self.mc.run()
        if self.verbose:
            print("adapted MC stepsize")
            print self.step.get_stepsize()

    def show_result(self):
        r = self.gr.get_hist_r()
        number_density = self.nr_particles / np.prod(self.box_vector)
        gr = self.gr.get_hist_gr(number_density, self.nr_particles)
        grq = self.gr_quench.get_hist_gr(number_density, self.nr_particles)
        plt.plot(r, gr, "o-", label="Equilibrium")
        plt.plot(r, grq, "x-", label="Quench")
        plt.xlabel(r"Distance $r$")
        plt.ylabel(r"Radial distr. function $g(r)$")
        plt.legend()
        plt.show()