def _map(self):
     """
     Query for the lattice map.
     """
     # Generate the lattice map if not done allready.
     if self.__lattice_map is None:
         self.__lattice_map = Backend.LatticeMap(
             len(self.__unit_cell.basis()),
             Backend.StdVectorInt(self.__repetitions),
             Backend.StdVectorBool(self.__periodic))
     # Return the lattice map.
     return self.__lattice_map
    def _backend(self, possible_types, n_basis):
        """
        Query for the interactions backend object.

        :param possible_types: A dict with the global mapping of type strings
                               to integers.

        :param n_basis: The size of the configuration basis is.
        :type n_basis: int

        :returns: The interactions object in C++
        """
        if self.__backend is None:

            # Check the possible_types against the types in the processes.
            for process_number, process in enumerate(self.__processes):
                all_elements = list(
                    set(process.elementsBefore() + process.elementsAfter()))
                if (not all([(e in possible_types) for e in all_elements])):
                    raise Error(
                        "Process %i contains elements not present in the list of possible types of the configuration."
                        % (process_number))

            # Setup the correct type of backend process objects
            # depending on the presence of a rate calculator.

            if self.__rate_calculator is not None:
                cpp_processes = Backend.StdVectorCustomRateProcess()
            else:
                cpp_processes = Backend.StdVectorProcess()

            # For each interaction.
            for process_number, process in enumerate(self.__processes):

                # Get the corresponding C++ objects.
                cpp_config1 = process.localConfigurations()[0]._backend(
                    possible_types)
                cpp_config2 = process.localConfigurations()[1]._backend(
                    possible_types)
                rate_constant = process.rateConstant()

                basis_list = range(n_basis)
                if process.basisSites() is not None:
                    # Make sure this basis list does not contain positions
                    # that are not in the configuration.
                    basis_list = []
                    for b in process.basisSites():
                        if b < n_basis:
                            basis_list.append(b)

                # And construct the C++ entry.
                cpp_basis = Backend.StdVectorInt(basis_list)

                # Setup the move vectors representation in C++.
                move_origins = [int(v[0]) for v in process.moveVectors()]
                cpp_move_origins = Backend.StdVectorInt(move_origins)
                cpp_move_vectors = Backend.StdVectorCoordinate()
                for v in process.moveVectors():
                    cpp_move_vectors.push_back(
                        Backend.Coordinate(v[1][0], v[1][1], v[1][2]))

                # Construct and store the C++ process.
                if self.__rate_calculator is not None:
                    # Set the cutoff correctly.
                    cutoff = self.__rate_calculator.cutoff()
                    if cutoff is None:
                        cutoff = 1.0

                    cpp_processes.push_back(
                        Backend.CustomRateProcess(cpp_config1, cpp_config2,
                                                  rate_constant, cpp_basis,
                                                  cutoff, cpp_move_origins,
                                                  cpp_move_vectors,
                                                  process_number))
                else:
                    cpp_processes.push_back(
                        Backend.Process(cpp_config1, cpp_config2,
                                        rate_constant, cpp_basis,
                                        cpp_move_origins, cpp_move_vectors,
                                        process_number))

            # Construct the C++ interactions object.
            if self.__rate_calculator is not None:
                self.__backend = Backend.Interactions(
                    cpp_processes, self.__implicit_wildcards,
                    self.__rate_calculator)
            else:
                self.__backend = Backend.Interactions(
                    cpp_processes, self.__implicit_wildcards)

        # Return the stored backend.
        return self.__backend
