Пример #1
0
    def testConstruction(self):
        """ Test that the XYZTrajectory object can be constructed. """
        filename = "abc123.xyz"
        name = os.path.abspath(os.path.dirname(__file__))
        name = os.path.join(name, "..", "..")
        name = os.path.join(name, "TestUtilities", "Scratch")
        filename = os.path.join(name, filename)

        if MPICommons.isMaster():
            self.__files_to_remove.append(filename)

        unit_cell = KMCUnitCell(cell_vectors=[[1.0, 0.0, 0.0],
                                              [0.0, 1.0, 0.0],
                                              [0.0, 0.0, 1.0]],
                                basis_points=[[0.0, 0.0, 0.0]])
        lattice = KMCLattice(unit_cell=unit_cell,
                             periodic=(True, True, True),
                             repetitions=(4,4,4))

        config = KMCConfiguration(lattice=lattice,
                                 types=["A","B","C","D"]*16)

        t = XYZTrajectory(trajectory_filename=filename,
                          configuration=config,
                          max_buffer_size=12345,
                          max_buffer_time=123.0)

        # Check that the internal memory buffers have been initiated.
        self.assertEqual(t._XYZTrajectory__atom_id_types, [])
        self.assertEqual(t._XYZTrajectory__atom_id_coordinates, [])
        self.assertEqual(t._XYZTrajectory__time, [])
        self.assertEqual(t._XYZTrajectory__step, [])
Пример #2
0
    def testWriteHeader(self):
        """ Test the header output. """
        # Get a file name.
        name = os.path.abspath(os.path.dirname(__file__))
        name = os.path.join(name, "..", "..")
        name = os.path.join(name, "TestUtilities", "Scratch")
        trajectory_filename = os.path.join(name, "tmp_trajectory.xyz")

        if MPICommons.isMaster():
            self.__files_to_remove.append(trajectory_filename)

        # Setup the trajectory object.
        unit_cell = KMCUnitCell(cell_vectors=[[1.0, 0.0, 0.0],
                                              [0.0, 1.0, 0.0],
                                              [0.0, 0.0, 1.0]],
                                basis_points=[[0.0, 0.0, 0.0]])
        lattice = KMCLattice(unit_cell=unit_cell,
                             periodic=(True, True, True),
                             repetitions=(4,2,3))

        config = KMCConfiguration(lattice=lattice,
                                 types=["A","B","C"]*8)

        t = XYZTrajectory(trajectory_filename=trajectory_filename,
                          configuration=config,
                          max_buffer_size=12345,
                          max_buffer_time=123.0)

        if MPICommons.isMaster():

            # Check that the header was written.
            self.assertTrue(os.path.exists(trajectory_filename))

            # Check the content of the header.
            with open(trajectory_filename, "r") as f:
                content = f.read()

            ref_content = """KMCLib XYZ FORMAT VERSION 2013.10.15

CELL VECTORS
a: 1.0000000000e+00 0.0000000000e+00 0.0000000000e+00
b: 0.0000000000e+00 1.0000000000e+00 0.0000000000e+00
c: 0.0000000000e+00 0.0000000000e+00 1.0000000000e+00

REPETITIONS 4 2 3

PERIODICITY True True True

"""
            self.assertEqual( content, ref_content )
