Reading output files
After completing a Zacros simulation, zacrostools can be used to parse and analyze the results.
Extract data from a single simulation
The KMCOutput class provides a convenient interface to load simulation data from output files, compute averages and coverages, and extract key performance indicators like turnover frequencies (TOFs) and selectivities.
Required parameters:
path(str): Path to the directory containing Zacros output files (e.g.,simulation_input.dat,general_output.txt,specnum_output.txt, etc.).analysis_range(list, optional): Portion of the simulation used for averaging and analysis ([start%, end%], default =[0.0, 100.0]).
Example:[50, 100]analyzes only the last half of the simulation.range_type(str, optional): Defines howanalysis_rangeis interpreted (default ='time').'time': Percentages refer to total simulated time.'nevents': Percentages refer to total number of simulated events.
weights(str, optional): Weighting scheme for averaging (default =None).'time': Weighted by time intervals.'nevents': Weighted by number of events.None: Equal weights for all data points.
from zacrostools.kmc_output import KMCOutput
# Here, we consider the last 50% of the simulation time and apply time-weighted averaging.
kmc_output = KMCOutput(path='/path/to/simulation_files', analysis_range=[50, 100], range_type='time', weights='time')
Once you have created a KMCOutput object, you can access all the information using the following attributes:
General simulation data:
random_seed(int): Random seed used by Zacros.temperature(float): Simulation temperature (K).pressure(float): Total pressure (bar).n_gas_species(int): Number of gas-phase species.gas_specs_names(list of str): Names of the gas-phase species.gas_molar_fracs(list of float): Molar fractions of each gas species.n_surf_species(int): Number of surface-bound species.surf_specs_names(list of str): Names of the surface species.n_sites(int): Total number of lattice sites.area(float): Catalyst surface area (Ų).site_types(dict): Mapping of site types to the number of sites of each type (e.g.,{'top': 50, 'bridge': 50}).
Events and time:
nevents(np.ndarray): Array of integers representing the cumulative number of KMC events at each recorded data point.time(np.ndarray): Simulated time at each data point (s).finaltime(float): Final simulation time (s).
Lattice energy:
energy(np.ndarray): Lattice energy over time (eV·Å⁻²).av_energy(float): Time/Events-weighted average lattice energy (eV·Å⁻²).final_energy(float): Final lattice energy (eV·Å⁻²).energyslope(float): Slope of energy vs. events (eV·Å⁻²·step⁻¹). A large slope may suggest the simulation did not reach steady-state.
Gas production and TOF:
production(dict): Dictionary of arrays tracking the cumulative production of each gas species over time (in molecules). For example,kmc_output.production['CO']gives an array of CO production values.total_production(dict): Total number of molecules produced for each gas species by the end of the simulation. Example:kmc_output.total_production['CO'].tof(dict): Turnover frequency of each gas species (molecules·s⁻¹·Å⁻²), indicating production rate normalized by the catalyst area. For example,kmc_output.tof['CO2'].
Surface coverage:
coverage(dict): Coverage of each surface species over time, expressed as a percentage of total sites. Example:kmc_output.coverage['CO']gives an array of CO coverage values.av_coverage(dict): Weighted average coverage of each surface species over the analysis window. Example:kmc_output.av_coverage['CO'].total_coverage(np.ndarray): Total coverage of all surface species combined, over time (%).av_total_coverage(float): Average total coverage (%).dominant_ads(str): The surface species with the highest average coverage.coverage_per_site_type(dict): Nested dictionaries of coverage by site type and species over time. Example:kmc_output.coverage_per_site_type['top']['CO'].av_coverage_per_site_type(dict): Weighted average coverage per site type and species. Example:kmc_output.av_coverage_per_site_type['top']['CO'].total_coverage_per_site_type(dict): Total coverage per site type over time (%).av_total_coverage_per_site_type(dict): Average total coverage per site type (%).dominant_ads_per_site_type(dict): Dominant adsorbed species on each site type.
Finally, the selectivity can be obtained using the get_selectivity() method. The following parameters are required:
main_product(str): Main product species name.side_products(list of str): List of side product species names.
Note that the selectivity is defined as:
selectivity = (TOF_main_product / (TOF_main_product + sum(TOF_side_products))) * 100
from zacrostools.kmc_output import KMCOutput
# Read simulation output
kmc_output = KMCOutput(
path='temp_600K',
analysis_range=[50, 100],
range_type='time',
weights='time')
# Print TOF of all gas-phase species
for gas_spec in kmc_output.gas_specs_names:
tof = kmc_output.tof[gas_spec]
print(f"{gas_spec}: {tof:.3e} molec·s⁻¹·Å⁻²")
# Compute selectivity of CH4 vs CO2 and CH3OH
select_ch4 = kmc_output.get_selectivity(
main_product='CH4',
side_products=['CO2', 'CH3OH'])
print(f"Selectivity of CH4: {select_ch4:.2f}%")
# Print average coverage of all surface species
for surf_spec in kmc_output.surf_specs_names:
avg_cov = kmc_output.av_coverage[surf_spec]
print(f"{surf_spec}: {avg_cov:.2f}%")
Extract data from multiple simulations
The read_scan function can be used to read the results of all KMC simulations in a given scan directory. This function returns a Pandas DataFrame containing key observables for each simulation.
from zacrostools.read_scan import read_scan
data_scan = read_scan(
scan_path='path_to_scan',
analysis_range=[50, 100],
range_type='time')
data_scan.to_csv('data_scan.csv', index=True)