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 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();
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 testFlush(self): """ Make sure we can flush the buffer as expected. """ # Get a filename. 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) # Construct the trajecctory object. 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]] # Construct. t = LatticeTrajectory(trajectory_filename, Config(sites)) # To check against. empty_list = [] # Check that the file is created but only with meta information. if MPICommons.isMaster(): global_dict = {} local_dict = {} execfile(trajectory_filename, global_dict, local_dict) ret_types = local_dict['types'] self.assertEqual(ret_types, empty_list) ret_times = local_dict['times'] self.assertEqual(ret_times, empty_list) ret_steps = local_dict['steps'] self.assertEqual(ret_steps, empty_list) # Fill the buffers. t._LatticeTrajectory__types_buffer = [["ABC", "123"], ["123", "ABC"]] t._LatticeTrajectory__simulation_time_buffer = [1.234, 5.678] t._LatticeTrajectory__step_buffer = [1, 99] # Flush the buffers. t.flush() # Check that the buffers are empty. self.assertEqual(t._LatticeTrajectory__types_buffer, empty_list) self.assertEqual(t._LatticeTrajectory__simulation_time_buffer, empty_list) self.assertEqual(t._LatticeTrajectory__step_buffer, empty_list) # Check that the file has the flushed values. if MPICommons.isMaster(): global_dict = {} local_dict = {} execfile(trajectory_filename, global_dict, local_dict) ret_types = local_dict['types'] self.assertEqual(ret_types, [["ABC", "123"], ["123", "ABC"]]) ret_times = local_dict['times'] self.assertAlmostEqual(ret_times, [1.234, 5.678], 10) ret_steps = local_dict['steps'] self.assertEqual(ret_steps, [1, 99])
def testFlush(self): """ Make sure we can flush the buffer as expected. """ # Get a filename. 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) # Construct the trajecctory object. 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]] # Construct. t = LatticeTrajectory(trajectory_filename, Config(sites)) # To check against. empty_list = [] # Check that the file is created but only with meta information. if MPICommons.isMaster(): global_dict = {} local_dict = {} execfile(trajectory_filename, global_dict, local_dict) ret_types = local_dict['types'] self.assertEqual( ret_types, empty_list ) ret_times = local_dict['times'] self.assertEqual( ret_times, empty_list ) ret_steps = local_dict['steps'] self.assertEqual( ret_steps, empty_list ) # Fill the buffers. t._LatticeTrajectory__types_buffer = [["ABC", "123"],["123", "ABC"]] t._LatticeTrajectory__simulation_time_buffer = [1.234, 5.678] t._LatticeTrajectory__step_buffer = [1, 99] # Flush the buffers. t.flush() # Check that the buffers are empty. self.assertEqual( t._LatticeTrajectory__types_buffer, empty_list ) self.assertEqual( t._LatticeTrajectory__simulation_time_buffer, empty_list ) self.assertEqual( t._LatticeTrajectory__step_buffer, empty_list ) # Check that the file has the flushed values. if MPICommons.isMaster(): global_dict = {} local_dict = {} execfile(trajectory_filename, global_dict, local_dict) ret_types = local_dict['types'] self.assertEqual( ret_types, [["ABC", "123"],["123", "ABC"]] ) ret_times = local_dict['times'] self.assertAlmostEqual( ret_times, [1.234, 5.678], 10 ) ret_steps = local_dict['steps'] self.assertEqual( ret_steps, [1, 99] )