Ejemplo n.º 1
0
    def testConstructionWithCustomRates(self):
        """ Test construction with custom rates. """
        # A first process.
        coords = [[1.0, 2.0, 3.4], [12.0, 13.0, -1.0], [1.1, 1.2, 1.3]]
        types0 = ["A", "*", "B"]
        types1 = ["B", "*", "A"]
        rate_0_1 = 3.5
        process_0 = KMCProcess(coords,
                               types0,
                               types1,
                               basis_sites=[0, 1, 3],
                               rate_constant=rate_0_1)

        # A second process.
        coords = [[1.0, 2.0, 3.4], [1.1, 1.2, 1.3]]
        types0 = ["A", "C"]
        types1 = ["C", "A"]
        rate_0_1 = 1.5
        process_1 = KMCProcess(coords,
                               types0,
                               types1,
                               basis_sites=[0, 1, 3],
                               rate_constant=rate_0_1)

        processes = [process_0, process_1]

        # Test that it fails with the wrong rate calculator.
        interactions = KMCInteractions(processes=processes,
                                       implicit_wildcards=True)

        # Test that it fails if the rate calculator is of wrong type.
        self.assertRaises(
            Error, lambda: interactions.setRateCalculator(
                rate_calculator="CustomRateCalculator"))

        # Test that it fails if the rate calculator is instantiated.
        self.assertRaises(
            Error, lambda: interactions.setRateCalculator(
                rate_calculator=CustomRateCalculator("DummyConfig")))

        # Construct the interactions object with a custom rate calculator class.
        kmc_interactions = KMCInteractions(processes=processes,
                                           implicit_wildcards=True)
        kmc_interactions.setRateCalculator(
            rate_calculator=CustomRateCalculator)

        # Test the stored name.
        self.assertEqual(
            kmc_interactions._KMCInteractions__rate_calculator_str,
            "CustomRateCalculator")

        # Test the stored rate calculator class.
        self.assertTrue(
            kmc_interactions._KMCInteractions__rate_calculator_class ==
            CustomRateCalculator)
Ejemplo n.º 2
0
    def testConstructionWithCustomRates(self):
        """ Test construction with custom rates. """
        # A first process.
        coords = [[1.0,2.0,3.4],[12.0,13.0,-1.0],[1.1,1.2,1.3]]
        types0 = ["A","*","B"]
        types1 = ["B","*","A"]
        rate_0_1 = 3.5
        process_0 = KMCProcess(coords, types0, types1, basis_sites=[0,1,3], rate_constant=rate_0_1)

        # A second process.
        coords = [[1.0,2.0,3.4],[1.1,1.2,1.3]]
        types0 = ["A","C"]
        types1 = ["C","A"]
        rate_0_1 = 1.5
        process_1 = KMCProcess(coords, types0, types1, basis_sites=[0,1,3], rate_constant=rate_0_1)

        processes = [process_0, process_1]

        # Test that it fails with the wrong rate calculator.
        interactions = KMCInteractions(processes=processes,
                                       implicit_wildcards=True)

        # Test that it fails if the rate calculator is of wrong type.
        self.assertRaises( Error, lambda : interactions.setRateCalculator(rate_calculator="CustomRateCalculator") )

        # Test that it fails if the rate calculator is instantiated.
        self.assertRaises( Error, lambda : interactions.setRateCalculator(rate_calculator=CustomRateCalculator("DummyConfig")) )

        # Construct the interactions object with a custom rate calculator class.
        kmc_interactions = KMCInteractions(processes=processes,
                                           implicit_wildcards=True)
        kmc_interactions.setRateCalculator(rate_calculator=CustomRateCalculator)

        # Test the stored name.
        self.assertEqual(kmc_interactions._KMCInteractions__rate_calculator_str, "CustomRateCalculator")

        # Test the stored rate calculator class.
        self.assertTrue(kmc_interactions._KMCInteractions__rate_calculator_class == CustomRateCalculator)