Пример #3
0
    def testFlush2(self):
        """ Test the file output. """
        # Get a file name.
        name = os.path.abspath(os.path.dirname(__file__))
        name = os.path.join(name, "..", "..")
        name = os.path.join(name, "TestUtilities", "Scratch")
        trajectory_filename = os.path.join(name, "tmp_trajectory.xyz")

        if MPICommons.isMaster():
            self.__files_to_remove.append(trajectory_filename)

        # Setup the trajectory object.
        unit_cell = KMCUnitCell(cell_vectors=[[1.0, 0.0, 0.0],
                                              [0.0, 1.0, 0.0],
                                              [0.0, 0.0, 1.0]],
                                basis_points=[[0.0, 0.0, 0.0]])
        lattice = KMCLattice(unit_cell=unit_cell,
                             periodic=(True, False, True),
                             repetitions=(4,4,4))

        config = KMCConfiguration(lattice=lattice,
                                 types=["A","B","C","D"]*16)

        t = XYZTrajectory(trajectory_filename=trajectory_filename,
                          configuration=config,
                          max_buffer_size=12345,
                          max_buffer_time=123.0)

        # Set data directly on the class.
        t._XYZTrajectory__atom_id_types = [("A","B","C","D","E"),
                                          ("This","is","the","next","step")]

        t._XYZTrajectory__atom_id_coordinates = [numpy.zeros((5,3)),
                                                numpy.ones((5,3))*1.234]

        t._XYZTrajectory__step = [0, 12]

        t._XYZTrajectory__time = [12.123,75.43]

        # Flush.
        t.flush()

        ref_content = """KMCLib XYZ FORMAT VERSION 2013.10.15

CELL VECTORS
a: 1.0000000000e+00 0.0000000000e+00 0.0000000000e+00
b: 0.0000000000e+00 1.0000000000e+00 0.0000000000e+00
c: 0.0000000000e+00 0.0000000000e+00 1.0000000000e+00

REPETITIONS 4 4 4

PERIODICITY True False True

STEP 0
          5
    TIME 1.2123000000e+01
                A   0.0000000000e+00 0.0000000000e+00 0.0000000000e+00  0
                B   0.0000000000e+00 0.0000000000e+00 0.0000000000e+00  1
                C   0.0000000000e+00 0.0000000000e+00 0.0000000000e+00  2
                D   0.0000000000e+00 0.0000000000e+00 0.0000000000e+00  3
                E   0.0000000000e+00 0.0000000000e+00 0.0000000000e+00  4
STEP 12
          5
    TIME 7.5430000000e+01
             This   1.2340000000e+00 1.2340000000e+00 1.2340000000e+00  0
               is   1.2340000000e+00 1.2340000000e+00 1.2340000000e+00  1
              the   1.2340000000e+00 1.2340000000e+00 1.2340000000e+00  2
             next   1.2340000000e+00 1.2340000000e+00 1.2340000000e+00  3
             step   1.2340000000e+00 1.2340000000e+00 1.2340000000e+00  4
"""

        if MPICommons.isMaster():
            with open(trajectory_filename, "r") as f:
                content = f.read()
            self.assertEqual( content, ref_content )

        # Check that the buffers are empty.
        self.assertEqual(t._XYZTrajectory__atom_id_types, [])
        self.assertEqual(t._XYZTrajectory__atom_id_coordinates, [])
        self.assertEqual(t._XYZTrajectory__time, [])
        self.assertEqual(t._XYZTrajectory__step, [])
