Пример #1
0
    def testBackendNoFailWrongBasisMatch(self):
        """ Test for no failure when constructing backend with wrong n_basis """
        # 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, 4],
                               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, 1],
                               rate_constant=rate_0_1)

        processes = [process_0, process_1]

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

        # 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"

        # Get the backend - The [0,4] sites list for process_0 is simply ignored.
        cpp_interactions = kmc_interactions._backend(possible_types, 2, config)

        self.assertEqual(len(cpp_interactions.processes()[0].basisSites()), 1)
        self.assertEqual(cpp_interactions.processes()[0].basisSites()[0], 0)

        self.assertEqual(len(cpp_interactions.processes()[1].basisSites()), 2)
        self.assertEqual(cpp_interactions.processes()[1].basisSites()[0], 0)
        self.assertEqual(cpp_interactions.processes()[1].basisSites()[1], 1)
Пример #2
0
    def testBackendNoFailWrongBasisMatch(self):
        """ Test for no failure when constructing backend with wrong n_basis """
        # 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,4], 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,1], rate_constant=rate_0_1)

        processes = [process_0, process_1]

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

        # 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"

        # Get the backend - The [0,4] sites list for process_0 is simply ignored.
        cpp_interactions = kmc_interactions._backend(possible_types, 2, config)

        self.assertEqual( len(cpp_interactions.processes()[0].basisSites()), 1 )
        self.assertEqual( cpp_interactions.processes()[0].basisSites()[0], 0 )

        self.assertEqual( len(cpp_interactions.processes()[1].basisSites()), 2 )
        self.assertEqual( cpp_interactions.processes()[1].basisSites()[0], 0 )
        self.assertEqual( cpp_interactions.processes()[1].basisSites()[1], 1 )
Пример #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 )
Пример #4
0
    def testBackendBuckets(self):
        """
        Test that the backend behaves as expected with bucket processes.
        """
        # A first process.
        coords = [[1.0,2.0,3.4],[12.0,13.0,-1.0],[1.1,1.2,1.3]]
        minimum_match = ["A","*","B"]
        update = [[(-1,"A"), (1, "B")],[(0,"*")],[(1,"A"), (-1, "B")]]
        rate_0_1 = 3.5
        process_0 = KMCBucketProcess(coordinates=coords,
                                     minimum_match=minimum_match,
                                     update=update,
                                     basis_sites=[0,1,3],
                                     rate_constant=rate_0_1)

        # A second process.
        coords = [[1.0,2.0,3.4],[12.0,13.0,-1.0],[1.1,1.2,1.3]]
        minimum_match = ["A","*","C"]
        update = [[(-1,"A"), (1, "C")],[(0,"*")],[(1,"A"), (-1, "C")]]
        rate_0_1 = 1.5
        process_1 = KMCBucketProcess(coordinates=coords,
                                     minimum_match=minimum_match,
                                     update=update,
                                     basis_sites=[0,1,3],
                                     rate_constant=rate_0_1)

        processes = [process_0, process_1]

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

        # Setup a dict with the possible types.
        possible_types = {
            "A" : 0,
            "B" : 1,
            "J" : 2,
            "C" : 3,
            }

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

        # Check that setting up the backend fails if we have types in the processes that do
        # not corresponds to a type in the list of possible types.
        self.assertRaises( Error, lambda : kmc_interactions._backend(possible_types, 2, config) )

        possible_types = {
            "A" : 0,
            "B" : 1,
            "D" : 2,
            "J" : 3,
            "C" : 4,
            }

        self.assertRaises( Error, lambda : kmc_interactions._backend(possible_types, 2, config) )

        possible_types = {
            "A" : 0,
            "B" : 1,
            "F" : 2,
            "J" : 3,
            "C" : 4,
            }

        self.assertRaises( Error, lambda : kmc_interactions._backend(possible_types, 2, config) )

        # Both "D" and "F" must be present, and the widcard "*".
        possible_types["D"] = 5
        possible_types["*"] = 6

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

        # Check the type.
        self.assertTrue( isinstance(cpp_interactions, Backend.Interactions) )

        # Get the processes out.
        cpp_processes = cpp_interactions.processes()

        # Check the length of the processes.
        self.assertEqual(cpp_processes.size(), 2)

        # Get the elements out of the second process.
        update_types = cpp_processes[1].processMatchList()[0].update_types

        # This is an "A"
        match_types  = cpp_processes[1].processMatchList()[0].match_types
        self.assertEqual(match_types[0], 1)
        self.assertEqual(match_types[1], 0)
        self.assertEqual(match_types[2], 0)
        self.assertEqual(match_types[3], 0)
        self.assertEqual(match_types[4], 0)
        self.assertEqual(match_types[5], 0)
        self.assertEqual(match_types[6], 0)

        # This is an "C"
        match_types  = cpp_processes[1].processMatchList()[1].match_types
        self.assertEqual(match_types[0], 0)
        self.assertEqual(match_types[1], 0)
        self.assertEqual(match_types[2], 0)
        self.assertEqual(match_types[3], 0)
        self.assertEqual(match_types[4], 1)
        self.assertEqual(match_types[5], 0)
        self.assertEqual(match_types[6], 0)

        # This is a "*"
        match_types  = cpp_processes[1].processMatchList()[2].match_types
        self.assertEqual(match_types[0], 0)
        self.assertEqual(match_types[1], 0)
        self.assertEqual(match_types[2], 0)
        self.assertEqual(match_types[3], 0)
        self.assertEqual(match_types[4], 0)
        self.assertEqual(match_types[5], 0)
        self.assertEqual(match_types[6], 1)