Ejemplo n.º 3
0
    def testBackendWithCustomRates(self):
        """ Test that we can construct the backend object with custom rates. """
        # A first process.
        coords = [[1.0,2.0,3.4],[1.1,1.2,1.3]]
        types0 = ["A","B"]
        types1 = ["B","A"]
        rate_0_1 = 3.5
        process_0 = KMCProcess(coords, types0, types1, basis_sites=[0], rate_constant=rate_0_1)

        # A second process.
        types0 = ["A","C"]
        types1 = ["C","A"]
        rate_0_1 = 1.5
        process_1 = KMCProcess(coords, types0, types1, basis_sites=[0], rate_constant=rate_0_1)

        processes = [process_0, process_1]

        # Set the custom rates class to use.
        custom_rates_class = CustomRateCalculator

        # Set the rate function on the custom rates calculator for testing.
        ref_rnd = numpy.random.uniform(0.0,1.0)
        def testRateFunction(obj, coords, types_before, types_after, rate_const, process_number, global_coordinate):
            return ref_rnd

        # Store the original.
        custom_rate_function = custom_rates_class.rate
        try:
            custom_rates_class.rate = testRateFunction

            # Construct the interactions object.
            kmc_interactions = KMCInteractions(processes=processes,
                                               implicit_wildcards=False)

            # Setup a dict with the possible types.
            possible_types = {
                "A" : 13,
                "D" : 2,
                "B" : 3,
                "J" : 4,
                "C" : 5,
                }

            # Use a dummy argument for the configuration.
            config = "DummyConfig"

            # Test that it fails if the rate calculator is of wrong class.
            kmc_interactions.setRateCalculator(rate_calculator=Error)
            self.assertRaises( Error, lambda : kmc_interactions._backend(possible_types, 2, config) )

            # Test that it fails if the rate calculator is the base class.
            kmc_interactions.setRateCalculator(rate_calculator=KMCRateCalculatorPlugin)
            self.assertRaises( Error, lambda : kmc_interactions._backend(possible_types, 2, config) )

            # But this should work.
            kmc_interactions.setRateCalculator(rate_calculator=custom_rates_class)

            # Construct the backend.
            cpp_interactions = kmc_interactions._backend(possible_types, 2, config)

            # Test that the configuration on the custom rate class is the one given.
            self.assertTrue(kmc_interactions._KMCInteractions__rate_calculator.configuration == config) #  <-  Check by reference.

            # Get the rate calculator reference out of the C++ object and
            # check that a call from C++ calls the Python extension.
            cpp_coords = Backend.StdVectorDouble()
            cpp_types1 = Backend.StdVectorString()
            cpp_types2 = Backend.StdVectorString()
            rate_constant = 543.2211
            process_number = 33
            coordinate = (1.2,3.4,5.6)

            self.assertAlmostEqual( cpp_interactions.rateCalculator().backendRateCallback(cpp_coords,
                                                                                          cpp_coords.size()/3,
                                                                                          cpp_types1,
                                                                                          cpp_types2,
                                                                                          rate_constant,
                                                                                          process_number,
                                                                                          coordinate[0],
                                                                                          coordinate[1],
                                                                                          coordinate[2]), ref_rnd, 12 )
            self.assertAlmostEqual( kmc_interactions._KMCInteractions__rate_calculator.backendRateCallback(cpp_coords,
                                                                                                           cpp_coords.size()/3,
                                                                                                           cpp_types1,
                                                                                                           cpp_types2,
                                                                                                           rate_constant,
                                                                                                           process_number,
                                                                                                           coordinate[0],
                                                                                                           coordinate[1],
                                                                                                           coordinate[2]), ref_rnd, 12 )


        finally:
            # Reset the class.
            custom_rates_class.rate = custom_rate_function





        # Construct a C++ RateCalculator object directly and check that this object
        # returns the rate given to it.
        cpp_rate_calculator = Backend.RateCalculator()
        self.assertAlmostEqual( cpp_rate_calculator.backendRateCallback(cpp_coords,
                                                                        cpp_coords.size()/3,
                                                                        cpp_types1,
                                                                        cpp_types2,
                                                                        rate_constant,
                                                                        process_number,
                                                                        coordinate[0],
                                                                        coordinate[1],
                                                                        coordinate[2]), rate_constant, 12 )