Пример #4
0
    def testFlush(self):
        """ Test the file output. """
        # Get a file name.
        name = os.path.abspath(os.path.dirname(__file__))
        name = os.path.join(name, "..", "..")
        name = os.path.join(name, "TestUtilities", "Scratch")
        trajectory_filename = os.path.join(name, "tmp_trajectory.xyz")

        if MPICommons.isMaster():
            self.__files_to_remove.append(trajectory_filename)

        # Setup the trajectory object.
        unit_cell = KMCUnitCell(cell_vectors=[[1.0, 0.0, 0.0],
                                              [0.0, 1.0, 0.0],
                                              [0.0, 0.0, 1.0]],
                                basis_points=[[0.0, 0.0, 0.0]])
        lattice = KMCLattice(unit_cell=unit_cell,
                             periodic=(True, False, True),
                             repetitions=(4,4,4))

        config = KMCConfiguration(lattice=lattice,
                                 types=["A","B","C","D"]*16)

        t = XYZTrajectory(trajectory_filename=trajectory_filename,
                          configuration=config,
                          max_buffer_size=12345,
                          max_buffer_time=123.0)

        # Store data.
        simulation_time = 1.234
        step = 123
        t._storeData(simulation_time, step, config)

        # Flush.
        t.flush()

        # Check the file.

        ref_content = """KMCLib XYZ FORMAT VERSION 2013.10.15

CELL VECTORS
a: 1.0000000000e+00 0.0000000000e+00 0.0000000000e+00
b: 0.0000000000e+00 1.0000000000e+00 0.0000000000e+00
c: 0.0000000000e+00 0.0000000000e+00 1.0000000000e+00

REPETITIONS 4 4 4

PERIODICITY True False True

STEP 123
          64
    TIME 1.2340000000e+00
                A   0.0000000000e+00 0.0000000000e+00 0.0000000000e+00  0
                B   0.0000000000e+00 0.0000000000e+00 1.0000000000e+00  1
                C   0.0000000000e+00 0.0000000000e+00 2.0000000000e+00  2
                D   0.0000000000e+00 0.0000000000e+00 3.0000000000e+00  3
                A   0.0000000000e+00 1.0000000000e+00 0.0000000000e+00  4
                B   0.0000000000e+00 1.0000000000e+00 1.0000000000e+00  5
                C   0.0000000000e+00 1.0000000000e+00 2.0000000000e+00  6
                D   0.0000000000e+00 1.0000000000e+00 3.0000000000e+00  7
                A   0.0000000000e+00 2.0000000000e+00 0.0000000000e+00  8
                B   0.0000000000e+00 2.0000000000e+00 1.0000000000e+00  9
                C   0.0000000000e+00 2.0000000000e+00 2.0000000000e+00  10
                D   0.0000000000e+00 2.0000000000e+00 3.0000000000e+00  11
                A   0.0000000000e+00 3.0000000000e+00 0.0000000000e+00  12
                B   0.0000000000e+00 3.0000000000e+00 1.0000000000e+00  13
                C   0.0000000000e+00 3.0000000000e+00 2.0000000000e+00  14
                D   0.0000000000e+00 3.0000000000e+00 3.0000000000e+00  15
                A   1.0000000000e+00 0.0000000000e+00 0.0000000000e+00  16
                B   1.0000000000e+00 0.0000000000e+00 1.0000000000e+00  17
                C   1.0000000000e+00 0.0000000000e+00 2.0000000000e+00  18
                D   1.0000000000e+00 0.0000000000e+00 3.0000000000e+00  19
                A   1.0000000000e+00 1.0000000000e+00 0.0000000000e+00  20
                B   1.0000000000e+00 1.0000000000e+00 1.0000000000e+00  21
                C   1.0000000000e+00 1.0000000000e+00 2.0000000000e+00  22
                D   1.0000000000e+00 1.0000000000e+00 3.0000000000e+00  23
                A   1.0000000000e+00 2.0000000000e+00 0.0000000000e+00  24
                B   1.0000000000e+00 2.0000000000e+00 1.0000000000e+00  25
                C   1.0000000000e+00 2.0000000000e+00 2.0000000000e+00  26
                D   1.0000000000e+00 2.0000000000e+00 3.0000000000e+00  27
                A   1.0000000000e+00 3.0000000000e+00 0.0000000000e+00  28
                B   1.0000000000e+00 3.0000000000e+00 1.0000000000e+00  29
                C   1.0000000000e+00 3.0000000000e+00 2.0000000000e+00  30
                D   1.0000000000e+00 3.0000000000e+00 3.0000000000e+00  31
                A   2.0000000000e+00 0.0000000000e+00 0.0000000000e+00  32
                B   2.0000000000e+00 0.0000000000e+00 1.0000000000e+00  33
                C   2.0000000000e+00 0.0000000000e+00 2.0000000000e+00  34
                D   2.0000000000e+00 0.0000000000e+00 3.0000000000e+00  35
                A   2.0000000000e+00 1.0000000000e+00 0.0000000000e+00  36
                B   2.0000000000e+00 1.0000000000e+00 1.0000000000e+00  37
                C   2.0000000000e+00 1.0000000000e+00 2.0000000000e+00  38
                D   2.0000000000e+00 1.0000000000e+00 3.0000000000e+00  39
                A   2.0000000000e+00 2.0000000000e+00 0.0000000000e+00  40
                B   2.0000000000e+00 2.0000000000e+00 1.0000000000e+00  41
                C   2.0000000000e+00 2.0000000000e+00 2.0000000000e+00  42
                D   2.0000000000e+00 2.0000000000e+00 3.0000000000e+00  43
                A   2.0000000000e+00 3.0000000000e+00 0.0000000000e+00  44
                B   2.0000000000e+00 3.0000000000e+00 1.0000000000e+00  45
                C   2.0000000000e+00 3.0000000000e+00 2.0000000000e+00  46
                D   2.0000000000e+00 3.0000000000e+00 3.0000000000e+00  47
                A   3.0000000000e+00 0.0000000000e+00 0.0000000000e+00  48
                B   3.0000000000e+00 0.0000000000e+00 1.0000000000e+00  49
                C   3.0000000000e+00 0.0000000000e+00 2.0000000000e+00  50
                D   3.0000000000e+00 0.0000000000e+00 3.0000000000e+00  51
                A   3.0000000000e+00 1.0000000000e+00 0.0000000000e+00  52
                B   3.0000000000e+00 1.0000000000e+00 1.0000000000e+00  53
                C   3.0000000000e+00 1.0000000000e+00 2.0000000000e+00  54
                D   3.0000000000e+00 1.0000000000e+00 3.0000000000e+00  55
                A   3.0000000000e+00 2.0000000000e+00 0.0000000000e+00  56
                B   3.0000000000e+00 2.0000000000e+00 1.0000000000e+00  57
                C   3.0000000000e+00 2.0000000000e+00 2.0000000000e+00  58
                D   3.0000000000e+00 2.0000000000e+00 3.0000000000e+00  59
                A   3.0000000000e+00 3.0000000000e+00 0.0000000000e+00  60
                B   3.0000000000e+00 3.0000000000e+00 1.0000000000e+00  61
                C   3.0000000000e+00 3.0000000000e+00 2.0000000000e+00  62
                D   3.0000000000e+00 3.0000000000e+00 3.0000000000e+00  63
"""

        if MPICommons.isMaster():
            with open(trajectory_filename, "r") as f:
                content = f.read()
            self.assertEqual( content, ref_content )

        # Check that the buffers are empty.
        self.assertEqual(t._XYZTrajectory__atom_id_types, [])
        self.assertEqual(t._XYZTrajectory__atom_id_coordinates, [])
        self.assertEqual(t._XYZTrajectory__time, [])
        self.assertEqual(t._XYZTrajectory__step, [])