Пример #5
0
    def testBackend(self):
        """
        Test that the generated backend object is what we expect.
        """
        # A first process.
        coords = [[1.0,2.0,3.4],[12.0,13.0,-1.0],[1.1,1.2,1.3]]
        types0 = ["A","D","B"]
        types1 = ["B","F","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]

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

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


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

        # Check that setting up the backend fails if we have types in the processes that do
        # not corresponds to a type in the list of possible types.
        self.assertRaises( Error, lambda : kmc_interactions._backend(possible_types, 2, config) )

        possible_types = {
            "A" : 13,
            "B" : 3,
            "D" : 2,
            "J" : 4,
            "C" : 5,
            }

        self.assertRaises( Error, lambda : kmc_interactions._backend(possible_types, 2, config) )

        possible_types = {
            "A" : 13,
            "B" : 3,
            "F" : 2,
            "J" : 4,
            "C" : 5,
            }

        self.assertRaises( Error, lambda : kmc_interactions._backend(possible_types, 2, config) )

        # Both "D" and "F" must be present.
        possible_types["D"] = 123

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

        # Check the type.
        self.assertTrue( isinstance(cpp_interactions, Backend.Interactions) )

        # Get the processes out.
        cpp_processes = cpp_interactions.processes()

        # Check the length of the processes.
        self.assertEqual(cpp_processes.size(), 2)

        # Get the elements out of the second process.
        match_types  = cpp_processes[1].processMatchList()[0].match_types
        update_types = cpp_processes[1].processMatchList()[0].update_types

        # Match type should be "A" -> 15 and update type "C" -> 5
        self.assertEqual( match_types[13], 1)
        self.assertEqual( update_types[5], 1)

        # Get the elements out of the second process.
        match_types  = cpp_processes[1].processMatchList()[1].match_types
        update_types = cpp_processes[1].processMatchList()[1].update_types

        # Match type should be "C" -> 5 and update type "A" -> 13
        self.assertEqual( match_types[5],   1)
        self.assertEqual( update_types[13], 1)
Пример #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

        # 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)
Пример #7
0
    def testBackendBuckets(self):
        """
        Test that the backend behaves as expected with bucket processes.
        """
        # A first process.
        coords = [[1.0, 2.0, 3.4], [12.0, 13.0, -1.0], [1.1, 1.2, 1.3]]
        minimum_match = ["A", "*", "B"]
        update = [[(-1, "A"), (1, "B")], [(0, "*")], [(1, "A"), (-1, "B")]]
        rate_0_1 = 3.5
        process_0 = KMCBucketProcess(coordinates=coords,
                                     minimum_match=minimum_match,
                                     update=update,
                                     basis_sites=[0, 1, 3],
                                     rate_constant=rate_0_1)

        # A second process.
        coords = [[1.0, 2.0, 3.4], [12.0, 13.0, -1.0], [1.1, 1.2, 1.3]]
        minimum_match = ["A", "*", "C"]
        update = [[(-1, "A"), (1, "C")], [(0, "*")], [(1, "A"), (-1, "C")]]
        rate_0_1 = 1.5
        process_1 = KMCBucketProcess(coordinates=coords,
                                     minimum_match=minimum_match,
                                     update=update,
                                     basis_sites=[0, 1, 3],
                                     rate_constant=rate_0_1)

        processes = [process_0, process_1]

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

        # Setup a dict with the possible types.
        possible_types = {
            "A": 0,
            "B": 1,
            "J": 2,
            "C": 3,
        }

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

        # Check that setting up the backend fails if we have types in the processes that do
        # not corresponds to a type in the list of possible types.
        self.assertRaises(
            Error,
            lambda: kmc_interactions._backend(possible_types, 2, config))

        possible_types = {
            "A": 0,
            "B": 1,
            "D": 2,
            "J": 3,
            "C": 4,
        }

        self.assertRaises(
            Error,
            lambda: kmc_interactions._backend(possible_types, 2, config))

        possible_types = {
            "A": 0,
            "B": 1,
            "F": 2,
            "J": 3,
            "C": 4,
        }

        self.assertRaises(
            Error,
            lambda: kmc_interactions._backend(possible_types, 2, config))

        # Both "D" and "F" must be present, and the widcard "*".
        possible_types["D"] = 5
        possible_types["*"] = 6

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

        # Check the type.
        self.assertTrue(isinstance(cpp_interactions, Backend.Interactions))

        # Get the processes out.
        cpp_processes = cpp_interactions.processes()

        # Check the length of the processes.
        self.assertEqual(cpp_processes.size(), 2)

        # Get the elements out of the second process.
        update_types = cpp_processes[1].processMatchList()[0].update_types

        # This is an "A"
        match_types = cpp_processes[1].processMatchList()[0].match_types
        self.assertEqual(match_types[0], 1)
        self.assertEqual(match_types[1], 0)
        self.assertEqual(match_types[2], 0)
        self.assertEqual(match_types[3], 0)
        self.assertEqual(match_types[4], 0)
        self.assertEqual(match_types[5], 0)
        self.assertEqual(match_types[6], 0)

        # This is an "C"
        match_types = cpp_processes[1].processMatchList()[1].match_types
        self.assertEqual(match_types[0], 0)
        self.assertEqual(match_types[1], 0)
        self.assertEqual(match_types[2], 0)
        self.assertEqual(match_types[3], 0)
        self.assertEqual(match_types[4], 1)
        self.assertEqual(match_types[5], 0)
        self.assertEqual(match_types[6], 0)

        # This is a "*"
        match_types = cpp_processes[1].processMatchList()[2].match_types
        self.assertEqual(match_types[0], 0)
        self.assertEqual(match_types[1], 0)
        self.assertEqual(match_types[2], 0)
        self.assertEqual(match_types[3], 0)
        self.assertEqual(match_types[4], 0)
        self.assertEqual(match_types[5], 0)
        self.assertEqual(match_types[6], 1)
Пример #8
0
    def testBackend(self):
        """
        Test that the generated backend object is what we expect.
        """
        # A first process.
        coords = [[1.0, 2.0, 3.4], [12.0, 13.0, -1.0], [1.1, 1.2, 1.3]]
        types0 = ["A", "D", "B"]
        types1 = ["B", "F", "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]

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

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

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

        # Check that setting up the backend fails if we have types in the processes that do
        # not corresponds to a type in the list of possible types.
        self.assertRaises(
            Error,
            lambda: kmc_interactions._backend(possible_types, 2, config))

        possible_types = {
            "A": 13,
            "B": 3,
            "D": 2,
            "J": 4,
            "C": 5,
        }

        self.assertRaises(
            Error,
            lambda: kmc_interactions._backend(possible_types, 2, config))

        possible_types = {
            "A": 13,
            "B": 3,
            "F": 2,
            "J": 4,
            "C": 5,
        }

        self.assertRaises(
            Error,
            lambda: kmc_interactions._backend(possible_types, 2, config))

        # Both "D" and "F" must be present.
        possible_types["D"] = 123

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

        # Check the type.
        self.assertTrue(isinstance(cpp_interactions, Backend.Interactions))

        # Get the processes out.
        cpp_processes = cpp_interactions.processes()

        # Check the length of the processes.
        self.assertEqual(cpp_processes.size(), 2)

        # Get the elements out of the second process.
        match_types = cpp_processes[1].processMatchList()[0].match_types
        update_types = cpp_processes[1].processMatchList()[0].update_types

        # Match type should be "A" -> 15 and update type "C" -> 5
        self.assertEqual(match_types[13], 1)
        self.assertEqual(update_types[5], 1)

        # Get the elements out of the second process.
        match_types = cpp_processes[1].processMatchList()[1].match_types
        update_types = cpp_processes[1].processMatchList()[1].update_types

        # Match type should be "C" -> 5 and update type "A" -> 13
        self.assertEqual(match_types[5], 1)
        self.assertEqual(update_types[13], 1)
Пример #9
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 )
Пример #10
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)