Ejemplo n.º 4
0
    def testBackendWithCustomRates(self):
        """ Test that we can construct the backend object with custom rates. """
        # A first process.
        coords = [[1.0, 2.0, 3.4], [1.1, 1.2, 1.3]]
        types0 = ["A", "B"]
        types1 = ["B", "A"]
        rate_0_1 = 3.5
        process_0 = KMCProcess(coords,
                               types0,
                               types1,
                               basis_sites=[0],
                               rate_constant=rate_0_1)

        # A second process.
        types0 = ["A", "C"]
        types1 = ["C", "A"]
        rate_0_1 = 1.5
        process_1 = KMCProcess(coords,
                               types0,
                               types1,
                               basis_sites=[0],
                               rate_constant=rate_0_1)

        processes = [process_0, process_1]

        # Set the custom rates class to use.
        custom_rates_class = CustomRateCalculator

        # Set the rate function on the custom rates calculator for testing.
        ref_rnd = numpy.random.uniform(0.0, 1.0)

        def testRateFunction(obj, coords, types_before, types_after,
                             rate_const, process_number, global_coordinate):
            return ref_rnd

        # Store the original.
        custom_rate_function = custom_rates_class.rate
        try:
            custom_rates_class.rate = testRateFunction

            # Construct the interactions object.
            kmc_interactions = KMCInteractions(processes=processes,
                                               implicit_wildcards=False)

            # Setup a dict with the possible types.
            possible_types = {
                "A": 13,
                "D": 2,
                "B": 3,
                "J": 4,
                "C": 5,
            }

            # Use a dummy argument for the configuration.
            config = "DummyConfig"

            # Test that it fails if the rate calculator is of wrong class.
            kmc_interactions.setRateCalculator(rate_calculator=Error)
            self.assertRaises(
                Error,
                lambda: kmc_interactions._backend(possible_types, 2, config))

            # Test that it fails if the rate calculator is the base class.
            kmc_interactions.setRateCalculator(
                rate_calculator=KMCRateCalculatorPlugin)
            self.assertRaises(
                Error,
                lambda: kmc_interactions._backend(possible_types, 2, config))

            # But this should work.
            kmc_interactions.setRateCalculator(
                rate_calculator=custom_rates_class)

            # Construct the backend.
            cpp_interactions = kmc_interactions._backend(
                possible_types, 2, config)

            # Test that the configuration on the custom rate class is the one given.
            self.assertTrue(
                kmc_interactions._KMCInteractions__rate_calculator.
                configuration == config)  #  <-  Check by reference.

            # Get the rate calculator reference out of the C++ object and
            # check that a call from C++ calls the Python extension.
            cpp_coords = Backend.StdVectorDouble()
            cpp_types1 = Backend.StdVectorString()
            cpp_types2 = Backend.StdVectorString()
            rate_constant = 543.2211
            process_number = 33
            coordinate = (1.2, 3.4, 5.6)

            self.assertAlmostEqual(
                cpp_interactions.rateCalculator().backendRateCallback(
                    cpp_coords,
                    cpp_coords.size() / 3, cpp_types1, cpp_types2,
                    rate_constant, process_number, coordinate[0],
                    coordinate[1], coordinate[2]), ref_rnd, 12)
            self.assertAlmostEqual(
                kmc_interactions._KMCInteractions__rate_calculator.
                backendRateCallback(cpp_coords,
                                    cpp_coords.size() / 3, cpp_types1,
                                    cpp_types2, rate_constant, process_number,
                                    coordinate[0], coordinate[1],
                                    coordinate[2]), ref_rnd, 12)

        finally:
            # Reset the class.
            custom_rates_class.rate = custom_rate_function

        # Construct a C++ RateCalculator object directly and check that this object
        # returns the rate given to it.
        cpp_rate_calculator = Backend.RateCalculator()
        self.assertAlmostEqual(
            cpp_rate_calculator.backendRateCallback(
                cpp_coords,
                cpp_coords.size() / 3, cpp_types1, cpp_types2, rate_constant,
                process_number, coordinate[0], coordinate[1], coordinate[2]),
            rate_constant, 12)