Exemplo n.º 3
0
    def _backend(self, possible_types, n_basis, configuration):
        """
        Query for the interactions backend object.

        :param possible_types: A dict with the global mapping of type strings
                               to integers.

        :param n_basis: The size of the configuration basis is.
        :type n_basis: int

        :param configuration: The configuration of the systm, to be passed
                              on to any attached custom rate calculator.

        :returns: The interactions object in C++
        """
        if self.__backend is None:

            # Check the possible_types against the types in the processes.
            for process_number, process in enumerate(self.__processes):
                all_elements = process.allPresentTypes()
                if (not all([(e in possible_types) for e in all_elements])):
                    raise Error(
                        "Process %i contains elements not present in the list of possible types of the configuration."
                        % (process_number))

            # Setup the correct type of backend process objects
            # depending on the presence of a rate calculator.

            if self.__rate_calculator_class is not None:

                # Instantiate the rate calculator.
                if self.__builtin_custom == False:
                    rate_calculator = self.__rate_calculator_class(
                        configuration)
                else:
                    rate_calculator = self.__rate_calculator_class(
                        configuration._backend())

                if self.__builtin_custom == False:
                    if not isinstance(rate_calculator,
                                      KMCRateCalculatorPlugin):
                        msg = """
The 'rate_calculator' given to the KMCInteractions class must
inherit from the KMCRateCalculatorPlugin. """
                        raise Error(msg)
                    elif rate_calculator.__class__ == KMCRateCalculatorPlugin(
                            configuration).__class__:
                        msg = """
The 'rate_calculator' given to the KMCInteractions class must
inherit from the KMCRateCalculatorPlugin class. It may not be
the KMCRateCalculatorPlugin class itself. """
                        raise Error(msg)
                # Tests passed. Save the instantiated rate calculator on the class.
                self.__rate_calculator = rate_calculator

                # Generate the process vector.
                cpp_processes = Backend.StdVectorCustomRateProcess()
            else:
                # Generate the process vector.
                cpp_processes = Backend.StdVectorProcess()

            # For each interaction.
            for process_number, process in enumerate(self.__processes):

                # Get the corresponding C++ objects.
                cpp_config1 = process.localConfigurations()[0]._backend(
                    possible_types)

                if len(process.localConfigurations()) == 2:
                    cpp_config2 = process.localConfigurations()[1]._backend(
                        possible_types)
                else:
                    # Take a copy of the first configuration and set the update from the
                    # process.
                    cpp_config2 = cpp_config1
                    cpp_config2.setUpdateInfo(process._update())

                rate_constant = process.rateConstant()

                basis_list = range(n_basis)
                if process.basisSites() is not None:
                    # Make sure this basis list does not contain positions
                    # that are not in the configuration.
                    basis_list = []
                    for b in process.basisSites():
                        if b < n_basis:
                            basis_list.append(b)

                # And construct the C++ entry.
                cpp_basis = Backend.StdVectorInt(basis_list)

                # Setup the move vectors representation in C++.
                move_origins = [int(v[0]) for v in process.moveVectors()]
                cpp_move_origins = Backend.StdVectorInt(move_origins)
                cpp_move_vectors = Backend.StdVectorCoordinate()
                for v in process.moveVectors():
                    cpp_move_vectors.push_back(
                        Backend.Coordinate(v[1][0], v[1][1], v[1][2]))

                # Construct and store the C++ process.
                if self.__rate_calculator is not None:
                    # Set the cutoff correctly.
                    cutoff = self.__rate_calculator.cutoff()
                    if cutoff is None:
                        cutoff = 1.0

                    # Get the cache_rate flag.
                    cache_rate = (self.__rate_calculator.cacheRates() and \
                                      not process_number in self.__rate_calculator.excludeFromCaching())

                    cpp_processes.push_back(
                        Backend.CustomRateProcess(cpp_config1, cpp_config2,
                                                  rate_constant, cpp_basis,
                                                  cutoff, cpp_move_origins,
                                                  cpp_move_vectors,
                                                  process_number, cache_rate))
                else:
                    cpp_processes.push_back(
                        Backend.Process(cpp_config1, cpp_config2,
                                        rate_constant, cpp_basis,
                                        cpp_move_origins, cpp_move_vectors,
                                        process_number))

            # Construct the C++ interactions object.
            if self.__rate_calculator is not None:
                self.__backend = Backend.Interactions(
                    cpp_processes, self.__implicit_wildcards,
                    self.__rate_calculator)
            else:
                self.__backend = Backend.Interactions(
                    cpp_processes, self.__implicit_wildcards)

        # Return the stored backend.
        return self.__backend