-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
162 additions
and
304 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,162 +1,173 @@ | ||
# Reading output files | ||
|
||
## 1. Store simulation data in a `KMCOutput` object | ||
## Overview | ||
|
||
All the information about a finished *Zacros* simulation can be extracted by creating a `KMCOutput` object using `zacrostools.kmc_output.KMCOutput`. | ||
After completing a Zacros simulation, you can use `zacrostools` to parse and analyze the results. 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. This unified approach simplifies the post-processing workflow, making it straightforward to analyze multiple simulations or perform parametric studies. | ||
|
||
--- | ||
|
||
## Creating a `KMCOutput` object | ||
|
||
To extract simulation results, instantiate a `KMCOutput` object by pointing it to the directory containing the Zacros output files. You can also specify analysis ranges and weighting schemes for averaging results, giving you fine-grained control over the portion of the simulation data you want to analyze. | ||
|
||
### Example | ||
|
||
```python | ||
from zacrostools.kmc_output import KMCOutput | ||
|
||
# Create a KMCOutput object to read data from the current directory. | ||
# Here, we consider the last 50% of the simulation time and apply time-weighted averaging. | ||
kmc_output = KMCOutput(path='.', analysis_range=[50, 100], range_type='time', weights='time') | ||
``` | ||
|
||
### Arguments | ||
|
||
**Mandatory:** | ||
|
||
- **`path`** (*str*): Path of the directory containing the output files. | ||
- **`path`** (*str*): Path to the directory containing the Zacros output files (e.g., `simulation_input.dat`, `general_output.txt`, `specnum_output.txt`, etc.). | ||
|
||
**Optional:** | ||
|
||
- **`analysis_range`** (*list*): A list of two elements `[initial_percent, final_percent]` specifying the window of the total simulation. The values should be between 0 and 100, representing the percentage of the total simulated time or the total number of events to be considered. | ||
- Default: `[0.0, 100.0]` | ||
- **`analysis_range`** (*list*, default: `[0.0, 100.0]`): Defines the segment of the simulation considered for averaging and analysis. The two-element list `[start_percent, end_percent]` specifies the portion of the simulation to use. For instance, `[50, 100]` focuses on the last half of the simulation. | ||
|
||
- **`range_type`** (*str*, default: `'time'`): Determines how `analysis_range` is interpreted: | ||
- `'time'`: The percentages refer to segments of total simulated time. | ||
- `'nevents'`: The percentages refer to segments of the total number of simulated events. | ||
|
||
- **`weights`** (*str*, default: `None`): Sets the weighting scheme for averaging: | ||
- `'time'`: Weighted by the time interval between data points. | ||
- `'nevents'`: Weighted by the number of events between data points. | ||
- `None`: No weighting (all data points are equally weighted). | ||
|
||
- **`range_type`** (*str*): The type of window to apply when calculating averages (e.g., `av_coverage`) or TOF. Possible values: | ||
- `'time'`: Apply a window over the simulated time. | ||
- `'nevents'`: Apply a window over the number of simulated events. | ||
- Default: `'time'` | ||
--- | ||
|
||
- **`weights`** (*str*): Weights for calculating the weighted average. Possible values: | ||
- `'time'` | ||
- `'nevents'` | ||
- `None` (all weights are set to 1) | ||
- Default: `None` | ||
## Accessing simulation data | ||
|
||
## 2. Read simulation data from a `KMCOutput` object | ||
|
||
All KMC results can be obtained from the different `KMCOutput` attributes. | ||
Once you have created a `KMCOutput` object, you can access a variety of data fields. These data fields include simulation conditions, reaction outcomes, coverage profiles, and calculated averages. The attributes and their meanings are summarized below. | ||
|
||
### General simulation data | ||
|
||
- **`random_seed`** (*int*): Random seed used in the simulation. | ||
- **`temperature`** (*float*): Temperature used in the simulation (in Kelvin). | ||
- **`pressure`** (*float*): Total pressure used in the simulation (in bar). | ||
- **`n_gas_species`** (*int*): Number of gas species. | ||
- **`gas_specs_names`** (*list of str*): Gas species names. | ||
- **`gas_molar_fracs`** (*list of float*): Molar fractions of gas species. | ||
- **`n_surf_species`** (*int*): Number of surface species. | ||
- **`surf_specs_names`** (*list of str*): Surface species names. | ||
- **`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*): Lattice surface area (in Ų). | ||
- **`site_types`** (*dict*): Site type names and the total number of sites of each type. | ||
|
||
### Events | ||
|
||
- **`nevents`** (*np.ndarray*): Number of KMC events occurred. | ||
- **`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}`). | ||
|
||
### Simulated time | ||
### Events and time | ||
|
||
- **`time`** (*np.ndarray*): Simulated time (in seconds). | ||
- **`finaltime`** (*float*): Final simulated time (in seconds). | ||
- **`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 (in eV·Å⁻²). | ||
- **`av_energy`** (*float*): Average lattice energy (in eV·Å⁻²). | ||
- **`final_energy`** (*float*): Final lattice energy (in eV·Å⁻²). | ||
- **`energyslope`** (*float*): Slope of the lattice energy over the number of events (in eV·Å⁻²·step⁻¹). A high value may indicate that the simulation has not reached steady-state. | ||
- **`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. | ||
|
||
### Molecules consumed/produced and TOF | ||
### Gas production and TOF | ||
|
||
- **`production`** (*dict*): Gas species produced over time (in molecules). Example: `kmc_output.production['CO']`. | ||
- **`total_production`** (*dict*): Total number of gas species produced (in molecules). Example: `kmc_output.total_production['CO']`. | ||
- **`tof`** (*dict*): TOF of gas species (in molecules·s⁻¹·Å⁻²). Example: `kmc_output.tof['CO2']`. | ||
- **`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']`. | ||
|
||
### Coverage | ||
### Surface coverage | ||
|
||
- **`coverage`** (*dict*): Coverage of surface species over time (in %). Example: `kmc_output.coverage['CO']`. | ||
- **`av_coverage`** (*dict*): Average coverage of surface species (in %). Example: `kmc_output.av_coverage['CO']`. | ||
- **`total_coverage`** (*np.ndarray*): Total coverage of surface species over time (in %). | ||
- **`av_total_coverage`** (*float*): Average total coverage of surface species (in %). | ||
- **`dominant_ads`** (*str*): Most dominant surface species, used to plot kinetic phase diagrams. | ||
- **`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 | ||
|
||
- **`coverage_per_site_type`** (*dict*): Coverage of surface species per site type over time (in %). Example: `kmc_output.coverage_per_site_type['top']['CO']`. | ||
- **`av_coverage_per_site_type`** (*dict*): Average coverage of surface species per site type (in %). Example: `kmc_output.av_coverage_per_site_type['top']['CO']`. | ||
- **`total_coverage_per_site_type`** (*dict*): Total coverage of surface species per site type over time (in %). Example: `kmc_output.total_coverage_per_site_type['top']`. | ||
- **`av_total_coverage_per_site_type`** (*dict*): Average total coverage of surface species per site type (in %). Example: `kmc_output.av_total_coverage_per_site_type['top']`. | ||
- **`dominant_ads_per_site_type`** (*dict*): Most dominant surface species per site type, used to plot kinetic phase diagrams. Example: `kmc_output.dominant_ads_per_site_type['top']`. | ||
To gain more detailed insight, you can also access coverage data broken down by site type: | ||
|
||
## 3. Methods | ||
- **`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. | ||
|
||
--- | ||
|
||
## Methods | ||
|
||
### `get_selectivity()` | ||
|
||
Calculate the selectivity of the main product over side products. | ||
The `get_selectivity()` method calculates the selectivity of a main product relative to other side products, providing a measure of reaction specificity. | ||
|
||
**Parameters:** | ||
|
||
- **`main_product`** (*str*): Name of the main product. | ||
- **`side_products`** (*list of str*): Names of the side products. | ||
- **`main_product`** (*str*): Main product species name. | ||
- **`side_products`** (*list of str*): List of side product species names. | ||
|
||
**Returns:** | ||
|
||
- (*float*): The selectivity of the main product (in %) over the side products. | ||
- (*float*): Selectivity (in %) of the main product over the side products. | ||
|
||
**Notes:** | ||
|
||
The selectivity is calculated as: | ||
The selectivity is defined as: | ||
|
||
```python | ||
selectivity = (TOF_main_product / (TOF_main_product + sum(TOF_side_products))) * 100 | ||
``` | ||
|
||
If the total TOF is zero, the selectivity is returned as `NaN`. | ||
If the denominator is zero (no products formed), the method returns `NaN`. | ||
|
||
**Example:** | ||
|
||
```python | ||
selectivity = kmc_output.get_selectivity(main_product='CH4', side_products=['CO2', 'CH3OH']) # in % | ||
selectivity = kmc_output.get_selectivity(main_product='CH4', side_products=['CO2', 'CH3OH']) | ||
print(f"CH4 Selectivity: {selectivity:.2f} %") | ||
``` | ||
|
||
## 4. Print simulation data (examples) | ||
--- | ||
|
||
### TOF | ||
## Examples of usage | ||
|
||
### Printing TOFs | ||
|
||
```python | ||
for gas_species in kmc_output.gas_specs_names: | ||
tof = kmc_output.tof[gas_species] | ||
print(f"TOF {gas_species}: {tof:.3e} molecules·s⁻¹·Å⁻²") | ||
print(f"TOF of {gas_species}: {tof:.3e} molecules·s⁻¹·Å⁻²") | ||
``` | ||
|
||
### Selectivity | ||
### Checking selectivity | ||
|
||
```python | ||
selectivity = kmc_output.get_selectivity(main_product='CH4', side_products=['CO2', 'CH3OH']) | ||
print(f"Selectivity for CH4: {selectivity:.2f} %") | ||
``` | ||
|
||
### Average coverage per total number of sites | ||
### Average coverage on total sites | ||
|
||
```python | ||
for surf_species in kmc_output.surf_specs_names: | ||
coverage = kmc_output.av_coverage[surf_species] | ||
print(f"Average coverage of {surf_species}: {coverage:.3f} % of total sites") | ||
avg_cov = kmc_output.av_coverage[surf_species] | ||
print(f"Average coverage of {surf_species}: {avg_cov:.3f} % of total sites") | ||
``` | ||
|
||
### Average coverage per site type | ||
|
||
```python | ||
for site_type in kmc_output.site_types: | ||
for surf_species in kmc_output.coverage_per_site_type[site_type]: | ||
coverage = kmc_output.av_coverage_per_site_type[site_type][surf_species] | ||
print(f"Average coverage of {surf_species} on {site_type} sites: {coverage:.3f} %") | ||
for stype in kmc_output.site_types: | ||
for sps in kmc_output.av_coverage_per_site_type[stype]: | ||
avg_cov = kmc_output.av_coverage_per_site_type[stype][sps] | ||
print(f"Average coverage of {sps} on {stype} sites: {avg_cov:.3f} %") | ||
``` | ||
|
||
### Energy slope | ||
|
||
```python | ||
print(f"Energy slope: {kmc_output.energyslope:.3e} eV·Å⁻²·step⁻¹") | ||
``` | ||
``` |
Oops, something went wrong.