Ejemplo n.º 5
0
    def testCustomRatesRun(self):
        """ Test the run of an A-B flip model with custom rates. """
        # Cell.
        cell_vectors = [[   1.000000e+00,   0.000000e+00,   0.000000e+00],
                        [   0.000000e+00,   1.000000e+00,   0.000000e+00],
                        [   0.000000e+00,   0.000000e+00,   1.000000e+00]]

        basis_points = [[   0.000000e+00,   0.000000e+00,   0.000000e+00]]

        unit_cell = KMCUnitCell(
            cell_vectors=cell_vectors,
            basis_points=basis_points)

        # Lattice.
        lattice = KMCLattice(
            unit_cell=unit_cell,
            repetitions=(10,10,1),
            periodic=(True, True, False))

        # Configuration.
        types = ['B']*100
        possible_types = ['A','B']
        configuration = KMCConfiguration(
            lattice=lattice,
            types=types,
            possible_types=possible_types)

        # Interactions.
        coordinates = [[   0.000000e+00,   0.000000e+00,   0.000000e+00]]
        process_0 = KMCProcess(coordinates, ['A'], ['B'], None, [0], 4.0)
        process_1 = KMCProcess(coordinates, ['B'], ['A'], None, [0], 1.0)
        processes = [process_0, process_1]
        interactions = KMCInteractions(processes,
                                       implicit_wildcards=True)

        # Custom rates.
        rate_calculator = CustomRateCalculator
        interactions.setRateCalculator(rate_calculator)

        # Setup the model.
        ab_flip_model = KMCLatticeModel(configuration, interactions)

        # Run the model with a trajectory file.
        name = os.path.abspath(os.path.dirname(__file__))
        name = os.path.join(name, "..", "TestUtilities", "Scratch")
        trajectory_filename = os.path.join(name, "ab_flip_traj_custom.py")
        self.__files_to_remove.append(trajectory_filename)

        # The control parameters.
        control_parameters = KMCControlParameters(number_of_steps=1000,
                                                  dump_interval=500,
                                                  seed=2013)

        # Run the model for 1000 steps.
        ab_flip_model.run(control_parameters,
                          trajectory_filename=trajectory_filename)

        # Read the first last frames from the trajectory file and check that
        # the fraction of A is close to 75% in the last, and 0 in the first.
        if MPICommons.isMaster():
            global_dict = {}
            local_dict  = {}
            execfile(trajectory_filename, global_dict, local_dict)

            # Count the first frame.
            elem = local_dict["types"][0]
            nA = len([ ee for ee in elem if ee == "A" ])
            nB = len([ ee for ee in elem if ee == "B" ])
            self.assertEqual(nA, 0)
            self.assertEqual(nB, 100)

            # Count the last frame.
            elem = local_dict["types"][-1]
            nA = len([ ee for ee in elem if ee == "A" ])
            nB = len([ ee for ee in elem if ee == "B" ])

            # Note that the average over a long simulation should be
            # 75% A using the modified rate function. In this particular
            # step the A population is 74%.
            value = 1.0 * nA / (nA + nB)
            self.assertAlmostEqual(0.74, value, 2)
Ejemplo n.º 6
0
    def testBackendWithCustomRates(self):
        """ Test that we can construct the backend object with custom rates. """
        # A first process.
        coords = [[1.0,2.0,3.4],[1.1,1.2,1.3]]
        types0 = ["A","B"]
        types1 = ["B","A"]
        rate_0_1 = 3.5
        process_0 = KMCProcess(coords, types0, types1, basis_sites=[0], rate_constant=rate_0_1)

        # A second process.
        types0 = ["A","C"]
        types1 = ["C","A"]
        rate_0_1 = 1.5
        process_1 = KMCProcess(coords, types0, types1, basis_sites=[0], rate_constant=rate_0_1)

        processes = [process_0, process_1]

        # Set the custom rates class to use.
        custom_rates_class = CustomRateCalculator

        # Construct the interactions object.
        kmc_interactions = KMCInteractions(processes=processes,
                                           implicit_wildcards=False)
        kmc_interactions.setRateCalculator(rate_calculator=custom_rates_class)

        # Set the rate function on the custom rates calculator for testing.
        ref_rnd = numpy.random.uniform(0.0,1.0)
        def testRateFunction(coords, types_before, types_after, rate_const, process_number, global_coordinate):
            return ref_rnd
        kmc_interactions._KMCInteractions__rate_calculator.rate = testRateFunction

        # Setup a dict with the possible types.
        possible_types = {
            "A" : 13,
            "D" : 2,
            "B" : 3,
            "J" : 4,
            "C" : 5,
            }

        # Construct the backend.
        cpp_interactions = kmc_interactions._backend(possible_types, 2)

        # Get the rate calculator reference out of the C++ object and
        # check that a call from C++ calls the Python extension.
        cpp_coords = Backend.StdVectorDouble()
        cpp_types1 = Backend.StdVectorString()
        cpp_types2 = Backend.StdVectorString()
        rate_constant = 543.2211
        process_number = 33
        coordinate = (1.2,3.4,5.6)

        self.assertAlmostEqual( cpp_interactions.rateCalculator().backendRateCallback(cpp_coords,
                                                                                      cpp_coords.size()/3,
                                                                                      cpp_types1,
                                                                                      cpp_types2,
                                                                                      rate_constant,
                                                                                      process_number,
                                                                                      coordinate[0],
                                                                                      coordinate[1],
                                                                                      coordinate[2]), ref_rnd, 12 )
        self.assertAlmostEqual( kmc_interactions._KMCInteractions__rate_calculator.backendRateCallback(cpp_coords,
                                                                                                       cpp_coords.size()/3,
                                                                                                       cpp_types1,
                                                                                                       cpp_types2,
                                                                                                       rate_constant,
                                                                                                       process_number,
                                                                                                       coordinate[0],
                                                                                                       coordinate[1],
                                                                                                       coordinate[2]), ref_rnd, 12 )

        # Construct a C++ RateCalculator object directly and check that this object
        # returns the rate given to it.
        cpp_rate_calculator = Backend.RateCalculator()
        self.assertAlmostEqual( cpp_rate_calculator.backendRateCallback(cpp_coords,
                                                                        cpp_coords.size()/3,
                                                                        cpp_types1,
                                                                        cpp_types2,
                                                                        rate_constant,
                                                                        process_number,
                                                                        coordinate[0],
                                                                        coordinate[1],
                                                                        coordinate[2]), rate_constant, 12 )