Пример #5
0
    def testBufferSize(self):
        """ Test the buffer size function. """
        # Get a file name.
        name = os.path.abspath(os.path.dirname(__file__))
        name = os.path.join(name, "..", "..")
        name = os.path.join(name, "TestUtilities", "Scratch")
        trajectory_filename = os.path.join(name, "tmp_trajectory.xyz")

        if MPICommons.isMaster():
            self.__files_to_remove.append(trajectory_filename)

        # Setup the trajectory object.
        unit_cell = KMCUnitCell(cell_vectors=[[1.0, 0.0, 0.0],
                                              [0.0, 1.0, 0.0],
                                              [0.0, 0.0, 1.0]],
                                basis_points=[[0.0, 0.0, 0.0]])
        lattice = KMCLattice(unit_cell=unit_cell,
                             periodic=(True, True, True),
                             repetitions=(4,4,4))

        config = KMCConfiguration(lattice=lattice,
                                 types=["A","B","C","D"]*16)

        t = XYZTrajectory(trajectory_filename=trajectory_filename,
                          configuration=config,
                          max_buffer_size=12345,
                          max_buffer_time=123.0)

        # Store a bunch of data.
        simulation_time = 1.234
        step = 123
        t._storeData(simulation_time, step, config)
        buffer_size = t._bufferSize()

        # Check the size again.
        ref_size =  sys.getsizeof(t._XYZTrajectory__atom_id_coordinates)
        ref_size += sys.getsizeof(t._XYZTrajectory__atom_id_coordinates[0])*len(t._XYZTrajectory__atom_id_coordinates)
        ref_size += sys.getsizeof(t._XYZTrajectory__atom_id_types)
        ref_size += sys.getsizeof(t._XYZTrajectory__atom_id_types[0])*len(t._XYZTrajectory__atom_id_types)
        ref_size += sys.getsizeof(t._XYZTrajectory__time)
        ref_size += sys.getsizeof(t._XYZTrajectory__time[0])*len(t._XYZTrajectory__time)
        ref_size += sys.getsizeof(t._XYZTrajectory__step)
        ref_size += sys.getsizeof(t._XYZTrajectory__step[0])*len(t._XYZTrajectory__step)

        self.assertEqual(buffer_size, ref_size)

        # Store more data.
        t._storeData(simulation_time, step, config)

        # Check the size again.
        t._storeData(simulation_time, step, config)
        t._storeData(simulation_time, step, config)
        t._storeData(simulation_time, step, config)
        t._storeData(simulation_time, step, config)
        t._storeData(simulation_time, step, config)

        ref_size =  sys.getsizeof(t._XYZTrajectory__atom_id_coordinates)
        ref_size += sys.getsizeof(t._XYZTrajectory__atom_id_coordinates[0])*len(t._XYZTrajectory__atom_id_coordinates)
        ref_size += sys.getsizeof(t._XYZTrajectory__atom_id_types)
        ref_size += sys.getsizeof(t._XYZTrajectory__atom_id_types[0])*len(t._XYZTrajectory__atom_id_types)
        ref_size += sys.getsizeof(t._XYZTrajectory__time)
        ref_size += sys.getsizeof(t._XYZTrajectory__time[0])*len(t._XYZTrajectory__time)
        ref_size += sys.getsizeof(t._XYZTrajectory__step)
        ref_size += sys.getsizeof(t._XYZTrajectory__step[0])*len(t._XYZTrajectory__step)

        buffer_size = t._bufferSize()

        self.assertEqual(buffer_size, ref_size)
