@@ -27,15 +27,15 @@ class PhononSimulator:
2727 This class can simulate a number of phonons and save all their data and then return it all
2828 It is meant to be used as a worker for multiprocessing
2929 """
30-
30+
3131 def __init__ (self , worker_id , total_phonons , shared_list , output_trajectories_of ):
3232 # save some general information about the process
3333 self .worker_id = worker_id
3434 self .total_phonons = total_phonons
3535 self .result_queue = shared_list
3636 self .creation_time = time .time ()
3737 self .output_trajectories_of = output_trajectories_of
38-
38+
3939 # Initiate data structures:
4040 self .material = Material (cf .media , num_points = cf .number_of_phonons + 1 )
4141 self .scatter_stats = ScatteringData ()
@@ -44,44 +44,44 @@ def __init__(self, worker_id, total_phonons, shared_list, output_trajectories_of
4444 self .path_stats = PathData ()
4545 self .scatter_maps = ScatteringMap ()
4646 self .thermal_maps = ThermalMaps ()
47-
47+
4848 self .total_thermal_conductivity = 0.0
49-
49+
5050 def simulate_phonon (self , index ):
5151 # Initiate a phonon and its flight:
52- phonon = Phonon (self .material )
53- flight = Flight (phonon )
54-
55- # Run this phonon through the structure:
56- run_phonon (phonon , flight , self .scatter_stats , self .segment_stats , self .thermal_maps , self .scatter_maps , self .material )
57-
58- # Record the properties returned for this phonon:
59- self .general_stats .save_phonon_data (phonon )
60- self .general_stats .save_flight_data (flight )
61-
62- # Record trajectories of the first N phonons:
63- if index < self .output_trajectories_of :
64- self .path_stats .save_phonon_path (flight )
65-
52+ phonon = Phonon (self .material )
53+ flight = Flight (phonon )
54+
55+ # Run this phonon through the structure:
56+ run_phonon (phonon , flight , self .scatter_stats , self .segment_stats , self .thermal_maps , self .scatter_maps , self .material )
57+
58+ # Record the properties returned for this phonon:
59+ self .general_stats .save_phonon_data (phonon )
60+ self .general_stats .save_flight_data (flight )
61+
62+ # Record trajectories of the first N phonons:
63+ if index < self .output_trajectories_of :
64+ self .path_stats .save_phonon_path (flight )
65+
6666 def simulate_phonons (self , render_progress = False ):
6767 """Simulate a number of phonons and save data to shared datastructure"""
68-
69- # only one of the workers will display it's progress as it is similar over all workers
68+
69+ # Only one of the workers will display its progress as it is similar over all workers:
7070 if render_progress :
7171 progress = Progress ()
72-
73- # for each phonon
72+
73+ # Run simulation for each phonon:
7474 for index in range (self .total_phonons ):
7575 # render progress
7676 if render_progress :
7777 progress .render (index , self .total_phonons )
78-
78+
7979 self .simulate_phonon (index )
80-
80+
8181 if render_progress :
8282 progress .render (index + 1 , self .total_phonons )
83-
84- # collect relevant data
83+
84+ # Collect relevant data:
8585 collected_data = {
8686 'scatter_stats' : self .scatter_stats .dump_data (),
8787 'general_stats' : self .general_stats .dump_data (),
@@ -91,25 +91,25 @@ def simulate_phonons(self, render_progress=False):
9191 'thermal_maps' : self .thermal_maps .dump_data (),
9292 'execution_time' : time .time () - self .creation_time ,
9393 }
94-
95- # put data into shared list
94+
95+ # Put the data into shared list:
9696 self .result_queue .append (collected_data )
9797
9898
9999def worker_process (worker_id , total_phonons , shared_list , output_trajectories_of , finished_workers ):
100100 try :
101- # create a phononsimulator and run the simulation
101+ # Create a phononsimulator and run the simulation:
102102 simulator = PhononSimulator (worker_id , total_phonons , shared_list , output_trajectories_of )
103103 simulator .simulate_phonons (render_progress = 1 if worker_id == 0 else 0 )
104-
105- # declare that the calculation is finished
104+
105+ # Declare that the calculation is finished:
106106 finished_workers .value += 1
107107 except Exception as e :
108108 sys .stdout .write (f'\r worker { worker_id } had error { e } \n ' )
109109
110110
111111def display_workers_finished (finished_workers ):
112- # display number of active workers
112+ """ Print out the number of active workers"""
113113 while True :
114114 text_to_display = f' Workers finished: { finished_workers .value } /{ cf .num_workers } '
115115 sys .stdout .write (text_to_display )
@@ -125,23 +125,23 @@ def main(input_file):
125125
126126 sys .stdout .write (f'Simulation of { Fore .GREEN } { cf .output_folder_name } { Style .RESET_ALL } \n ' )
127127 start_time = time .time ()
128-
129- # create manager for managing variable acces for multiple workers
128+
129+ # Create manager for managing variable acces for multiple workers:
130130 manager = multiprocessing .Manager ()
131-
132- # these variables created with the manager can safely be accessed by multiple workers. Using normal values might create wrong data
131+
132+ # These variables created with the manager can safely be accessed by multiple workers:
133133 shared_list = manager .list ()
134134 finished_workers = manager .Value ('i' , 0 )
135-
136- # Divide workload among workers
135+
136+ # Divide all the phonons among the workers:
137137 workload_per_worker = cf .number_of_phonons // cf .num_workers
138138 remaining_phonons = cf .number_of_phonons % cf .num_workers
139139
140- # divide number of output trajectories to save among workers
140+ # Divide number of output trajectories to save among workers:
141141 output_trajectories_per_worker = cf .output_trajectories_of_first // cf .num_workers
142142 remaining_output_trajectories = cf .output_trajectories_of_first % cf .num_workers
143143
144- # Create and start worker processes
144+ # Create and start worker processes:
145145 sys .stdout .write ('Starting the workers...\r ' )
146146 sys .stdout .flush ()
147147 processes = []
@@ -151,40 +151,40 @@ def main(input_file):
151151 process = multiprocessing .Process (target = worker_process , args = (i , worker_phonons , shared_list , output_trajectory_of , finished_workers ))
152152 processes .append (process )
153153 process .start ()
154-
155- # start a seperate worker to display the number of workers that finished
154+
155+ # Start a seperate worker to display the number of workers that finished:
156156 worker_count_process = multiprocessing .Process (target = display_workers_finished , args = (finished_workers ,))
157157 worker_count_process .start ()
158158
159- # Wait for all processes to finish
160- # note that join is not called on worker_count_process because we do not want to wait for it to finish
159+ # Wait for all processes to finish:
160+ # Note that join is not called on worker_count_process because we do not want to wait for it to finish
161161 for process in processes :
162162 process .join ()
163-
164- # wait for worker count to finish but continue after 3 seconds
163+
164+ # Wait for the worker count to finish but continue after 3 seconds:
165165 worker_count_process .join (timeout = 3 )
166166 worker_count_process .terminate () # should not be necessary but sometimes process does not terminate
167-
168- # Initiate data structures to collect the data from the workers
167+
168+ # Initiate data structures to collect the data from the workers:
169169 # material = Material(cf.media, num_points=cf.number_of_phonons+1)
170170 scatter_stats = ScatteringData ()
171171 general_stats = GeneralData ()
172172 segment_stats = SegmentData ()
173173 path_stats = PathData ()
174174 scatter_maps = ScatteringMap ()
175175 thermal_maps = ThermalMaps ()
176-
177- # collect the results
176+
177+ # Collect the results:
178178 sys .stdout .write ('\n Collecting data from workers...\r ' )
179-
180- # convert the shared list to a normal list so it's easyer to use
179+
180+ # Convert the shared list to a normal list so it's easier to use
181181 result_list = list (shared_list )
182-
183- # check that all workers actually returned some data
182+
183+ # Check that all workers actually returned some data
184184 if len (result_list ) != cf .num_workers :
185185 sys .stdout .write (f'WARNING: of { cf .num_workers } workers only the results of { len (result_list )} were collected\n ' )
186-
187- # put the data from every worker into it's respective place
186+
187+ # Put the data from every worker into it's respective place:
188188 execution_time_list = []
189189 for collected_data in result_list :
190190 scatter_stats .read_data (collected_data ['scatter_stats' ])
@@ -194,18 +194,20 @@ def main(input_file):
194194 scatter_maps .read_data (collected_data ['scatter_maps' ])
195195 thermal_maps .read_data (collected_data ['thermal_maps' ])
196196 execution_time_list .append (collected_data ['execution_time' ])
197-
198- # give some info about the variability in the worker calculation time
197+
198+ # Give some info about the variability in the worker calculation time:
199199 if cf .num_workers > 1 :
200- sys .stdout .write (f'Shortest worker execution time: { round (min (execution_time_list ))} s; Longest worker execution time: { round (max (execution_time_list ))} s\n ' )
200+ sys .stdout .write (f'Shortest process execution time: { round (min (execution_time_list ))} s\n ' )
201+ sys .stdout .write (f'Longest process execution time: { round (max (execution_time_list ))} s\n ' )
201202
202- # check if the total amount of returned phonons from the workers correspoinds with the number of phonons to be simulated
203+ # Check if the total number of returned phonons from the workers corresponds with the number of phonons to be simulated:
203204 if len (general_stats .initial_angles ) != cf .number_of_phonons :
204205 sys .stdout .write (f'WARNING: { cf .number_of_phonons } were meant to be simulated but only { len (general_stats .initial_angles )} phonons were collected from the workers\n ' )
205206
206207 # Run additional calculations:
207208 thermal_maps .calculate_thermal_conductivity ()
208209 thermal_maps .calculate_normalized_flux ()
210+
209211 # Create the folder if it does not exist and copy input file there:
210212 if not os .path .exists (f"Results/{ cf .output_folder_name } " ):
211213 os .makedirs (f"Results/{ cf .output_folder_name } " )
@@ -238,4 +240,4 @@ def main(input_file):
238240 output_scattering_information (scatter_stats )
239241
240242 sys .stdout .write (f'\r See the results in { Fore .GREEN } Results/{ cf .output_folder_name } { Style .RESET_ALL } \n ' )
241- sys .stdout .write (f"\r { Fore .BLUE } Thank you for using FreePATHS{ Style .RESET_ALL } \n " )
243+ sys .stdout .write (f"\r { Fore .BLUE } Thank you for using FreePATHS{ Style .RESET_ALL } \n \n " )
0 commit comments