Beispiel #1
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()
Beispiel #2
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();
Beispiel #3
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();
    def testAppend(self):
        """ Test appending to the trajectory. """
        # Setup input.
        sites = [[0.0, 1.0, 2.3], [1.0, 0.0, 2.3], [1.0, 1.0, 0.3],
                 [1.0, 1.0, 2.3], [3.4, 4.5, 4.3], [3.4, 4.3, 4.3],
                 [3.4, 5.5, 4.3], [3.7, 7.5, 6.5]]
        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_file.py")

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

        class DummyConfig:
            def types(self):
                return site_types

        # Construct.
        t = LatticeTrajectory(trajectory_filename, Config(sites))

        # Append times, steps and typers.
        site_types = ["A", "A", "A", "A", "A", "A"]
        t.append(1.10045, 12, DummyConfig())

        # Since this was the first time it should have triggered a dump to file.
        if MPICommons.isMaster():
            global_dict = {}
            local_dict = {}
            execfile(trajectory_filename, global_dict, local_dict)

            # Check the types.
            ret_types = local_dict['types']
            ref_types = [["A", "A", "A", "A", "A", "A"]]
            self.assertEqual(ret_types, ref_types)

            # Check the steps.
            ret_steps = local_dict['steps']
            ref_steps = [12]
            self.assertEqual(ret_steps, ref_steps)

            # Check the times.
            ret_times = local_dict['times']
            ref_times = [1.10045]
            self.assertEqual(ret_times, ref_times)

        # Appending again directly makes no dump.
        site_types = ["B", "B", "B", "B", "B", "B"]
        t.append(1.1993, 14, DummyConfig())

        if MPICommons.isMaster():
            global_dict = {}
            local_dict = {}
            execfile(trajectory_filename, global_dict, local_dict)

            # Check.
            ret_types = local_dict['types']
            self.assertEqual(ret_types, ref_types)
            ret_steps = local_dict['steps']
            self.assertEqual(ret_steps, ref_steps)
            ret_times = local_dict['times']
            self.assertEqual(ret_times, ref_times)

        # But if we dump again and set the time limit to zero we will trigger a dump.
        t._Trajectory__max_buffer_time = 0.0
        site_types = ["C", "C", "C", "C", "C", "C"]
        t.append(1.199, 19, DummyConfig())

        # Reset the time to some thing large.
        t._Trajectory__max_buffer_time = 100000000000.0

        if MPICommons.isMaster():
            global_dict = {}
            local_dict = {}
            execfile(trajectory_filename, global_dict, local_dict)

            # Check the types.
            ret_types = local_dict['types']
            ref_types = [["A", "A", "A", "A", "A", "A"],
                         ["B", "B", "B", "B", "B", "B"],
                         ["C", "C", "C", "C", "C", "C"]]

            self.assertEqual(ret_types, ref_types)

            # Check the steps.
            ret_steps = local_dict['steps']
            ref_steps = [12, 14, 19]
            self.assertEqual(ret_steps, ref_steps)

            # Check the times.
            ret_times = local_dict['times']
            ref_times = [1.10045, 1.1993, 1.199]
            self.assertEqual(ret_times, ref_times)

        # The buffers are reset after each dump. If we make the
        # max size limit smaller than the size of the appended types
        # list this must trigger a dump.
        size = sys.getsizeof(site_types)
        t._Trajectory__max_buffer_size = size

        # Append.
        site_types = ["A", "A", "A", "A", "A", "B"]
        t.append(1.1995, 43, DummyConfig())

        # Check.
        if MPICommons.isMaster():
            global_dict = {}
            local_dict = {}
            execfile(trajectory_filename, global_dict, local_dict)

            ret_types = local_dict['types']
            ref_types = [["A", "A", "A", "A", "A", "A"],
                         ["B", "B", "B", "B", "B", "B"],
                         ["C", "C", "C", "C", "C", "C"],
                         ["A", "A", "A", "A", "A", "B"]]

            self.assertEqual(ret_types, ref_types)

        # Append.
        t.append(1.1995, 43, DummyConfig())
        t.append(1.1995, 43, DummyConfig())
        t.append(1.1995, 43, DummyConfig())
        # This last one triggers the dump.
        t.append(1.1995, 43, DummyConfig())

        # Check.
        if MPICommons.isMaster():
            global_dict = {}
            local_dict = {}
            execfile(trajectory_filename, global_dict, local_dict)

            ret_types = local_dict['types']
            ref_types = [["A", "A", "A", "A", "A", "A"],
                         ["B", "B", "B", "B", "B", "B"],
                         ["C", "C", "C", "C", "C", "C"],
                         ["A", "A", "A", "A", "A", "B"],
                         ["A", "A", "A", "A", "A", "B"],
                         ["A", "A", "A", "A", "A", "B"],
                         ["A", "A", "A", "A", "A", "B"],
                         ["A", "A", "A", "A", "A", "B"]]

            self.assertEqual(ret_types, ref_types)
    def testAppend(self):
        """ Test appending to the trajectory. """
        # Setup input.
        sites = [[0.0,1.0,2.3],
                 [1.0,0.0,2.3],
                 [1.0,1.0,0.3],
                 [1.0,1.0,2.3],
                 [3.4,4.5,4.3],
                 [3.4,4.3,4.3],
                 [3.4,5.5,4.3],
                 [3.7,7.5,6.5]]
        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_file.py")

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

        class DummyConfig:
            def types(self):
                return site_types

        # Construct.
        t = LatticeTrajectory(trajectory_filename, Config(sites))

        # Append times, steps and typers.
        site_types = ["A", "A", "A", "A", "A", "A"]
        t.append(1.10045, 12, DummyConfig())

        # Since this was the first time it should have triggered a dump to file.
        if MPICommons.isMaster():
            global_dict = {}
            local_dict  = {}
            execfile(trajectory_filename, global_dict, local_dict)

            # Check the types.
            ret_types = local_dict['types']
            ref_types = [["A", "A", "A", "A", "A", "A"]]
            self.assertEqual( ret_types, ref_types )

            # Check the steps.
            ret_steps = local_dict['steps']
            ref_steps = [12]
            self.assertEqual( ret_steps, ref_steps )

            # Check the times.
            ret_times = local_dict['times']
            ref_times = [1.10045]
            self.assertEqual( ret_times, ref_times )

        # Appending again directly makes no dump.
        site_types = ["B", "B", "B", "B", "B", "B"]
        t.append(1.1993, 14, DummyConfig())

        if MPICommons.isMaster():
            global_dict = {}
            local_dict  = {}
            execfile(trajectory_filename, global_dict, local_dict)

            # Check.
            ret_types = local_dict['types']
            self.assertEqual( ret_types, ref_types )
            ret_steps = local_dict['steps']
            self.assertEqual( ret_steps, ref_steps )
            ret_times = local_dict['times']
            self.assertEqual( ret_times, ref_times )

        # But if we dump again and set the time limit to zero we will trigger a dump.
        t._Trajectory__max_buffer_time = 0.0
        site_types = ["C", "C", "C", "C", "C", "C"]
        t.append(1.199, 19, DummyConfig())

        # Reset the time to some thing large.
        t._Trajectory__max_buffer_time = 100000000000.0

        if MPICommons.isMaster():
            global_dict = {}
            local_dict  = {}
            execfile(trajectory_filename, global_dict, local_dict)

            # Check the types.
            ret_types = local_dict['types']
            ref_types = [["A","A","A","A","A","A"],
                         ["B","B","B","B","B","B"],
                         ["C","C","C","C","C","C"]]

            self.assertEqual( ret_types, ref_types )

            # Check the steps.
            ret_steps = local_dict['steps']
            ref_steps = [12,14,19]
            self.assertEqual( ret_steps, ref_steps )

            # Check the times.
            ret_times = local_dict['times']
            ref_times = [1.10045, 1.1993, 1.199]
            self.assertEqual( ret_times, ref_times )

        # The buffers are reset after each dump. If we make the
        # max size limit smaller than the size of the appended types
        # list this must trigger a dump.
        size = sys.getsizeof(site_types)
        t._Trajectory__max_buffer_size = size

        # Append.
        site_types = ["A","A","A","A","A","B"]
        t.append(1.1995, 43, DummyConfig())

        # Check.
        if MPICommons.isMaster():
            global_dict = {}
            local_dict  = {}
            execfile(trajectory_filename, global_dict, local_dict)

            ret_types = local_dict['types']
            ref_types = [["A","A","A","A","A","A"],
                         ["B","B","B","B","B","B"],
                         ["C","C","C","C","C","C"],
                         ["A","A","A","A","A","B"]]

            self.assertEqual( ret_types, ref_types )

        # Append.
        t.append(1.1995, 43, DummyConfig() )
        t.append(1.1995, 43, DummyConfig() )
        t.append(1.1995, 43, DummyConfig() )
        # This last one triggers the dump.
        t.append(1.1995, 43, DummyConfig() )

        # Check.
        if MPICommons.isMaster():
            global_dict = {}
            local_dict  = {}
            execfile(trajectory_filename, global_dict, local_dict)

            ret_types = local_dict['types']
            ref_types = [["A","A","A","A","A","A"],
                         ["B","B","B","B","B","B"],
                         ["C","C","C","C","C","C"],
                         ["A","A","A","A","A","B"],
                         ["A","A","A","A","A","B"],
                         ["A","A","A","A","A","B"],
                         ["A","A","A","A","A","B"],
                         ["A","A","A","A","A","B"]]

            self.assertEqual( ret_types, ref_types )