Пример #6
0
    def testStoreData(self):
        """ Test the data storage function. """
        # Get a file name.
        name = os.path.abspath(os.path.dirname(__file__))
        name = os.path.join(name, "..", "..")
        name = os.path.join(name, "TestUtilities", "Scratch")
        trajectory_filename = os.path.join(name, "tmp_trajectory.xyz")

        if MPICommons.isMaster():
            self.__files_to_remove.append(trajectory_filename)

        # Setup the trajectory object.
        unit_cell = KMCUnitCell(cell_vectors=[[1.0, 0.0, 0.0],
                                              [0.0, 1.0, 0.0],
                                              [0.0, 0.0, 1.0]],
                                basis_points=[[0.0, 0.0, 0.0]])
        lattice = KMCLattice(unit_cell=unit_cell,
                             periodic=(True, True, True),
                             repetitions=(4,4,4))

        config = KMCConfiguration(lattice=lattice,
                                 types=["A","B","C","D"]*16)

        t = XYZTrajectory(trajectory_filename=trajectory_filename,
                          configuration=config,
                          max_buffer_size=12345,
                          max_buffer_time=123.0)

        # Construct data to store.
        simulation_time = 1.234
        step = 123
        configuration = config

        # Store.
        t._storeData(simulation_time, step, configuration)

        # Check that the member data was updated.
        self.assertEqual(len(t._XYZTrajectory__atom_id_types), 1)
        self.assertEqual(len(t._XYZTrajectory__atom_id_coordinates), 1)
        self.assertEqual(len(t._XYZTrajectory__time), 1)
        self.assertEqual(len(t._XYZTrajectory__step), 1)

        # store again.
        simulation_time = 1.999
        step = 4444
        t._storeData(simulation_time, step, configuration)

        # Check that the member data was updated.
        self.assertEqual(len(t._XYZTrajectory__atom_id_types), 2)
        self.assertEqual(len(t._XYZTrajectory__atom_id_coordinates), 2)
        self.assertEqual(len(t._XYZTrajectory__time), 2)
        self.assertEqual(len(t._XYZTrajectory__step), 2)

        # Check the values of the stored data.
        self.assertAlmostEqual(t._XYZTrajectory__time[0], 1.234, 10)
        self.assertAlmostEqual(t._XYZTrajectory__time[1], 1.999, 10)

        self.assertEqual(t._XYZTrajectory__step[0],  123)
        self.assertEqual(t._XYZTrajectory__step[1], 4444)

        diff = numpy.linalg.norm(config.atomIDCoordinates() - t._XYZTrajectory__atom_id_coordinates[0])
        self.assertAlmostEqual(diff, 0.0, 10)

        diff = numpy.linalg.norm(config.atomIDCoordinates() - t._XYZTrajectory__atom_id_coordinates[1])
        self.assertAlmostEqual(diff, 0.0, 10)

        self.assertEqual(t._XYZTrajectory__atom_id_types[0], config.atomIDTypes())
        self.assertEqual(t._XYZTrajectory__atom_id_types[1], config.atomIDTypes())