Ejemplo n.º 7
0
    def testBackendWithCustomRates(self):
        """ Test that we can construct the backend object with custom rates. """
        # A first process.
        coords = [[1.0, 2.0, 3.4], [1.1, 1.2, 1.3]]
        types0 = ["A", "B"]
        types1 = ["B", "A"]
        rate_0_1 = 3.5
        process_0 = KMCProcess(coords,
                               types0,
                               types1,
                               basis_sites=[0],
                               rate_constant=rate_0_1)

        # A second process.
        types0 = ["A", "C"]
        types1 = ["C", "A"]
        rate_0_1 = 1.5
        process_1 = KMCProcess(coords,
                               types0,
                               types1,
                               basis_sites=[0],
                               rate_constant=rate_0_1)

        processes = [process_0, process_1]

        # Set the custom rates class to use.
        custom_rates_class = CustomRateCalculator

        # Construct the interactions object.
        kmc_interactions = KMCInteractions(processes=processes,
                                           implicit_wildcards=False)
        kmc_interactions.setRateCalculator(rate_calculator=custom_rates_class)

        # Set the rate function on the custom rates calculator for testing.
        ref_rnd = numpy.random.uniform(0.0, 1.0)

        def testRateFunction(coords, types_before, types_after, rate_const,
                             process_number, global_coordinate):
            return ref_rnd

        kmc_interactions._KMCInteractions__rate_calculator.rate = testRateFunction

        # Setup a dict with the possible types.
        possible_types = {
            "A": 13,
            "D": 2,
            "B": 3,
            "J": 4,
            "C": 5,
        }

        # Construct the backend.
        cpp_interactions = kmc_interactions._backend(possible_types, 2)

        # Get the rate calculator reference out of the C++ object and
        # check that a call from C++ calls the Python extension.
        cpp_coords = Backend.StdVectorDouble()
        cpp_types1 = Backend.StdVectorString()
        cpp_types2 = Backend.StdVectorString()
        rate_constant = 543.2211
        process_number = 33
        coordinate = (1.2, 3.4, 5.6)

        self.assertAlmostEqual(
            cpp_interactions.rateCalculator().backendRateCallback(
                cpp_coords,
                cpp_coords.size() / 3, cpp_types1, cpp_types2, rate_constant,
                process_number, coordinate[0], coordinate[1], coordinate[2]),
            ref_rnd, 12)
        self.assertAlmostEqual(
            kmc_interactions._KMCInteractions__rate_calculator.
            backendRateCallback(cpp_coords,
                                cpp_coords.size() / 3, cpp_types1, cpp_types2,
                                rate_constant, process_number, coordinate[0],
                                coordinate[1], coordinate[2]), ref_rnd, 12)

        # Construct a C++ RateCalculator object directly and check that this object
        # returns the rate given to it.
        cpp_rate_calculator = Backend.RateCalculator()
        self.assertAlmostEqual(
            cpp_rate_calculator.backendRateCallback(
                cpp_coords,
                cpp_coords.size() / 3, cpp_types1, cpp_types2, rate_constant,
                process_number, coordinate[0], coordinate[1], coordinate[2]),
            rate_constant, 12)