Пример #7
0
    def run(self,
            control_parameters=None,
            trajectory_filename=None,
            trajectory_type=None,
            analysis=None,
            breakers=None):
        """
        Run the KMC lattice model simulation with specified parameters.

        :param control_paramters:   An instance of KMCControlParameters specifying
                                    number of steps to run etc.

        :param trajectory_filename: The filename of the trajectory. If not given
                                    no trajectory will be saved.

        :param trajectory_type:     The type of trajectory to use. Either 'lattice' or 'xyz'.
                                    The 'lattice' format shows the types at the latice points.
                                    The 'xyz' format gives type and coordinate for each particle.
                                    The default type is 'lattice'.
        :param analysis:            A list of instantiated analysis objects that should be used for on-the-fly analysis.

        :param breakers:            A list of instantiated breaker objects to break the Monte Carlo loop with a custom criterion.
        """
        # Check the input.
        if not isinstance(control_parameters, KMCControlParameters):
            msg = """
The 'control_parameters' input to the KMCLatticeModel run funtion
must be an instance of type KMCControlParameters."""
            raise Error(msg)

        # Check the trajectory filename.
        use_trajectory = True
        if trajectory_filename is None:
            use_trajectory = False
            msg = """ KMCLib: WARNING: No trajectory filename given -> no trajectory will be saved."""
            prettyPrint(msg)

        elif not isinstance(trajectory_filename, str):
            msg = """
The 'trajectory_filename' input to the KMCLattice model run function
must be given as string."""
            raise Error(msg)

        # Check the analysis type.
        if trajectory_type is None:
            trajectory_type = 'lattice'

        if not isinstance(trajectory_type, str):
            raise Error("The 'trajectory_type' input must given as a string.")

        # Check the analysis.
        if analysis is None:
            analysis = []
        else:
            msg = "Each element in the 'analyis' list must be an instance of KMCAnalysisPlugin."
            analysis = checkSequenceOf(analysis, KMCAnalysisPlugin, msg)

        # Check the breakers.
        if breakers is None:
            breakers = []
        else:
            msg = "Each element in the 'breakers' list must be an instance of KMCBreakerPlugin."
            breakers = checkSequenceOf(breakers, KMCBreakerPlugin, msg)

        # Set and seed the backend random number generator.
        if not Backend.setRngType(control_parameters.rngType()):
            raise Error(
                "DEVICE random number generator is not supported by your system, or the std::random_device in the standard C++ library you use is implemented using a pseudo random number generator (entropy=0)."
            )

        Backend.seedRandom(control_parameters.timeSeed(),
                           control_parameters.seed())

        # Construct the C++ lattice model.
        prettyPrint(" KMCLib: setting up the backend C++ object.")

        cpp_model = self._backend()

        # Print the initial matching information if above the verbosity threshold.
        if self.__verbosity_level > 9:
            self.__printMatchInfo(cpp_model)

        # Check that we have at least one available process to  run the KMC simulation.
        if cpp_model.interactions().totalAvailableSites() == 0:
            raise Error(
                "No available processes. None of the processes defined as input match any position in the configuration. Change the initial configuration or processes to run KMC."
            )

        # Setup a trajectory object.
        last_time = self.__cpp_timer.simulationTime()
        if use_trajectory:
            if trajectory_type == 'lattice':
                trajectory = LatticeTrajectory(
                    trajectory_filename=trajectory_filename,
                    configuration=self.__configuration)
            elif trajectory_type == 'xyz':
                trajectory = XYZTrajectory(
                    trajectory_filename=trajectory_filename,
                    configuration=self.__configuration)
            else:
                raise Error(
                    "The 'trajectory_type' input must be either 'lattice' or 'xyz'."
                )

            # Add the first step.
            trajectory.append(
                simulation_time=self.__cpp_timer.simulationTime(),
                step=0,
                configuration=self.__configuration)

        # Setup the analysis objects.
        for ap in analysis:
            step = 0
            ap.setup(step, self.__cpp_timer.simulationTime(),
                     self.__configuration)

        # Get the needed parameters.
        n_steps = control_parameters.numberOfSteps()
        n_dump = control_parameters.dumpInterval()
        n_analyse = control_parameters.analysisInterval()
        dump_time = control_parameters.dumpTimeInterval()

        prettyPrint(" KMCLib: Runing for %i steps, starting from time: %f\n" %
                    (n_steps, self.__cpp_timer.simulationTime()))

        # Run the KMC simulation.
        try:
            # Loop over the steps.
            step = 0
            time_step = 0
            while (step < n_steps):
                step += 1

                # Check if it is possible to take a step.
                nP = cpp_model.interactions().totalAvailableSites()
                if nP == 0:
                    raise Error("No more available processes.")

                # Take a step.
                time_before = self.__cpp_timer.simulationTime()
                cpp_model.propagateTime()
                time_after = self.__cpp_timer.simulationTime()

                # Check if it is time to dump the previous step to the equidistant trajectory.
                if ((dump_time is not None)
                        and ((time_after - last_time) >= dump_time)):
                    time_step += 1
                    sample_time = time_step * dump_time
                    prettyPrint(" KMCLib: %14i steps executed. time: %20.10e" %
                                (step - 1, sample_time))
                    last_time = sample_time

                    # Perform IO using the trajectory object.
                    if use_trajectory:
                        trajectory.append(simulation_time=time_before,
                                          step=step - 1,
                                          configuration=self.__configuration)

                # Update the model.
                cpp_model.singleStep()

                # Get the current simulation time.
                now = self.__cpp_timer.simulationTime()

                # Check if it is time to write a trajectory dump.
                if ((dump_time is None) and ((step) % n_dump == 0)):
                    last_time = now
                    prettyPrint(" KMCLib: %i steps executed. time: %20.10e " %
                                (step, now))

                    # Perform IO using the trajectory object.
                    if use_trajectory:
                        trajectory.append(simulation_time=now,
                                          step=step,
                                          configuration=self.__configuration)

                if ((step) % n_analyse == 0):
                    # Run all other python analysis.
                    for ap in analysis:
                        ap.registerStep(step, now, self.__configuration)

                # Check all custom break criteria.
                break_the_loop = False
                for b in breakers:

                    # If it is time to evaluate this breaker.
                    if ((step) % b.interval() == 0):
                        break_the_loop = b.evaluate(step, now,
                                                    self.__configuration)
                        # Break the inner loop.
                        if break_the_loop:
                            break

                # Break the main Monte-Carlo loop.
                if break_the_loop:
                    break

        finally:

            # Flush the trajectory buffers when done.
            if use_trajectory:
                trajectory.flush()

            # Perform the analysis post processing.
            for ap in analysis:
                ap.finalize()
Пример #8
0
    def run(self,
            control_parameters=None,
            trajectory_filename=None,
            trajectory_type=None,
            analysis=None):
        """
        Run the KMC lattice model simulation with specified parameters.

        :param control_paramters:   An instance of KMCControlParameters specifying
                                    number of steps to run etc.

        :param trajectory_filename: The filename of the trajectory. If not given
                                    no trajectory will be saved.

        :param trajectory_type:     The type of trajectory to use. Either 'lattice' or 'xyz'.
                                    The 'lattice' format shows the types at the latice points.
                                    The 'xyz' format gives type and coordinate for each particle.
                                    The default type is 'lattice'.
        :param analysis:            A list of instantiated analysis objects that should be used for on-the-fly analysis.
        """
        # Check the input.
        if not isinstance(control_parameters, KMCControlParameters):
            msg ="""
The 'control_parameters' input to the KMCLatticeModel run funtion
must be an instance of type KMCControlParameters."""
            raise Error(msg)

        # Check the trajectory filename.
        use_trajectory = True
        if trajectory_filename is None:
            use_trajectory = False
            msg =""" KMCLib: WARNING: No trajectory filename given -> no trajectory will be saved."""
            prettyPrint(msg)

        elif not isinstance(trajectory_filename, str):
            msg = """
The 'trajectory_filename' input to the KMCLattice model run function
must be given as string."""
            raise Error(msg)

        # Check the analysis type.
        if trajectory_type is None:
            trajectory_type = 'lattice'

        if not isinstance(trajectory_type, str):
            raise Error("The 'trajectory_type' input must given as a string.")

        # Check the analysis.
        if analysis is None:
            analysis = []
        else:
            msg = "Each element in the 'analyis' list must be an instance of KMCAnalysisPlugin."
            analysis = checkSequenceOf(analysis, KMCAnalysisPlugin, msg)

        # Seed the backend random number generator.
        Backend.seedRandom(control_parameters.timeSeed(),
                           control_parameters.seed())

        # Construct the C++ lattice model.
        prettyPrint(" KMCLib: setting up the backend C++ object.")

        cpp_model = self._backend()

        # Print the initial matching information if above the verbosity threshold.
        if self.__verbosity_level > 9:
            self.__printMatchInfo(cpp_model)

        # Check that we have at least one available process to  run the KMC simulation.
        if cpp_model.interactions().totalAvailableSites() == 0:
            raise Error("No available processes. None of the processes defined as input match any position in the configuration. Change the initial configuration or processes to run KMC.")
#####
##### Custom addiation to use_trajectory -- added CFG.
#####
        # Setup a trajectory object.
        if use_trajectory:
            if trajectory_type == 'lattice':
                trajectory = LatticeTrajectory(trajectory_filename=trajectory_filename,
                                               configuration=self.__configuration)
            elif trajectory_type == 'xyz':
                trajectory = XYZTrajectory(trajectory_filename=trajectory_filename,
                                           configuration=self.__configuration)
            elif trajectory_type == 'cfg':
                trajectory = CFGTrajectory(trajectory_filename=trajectory_filename,
                                           configuration=self.__configuration)                                               
            else:
                raise Error("The 'trajectory_type' input must be either 'lattice' or 'xyz'.")

            # Add the first step.
            trajectory.append(simulation_time  = self.__cpp_timer.simulationTime(),
                              step             = 0,
                              configuration    = self.__configuration)
            
        # Setup the analysis objects.
        for ap in analysis:
            step = 0
            ap.setup(step,
                     self.__cpp_timer.simulationTime(),
                     self.__configuration);

        # Get the needed parameters.
        n_steps   = control_parameters.numberOfSteps()
        n_dump    = control_parameters.dumpInterval()
        n_analyse = control_parameters.analysisInterval()
        prettyPrint(" KMCLib: Runing for %i steps, starting from time: %f\n"%(n_steps, self.__cpp_timer.simulationTime()))

        # Run the KMC simulation.
        try:
            # Loop over the steps.
            step = 0
            while(step < n_steps):
                step += 1
#            for s in range(n_steps):
#                step = s+1

                # Check if it is possible to take a step.
                nP = cpp_model.interactions().totalAvailableSites()
                if nP == 0:
                    raise Error("No more available processes.")

                # Take a step.
                cpp_model.singleStep()

                if ((step)%n_dump == 0):
                    prettyPrint(" KMCLib: %i steps executed. time: %20.10e "%(step, self.__cpp_timer.simulationTime()))

                    # Perform IO using the trajectory object.
                    if use_trajectory:
                        trajectory.append(simulation_time  = self.__cpp_timer.simulationTime(),
                                          step             = step,
                                          configuration    = self.__configuration)

                if ((step)%n_analyse == 0):
                    # Run all other python analysis.
                    for ap in analysis:
                        ap.registerStep(step,
                                        self.__cpp_timer.simulationTime(),
                                        self.__configuration);

        finally:

            # Flush the trajectory buffers when done.
            if use_trajectory:
                trajectory.flush()

            # Perform the analysis post processing.
            for ap in analysis:
                ap.finalize();