diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ca9afd5..68ff807 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,7 +50,7 @@ jobs: python-version: '3.11' - run: | python -m pip install --upgrade pip - pip install numpy pandas scipy + pip install -e . - run: python tests/test_accuracy.py API: @@ -62,7 +62,7 @@ jobs: python-version: '3.11' - run: | python -m pip install --upgrade pip - pip install numpy pandas scipy + pip install -e . - run: python tests/test_api.py -v Source-Docstrings: @@ -74,8 +74,33 @@ jobs: python-version: '3.11' - run: | python -m pip install --upgrade pip + pip install -e . - run: python tests/test_source_docstrings.py -v + Utilities: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.11' + - run: | + python -m pip install --upgrade pip + pip install -e '.[dev]' + - run: python -m pytest tests/test_utilities.py -v + + Hydrocarbon-Identification: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.11' + - run: | + python -m pip install --upgrade pip + pip install -e '.[dev]' + - run: python -m pytest tests/test_hc_identification.py -v -s + Exporting-Scripts: runs-on: ubuntu-latest steps: @@ -85,19 +110,6 @@ jobs: python-version: '3.11' - run: | python -m pip install --upgrade pip - pip install numpy pandas scipy - - name: Export4Pele - individual component export - run: python source/Export4Pele.py --fuel_name posf10264 - - name: Export4Pele - mixture export with GCM model - run: python source/Export4Pele.py --fuel_name posf10264 --export_mix True - - name: Export4Pele - mixture export with MP model - run: python source/Export4Pele.py --fuel_name posf10264 --export_mix True --liq_prop_model mp - - name: Export4Pele - mixture export with CGS units - run: python source/Export4Pele.py --fuel_name posf10264 --export_mix True --units cgs - - name: Export4Pele - single deposit species - run: python source/Export4Pele.py --fuel_name posf10264 --dep_fuel_names POSF10264 - - name: Export4Converge - individual component export - run: python source/Export4Converge.py --fuel_name posf10264 - - name: Export4Converge - mixture export - run: python source/Export4Converge.py --fuel_name posf10264 --export_mix 1 --temp_min 280 --temp_max 400 --temp_step 10 + pip install -e . + - run: python tests/test_exporters.py diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 382605a..33aad6d 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -32,17 +32,17 @@ jobs: - name: Install dependencies run: | - pip install sphinx sphinx_rtd_theme myst_parser sphinxcontrib-bibtex pandas scipy + pip install -e '.[dev]' - name: Build docs run: | - sphinx-build -b html -W docs _build + sphinx-build -W -b html docs docs/_build/html - name: Upload artifact (for PR preview or later steps) uses: actions/upload-artifact@v4 with: name: site - path: _build + path: docs/_build/html Deploy-Docs: if: github.event_name == 'push' diff --git a/.gitignore b/.gitignore index fa440e7..31587ed 100644 --- a/.gitignore +++ b/.gitignore @@ -6,5 +6,20 @@ _build* generated* sprayPropsGCM* mixturePropsGCM* +exportData +# Python packaging +*.egg-info/ +dist/ +build/ +*.egg +*.whl +# Virtual environments +.env +env/ +venv/ + +# Figures from plotting tools +composition_*.png +mixture_*.png diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 0000000..a281472 --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,53 @@ +This PR makes several improvements to the FuelLib project's installation, documentation, and CI workflows. The main changes include updating installation instructions and documentation to reflect new CLI tools and development workflows, switching CI and documentation builds to use editable/development installs, and modernizing the command-line exporter interface. Additionally, a new publishing guide has been added, and Sphinx documentation references and paths have been updated for consistency. + +## Major Changes + +### Module Organization & Architecture +- **Split monolithic `FuelLib.py` into modules:** + - `constants.py` - Physical constants (k_B, N_A) + - `convert.py` - Temperature and unit conversions + - `utility.py` - Mixture properties and droplet calculations + - `fuel.py` - Main Fuel class for GCM calculations +- **Reorganized repository structure for proper Python packaging:** + - Renamed `source` -> `fuellib` and added a `pyproject.toml` for distribution via pip and conda with proper entry point configuration + - Created `fuellib/cli/` subpackage containing all command-line tools + - Improved package discovery and installation with `pip install -e .`, `pip install -e '.[dev]'`, and `pip install fuellib` + - Reworked the antiquated paths structure for managing paths between data and scripts. Users only need to `import fuellib as fl` provided a `pip install`. + +### CLI Tools Expansion & Organization +**New CLI Commands:** +- `fl-C2K`, `fl-K2C` - Celsius/Kelvin conversion utilities +- `fl-C2F`, `fl-F2C`, `fl-F2K`, `fl-K2F` - Additional temperature conversions +- `fl-eps2K` - Lennard-Jones epsilon to characteristic temperature conversion +- `fl-export-converge` - Export mixture properties for Converge CFD simulations +- `fl-export-pele` - Export properties for PelePhysics simulations +- `fl-plt-comp` - Composition plotting +- `fl-plt-props` - Properties plotting +- `fl-fuels` - List available fuels with metadata support + +### Testing Improvements +- **New `test_exporters.py`:** Comprehensive integration tests for export commands (7 tests) +- **Updated `test_source_docstrings.py`:** Now validates docstrings for all public API modules +- `test_utilities.py` - Unit tests for utility functions and CLI temperature conversion commands +- `test_hc_identification.py` - Unit tests for hydrocarbon classification logic +- Simplified CI exporter job from 8 individual steps to single `test_exporters.py` call +- Total test suite: 40 tests, all passing + +### Documentation & Bug Fixes +- Fixed CSV file path in `fuelprops.rst`: `../../fuelData/` → `../fuellib/data/fuelData/` +- Updated `sourcecode.rst` to reflect new file organization +- Added Sphinx docstring comments to `constants.py` and `fuel.py` attributes +- Fixed GitHub Actions failures related to decomposition metadata +- Fixed error handling for Jet A and cycloaromatic compounds + +### CI/CD Modernization +- Switched to editable/development installs (`pip install -e .` and `pip install -e '.[dev]'`) +- Updated GitHub Actions workflows to use new installation methods + +## Breaking Changes (v3.0.0) + +Functions moved from `fuellib` namespace to submodules: + +- **Temperature conversions:** `fl.C2K()` → `fl.convert.C2K()` +- **Utility functions:** `fl.mixing_rule()` → `fl.utility.mixing_rule()` +- **Constants:** `fl.k_B` still works, but `fl.constants.k_B` recommended \ No newline at end of file diff --git a/README.md b/README.md index 9d3ae60..cb749e4 100644 --- a/README.md +++ b/README.md @@ -15,37 +15,74 @@ If you use FuelLib in your research, please cite the following software record: Montgomery, David, Appukuttan, Sreejith, Yellapantula, Shashank, Perry, Bruce, and Binswanger, Adam. FuelLib (Fuel Library) [SWR-25-26]. Computer Software. https://github.com/NatLabRockies/FuelLib. USDOE Office of Energy Efficiency and Renewable Energy (EERE), Office of Sustainable Transportation. Vehicle Technologies Office (VTO). 27 Feb. 2025. Web. doi:10.11578/dc.20250317.1. ~~~ -## Python Environment -The following conda environment is required to run this code: -~~~ -conda create --name fuellib-env matplotlib pandas scipy black=26.3.1 -~~~ +## Installation + +### Option 1: Install from PyPI (Recommended) + +The easiest way to install FuelLib is via pip: + +```bash +pip install fuellib +``` + +This will make the command-line tools available, including: +- `fl-export-pele` and `fl-export-converge` for exporting fuel properties +- `fl-plt-props` and `fl-plt-comp` for plotting fuel composition and properties +- `fl-fuels` for listing available fuels +- Temperature and unit conversion utilities + +### Option 2: Development Installation (For Contributors) + +Clone the repository and install in editable mode: + +```bash +git clone https://github.com/NatLabRockies/FuelLib.git +cd FuelLib +pip install -e '.[dev]' # Install with development tools (docs, testing, formatting) +``` -## Running the Code -This repository includes multiple tutorials of ways to use FuelLib. We recommend starting with the basic tutorial, `tutorials/basic.py`, which is documented at [https://NatLabRockies.github.io/FuelLib/tutorials.html#introduction]. The script `tutorials/mixtureProperties.py` calculates a given mixture's density, viscosity and vapor pressure from GC x GC data. The results are plotted against data from NIST and [Edwards (2020)](https://apps.dtic.mil/sti/pdfs/AD1093317.pdf). +See the [Contributing](https://NatLabRockies.github.io/FuelLib/development.html) page for more detailed setup instructions and contribution guidelines. + +### Optional: Use a Dedicated Conda Environment + +For better dependency isolation, you can create a conda environment first: + +```bash +conda create --name fuellib-env python +conda activate fuellib-env +pip install fuellib +``` + +## Library Usage +This repository includes multiple tutorials of ways to use FuelLib. We recommend starting with the basic tutorial, [`tutorials/basic.py`](https://github.com/NatLabRockies/FuelLib/blob/main/tutorials/basic.py), which is documented at [https://natlabrockies.github.io/FuelLib/tutorials-basic.html](https://natlabrockies.github.io/FuelLib/tutorials-basic.html). The script [`tutorials/mixtureProperties.py`](https://github.com/NatLabRockies/FuelLib/blob/main/tutorials/mixtureProperties.py) calculates a given mixture's density, viscosity and vapor pressure from GC x GC data. The results are plotted against data from NIST and [Edwards (2020)](https://apps.dtic.mil/sti/pdfs/AD1093317.pdf). + +### Command-Line Tools +After installing FuelLib using one of the methods above, you have access to several command-line tools for plotting, unit conversion, and exporting fuel data. A comprehensive list is provided in the documentation at [https://natlabrockies.github.io/FuelLib/tutorials-cli.html](https://natlabrockies.github.io/FuelLib/tutorials-cli.html). # Contributing -New contributions are always welcome. If you have an idea for a new feature follow these steps: +New contributions are always welcome! For detailed contribution guidelines, installation instructions, and development setup, see the [Contributing](https://NatLabRockies.github.io/FuelLib/development.html) page in the documentation. + +Quick start: 1. Fork the main repository 2. Create a `newFeature` branch that contains your changes 3. Update the sphinx documentation in `newFeature` -4. Format the source code files using the [Black code formatter](https://github.com/psf/black) by running the following command: - (CI currently uses Black version `26.3.1`; use the same version locally.) - ~~~ - find . -name "*.py" -print0 | xargs -0 black - ~~~ -5. Open a Pull Request (PR) from `newFeature` on your fork to branch `main` FuelLib repository. +4. Install development dependencies: `pip install -e '.[dev]'` +5. Format the source code files using the provided CLI command: `fl-format` +6. Run tests and build documentation locally to verify your changes +7. Open a Pull Request (PR) from `newFeature` on your fork to branch `main` FuelLib repository. ## Sphinx Documentation -This repository uses [Sphinx](https://www.sphinx-doc.org/en/master/usage/quickstart.html) to generate documentation. This requires the following Conda environment: +This repository uses [Sphinx](https://www.sphinx-doc.org/en/master/usage/quickstart.html) to generate documentation. + +To build the documentation, first install FuelLib with development support: ~~~ -conda create --name sphinx-env sphinx sphinx_rtd_theme sphinxcontrib-bibtex pandas scipy +pip install -e ".[dev]" ~~~ -To view the documentation locally, build the html using the following: +Then use the provided CLI command: ~~~ -cd FuelLib/docs/ -sphinx-build -M html . _build/ +fl-build-docs ~~~ -You should now be able to view the html by opening `FuelLib/docs/_build/html/index.html` in a web browser. + +The HTML documentation will be generated in `docs/_build/html/`. Open `docs/_build/html/index.html` in your web browser to view it. diff --git a/customFuels b/customFuels new file mode 160000 index 0000000..00a19ae --- /dev/null +++ b/customFuels @@ -0,0 +1 @@ +Subproject commit 00a19ae44d8a706b4fe5a4e5dec9ba6e3b8af30a diff --git a/docs/conf.py b/docs/conf.py index f7c8888..2b6e702 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -5,7 +5,10 @@ import os import sys -sys.path.insert(0, os.path.abspath("../source")) +# Add parent directory to path so we can import fuellib +DOCS_DIR = os.path.abspath(os.path.dirname(__file__)) +PROJECT_ROOT = os.path.abspath(os.path.join(DOCS_DIR, "..")) +sys.path.insert(0, PROJECT_ROOT) # -- Project information ----------------------------------------------------- diff --git a/docs/development.rst b/docs/development.rst new file mode 100644 index 0000000..016541c --- /dev/null +++ b/docs/development.rst @@ -0,0 +1,63 @@ +Contributing to FuelLib +======================= + +We welcome contributions! This page covers how to set up your development environment, make changes, and submit pull requests. + +Development Setup +----------------- + +Clone the repository and install in editable mode with development dependencies: + +.. code-block:: bash + + git clone https://github.com/NatLabRockies/FuelLib.git + cd FuelLib + pip install -e '.[dev]' + +This installs FuelLib with all development tools: + +- **Documentation:** Sphinx, sphinx-rtd-theme, sphinxcontrib-bibtex +- **Code formatting:** Black +- **Testing:** pytest + +Optional: Conda Environment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To use a specific conda environment: + +.. code-block:: bash + + conda create --name fuellib-env python numpy pandas scipy matplotlib + conda activate fuellib-env + pip install -e '.[dev]' + +Contributing Guidelines +----------------------- + +New contributions are always welcome! To contribute: + +1. Fork the main repository on GitHub +2. Create a new branch for your feature: ``git checkout -b newFeature`` +3. Make your changes and update documentation as needed +4. Ensure development dependencies are installed (see Development Setup above) +5. Format your code using Black ``fl-format`` + +6. Run tests to verify your changes. See `.github/workflows/ci.yml` for the most up-to-date list of tests run in CI +7. Open a Pull Request (PR) from your fork to the main FuelLib repository + +Building and Viewing Documentation Locally +------------------------------------------- + +To build the documentation after installing with ``pip install -e '.[dev]'``: + +.. code-block:: bash + + fl-build-docs + +The built documentation will be in ``docs/_build/html/``. Open ``index.html`` in your browser to view it. + +To clean the build artifacts: + +.. code-block:: bash + + fl-clean-docs diff --git a/docs/figures/composition_posf10325.png b/docs/figures/composition_posf10325.png new file mode 100644 index 0000000..3aac230 Binary files /dev/null and b/docs/figures/composition_posf10325.png differ diff --git a/docs/figures/mixture_properties_posf10264_posf10325_posf10289.png b/docs/figures/mixture_properties_posf10264_posf10325_posf10289.png new file mode 100644 index 0000000..b919f21 Binary files /dev/null and b/docs/figures/mixture_properties_posf10264_posf10325_posf10289.png differ diff --git a/docs/fuelprops.rst b/docs/fuelprops.rst index 784395a..fe65546 100644 --- a/docs/fuelprops.rst +++ b/docs/fuelprops.rst @@ -46,7 +46,7 @@ Table of GCM properties :math:`\Delta H_{v,\textit{stp},i}` J/mol :math:`h_{v1k}`, :math:`h_{v2j}` kJ/mol Enthalpy of vaporization at 298 K\ :footcite:p:`constantinou_new_1994`. :math:`\omega_i` 1 :math:`\omega_{1k}`, :math:`\omega_{2j}` 1 Acentric factor\ :footcite:p:`constantinou_estimation_1995`. :math:`V_{m,\textit{stp},i}` m\ :sup:`3`\ /mol :math:`v_{m1k}`, :math:`v_{m2j}` m\ :sup:`3`\ /kmol Liquid molar volume at 298 K\ :footcite:p:`constantinou_estimation_1995`. - :math:`C_{p,i}` J/mol/K :math:`C_{pA1_k}`, :math:`C_{pA2_k}`,... J/mol/K Specific heat capacity\ :footcite:p:`nielsen_molecular_1998` \ :footcite:p:`poling_properties_2001`. + :math:`C_{p,i}` J/mol/K :math:`C_{pA1_k}`, :math:`C_{pA2_k}`,... J/mol/K Molar specific heat capacity\ :footcite:p:`nielsen_molecular_1998` \ :footcite:p:`poling_properties_2001`. ==================================== ===================== =========================================== ==================== =========================================================== .. _eq-GCM-properties: @@ -113,7 +113,7 @@ provided :math:`T` in K unless noted otherwise. :math:`L_{v,i}` J/kg Temperature-adjusted latent heat of vaporization at 298 K\ :footcite:p:`govindaraju_group_2016`. :math:`V_{m,i}` m\ :sup:`3`\ /mol Temperature-adjusted liquid molar volume\ :footcite:p:`rackett_equation_1970` \ :footcite:p:`yamada_saturated_1973` \ :footcite:p:`govindaraju_group_2016`. :math:`\rho_i` kg/m\ :sup:`3` Density - :math:`C_{\ell,i}` J/kg/K Liquid specific heat capacity\ :footcite:p:`govindaraju_group_2016`. + :math:`C_{\ell,i}` J/kg/K Mass specific heat capacity. :math:`p_{sat,i}` Pa Saturated vapor pressure\ :footcite:p:`lee_generalized_1975` \ :footcite:p:`ambrose_vapour_1989`. :math:`\sigma_i` N/m Surface tension\ :footcite:p:`brock_surface_1955`. :math:`\lambda_i` W/m/K Thermal conductivity\ :footcite:p:`poling_properties_2001`. @@ -138,7 +138,7 @@ provided :math:`T` in K unless noted otherwise. Kinematic viscosity ^^^^^^^^^^^^^^^^^^^ -.. automethod:: FuelLib.fuel.viscosity_kinematic +.. automethod:: fuellib.fuel.viscosity_kinematic :noindex: The kinematic viscosity of the *i-th* compound of the fuel, @@ -159,7 +159,7 @@ Liquids\ :footcite:p:`viswanath_viscosity_2007`) provided :math:`T` in :math:`^{ Latent heat of vaporization ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automethod:: FuelLib.fuel.latent_heat_vaporization +.. automethod:: fuellib.fuel.latent_heat_vaporization :noindex: The latent heat of vaporization for each compound at standard pressure and @@ -178,7 +178,7 @@ temperature\ :footcite:p:`govindaraju_group_2016`: Liquid molar volume ^^^^^^^^^^^^^^^^^^^ -.. automethod:: FuelLib.fuel.molar_liquid_vol +.. automethod:: fuellib.fuel.molar_liquid_vol :noindex: The liquid molar volume is calculated at a specific temperature :math:`T` using @@ -203,7 +203,7 @@ where Density ^^^^^^^ -.. automethod:: FuelLib.fuel.density +.. automethod:: fuellib.fuel.density :noindex: The density of the *i-th* compound is given by @@ -212,13 +212,13 @@ The density of the *i-th* compound is given by \rho_i = \frac{M_{w,i}}{V_{m,i}}. -Liquid specific heat capacity -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Mass specific heat capacity of the liquid +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automethod:: FuelLib.fuel.Cl +.. automethod:: fuellib.fuel.Cl :noindex: -The liquid specific heat capacity for each compound at standard pressure temperature is calculated from the specific heat capacity as: +The mass specific heat capacity for each compound at standard pressure temperature is calculated from the molar specific heat capacity as: .. math:: C_{\ell,i} = \dfrac{C_{p,i}}{M_{w,i}} @@ -228,7 +228,7 @@ The liquid specific heat capacity for each compound at standard pressure tempera Saturated vapor pressure ^^^^^^^^^^^^^^^^^^^^^^^^ -.. automethod:: FuelLib.fuel.psat +.. automethod:: fuellib.fuel.psat :noindex: The saturated vapor pressure for each compound is calculated as a function of @@ -260,7 +260,7 @@ The Ambrose-Walton\ :footcite:p:`ambrose_vapour_1989` correlation sets: with :math:`\tau_i = 1 - T_{r,i}`. -.. automethod:: FuelLib.fuel.psat_antoine_coeffs +.. automethod:: fuellib.fuel.psat_antoine_coeffs :noindex: Users also have the option to return the coefficients from an Antoine fit based on @@ -279,7 +279,7 @@ for additional information. Surface tension ^^^^^^^^^^^^^^^ -.. automethod:: FuelLib.fuel.surface_tension +.. automethod:: fuellib.fuel.surface_tension :noindex: Surface tension for each compound is approximated using the relation: @@ -302,7 +302,7 @@ or by Curl and Pitzer\ :footcite:p:`poling_properties_2001` \ :footcite:p:`curl_ Thermal conductivity ^^^^^^^^^^^^^^^^^^^^ -.. automethod:: FuelLib.fuel.thermal_conductivity +.. automethod:: fuellib.fuel.thermal_conductivity :noindex: Thermal conductivity for each compound is computed according to the method of @@ -389,7 +389,7 @@ are used throughout this section. Conventional mixing rules ^^^^^^^^^^^^^^^^^^^^^^^^^ -.. autofunction:: FuelLib.mixing_rule +.. autofunction:: fuellib.utility.mixing_rule :noindex: While many of the mixture properties in FuelLib have a unique mixing rule, @@ -415,7 +415,7 @@ where :math:`Q_i` is the property of the *i-th* compound of the multicomponent m Mixture density ^^^^^^^^^^^^^^^ -.. automethod:: FuelLib.fuel.mixture_density +.. automethod:: fuellib.fuel.mixture_density :noindex: The mixture's density is calculated as: @@ -428,7 +428,7 @@ The mixture's density is calculated as: Mixture kinematic viscosity ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automethod:: FuelLib.fuel.mixture_kinematic_viscosity +.. automethod:: fuellib.fuel.mixture_kinematic_viscosity :noindex: The kinematic viscosity of the mixture is computed using the Kendall-Monroe\ :footcite:p:`kendall_viscosity_1917` @@ -453,7 +453,7 @@ The Arrhenius rule is: Mixture vapor pressure ^^^^^^^^^^^^^^^^^^^^^^ -.. automethod:: FuelLib.fuel.mixture_vapor_pressure +.. automethod:: fuellib.fuel.mixture_vapor_pressure :noindex: The vapor pressure of the mixture is calculated according to Raoult's law: @@ -462,7 +462,7 @@ The vapor pressure of the mixture is calculated according to Raoult's law: p_{v} = \sum_{i = 1}^{N_c} X_i \, p_{\textit{sat},i}. -.. automethod:: FuelLib.fuel.mixture_vapor_pressure_antoine_coeffs +.. automethod:: fuellib.fuel.mixture_vapor_pressure_antoine_coeffs :noindex: Users also have the option to return the coefficients from an Antoine fit based on @@ -481,7 +481,7 @@ for additional information. Mixture surface tension ^^^^^^^^^^^^^^^^^^^^^^^ -.. automethod:: FuelLib.fuel.mixture_surface_tension +.. automethod:: fuellib.fuel.mixture_surface_tension :noindex: The surface tension of the mixture is calculated using the :ref:`conventional-mixing-rules` @@ -494,7 +494,7 @@ Hugill and van Welsenes\ :footcite:p:`hugill_surface_1986`: Mixture thermal conductivity ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automethod:: FuelLib.fuel.mixture_thermal_conductivity +.. automethod:: fuellib.fuel.mixture_thermal_conductivity :noindex: The thermal conductivity of the mixture is calculated using the power law method of @@ -517,7 +517,7 @@ For ease of reference, the reference compounds and keys corresponding to a PeleP When provided, the PelePhysics keys can be used to link the compounds in FuelLib to species in PelePhysics simulations via ``Export4Pele.py`` as described in :ref:`Exporting to PelePhysics `. .. csv-table:: Reference compounds, chemical formulas, and corresponding PelePhysics keys by GCxGC bin. - :file: ../fuelData/refCompounds.csv + :file: ../fuellib/data/fuelData/refCompounds.csv :header-rows: 1 :align: center :widths: auto diff --git a/docs/index.rst b/docs/index.rst index 2280df7..132f040 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -14,22 +14,20 @@ The source code is available at `github.com/NatLabRockies/FuelLib `_. - Montgomery, David, Appukuttan, Sreejith, Yellapantula, Shashank, Perry, Bruce, and Binswanger, Adam. FuelLib (Fuel Library) [SWR-25-26]. Computer Software. https://github.com/NatLabRockies/FuelLib. USDOE Office of Energy Efficiency and Renewable Energy (EERE), Office of Sustainable Transportation. Vehicle Technologies Office (VTO). 27 Feb. 2025. Web. doi:10.11578/dc.20250317.1. +Or in BibTeX format: .. code-block:: bibtex - @misc{montgomery_fuellib_2025, + @misc{fuellib_2025, title = {FuelLib (Fuel Library) [SWR-25-26]}, author = {Montgomery, David and Appukuttan, Sreejith and Yellapantula, Shashank and Perry, Bruce and Binswanger, Adam}, - abstractNote = {FuelLib is a library that utilizes the group contribution method (GCM) for calculating thermodynamic properties of hydro-carbon jet fuels. FuelLib utilizes the tables and functions of the GCM as proposed by Constantinou and Gani (1994) and Constantinou, Gani and O'Connel (1995), with additional physical properties discussed in Govindaraju & Ihme (2016). The code is based on Pavan B. Govindaraju's Matlab implementation of the GCM, and has been expanded to include additional thermodynamic properties and mixture properties. The fuel library contains gas chromatography (GC x GC) data for a variety of fuels ranging from simple single component fuels to complex jet fuels. The GC x GC data for POSF jet fuels comes from Edwards (2020).}, doi = {10.11578/dc.20250317.1}, url = {https://doi.org/10.11578/dc.20250317.1}, howpublished = {[Computer Software] \url{https://doi.org/10.11578/dc.20250317.1}}, @@ -37,13 +35,38 @@ If you use FuelLib in your research, please cite the following software record: month = {feb} } +Installation +------------ + +The easiest way to install FuelLib is via pip: + +.. code-block:: bash + + pip install fuellib + +After installation, several command-line tools will be available for exporting fuel data and plotting fuel properties. See the `CLI Tutorials `_ for detailed usage examples and options. + +For more detailed information on a development setup, see the `Contributing `_ page. + +**Package Requirements** + +FuelLib requires: + +- numpy ≥1.19.0 +- pandas ≥1.0.0 +- scipy ≥1.5.0 +- matplotlib ≥3.0.0 + +Development tools (Sphinx, Black, pytest) are available for developers installing from source; see the installation instructions in the `Contributing `_ section. + .. toctree:: :maxdepth: 4 :includehidden: :caption: Contents: fuelprops - sourcecode tutorials + sourcecode + development .. footbibliography:: \ No newline at end of file diff --git a/docs/sourcecode.rst b/docs/sourcecode.rst index 84fa754..84fc942 100644 --- a/docs/sourcecode.rst +++ b/docs/sourcecode.rst @@ -9,23 +9,46 @@ FuelLib File Organization ------------------------- - **docs:** directory containing the documentation source files -- **fuelData:** - - **gcData:** directory containing a collection of GCxGC compositional data by weight percentages - - **groupDecompositionData:** directory containing a collection of functional group decompositions - - **propertiesData:** directory containing measurement or predicted data for validation (see *fuelData/dataReferences.md*) - **gcmTableData:** directory that contains the pre-tabulated group contributions -- **source:** directory containing the main source code files +- **fuellib:** main package directory containing: - - ``Export4Converge.py``: script that exports mixture properties over a range of user specified temperatures for use in Converge simulations. - - ``Export4Pele.py``: script that exports critical properties and initial mass fraction data for use in Pele simulations. - - ``FuelLib.py``: class for enabling GCM predictions + - ``fuel.py``: core :class:`fuel` class for Group Contribution Method calculations + - ``constants.py``: physical constants (Boltzmann, Avogadro) + - ``convert.py``: temperature conversion functions and Lennard-Jones calculations + - ``utility.py``: utility functions for mixture properties and droplet calculations + - ``_data_locator.py``: internal module for locating and validating fuel data directories + + - **data**: directory containing fuel data and metadata + + - **fuelData:** + - **gcData:** directory containing a collection of GCxGC compositional data by weight percentages + - **groupDecompositionData:** directory containing a collection of functional group decompositions + - **propertiesData:** directory containing measurement or predicted data used for validation + - ``fuel_metadata.yaml``: YAML file that maps fuel names to their decomposition files and optional metadata fields + + - **exporters:** subpackage with CLI exporters for generating fuel properties + + - ``converge.py``: exporter for Converge CFD simulations (CLI: ``fl-export-converge``) + - ``pele.py``: exporter for PelePhysics simulations (CLI: ``fl-export-pele``) + + - **cli:** subpackage with command-line interface tools for data conversion and analysis + + - ``temp_converter.py``: temperature conversion utilities + - ``transport_props_converter.py``: transport properties conversion utilities + - ``plotting.py``: plotting utilities for composition and properties + - ``fuel_manager.py``: fuel manager utility + - ``build_docs.py``: documentation builder utility + - ``clean_docs.py``: documentation cleaner utility + - ``format_code.py``: code formatter utility - **tests:** directory containing CI unit tests for FuelLib. The CI test checks if the cumulative error of property predictions of a new proposed model are less than or equal to the current model. - **baselinePredictions:** directory that contains baseline predictions and script ``generate_baseline.py`` for generating baseline predictions for CI testing. - ``test_accuracy.py``: unit test used in CI for verifying new model predictions preserve accuracy - ``test_source_docstrings.py``: documentation contract test that checks public source functions include required docstring fields (``:param:``, ``:type:``, ``:return:``, ``:rtype:``). - - ``test_api.py``: combined API/signature and function-evaluation test that checks public ``FuelLib.py`` module and class method signatures for unexpected API drift and runs representative FuelLib smoke evaluations. + - ``test_api.py``: combined API/signature and function-evaluation test that checks public fuellib module and class method signatures for unexpected API drift and runs representative FuelLib smoke evaluations. + - ``test_utilities.py``: unit test for utility functions and CLI commands including temperature conversion and transport property calculations. + - ``test_hc_identification.py``: unit test for hydrocarbon classification logic. - ``get_pred_and_data.py``: helper function used by ``test_accuracy.py`` and ``baselinePredictions/generate_baseline.py`` to compute predictions and load validation data. - **tutorials:** directory containing example scripts that demonstrate how to use FuelLib @@ -35,8 +58,6 @@ FuelLib File Organization - ``hefaBlends.py``: example script that calculates properties of HEFA:Jet-A blends - ``mixtureProperties.py``: validation script that calculates properties of single component fuels and mixture properties of multicomponent fuels. -- ``paths.py``: file that defines paths to various directories and files used in FuelLib - Public API ---------- @@ -53,4 +74,7 @@ Click on links below for the full auto-documentation of the API. .. autosummary:: :toctree: generated - FuelLib \ No newline at end of file + fuellib.fuel + fuellib.constants + fuellib.convert + fuellib.utility \ No newline at end of file diff --git a/docs/tutorials-basic.rst b/docs/tutorials-basic.rst index dfb2bcb..14bb8a0 100644 --- a/docs/tutorials-basic.rst +++ b/docs/tutorials-basic.rst @@ -8,28 +8,31 @@ provides a basic introduction to using FuelLib, including installation, required Download and Setup ^^^^^^^^^^^^^^^^^^ -Clone the FuelLib repository from GitHub: :: +Install FuelLib using pip: - git clone https://github.com/NatLabRockies/FuelLib.git +.. code-block:: bash -Create and activate a Conda environment, install the required dependencies: :: + pip install fuellib - conda create --name fuellib-env matplotlib pandas scipy - conda activate fuellib-env +The required dependencies will be installed automatically. -Change to the FuelLib/tutorials directory: :: +For information about contributing or installation for development, see the `Contributing `_ page. - cd FuelLib/tutorials +If you want to run the example scripts, you can either clone the repository or download individual tutorial files from the `tutorials `_ directory on GitHub. -Required Input Files and Decomposing Fuel Components -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Required Input Files +^^^^^^^^^^^^^^^^^^^^^ -FuelLib requires two input files for any given fuel, ````: +FuelLib comes with a variety of built-in fuels with pre-populated input files, but you can also add your own custom fuels by providing the required input files. Each fuel requires two input files: -- ``FuelLib/fuelData/gcData/_init.csv``: the initial weight percentage composition of the fuel components (must include columns "Compound" and "Weight %") -- ``FuelLib/fuelData/groupDecompositionData/.csv``: the fundamental group decomposition for each component of the fuel (must have columns for groups in the same order as `gcmTable `_) +- ``fuellib/data/fuelData/gcData/_init.csv``: the initial weight percentage composition of the fuel components (must include columns "Compound" and "Weight %") +- ``fuellib/data/fuelData/groupDecompositionData/.csv``: the fundamental group decomposition for each component of the fuel (must have columns for groups in the same order as `gcmTable `_) -These two required files must have the same number of rows and the same order of components. Many examples can be found in the `fuelData `_ directory. +These two required files must have the same number of rows and the same order of components. Many examples can be found in the `fuellib/data/fuelData `_ directory in the repository. When working with an installed package, prefer ``fuellib.get_fueldata_dir()`` to discover the local fuel-data directory instead of hard-coding package paths. + +**Fuel Metadata** + +A ``fuel_metadata.yaml`` file is required to define decomposition name mappings. This allows you to map multiple fuel variants to a shared group decomposition file. See the `Adding Custom Fuels `_ tutorial for details on the metadata file format and structure. Decomposing Fuel Components into Fundamental Groups ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -63,6 +66,12 @@ the remaining branch with a single CH3 group bonded to a CH2 group is not define | (1,5-dimethylhexyl)cyclohexane | 3 | 8 | 3 | ... | 1 | 1 | +--------------------------------+-------+-------+-------+-----+----------+-----------------+ +.. note:: + All group decomposition files must follow the groups defined in `gcmTable`_, there are :math:`N_{g1} = 78` + first-order groups and :math:`N_{g2} = 43` second order groups. The second-order groups start with the + branching structure `(CH3)2CH`. Not all branching structures are defined in the `gcmTable`_. We recommend + starting with `fuellib/data/fuelData/groupDecompositionData/refCompounds.csv` and adapting the decompositions and compounds for your fuel. + Basic Usage ^^^^^^^^^^^ @@ -75,14 +84,7 @@ as ``basic.py``. To begin, we will import the necessary modules and create a ``f .. code-block:: python - import os - import sys - - # Add the FuelLib directory to the Python path - FUELLIB_DIR = os.path.dirname(os.path.dirname(__file__)) - sys.path.append(FUELLIB_DIR) - import paths - import FuelLib as fl + import fuellib as fl # Create a fuel object for the fuel "heptane-decane" fuel = fl.fuel("heptane-decane") diff --git a/docs/tutorials-cli.rst b/docs/tutorials-cli.rst new file mode 100644 index 0000000..c863f46 --- /dev/null +++ b/docs/tutorials-cli.rst @@ -0,0 +1,94 @@ +Command-Line Interface (CLI) Tools +=================================== + +FuelLib provides command-line tools for plotting, unit conversion, and exporting fuel data. +For detailed usage of each tool, use the ``--help`` or ``-h`` flag with the command (e.g., ``fl-plt-comp --help``). + +Plotting +~~~~~~~~ + +The plotting CLI provides quick visualization of fuel composition and properties. The following commands are available: + +.. code-block:: bash + + fl-plt-comp -f FUEL_NAME [OPTIONS] # Plot composition + fl-plt-props -f FUEL_NAME [OPTIONS] # Plot properties vs temperature + +If experimental data is available for the fuel and it is properly linked in the ``fuel_metadata.yaml`` file, it will be included in the plots for comparison with GCM predictions. + +Examples: + +.. code-block:: bash + + fl-plt-comp -f posf10325 + fl-plt-props -f posf10264 posf10325 posf10289 + fl-plt-props -f my-fuel -dir customFuels/fuelData -p Density Viscosity -d + +The first two commands provide the following plots for the specified fuels: + +.. figure:: /figures/composition_posf10325.png + :width: 600pt + :align: center + + Compositional information of Jet A (POSF10325). + +.. figure:: /figures/mixture_properties_posf10264_posf10325_posf10289.png + :width: 600pt + :align: center + + Properties of conventional jet fuels JP-8 (POSF10264), Jet A (POSF10325), and JP-5 (POSF10289) against data from the Air Force Research Laboratory\ :footcite:p:`edwards_jet_2020`. Note that the data sets for thermal conductivity are very inconsistent, but they typically show linear decreases in thermal conductivity with temperature. + +Unit Conversion Tools +~~~~~~~~~~~~~~~~~~~~~~ + +**Temperature Conversion** + +.. code-block:: bash + + fl-C2K 25 # Celsius to Kelvin + fl-K2C 298.15 # Kelvin to Celsius + fl-C2F 25 # Celsius to Fahrenheit + fl-F2C 77 # Fahrenheit to Celsius + fl-F2K 77 # Fahrenheit to Kelvin + fl-K2F 298.15 # Kelvin to Fahrenheit + +**Lennard-Jones Parameters** + +Convert Lennard-Jones well depth from J/mol to characteristic temperature in Kelvin (for CHEMKIN chemical mechanisms): + +.. code-block:: bash + + fl-eps2K 1000 # epsilon (J/mol) to characteristic temperature (K) + +Fuel Management +~~~~~~~~~~~~~~~ + +Quick listing of available fuels: + +.. code-block:: bash + + fl-fuels # List fuels shipped with FuelLib + fl-fuels -dir customFuels # List custom fuels + +Export for CFD +~~~~~~~~~~~~~~ + +FuelLib provides exporters for generating fuel property files for use in CFD simulations. The following commands are available: + +.. code-block:: bash + + fl-export-pele -f FUEL_NAME [OPTIONS] # PelePhysics + fl-export-converge -f FUEL_NAME [OPTIONS] # CONVERGE + +Additional information and examples for using the exporters can be found in the `Exporting Properties for Pele `_ and `Exporting Properties for CONVERGE `_ tutorials. + +Developer Tools +~~~~~~~~~~~~~~~ + +Tools for development and documentation maintenance: + +.. code-block:: bash + + fl-build-docs # Build Sphinx documentation + fl-clean-docs # Clean generated documentation + fl-format # Format Python code with black diff --git a/docs/tutorials-custom-fuels.rst b/docs/tutorials-custom-fuels.rst new file mode 100644 index 0000000..5988732 --- /dev/null +++ b/docs/tutorials-custom-fuels.rst @@ -0,0 +1,117 @@ +Adding Custom Fuels +==================== + +This tutorial explains how to add custom fuels to FuelLib. Custom fuels allow you to use your own fuel composition and property data with the FuelLib calculations and plotting tools. + +Directory Structure +------------------- + +Create a fuel data directory with this structure: + +.. code-block:: text + + customFuels/ + ├── gcData/ + │ └── your_fuel_name_init.csv + ├── groupDecompositionData/ + │ └── your_fuel_name.csv + └── fuel_metadata.yaml + +**Required subdirectories:** + +- ``gcData/``: Contains GC×GC composition data (one file per fuel) +- ``groupDecompositionData/``: Contains functional group decomposition data (one file per fuel) + +**Required metadata:** + +- ``fuel_metadata.yaml``: Configuration file that maps fuel names to their decomposition files + +Metadata Configuration +---------------------- + +Each custom fuel directory must have a ``fuel_metadata.yaml`` file at the root of the directory. This file defines the mapping from fuel names to their group decomposition files. +At a minimum, each fuel entry must include the ``decomp_name`` field that specifies the name of the decomposition file (without the ``.csv`` extension) in the ``groupDecompositionData/`` directory as shown below. + +.. code-block:: yaml + + fuels: + your_fuel: + decomp_name: your_fuel + +Additional metadata can be included for documentation purposes, but is not required for FuelLib to function. The following fields are available for each fuel: + +.. code-block:: yaml + + fuels: + your_fuel: + name: Display Name for Your Fuel + category: Conventional|SATF|Simple + source: Citation or origin of fuel data + reference: URL to source paper + description: Brief description of the fuel + decomp_name: name_of_decomposition_file in ``groupDecompositionData/`` (without ``.csv`` extension) + props_data: Name of any related properties data file in ``propertiesData/`` (without ``.csv`` extension) + + +Note that you can assign the same decomposition to multiple fuel variants if they have identical bulk composition. + +GCxGC Composition Data +---------------------- + +Create a file named ``{fuel_name}_init.csv`` in the ``gcData/`` directory with fuel composition data. + +**Required columns:** + +- ``Compound``: Name of each component +- ``Weight %``: Weight percentage of each component + +**Example:** + +.. code-block:: text + + Compound,Weight % + n-Decane,60 + n-Dodecane,40 + +Group Decomposition Data +------------------------ + +Create a file named ``{decomp_name}.csv`` in the ``groupDecompositionData/`` directory with functional group decompositions for each compound. + +See the `Basic Usage tutorial `_ for detailed information on group decompositions. + + +Using Custom Fuels +------------------ + +Once your custom fuel directory is set up, you can use it like any built-in fuel by specifying the ``fuelDataDir`` when creating a fuel object: + +.. code-block:: python + + import fuellib as fl + + # Load a custom fuel + fuel = fl.fuel("new-satf", fuelDataDir="/path/to/customFuels") + + # Calculate the saturated vapor pressure at 320 K + T = 320 # K + p_sat_i = fuel.psat(T) + p_sat_mix = fuel.mixture_vapor_pressure(fuel.Y_0, T) + +Tips and Best Practices +----------------------- + +1. **Composition Normalization**: Weight percentages don't need to sum to exactly 100% - FuelLib normalizes them automatically. + +2. **Group Decomposition Accuracy**: Predictions depend heavily on decomposition quality. When possible you should validate individual compound properties against measured properties or NIST WebBook. + +3. **Fuel Variants**: Use ``decomp_name`` to map multiple fuel variants to the same decomposition file when they have identical compounds but different weight percentages. + + .. code-block:: yaml + + fuels: + fuel_1: + decomp_name: fuel_decomp_1_and_2 + + fuel_2: + decomp_name: fuel_decomp_1_and_2 diff --git a/docs/tutorials-export4converge.rst b/docs/tutorials-export-converge.rst similarity index 57% rename from docs/tutorials-export4converge.rst rename to docs/tutorials-export-converge.rst index 0a50c14..f2c9d99 100644 --- a/docs/tutorials-export4converge.rst +++ b/docs/tutorials-export-converge.rst @@ -1,7 +1,7 @@ Exporting Properties for Converge ---------------------------------- -The export script, ``Export4Converge.py`` generates property data files for use in Converge CFD simulations. +The export script, ``fl-export-converge``, generates property data files for use in Converge CFD simulations. There are two options for exporting data: 1. **Mixture Properties**: This option generates a csv file named ``mixturePropsGCM_.csv`` containing @@ -18,7 +18,7 @@ The properties include: - Latent heat of vaporization - Vapor pressure - Density -- Specific heat +- Mass specific heat - Thermal conductivity .. note:: @@ -28,15 +28,18 @@ The properties include: terminal output and should be considered when using the mixture properties in a simulation. This example walks through the process and the available options for exporting GCM-based properties for -"posf10325", which is conventional Jet-A, using the ``Export4Converge.py`` script. +"posf10325", which is conventional Jet-A, using the ``fl-export-converge`` command. Default Options ^^^^^^^^^^^^^^^ -From the ``FuelLib`` directory, run the following command in the terminal, noting that ``--fuel_name`` is the only required input: :: +After installing FuelLib with ``pip install fuellib``, run the following command in the terminal, noting that ``--fuel_name`` is the only required input: :: - cd FuelLib/source - python Export4Converge.py --fuel_name posf10325 + fl-export-converge --fuel_name posf10325 + +Or using the short option ``-f``: :: + + fl-export-converge -f posf10325 This generates the files for each compound and a composition description in ``FuelLib/exportData/posf10325`` with @@ -45,20 +48,23 @@ property predictions from 0 K to 1000 K for use in a Converge simulation. Additional Options ^^^^^^^^^^^^^^^^^^ -There are several additional options that can be specified when running the export script: +There are several additional options that can be specified when running the ``fl-export-converge`` command: -- ``--units``: Specify the units for the mixture properties. The default is "mks" but users can set the units to "cgs". -- ``--temp_min``: Specify the minimum temperature. The default is 0 K. -- ``--temp_max``: Specify the maximum temperature. The default is 1000 K. -- ``--temp_step``: Specify the temperature step size. The default is :math:`\Delta T = 10` K. -- ``--export_dir``: Specify the directory to export the file. The default is "FuelLib/exportData". -- ``--fuel_data_dir``: Specify the directory containing the fuel data files. The default is "FuelLib/fuelData". -- ``--export_mix``: Set this flag to export mixture properties only. If not set, individual component properties and composition are exported. +- ``-dir, --fuel_data_dir PATH``: Directory containing the fuel data files. Default: ``FuelLib/fuelData``. +- ``-u, --units {mks,cgs}``: Units for the properties. Default: ``mks``. +- ``-t, --temp_min K``: Minimum temperature for property calculations. Default: ``0``. +- ``-T, --temp_max K``: Maximum temperature for property calculations. Default: ``1000``. +- ``-s, --temp_step K``: Step size for temperature. Default: ``10``. +- ``-o, --export_dir PATH``: Directory to export the file. Default: ``./exportData``. +- ``-m, --export_mix {true,false}``: Export mixture properties only (no individual components). Default: ``false``. + +For example, run the following command to export mixture properties from 273 K to 550 K with 5 K steps: :: + + fl-export-converge -f posf10325 -m true -t 273 -T 550 -s 5 -For example, run the following command in the terminal: :: +Or with long options: :: - cd FuelLib/source - python Export4Converge.py --fuel_name posf10325 --export_mix True --temp_min 273 --temp_max 550 + fl-export-converge --fuel_name posf10325 --export_mix true --temp_min 273 --temp_max 550 --temp_step 5 This generates the file ``FuelLib/exportData/mixturePropsGCM_posf10325.csv`` with mixture diff --git a/docs/tutorials-export4pele.rst b/docs/tutorials-export-pele.rst similarity index 74% rename from docs/tutorials-export4pele.rst rename to docs/tutorials-export-pele.rst index 0e6abcb..e512d0a 100644 --- a/docs/tutorials-export4pele.rst +++ b/docs/tutorials-export-pele.rst @@ -16,7 +16,7 @@ and the original `PeleMP (MP) model 1,CH3CH3,CHCHO or CCHO,CH3COCH2,CH3COCH or CH3COC,Ccyclic(=0),ACCHO,CHCOOH or CCOOH,ACCOOH,CH3COOCH or CH3COOC,COCH2COO or COCHCOO or COCCOO, CO-O-CO,ACCOO,CHOH,COH,"CHm(OH)CHn(OH), m,n in (0,2)","CHm cyclic-OH, m in (0,1)","CHm(OH)CHn(NHp), m,n,p in (0,3)",CHm(NH2)CHn(NH2),"CHm cyclic-NHp-CHn cyclic, m,n,p in (0,2)","Chm=Chn-F, m,n in (0,2)",AC-O-CHm,"CHm cyclic-S-CHn cyclic, m,n in (0,2)","CHm=CHn—F, m,n in (0,2)","CHm=CHn—Br, m,n in (0,2)","CHm=CHn—I, m,n in (0,2)",ACBr,ACI,"CHm(NH2)-COOH, m,n in (0,2)" -Toluene,0,0,0,0,0,0,0,0,0,0,5,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C2-Benzene,1,0,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C3-Benzene,1,1,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C4-Benzene,1,2,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C5-Benzene,1,3,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C6-Benzene,1,4,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C7-Benzene,1,5,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C8-Benzene,1,6,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C9-Benzene,1,7,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Diaromatic-C10,0,0,0,0,0,0,0,0,0,0,8,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Diaromatic-C11,0,0,0,0,0,0,0,0,0,0,7,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Diaromatic-C12,1,0,0,0,0,0,0,0,0,0,7,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Diaromatic-C13,1,1,0,0,0,0,0,0,0,0,7,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C09,0,1,0,0,0,0,0,0,0,0,4,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C10,0,2,0,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C11,1,1,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C12,1,2,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C13,1,3,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C14,1,4,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C07-Isoparaffin,3,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C08-Isoparaffin,3,4,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C09-Isoparaffin,3,5,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C10-Isoparaffin,3,6,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C11-Isoparaffin,3,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C12-Isoparaffin,3,8,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C13-Isoparaffin,3,9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C14-Isoparaffin,3,10,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C15-Isoparaffin,3,11,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C16-Isoparaffin,3,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C17-Isoparaffin,3,13,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C18-Isoparaffin,3,14,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C19-Isoparaffin,3,15,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C20-Isoparaffin,3,16,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C07,2,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C08,2,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C09,2,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C10,2,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C11,2,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C12,2,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C13,2,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C14,2,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C15,2,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C16,2,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C17,2,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C18,2,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C07-Monocycloparaffin,1,5,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C08-Monocycloparaffin,1,6,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C09-Monocycloparaffin,1,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C10-Monocycloparaffin,1,8,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C11-Monocycloparaffin,1,9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C12-Monocycloparaffin,1,10,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C13-Monocycloparaffin,1,11,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C14-Monocycloparaffin,1,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C15-Monocycloparaffin,1,13,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C16-Monocycloparaffin,1,14,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C17-Monocycloparaffin,1,15,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C08-Dicycloparaffin,0,6,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C09-Dicycloparaffin,0,7,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C10-Dicycloparaffin,0,8,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C11-Dicycloparaffin,1,7,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C12-Dicycloparaffin,1,8,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C13-Dicycloparaffin,1,9,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C14-Dicycloparaffin,1,10,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C15-Dicycloparaffin,1,11,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C10-Tricycloparaffin,0,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C11-Tricycloparaffin,0,7,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C12-Tricycloparaffin,0,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 \ No newline at end of file diff --git a/fuelData/groupDecompositionData/posf10325.csv b/fuelData/groupDecompositionData/posf10325.csv deleted file mode 100644 index b0216f6..0000000 --- a/fuelData/groupDecompositionData/posf10325.csv +++ /dev/null @@ -1,68 +0,0 @@ -Compound,CH3,CH2,CH,C,CH2=CH,CH=CH,CH2=C,CH=C,C=C,CH2=C=CH,ACH,AC,ACCH3,ACCH2,ACCH,OH,ACOH,CH3CO,CH2CO,CHO,CH3COO,CH2COO,HCOO,CH3O,CH2O,CH-O,FCH2O,CH2NH2,CHNH2,CH3NH,CH2NH,CHNH,CH3N,CH2N,ACNH2,C5H4N,C5H3N,CH2CN,COOH,CH2CL,CHCL,CCL,CHCL2,CCL2,CCL3,ACCL,CH2NO2,CHNO2,ACNO2,CH2SH,I,Br,CH≡C,C≡C,CL—(C=C),ACF,HCON(CH2)2,CF3,CF2,CF,COO,CCL2F,HCCLF,CCLF2,Fspecial,CONH2,CONHCH3,CONHCH2,CON(CH3)2,CONCH3CH2,CON(CH2)2,C2H5O2,C2H4O2,CH3S,CH2S,CHS,C4H3S,C4H2S,(CH3)2CH,(CH3)3C,CH(CH3)CH(CH3),CH(CH3)C(CH3)2,C(CH3)2C(CH3)2,3 membered ring,4 membered ring,5 membered ring,6 membered ring,7 membered ring,"CHn=CHm—CHp=CHk k,n,m,p in (0,2)","CH3-CHm=CH, m in (0,1), n in (0,2)","CH2-CHm=CHn, m, n in (0,2)","CH-CHm=CHn or C-CHm=CHn, m,n m in (0,2)",Alicyclic side-chain CcyclicCm m > 1,CH3CH3,CHCHO or CCHO,CH3COCH2,CH3COCH or CH3COC,Ccyclic(=0),ACCHO,CHCOOH or CCOOH,ACCOOH,CH3COOCH or CH3COOC,COCH2COO or COCHCOO or COCCOO, CO-O-CO,ACCOO,CHOH,COH,"CHm(OH)CHn(OH), m,n in (0,2)","CHm cyclic-OH, m in (0,1)","CHm(OH)CHn(NHp), m,n,p in (0,3)",CHm(NH2)CHn(NH2),"CHm cyclic-NHp-CHn cyclic, m,n,p in (0,2)","Chm=Chn-F, m,n in (0,2)",AC-O-CHm,"CHm cyclic-S-CHn cyclic, m,n in (0,2)","CHm=CHn—F, m,n in (0,2)","CHm=CHn—Br, m,n in (0,2)","CHm=CHn—I, m,n in (0,2)",ACBr,ACI,"CHm(NH2)-COOH, m,n in (0,2)" -Toluene,0,0,0,0,0,0,0,0,0,0,5,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C2-Benzene,1,0,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C3-Benzene,1,1,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C4-Benzene,1,2,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C5-Benzene,1,3,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C6-Benzene,1,4,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C7-Benzene,1,5,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C8-Benzene,1,6,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C9-Benzene,1,7,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Diaromatic-C10,0,0,0,0,0,0,0,0,0,0,8,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Diaromatic-C11,0,0,0,0,0,0,0,0,0,0,7,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Diaromatic-C12,1,0,0,0,0,0,0,0,0,0,7,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Diaromatic-C13,1,1,0,0,0,0,0,0,0,0,7,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C09,0,1,0,0,0,0,0,0,0,0,4,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C10,0,2,0,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C11,1,1,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C12,1,2,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C13,1,3,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C14,1,4,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C07-Isoparaffin,3,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C08-Isoparaffin,3,4,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C09-Isoparaffin,3,5,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C10-Isoparaffin,3,6,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C11-Isoparaffin,3,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C12-Isoparaffin,3,8,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C13-Isoparaffin,3,9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C14-Isoparaffin,3,10,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C15-Isoparaffin,3,11,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C16-Isoparaffin,3,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C17-Isoparaffin,3,13,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C18-Isoparaffin,3,14,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C19-Isoparaffin,3,15,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C20-Isoparaffin,3,16,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C07,2,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C08,2,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C09,2,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C10,2,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C11,2,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C12,2,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C13,2,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C14,2,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C15,2,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C16,2,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C17,2,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C18,2,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C07-Monocycloparaffin,1,5,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C08-Monocycloparaffin,1,6,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C09-Monocycloparaffin,1,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C10-Monocycloparaffin,1,8,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C11-Monocycloparaffin,1,9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C12-Monocycloparaffin,1,10,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C13-Monocycloparaffin,1,11,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C14-Monocycloparaffin,1,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C15-Monocycloparaffin,1,13,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C16-Monocycloparaffin,1,14,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C17-Monocycloparaffin,1,15,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C08-Dicycloparaffin,0,6,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C09-Dicycloparaffin,0,7,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C10-Dicycloparaffin,0,8,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C11-Dicycloparaffin,1,7,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C12-Dicycloparaffin,1,8,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C13-Dicycloparaffin,1,9,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C14-Dicycloparaffin,1,10,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C15-Dicycloparaffin,1,11,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C10-Tricycloparaffin,0,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C11-Tricycloparaffin,0,7,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C12-Tricycloparaffin,0,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 \ No newline at end of file diff --git a/fuelData/groupDecompositionData/posf4658.csv b/fuelData/groupDecompositionData/posf4658.csv deleted file mode 100644 index b0216f6..0000000 --- a/fuelData/groupDecompositionData/posf4658.csv +++ /dev/null @@ -1,68 +0,0 @@ -Compound,CH3,CH2,CH,C,CH2=CH,CH=CH,CH2=C,CH=C,C=C,CH2=C=CH,ACH,AC,ACCH3,ACCH2,ACCH,OH,ACOH,CH3CO,CH2CO,CHO,CH3COO,CH2COO,HCOO,CH3O,CH2O,CH-O,FCH2O,CH2NH2,CHNH2,CH3NH,CH2NH,CHNH,CH3N,CH2N,ACNH2,C5H4N,C5H3N,CH2CN,COOH,CH2CL,CHCL,CCL,CHCL2,CCL2,CCL3,ACCL,CH2NO2,CHNO2,ACNO2,CH2SH,I,Br,CH≡C,C≡C,CL—(C=C),ACF,HCON(CH2)2,CF3,CF2,CF,COO,CCL2F,HCCLF,CCLF2,Fspecial,CONH2,CONHCH3,CONHCH2,CON(CH3)2,CONCH3CH2,CON(CH2)2,C2H5O2,C2H4O2,CH3S,CH2S,CHS,C4H3S,C4H2S,(CH3)2CH,(CH3)3C,CH(CH3)CH(CH3),CH(CH3)C(CH3)2,C(CH3)2C(CH3)2,3 membered ring,4 membered ring,5 membered ring,6 membered ring,7 membered ring,"CHn=CHm—CHp=CHk k,n,m,p in (0,2)","CH3-CHm=CH, m in (0,1), n in (0,2)","CH2-CHm=CHn, m, n in (0,2)","CH-CHm=CHn or C-CHm=CHn, m,n m in (0,2)",Alicyclic side-chain CcyclicCm m > 1,CH3CH3,CHCHO or CCHO,CH3COCH2,CH3COCH or CH3COC,Ccyclic(=0),ACCHO,CHCOOH or CCOOH,ACCOOH,CH3COOCH or CH3COOC,COCH2COO or COCHCOO or COCCOO, CO-O-CO,ACCOO,CHOH,COH,"CHm(OH)CHn(OH), m,n in (0,2)","CHm cyclic-OH, m in (0,1)","CHm(OH)CHn(NHp), m,n,p in (0,3)",CHm(NH2)CHn(NH2),"CHm cyclic-NHp-CHn cyclic, m,n,p in (0,2)","Chm=Chn-F, m,n in (0,2)",AC-O-CHm,"CHm cyclic-S-CHn cyclic, m,n in (0,2)","CHm=CHn—F, m,n in (0,2)","CHm=CHn—Br, m,n in (0,2)","CHm=CHn—I, m,n in (0,2)",ACBr,ACI,"CHm(NH2)-COOH, m,n in (0,2)" -Toluene,0,0,0,0,0,0,0,0,0,0,5,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C2-Benzene,1,0,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C3-Benzene,1,1,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C4-Benzene,1,2,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C5-Benzene,1,3,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C6-Benzene,1,4,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C7-Benzene,1,5,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C8-Benzene,1,6,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C9-Benzene,1,7,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Diaromatic-C10,0,0,0,0,0,0,0,0,0,0,8,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Diaromatic-C11,0,0,0,0,0,0,0,0,0,0,7,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Diaromatic-C12,1,0,0,0,0,0,0,0,0,0,7,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Diaromatic-C13,1,1,0,0,0,0,0,0,0,0,7,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C09,0,1,0,0,0,0,0,0,0,0,4,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C10,0,2,0,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C11,1,1,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C12,1,2,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C13,1,3,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C14,1,4,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C07-Isoparaffin,3,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C08-Isoparaffin,3,4,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C09-Isoparaffin,3,5,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C10-Isoparaffin,3,6,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C11-Isoparaffin,3,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C12-Isoparaffin,3,8,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C13-Isoparaffin,3,9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C14-Isoparaffin,3,10,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C15-Isoparaffin,3,11,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C16-Isoparaffin,3,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C17-Isoparaffin,3,13,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C18-Isoparaffin,3,14,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C19-Isoparaffin,3,15,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C20-Isoparaffin,3,16,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C07,2,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C08,2,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C09,2,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C10,2,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C11,2,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C12,2,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C13,2,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C14,2,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C15,2,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C16,2,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C17,2,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -n-C18,2,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C07-Monocycloparaffin,1,5,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C08-Monocycloparaffin,1,6,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C09-Monocycloparaffin,1,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C10-Monocycloparaffin,1,8,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C11-Monocycloparaffin,1,9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C12-Monocycloparaffin,1,10,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C13-Monocycloparaffin,1,11,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C14-Monocycloparaffin,1,12,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C15-Monocycloparaffin,1,13,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C16-Monocycloparaffin,1,14,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C17-Monocycloparaffin,1,15,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C08-Dicycloparaffin,0,6,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C09-Dicycloparaffin,0,7,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C10-Dicycloparaffin,0,8,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C11-Dicycloparaffin,1,7,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C12-Dicycloparaffin,1,8,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C13-Dicycloparaffin,1,9,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C14-Dicycloparaffin,1,10,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C15-Dicycloparaffin,1,11,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C10-Tricycloparaffin,0,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C11-Tricycloparaffin,0,7,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -C12-Tricycloparaffin,0,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 \ No newline at end of file diff --git a/fuellib/__init__.py b/fuellib/__init__.py new file mode 100644 index 0000000..93d8f3d --- /dev/null +++ b/fuellib/__init__.py @@ -0,0 +1,41 @@ +""" +FuelLib: Fuel Library for Group Contribution Method calculations. + +FuelLib utilizes the Group Contribution Method (GCM) as proposed by Constantinou +and Gani (1994, 1995) to calculate thermodynamic and mixture properties of fuels. + +See :class:`fuel` for the main class and complete API documentation. +""" + +try: + from importlib.metadata import version + + __version__ = version("fuellib") +except Exception: + __version__ = "unknown" + +# Import fuel class +from .fuel import fuel + +# Import data locator functions +from ._data_locator import * + +# Import submodules for namespacing +from . import constants +from . import convert +from . import utility + +__all__ = [ + "fuel", + "get_data_dir", + "get_gcmtable_dir", + "get_fueldata_dir", + "get_fueldata_gc_dir", + "get_fueldata_decomp_dir", + "get_fueldata_props_dir", + "get_metadata_decomp_name", + "get_metadata_props_data", + "constants", + "convert", + "utility", +] diff --git a/fuellib/_data_locator.py b/fuellib/_data_locator.py new file mode 100644 index 0000000..c514cd7 --- /dev/null +++ b/fuellib/_data_locator.py @@ -0,0 +1,263 @@ +""" +Data locator module for FuelLib. + +This module provides functions to locate data directories and files embedded +within the fuellib package using importlib.resources. +""" + +import os +import sys + +if sys.version_info >= (3, 9): + from importlib.resources import files +else: + from importlib_resources import files + +try: + import yaml + + HAS_YAML = True +except ImportError: + HAS_YAML = False + + +__all__ = [ + "get_data_dir", + "get_gcmtable_dir", + "get_fueldata_dir", + "get_fueldata_gc_dir", + "get_fueldata_decomp_dir", + "get_fueldata_props_dir", + "get_metadata_decomp_name", + "get_metadata_props_data", +] + + +def _validate_fuel_data_dir(fuel_data_dir): + """ + Validate that a custom fuel data directory has required subdirectories. + + :param fuel_data_dir: Path to fuel data directory. + :type fuel_data_dir: str + :raises ValueError: If required subdirectories are missing. + """ + if fuel_data_dir is None: + return + + gc_dir = os.path.join(fuel_data_dir, "gcData") + decomp_dir = os.path.join(fuel_data_dir, "groupDecompositionData") + + if not os.path.isdir(gc_dir): + raise ValueError( + f"Custom fuel data directory is missing 'gcData' subdirectory:\n" + f" Expected: {gc_dir}" + ) + + if not os.path.isdir(decomp_dir): + raise ValueError( + f"Custom fuel data directory is missing 'groupDecompositionData' subdirectory:\n" + f" Expected: {decomp_dir}" + ) + + +def _get_props_dir_for_fueldata(fuel_data_dir): + """ + Get the properties directory for a fuel data directory, or None if it doesn't exist. + + :param fuel_data_dir: Path to fuel data directory. + :type fuel_data_dir: str + :return: Path to properties directory, or None if not found. + :rtype: str or None + """ + props_dir = os.path.join(fuel_data_dir, "propertiesData") + return props_dir if os.path.isdir(props_dir) else None + + +def get_data_dir(): + """ + Get the path to FuelLib's data directory. + + :return: Absolute path to the data directory. + :rtype: str + """ + data_ref = files("fuellib").joinpath("data") + # Convert to a concrete path + return str(data_ref) + + +def get_gcmtable_dir(): + """ + Get the path to the GCM table data directory. + + :return: Absolute path to gcmTableData directory. + :rtype: str + """ + return os.path.join(get_data_dir(), "gcmTableData") + + +def get_fueldata_dir(): + """ + Get the path to FuelLib's fuel data directory. + + :return: Absolute path to embedded fuelData directory. + :rtype: str + """ + return os.path.join(get_data_dir(), "fuelData") + + +def get_fueldata_gc_dir(): + """ + Get the path to FuelLib's GC data subdirectory. + + :return: Absolute path to embedded fuelData/gcData directory. + :rtype: str + """ + return os.path.join(get_fueldata_dir(), "gcData") + + +def get_fueldata_decomp_dir(): + """ + Get the path to FuelLib's group decomposition data subdirectory. + + :return: Absolute path to embedded fuelData/groupDecompositionData directory. + :rtype: str + """ + return os.path.join(get_fueldata_dir(), "groupDecompositionData") + + +def get_fueldata_props_dir(): + """ + Get the path to FuelLib's properties data subdirectory, or None if not found. + + This directory is optional. + + :return: Absolute path to embedded fuelData/propertiesData directory, or None if not found. + :rtype: str or None + """ + return _get_props_dir_for_fueldata(get_fueldata_dir()) + + +def get_metadata_decomp_name(fuel_name, fuel_data_dir=None): + """ + Load decomposition name mapping from fuel_metadata.yaml. + + :param fuel_name: Name of the fuel to look up. + :type fuel_name: str + :param fuel_data_dir: Directory containing fuel data. If None, uses embedded data. + :type fuel_data_dir: str, optional + :return: Decomposition name from metadata. + :rtype: str + :raises FileNotFoundError: If fuel_metadata.yaml is missing or fuel not found in metadata + """ + if not HAS_YAML: + raise ImportError( + "PyYAML is required to use custom fuels. Install it with: pip install pyyaml" + ) + + if fuel_data_dir is None: + # Use embedded data + metadata_file = os.path.join(get_fueldata_dir(), "fuel_metadata.yaml") + data_dir_display = "FuelLib embedded data" + else: + # Use custom data directory + metadata_file = os.path.join(fuel_data_dir, "fuel_metadata.yaml") + data_dir_display = fuel_data_dir + + if not os.path.exists(metadata_file): + raise FileNotFoundError( + f"fuel_metadata.yaml not found in {data_dir_display}.\n\n" + f"This file is required for all fuels. Please create:\n" + f" {metadata_file}\n\n" + f"Minimal example:\n" + f" fuels:\n" + f" {fuel_name}:\n" + f" decomp_name: {fuel_name} # or name of your .csv file in groupDecompositionData/\n\n" + f"See the 'Adding Custom Fuels' documentation for more details." + ) + + try: + with open(metadata_file, "r") as f: + data = yaml.safe_load(f) + except Exception as e: + raise ValueError( + f"Error parsing {metadata_file}:\n{e}\n\n" + f"Make sure the file is valid YAML with proper indentation." + ) + + if not data or "fuels" not in data: + raise ValueError( + f"Invalid metadata file {metadata_file}.\n" + f"File must contain a 'fuels' section.\n\n" + f"Example:\n" + f" fuels:\n" + f" {fuel_name}:\n" + f" decomp_name: {fuel_name}" + ) + + if fuel_name not in data["fuels"]: + available = list(data["fuels"].keys()) + raise KeyError( + f"Fuel '{fuel_name}' not found in {metadata_file}.\n\n" + f"Available fuels: {', '.join(available) if available else 'none'}\n\n" + f"Add an entry for '{fuel_name}':\n" + f" fuels:\n" + f" {fuel_name}:\n" + f" decomp_name: {fuel_name}" + ) + + fuel_meta = data["fuels"][fuel_name] + + if "decomp_name" not in fuel_meta: + raise ValueError( + f"Incomplete metadata for fuel '{fuel_name}' in {metadata_file}.\n\n" + f"Required fields:\n" + f" - decomp_name: Name of the .csv file in groupDecompositionData/ (without .csv extension)\n\n" + f"Current entry:\n" + f" {fuel_name}: {fuel_meta}" + ) + + return fuel_meta["decomp_name"] + + +def get_metadata_props_data(fuel_name, fuel_data_dir=None): + """ + Load properties data name mapping from fuel_metadata.yaml. + + Returns None if props_data is not specified in metadata (it's optional). + + :param fuel_name: Name of the fuel to look up. + :type fuel_name: str + :param fuel_data_dir: Directory containing fuel data. If None, uses embedded data. + :type fuel_data_dir: str, optional + :return: Properties data name from metadata, or None if not specified. + :rtype: str or None + :raises FileNotFoundError: If fuel_metadata.yaml is missing or fuel not found in metadata + """ + if not HAS_YAML: + raise ImportError( + "PyYAML is required to use custom fuels. Install it with: pip install pyyaml" + ) + + if fuel_data_dir is None: + # Use embedded data + metadata_file = os.path.join(get_fueldata_dir(), "fuel_metadata.yaml") + else: + # Use custom data directory + metadata_file = os.path.join(fuel_data_dir, "fuel_metadata.yaml") + + if not os.path.exists(metadata_file): + return None + + try: + with open(metadata_file, "r") as f: + data = yaml.safe_load(f) + except Exception: + return None + + if not data or "fuels" not in data or fuel_name not in data["fuels"]: + return None + + fuel_meta = data["fuels"][fuel_name] + + # Return props_data if present, otherwise None + return fuel_meta.get("props_data", None) diff --git a/fuellib/cli/__init__.py b/fuellib/cli/__init__.py new file mode 100644 index 0000000..f219016 --- /dev/null +++ b/fuellib/cli/__init__.py @@ -0,0 +1 @@ +"""Command-line utility tools for FuelLib.""" diff --git a/fuellib/cli/build_docs.py b/fuellib/cli/build_docs.py new file mode 100644 index 0000000..daab646 --- /dev/null +++ b/fuellib/cli/build_docs.py @@ -0,0 +1,66 @@ +""" +Build Sphinx documentation for FuelLib. + +This script builds the HTML documentation using Sphinx, handling the proper +setup of paths and environment variables needed for autodoc to work correctly. +""" + +import os +import sys +import subprocess + + +def main(): + """ + Build the FuelLib documentation. + + Changes to the docs directory and runs sphinx-build to generate HTML documentation. + """ + # Get the directory of this script (fuellib/cli) + cli_dir = os.path.dirname(os.path.abspath(__file__)) + + # Get the fuellib package directory (one level up from cli) + fuellib_dir = os.path.dirname(cli_dir) + + # Get the project root (one level up from fuellib package) + project_root = os.path.dirname(fuellib_dir) + + # Docs directory + docs_dir = os.path.join(project_root, "docs") + + # Ensure fuellib is in the Python path for autodoc + if project_root not in sys.path: + sys.path.insert(0, project_root) + + # Build command + build_cmd = [ + "sphinx-build", + "-M", + "html", + docs_dir, + os.path.join(docs_dir, "_build"), + ] + + print(f"Building documentation from {docs_dir}") + print(f"Command: {' '.join(build_cmd)}") + print() + + # Run sphinx-build + result = subprocess.run(build_cmd) + + if result.returncode == 0: + print() + print("=" * 80) + print("Documentation built successfully!") + print( + f"View the documentation at: {os.path.join(docs_dir, '_build', 'html', 'index.html')}" + ) + print("=" * 80) + else: + print() + print("Documentation build failed. Please check the errors above.") + sys.exit(result.returncode) + + +if __name__ == "__main__": + main() diff --git a/fuellib/cli/clean_docs.py b/fuellib/cli/clean_docs.py new file mode 100644 index 0000000..d95ef0e --- /dev/null +++ b/fuellib/cli/clean_docs.py @@ -0,0 +1,53 @@ +"""Remove Sphinx documentation build artifacts.""" + +import os +import shutil +import sys + + +def main(): + """ + Remove the documentation build directory and generated files. + + Cleans up the Sphinx build output in docs/_build/ and + generated documentation in docs/generated/ + """ + # Get the directory of this script (fuellib/cli) + cli_dir = os.path.dirname(os.path.abspath(__file__)) + + # Get the fuellib package directory (one level up from cli) + fuellib_dir = os.path.dirname(cli_dir) + + # Get the project root (one level up from fuellib package) + project_root = os.path.dirname(fuellib_dir) + + # Docs directory + docs_dir = os.path.join(project_root, "docs") + build_dir = os.path.join(docs_dir, "_build") + generated_dir = os.path.join(docs_dir, "generated") + + # Remove build directory + if os.path.exists(build_dir): + try: + shutil.rmtree(build_dir) + print(f"Removed documentation build directory: {build_dir}") + except Exception as e: + print(f"Error removing build directory: {e}", file=sys.stderr) + sys.exit(1) + else: + print(f"Build directory does not exist: {build_dir}") + + # Remove generated directory + if os.path.exists(generated_dir): + try: + shutil.rmtree(generated_dir) + print(f"Removed generated documentation directory: {generated_dir}") + except Exception as e: + print(f"Error removing generated directory: {e}", file=sys.stderr) + sys.exit(1) + else: + print(f"Generated directory does not exist: {generated_dir}") + + +if __name__ == "__main__": + main() diff --git a/fuellib/cli/format_code.py b/fuellib/cli/format_code.py new file mode 100644 index 0000000..60dbdba --- /dev/null +++ b/fuellib/cli/format_code.py @@ -0,0 +1,35 @@ +"""Format all Python source code using Black.""" + +import os +import subprocess +import sys + + +def main(): + """Run Black formatter on all Python files in the repository.""" + # Get the directory of this script (fuellib/cli) + cli_dir = os.path.dirname(os.path.abspath(__file__)) + + # Get the fuellib package directory (one level up from cli) + fuellib_dir = os.path.dirname(cli_dir) + + # Get the project root (one level up from fuellib package) + project_root = os.path.dirname(fuellib_dir) + + try: + # Call Black directly with the project root + # Black will recursively find and format all .py files + result = subprocess.run( + [sys.executable, "-m", "black", project_root], + check=True, + ) + sys.exit(result.returncode) + except subprocess.CalledProcessError as e: + sys.exit(e.returncode) + except Exception as e: + print(f"Error running black formatter: {e}", file=sys.stderr) + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/fuellib/cli/fuel_manager.py b/fuellib/cli/fuel_manager.py new file mode 100644 index 0000000..bc18933 --- /dev/null +++ b/fuellib/cli/fuel_manager.py @@ -0,0 +1,153 @@ +""" +Utilities for managing and querying the fuel library. + +This module provides tools for listing and discovering available fuels +in the FuelLib database, including source information and metadata. +""" + +import os +import argparse +import warnings +import fuellib as fl + +try: + import yaml + + HAS_YAML = True +except ImportError: + HAS_YAML = False + + +def load_fuel_metadata(fuel_data_dir=None): + """ + Load fuel metadata from YAML file if available. + + :param fuel_data_dir: Optional directory containing fuel data (parent of gcData/, + groupDecompositionData/, and fuel_metadata.yaml). + If None, loads from embedded FuelLib data. + :type fuel_data_dir: str, optional + :return: Dictionary of fuel metadata or empty dict if not available + :rtype: dict + """ + if not HAS_YAML: + return {} + + # Determine which metadata file to load + if fuel_data_dir is None: + # Load from embedded data + metadata_file = os.path.join(fl.get_fueldata_dir(), "fuel_metadata.yaml") + else: + # Load from custom directory + metadata_file = os.path.join(fuel_data_dir, "fuel_metadata.yaml") + + try: + if os.path.exists(metadata_file): + with open(metadata_file, "r") as f: + data = yaml.safe_load(f) + return data.get("fuels", {}) if data else {} + except yaml.YAMLError as e: + warnings.warn( + f"Failed to parse fuel metadata from {metadata_file}: {e}", stacklevel=2 + ) + except OSError as e: + warnings.warn( + f"Failed to read fuel metadata from {metadata_file}: {e}", stacklevel=2 + ) + + return {} + + +def list_fuels_main(): + """ + Entry point for fl-fuels command - List all available fuels in the library. + """ + parser = argparse.ArgumentParser( + description="List all available fuels in the FuelLib library." + ) + + parser.add_argument( + "-dir", + "--fuel_data_dir", + default=None, + metavar="PATH", + help="Directory containing fuel data (with gcData/, groupDecompositionData/, and fuel_metadata.yaml). " + "If not specified, uses embedded FuelLib data.", + ) + parser.add_argument( + "-v", + "--verbose", + action="store_true", + help="Show detailed information including source and category for each fuel.", + ) + + args = parser.parse_args() + + if args.fuel_data_dir is None: + fuel_data_dir = fl.get_fueldata_gc_dir() + metadata_dir = None # Use embedded metadata + else: + fuel_data_dir = os.path.join(args.fuel_data_dir, "gcData") + metadata_dir = args.fuel_data_dir # Load metadata from same custom directory + + try: + # List all fuel files in the gcData directory + if not os.path.exists(fuel_data_dir): + print(f"Error: Fuel data directory not found: {fuel_data_dir}") + exit(1) + + # Extract fuel names from *_init.csv files + fuel_files = [f for f in os.listdir(fuel_data_dir) if f.endswith("_init.csv")] + fuel_names = sorted([f.replace("_init.csv", "") for f in fuel_files]) + + if not fuel_names: + print("No fuels found in the specified directory.") + exit(0) + + # Load metadata from the appropriate location + metadata = load_fuel_metadata(metadata_dir) + + print("\n" + "=" * 80) + if args.fuel_data_dir: + print(f"Available Fuels in {args.fuel_data_dir}") + else: + print("Available Fuels in FuelLib") + print("=" * 80) + + if args.verbose and metadata: + # Verbose output with metadata + for i, fuel_name in enumerate(fuel_names, 1): + meta = metadata.get(fuel_name, {}) + category = meta.get("category", "Unknown") + source = meta.get("source") + description = meta.get("description", "") + + print(f"{i:2d}. {fuel_name}") + print(f" Category: {category}") + if source: + print(f" Source: {source}") + if description: + print(f" Note: {description}") + print() + else: + # Simple list output + for i, fuel_name in enumerate(fuel_names, 1): + if metadata and fuel_name in metadata: + source = metadata[fuel_name].get("source", "") + if source: + print(f"{i:2d}. {fuel_name:<20} [{source}]") + else: + print(f"{i:2d}. {fuel_name}") + else: + print(f"{i:2d}. {fuel_name}") + + print("=" * 80) + print(f"Total: {len(fuel_names)} fuel(s)") + if not args.verbose and metadata: + print( + "Use -v/--verbose for detailed information including source and category" + ) + print("=" * 80 + "\n") + + except Exception as e: + print(f"Error listing fuels: {e}") + exit(1) diff --git a/fuellib/cli/plotting.py b/fuellib/cli/plotting.py new file mode 100644 index 0000000..8f3cb93 --- /dev/null +++ b/fuellib/cli/plotting.py @@ -0,0 +1,790 @@ +""" +Utilities for plotting fuel properties and composition. + +This module provides functions for visualizing: +- Fuel composition by compound and chemical family +- Mixture properties over a temperature range +""" + +import os +import re +import numpy as np +import pandas as pd +import matplotlib.pyplot as plt +import argparse +import fuellib as fl + + +def plot_composition( + fuel_name, + fuel_data_dir=None, + output_dir=None, + title=None, + decomp_name=None, + save=True, + display=False, +): + """ + Plot the composition of a given fuel. + + :param fuel_name: Name of the fuel to plot. + :type fuel_name: str + :param fuel_data_dir: Directory where fuel data files are located (optional). + :type fuel_data_dir: str, optional + :param output_dir: Directory to save the plot (optional, default: current directory). + :type output_dir: str, optional + :param title: Title for the plots (optional, default: fuel_name, or "none"/"None" to disable). + :type title: str, optional + :param decomp_name: Name of the decomposition file to use (optional, default: fuel_name). + :type decomp_name: str, optional + :param save: Whether to save the plot to a file (optional, default: True). + :type save: bool, optional + :param display: Whether to display the plot with plt.show() (optional, default: False). + :type display: bool, optional + """ + if output_dir is None: + output_dir = os.getcwd() + + # Handle title + plot_title = None + if title is None: + plot_title = "Fuel Composition" + elif title.lower() != "none": + plot_title = title + + if fuel_data_dir is None: + fuel_data_dir = fl.get_fueldata_dir() + + if save and not os.path.exists(output_dir): + os.makedirs(output_dir) + + # Load the fuel + fuel = fl.fuel(fuel_name, decompName=decomp_name, fuelDataDir=fuel_data_dir) + + # Create DataFrame with compound data and carbon numbers from fuel object + df = pd.DataFrame( + { + "Compound": fuel.compounds, + "Weight %": fuel.Y_0 * 100, + "Family": fuel.hc_type, + "nC": fuel.nC, + } + ) + + # Get unique families from the fuel data in canonical order + canonical_order = ["n-alkane", "iso-alkane", "cyclo-alkane", "aromatic", "alkene"] + unique_families = list(np.unique(fuel.hc_type)) + family_names = [f for f in canonical_order if f in unique_families] + + # Remove rows with weight % <= 0.01 + df = df[df["Weight %"] > 0.01] + + # Calculate family weights + family_weights = df.groupby("Family")["Weight %"].sum() + + # Print composition table + print(f"\n{'=' * 50}") + print("Relative Weight % of Each Compound Family") + print(f"Fuel: {fuel_name}") + print("=" * 50) + for family in family_names: + if family in family_weights.index: + weight = family_weights[family] + print(f" {family:<20} {weight:>8.2f}%") + print("-" * 50) + print(f" {'Total':<20} {family_weights.sum():>8.2f}%") + print("=" * 50 + "\n") + + # Color scheme + colors = { + "n-alkane": "#063C61", + "iso-alkane": "#2980B9", + "cyclo-alkane": "#91BCD8", + "alkene": "#663399", + "aromatic": "#7f7f7f", + } + + # Create figure with two subplots side by side + fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5), constrained_layout=True) + + # Plot 1: Bar chart grouped by carbon number, colored by hydrocarbon type + spacing = [-0.2985, -0.099, 0.099, 0.2985] + nC_values = sorted(df["nC"].unique()) + + # Get unique families that are in the filtered data + families_in_data = [f for f in family_names if f in df["Family"].values] + + # Create bars for each family at each carbon number + for k, family in enumerate(families_in_data): + df_family = df[df["Family"] == family] + + # Group by carbon number and sum weights + family_by_nC = df_family.groupby("nC")["Weight %"].sum() + + ax1.bar( + family_by_nC.index + spacing[k], + family_by_nC.values, + label=family, + alpha=1, + color=colors.get(family, "#7f7f7f"), + width=0.2, + ) + + ax1.set_xlabel("Carbon Number", fontsize=16) + ax1.set_ylabel("Weight %", fontsize=16) + ax1.set_xticks(nC_values) + ax1.set_xticklabels( + [int(n) if n == int(n) else f"{n:.1f}" for n in nC_values], fontsize=14 + ) + ax1.set_xlim(min(nC_values) - 0.5, max(nC_values) + 0.5) + ax1.tick_params(axis="y", labelsize=14) + ax1.grid(axis="y", alpha=0.3) + + # Plot 2: Pie chart of family composition + # Only include families that have weight > 0, in canonical order + families_present = [ + f for f in family_names if f in family_weights.index and family_weights[f] > 0 + ] + family_weights_sorted = family_weights[families_present] + + # Create pie chart without labels/percentages (we'll add them outside) + wedges, texts = ax2.pie( + family_weights_sorted, + labels=None, + autopct=None, + startangle=140, + colors=[ + colors.get(family, "#7f7f7f") for family in family_weights_sorted.index + ], + ) + + # Add percentages outside the pie with arrows + for wedge, value, family in zip( + wedges, family_weights_sorted.values, family_weights_sorted.index + ): + angle = (wedge.theta2 + wedge.theta1) / 2 + radius = 1.3 + x = radius * np.cos(np.radians(angle)) + y = radius * np.sin(np.radians(angle)) + + # Determine horizontal alignment based on position + ha = "left" if x > 0 else "right" + + # Add annotation with arrow + ax2.annotate( + f"{value:.1f}%", + xy=(np.cos(np.radians(angle)), np.sin(np.radians(angle))), + xytext=(x, y), + ha=ha, + va="center", + fontsize=14, + fontweight="bold", + arrowprops=dict(arrowstyle="-", color="black", lw=1.5), + ) + + ax2.axis("equal") + + # Add a single figure-level legend for all families + legend_handles = [ + plt.Rectangle((0, 0), 1, 1, fc=colors.get(family, "#7f7f7f")) + for family in family_weights_sorted.index + ] + fig.legend( + legend_handles, + family_weights_sorted.index, + loc="upper center", + bbox_to_anchor=(0.5, -0.02), + ncol=4, + fontsize=13, + frameon=True, + ) + + # Add title if specified + if plot_title: + fig.suptitle(plot_title, fontsize=16, fontweight="bold") + + # Save the plot if requested + if save: + plot_file = os.path.join(output_dir, f"composition_{fuel_name}.png") + fig.savefig(plot_file, dpi=300, bbox_inches="tight") + print(f"Composition plot saved to {plot_file}") + + # Display the plot if requested + if display: + plt.show() + else: + plt.close(fig) + + +def plot_mixture_properties( + fuel_names, + property_names=None, + fuel_data_dir=None, + output_dir=None, + title=None, + decomp_name=None, + save=True, + display=False, +): + """ + Plot mixture properties for fuel(s) over a temperature range. + + :param fuel_names: Name or list of fuel names to plot. + :type fuel_names: str or list[str] + :param property_names: Properties to plot (optional, defaults to standard set). + :type property_names: list[str], optional + :param fuel_data_dir: Directory where fuel data files are located (optional). + :type fuel_data_dir: str, optional + :param output_dir: Directory to save the plot (optional, default: current directory). + :type output_dir: str, optional + :param title: Title for the plot (optional, default: None). + :type title: str, optional + :param decomp_name: Name of the decomposition file to use (optional, default: fuel_name). + :type decomp_name: str, optional + :param save: Whether to save the plot to a file (optional, default: True). + :type save: bool, optional + :param display: Whether to display the plot with plt.show() (optional, default: False). + :type display: bool, optional + """ + if output_dir is None: + output_dir = os.getcwd() + + if fuel_data_dir is None: + fuel_data_dir = fl.get_fueldata_dir() + + if save and not os.path.exists(output_dir): + os.makedirs(output_dir) + + # Handle single fuel_name or list + if isinstance(fuel_names, str): + fuel_names = [fuel_names] + + # Default properties if not specified + if property_names is None: + property_names = [ + "Density", + "Viscosity", + "VaporPressure", + "SurfaceTension", + "ThermalConductivity", + ] + + # Default temperature ranges (in °C) for different properties + default_ranges_by_property = { + "Density": [-40, 40], + "Viscosity": [-40, 100], + "VaporPressure": [0, 125], + "SurfaceTension": [-10, 40], + "ThermalConductivity": [0, 60], + } + + # Deprecated: fuel-specific ranges (kept for reference, now using property-based) + default_ranges = { + "posf10264": [-40, 125], + "posf10325": [-40, 125], + "posf10289": [-40, 125], + "posf11498": [-40, 125], + "jet-a": [-40, 125], + "hefa": [-40, 125], + "decane": [-50, 100], + "dodecane": [-50, 100], + "heptane": [-50, 100], + } + + # Y-axis labels + ylab = { + "Density": r"Density [g/cm$^3$]", + "Viscosity": r"Viscosity [mm$^2$/s]", + "VaporPressure": r"Vapor Pressure [kPa]", + "SurfaceTension": r"Surface Tension [N/m]", + "ThermalConductivity": r"Thermal Conductivity [W/m/K]", + } + + # Line specs for different fuels (marker styles) + line_specs_map = { + "decane": "o", + "posf10325": "o", + "dodecane": "s", + "posf10289": "s", + "heptane": "D", + "posf10264": "D", + "posf11498": "^", + "jet-a": "v", + "hefa": "p", + } + + # Fuel-specific colors + fuel_color_map = { + "posf10264": "#2980B9", # Primary Blue + "posf10325": "#7f7f7f", # 50% Gray + "posf10289": "#333333", # Dark Gray + "heptane": "#2980B9", # Primary Blue + "decane": "#7f7f7f", # 50% Gray + "dodecane": "#333333", # Dark Gray + } + + # Color palette for cycling through distinct colors + color_palette = [ + "#2980B9", # Medium blue + "#e74c3c", # Red + "#27ae60", # Green + "#8e44ad", # Purple + "#f39c12", # Orange + "#1abc9c", # Turquoise + "#c0392b", # Dark red + "#16a085", # Dark turquoise + "#d35400", # Dark orange + ] + + def get_line_spec(fuel_name, fuel_index=0): + """Get line color and marker style for fuel. + + :param fuel_name: Name of the fuel + :param fuel_index: Index of fuel in the plot (for cycling through colors) + :return: Tuple of (color, marker_style) + """ + # Get marker style from map + marker_style = "o" # Default + for key, spec in line_specs_map.items(): + if key in fuel_name.lower(): + marker_style = spec + break + + # Get color: use fuel-specific mapping if available, otherwise use palette + if fuel_name in fuel_color_map: + color = fuel_color_map[fuel_name] + else: + color = color_palette[fuel_index % len(color_palette)] + return (color, marker_style) + + def get_legend_label(fuel_name): + """Create legend label for fuel.""" + if "hefa" in fuel_name.lower(): + return fuel_name.upper() + elif "posf" in fuel_name.lower(): + return fuel_name[4:].upper() + else: + return fuel_name.capitalize() + + def get_temp_range(prop_name): + """Get default temperature range for a property.""" + return default_ranges_by_property.get( + prop_name, [0, 100] + ) # Fallback to [0, 100] + + def get_predictions_and_data(fuel_name, prop_name): + """Get predicted and experimental data for a property.""" + fuel = fl.fuel(fuel_name, decompName=decomp_name, fuelDataDir=fuel_data_dir) + + # Try to load experimental data + props_dir = fuel.fuelDataPropsDir + + T_data = pd.Series(dtype=float) + prop_data = pd.Series(dtype=float) + + if props_dir and os.path.exists(props_dir): + # Check if metadata specifies a different props_data filename + props_data_name = fl.get_metadata_props_data(fuel_name, fuel_data_dir) + data_filename = props_data_name if props_data_name else fuel_name + + data_file = os.path.join(props_dir, f"{data_filename}.csv") + if os.path.exists(data_file): + try: + data = pd.read_csv(data_file, skiprows=[1]) + if prop_name in data.columns: + mask = data[prop_name].notna() + T_data = data.loc[mask, "Temperature"] + prop_data = data.loc[mask, prop_name] + except Exception: + pass + + # Generate predictions over temperature range + # First check if experimental data exists - use its range if available + if len(T_data) > 0: + # Use data range if available + T_pred = fl.convert.C2K(np.linspace(T_data.min(), T_data.max(), 100)) + else: + # Use property-specific default range + temp_min, temp_max = get_temp_range(prop_name) + T_pred = fl.convert.C2K(np.linspace(temp_min, temp_max, 100)) + + pred = np.zeros_like(T_pred) + Y_li = fuel.Y_0 + + for i, T in enumerate(T_pred): + try: + if prop_name == "Density": + pred[i] = ( + fuel.mixture_density(Y_li, T) * 1.0e-03 + ) # Convert to g/cm^3 + elif prop_name == "VaporPressure": + pred[i] = ( + fuel.mixture_vapor_pressure(Y_li, T) * 1.0e-03 + ) # Convert to kPa + elif prop_name == "Viscosity": + pred[i] = ( + fuel.mixture_kinematic_viscosity(Y_li, T) * 1.0e6 + ) # Convert to mm^2/s + elif prop_name == "SurfaceTension": + pred[i] = fuel.mixture_surface_tension(Y_li, T) + elif prop_name == "ThermalConductivity": + pred[i] = fuel.mixture_thermal_conductivity(Y_li, T) + except Exception: + pred[i] = np.nan + + return T_data, prop_data, T_pred, pred + + # Create figure with subplots + n_props = len(property_names) + figW = 4.25 * n_props + fig, ax = plt.subplots(1, n_props, figsize=(figW, 5.5), constrained_layout=True) + + # Handle single subplot case + if n_props == 1: + ax = [ax] + + # Plot properties for each fuel + for i, prop_name in enumerate(property_names): + for fuel_idx, fuel_name in enumerate(fuel_names): + T_data, prop_data, T_pred, pred = get_predictions_and_data( + fuel_name, prop_name + ) + line_color, marker_style = get_line_spec(fuel_name, fuel_index=fuel_idx) + + # Plot predictions + ax[i].plot( + fl.convert.K2C(T_pred), + pred, + "-", + color=line_color, + label=f"FuelLib: {get_legend_label(fuel_name)}", + linewidth=4, + ) + + # Plot experimental data if available + if len(prop_data) > 0: + # Get props_data name for the legend + props_data_name = fl.get_metadata_props_data(fuel_name, fuel_data_dir) + data_label = props_data_name if props_data_name else fuel_name + ax[i].scatter( + T_data, + prop_data, + marker=marker_style, + label=f"Data: {get_legend_label(data_label)}", + facecolors=line_color, + s=75, + zorder=5, + ) + + # Format subplot + ax[i].set_xlabel("T [°C]", fontsize=18) + ax[i].set_ylabel(ylab.get(prop_name, prop_name), fontsize=18) + ax[i].tick_params(labelsize=18) + ax[i].grid(alpha=0.3) + + # Add legend + handles, labels = ax[0].get_legend_handles_labels() + fig.legend( + handles, labels, loc="outside lower center", ncol=len(fuel_names), fontsize=18 + ) + + if title: + fig.suptitle(title, fontsize=14, fontweight="bold") + + # Save the plot if requested + if save: + fuel_str = "_".join(fuel_names) + plot_file = os.path.join(output_dir, f"mixture_properties_{fuel_str}.png") + fig.savefig(plot_file, dpi=300, bbox_inches="tight") + print(f"Mixture properties plot saved to {plot_file}") + + # Display the plot if requested + if display: + plt.show() + else: + plt.close(fig) + + +def comp_main(): + """ + Entry point for fl-plt-comp command - Plot fuel composition. + """ + parser = argparse.ArgumentParser( + description="Plot fuel composition by compound and chemical family." + ) + + # Fuel name (required) + parser.add_argument( + "-f", + "--fuel_name", + required=True, + metavar="NAME", + help="Name of the fuel to plot (required).", + ) + parser.add_argument( + "-dir", + "--fuel_data_dir", + default=None, + metavar="PATH", + help="Directory where fuel data files are located (optional).", + ) + parser.add_argument( + "-o", + "--output_dir", + default=None, + metavar="PATH", + help="Directory to save the plot (optional, default: current directory).", + ) + parser.add_argument( + "-t", + "--title", + default=None, + metavar="TITLE", + help="Title for the plots (optional, default: fuel_name, or 'none' to disable).", + ) + parser.add_argument( + "-decomp", + "--decomp_name", + default=None, + metavar="NAME", + help="Name of the decomposition file to use (optional, default: fuel_name).", + ) + parser.add_argument( + "-d", + "--display", + action="store_true", + help="Display the plot with plt.show() (optional, default: False).", + ) + parser.add_argument( + "-s", + "--save", + type=lambda x: str(x).lower() not in ["false", "0"], + default=True, + metavar="{true,false}", + help="Save the plot to a file (optional, default: True).", + ) + + args = parser.parse_args() + + try: + plot_composition( + args.fuel_name, + fuel_data_dir=args.fuel_data_dir, + output_dir=args.output_dir, + title=args.title, + decomp_name=args.decomp_name, + save=args.save, + display=args.display, + ) + except Exception as e: + print(f"Error plotting composition: {e}") + exit(1) + + +def props_main(): + """ + Entry point for fl-plt-props command - Plot mixture properties. + """ + parser = argparse.ArgumentParser( + description="Plot mixture properties over temperature range for fuel(s)." + ) + + parser.add_argument( + "-f", + "--fuel_names", + required=True, + nargs="+", + metavar="NAME", + help="Name(s) of fuel(s) to plot (required, space-separated for multiple).", + ) + parser.add_argument( + "-p", + "--property_names", + nargs="+", + default=None, + metavar="PROP", + help="Properties to plot (optional). Options: Density, Viscosity, VaporPressure, SurfaceTension, ThermalConductivity", + ) + parser.add_argument( + "-dir", + "--fuel_data_dir", + default=None, + metavar="PATH", + help="Directory where fuel data files are located (optional).", + ) + parser.add_argument( + "-o", + "--output_dir", + default=None, + metavar="PATH", + help="Directory to save the plot (optional, default: current directory).", + ) + parser.add_argument( + "-t", + "--title", + default=None, + metavar="TITLE", + help="Title for the plot (optional).", + ) + parser.add_argument( + "-decomp", + "--decomp_name", + default=None, + metavar="NAME", + help="Name of the decomposition file to use (optional, default: fuel_name).", + ) + parser.add_argument( + "-d", + "--display", + action="store_true", + help="Display the plot with plt.show() (optional, default: False).", + ) + parser.add_argument( + "-s", + "--save", + type=lambda x: str(x).lower() not in ["false", "0"], + default=True, + metavar="{true,false}", + help="Save the plot to a file (optional, default: True).", + ) + + args = parser.parse_args() + + try: + plot_mixture_properties( + args.fuel_names, + property_names=args.property_names, + fuel_data_dir=args.fuel_data_dir, + output_dir=args.output_dir, + title=args.title, + decomp_name=args.decomp_name, + save=args.save, + display=args.display, + ) + except Exception as e: + print(f"Error plotting mixture properties: {e}") + exit(1) + + +def main(): + """ + Main entry point for CLI usage. + + This function handles routing between composition and mixture properties plotting. + """ + parser = argparse.ArgumentParser( + description="Plot fuel composition or mixture properties." + ) + + # Subparsers for different plot types + subparsers = parser.add_subparsers( + dest="plot_type", help="Type of plot to generate" + ) + + # Composition plotter subcommand + comp_parser = subparsers.add_parser("comp", help="Plot fuel composition") + comp_parser.add_argument( + "-f", + "--fuel_name", + required=True, + metavar="NAME", + help="Name of the fuel to plot (required).", + ) + comp_parser.add_argument( + "-dir", + "--fuel_data_dir", + default=None, + metavar="PATH", + help="Directory where fuel data files are located (optional).", + ) + comp_parser.add_argument( + "-o", + "--output_dir", + default=None, + metavar="PATH", + help="Directory to save the plot (optional, default: current directory).", + ) + comp_parser.add_argument( + "-t", + "--title", + default=None, + metavar="TITLE", + help="Title for the plots (optional, default: fuel_name, or 'none' to disable).", + ) + + # Mixture properties plotter subcommand + props_parser = subparsers.add_parser( + "props", help="Plot mixture properties over temperature range" + ) + props_parser.add_argument( + "-f", + "--fuel_names", + required=True, + nargs="+", + metavar="NAME", + help="Name(s) of fuel(s) to plot (required, space-separated for multiple).", + ) + props_parser.add_argument( + "-p", + "--property_names", + nargs="+", + default=None, + metavar="PROP", + help="Properties to plot (optional). Options: Density, Viscosity, VaporPressure, SurfaceTension, ThermalConductivity", + ) + props_parser.add_argument( + "-dir", + "--fuel_data_dir", + default=None, + metavar="PATH", + help="Directory where fuel data files are located (optional).", + ) + props_parser.add_argument( + "-o", + "--output_dir", + default=None, + metavar="PATH", + help="Directory to save the plot (optional, default: current directory).", + ) + props_parser.add_argument( + "-t", + "--title", + default=None, + metavar="TITLE", + help="Title for the plot (optional).", + ) + + args = parser.parse_args() + + if args.plot_type == "comp": + try: + plot_composition( + args.fuel_name, + fuel_data_dir=args.fuel_data_dir, + output_dir=args.output_dir, + title=args.title, + ) + except Exception as e: + print(f"Error plotting composition: {e}") + exit(1) + + elif args.plot_type == "props": + try: + plot_mixture_properties( + args.fuel_names, + property_names=args.property_names, + fuel_data_dir=args.fuel_data_dir, + output_dir=args.output_dir, + title=args.title, + ) + except Exception as e: + print(f"Error plotting mixture properties: {e}") + exit(1) + + else: + # If no subcommand specified, show help + parser.print_help() + + +if __name__ == "__main__": + main() diff --git a/fuellib/cli/temp_converter.py b/fuellib/cli/temp_converter.py new file mode 100644 index 0000000..c56e958 --- /dev/null +++ b/fuellib/cli/temp_converter.py @@ -0,0 +1,106 @@ +"""Command-line tools to convert temperatures.""" + +import argparse +from .. import convert + + +def c2k_main(): + """Convert temperature from Celsius to Kelvin via command line.""" + parser = argparse.ArgumentParser( + description="Convert temperature from Celsius to Kelvin" + ) + parser.add_argument( + "temperature", + type=float, + metavar="TEMP", + help="Temperature in Celsius", + ) + + args = parser.parse_args() + result = convert.C2K(args.temperature) + print(f"{args.temperature} °C = {result:.2f} K") + + +def k2c_main(): + """Convert temperature from Kelvin to Celsius via command line.""" + parser = argparse.ArgumentParser( + description="Convert temperature from Kelvin to Celsius" + ) + parser.add_argument( + "temperature", + type=float, + metavar="TEMP", + help="Temperature in Kelvin", + ) + + args = parser.parse_args() + result = convert.K2C(args.temperature) + print(f"{args.temperature} K = {result:.2f} °C") + + +def c2f_main(): + """Convert temperature from Celsius to Fahrenheit via command line.""" + parser = argparse.ArgumentParser( + description="Convert temperature from Celsius to Fahrenheit" + ) + parser.add_argument( + "temperature", + type=float, + metavar="TEMP", + help="Temperature in Celsius", + ) + + args = parser.parse_args() + result = convert.C2F(args.temperature) + print(f"{args.temperature} °C = {result:.2f} °F") + + +def f2c_main(): + """Convert temperature from Fahrenheit to Celsius via command line.""" + parser = argparse.ArgumentParser( + description="Convert temperature from Fahrenheit to Celsius" + ) + parser.add_argument( + "temperature", + type=float, + metavar="TEMP", + help="Temperature in Fahrenheit", + ) + + args = parser.parse_args() + result = convert.F2C(args.temperature) + print(f"{args.temperature} °F = {result:.2f} °C") + + +def f2k_main(): + """Convert temperature from Fahrenheit to Kelvin via command line.""" + parser = argparse.ArgumentParser( + description="Convert temperature from Fahrenheit to Kelvin" + ) + parser.add_argument( + "temperature", + type=float, + metavar="TEMP", + help="Temperature in Fahrenheit", + ) + + args = parser.parse_args() + result = convert.F2K(args.temperature) + print(f"{args.temperature} °F = {result:.2f} K") + + +def k2f_main(): + """Convert temperature from Kelvin to Fahrenheit via command line.""" + parser = argparse.ArgumentParser( + description="Convert temperature from Kelvin to Fahrenheit" + ) + parser.add_argument( + "temperature", + type=float, + metavar="TEMP", + help="Temperature in Kelvin", + ) + + args = parser.parse_args() + result = convert.K2F(args.temperature) + print(f"{args.temperature} K = {result:.2f} °F") diff --git a/fuellib/cli/transport_props_converter.py b/fuellib/cli/transport_props_converter.py new file mode 100644 index 0000000..330f760 --- /dev/null +++ b/fuellib/cli/transport_props_converter.py @@ -0,0 +1,21 @@ +"""Command-line tool to convert transport properties for combustion simulations.""" + +import argparse +from .. import convert + + +def eps2K_main(): + """Convert Lennard-Jones epsilon from J/mol to K via command line.""" + parser = argparse.ArgumentParser( + description="Convert Lennard-Jones well depth epsilon from J/mol to Kelvin" + ) + parser.add_argument( + "epsilon", + type=float, + metavar="EPSILON", + help="Lennard-Jones well depth in J/mol", + ) + + args = parser.parse_args() + result = convert.epsilon_to_characteristic_temperature(args.epsilon) + print(f"Characteristic temperature: {result:.3f} K") diff --git a/fuellib/constants.py b/fuellib/constants.py new file mode 100644 index 0000000..d5a7b71 --- /dev/null +++ b/fuellib/constants.py @@ -0,0 +1,10 @@ +"""Physical constants used in FuelLib calculations.""" + +# Physical constants +#: Boltzmann's constant in J/K. +k_B = 1.380649e-23 + +#: Avogadro's number in 1/mol. +N_A = 6.02214076e23 + +__all__ = ["k_B", "N_A"] diff --git a/fuellib/convert.py b/fuellib/convert.py new file mode 100644 index 0000000..a8a4c3e --- /dev/null +++ b/fuellib/convert.py @@ -0,0 +1,105 @@ +"""Unit conversion functions.""" + +from .constants import k_B, N_A + + +def C2K(T): + """ + Convert temperature from Celsius to Kelvin. + + :param T: Temperature in Celsius. + :type T: float or np.ndarray + :return: Temperature in Kelvin. + :rtype: float or np.ndarray + """ + return T + 273.15 + + +def K2C(T): + """ + Convert temperature from Kelvin to Celsius. + + :param T: Temperature in Kelvin. + :type T: float or np.ndarray + :return: Temperature in Celsius. + :rtype: float or np.ndarray + """ + return T - 273.15 + + +def C2F(T): + """ + Convert temperature from Celsius to Fahrenheit. + + :param T: Temperature in Celsius. + :type T: float or np.ndarray + :return: Temperature in Fahrenheit. + :rtype: float or np.ndarray + """ + return T * 9 / 5 + 32 + + +def F2C(T): + """ + Convert temperature from Fahrenheit to Celsius. + + :param T: Temperature in Fahrenheit. + :type T: float or np.ndarray + :return: Temperature in Celsius. + :rtype: float or np.ndarray + """ + return (T - 32) * 5 / 9 + + +def F2K(T): + """ + Convert temperature from Fahrenheit to Kelvin. + + :param T: Temperature in Fahrenheit. + :type T: float or np.ndarray + :return: Temperature in Kelvin. + :rtype: float or np.ndarray + """ + return C2K(F2C(T)) + + +def K2F(T): + """ + Convert temperature from Kelvin to Fahrenheit. + + :param T: Temperature in Kelvin. + :type T: float or np.ndarray + :return: Temperature in Fahrenheit. + :rtype: float or np.ndarray + """ + return C2F(K2C(T)) + + +def epsilon_to_characteristic_temperature(epsilon_j_per_mol): + """ + Convert Lennard-Jones epsilon from J/mol to characteristic temperature in Kelvin. + + The characteristic temperature (epsilon/k_B) is used in transport property + correlations and is required by combustion codes like CHEMKIN. + + Uses the relation: T* = (epsilon_J/mol) / (N_A * k_B) + + :param epsilon_j_per_mol: Lennard-Jones well depth epsilon in J/mol. + :type epsilon_j_per_mol: float + :return: Characteristic temperature (epsilon/k_B) in Kelvin. + :rtype: float + """ + epsilon_per_molecule = epsilon_j_per_mol / N_A + lj_welldepth_K = epsilon_per_molecule / k_B + return lj_welldepth_K + + +__all__ = [ + "C2K", + "K2C", + "C2F", + "F2C", + "F2K", + "K2F", + "epsilon_to_characteristic_temperature", +] diff --git a/fuellib/data/__init__.py b/fuellib/data/__init__.py new file mode 100644 index 0000000..a3928fa --- /dev/null +++ b/fuellib/data/__init__.py @@ -0,0 +1 @@ +"""FuelLib embedded data package.""" diff --git a/fuellib/data/fuelData/__init__.py b/fuellib/data/fuelData/__init__.py new file mode 100644 index 0000000..7693958 --- /dev/null +++ b/fuellib/data/fuelData/__init__.py @@ -0,0 +1 @@ +"""Fuel data.""" diff --git a/fuellib/data/fuelData/fuel_metadata.yaml b/fuellib/data/fuelData/fuel_metadata.yaml new file mode 100644 index 0000000..33c5453 --- /dev/null +++ b/fuellib/data/fuelData/fuel_metadata.yaml @@ -0,0 +1,115 @@ +# Fuel Library Metadata +# Contains source information and properties for fuels in FuelLib + +fuels: + # POSF Fuels (Petroleum Surrogate Fuels) + posf4658: + name: POSF4658 + category: Conventional + source: Edwards et al. (2017) + reference: https://doi.org/10.2514/6.2017-0146 + description: 2004 physical average jet fuel constructed by blending 5 separate jet fuels from across the U.S. + decomp_name: posf-cat-a + + posf10264: + name: A-1 POSF10264 JP-8 + category: Conventional + source: Edwards et al. (2020) + reference: https://apps.dtic.mil/sti/pdfs/AD1093317.pdf + description: Best case fuel from NJFCP. Low viscosity, low density, and a low flash point. + decomp_name: posf-cat-a + + posf10289: + name: A-3 POSF10289 JP-5 + category: Conventional + source: Edwards et al. (2020) + reference: https://apps.dtic.mil/sti/pdfs/AD1093317.pdf + description: Worst case fuel from NJFCP. High viscosity, high density, and a high flash point. + decomp_name: posf-cat-a + + posf10325: + name: A-2 POSF10325 Jet A + category: Conventional + source: Edwards et al. (2020) + reference: https://apps.dtic.mil/sti/pdfs/AD1093317.pdf + description: Baseline fuel from NJFCP. Average density, average viscosity, and average flash point. + decomp_name: posf-cat-a + + posf11498: + name: C-1 POSF11498 ATJ + category: SATF + source: Edwards et al. (2020) + reference: https://apps.dtic.mil/sti/pdfs/AD1093317.pdf + description: Atypical alternative fuel from NJFCP. Isoparaffinic-only with low density, average viscosity, and a flat distillation curve. + decomp_name: posf11498 + + # HEFA Fuels (Hydroprocessed Esters and Fatty Acids) + hefa-came: + name: HEFA-CAME + category: SATF + source: Vozka et al. (2018) + reference: https://doi.org/10.1021/acs.energyfuels.8b02787 + description: HEFA-SPK from camelina oil feedstock + decomp_name: hefa + + hefa-mfat: + name: HEFA-MFAT + category: SATF + source: Vozka et al. (2018) + reference: https://doi.org/10.1021/acs.energyfuels.8b02787 + description: HEFA from mixed fat feedstock + decomp_name: hefa + + hefa-tall: + name: HEFA-TALL + category: SATF + source: Vozka et al. (2018) + reference: https://doi.org/10.1021/acs.energyfuels.8b02787 + description: HEFA from tallow feedstock + decomp_name: hefa + + # Jet-A (Conventional Jet Fuel) + jet-a: + name: Jet-A + category: Conventional + source: Vozka et al. (2018) + reference: https://doi.org/10.1021/acs.energyfuels.8b02787 + description: Conventional Jet-A + decomp_name: jet-a + + # Single Component Reference Fuels + decane: + name: n-Decane + category: Simple + source: NIST + reference: null + description: 100% n-decane + decomp_name: decane + props_data: decane + + dodecane: + name: n-Dodecane + category: Simple + source: NIST + reference: null + description: 100% n-dodecane + decomp_name: dodecane + props_data: dodecane + + heptane: + name: n-Heptane + category: Simple + source: NIST + reference: null + description: 100% n-heptane + decomp_name: heptane + props_data: heptane + + heptane-decane: + name: n-Heptane/n-Decane Blend + category: Simple + source: null + reference: null + description: 50/50 (mass) blend of n-heptane and n-decane + decomp_name: heptane-decane + props_data: null \ No newline at end of file diff --git a/fuellib/data/fuelData/gcData/__init__.py b/fuellib/data/fuelData/gcData/__init__.py new file mode 100644 index 0000000..2bd91d6 --- /dev/null +++ b/fuellib/data/fuelData/gcData/__init__.py @@ -0,0 +1 @@ +"""GC data.""" diff --git a/fuellib/data/fuelData/gcData/decane_init.csv b/fuellib/data/fuelData/gcData/decane_init.csv new file mode 100644 index 0000000..def497b --- /dev/null +++ b/fuellib/data/fuelData/gcData/decane_init.csv @@ -0,0 +1,2 @@ +Compound,Formula,Weight % +n-C10,C10H22,100 diff --git a/fuellib/data/fuelData/gcData/dodecane_init.csv b/fuellib/data/fuelData/gcData/dodecane_init.csv new file mode 100644 index 0000000..32644f4 --- /dev/null +++ b/fuellib/data/fuelData/gcData/dodecane_init.csv @@ -0,0 +1,2 @@ +Compound,Formula,Weight % +n-C12,C12H26,100 diff --git a/fuellib/data/fuelData/gcData/hefa-came_init.csv b/fuellib/data/fuelData/gcData/hefa-came_init.csv new file mode 100644 index 0000000..431a1a0 --- /dev/null +++ b/fuellib/data/fuelData/gcData/hefa-came_init.csv @@ -0,0 +1,68 @@ +Compound,Reference Compound,Formula,PelePhysics Key,Weight % +Toluene,toluene,C7H8,C6H5CH3,0.0 +C2-Benzene,ethyl benzene ,C8H10,C6H5C2H5,0.01 +C3-Benzene,propyl benzene,C9H12,C6H5C3H7,0.02 +C4-Benzene,butyl benzene,C10H14,C6H5C4H9,0.0 +C5-Benzene,pentyl benzene,C11H16,C6H5C5H11,0.0 +C6-Benzene,hexyl benzene,C12H18,C6H5C6H13,0.0 +C7-Benzene,heptyl benzene,C13H20,C6H5C7H15,0.0 +C8-Benzene,octyl benzene,C14H22,C6H5C8H17,0.0 +C9-Benzene,nonyl benzene,C15H24,C6H5C9H19,0.0 +Diaromatic-C10,naphthalene,C10H8,NAPH,0.0 +Diaromatic-C11,1-methyl naphthalene,C11H10,METHYLNAPH-1,0.0 +Diaromatic-C12,1-ethyl naphthalene,C12H12,ETHYLNAPH-1,0.0 +Diaromatic-C13,1-propyl naphthalene,C13H14,PROPYLNAPH-1,0.0 +Cycloaromatic-C09,indane,C9H10,INDANE,0.0 +Cycloaromatic-C10,tetralin,C10H12,TETRA,0.0 +Cycloaromatic-C11,2-methyl tetralin,C11H14,METHYLTETRA-2,0.0 +Cycloaromatic-C12,2-ethly tetralin,C12H16,ETHYLTETRA-2,0.0 +Cycloaromatic-C13,2-propyl tetralin,C13H18,PROPYLTETRA-2,0.0 +Cycloaromatic-C14,2-butyl tetralin,C14H20,BUTYLTETRA-2,0.0 +C07-Isoparaffin,2-methyl hexane,C7H16,C7H16-2,0.0 +C08-Isoparaffin,2-methyl heptane,C8H18,C8H18-2,1.51 +C09-Isoparaffin,2-methyl octane,C9H20,C9H20-2,11.09 +C10-Isoparaffin,2-methyl nonane,C10H22,C10H22-2,11.1 +C11-Isoparaffin,2-methyl decane,C11H24,C11H24-2,9.62 +C12-Isoparaffin,2-methyl undecane,C12H26,C12H26-2,8.27 +C13-Isoparaffin,2-methyl dodecane,C13H28,C13H28-2,8.33 +C14-Isoparaffin,2-methyl tridecane,C14H30,C14H30-2,6.39 +C15-Isoparaffin,2-methyl tetradecane,C15H32,C15H32-2,5.42 +C16-Isoparaffin,2-methyl pentadecane,C16H34,C16H34-2,2.14 +C17-Isoparaffin,2-methyl hexadecane,C17H36,C17H36-2,21.58 +C18-Isoparaffin,2-methyl heptadecane,C18H38,C18H38-2,4.71 +C19-Isoparaffin,2-methyl octadecane,C19H40,C19H40-2,0.0 +C20-Isoparaffin,2-methyl nonadecane,C20H42,C20H42-2,0.0 +n-C07,n-heptane,C7H16,NC7H16,0.0 +n-C08,n-octane,C8H18,NC8H18,0.83 +n-C09,n-nonane,C9H20,NC9H20,1.92 +n-C10,n-decane,C10H22,NC10H22,1.4 +n-C11,n-undecane,C11H24,NC11H24,0.84 +n-C12,n-dodecane,C12H26,NC12H26,0.59 +n-C13,n-tridecane,C13H28,NC13H28,0.49 +n-C14,n-tetradecane,C14H30,NC14H30,0.23 +n-C15,n-pentadecane,C15H32,NC15H32,0.46 +n-C16,n-hexadecane (cetane),C16H34,NC16H34,0.2 +n-C17,n-heptadecane,C17H36,NC17H36,0.12 +n-C18,n-octadecane,C18H38,NC18H38,0.0 +C07-Monocycloparaffin,methyl cyclohexane,C7C14,C6H11CH3,0.1 +C08-Monocycloparaffin,ethyl cyclohexane,C8H16,C6H11C2H5,1.94 +C09-Monocycloparaffin,propyl cyclohexane,C9H18,C6H11C3H7,0.52 +C10-Monocycloparaffin,butyl cyclohexane,C10H20,C6H11C4H9,0.15 +C11-Monocycloparaffin,pentyl cyclohexane,C11H22,C6H11C5H11,0.04 +C12-Monocycloparaffin,hexyl cyclohexane,C12H24,C6H11C6H13,0.0 +C13-Monocycloparaffin,heptyl cyclohexane,C13H26,C6H11C7H15,0.0 +C14-Monocycloparaffin,octyl cyclohexane,C14H28,C6H11C8H17,0.0 +C15-Monocycloparaffin,nonyl cyclohexane,C15H30,C6H11C9H19,0.0 +C16-Monocycloparaffin,decyl cyclohexane,C16H32,C6H11C10H21,0.0 +C17-Monocycloparaffin,undecyl cyclohexane,C17H34,C6H11C11H23,0.0 +C08-Dicycloparaffin,Octahydropentalene,C8H14,OHPEN,0.0 +C09-Dicycloparaffin,Hydrindane,C9H16,HYDRIND,0.01 +C10-Dicycloparaffin,Decalin,C10H18,DECALIN,0.0 +C11-Dicycloparaffin,2-methyldecalin,C11H20,METHYLDECALIN-2,0.0 +C12-Dicycloparaffin,2-ethyldecalin,C12H22,ETHYLDECALIN-2,0.0 +C13-Dicycloparaffin,2-propyldecalin,C13H24,PROPYLDECALIN-2,0.0 +C14-Dicycloparaffin,2-butyldecalin,C14H26,BUTYLDECALIN-2,0.0 +C15-Dicycloparaffin,2-pentyldacalin,C15H28,PENTYLDECALIN-2,0.0 +C10-Tricycloparaffin,C1CC2C(C1)C1CCCC21,C10H16,TRICYCLO-C10,0.0 +C11-Tricycloparaffin,C1CC2CC3CCCC3C2C1,C11H18,TRICYCLO-C11,0.0 +C12-Tricycloparaffin,C1CC2CC3CCCC3CC2C1,C12H20,TRICYCLO-C12,0.0 diff --git a/fuellib/data/fuelData/gcData/hefa-mfat_init.csv b/fuellib/data/fuelData/gcData/hefa-mfat_init.csv new file mode 100644 index 0000000..23a8ff6 --- /dev/null +++ b/fuellib/data/fuelData/gcData/hefa-mfat_init.csv @@ -0,0 +1,68 @@ +Compound,Reference Compound,Formula,PelePhysics Key,Weight % +Toluene,toluene,C7H8,C6H5CH3,0.01 +C2-Benzene,ethyl benzene ,C8H10,C6H5C2H5,0.0 +C3-Benzene,propyl benzene,C9H12,C6H5C3H7,0.01 +C4-Benzene,butyl benzene,C10H14,C6H5C4H9,0.0 +C5-Benzene,pentyl benzene,C11H16,C6H5C5H11,0.0 +C6-Benzene,hexyl benzene,C12H18,C6H5C6H13,0.0 +C7-Benzene,heptyl benzene,C13H20,C6H5C7H15,0.0 +C8-Benzene,octyl benzene,C14H22,C6H5C8H17,0.0 +C9-Benzene,nonyl benzene,C15H24,C6H5C9H19,0.0 +Diaromatic-C10,naphthalene,C10H8,NAPH,0.0 +Diaromatic-C11,1-methyl naphthalene,C11H10,METHYLNAPH-1,0.0 +Diaromatic-C12,1-ethyl naphthalene,C12H12,ETHYLNAPH-1,0.0 +Diaromatic-C13,1-propyl naphthalene,C13H14,PROPYLNAPH-1,0.0 +Cycloaromatic-C09,indane,C9H10,INDANE,0.0 +Cycloaromatic-C10,tetralin,C10H12,TETRA,0.0 +Cycloaromatic-C11,2-methyl tetralin,C11H14,METHYLTETRA-2,0.0 +Cycloaromatic-C12,2-ethly tetralin,C12H16,ETHYLTETRA-2,0.0 +Cycloaromatic-C13,2-propyl tetralin,C13H18,PROPYLTETRA-2,0.0 +Cycloaromatic-C14,2-butyl tetralin,C14H20,BUTYLTETRA-2,0.0 +C07-Isoparaffin,2-methyl hexane,C7H16,C7H16-2,0.01 +C08-Isoparaffin,2-methyl heptane,C8H18,C8H18-2,1.77 +C09-Isoparaffin,2-methyl octane,C9H20,C9H20-2,3.65 +C10-Isoparaffin,2-methyl nonane,C10H22,C10H22-2,6.69 +C11-Isoparaffin,2-methyl decane,C11H24,C11H24-2,10.33 +C12-Isoparaffin,2-methyl undecane,C12H26,C12H26-2,12.37 +C13-Isoparaffin,2-methyl dodecane,C13H28,C13H28-2,11.54 +C14-Isoparaffin,2-methyl tridecane,C14H30,C14H30-2,13.98 +C15-Isoparaffin,2-methyl tetradecane,C15H32,C15H32-2,4.29 +C16-Isoparaffin,2-methyl pentadecane,C16H34,C16H34-2,20.73 +C17-Isoparaffin,2-methyl hexadecane,C17H36,C17H36-2,0.29 +C18-Isoparaffin,2-methyl heptadecane,C18H38,C18H38-2,3.44 +C19-Isoparaffin,2-methyl octadecane,C19H40,C19H40-2,0.0 +C20-Isoparaffin,2-methyl nonadecane,C20H42,C20H42-2,0.0 +n-C07,n-heptane,C7H16,NC7H16,0.0 +n-C08,n-octane,C8H18,NC8H18,0.54 +n-C09,n-nonane,C9H20,NC9H20,1.0 +n-C10,n-decane,C10H22,NC10H22,1.42 +n-C11,n-undecane,C11H24,NC11H24,1.36 +n-C12,n-dodecane,C12H26,NC12H26,1.44 +n-C13,n-tridecane,C13H28,NC13H28,0.87 +n-C14,n-tetradecane,C14H30,NC14H30,1.67 +n-C15,n-pentadecane,C15H32,NC15H32,0.18 +n-C16,n-hexadecane (cetane),C16H34,NC16H34,0.7 +n-C17,n-heptadecane,C17H36,NC17H36,0.01 +n-C18,n-octadecane,C18H38,NC18H38,0.0 +C07-Monocycloparaffin,methyl cyclohexane,C7C14,C6H11CH3,0.07 +C08-Monocycloparaffin,ethyl cyclohexane,C8H16,C6H11C2H5,0.76 +C09-Monocycloparaffin,propyl cyclohexane,C9H18,C6H11C3H7,0.41 +C10-Monocycloparaffin,butyl cyclohexane,C10H20,C6H11C4H9,0.27 +C11-Monocycloparaffin,pentyl cyclohexane,C11H22,C6H11C5H11,0.14 +C12-Monocycloparaffin,hexyl cyclohexane,C12H24,C6H11C6H13,0.02 +C13-Monocycloparaffin,heptyl cyclohexane,C13H26,C6H11C7H15,0.01 +C14-Monocycloparaffin,octyl cyclohexane,C14H28,C6H11C8H17,0.0 +C15-Monocycloparaffin,nonyl cyclohexane,C15H30,C6H11C9H19,0.0 +C16-Monocycloparaffin,decyl cyclohexane,C16H32,C6H11C10H21,0.0 +C17-Monocycloparaffin,undecyl cyclohexane,C17H34,C6H11C11H23,0.0 +C08-Dicycloparaffin,Octahydropentalene,C8H14,OHPEN,0.0 +C09-Dicycloparaffin,Hydrindane,C9H16,HYDRIND,0.0 +C10-Dicycloparaffin,Decalin,C10H18,DECALIN,0.0 +C11-Dicycloparaffin,2-methyldecalin,C11H20,METHYLDECALIN-2,0.0 +C12-Dicycloparaffin,2-ethyldecalin,C12H22,ETHYLDECALIN-2,0.0 +C13-Dicycloparaffin,2-propyldecalin,C13H24,PROPYLDECALIN-2,0.0 +C14-Dicycloparaffin,2-butyldecalin,C14H26,BUTYLDECALIN-2,0.0 +C15-Dicycloparaffin,2-pentyldacalin,C15H28,PENTYLDECALIN-2,0.0 +C10-Tricycloparaffin,C1CC2C(C1)C1CCCC21,C10H16,TRICYCLO-C10,0.0 +C11-Tricycloparaffin,C1CC2CC3CCCC3C2C1,C11H18,TRICYCLO-C11,0.0 +C12-Tricycloparaffin,C1CC2CC3CCCC3CC2C1,C12H20,TRICYCLO-C12,0.0 diff --git a/fuellib/data/fuelData/gcData/hefa-tall_init.csv b/fuellib/data/fuelData/gcData/hefa-tall_init.csv new file mode 100644 index 0000000..54ba687 --- /dev/null +++ b/fuellib/data/fuelData/gcData/hefa-tall_init.csv @@ -0,0 +1,68 @@ +Compound,Reference Compound,Formula,PelePhysics Key,Weight % +Toluene,toluene,C7H8,C6H5CH3,0.0 +C2-Benzene,ethyl benzene ,C8H10,C6H5C2H5,0.0 +C3-Benzene,propyl benzene,C9H12,C6H5C3H7,0.0 +C4-Benzene,butyl benzene,C10H14,C6H5C4H9,0.0 +C5-Benzene,pentyl benzene,C11H16,C6H5C5H11,0.0 +C6-Benzene,hexyl benzene,C12H18,C6H5C6H13,0.0 +C7-Benzene,heptyl benzene,C13H20,C6H5C7H15,0.0 +C8-Benzene,octyl benzene,C14H22,C6H5C8H17,0.0 +C9-Benzene,nonyl benzene,C15H24,C6H5C9H19,0.0 +Diaromatic-C10,naphthalene,C10H8,NAPH,0.0 +Diaromatic-C11,1-methyl naphthalene,C11H10,METHYLNAPH-1,0.0 +Diaromatic-C12,1-ethyl naphthalene,C12H12,ETHYLNAPH-1,0.0 +Diaromatic-C13,1-propyl naphthalene,C13H14,PROPYLNAPH-1,0.0 +Cycloaromatic-C09,indane,C9H10,INDANE,0.0 +Cycloaromatic-C10,tetralin,C10H12,TETRA,0.0 +Cycloaromatic-C11,2-methyl tetralin,C11H14,METHYLTETRA-2,0.0 +Cycloaromatic-C12,2-ethly tetralin,C12H16,ETHYLTETRA-2,0.0 +Cycloaromatic-C13,2-propyl tetralin,C13H18,PROPYLTETRA-2,0.0 +Cycloaromatic-C14,2-butyl tetralin,C14H20,BUTYLTETRA-2,0.0 +C07-Isoparaffin,2-methyl hexane,C7H16,C7H16-2,0.0 +C08-Isoparaffin,2-methyl heptane,C8H18,C8H18-2,0.06 +C09-Isoparaffin,2-methyl octane,C9H20,C9H20-2,6.13 +C10-Isoparaffin,2-methyl nonane,C10H22,C10H22-2,12.14 +C11-Isoparaffin,2-methyl decane,C11H24,C11H24-2,12.6 +C12-Isoparaffin,2-methyl undecane,C12H26,C12H26-2,13.52 +C13-Isoparaffin,2-methyl dodecane,C13H28,C13H28-2,12.69 +C14-Isoparaffin,2-methyl tridecane,C14H30,C14H30-2,8.75 +C15-Isoparaffin,2-methyl tetradecane,C15H32,C15H32-2,21.74 +C16-Isoparaffin,2-methyl pentadecane,C16H34,C16H34-2,4.13 +C17-Isoparaffin,2-methyl hexadecane,C17H36,C17H36-2,0.0 +C18-Isoparaffin,2-methyl heptadecane,C18H38,C18H38-2,0.0 +C19-Isoparaffin,2-methyl octadecane,C19H40,C19H40-2,0.0 +C20-Isoparaffin,2-methyl nonadecane,C20H42,C20H42-2,0.0 +n-C07,n-heptane,C7H16,NC7H16,0.0 +n-C08,n-octane,C8H18,NC8H18,0.1 +n-C09,n-nonane,C9H20,NC9H20,1.84 +n-C10,n-decane,C10H22,NC10H22,1.69 +n-C11,n-undecane,C11H24,NC11H24,1.33 +n-C12,n-dodecane,C12H26,NC12H26,1.12 +n-C13,n-tridecane,C13H28,NC13H28,0.86 +n-C14,n-tetradecane,C14H30,NC14H30,0.56 +n-C15,n-pentadecane,C15H32,NC15H32,0.32 +n-C16,n-hexadecane (cetane),C16H34,NC16H34,0.0 +n-C17,n-heptadecane,C17H36,NC17H36,0.0 +n-C18,n-octadecane,C18H38,NC18H38,0.0 +C07-Monocycloparaffin,methyl cyclohexane,C7C14,C6H11CH3,0.0 +C08-Monocycloparaffin,ethyl cyclohexane,C8H16,C6H11C2H5,0.22 +C09-Monocycloparaffin,propyl cyclohexane,C9H18,C6H11C3H7,0.18 +C10-Monocycloparaffin,butyl cyclohexane,C10H20,C6H11C4H9,0.02 +C11-Monocycloparaffin,pentyl cyclohexane,C11H22,C6H11C5H11,0.01 +C12-Monocycloparaffin,hexyl cyclohexane,C12H24,C6H11C6H13,0.0 +C13-Monocycloparaffin,heptyl cyclohexane,C13H26,C6H11C7H15,0.0 +C14-Monocycloparaffin,octyl cyclohexane,C14H28,C6H11C8H17,0.0 +C15-Monocycloparaffin,nonyl cyclohexane,C15H30,C6H11C9H19,0.0 +C16-Monocycloparaffin,decyl cyclohexane,C16H32,C6H11C10H21,0.0 +C17-Monocycloparaffin,undecyl cyclohexane,C17H34,C6H11C11H23,0.0 +C08-Dicycloparaffin,Octahydropentalene,C8H14,OHPEN,0.0 +C09-Dicycloparaffin,Hydrindane,C9H16,HYDRIND,0.0 +C10-Dicycloparaffin,Decalin,C10H18,DECALIN,0.0 +C11-Dicycloparaffin,2-methyldecalin,C11H20,METHYLDECALIN-2,0.0 +C12-Dicycloparaffin,2-ethyldecalin,C12H22,ETHYLDECALIN-2,0.0 +C13-Dicycloparaffin,2-propyldecalin,C13H24,PROPYLDECALIN-2,0.0 +C14-Dicycloparaffin,2-butyldecalin,C14H26,BUTYLDECALIN-2,0.0 +C15-Dicycloparaffin,2-pentyldacalin,C15H28,PENTYLDECALIN-2,0.0 +C10-Tricycloparaffin,C1CC2C(C1)C1CCCC21,C10H16,TRICYCLO-C10,0.0 +C11-Tricycloparaffin,C1CC2CC3CCCC3C2C1,C11H18,TRICYCLO-C11,0.0 +C12-Tricycloparaffin,C1CC2CC3CCCC3CC2C1,C12H20,TRICYCLO-C12,0.0 diff --git a/fuellib/data/fuelData/gcData/heptane-decane_init.csv b/fuellib/data/fuelData/gcData/heptane-decane_init.csv new file mode 100644 index 0000000..fcd2deb --- /dev/null +++ b/fuellib/data/fuelData/gcData/heptane-decane_init.csv @@ -0,0 +1,3 @@ +Compound,Formula,Weight % +n-C07,C7H16,73.75 +n-C10,C10H22,26.25 diff --git a/fuellib/data/fuelData/gcData/heptane_init.csv b/fuellib/data/fuelData/gcData/heptane_init.csv new file mode 100644 index 0000000..7263299 --- /dev/null +++ b/fuellib/data/fuelData/gcData/heptane_init.csv @@ -0,0 +1,2 @@ +Compound,Formula,Weight % +n-C07,C7H16,100 diff --git a/fuellib/data/fuelData/gcData/jet-a_init.csv b/fuellib/data/fuelData/gcData/jet-a_init.csv new file mode 100644 index 0000000..a1f129f --- /dev/null +++ b/fuellib/data/fuelData/gcData/jet-a_init.csv @@ -0,0 +1,68 @@ +Compound,Reference Compound,Formula,PelePhysics Key,Weight % +Toluene,toluene,C7H8,C6H5CH3,0.07 +C2-Benzene,ethyl benzene ,C8H10,C6H5C2H5,1.79 +C3-Benzene,propyl benzene,C9H12,C6H5C3H7,4.54 +C4-Benzene,butyl benzene,C10H14,C6H5C4H9,3.27 +C5-Benzene,pentyl benzene,C11H16,C6H5C5H11,2.73 +C6-Benzene,hexyl benzene,C12H18,C6H5C6H13,1.76 +C7-Benzene,heptyl benzene,C13H20,C6H5C7H15,0.98 +C8-Benzene,octyl benzene,C14H22,C6H5C8H17,0.47 +C9-Benzene,nonyl benzene,C15H24,C6H5C9H19,0.15 +Diaromatic-C10,naphthalene,C10H8,NAPH,0.11 +Diaromatic-C11,1-methyl naphthalene,C11H10,METHYLNAPH-1,0.44 +Diaromatic-C12,1-ethyl naphthalene,C12H12,ETHYLNAPH-1,0.63 +Diaromatic-C13,1-propyl naphthalene,C13H14,PROPYLNAPH-1,0.51 +Cycloaromatic-C09,indane,C9H10,INDANE,0.14 +Cycloaromatic-C10,tetralin,C10H12,TETRA,0.45 +Cycloaromatic-C11,2-methyl tetralin,C11H14,METHYLTETRA-2,2.43 +Cycloaromatic-C12,2-ethly tetralin,C12H16,ETHYLTETRA-2,2.21 +Cycloaromatic-C13,2-propyl tetralin,C13H18,PROPYLTETRA-2,1.46 +Cycloaromatic-C14,2-butyl tetralin,C14H20,BUTYLTETRA-2,0.42 +C07-Isoparaffin,2-methyl hexane,C7H16,C7H16-2,0.01 +C08-Isoparaffin,2-methyl heptane,C8H18,C8H18-2,0.31 +C09-Isoparaffin,2-methyl octane,C9H20,C9H20-2,4.12 +C10-Isoparaffin,2-methyl nonane,C10H22,C10H22-2,6.63 +C11-Isoparaffin,2-methyl decane,C11H24,C11H24-2,5.02 +C12-Isoparaffin,2-methyl undecane,C12H26,C12H26-2,3.21 +C13-Isoparaffin,2-methyl dodecane,C13H28,C13H28-2,2.95 +C14-Isoparaffin,2-methyl tridecane,C14H30,C14H30-2,2.39 +C15-Isoparaffin,2-methyl tetradecane,C15H32,C15H32-2,1.66 +C16-Isoparaffin,2-methyl pentadecane,C16H34,C16H34-2,0.87 +C17-Isoparaffin,2-methyl hexadecane,C17H36,C17H36-2,0.19 +C18-Isoparaffin,2-methyl heptadecane,C18H38,C18H38-2,0.08 +C19-Isoparaffin,2-methyl octadecane,C19H40,C19H40-2,0.0 +C20-Isoparaffin,2-methyl nonadecane,C20H42,C20H42-2,0.0 +n-C07,n-heptane,C7H16,NC7H16,0.0 +n-C08,n-octane,C8H18,NC8H18,0.67 +n-C09,n-nonane,C9H20,NC9H20,4.42 +n-C10,n-decane,C10H22,NC10H22,4.73 +n-C11,n-undecane,C11H24,NC11H24,3.44 +n-C12,n-dodecane,C12H26,NC12H26,2.49 +n-C13,n-tridecane,C13H28,NC13H28,1.93 +n-C14,n-tetradecane,C14H30,NC14H30,1.31 +n-C15,n-pentadecane,C15H32,NC15H32,0.79 +n-C16,n-hexadecane (cetane),C16H34,NC16H34,0.38 +n-C17,n-heptadecane,C17H36,NC17H36,0.09 +n-C18,n-octadecane,C18H38,NC18H38,0.02 +C07-Monocycloparaffin,methyl cyclohexane,C7C14,C6H11CH3,0.19 +C08-Monocycloparaffin,ethyl cyclohexane,C8H16,C6H11C2H5,5.81 +C09-Monocycloparaffin,propyl cyclohexane,C9H18,C6H11C3H7,5.26 +C10-Monocycloparaffin,butyl cyclohexane,C10H20,C6H11C4H9,4.58 +C11-Monocycloparaffin,pentyl cyclohexane,C11H22,C6H11C5H11,2.82 +C12-Monocycloparaffin,hexyl cyclohexane,C12H24,C6H11C6H13,2.5 +C13-Monocycloparaffin,heptyl cyclohexane,C13H26,C6H11C7H15,1.53 +C14-Monocycloparaffin,octyl cyclohexane,C14H28,C6H11C8H17,0.65 +C15-Monocycloparaffin,nonyl cyclohexane,C15H30,C6H11C9H19,0.02 +C16-Monocycloparaffin,decyl cyclohexane,C16H32,C6H11C10H21,0.0 +C17-Monocycloparaffin,undecyl cyclohexane,C17H34,C6H11C11H23,0.0 +C08-Dicycloparaffin,Octahydropentalene,C8H14,OHPEN,0.86 +C09-Dicycloparaffin,Hydrindane,C9H16,HYDRIND,1.21 +C10-Dicycloparaffin,Decalin,C10H18,DECALIN,1.05 +C11-Dicycloparaffin,2-methyldecalin,C11H20,METHYLDECALIN-2,0.8 +C12-Dicycloparaffin,2-ethyldecalin,C12H22,ETHYLDECALIN-2,0.27 +C13-Dicycloparaffin,2-propyldecalin,C13H24,PROPYLDECALIN-2,0.09 +C14-Dicycloparaffin,2-butyldecalin,C14H26,BUTYLDECALIN-2,0.0 +C15-Dicycloparaffin,2-pentyldacalin,C15H28,PENTYLDECALIN-2,0.0 +C10-Tricycloparaffin,C1CC2C(C1)C1CCCC21,C10H16,TRICYCLO-C10,0.0 +C11-Tricycloparaffin,C1CC2CC3CCCC3C2C1,C11H18,TRICYCLO-C11,0.0 +C12-Tricycloparaffin,C1CC2CC3CCCC3CC2C1,C12H20,TRICYCLO-C12,0.0 diff --git a/fuellib/data/fuelData/gcData/posf10264_init.csv b/fuellib/data/fuelData/gcData/posf10264_init.csv new file mode 100644 index 0000000..693d2d7 --- /dev/null +++ b/fuellib/data/fuelData/gcData/posf10264_init.csv @@ -0,0 +1,68 @@ +Compound,Reference Compound,Formula,PelePhysics Key,Weight % +Toluene,toluene,C7H8,C6H5CH3,0.25 +C2-Benzene,ethyl benzene ,C8H10,C6H5C2H5,1.98 +C3-Benzene,propyl benzene,C9H12,C6H5C3H7,4.17 +C4-Benzene,butyl benzene,C10H14,C6H5C4H9,2.33 +C5-Benzene,pentyl benzene,C11H16,C6H5C5H11,1.19 +C6-Benzene,hexyl benzene,C12H18,C6H5C6H13,0.66 +C7-Benzene,heptyl benzene,C13H20,C6H5C7H15,0.25 +C8-Benzene,octyl benzene,C14H22,C6H5C8H17,0.12 +C9-Benzene,nonyl benzene,C15H24,C6H5C9H19,0.06 +Diaromatic-C10,naphthalene,C10H8,NAPH,0.1 +Diaromatic-C11,1-methyl naphthalene,C11H10,METHYLNAPH-1,0.33 +Diaromatic-C12,1-ethyl naphthalene,C12H12,ETHYLNAPH-1,0.41 +Diaromatic-C13,1-propyl naphthalene,C13H14,PROPYLNAPH-1,0.22 +Cycloaromatic-C09,indane,C9H10,INDANE,0.02 +Cycloaromatic-C10,tetralin,C10H12,TETRA,0.19 +Cycloaromatic-C11,2-methyl tetralin,C11H14,METHYLTETRA-2,0.37 +Cycloaromatic-C12,2-ethly tetralin,C12H16,ETHYLTETRA-2,0.38 +Cycloaromatic-C13,2-propyl tetralin,C13H18,PROPYLTETRA-2,0.34 +Cycloaromatic-C14,2-butyl tetralin,C14H20,BUTYLTETRA-2,0.19 +C07-Isoparaffin,2-methyl hexane,C7H16,C7H16-2,0.21 +C08-Isoparaffin,2-methyl heptane,C8H18,C8H18-2,0.88 +C09-Isoparaffin,2-methyl octane,C9H20,C9H20-2,2.59 +C10-Isoparaffin,2-methyl nonane,C10H22,C10H22-2,8.15 +C11-Isoparaffin,2-methyl decane,C11H24,C11H24-2,8.38 +C12-Isoparaffin,2-methyl undecane,C12H26,C12H26-2,5.41 +C13-Isoparaffin,2-methyl dodecane,C13H28,C13H28-2,4.63 +C14-Isoparaffin,2-methyl tridecane,C14H30,C14H30-2,3.96 +C15-Isoparaffin,2-methyl tetradecane,C15H32,C15H32-2,2.28 +C16-Isoparaffin,2-methyl pentadecane,C16H34,C16H34-2,0.75 +C17-Isoparaffin,2-methyl hexadecane,C17H36,C17H36-2,0.2 +C18-Isoparaffin,2-methyl heptadecane,C18H38,C18H38-2,0.03 +C19-Isoparaffin,2-methyl octadecane,C19H40,C19H40-2,0.0 +C20-Isoparaffin,2-methyl nonadecane,C20H42,C20H42-2,0.0 +n-C07,n-heptane,C7H16,NC7H16,0.24 +n-C08,n-octane,C8H18,NC8H18,1.11 +n-C09,n-nonane,C9H20,NC9H20,2.97 +n-C10,n-decane,C10H22,NC10H22,6.46 +n-C11,n-undecane,C11H24,NC11H24,5.22 +n-C12,n-dodecane,C12H26,NC12H26,3.99 +n-C13,n-tridecane,C13H28,NC13H28,2.97 +n-C14,n-tetradecane,C14H30,NC14H30,1.97 +n-C15,n-pentadecane,C15H32,NC15H32,0.83 +n-C16,n-hexadecane (cetane),C16H34,NC16H34,0.23 +n-C17,n-heptadecane,C17H36,NC17H36,0.06 +n-C18,n-octadecane,C18H38,NC18H38,0.0 +C07-Monocycloparaffin,methyl cyclohexane,C7C14,C6H11CH3,0.51 +C08-Monocycloparaffin,ethyl cyclohexane,C8H16,C6H11C2H5,1.01 +C09-Monocycloparaffin,propyl cyclohexane,C9H18,C6H11C3H7,3.06 +C10-Monocycloparaffin,butyl cyclohexane,C10H20,C6H11C4H9,4.47 +C11-Monocycloparaffin,pentyl cyclohexane,C11H22,C6H11C5H11,3.55 +C12-Monocycloparaffin,hexyl cyclohexane,C12H24,C6H11C6H13,2.45 +C13-Monocycloparaffin,heptyl cyclohexane,C13H26,C6H11C7H15,2.25 +C14-Monocycloparaffin,octyl cyclohexane,C14H28,C6H11C8H17,1.19 +C15-Monocycloparaffin,nonyl cyclohexane,C15H30,C6H11C9H19,0.77 +C16-Monocycloparaffin,decyl cyclohexane,C16H32,C6H11C10H21,0.11 +C17-Monocycloparaffin,undecyl cyclohexane,C17H34,C6H11C11H23,0.02 +C08-Dicycloparaffin,Octahydropentalene,C8H14,OHPEN,0.03 +C09-Dicycloparaffin,Hydrindane,C9H16,HYDRIND,0.35 +C10-Dicycloparaffin,Decalin,C10H18,DECALIN,0.47 +C11-Dicycloparaffin,2-methyldecalin,C11H20,METHYLDECALIN-2,0.71 +C12-Dicycloparaffin,2-ethyldecalin,C12H22,ETHYLDECALIN-2,0.77 +C13-Dicycloparaffin,2-propyldecalin,C13H24,PROPYLDECALIN-2,0.52 +C14-Dicycloparaffin,2-butyldecalin,C14H26,BUTYLDECALIN-2,0.45 +C15-Dicycloparaffin,2-pentyldacalin,C15H28,PENTYLDECALIN-2,0.08 +C10-Tricycloparaffin,C1CC2C(C1)C1CCCC21,C10H16,TRICYCLO-C10,0.0 +C11-Tricycloparaffin,C1CC2CC3CCCC3C2C1,C11H18,TRICYCLO-C11,0.11 +C12-Tricycloparaffin,C1CC2CC3CCCC3CC2C1,C12H20,TRICYCLO-C12,0.0 diff --git a/fuellib/data/fuelData/gcData/posf10289_init.csv b/fuellib/data/fuelData/gcData/posf10289_init.csv new file mode 100644 index 0000000..90b0c53 --- /dev/null +++ b/fuellib/data/fuelData/gcData/posf10289_init.csv @@ -0,0 +1,68 @@ +Compound,Reference Compound,Formula,PelePhysics Key,Weight % +Toluene,toluene,C7H8,C6H5CH3,0.03 +C2-Benzene,ethyl benzene ,C8H10,C6H5C2H5,0.41 +C3-Benzene,propyl benzene,C9H12,C6H5C3H7,1.32 +C4-Benzene,butyl benzene,C10H14,C6H5C4H9,2.09 +C5-Benzene,pentyl benzene,C11H16,C6H5C5H11,1.98 +C6-Benzene,hexyl benzene,C12H18,C6H5C6H13,1.8 +C7-Benzene,heptyl benzene,C13H20,C6H5C7H15,1.24 +C8-Benzene,octyl benzene,C14H22,C6H5C8H17,1.05 +C9-Benzene,nonyl benzene,C15H24,C6H5C9H19,0.42 +Diaromatic-C10,naphthalene,C10H8,NAPH,0.09 +Diaromatic-C11,1-methyl naphthalene,C11H10,METHYLNAPH-1,0.33 +Diaromatic-C12,1-ethyl naphthalene,C12H12,ETHYLNAPH-1,0.6 +Diaromatic-C13,1-propyl naphthalene,C13H14,PROPYLNAPH-1,0.33 +Cycloaromatic-C09,indane,C9H10,INDANE,0.03 +Cycloaromatic-C10,tetralin,C10H12,TETRA,0.57 +Cycloaromatic-C11,2-methyl tetralin,C11H14,METHYLTETRA-2,1.91 +Cycloaromatic-C12,2-ethly tetralin,C12H16,ETHYLTETRA-2,2.67 +Cycloaromatic-C13,2-propyl tetralin,C13H18,PROPYLTETRA-2,2.27 +Cycloaromatic-C14,2-butyl tetralin,C14H20,BUTYLTETRA-2,1.22 +C07-Isoparaffin,2-methyl hexane,C7H16,C7H16-2,0.02 +C08-Isoparaffin,2-methyl heptane,C8H18,C8H18-2,0.13 +C09-Isoparaffin,2-methyl octane,C9H20,C9H20-2,0.48 +C10-Isoparaffin,2-methyl nonane,C10H22,C10H22-2,1.66 +C11-Isoparaffin,2-methyl decane,C11H24,C11H24-2,2.73 +C12-Isoparaffin,2-methyl undecane,C12H26,C12H26-2,3.36 +C13-Isoparaffin,2-methyl dodecane,C13H28,C13H28-2,3.57 +C14-Isoparaffin,2-methyl tridecane,C14H30,C14H30-2,3.54 +C15-Isoparaffin,2-methyl tetradecane,C15H32,C15H32-2,2.7 +C16-Isoparaffin,2-methyl pentadecane,C16H34,C16H34-2,0.65 +C17-Isoparaffin,2-methyl hexadecane,C17H36,C17H36-2,0.08 +C18-Isoparaffin,2-methyl heptadecane,C18H38,C18H38-2,0.0 +C19-Isoparaffin,2-methyl octadecane,C19H40,C19H40-2,0.0 +C20-Isoparaffin,2-methyl nonadecane,C20H42,C20H42-2,0.0 +n-C07,n-heptane,C7H16,NC7H16,0.02 +n-C08,n-octane,C8H18,NC8H18,0.19 +n-C09,n-nonane,C9H20,NC9H20,0.64 +n-C10,n-decane,C10H22,NC10H22,1.41 +n-C11,n-undecane,C11H24,NC11H24,2.6 +n-C12,n-dodecane,C12H26,NC12H26,3.09 +n-C13,n-tridecane,C13H28,NC13H28,2.5 +n-C14,n-tetradecane,C14H30,NC14H30,1.92 +n-C15,n-pentadecane,C15H32,NC15H32,0.86 +n-C16,n-hexadecane (cetane),C16H34,NC16H34,0.11 +n-C17,n-heptadecane,C17H36,NC17H36,0.01 +n-C18,n-octadecane,C18H38,NC18H38,0.0 +C07-Monocycloparaffin,methyl cyclohexane,C7C14,C6H11CH3,0.08 +C08-Monocycloparaffin,ethyl cyclohexane,C8H16,C6H11C2H5,0.35 +C09-Monocycloparaffin,propyl cyclohexane,C9H18,C6H11C3H7,1.53 +C10-Monocycloparaffin,butyl cyclohexane,C10H20,C6H11C4H9,3.25 +C11-Monocycloparaffin,pentyl cyclohexane,C11H22,C6H11C5H11,5.77 +C12-Monocycloparaffin,hexyl cyclohexane,C12H24,C6H11C6H13,6.25 +C13-Monocycloparaffin,heptyl cyclohexane,C13H26,C6H11C7H15,6.11 +C14-Monocycloparaffin,octyl cyclohexane,C14H28,C6H11C8H17,4.22 +C15-Monocycloparaffin,nonyl cyclohexane,C15H30,C6H11C9H19,2.27 +C16-Monocycloparaffin,decyl cyclohexane,C16H32,C6H11C10H21,0.41 +C17-Monocycloparaffin,undecyl cyclohexane,C17H34,C6H11C11H23,0.01 +C08-Dicycloparaffin,Octahydropentalene,C8H14,OHPEN,0.03 +C09-Dicycloparaffin,Hydrindane,C9H16,HYDRIND,0.46 +C10-Dicycloparaffin,Decalin,C10H18,DECALIN,1.04 +C11-Dicycloparaffin,2-methyldecalin,C11H20,METHYLDECALIN-2,2.84 +C12-Dicycloparaffin,2-ethyldecalin,C12H22,ETHYLDECALIN-2,4.33 +C13-Dicycloparaffin,2-propyldecalin,C13H24,PROPYLDECALIN-2,4.53 +C14-Dicycloparaffin,2-butyldecalin,C14H26,BUTYLDECALIN-2,3.14 +C15-Dicycloparaffin,2-pentyldacalin,C15H28,PENTYLDECALIN-2,0.67 +C10-Tricycloparaffin,C1CC2C(C1)C1CCCC21,C10H16,TRICYCLO-C10,0.0 +C11-Tricycloparaffin,C1CC2CC3CCCC3C2C1,C11H18,TRICYCLO-C11,0.1 +C12-Tricycloparaffin,C1CC2CC3CCCC3CC2C1,C12H20,TRICYCLO-C12,0.0 diff --git a/fuellib/data/fuelData/gcData/posf10325_init.csv b/fuellib/data/fuelData/gcData/posf10325_init.csv new file mode 100644 index 0000000..81e117c --- /dev/null +++ b/fuellib/data/fuelData/gcData/posf10325_init.csv @@ -0,0 +1,68 @@ +Compound,Reference Compound,Formula,PelePhysics Key,Weight % +Toluene,toluene,C7H8,C6H5CH3,0.17 +C2-Benzene,ethyl benzene ,C8H10,C6H5C2H5,1.1 +C3-Benzene,propyl benzene,C9H12,C6H5C3H7,2.97 +C4-Benzene,butyl benzene,C10H14,C6H5C4H9,3.32 +C5-Benzene,pentyl benzene,C11H16,C6H5C5H11,2.22 +C6-Benzene,hexyl benzene,C12H18,C6H5C6H13,1.45 +C7-Benzene,heptyl benzene,C13H20,C6H5C7H15,0.73 +C8-Benzene,octyl benzene,C14H22,C6H5C8H17,0.52 +C9-Benzene,nonyl benzene,C15H24,C6H5C9H19,0.42 +Diaromatic-C10,naphthalene,C10H8,NAPH,0.22 +Diaromatic-C11,1-methyl naphthalene,C11H10,METHYLNAPH-1,0.66 +Diaromatic-C12,1-ethyl naphthalene,C12H12,ETHYLNAPH-1,0.86 +Diaromatic-C13,1-propyl naphthalene,C13H14,PROPYLNAPH-1,0.6 +Cycloaromatic-C09,indane,C9H10,INDANE,0.02 +Cycloaromatic-C10,tetralin,C10H12,TETRA,0.26 +Cycloaromatic-C11,2-methyl tetralin,C11H14,METHYLTETRA-2,0.66 +Cycloaromatic-C12,2-ethly tetralin,C12H16,ETHYLTETRA-2,0.89 +Cycloaromatic-C13,2-propyl tetralin,C13H18,PROPYLTETRA-2,0.85 +Cycloaromatic-C14,2-butyl tetralin,C14H20,BUTYLTETRA-2,0.61 +C07-Isoparaffin,2-methyl hexane,C7H16,C7H16-2,0.15 +C08-Isoparaffin,2-methyl heptane,C8H18,C8H18-2,0.44 +C09-Isoparaffin,2-methyl octane,C9H20,C9H20-2,1.05 +C10-Isoparaffin,2-methyl nonane,C10H22,C10H22-2,4.2 +C11-Isoparaffin,2-methyl decane,C11H24,C11H24-2,5.7 +C12-Isoparaffin,2-methyl undecane,C12H26,C12H26-2,5.63 +C13-Isoparaffin,2-methyl dodecane,C13H28,C13H28-2,4.22 +C14-Isoparaffin,2-methyl tridecane,C14H30,C14H30-2,4.2 +C15-Isoparaffin,2-methyl tetradecane,C15H32,C15H32-2,2.51 +C16-Isoparaffin,2-methyl pentadecane,C16H34,C16H34-2,1.0 +C17-Isoparaffin,2-methyl hexadecane,C17H36,C17H36-2,0.39 +C18-Isoparaffin,2-methyl heptadecane,C18H38,C18H38-2,0.11 +C19-Isoparaffin,2-methyl octadecane,C19H40,C19H40-2,0.03 +C20-Isoparaffin,2-methyl nonadecane,C20H42,C20H42-2,0.03 +n-C07,n-heptane,C7H16,NC7H16,0.17 +n-C08,n-octane,C8H18,NC8H18,0.54 +n-C09,n-nonane,C9H20,NC9H20,1.42 +n-C10,n-decane,C10H22,NC10H22,3.26 +n-C11,n-undecane,C11H24,NC11H24,4.29 +n-C12,n-dodecane,C12H26,NC12H26,3.74 +n-C13,n-tridecane,C13H28,NC13H28,2.8 +n-C14,n-tetradecane,C14H30,NC14H30,2.02 +n-C15,n-pentadecane,C15H32,NC15H32,1.03 +n-C16,n-hexadecane (cetane),C16H34,NC16H34,0.43 +n-C17,n-heptadecane,C17H36,NC17H36,0.21 +n-C18,n-octadecane,C18H38,NC18H38,0.06 +C07-Monocycloparaffin,methyl cyclohexane,C7C14,C6H11CH3,0.36 +C08-Monocycloparaffin,ethyl cyclohexane,C8H16,C6H11C2H5,0.78 +C09-Monocycloparaffin,propyl cyclohexane,C9H18,C6H11C3H7,2.3 +C10-Monocycloparaffin,butyl cyclohexane,C10H20,C6H11C4H9,4.11 +C11-Monocycloparaffin,pentyl cyclohexane,C11H22,C6H11C5H11,5.43 +C12-Monocycloparaffin,hexyl cyclohexane,C12H24,C6H11C6H13,3.73 +C13-Monocycloparaffin,heptyl cyclohexane,C13H26,C6H11C7H15,4.19 +C14-Monocycloparaffin,octyl cyclohexane,C14H28,C6H11C8H17,2.19 +C15-Monocycloparaffin,nonyl cyclohexane,C15H30,C6H11C9H19,1.33 +C16-Monocycloparaffin,decyl cyclohexane,C16H32,C6H11C10H21,0.42 +C17-Monocycloparaffin,undecyl cyclohexane,C17H34,C6H11C11H23,0.24 +C08-Dicycloparaffin,Octahydropentalene,C8H14,OHPEN,0.03 +C09-Dicycloparaffin,Hydrindane,C9H16,HYDRIND,0.43 +C10-Dicycloparaffin,Decalin,C10H18,DECALIN,0.72 +C11-Dicycloparaffin,2-methyldecalin,C11H20,METHYLDECALIN-2,1.52 +C12-Dicycloparaffin,2-ethyldecalin,C12H22,ETHYLDECALIN-2,1.57 +C13-Dicycloparaffin,2-propyldecalin,C13H24,PROPYLDECALIN-2,1.21 +C14-Dicycloparaffin,2-butyldecalin,C14H26,BUTYLDECALIN-2,0.81 +C15-Dicycloparaffin,2-pentyldacalin,C15H28,PENTYLDECALIN-2,0.27 +C10-Tricycloparaffin,C1CC2C(C1)C1CCCC21,C10H16,TRICYCLO-C10,0.0 +C11-Tricycloparaffin,C1CC2CC3CCCC3C2C1,C11H18,TRICYCLO-C11,0.16 +C12-Tricycloparaffin,C1CC2CC3CCCC3CC2C1,C12H20,TRICYCLO-C12,0.0 diff --git a/fuellib/data/fuelData/gcData/posf11498_init.csv b/fuellib/data/fuelData/gcData/posf11498_init.csv new file mode 100644 index 0000000..c04dd00 --- /dev/null +++ b/fuellib/data/fuelData/gcData/posf11498_init.csv @@ -0,0 +1,14 @@ +Compound,Reference Compound,Formula,PelePhysics Key,Weight % +C07-Isoparaffin,2-methyl hexane,C7H16,C7H16-2,0.02 +C08-Isoparaffin,2-methyl heptane,C8H18,C8H18-2,0.61 +C09-Isoparaffin,2-methyl octane,C9H20,C9H20-2,0.17 +C10-Isoparaffin,2-methyl nonane,C10H22,C10H22-2,0.22 +C11-Isoparaffin,2-methyl decane,C11H24,C11H24-2,0.52 +C12-Isoparaffin,2-methyl undecane,C12H26,C12H26-2,78.28 +C13-Isoparaffin,2-methyl dodecane,C13H28,C13H28-2,1.23 +C14-Isoparaffin,2-methyl tridecane,C14H30,C14H30-2,0.53 +C16-Isoparaffin,2-methyl pentadecane,C16H34,C16H34-2,16.25 +C20-Isoparaffin,2-methyl nonadecane,C20H42,C20H42-2,1.69 +C24-Isoparaffin,2-methyltricosane,C24H50,C24H50-2,0.12 +C12-Alkene,1-dodecene,C12H24,DODECENE-1,0.08 +C16-Alkene,1-hexadecene,C16H32,HEXADECENE-1,0.24 diff --git a/fuellib/data/fuelData/gcData/posf4658_init.csv b/fuellib/data/fuelData/gcData/posf4658_init.csv new file mode 100644 index 0000000..5f5746f --- /dev/null +++ b/fuellib/data/fuelData/gcData/posf4658_init.csv @@ -0,0 +1,68 @@ +Compound,Reference Compound,Formula,PelePhysics Key,Weight % +Toluene,toluene,C7H8,C6H5CH3,0.16 +C2-Benzene,ethyl benzene,C8H10,C6H5C2H5,0.78 +C3-Benzene,propyl benzene,C9H12,C6H5C3H7,2.24 +C4-Benzene,butyl benzene,C10H14,C6H5C4H9,3.02 +C5-Benzene,pentyl benzene,C11H16,C6H5C5H11,2.48 +C6-Benzene,hexyl benzene,C12H18,C6H5C6H13,1.93 +C7-Benzene,heptyl benzene,C13H20,C6H5C7H15,1.19 +C8-Benzene,octyl benzene,C14H22,C6H5C8H17,0.89 +C9-Benzene,nonyl benzene,C15H24,C6H5C9H19,1.0 +Diaromatic-C10,naphthalene,C10H8,NAPH,0.12 +Diaromatic-C11,1-methyl naphthalene,C11H10,METHYLNAPH-1,0.42 +Diaromatic-C12,1-ethyl naphthalene,C12H12,ETHYLNAPH-1,0.6 +Diaromatic-C13,1-propyl naphthalene,C13H14,PROPYLNAPH-1,0.63 +Cycloaromatic-C09,indane,C9H10,INDANE,0.04 +Cycloaromatic-C10,tetralin,C10H12,TETRA,0.43 +Cycloaromatic-C11,2-methyl tetralin,C11H14,METHYLTETRA-2,1.13 +Cycloaromatic-C12,2-ethly tetralin,C12H16,ETHYLTETRA-2,1.63 +Cycloaromatic-C13,2-propyl tetralin,C13H18,PROPYLTETRA-2,1.45 +Cycloaromatic-C14,2-butyl tetralin,C14H20,BUTYLTETRA-2,1.12 +C07-Isoparaffin,2-methyl hexane,C7H16,C7H16-2,0.23 +C08-Isoparaffin,2-methyl heptane,C8H18,C8H18-2,0.56 +C09-Isoparaffin,2-methyl octane,C9H20,C9H20-2,1.08 +C10-Isoparaffin,2-methyl nonane,C10H22,C10H22-2,3.59 +C11-Isoparaffin,2-methyl decane,C11H24,C11H24-2,5.12 +C12-Isoparaffin,2-methyl undecane,C12H26,C12H26-2,5.31 +C13-Isoparaffin,2-methyl dodecane,C13H28,C13H28-2,5.25 +C14-Isoparaffin,2-methyl tridecane,C14H30,C14H30-2,4.44 +C15-Isoparaffin,2-methyl tetradecane,C15H32,C15H32-2,3.1 +C16-Isoparaffin,2-methyl pentadecane,C16H34,C16H34-2,1.66 +C17-Isoparaffin,2-methyl hexadecane,C17H36,C17H36-2,0.69 +C18-Isoparaffin,2-methyl heptadecane,C18H38,C18H38-2,0.19 +C19-Isoparaffin,2-methyl octadecane,C19H40,C19H40-2,0.08 +C20-Isoparaffin,2-methyl nonadecane,C20H42,C20H42-2,0.02 +n-C07,n-heptane,C7H16,NC7H16,0.15 +n-C08,n-octane,C8H18,NC8H18,0.54 +n-C09,n-nonane,C9H20,NC9H20,1.14 +n-C10,n-decane,C10H22,NC10H22,2.55 +n-C11,n-undecane,C11H24,NC11H24,3.62 +n-C12,n-dodecane,C12H26,NC12H26,3.7 +n-C13,n-tridecane,C13H28,NC13H28,2.86 +n-C14,n-tetradecane,C14H30,NC14H30,2.17 +n-C15,n-pentadecane,C15H32,NC15H32,1.28 +n-C16,n-hexadecane (cetane),C16H34,NC16H34,0.61 +n-C17,n-heptadecane,C17H36,NC17H36,0.27 +n-C18,n-octadecane,C18H38,NC18H38,0.07 +C07-Monocycloparaffin,methyl cyclohexane,C7C14,C6H11CH3,0.2 +C08-Monocycloparaffin,ethyl cyclohexane,C8H16,C6H11C2H5,0.69 +C09-Monocycloparaffin,propyl cyclohexane,C9H18,C6H11C3H7,1.67 +C10-Monocycloparaffin,butyl cyclohexane,C10H20,C6H11C4H9,3.26 +C11-Monocycloparaffin,pentyl cyclohexane,C11H22,C6H11C5H11,4.11 +C12-Monocycloparaffin,hexyl cyclohexane,C12H24,C6H11C6H13,4.07 +C13-Monocycloparaffin,heptyl cyclohexane,C13H26,C6H11C7H15,3.65 +C14-Monocycloparaffin,octyl cyclohexane,C14H28,C6H11C8H17,2.43 +C15-Monocycloparaffin,nonyl cyclohexane,C15H30,C6H11C9H19,1.55 +C16-Monocycloparaffin,decyl cyclohexane,C16H32,C6H11C10H21,0.64 +C17-Monocycloparaffin,undecyl cyclohexane,C17H34,C6H11C11H23,0.37 +C08-Dicycloparaffin,Octahydropentalene,C8H14,OHPEN,0.02 +C09-Dicycloparaffin,Hydrindane,C9H16,HYDRIND,0.29 +C10-Dicycloparaffin,Decalin,C10H18,DECALIN,0.43 +C11-Dicycloparaffin,2-methyldecalin,C11H20,METHYLDECALIN-2,1.26 +C12-Dicycloparaffin,2-ethyldecalin,C12H22,ETHYLDECALIN-2,1.22 +C13-Dicycloparaffin,2-propyldecalin,C13H24,PROPYLDECALIN-2,1.42 +C14-Dicycloparaffin,2-butyldecalin,C14H26,BUTYLDECALIN-2,0.82 +C15-Dicycloparaffin,2-pentyldacalin,C15H28,PENTYLDECALIN-2,0.26 +C10-Tricycloparaffin,C1CC2C(C1)C1CCCC21,C10H16,TRICYCLO-C10,0.0 +C11-Tricycloparaffin,C1CC2CC3CCCC3C2C1,C11H18,TRICYCLO-C11,0.05 +C12-Tricycloparaffin,C1CC2CC3CCCC3CC2C1,C12H20,TRICYCLO-C12,0.0 diff --git a/fuellib/data/fuelData/groupDecompositionData/__init__.py b/fuellib/data/fuelData/groupDecompositionData/__init__.py new file mode 100644 index 0000000..cee26ca --- /dev/null +++ b/fuellib/data/fuelData/groupDecompositionData/__init__.py @@ -0,0 +1 @@ +"""Group decomposition data.""" diff --git a/fuelData/groupDecompositionData/decane.csv b/fuellib/data/fuelData/groupDecompositionData/decane.csv similarity index 100% rename from fuelData/groupDecompositionData/decane.csv rename to fuellib/data/fuelData/groupDecompositionData/decane.csv diff --git a/fuelData/groupDecompositionData/dodecane.csv b/fuellib/data/fuelData/groupDecompositionData/dodecane.csv similarity index 100% rename from fuelData/groupDecompositionData/dodecane.csv rename to fuellib/data/fuelData/groupDecompositionData/dodecane.csv diff --git a/fuelData/groupDecompositionData/hefa.csv b/fuellib/data/fuelData/groupDecompositionData/hefa.csv similarity index 99% rename from fuelData/groupDecompositionData/hefa.csv rename to fuellib/data/fuelData/groupDecompositionData/hefa.csv index 53b4bfd..e4cf12e 100644 --- a/fuelData/groupDecompositionData/hefa.csv +++ b/fuellib/data/fuelData/groupDecompositionData/hefa.csv @@ -12,7 +12,7 @@ Diaromatic-C10,0,0,0,0,0,0,0,0,0,0,8,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Diaromatic-C11,0,0,0,0,0,0,0,0,0,0,7,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Diaromatic-C12,1,0,0,0,0,0,0,0,0,0,7,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Diaromatic-C13,1,1,0,0,0,0,0,0,0,0,7,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C09,0,1,0,0,0,0,0,0,0,0,4,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +Cycloaromatic-C09,0,1,0,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Cycloaromatic-C10,0,2,0,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Cycloaromatic-C11,1,1,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Cycloaromatic-C12,1,2,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 diff --git a/fuelData/groupDecompositionData/heptane-decane.csv b/fuellib/data/fuelData/groupDecompositionData/heptane-decane.csv similarity index 100% rename from fuelData/groupDecompositionData/heptane-decane.csv rename to fuellib/data/fuelData/groupDecompositionData/heptane-decane.csv diff --git a/fuelData/groupDecompositionData/heptane.csv b/fuellib/data/fuelData/groupDecompositionData/heptane.csv similarity index 100% rename from fuelData/groupDecompositionData/heptane.csv rename to fuellib/data/fuelData/groupDecompositionData/heptane.csv diff --git a/fuelData/groupDecompositionData/jet-a.csv b/fuellib/data/fuelData/groupDecompositionData/jet-a.csv similarity index 99% rename from fuelData/groupDecompositionData/jet-a.csv rename to fuellib/data/fuelData/groupDecompositionData/jet-a.csv index b0216f6..e513610 100644 --- a/fuelData/groupDecompositionData/jet-a.csv +++ b/fuellib/data/fuelData/groupDecompositionData/jet-a.csv @@ -12,7 +12,7 @@ Diaromatic-C10,0,0,0,0,0,0,0,0,0,0,8,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Diaromatic-C11,0,0,0,0,0,0,0,0,0,0,7,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Diaromatic-C12,1,0,0,0,0,0,0,0,0,0,7,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Diaromatic-C13,1,1,0,0,0,0,0,0,0,0,7,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C09,0,1,0,0,0,0,0,0,0,0,4,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +Cycloaromatic-C09,0,1,0,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Cycloaromatic-C10,0,2,0,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Cycloaromatic-C11,1,1,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Cycloaromatic-C12,1,2,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 diff --git a/fuelData/groupDecompositionData/posf10264.csv b/fuellib/data/fuelData/groupDecompositionData/posf-cat-a.csv similarity index 99% rename from fuelData/groupDecompositionData/posf10264.csv rename to fuellib/data/fuelData/groupDecompositionData/posf-cat-a.csv index b0216f6..e513610 100644 --- a/fuelData/groupDecompositionData/posf10264.csv +++ b/fuellib/data/fuelData/groupDecompositionData/posf-cat-a.csv @@ -12,7 +12,7 @@ Diaromatic-C10,0,0,0,0,0,0,0,0,0,0,8,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Diaromatic-C11,0,0,0,0,0,0,0,0,0,0,7,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Diaromatic-C12,1,0,0,0,0,0,0,0,0,0,7,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Diaromatic-C13,1,1,0,0,0,0,0,0,0,0,7,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C09,0,1,0,0,0,0,0,0,0,0,4,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +Cycloaromatic-C09,0,1,0,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Cycloaromatic-C10,0,2,0,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Cycloaromatic-C11,1,1,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Cycloaromatic-C12,1,2,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 diff --git a/fuelData/groupDecompositionData/posf11498.csv b/fuellib/data/fuelData/groupDecompositionData/posf11498.csv similarity index 100% rename from fuelData/groupDecompositionData/posf11498.csv rename to fuellib/data/fuelData/groupDecompositionData/posf11498.csv diff --git a/fuelData/groupDecompositionData/refCompounds.csv b/fuellib/data/fuelData/groupDecompositionData/refCompounds.csv similarity index 96% rename from fuelData/groupDecompositionData/refCompounds.csv rename to fuellib/data/fuelData/groupDecompositionData/refCompounds.csv index acbb91d..1090d9b 100755 --- a/fuelData/groupDecompositionData/refCompounds.csv +++ b/fuellib/data/fuelData/groupDecompositionData/refCompounds.csv @@ -1,4 +1,4 @@ -Compound,CH3 (1),CH2 (2),CH (3),C (4),CH2=CH (1),CH=CH (2),CH2=C (2),CH=C (3),C=C (4),CH2=C=CH(1),ACH (2),AC (3),ACCH3 (2),ACCH2 (3),ACCH (4),OH (1),ACOH (2),CH3CO (1),CH2CO (2),CHO (1)*,CH3COO (1),CH2COO (2),HCOO (1),CH30 (1),CH20 (2),CH-O (3),FCH20 (1)*,CH2NH2 (1),CHNH2 (2),CH3NH (2),CH2NH (3),CHNH (4)*,CH3N (2),CH2N (3),ACNH2 (2),C5H4N (1),C5H3N (2),CH2CN (1)*,COOH (1),CH2C1 (1),CHC1 (2),CC1 (3),CHC12 (1)*,CC13 (1),CC12 (2),ACC1 (2),CH2N02 (1)*,CHN02 (2)*,ACN02 (2)*,CH2SH (1),C1(1)*,Br (1),CH≡C (1),C≡C (2)*,Cl—(C=C) (3)*,ACF (2),HCON(CH2)2 (2)*,CF3 (1),CF2 (2),CF (3),COO (2),CC12F (1),HCC1F (1),CC1F2 (1),FSpecial (1),CONH2 (1)*,CONHCH3 (1)*,CONHCH2 (1)*,CON(CH3)2 (1)*,CONCH2CH2 (3)*,CON(CH2)2 (3)*,C2H502 (1)*,C2H402 (2),CH3S (1),CH2S (2),CHS (3)*,C4H3S (1),C4H2S (2)*,Group j (CH3)2CH,(CH3)3C,CH(CH3)CH(CH3),CH(CH3)C(CH3)2,C(CH3)2C(CH3)2,3 membered ring,4 membered ring,5 membered ring,6 membered ring,7 membered ring,"CR=CRm—CRp=CRk m, p G (0,1), K n G (0,2)","CH3-CHm=CH, m G (0,1), n G (0,2)","CH2-CHm=CH, m G (0,1), n G (0,2)","CH—CUm=CUn or C—CHm=CH/ m G (0,1), n G (0,2)",Alicyclic side-chain CcyclicCm m > 1,ch3ch3,CHCHO or CCHO*,CH3COCH2,CH3COCH or CH3COC,Ccyclic^=0,ACCHO*,CHCOOH or CCOOH*,ACCOOH*,CH3COOCH or CH3COOC,COCH2COO or COCHCOO or COCCOO*, CO—O—CO,ACCOO*,CHOH,COH,CHm(OH)CHn(OH),CHm cyclic-OH,CHn(OH)CHm(NHp),CHm(NH2)CHn(NH2)*,CHm cyclic—NHp—CHn cyclic*,CHnOCHmCHp*,AC—O—CHm*,CHm cyclic—S—CHn cyclic,CHnCHm—F,CHnCHm—Br*,CHnCHm—I*,ACBr*,ACI*,CHm(NH2)—COOH* +Compound,CH3 (1),CH2 (2),CH (3),C (4),CH2=CH (1),CH=CH (2),CH2=C (2),CH=C (3),C=C (4),CH2=C=CH(1),ACH (2),AC (3),ACCH3 (2),ACCH2 (3),ACCH (4),OH (1),ACOH (2),CH3CO (1),CH2CO (2),CHO (1)*,CH3COO (1),CH2COO (2),HCOO (1),CH30 (1),CH20 (2),CH-O (3),FCH20 (1)*,CH2NH2 (1),CHNH2 (2),CH3NH (2),CH2NH (3),CHNH (4)*,CH3N (2),CH2N (3),ACNH2 (2),C5H4N (1),C5H3N (2),CH2CN (1)*,COOH (1),CH2C1 (1),CHC1 (2),CC1 (3),CHC12 (1)*,CC13 (1),CC12 (2),ACC1 (2),CH2N02 (1)*,CHN02 (2)*,ACN02 (2)*,CH2SH (1),C1(1)*,Br (1),CH≡C (1),C≡C (2)*,Cl—(C=C) (3)*,ACF (2),HCON(CH2)2 (2)*,CF3 (1),CF2 (2),CF (3),COO (2),CC12F (1),HCC1F (1),CC1F2 (1),FSpecial (1),CONH2 (1)*,CONHCH3 (1)*,CONHCH2 (1)*,CON(CH3)2 (1)*,CONCH2CH2 (3)*,CON(CH2)2 (3)*,C2H502 (1)*,C2H402 (2),CH3S (1),CH2S (2),CHS (3)*,C4H3S (1),C4H2S (2)*,(CH3)2CH,(CH3)3C,CH(CH3)CH(CH3),CH(CH3)C(CH3)2,C(CH3)2C(CH3)2,3 membered ring,4 membered ring,5 membered ring,6 membered ring,7 membered ring,"CR=CRm—CRp=CRk m, p G (0,1), K n G (0,2)","CH3-CHm=CH, m G (0,1), n G (0,2)","CH2-CHm=CH, m G (0,1), n G (0,2)","CH—CUm=CUn or C—CHm=CH/ m G (0,1), n G (0,2)",Alicyclic side-chain CcyclicCm m > 1,ch3ch3,CHCHO or CCHO*,CH3COCH2,CH3COCH or CH3COC,Ccyclic^=0,ACCHO*,CHCOOH or CCOOH*,ACCOOH*,CH3COOCH or CH3COOC,COCH2COO or COCHCOO or COCCOO*, CO—O—CO,ACCOO*,CHOH,COH,CHm(OH)CHn(OH),CHm cyclic-OH,CHn(OH)CHm(NHp),CHm(NH2)CHn(NH2)*,CHm cyclic—NHp—CHn cyclic*,CHnOCHmCHp*,AC—O—CHm*,CHm cyclic—S—CHn cyclic,CHnCHm—F,CHnCHm—Br*,CHnCHm—I*,ACBr*,ACI*,CHm(NH2)—COOH* Toluene,0,0,0,0,0,0,0,0,0,0,5,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 C2-Benzene,1,0,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 C3-Benzene,1,1,0,0,0,0,0,0,0,0,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 @@ -14,7 +14,7 @@ Diaromatic-C11,0,0,0,0,0,0,0,0,0,0,7,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Diaromatic-C12,1,0,0,0,0,0,0,0,0,0,7,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Diaromatic-C13,1,1,0,0,0,0,0,0,0,0,7,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Diaromatic-C14,1,2,0,0,0,0,0,0,0,0,7,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -Cycloaromatic-C09,0,1,0,0,0,0,0,0,0,0,4,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +Cycloaromatic-C09,0,1,0,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Cycloaromatic-C10,0,2,0,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Cycloaromatic-C11,1,1,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Cycloaromatic-C12,1,2,1,0,0,0,0,0,0,0,4,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 diff --git a/fuellib/data/fuelData/propertiesData/__init__.py b/fuellib/data/fuelData/propertiesData/__init__.py new file mode 100644 index 0000000..26ee947 --- /dev/null +++ b/fuellib/data/fuelData/propertiesData/__init__.py @@ -0,0 +1 @@ +"""Properties data.""" diff --git a/fuelData/propertiesData/decane.csv b/fuellib/data/fuelData/propertiesData/decane.csv similarity index 100% rename from fuelData/propertiesData/decane.csv rename to fuellib/data/fuelData/propertiesData/decane.csv diff --git a/fuelData/propertiesData/dodecane.csv b/fuellib/data/fuelData/propertiesData/dodecane.csv similarity index 100% rename from fuelData/propertiesData/dodecane.csv rename to fuellib/data/fuelData/propertiesData/dodecane.csv diff --git a/fuellib/data/fuelData/propertiesData/hefa-S1.csv b/fuellib/data/fuelData/propertiesData/hefa-S1.csv new file mode 100755 index 0000000..de03193 --- /dev/null +++ b/fuellib/data/fuelData/propertiesData/hefa-S1.csv @@ -0,0 +1,20 @@ +Temperature,Density,VaporPressure,Viscosity +C,g/cm^3,kPa,mm^2/s +-50,,, +-40,0.78008,,5.0983 +-30,0.77194,,3.7544 +-20,0.76433,0.37,2.876 +-10,0.75689,0.96,2.2514 +0,0.7494,1.43,1.7466 +10,0.74217,1.76,1.4599 +20,0.73444,2.12,1.2459 +30,0.72726,2.57,1.1493 +40,,3.25, +50,,4.06, +60,,5.19, +70,,6.93, +80,,9.32, +90,,12.61, +100,,17.16, +110,,23.13, +120,,31.29, \ No newline at end of file diff --git a/fuellib/data/fuelData/propertiesData/hefa-WE-SAF-262714.csv b/fuellib/data/fuelData/propertiesData/hefa-WE-SAF-262714.csv new file mode 100644 index 0000000..0663f97 --- /dev/null +++ b/fuellib/data/fuelData/propertiesData/hefa-WE-SAF-262714.csv @@ -0,0 +1,20 @@ +Temperature,Density,VaporPressure,Viscosity,SurfaceTension,ThermalConductivity +C,g/cm^3,kPa,mm^2/s,N/m,W/m/K +-50,0.79867,,17.745,, +-40,0.7901,,8.1981,, +-30,0.78225,,5.6559,, +-20,0.77441,0.37,4.1397,, +-10,0.76662,0.96,3.1371,, +0,0.75716,1.43,2.4042,, +10,0.74983,1.76,1.9633,, +20,0.74467,2.12,1.6429,, +30,0.73974,2.57,1.4027,, +40,0.73245,3.25,1.2165,, +50,0.72533,4.06,1.0669,, +60,,5.19,1.0202,, +70,,6.93,,, +80,,9.32,,, +90,,12.61,,, +100,,17.16,,, +110,,23.13,,, +120,,31.29,,, \ No newline at end of file diff --git a/fuelData/propertiesData/hefa-jet-a-blends.csv b/fuellib/data/fuelData/propertiesData/hefa-jet-a-blends.csv similarity index 100% rename from fuelData/propertiesData/hefa-jet-a-blends.csv rename to fuellib/data/fuelData/propertiesData/hefa-jet-a-blends.csv diff --git a/fuelData/propertiesData/heptane.csv b/fuellib/data/fuelData/propertiesData/heptane.csv similarity index 100% rename from fuelData/propertiesData/heptane.csv rename to fuellib/data/fuelData/propertiesData/heptane.csv diff --git a/fuelData/propertiesData/posf10264.csv b/fuellib/data/fuelData/propertiesData/posf10264.csv similarity index 100% rename from fuelData/propertiesData/posf10264.csv rename to fuellib/data/fuelData/propertiesData/posf10264.csv diff --git a/fuelData/propertiesData/posf10289.csv b/fuellib/data/fuelData/propertiesData/posf10289.csv similarity index 100% rename from fuelData/propertiesData/posf10289.csv rename to fuellib/data/fuelData/propertiesData/posf10289.csv diff --git a/fuelData/propertiesData/posf10325.csv b/fuellib/data/fuelData/propertiesData/posf10325.csv similarity index 100% rename from fuelData/propertiesData/posf10325.csv rename to fuellib/data/fuelData/propertiesData/posf10325.csv diff --git a/fuelData/propertiesData/posf11498.csv b/fuellib/data/fuelData/propertiesData/posf11498.csv similarity index 100% rename from fuelData/propertiesData/posf11498.csv rename to fuellib/data/fuelData/propertiesData/posf11498.csv diff --git a/fuelData/refCompounds.csv b/fuellib/data/fuelData/refCompounds.csv similarity index 100% rename from fuelData/refCompounds.csv rename to fuellib/data/fuelData/refCompounds.csv diff --git a/fuellib/data/gcmTableData/__init__.py b/fuellib/data/gcmTableData/__init__.py new file mode 100644 index 0000000..7fa9dc1 --- /dev/null +++ b/fuellib/data/gcmTableData/__init__.py @@ -0,0 +1 @@ +"""GCM table data.""" diff --git a/fuellib/data/gcmTableData/gcmTable.csv b/fuellib/data/gcmTableData/gcmTable.csv new file mode 100644 index 0000000..997d23d --- /dev/null +++ b/fuellib/data/gcmTableData/gcmTable.csv @@ -0,0 +1,15 @@ +Property,Units,CH3,CH2,CH,C,CH2=CH,CH=CH,CH2=C,CH=C,C=C,CH2=C=CH,ACH,AC,ACCH3,ACCH2,ACCH,OH,ACOH,CH3CO,CH2CO,CHO,CH3COO,CH2COO,HCOO,CH3O,CH2O,CH-O,FCH2O,CH2NH2,CHNH2,CH3NH,CH2NH,CHNH,CH3N,CH2N,ACNH2,C5H4N,C5H3N,CH2CN,COOH,CH2CL,CHCL,CCL,CHCL2,CCL2,CCL3,ACCL,CH2NO2,CHNO2,ACNO2,CH2SH,I,Br,CH≡C,C≡C,CL—(C=C),ACF,HCON(CH2)2,CF3,CF2,CF,COO,CCL2F,HCCLF,CCLF2,Fspecial,CONH2,CONHCH3,CONHCH2,CON(CH3)2,CONCH3CH2,CON(CH2)2,C2H5O2,C2H4O2,CH3S,CH2S,CHS,C4H3S,C4H2S,(CH3)2CH,(CH3)3C,CH(CH3)CH(CH3),CH(CH3)C(CH3)2,C(CH3)2C(CH3)2,3 membered ring,4 membered ring,5 membered ring,6 membered ring,7 membered ring,"CHn=CHm—CHp=CHk k,n,m,p in (0,2)","CH3-CHm=CH, m in (0,1), n in (0,2)","CH2-CHm=CHn, m, n in (0,2)","CH-CHm=CHn or C-CHm=CHn, m,n m in (0,2)",Alicyclic side-chain CcyclicCm m > 1,CH3CH3,CHCHO or CCHO,CH3COCH2,CH3COCH or CH3COC,Ccyclic(=0),ACCHO,CHCOOH or CCOOH,ACCOOH,CH3COOCH or CH3COOC,COCH2COO or COCHCOO or COCCOO, CO-O-CO,ACCOO,CHOH,COH,"CHm(OH)CHn(OH), m,n in (0,2)","CHm cyclic-OH, m in (0,1)","CHm(OH)CHn(NHp), m,n,p in (0,3)",CHm(NH2)CHn(NH2),"CHm cyclic-NHp-CHn cyclic, m,n,p in (0,2)","Chm=Chn-F, m,n in (0,2)",AC-O-CHm,"CHm cyclic-S-CHn cyclic, m,n in (0,2)","CHm=CHn—F, m,n in (0,2)","CHm=CHn—Br, m,n in (0,2)","CHm=CHn—I, m,n in (0,2)",ACBr,ACI,"CHm(NH2)-COOH, m,n in (0,2)" +tck,K,1.6781,3.492,4.033,4.8823,5.0146,7.3691,6.5081,8.9582,11.3764,9.9318,3.7337,14.6409,8.213,10.3239,10.4664,9.7292,25.9145,13.2896,14.6273,10.1986,12.5965,13.8116,11.6057,6.4737,6.0723,5.0663,9.5059,12.1726,10.2075,9.8544,10.4677,7.2121,7.6924,5.5172,28.757,29.1528,27.9464,20.3781,23.7593,11.0752,10.8632,11.3959,16.3945,0,18.5875,14.1565,24.7369,23.205,34.587,13.8058,17.3947,10.5371,7.5433,11.4501,5.4334,2.8977,0,2.4778,1.7399,3.5192,12.1084,9.8408,0,4.8923,1.5974,65.1053,0,0,36.1403,0,0,17.9668,0,14.3969,17.7916,0,0,0,-0.5334,-0.5143,1.0699,1.9886,5.8254,-2.3305,-1.2978,-0.6785,0.8479,3.6714,0.4402,0.0167,-0.5231,-0.385,2.116,2.0427,-1.5826,0.2996,0.5018,2.9571,1.1696,-1.7493,6.1279,-1.3406,2.5413,-2.7617,-3.4235,-2.8035,-3.5442,5.4941,0.3233,5.4864,2.0699,2.1345,1.0159,-5.3307,4.4847,-0.4996,-1.9334,0,-2.2974,2.8907,0 +pck,bar^(-1/2),0.0199,0.0106,0.0013,-0.0104,0.025,0.0179,0.0223,0.0126,0.002,0.0313,0.0075,0.0021,0.0194,0.0122,0.0028,0.0051,-0.0074,0.0251,0.0178,0.0141,0.029,0.0218,0.0138,0.0204,0.0151,0.0099,0.009,0.0126,0.0107,0.0126,0.0104,-0.0005,0.0159,0.0049,0.0011,0.0296,0.0257,0.0361,0.0115,0.0198,0.0114,0.0031,0.0268,0,0.0349,0.0131,0.021,0.0122,0.015,0.0136,0.0028,-0.0018,0.0148,0.0041,0.016,0.013,0,0.0442,0.0129,0.0047,0.0113,0.0354,0,0.039,0.0144,0.0043,0,0,0.0401,0,0,0.0254,0,0.016,0.0111,0,0,0,0.000488,0.00141,-0.00185,-0.0052,-0.01323,0.003714,0.001171,0.000424,0.002257,-0.0098,0.004186,-0.00018,0.003538,0.005675,-0.00255,0.005175,0.003659,0.001474,-0.0023,0.003818,-0.00248,0.00492,0.000344,0.000659,0.001067,-0.00488,-0.00054,-0.00439,0.000178,0.005052,0.006917,0.001408,0.002148,-0.00595,-0.00088,-0.00225,0,0.000319,0,0,0.009027,0.008247,0 +vck,m^3/kmol,0.075,0.0558,0.0315,-0.0003,0.1165,0.0954,0.0918,0.0733,0.0762,0.1483,0.0422,0.0398,0.1036,0.101,0.0712,0.039,0.0316,0.134,0.1119,0.0863,0.1589,0.1365,0.1056,0.0875,0.0729,0.0587,0.0686,0.1313,0.0753,0.1215,0.0996,0.0916,0.126,0.067,0.0636,0.2483,0.1703,0.1583,0.1019,0.1156,0.1035,0.0792,0.1695,0,0.2103,0.1016,0.1653,0.1423,0.1426,0.1025,0.1081,0.0828,0.0933,0.0763,0.0569,0.0567,0,0.1148,0.0952,0,0.0859,0.1821,0,0.1475,0.0378,0.1443,0,0,0.2503,0,0,0.1675,0,0.1302,0.1165,0,0,0,0.004,0.00572,-0.00398,-0.01081,-0.023,-0.00014,-0.00851,-0.00866,0.01636,-0.027,-0.00781,-0.00098,0.00281,0.00826,-0.01755,0.00227,-0.00664,-0.0051,-0.00122,-0.01966,0.00664,0.00559,-0.00415,-0.00293,-0.00591,-0.00144,0.02605,-0.00777,0.01511,0.00397,-0.02297,0.00433,0.0058,-0.0138,0.00297,-0.00045,0,-0.00596,0.0051,0,-0.00832,-0.00341,0 +tbk,K,0.8894,0.9225,0.6033,0.2878,1.7827,1.8433,1.7117,1.7957,1.8881,3.1243,0.9297,1.6254,1.9669,1.9478,1.7444,3.2152,4.4014,3.5668,3.8967,2.8526,3.636,3.3953,3.1459,2.2536,1.6249,1.1557,2.5892,3.1656,2.5983,3.1376,2.6127,1.578,2.1647,1.2171,5.4736,6.28,5.9234,5.0525,5.8337,2.9637,2.6948,2.2073,3.93,3.56,4.5797,2.6293,5.7619,5.0767,6.0837,3.2914,3.665,2.6495,2.3678,2.5645,1.7824,0.9442,7.2644,1.288,0.6115,1.1739,2.6446,2.8881,2.3086,1.9163,1.0081,10.3428,0,0,7.6904,0,6.7822,5.5566,5.4248,3.6796,3.6763,2.6812,5.7093,5.826,-0.1157,-0.0489,0.1798,0.3189,0.7273,0.4745,0.3563,0.1919,0.1957,0.3489,0.1589,0.0668,-0.1406,-0.09,0.0511,0.6884,-0.1074,0.0224,0.092,0.558,0.0735,-0.1552,0.7801,-0.2383,0.4456,-0.1977,0.0835,-0.5385,-0.6331,1.4108,-0.069,1.0682,0.4247,0.2499,0.1134,-0.2596,0.4408,-0.1168,-0.3201,-0.4453,-0.6776,-0.3678,0 +tmk,K,0.464,0.9246,0.3557,1.6479,1.6472,1.6322,1.7899,2.0018,5.1175,3.3439,1.4669,0.2098,1.8635,0.4177,-1.7567,3.5979,13.7349,4.8776,5.6622,4.2927,4.0823,3.5572,4.225,2.9248,2.0695,4.0352,4.5047,6.7684,4.1187,4.5341,6.0609,3.41,4.058,0.9544,10.1031,0,12.6275,4.1859,11.563,3.3376,2.9933,9.8409,5.1638,0,10.2337,2.7336,5.5424,4.9738,8.4724,3.0044,4.6089,3.7442,3.9106,9.5793,1.5598,2.5015,0,3.2411,0,0,3.4448,7.4756,0,2.7523,1.9623,31.2786,0,0,11.377,0,0,0,0,5.0506,3.1468,0,0,0,0.0381,-0.2355,0.4401,-0.4923,6.065,1.3772,0,0.6824,1.5656,6.9709,1.9913,0.2476,-0.587,-0.2361,-2.8298,1.488,2.0547,-0.2951,-0.2986,0.7143,-0.6697,-3.1034,28.4324,0.4838,0.0127,-2.3598,-2.0198,-0.548,0.3189,0.9124,9.5209,2.7826,2.5114,1.0729,0.2476,0.1175,-0.2914,-0.0514,-1.6425,0,2.5832,-1.5511,0 +hfk,kJ/mol,-45.947,-20.763,-3.766,17.119,53.712,69.939,64.145,82.528,104.293,197.322,11.189,27.016,-19.243,9.404,27.671,-181.422,-164.609,-182.329,-164.41,-129.158,-389.737,-359.258,-332.822,-163.569,-151.143,-129.488,-140.313,-15.505,3.32,5.432,23.101,26.718,54.929,69.885,20.079,134.062,139.758,88.298,-396.242,-73.568,-63.795,-57.795,-82.921,0,-107.188,-16.752,-66.138,-59.142,-7.365,-8.253,57.546,1.834,220.803,227.368,-36.097,-161.74,0,-679.195,0,0,-313.545,-258.96,0,-446.835,-223.398,-203.188,-67.778,-182.096,-189.888,-46.562,0,-344.125,0,-2.084,18.022,0,0,0,-0.86,-1.338,6.771,7.205,14.271,104.8,99.455,13.782,-9.66,15.465,-8.392,0.474,1.472,4.504,1.252,-2.792,-2.092,0.975,4.753,14.145,-3.173,1.279,12.245,-7.807,37.462,-16.097,-9.874,-3.887,-24.125,0.366,-16.333,-2.992,2.855,0.351,-8.644,1.532,-0.329,0,11.989,0,12.285,11.207,11.74 +gfk,kJ/mol,-8.03,8.231,19.848,37.977,84.926,92.9,88.402,93.745,116.613,221.308,22.533,30.485,22.505,41.228,52.948,-158.589,-132.097,-131.366,-132.386,-107.858,-318.616,-291.188,-288.902,-105.767,-101.563,-92.099,-90.883,58.085,63.051,82.471,95.888,85.001,128.602,132.756,68.861,199.958,199.288,121.544,-349.439,-33.373,-31.502,-25.261,-35.814,0,-53.332,-0.596,17.963,18.088,60.161,16.731,46.945,-1.721,217.003,216.328,-28.148,-144.549,0,-626.58,0,0,-281.495,-209.337,0,-392.975,-212.718,-136.742,0,0,-65.642,0,0,-241.373,0,30.222,38.346,0,0,0,0.297,-0.399,6.342,7.466,16.224,94.564,92.573,5.733,-8.18,20.597,-5.505,0.95,0.699,1.013,1.041,-1.062,-1.359,0.075,0,23.539,-2.602,2.149,10.715,-6.208,29.181,-12.809,-7.415,-6.77,-20.77,3.805,-5.487,-1.6,1.858,8.846,-13.167,-0.654,-2.091,0,12.373,0,14.161,12.53,0 +hvk,KJ/mol,4.116,4.65,2.771,1.284,6.714,7.37,6.797,8.178,9.342,12.318,4.098,12.552,9.776,10.185,8.834,24.529,40.246,18.999,20.041,12.909,22.709,17.759,0,10.919,7.478,5.708,11.227,14.599,11.876,14.452,14.481,0,6.947,6.918,28.453,31.523,31.005,23.34,43.046,13.78,11.985,9.818,19.208,17.574,0,11.883,30.644,26.277,0,14.931,14.364,11.423,7.751,11.549,0,4.877,0,8.901,1.86,8.901,0,13.322,0,8.301,0,0,0,51.787,0,0,0,0,0,16.921,17.117,13.265,27.966,0,0.292,-0.72,0.868,1.027,2.426,0,0,-0.568,-0.905,-0.847,2.057,-0.073,-0.369,0.345,-0.114,0,0.207,-0.668,0.071,0.744,-3.41,0,8.502,-3.345,0,1.517,0,-1.398,0.32,-3.661,4.626,0,0,2.311,0,0,0.972,0,0,0,-7.488,-4.864,0 +wk,1,0.296,0.147,-0.071,-0.351,0.408,0.252,0.223,0.235,-0.21,0.152,0.027,0.334,0.146,-0.088,1.524,0.737,1.015,0.633,0.963,1.133,0.756,0.765,0.526,0.442,0.218,0.509,0.8,0,0.953,0.55,0.386,0.384,0.075,0.793,0,0,0,1.67,0.57,0,0,0.716,0,0.617,0,0.296,0,0,0,0,0.233,0.278,0.618,0,0,0.263,0.5,0,0,0,0,0.503,0,0.547,0,0,0,0,0,0,0,0.428,0,0,0.438,0.739,0,0,0.0174,0.01922,-0.00475,-0.02883,-0.08632,0.17563,0.22216,0.16284,-0.03065,-0.02094,0.01648,0.00619,-0.0115,0.02778,-0.11024,-0.1124,0,-0.20789,-0.16571,0,0,0.08774,0,-0.26623,0,0.91939,0,0.03654,0.21106,0,0,0,0,-0.13106,0,0,-0.01509,0,0,0,-0.03078,0.00001,0 +vmk,m^3/kmol,0.0261,0.0164,0.0071,-0.0038,0.0373,0.0269,0.027,0.0161,0.003,0.0434,0.0132,0.0044,0.0289,0.0192,0.0099,0.0055,0.0113,0.0365,0.0282,0.02,0.045,0.0357,0.0267,0.0327,0.0231,0.018,0.0206,0.0265,0.0195,0.0267,0.0232,0.0181,0.0191,0.0168,0.0137,0.0608,0.0524,0.0331,0.0223,0.0337,0.0266,0.0202,0.0468,0.062,0,0.0241,0.0338,0.0262,0.025,0.0345,0.0279,0.0214,0,0.0145,0.0153,0.0173,0,0,0,0,0.0192,0.0538,0,0.0538,0,0,0,0,0.0548,0,0,0.041,0,0.0348,0.0273,0,0,0,0.00133,0.00179,-0.00203,-0.00243,-0.00744,0,0,0.00213,0.00063,-0.00519,-0.00188,0.00009,0.00012,0.00142,-0.00107,0,-0.00009,-0.0003,-0.00108,-0.00111,-0.00036,-0.0005,0.00777,0.00083,0.00036,0.00198,0.00001,-0.00092,0.00175,0.00235,-0.0025,0.00046,0,-0.00179,-0.00206,0.01203,-0.00023,0,0,0,0.00178,0.00171,0 +CpAk,J/mol/K,35.1152,22.6346,8.9272,0.3456,49.2506,35.2248,37.6299,21.3528,10.2797,66.0574,16.3794,10.4283,42.8569,32.8206,19.9504,27.2107,39.7712,59.3032,0,40.7501,66.8423,0,51.5048,50.5604,39.5784,25.675,0,57.6861,44.1122,53.7012,44.6388,0,41.4064,30.1561,47.1311,84.7602,0,58.2837,46.5577,48.4648,36.5885,29.1848,60.8262,56.1685,78.6054,33.645,63.7851,51.1442,0,58.2445,29.1815,28.026,45.9768,26.7371,25.8094,30.1696,0,63.2024,44.3567,0,0,0,0,0,22.2082,0,0,0,0,0,0,0,0,57.767,45.0314,40.5275,80.301,0,0.583,0.3226,0.9668,-0.3082,-0.1201,8.5546,3.1721,-5.906,-3.9682,-3.2746,2.6142,-1.3913,0.263,6.5145,4.1707,0,0,3.7978,0,0,0,0,-15.7667,0,0,-6.4072,0,2.4484,-1.5252,0,0,0,0,0,0,0,-2.7407,0,-1.6978,0,-2.2923,-0.3162,0 +CpBk,J/mol/K,39.5923,45.0933,59.9786,74.0368,59.384,62.1924,62.1285,66.3947,65.5372,69.3936,32.7433,25.3634,65.6464,70.4153,81.8764,2.7609,35.5676,67.8149,0,19.699,102.4553,0,44.4133,38.9681,41.8177,24.7281,0,64.0768,77.2155,71.7948,68.5041,0,85.0996,81.6814,51.3326,177.2513,0,49.6388,48.2322,37.237,47.6004,52.3817,41.9908,46.9337,32.1318,23.2759,83.4744,94.2934,0,46.9958,-9.7846,-7.1651,20.6417,21.7676,-5.2241,26.9738,0,51.9366,44.5875,0,0,0,0,0,-2.8385,0,0,0,0,0,0,0,0,44.1238,55.1432,55.0141,132.7786,0,-1.2002,2.1309,-2.0762,1.8969,4.2846,-22.9771,-10.0834,-1.871,17.7889,32.167,4.4511,-1.5496,-2.3428,-17.5541,-3.1964,0,0,-7.3251,0,0,0,0,-0.1174,0,0,15.2583,0,-0.0765,-7.638,0,0,0,0,0,0,0,11.1033,0,1.0477,0,3.1142,2.3711,0 +CpCk,J/mol/K,-9.9232,-15.7033,-29.5143,-45.7878,-21.7908,-24.8156,-26.0637,-29.3703,-30.6057,-25.1081,-13.1692,-12.7283,-21.067,-28.9361,-40.2864,1.306,-15.5875,-20.9948,0,-5.436,-43.3306,0,-19.6155,-4.7799,-11.0837,4.2419,0,-21.048,-33.5086,-22.9685,-26.7106,0,-35.6318,-36.1441,-25.0276,-72.3213,0,-15.6291,-20.4868,-13.0635,-22.8148,-30.8526,-20.4091,-31.3325,-19.4033,-12.2406,-35.1171,-45.2029,0,-10.5106,3.4554,2.4332,-8.3297,-6.4481,1.4542,-13.3722,0,-28.6308,-23.282,0,0,0,0,0,1.2679,0,0,0,0,0,0,0,0,-9.5565,-18.7776,-31.719,-58.3241,0,-0.0584,-1.5728,0.3148,-1.6454,-2.0262,10.7278,4.9674,4.2945,-3.3639,-17.8246,-5.9808,2.5899,0.8975,10.6977,-1.1997,0,0,2.5312,0,0,0,0,6.1191,0,0,-8.3149,0,0.146,8.1795,0,0,0,0,0,0,0,-11.0878,0,0.2002,0,-1.4995,-1.4825,-0.0584 +MW,g/mol,15,14,13,12,27,26,26,25,24,39,13,12,27,26,25,17,29,43,42,41,59,58,45,31,30,29,49,30,29,30,29,28,29,28,28,78,77,40,45,49.5,48.5,47.5,84,119.5,118.5,47.5,60,59,58,47,35.5,80,25,24,59.5,31,71,69,50,31,44,102,67.5,85.5,0,44,58,57,72,0,70,61,60,47,46,45,83,82,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 \ No newline at end of file diff --git a/fuellib/exporters/__init__.py b/fuellib/exporters/__init__.py new file mode 100644 index 0000000..4762ce3 --- /dev/null +++ b/fuellib/exporters/__init__.py @@ -0,0 +1,9 @@ +""" +Export utilities for FuelLib. + +This module provides functions to export FuelLib data in various formats. +""" + +from . import converge, pele + +__all__ = ["converge", "pele"] diff --git a/source/Export4Converge.py b/fuellib/exporters/converge.py similarity index 88% rename from source/Export4Converge.py rename to fuellib/exporters/converge.py index d727c40..8189ebf 100644 --- a/source/Export4Converge.py +++ b/fuellib/exporters/converge.py @@ -1,15 +1,11 @@ import os -import sys import numpy as np import pandas as pd import argparse -import FuelLib as fl +import fuellib as fl -# Add the FuelLib directory to the Python path -FUELLIB_DIR = os.path.dirname(os.path.dirname(__file__)) -if FUELLIB_DIR not in sys.path: - sys.path.append(FUELLIB_DIR) -from paths import * +# Default data directory - use fuellib's embedded data +FUELDATA_DIR = fl.get_fueldata_dir() """ Script that exports mixture properties over large temperature range for use in @@ -20,15 +16,10 @@ The file contains mixture properties for the fuel, formatted for Converge. Usage: - python Export4Converge.py --fuel_name - -Options: - --units - --temp_min (K) - --temp_max (K) - --temp_step (K) - --export_dir - --export_mix + fl-export-converge -f + +For detailed options, run: + fl-export-converge -h """ @@ -141,7 +132,7 @@ def create_data_dict( def export_converge( fuel, - path=os.path.join(FUELLIB_DIR, "exportData"), + path=None, units="mks", temp_min=0, temp_max=1000, @@ -155,7 +146,7 @@ def export_converge( :type fuel: fl.fuel :param path: Directory to save the input file. - :type path: str, optional (default: FuelLib/exportData) + :type path: str, optional (default: current working directory) :param units: Units for the properties ("mks" for SI, "cgs" for CGS). :type units: str, optional (default: "mks") @@ -178,6 +169,9 @@ def export_converge( :raises ValueError: If input parameters are invalid :raises TypeError: If fuel object is not a FuelLib fuel instance """ + if path is None: + path = os.getcwd() + # Input validation if not hasattr(fuel, "compounds") or not hasattr(fuel, "Y_0"): raise TypeError("fuel parameter must be a valid FuelLib fuel object") @@ -349,8 +343,10 @@ def calculate_mixture_properties(T_array, fuel): thermal_conductivity[k] = fuel.mixture_thermal_conductivity(Y_li, Temp) # Generic mixing rules for latent heat and specific heat - Lv[k] = fl.mixing_rule(fuel.latent_heat_vaporization(Temp), X_li) # J/kg - Cl[k] = fl.mixing_rule(fuel.Cl(Temp), X_li) # J/kg/K + Lv[k] = fl.utility.mixing_rule( + fuel.latent_heat_vaporization(Temp), X_li + ) # J/kg + Cl[k] = fl.utility.mixing_rule(fuel.Cl(Temp), X_li) # J/kg/K return mu, surface_tension, Lv, pv, rho, Cl, thermal_conductivity @@ -417,8 +413,8 @@ def export_properties_to_csv(file_path, data_dict, overwrite=True): T = np.linspace(temp_min, temp_max, nT) # Estimate freezing point and critical temp of mixture - T_freeze = fl.mixing_rule(fuel.Tm, fuel.Y2X(fuel.Y_0)) - T_crit = fl.mixing_rule(fuel.Tc, fuel.Y2X(fuel.Y_0)) + T_freeze = fl.utility.mixing_rule(fuel.Tm, fuel.Y2X(fuel.Y_0)) + T_crit = fl.utility.mixing_rule(fuel.Tc, fuel.Y2X(fuel.Y_0)) print(f"\nEstimated mixture freezing temp: {T_freeze:.2f} K") print(f"Min freezing temp min(Tm_i): {min(fuel.Tm):.2f} K") @@ -507,30 +503,6 @@ def export_properties_to_csv(file_path, data_dict, overwrite=True): export_properties_to_csv(composition_file, composition_data) -def validate_fuel_files(fuel_name, fuel_data_dir): - """ - Validate that required fuel data files exist. - - :param fuel_name: Name of the fuel. - :type fuel_name: str - :param fuel_data_dir: Directory containing fuel data files. - :type fuel_data_dir: str - :raises FileNotFoundError: If required files are missing. - """ - gcxgc_file = os.path.join(fuel_data_dir, f"gcData/{fuel_name}_init.csv") - decomp_file = os.path.join(fuel_data_dir, f"groupDecompositionData/{fuel_name}.csv") - - if not os.path.exists(gcxgc_file): - raise FileNotFoundError(f"GCXGC file for {fuel_name} not found: {gcxgc_file}") - - if not os.path.exists(decomp_file): - raise FileNotFoundError( - f"Decomposition file for {fuel_name} not found: {decomp_file}" - ) - - print("All required files found.") - - def main(): """ Main function to execute the export process. @@ -554,7 +526,7 @@ def main(): :type --temp_step: float, optional (default: 10 K) :param --export_dir: Directory to export the properties. - :type --export_dir: str, optional (default: FuelLib/exportData) + :type --export_dir: str, optional (default: current working directory) :param --export_mix: Whether to export individual component or mixture properties. :type --export_mix: bool, optional (default: False) @@ -569,63 +541,79 @@ def main(): # Mandatory argument for fuel name parser.add_argument( + "-f", "--fuel_name", required=True, + metavar="NAME", help="Name of the fuel (mandatory).", ) # Optional argument for fuel data directory parser.add_argument( + "-dir", "--fuel_data_dir", default=FUELDATA_DIR, + metavar="PATH", help="Directory where fuel data files are located (optional, default: FuelLib/fuelData).", ) # Optional argument for units # Default is 'mks', but can be set to 'cgs' parser.add_argument( + "-u", "--units", default="mks", - help="Units for critical properties: mks or cgs (optional, default: mks).", + metavar="{mks,cgs}", + help="Units for critical properties (optional, default: mks).", ) # Optional argument for minimum temperature parser.add_argument( + "-t", "--temp_min", type=float, default=0, - help="Minimum temperature (K) for the property calculations (optional, default: 0).", + metavar="K", + help="Minimum temperature for property calculations (optional, default: 0).", ) # Optional argument for maximum temperature parser.add_argument( + "-T", "--temp_max", type=float, default=1000, - help="Maximum temperature (K) for the property calculations (optional, default: 1000).", + metavar="K", + help="Maximum temperature for property calculations (optional, default: 1000).", ) # Optional argument for temperature step size parser.add_argument( + "-s", "--temp_step", type=int, default=10, - help="Step size for temperature (K) (optional, default: 10).", + metavar="K", + help="Step size for temperature (optional, default: 10).", ) # Optional argument for export directory parser.add_argument( + "-o", "--export_dir", - default=os.path.join(FUELLIB_DIR, "exportData"), - help="Directory to export the properties (optional, default: FuelLib/exportData).", + default=os.getcwd(), + metavar="PATH", + help="Directory to export the properties (optional, default: current working directory).", ) # Optional argument for exporting mixture properties parser.add_argument( + "-m", "--export_mix", type=lambda x: str(x).lower() in ["true", "1"], default=False, - help="Option to export mixture properties of the fuel (True or False, default: False).", + metavar="{true,false}", + help="Export mixture properties of the fuel (optional, default: false).", ) # Parse arguments @@ -651,17 +639,8 @@ def main(): print(f" Export directory: {export_dir}") print(f" Fuel data directory: {fuel_data_dir}") - # Check if necessary files exist in the fuelData directory - print("\nChecking for required files...") - gcxgc_file = os.path.join(fuel_data_dir, f"gcData/{fuel_name}_init.csv") - decomp_file = os.path.join(fuel_data_dir, f"groupDecompositionData/{fuel_name}.csv") - if not os.path.exists(gcxgc_file): - err = f"GCXGC file for {fuel_name} not found in {fuel_data_dir}/gcData. gcxgc_file = {gcxgc_file}" - raise FileNotFoundError(err) - if not os.path.exists(decomp_file): - err = f"Decomposition file for {fuel_name} not found in {fuel_data_dir}/groupDecompositionData. decomp_file = {decomp_file}" - raise FileNotFoundError(err) - print("All required files found.") + # Get decomposition name from metadata (required) + decomp_name = fl.get_metadata_decomp_name(fuel_name, fuel_data_dir) # Create the fuel object fuel = fl.fuel(fuel_name, fuelDataDir=fuel_data_dir) diff --git a/source/Export4Pele.py b/fuellib/exporters/pele.py similarity index 87% rename from source/Export4Pele.py rename to fuellib/exporters/pele.py index 804838f..0f75de9 100644 --- a/source/Export4Pele.py +++ b/fuellib/exporters/pele.py @@ -1,17 +1,13 @@ import os -import sys import pandas as pd import argparse import subprocess from datetime import datetime from scipy import stats as st -import FuelLib as fl +import fuellib as fl -# Add the FuelLib directory to the Python path -FUELLIB_DIR = os.path.dirname(os.path.dirname(__file__)) -if FUELLIB_DIR not in sys.path: - sys.path.append(FUELLIB_DIR) -from paths import * +# Default data directory - use fuellib's embedded data +FUELDATA_DIR = fl.get_fueldata_dir() """ Script that exports critical properties and initial mass fraction data @@ -23,20 +19,10 @@ the fuel, formatted for Pele. Usage: - python Export4Pele.py --fuel_name - -Options: - --units - --fuel_decomp_name - --fuel_data_dir - --dep_fuel_names - --use_pp_keys - --export_dir - --export_mix - --export_mix_name - --fuel_data_dir - --liq_prop_model - --psat_antoine + fl-export-pele -f + +For detailed options, run: + fl-export-pele -h """ @@ -201,9 +187,9 @@ def create_mixture_dataframe(fuel, export_mix_name, converter): # Cp(T) = Cp_A + Cp_B * theta + Cp_C * theta^2 # where theta = (T - 298.15) / 700 X = fuel.Y2X(fuel.Y_0) - Cp_A = fl.mixing_rule(fuel.Cp_stp / fuel.MW, X) - Cp_B = fl.mixing_rule(fuel.Cp_B / fuel.MW, X) - Cp_C = fl.mixing_rule(fuel.Cp_C / fuel.MW, X) + Cp_A = fl.utility.mixing_rule(fuel.Cp_stp / fuel.MW, X) + Cp_B = fl.utility.mixing_rule(fuel.Cp_B / fuel.MW, X) + Cp_C = fl.utility.mixing_rule(fuel.Cp_C / fuel.MW, X) return pd.DataFrame( { @@ -211,17 +197,17 @@ def create_mixture_dataframe(fuel, export_mix_name, converter): "Family": [st.mode(fuel.fam).mode], "Y_0": [1.0], "MW": [fuel.mean_molecular_weight(fuel.Y_0) * converter.MW], - "Tc": [fl.mixing_rule(fuel.Tc, X)], - "Pc": [fl.mixing_rule(fuel.Pc, X) * converter.P], - "Vc": [fl.mixing_rule(fuel.Vc, X) * converter.Vm], - "Tb": [fl.mixing_rule(fuel.Tb, X)], - "omega": [fl.mixing_rule(fuel.omega, X)], - "Vm_stp": [fl.mixing_rule(fuel.Vm_stp, X) * converter.Vm], + "Tc": [fl.utility.mixing_rule(fuel.Tc, X)], + "Pc": [fl.utility.mixing_rule(fuel.Pc, X) * converter.P], + "Vc": [fl.utility.mixing_rule(fuel.Vc, X) * converter.Vm], + "Tb": [fl.utility.mixing_rule(fuel.Tb, X)], + "omega": [fl.utility.mixing_rule(fuel.omega, X)], + "Vm_stp": [fl.utility.mixing_rule(fuel.Vm_stp, X) * converter.Vm], "Cp_A": [Cp_A * converter.Cp], "Cp_B": [Cp_B * converter.Cp], "Cp_C": [Cp_C * converter.Cp], "Cp_stp": [Cp_A * converter.Cp], # For MP model: Cp_stp = Cp_A - "Lv_stp": [fl.mixing_rule(fuel.Lv_stp, X) * converter.Lv], + "Lv_stp": [fl.utility.mixing_rule(fuel.Lv_stp, X) * converter.Lv], } ) @@ -246,7 +232,7 @@ def vec_to_str(vec): def export_pele( fuel, - path=os.path.join(FUELLIB_DIR, "exportData"), + path=None, units="mks", dep_fuel_names=None, use_pp_keys=True, @@ -262,7 +248,7 @@ def export_pele( :type fuel: fuel object :param path: Directory to save the input file. - :type path: str, optional (default: FuelLib/exportData) + :type path: str, optional (default: current working directory) :param units: Units for the properties ("mks" for SI, "cgs" for CGS). :type units: str, optional (default: "mks") @@ -291,6 +277,9 @@ def export_pele( :raises ValueError: If input parameters are invalid :raises TypeError: If fuel object is not a FuelLib fuel instance """ + if path is None: + path = os.getcwd() + # Input validation if not hasattr(fuel, "compounds") or not hasattr(fuel, "Y_0"): raise TypeError("fuel parameter must be a valid FuelLib fuel object") @@ -535,7 +524,7 @@ def main(): :param --use_pp_keys: Use the PelePhysics key for each compound (True or False). Default is True. :type --use_pp_keys: bool, optional - :param --export_dir: Directory to export the properties. Default is "FuelLib/exportData". + :param --export_dir: Directory to export the properties. Default is the current working directory. :type --export_dir: str, optional :param --export_mix: Option to export mixture properties of the fuel (True or False). Default is False. @@ -560,84 +549,106 @@ def main(): # Mandatory argument for fuel name parser.add_argument( + "-f", "--fuel_name", required=True, + metavar="NAME", help="Name of the fuel (mandatory).", ) # Optional argument for fuel data directory parser.add_argument( + "-dir", "--fuel_data_dir", default=FUELDATA_DIR, + metavar="PATH", help="Directory where fuel data files are located (optional, default: FuelLib/fuelData).", ) # Optional argument for decomposition file name parser.add_argument( + "-decomp", "--fuel_decomp_name", default=None, + metavar="NAME", help="Name of the decomposition file (optional). If not provided, defaults to fuel_name.", ) # Optional argument for units # Default is 'mks', but can be set to 'cgs' parser.add_argument( + "-u", "--units", default="mks", - help="Units for critical properties: mks or cgs (optional, default: mks).", + metavar="{mks,cgs}", + help="Units for critical properties (optional, default: mks).", ) # Optional argument for deposition fuel names parser.add_argument( + "-dep", "--dep_fuel_names", nargs="+", # Accepts one or more values default=None, + metavar="NAME", help="Space-separated list or single fuel that each compound deposits to (optional, default: fuel.compounds).", ) # Optional argument for using PelePhysics key parser.add_argument( + "-pp", "--use_pp_keys", type=lambda x: str(x).lower() in ["true", "1"], default=True, - help="Use the PelePhysics key for each compound (True or False, default: True).", + metavar="{true,false}", + help="Use PelePhysics keys for each compound (optional, default: true).", ) # Optional argument for export directory parser.add_argument( + "-o", "--export_dir", - default=os.path.join(FUELLIB_DIR, "exportData"), - help="Directory to export the properties (optional, default: FuelLib/exportData).", + default=os.getcwd(), + metavar="PATH", + help="Directory to export the properties (optional, default: current working directory).", ) # Optional argument for exporting mixture properties parser.add_argument( + "-m", "--export_mix", type=lambda x: str(x).lower() in ["true", "1"], default=False, - help="Option to export mixture properties of the fuel (True or False, default: False).", + metavar="{true,false}", + help="Export mixture properties of the fuel (optional, default: false).", ) # Optional argument for mixture name if different than fuel_name parser.add_argument( + "-mn", "--export_mix_name", default=None, + metavar="NAME", help="Name the mixture if different than fuel_name (optional, default: fuel_name).", ) # Optional argument for liquid property model parser.add_argument( + "-l", "--liq_prop_model", default="gcm", - help='Model for liquid properties: "gcm" (default) or "mp" (optional, default: gcm).', + metavar="{gcm,mp}", + help="Model for liquid properties (optional, default: gcm).", ) # Optional argument for printing Antoine coefficients in MP model parser.add_argument( + "-psat", "--psat_antoine", type=lambda x: str(x).lower() in ["true", "1"], default=True, - help="Use Antoine coefficients for vapor pressure in MP model (True or False, default: True).", + metavar="{true,false}", + help="Use Antoine coefficients for vapor pressure in MP model (optional, default: true).", ) # Parse arguments @@ -645,6 +656,11 @@ def main(): fuel_name = args.fuel_name fuel_decomp_name = args.fuel_decomp_name fuel_data_dir = args.fuel_data_dir + + # If decomposition name not provided, read from metadata (required) + if fuel_decomp_name is None: + fuel_decomp_name = fl.get_metadata_decomp_name(fuel_name, fuel_data_dir) + units = args.units.lower() dep_fuel_names = args.dep_fuel_names use_pp_keys = args.use_pp_keys @@ -657,8 +673,7 @@ def main(): # Print the parsed arguments print(f"Preparing to export properties:") print(f" Fuel name: {fuel_name}") - if fuel_decomp_name is not None: - print(f" Decomposition name: {fuel_decomp_name}") + print(f" Decomposition name: {fuel_decomp_name}") print(f" Units: {units}") print(f" Liquid property model: {liq_prop_model}") if liq_prop_model.lower() == "mp": @@ -667,25 +682,6 @@ def main(): print(f" Export directory: {export_dir}") print(f" Fuel data directory: {fuel_data_dir}") - # Check if necessary files exist in the fuelData directory - print("\nChecking for required files...") - gcxgc_file = os.path.join(fuel_data_dir, f"gcData/{fuel_name}_init.csv") - if fuel_decomp_name is None: - decomp_file = os.path.join( - fuel_data_dir, f"groupDecompositionData/{fuel_name}.csv" - ) - else: - decomp_file = os.path.join( - fuel_data_dir, f"groupDecompositionData/{fuel_decomp_name}.csv" - ) - if not os.path.exists(gcxgc_file): - err = f"GCXGC file for {fuel_name} not found in {fuel_data_dir}/gcData. gxcgc_file = {gcxgc_file}" - raise FileNotFoundError(err) - if not os.path.exists(decomp_file): - err = f"Decomposition file for {fuel_name} not found in {fuel_data_dir}/groupDecompositionData. decomp_file = {decomp_file}" - raise FileNotFoundError(err) - print("All required files found.") - # Create the groupContribution object for the specified fuel fuel = fl.fuel(fuel_name, decompName=fuel_decomp_name, fuelDataDir=fuel_data_dir) diff --git a/source/FuelLib.py b/fuellib/fuel.py similarity index 82% rename from source/FuelLib.py rename to fuellib/fuel.py index aa6e9c8..879c20b 100644 --- a/source/FuelLib.py +++ b/fuellib/fuel.py @@ -1,14 +1,21 @@ +"""Fuel class for Group Contribution Method calculations.""" + import os -import sys import numpy as np import pandas as pd from scipy.optimize import curve_fit -# Add the FuelLib directory to the Python path -FUELLIB_DIR = os.path.dirname(os.path.dirname(__file__)) -if FUELLIB_DIR not in sys.path: - sys.path.append(FUELLIB_DIR) -from paths import * +from .constants import k_B, N_A +from .convert import K2C +from .utility import mixing_rule +from ._data_locator import ( + get_gcmtable_dir, + get_fueldata_dir, + get_fueldata_gc_dir, + get_fueldata_decomp_dir, + get_fueldata_props_dir, + get_metadata_decomp_name, +) class fuel: @@ -19,18 +26,109 @@ class fuel: :type name: str :param decompName: Name of the groupDecomposition file if different from name. Defaults to None. :type decompName: str, optional - :param fuelDataDir: Directory where the fuel data is stored. Defaults to FuelLib/fuelData. + :param fuelDataDir: Directory where the fuel data is stored. If None, uses built-in embedded data. :type fuelDataDir: str, optional """ + # Type annotations for documented attributes + #: Root directory for fuel data (custom or embedded) + fuelDataDir: str + + #: Directory containing GCxGC compositional data files + fuelDataGcDir: str + + #: Directory containing functional group decomposition files + fuelDataDecompDir: str + + #: Directory containing experimental property data (may be None) + fuelDataPropsDir: str + + #: Name of the fuel/mixture + name: str + + #: List of compound names in the mixture + compounds: list + + #: Molecular formulas for each compound + formulas: np.ndarray + + #: Mass fractions of each compound. Shape: (num_compounds,) + Y_0: np.ndarray + + #: Functional group decomposition matrix. Shape: (num_compounds, num_groups) + Nij: np.ndarray + + #: Number of compounds in the mixture + num_compounds: int + + #: Number of functional groups in the decomposition + num_groups: int + + #: Molecular weights in kg/mol. Shape: (num_compounds,) + MW: np.ndarray + + #: Critical temperatures in K. Shape: (num_compounds,) + Tc: np.ndarray + + #: Critical pressures in Pa. Shape: (num_compounds,) + Pc: np.ndarray + + #: Critical volumes in m³/mol. Shape: (num_compounds,) + Vc: np.ndarray + + #: Boiling temperatures in K. Shape: (num_compounds,) + Tb: np.ndarray + + #: Melting temperatures in K. Shape: (num_compounds,) + Tm: np.ndarray + + #: Enthalpy of formation in J/mol. Shape: (num_compounds,) + Hf: np.ndarray + + #: Gibbs free energy in J/mol. Shape: (num_compounds,) + Gf: np.ndarray + + #: Enthalpy of vaporization at 298 K in J/mol. Shape: (num_compounds,) + Hv_stp: np.ndarray + + #: Latent heat of vaporization at 298 K in J/kg. Shape: (num_compounds,) + Lv_stp: np.ndarray + + #: Molar specific heat at 298 K in J/mol/K. Shape: (num_compounds,) + Cp_stp: np.ndarray + + #: Molar liquid volume at 298 K in m³/mol. Shape: (num_compounds,) + Vm_stp: np.ndarray + + #: Acentric factors. Shape: (num_compounds,) + omega: np.ndarray + + #: Lennard-Jones collision diameters in m. Shape: (num_compounds,) + sigma: np.ndarray + + #: Lennard-Jones well depths in K. Shape: (num_compounds,) + epsilonByKB: np.ndarray + + #: Hydrocarbon types ("n-alkane", "iso-alkane", "cyclo-alkane", "aromatic", "alkene") + hc_type: np.ndarray + + #: Family codes for thermal conductivity (0: saturated, 1: aromatic, 2: cycloparaffin, 3: olefin) + fam: np.ndarray + + #: Carbon numbers. Shape: (num_compounds,) + nC: np.ndarray + + #: Hydrogen numbers. Shape: (num_compounds,) + nH: np.ndarray + + #: PelePhysics keys for each compound (if available) + pelephysics_keys: np.ndarray + # Number of first and second order groups from Constantinou and Gani N_g1 = 78 N_g2 = 43 - # Boltzmann's constant J/K - k_B = 1.380649e-23 - - def __init__(self, name, decompName=None, fuelDataDir=FUELDATA_DIR): + def __init__(self, name, decompName=None, fuelDataDir=None): """ Initialize the fuel object and calculate GCM properties. @@ -38,27 +136,41 @@ def __init__(self, name, decompName=None, fuelDataDir=FUELDATA_DIR): :type name: str :param decompName: Name of the groupDecomposition file if different from name. :type decompName: str, optional - :param fuelDataDir: Directory where the fuel data is stored. + :param fuelDataDir: Directory where the fuel data is stored. If None, uses built-in embedded data. :type fuelDataDir: str, optional """ self.name = name if decompName is None: - decompName = name - if fuelDataDir != FUELDATA_DIR: - self.fuelDataDir = fuelDataDir - self.fuelDataGcDir = os.path.join(self.fuelDataDir, "gcData") - self.fuelDataDecompDir = os.path.join( - self.fuelDataDir, "groupDecompositionData" - ) + # Try to get decomposition name from metadata + decompName = get_metadata_decomp_name(name, fuelDataDir) + + # Determine and set data directories for this fuel instance + if fuelDataDir is None: + # Use built-in embedded data + self.fuelDataDir = get_fueldata_dir() + self.fuelDataGcDir = get_fueldata_gc_dir() + self.fuelDataDecompDir = get_fueldata_decomp_dir() + self.fuelDataPropsDir = get_fueldata_props_dir() else: - self.fuelDataDir = FUELDATA_DIR - self.fuelDataGcDir = FUELDATA_GC_DIR - self.fuelDataDecompDir = FUELDATA_DECOMP_DIR + # Validate and use custom fuel directory + from ._data_locator import ( + _validate_fuel_data_dir, + _get_props_dir_for_fueldata, + ) + + _validate_fuel_data_dir(fuelDataDir) + self.fuelDataDir = fuelDataDir + self.fuelDataGcDir = os.path.join(fuelDataDir, "gcData") + self.fuelDataDecompDir = os.path.join(fuelDataDir, "groupDecompositionData") + self.fuelDataPropsDir = _get_props_dir_for_fueldata(fuelDataDir) + + # Get GCM table directory (always from built-in data) + gcmtable_dir = get_gcmtable_dir() self.groupDecompFile = os.path.join(self.fuelDataDecompDir, f"{decompName}.csv") self.gcxgcFile = os.path.join(self.fuelDataGcDir, f"{name}_init.csv") - self.gcmTableFile = os.path.join(GCMTABLE_DIR, "gcmTable.csv") + self.gcmTableFile = os.path.join(gcmtable_dir, "gcmTable.csv") # Read functional group data for mixture (num_compounds,num_groups) df_Nij = pd.read_csv(self.groupDecompFile) @@ -72,28 +184,81 @@ def __init__(self, name, decompName=None, fuelDataDir=FUELDATA_DIR): # 2: cycloparaffins # 3: olefins self.fam = np.zeros(self.num_compounds, dtype=int) + + # Classify hydrocarbon by type (n-alkane, iso-alkane, cyclo-alkane, aromatic) + # Based on group decompositions from Constantinou-Gani method + self.hc_type = np.array([""] * self.num_compounds, dtype=object) + aromatics = 10 # starting index for aromatic groups num_aromatics = 5 - cyclos = 84 # starting index for membered ring groups + branching = 78 # starting index for branching groups (Group j (CH3)2CH through C(CH3)2C(CH3)2) + num_branching = 5 # groups 78-82 inclusive + cyclos = 83 # starting index for membered ring groups (3-7 membered rings) num_cyclos = 5 olefins = 4 # starting index for double bound groups num_olefins = 6 + for i in range(self.num_compounds): # Check if aromatic: does it contain AC's? if sum(self.Nij[i, aromatics : aromatics + num_aromatics]) > 0: self.fam[i] = 1 + self.hc_type[i] = "aromatic" # Check if cycloparaffin: does it contain rings? elif sum(self.Nij[i, cyclos : cyclos + num_cyclos]) > 0: self.fam[i] = 2 + self.hc_type[i] = "cyclo-alkane" # Check if olefin: does it contain double bonds? elif sum(self.Nij[i, olefins : olefins + num_olefins]) > 0: self.fam[i] = 3 - - # Read initial liquid composition of mixture and normalize to get mass frac + self.hc_type[i] = "alkene" + # Check for branching groups (CH, C quaternary carbons) + elif sum(self.Nij[i, branching : branching + num_branching]) > 0: + self.hc_type[i] = "iso-alkane" + else: + # Only CH3 and CH2 -> n-alkane (linear) + self.hc_type[i] = "n-alkane" + + # Calculate carbon and hydrogen numbers from first-order group decomposition + # For jet fuels, use only alkyl (0-3) and aromatic (10-14) groups + # Alkyl: CH3=1C,3H; CH2=1C,2H; CH=1C,1H; C=1C,0H + # Aromatic: ACH=1C,1H; AC=1C,0H; ACCH3=2C,3H; ACCH2=2C,2H; ACCH=2C,1H + alkyl_carbons = np.array([1, 1, 1, 1]) # groups 0-3 + alkyl_hydrogens = np.array([3, 2, 1, 0]) + # Olefinic: group 4 appears to represent 2 carbons with 3 hydrogens in UNIFAC-based system + olefinic_carbons = np.array([2, 1, 1, 0, 0, 0]) # groups 4-9 + olefinic_hydrogens = np.array([3, 1, 0, 0, 0, 0]) + aromatic_carbons = np.array([1, 1, 2, 2, 2]) # groups 10-14 + aromatic_hydrogens = np.array([1, 0, 3, 2, 1]) + + self.nC = np.zeros(self.num_compounds, dtype=float) + self.nH = np.zeros(self.num_compounds, dtype=float) + for i in range(self.num_compounds): + # Alkyl contribution (groups 0-3) + self.nC[i] = np.dot(self.Nij[i, 0:4], alkyl_carbons) + self.nH[i] = np.dot(self.Nij[i, 0:4], alkyl_hydrogens) + # Olefinic contribution (groups 4-9) + self.nC[i] += np.dot(self.Nij[i, 4:10], olefinic_carbons) + self.nH[i] += np.dot(self.Nij[i, 4:10], olefinic_hydrogens) + # Aromatic contribution (groups 10-14) + self.nC[i] += np.dot(self.Nij[i, 10:15], aromatic_carbons) + self.nH[i] += np.dot(self.Nij[i, 10:15], aromatic_hydrogens) + + # Read GCxGC/compound data df_gcxgc = pd.read_csv(self.gcxgcFile) + self.compounds = [ compound.strip() for compound in df_gcxgc["Compound"].to_list() ] + + # Load molecular formulas if available + if "Formula" in df_gcxgc.columns: + self.formulas = [ + formula.strip() if pd.notna(formula) else None + for formula in df_gcxgc["Formula"].to_list() + ] + else: + self.formulas = None + if "PelePhysics Key" in df_gcxgc.columns: self.pelephysics_keys = [ key.strip() for key in df_gcxgc["PelePhysics Key"].to_list() @@ -194,7 +359,7 @@ def get_row(property_name): self.Vm_stp = 0.01211 + np.matmul(self.Nij, Vmk) # m^3/kmol self.Vm_stp *= 1e-3 # Convert to m^3/mol - # C_p,stp (specific heat at 298 K) + # C_p,stp (molar specific heat at 298 K) self.Cp_stp = np.matmul(self.Nij, cpak) - 19.7779 # J/mol/K # Temperature corrections for C_p @@ -381,13 +546,13 @@ def viscosity_dynamic(self, T, comp_idx=None): def Cp(self, T, comp_idx=None): """ - Compute specific heat capacity at a given temperature. + Compute molar specific heat capacity at a given temperature. :param T: Temperature in Kelvin. :type T: float :param comp_idx: Index of compound to calculate property for. :type comp_idx: int, optional - :return: Specific heat capacity in J/mol/K. + :return: Molar specific heat capacity in J/mol/K. :rtype: np.ndarray """ @@ -407,13 +572,13 @@ def Cp(self, T, comp_idx=None): def Cl(self, T, comp_idx=None): """ - Compute liquid specific heat capacity in J/kg/K at a given temperature. + Compute liquid mass specific heat capacity in J/kg/K at a given temperature. :param T: Temperature in Kelvin. :type T: float :param comp_idx: Index of compound to calculate property for. :type comp_idx: int, optional - :return: Specific heat capacity in J/kg/K. + :return: Mass specific heat capacity in J/kg/K. :rtype: np.ndarray """ if comp_idx is None: @@ -1002,89 +1167,4 @@ def mixture_thermal_conductivity(self, Yi, T): return np.sum(Yi * tc ** (-2)) ** (-0.5) -# ----------------------------------------------------------------------------- -# Utility functions -# ----------------------------------------------------------------------------- -def C2K(T): - """ - Convert temperature from Celsius to Kelvin. - - :param T: Temperature in Celsius. - :type T: float or np.ndarray - :return: Temperature in Kelvin. - :rtype: float or np.ndarray - """ - return T + 273.15 - - -def K2C(T): - """ - Convert temperature from Kelvin to Celsius. - - :param T: Temperature in Kelvin. - :type T: float or np.ndarray - :return: Temperature in Celsius. - :rtype: float or np.ndarray - """ - return T - 273.15 - - -def mixing_rule(var_n, X, pseudo_prop="arithmetic"): - """ - Mixing rules for computing mixture properties. - - :param var_n: Individual compound properties. - :type var_n: np.ndarray - :param X: Mole fractions of the compounds. - :type X: np.ndarray - :param pseudo_prop: Type of mean ("arithmetic" or "geometric"). - :type pseudo_prop: str, optional - :return: Mixture property value. - :rtype: float - """ - num_comps = len(var_n) - var_mix = 0.0 - for i in range(num_comps): - for j in range(num_comps): - if pseudo_prop.casefold() == "geometric": - # Use geometric mean definition for the pseudo property - var_ij = (var_n[i] * var_n[j]) ** (0.5) - else: - # Use arithmetic definition for the pseudo property - var_ij = (var_n[i] + var_n[j]) / 2 - var_mix += X[i] * X[j] * var_ij - return var_mix - - -def droplet_volume(r): - """ - Calculate spherical volume of a droplet given the radius. - - :param r: Radius of the droplet in meters. - :type r: float - :return: Spherical volume of droplet in cubic meters. - :rtype: float - """ - return 4.0 / 3.0 * np.pi * r**3 - - -def droplet_mass(fuel, r, Yi, T): - """ - Calculate the mass of each compound in the fuel provided the radius of the droplet. - - :param fuel: An instance of the groupContribution class. - :type fuel: groupContribution object - :param r: Radius of the droplet in meters. - :type r: float - :param Yi: Mass fractions of each compound. - :type Yi: np.ndarray - :param T: Droplet temperature in Kelvin. - :type T: float - :return: Mass of each compound in droplet in kg. - :rtype: np.ndarray - """ - volume = droplet_volume(r) # m^3 - if volume > 0: - return volume / (fuel.molar_liquid_vol(T) @ Yi) * Yi * fuel.MW - else: - return np.zeros_like(fuel.MW) +__all__ = ["fuel"] diff --git a/fuellib/utility.py b/fuellib/utility.py new file mode 100644 index 0000000..3fc0ea8 --- /dev/null +++ b/fuellib/utility.py @@ -0,0 +1,67 @@ +"""Utility functions for mixture calculations and droplet properties.""" + +import numpy as np + + +def mixing_rule(var_n, X, pseudo_prop="arithmetic"): + """ + Mixing rules for computing mixture properties. + + :param var_n: Individual compound properties. + :type var_n: np.ndarray + :param X: Mole fractions of the compounds. + :type X: np.ndarray + :param pseudo_prop: Type of mean ("arithmetic" or "geometric"). + :type pseudo_prop: str, optional + :return: Mixture property value. + :rtype: float + """ + num_comps = len(var_n) + var_mix = 0.0 + for i in range(num_comps): + for j in range(num_comps): + if pseudo_prop.casefold() == "geometric": + # Use geometric mean definition for the pseudo property + var_ij = (var_n[i] * var_n[j]) ** (0.5) + else: + # Use arithmetic definition for the pseudo property + var_ij = (var_n[i] + var_n[j]) / 2 + var_mix += X[i] * X[j] * var_ij + return var_mix + + +def droplet_volume(r): + """ + Calculate spherical volume of a droplet given the radius. + + :param r: Radius of the droplet in meters. + :type r: float + :return: Spherical volume of droplet in cubic meters. + :rtype: float + """ + return 4.0 / 3.0 * np.pi * r**3 + + +def droplet_mass(fuel, r, Yi, T): + """ + Calculate the mass of each compound in the fuel provided the radius of the droplet. + + :param fuel: An instance of the fuel class. + :type fuel: fuel object + :param r: Radius of the droplet in meters. + :type r: float + :param Yi: Mass fractions of each compound. + :type Yi: np.ndarray + :param T: Droplet temperature in Kelvin. + :type T: float + :return: Mass of each compound in droplet in kg. + :rtype: np.ndarray + """ + volume = droplet_volume(r) # m^3 + if volume > 0: + return volume / (fuel.molar_liquid_vol(T) @ Yi) * Yi * fuel.MW + else: + return np.zeros_like(fuel.MW) + + +__all__ = ["mixing_rule", "droplet_volume", "droplet_mass"] diff --git a/gcmTableData/gcmTable.csv b/gcmTableData/gcmTable.csv index 997d23d..fd1a89e 100644 --- a/gcmTableData/gcmTable.csv +++ b/gcmTableData/gcmTable.csv @@ -12,4 +12,4 @@ vmk,m^3/kmol,0.0261,0.0164,0.0071,-0.0038,0.0373,0.0269,0.027,0.0161,0.003,0.043 CpAk,J/mol/K,35.1152,22.6346,8.9272,0.3456,49.2506,35.2248,37.6299,21.3528,10.2797,66.0574,16.3794,10.4283,42.8569,32.8206,19.9504,27.2107,39.7712,59.3032,0,40.7501,66.8423,0,51.5048,50.5604,39.5784,25.675,0,57.6861,44.1122,53.7012,44.6388,0,41.4064,30.1561,47.1311,84.7602,0,58.2837,46.5577,48.4648,36.5885,29.1848,60.8262,56.1685,78.6054,33.645,63.7851,51.1442,0,58.2445,29.1815,28.026,45.9768,26.7371,25.8094,30.1696,0,63.2024,44.3567,0,0,0,0,0,22.2082,0,0,0,0,0,0,0,0,57.767,45.0314,40.5275,80.301,0,0.583,0.3226,0.9668,-0.3082,-0.1201,8.5546,3.1721,-5.906,-3.9682,-3.2746,2.6142,-1.3913,0.263,6.5145,4.1707,0,0,3.7978,0,0,0,0,-15.7667,0,0,-6.4072,0,2.4484,-1.5252,0,0,0,0,0,0,0,-2.7407,0,-1.6978,0,-2.2923,-0.3162,0 CpBk,J/mol/K,39.5923,45.0933,59.9786,74.0368,59.384,62.1924,62.1285,66.3947,65.5372,69.3936,32.7433,25.3634,65.6464,70.4153,81.8764,2.7609,35.5676,67.8149,0,19.699,102.4553,0,44.4133,38.9681,41.8177,24.7281,0,64.0768,77.2155,71.7948,68.5041,0,85.0996,81.6814,51.3326,177.2513,0,49.6388,48.2322,37.237,47.6004,52.3817,41.9908,46.9337,32.1318,23.2759,83.4744,94.2934,0,46.9958,-9.7846,-7.1651,20.6417,21.7676,-5.2241,26.9738,0,51.9366,44.5875,0,0,0,0,0,-2.8385,0,0,0,0,0,0,0,0,44.1238,55.1432,55.0141,132.7786,0,-1.2002,2.1309,-2.0762,1.8969,4.2846,-22.9771,-10.0834,-1.871,17.7889,32.167,4.4511,-1.5496,-2.3428,-17.5541,-3.1964,0,0,-7.3251,0,0,0,0,-0.1174,0,0,15.2583,0,-0.0765,-7.638,0,0,0,0,0,0,0,11.1033,0,1.0477,0,3.1142,2.3711,0 CpCk,J/mol/K,-9.9232,-15.7033,-29.5143,-45.7878,-21.7908,-24.8156,-26.0637,-29.3703,-30.6057,-25.1081,-13.1692,-12.7283,-21.067,-28.9361,-40.2864,1.306,-15.5875,-20.9948,0,-5.436,-43.3306,0,-19.6155,-4.7799,-11.0837,4.2419,0,-21.048,-33.5086,-22.9685,-26.7106,0,-35.6318,-36.1441,-25.0276,-72.3213,0,-15.6291,-20.4868,-13.0635,-22.8148,-30.8526,-20.4091,-31.3325,-19.4033,-12.2406,-35.1171,-45.2029,0,-10.5106,3.4554,2.4332,-8.3297,-6.4481,1.4542,-13.3722,0,-28.6308,-23.282,0,0,0,0,0,1.2679,0,0,0,0,0,0,0,0,-9.5565,-18.7776,-31.719,-58.3241,0,-0.0584,-1.5728,0.3148,-1.6454,-2.0262,10.7278,4.9674,4.2945,-3.3639,-17.8246,-5.9808,2.5899,0.8975,10.6977,-1.1997,0,0,2.5312,0,0,0,0,6.1191,0,0,-8.3149,0,0.146,8.1795,0,0,0,0,0,0,0,-11.0878,0,0.2002,0,-1.4995,-1.4825,-0.0584 -MW,g/mol,15,14,13,12,27,26,26,25,24,39,13,12,27,26,25,17,29,43,42,41,59,58,45,31,30,29,49,30,29,30,29,28,29,28,28,78,77,40,45,49.5,48.5,47.5,84,119.5,118.5,47.5,60,59,58,47,35.5,80,25,24,59.5,31,71,69,50,31,44,102,67.5,85.5,0,44,58,57,72,0,70,61,60,47,46,45,83,82,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 \ No newline at end of file +MW,g/mol,15.0345,14.0266,13.0186,12.0107,27.0452,26.0373,26.0373,25.0293,24.0214,39.0559,25.0293,24.0214,40.0639,39.0559,38.048,17.0073,42.0367,43.0446,42.0367,29.018,59.044,58.0361,45.0174,31.0339,30.026,29.018,49.0244,30.0492,29.0412,30.0492,29.0412,28.0333,29.0412,28.0333,41.0519,78.092,77.084,41.0519,45.0174,49.4796,48.4716,47.4637,83.9246,82.9167,118.3697,60.4823,60.0321,59.0241,70.0269,47.0945,126.9,79.904,25.0293,24.0214,59.4744,44.0277,71.0779,69.0059,50.0075,31.0091,44.0095,101.9151,67.47,85.4605,0,44.0327,58.0593,57.0513,72.0858,0,70.07,61.0599,60.052,47.0945,46.0866,45.0786,83.1266,82.1187,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 diff --git a/paths.py b/paths.py deleted file mode 100644 index a3e68f9..0000000 --- a/paths.py +++ /dev/null @@ -1,15 +0,0 @@ -import os -import sys - -FUELLIB_DIR = os.path.dirname(__file__) -GCMTABLE_DIR = os.path.join(FUELLIB_DIR, "gcmTableData") -SOURCE_DIR = os.path.join(FUELLIB_DIR, "source") -FUELDATA_DIR = os.path.join(FUELLIB_DIR, "fuelData") -FUELDATA_GC_DIR = os.path.join(FUELDATA_DIR, "gcData") -FUELDATA_DECOMP_DIR = os.path.join(FUELDATA_DIR, "groupDecompositionData") -FUELDATA_PROPS_DIR = os.path.join(FUELDATA_DIR, "propertiesData") -TESTS_DIR = os.path.join(FUELLIB_DIR, "tests") -TESTS_BASELINE_DIR = os.path.join(TESTS_DIR, "baselinePredictions") -TUTORIALS_DIR = os.path.join(FUELLIB_DIR, "tutorials") - -sys.path.append(SOURCE_DIR) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..4424b25 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,94 @@ +[build-system] +requires = ["setuptools>=61.0", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "fuellib" +version = "3.0.0a5" +description = "FuelLib: A Python library for Group Contribution Method (GCM) calculations of fuel properties" +readme = "README.md" +license = {text = "BSD-3-Clause"} +authors = [ + {name = "NLR", email = "david.montgomery@nlr.gov"}, +] +requires-python = ">=3.8" +keywords = ["fuel", "thermodynamics", "group-contribution", "properties"] +classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: BSD License", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Topic :: Scientific/Engineering", +] + +dependencies = [ + "numpy>=1.19.0", + "pandas>=1.0.0", + "scipy>=1.5.0", + "pyyaml>=5.0", + "matplotlib>=3.0", + "importlib-resources>=5.0; python_version < '3.9'", +] + +[project.optional-dependencies] +dev = [ + "black>=26.3.1", + "pytest>=6.0", + "sphinx>=4.0", + "sphinx-rtd-theme>=1.0", + "sphinxcontrib-bibtex>=2.0", +] + +[project.scripts] +fl-export-converge = "fuellib.exporters.converge:main" +fl-export-pele = "fuellib.exporters.pele:main" +fl-build-docs = "fuellib.cli.build_docs:main" +fl-clean-docs = "fuellib.cli.clean_docs:main" +fl-format = "fuellib.cli.format_code:main" +fl-eps2K = "fuellib.cli.transport_props_converter:eps2K_main" +fl-C2K = "fuellib.cli.temp_converter:c2k_main" +fl-K2C = "fuellib.cli.temp_converter:k2c_main" +fl-C2F = "fuellib.cli.temp_converter:c2f_main" +fl-F2C = "fuellib.cli.temp_converter:f2c_main" +fl-F2K = "fuellib.cli.temp_converter:f2k_main" +fl-K2F = "fuellib.cli.temp_converter:k2f_main" +fl-plt-comp = "fuellib.cli.plotting:comp_main" +fl-plt-props = "fuellib.cli.plotting:props_main" +fl-fuels = "fuellib.cli.fuel_manager:list_fuels_main" + +[project.urls] +Repository = "https://github.com/NatLabRockies/FuelLib" +Issues = "https://github.com/NatLabRockies/FuelLib/issues" +Documentation = "https://NatLabRockies.github.io/FuelLib" + +[tool.setuptools] +packages = ["fuellib", "fuellib.exporters", "fuellib.cli"] + +[tool.setuptools.package-data] +fuellib = [ + "data/**/*.csv", + "data/**/*.yaml", +] + +[tool.black] +line-length = 88 +target-version = ["py38", "py39", "py310", "py311", "py312"] +extend-exclude = ''' +/( + # directories + \.eggs + | \.git + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | build + | dist +)/ +''' diff --git a/tests/baselinePredictions/generate_baseline.py b/tests/baselinePredictions/generate_baseline.py index 67d6efe..0b91f05 100644 --- a/tests/baselinePredictions/generate_baseline.py +++ b/tests/baselinePredictions/generate_baseline.py @@ -11,12 +11,15 @@ # Add the FuelLib directory to the Python path FUELLIB_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) if FUELLIB_DIR not in sys.path: - sys.path.append(FUELLIB_DIR) -from paths import * + sys.path.insert(0, FUELLIB_DIR) -sys.path.append(os.path.join(FUELLIB_DIR, "tests")) -import FuelLib as fl -from get_pred_and_data import * +# Add the tests directory to import get_pred_and_data +TESTS_DIR = os.path.dirname(os.path.dirname(__file__)) +if TESTS_DIR not in sys.path: + sys.path.insert(0, TESTS_DIR) + +import fuellib as fl +from get_pred_and_data import get_pred_and_data # Directories for tests and baseline predictions # test_dir = os.path.dirname(__file__) diff --git a/tests/baselinePredictions/posf10264.csv b/tests/baselinePredictions/posf10264.csv index 46d1765..f5eac7c 100644 --- a/tests/baselinePredictions/posf10264.csv +++ b/tests/baselinePredictions/posf10264.csv @@ -1,13 +1,13 @@ Temperature,Density,Error_Density,Viscosity,Error_Viscosity,VaporPressure,Error_VaporPressure,SurfaceTension,Error_SurfaceTension,ThermalConductivity,Error_ThermalConductivity C,g/cm^3,g/cm^3,mm^2/s,mm^2/s,kPa,kPa,N/m,N/m,W/m/K,W/m/K --40.0,0.8155335646187369,0.007441435381263073,5.385883820556434,1.2141161794435655,,,,,, --20.0,0.8017870163101283,0.00681298368987171,3.186551296191339,0.31344870380866086,,,,,, --10.0,,,,,,,0.027399809834902835,0.0015573708349028367,, -0.0,0.7877750159741987,0.006449984025801214,,,0.20168590601758393,0.15333557601758394,,,0.12754384230554927,0.0014946196944507217 -20.0,0.7734734981982996,0.006376501801700463,,,0.6032234151495549,0.02533086985044508,0.02476740982671452,0.0009311718267145212,, -30.0,,,,,,,,,0.12143487551294638,0.0026035864870536246 -40.0,0.758854670606472,0.006428662393527906,1.1202487212301215,0.019751278769878367,1.5852102148738378,0.18305065687383792,0.023040303411569155,0.00020663641156915685,0.11943453010186489,0.000565469898135107 -60.0,,,,,3.7367158627205708,0.3038424617205706,,,0.11546676509633357,0.0006870809036664399 -80.0,,,,,8.028295546971819,0.6306951189718193,,,, -100.0,,,0.5992371143133661,0.01076288568663386,15.923196354015541,1.3213968140155412,,,, -120.0,,,,,29.46321488373632,2.8705336037363196,,,, +-40.0,0.8155103856313599,0.007464614368640099,5.384548853271682,1.2154511467283173,,,,,, +-20.0,0.8017636954386373,0.006836304561362638,3.1858812644715027,0.31411873552849734,,,,,, +-10.0,,,,,,,0.02739964557873879,0.0015572065787387915,, +0.0,0.7877515362472498,0.006473463752750153,,,0.2019489253708018,0.1535985953708018,,,0.1275435749655079,0.001494887034492104 +20.0,0.773449840420139,0.006400159579861064,,,0.6039256775538239,0.02462860744617612,0.024767103410105146,0.0009308654101051472,, +30.0,,,,,,,,,0.12143449347415747,0.0026039685258425344 +40.0,0.7588308129406026,0.0064525200593973375,1.1200887164361617,0.0199112835638382,1.5868450780907746,0.18468552009077466,0.023039904918752383,0.00020623791875238467,0.11943410886708083,0.0005658911329191607 +60.0,,,,,3.7401171991572113,0.30724379815721115,,,0.1154662638321051,0.0006875821678948985 +80.0,,,,,8.034741768664695,0.6371413406646953,,,, +100.0,,,0.5991728391147394,0.01082716088526059,15.934494237972615,1.3326946979726149,,,, +120.0,,,,,29.48174921391003,2.889067933910031,,,, diff --git a/tests/baselinePredictions/posf10289.csv b/tests/baselinePredictions/posf10289.csv index bedf839..b657506 100644 --- a/tests/baselinePredictions/posf10289.csv +++ b/tests/baselinePredictions/posf10289.csv @@ -1,15 +1,15 @@ Temperature,Density,Error_Density,Viscosity,Error_Viscosity,VaporPressure,Error_VaporPressure,SurfaceTension,Error_SurfaceTension,ThermalConductivity,Error_ThermalConductivity C,g/cm^3,g/cm^3,mm^2/s,mm^2/s,kPa,kPa,N/m,N/m,W/m/K,W/m/K --40.0,,,7.507948035184114,6.5920519648158855,,,,,, --20.0,,,4.24045399508395,2.25954600491605,,,,,, --10.0,,,,,,,0.028407578965936976,1.3851034063025458e-05,, -0.0,0.8309075418516484,0.007784125148351584,,,0.08660861469983731,0.03825828469983732,,,, -20.0,0.8168993942721436,0.007033938727856404,,,0.27321768591796414,0.06523462108203587,0.02587880375673309,0.00015129275673309017,, -30.0,,,,,,,,,0.10792801466210523,0.010052754337894765 -40.0,0.8026057063960078,0.007144293603992158,1.367514017820846,0.20248598217915403,0.7531450373224744,0.3179920713224744,0.024217518294994553,0.0005074207050054479,, -60.0,,,,,1.8537008936525574,0.5482419946525574,,,, -75.0,,,,,,,,,0.10045608472357537,0.008486223276424634 -80.0,,,,,4.142277288892066,0.8061045468920658,,,, -100.0,,,0.6977234633132008,0.06227653668679922,8.516417387410218,2.1341738814102182,,,, -120.0,,,,,16.286558420578324,2.5067144905783234,,,, -125.0,,,,,,,,,0.09225950233374283,0.00860588266625717 +-40.0,,,7.505044907152401,6.594955092847599,,,,,, +-20.0,,,4.2390408189958135,2.2609591810041865,,,,,, +-10.0,,,,,,,0.028407237447798647,1.4192552201353764e-05,, +0.0,0.8308723433887537,0.007819323611246265,,,0.08704862669817676,0.03869829669817676,,,, +20.0,0.8168639288926455,0.007069404107354571,,,0.27439414117821065,0.06405816582178936,0.0258782214609667,0.00015071046096669719,, +30.0,,,,,,,,,0.10792761258438621,0.010053156415613787 +40.0,0.8025699413648093,0.007180058635190667,1.3671951736956889,0.20280482630431118,0.7558883689289037,0.3207354029289037,0.02421678014184961,0.0005081588581503926,, +60.0,,,,,1.8594192315039126,0.5539603325039126,,,, +75.0,,,,,,,,,0.10045548410130546,0.00848682389869454 +80.0,,,,,4.1531373227981625,0.8169645807981625,,,, +100.0,,,0.6975992964511253,0.062400703548874725,8.535493574870209,2.153250068870209,,,, +120.0,,,,,16.317926296740087,2.5380823667400865,,,, +125.0,,,,,,,,,0.09225865338450474,0.008606731615495258 diff --git a/tests/baselinePredictions/posf10325.csv b/tests/baselinePredictions/posf10325.csv index dcefb1a..4c799fd 100644 --- a/tests/baselinePredictions/posf10325.csv +++ b/tests/baselinePredictions/posf10325.csv @@ -1,12 +1,12 @@ Temperature,Density,Error_Density,Viscosity,Error_Viscosity,VaporPressure,Error_VaporPressure,SurfaceTension,Error_SurfaceTension,ThermalConductivity,Error_ThermalConductivity C,g/cm^3,g/cm^3,mm^2/s,mm^2/s,kPa,kPa,N/m,N/m,W/m/K,W/m/K --40.0,0.8351805862254434,0.00868608077455657,6.46195013881539,2.738049861184609,,,,,, --20.0,0.8215770343700424,0.008106298629957598,3.7221869857688796,0.7778130142311204,,,,,, --10.0,,,,,,,0.02794563148900469,8.277151099531088e-05,, -0.0,0.8077210579942483,0.007395609005751647,,,0.15123802785325355,0.10288769785325355,,,0.121532038531724,0.0026987304682760116 -20.0,0.7935906587552476,0.008109341244752377,,,0.4573916369164672,0.02223867091646725,0.025362374564334628,0.0005436355643346283,0.11773349322663719,0.002458814773362808 -40.0,0.779160570944024,0.00816442905597603,1.2465786144401685,0.06342138555983157,1.2129921587874934,0.3910365557874934,0.023666414390480225,4.678239048022323e-05,0.11401351334435658,0.002044178655643422 -60.0,,,,,2.882097588054224,0.6096320970542237,,,0.1103462678289954,0.0018652701710046016 -80.0,,,,,6.237942743287926,1.3062091242879257,,,, -100.0,,,0.6497220808733932,0.030277919126606823,12.461340400164664,2.597873163164664,,,, -120.0,,,,,23.22344459897438,4.463516718974379,,,, +-40.0,0.8351574072380663,0.008709259761933708,6.460319977618209,2.7396800223817905,,,,,, +-20.0,0.8215537134985513,0.008129619501448637,3.7213832449838535,0.7786167550161465,,,,,, +-10.0,,,,,,,0.02794543468604107,8.2968313958931e-05,, +0.0,0.8076975782672994,0.007419088732700585,,,0.15151571402646025,0.10316538402646025,,,0.12153180724111683,0.0026989617588831782 +20.0,0.793567000977087,0.008132999022912979,,,0.45813356614511086,0.022980600145110885,0.0253620266788215,0.000543287678821499,0.11773319540798219,0.002459112592017809 +40.0,0.7791367132781545,0.008188286721845572,1.2463927637332222,0.06360723626677789,1.2147208541399832,0.3927652511399832,0.023665968681056217,4.6336681056215884e-05,0.11401314690365934,0.0020445450963406664 +60.0,,,,,2.8856977901650787,0.6132322991650785,,,0.11034583033821149,0.0018657076617885071 +80.0,,,,,6.2447736169035775,1.3130399979035774,,,, +100.0,,,0.6496486957331365,0.0303513042668635,12.473327173108917,2.6098599361089168,,,, +120.0,,,,,23.243134550414723,4.483206670414724,,,, diff --git a/tests/get_pred_and_data.py b/tests/get_pred_and_data.py index 5c5a840..e567818 100644 --- a/tests/get_pred_and_data.py +++ b/tests/get_pred_and_data.py @@ -1,14 +1,11 @@ import os -import sys import numpy as np import pandas as pd -# Add the FuelLib directory to the Python path -FUELLIB_DIR = os.path.dirname(os.path.dirname(__file__)) -if FUELLIB_DIR not in sys.path: - sys.path.append(FUELLIB_DIR) -from paths import * -import FuelLib as fl +import fuellib as fl +from fuellib._data_locator import get_fueldata_props_dir + +FUELDATA_PROPS_DIR = get_fueldata_props_dir() def get_pred_and_data(fuel_name, prop_name): @@ -26,7 +23,7 @@ def get_pred_and_data(fuel_name, prop_name): pred = np.zeros_like(T_data) # Vectors for temperature (convert from C to K) - T_pred = fl.C2K(T_data) + T_pred = fl.convert.C2K(T_data) for i in range(0, len(T_pred)): Y_li = fuel.Y_0 diff --git a/tests/test_accuracy.py b/tests/test_accuracy.py index 8373ca2..69570ff 100644 --- a/tests/test_accuracy.py +++ b/tests/test_accuracy.py @@ -1,15 +1,12 @@ import os -import sys import numpy as np import pandas as pd from get_pred_and_data import get_pred_and_data import unittest -# Add the FuelLib directory to the Python path -FUELLIB_DIR = os.path.dirname(os.path.dirname(__file__)) -if FUELLIB_DIR not in sys.path: - sys.path.append(FUELLIB_DIR) -from paths import * +# Locate the tests baseline directory +TESTS_DIR = os.path.dirname(os.path.abspath(__file__)) +TESTS_BASELINE_DIR = os.path.join(TESTS_DIR, "baselinePredictions") class CompTestCase(unittest.TestCase): diff --git a/tests/test_api.py b/tests/test_api.py index ad74dbd..a31bb15 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1,15 +1,9 @@ import inspect -import os -import sys +import types import unittest import numpy as np -# Add the FuelLib directory to the Python path -FUELLIB_DIR = os.path.dirname(os.path.dirname(__file__)) -if FUELLIB_DIR not in sys.path: - sys.path.append(FUELLIB_DIR) -from paths import * -import FuelLib as fl +import fuellib as fl def _normalize_signature(sig): @@ -30,11 +24,16 @@ def _normalize_signature(sig): def _public_module_functions(module): - return { - name: obj - for name, obj in inspect.getmembers(module, inspect.isfunction) - if not name.startswith("_") and obj.__module__ == module.__name__ - } + """Get public functions from module, including re-exported ones from __all__.""" + functions = {} + # Check all public names in __all__ + if hasattr(module, "__all__"): + for name in module.__all__: + if not name.startswith("_"): + obj = getattr(module, name, None) + if inspect.isfunction(obj) or inspect.isbuiltin(obj): + functions[name] = obj + return functions def _public_class_methods(cls): @@ -48,33 +47,102 @@ def _public_class_methods(cls): class ApiContractTestCase(unittest.TestCase): def test_fuellib_module_api(self): print("\nFuelLib Module API:") - expected = { + expected_top_level = { + "fuel": "class", + "constants": "module", + "convert": "module", + "utility": "module", + } + + # Check top-level API + for name, obj_type in expected_top_level.items(): + self.assertTrue( + hasattr(fl, name), + msg=f"FuelLib module missing expected attribute: {name}", + ) + if obj_type == "class": + self.assertTrue( + inspect.isclass(getattr(fl, name)), + msg=f"FuelLib.{name} should be a class", + ) + elif obj_type == "module": + import types + + self.assertTrue( + isinstance(getattr(fl, name), types.ModuleType), + msg=f"FuelLib.{name} should be a module", + ) + else: + print(f" ✓ {name} ({obj_type})") + + # Check that constants are available via module + self.assertTrue( + hasattr(fl.constants, "k_B"), msg="FuelLib.constants.k_B not found" + ) + self.assertTrue( + hasattr(fl.constants, "N_A"), msg="FuelLib.constants.N_A not found" + ) + print(f" ✓ constants.k_B (constant)") + print(f" ✓ constants.N_A (constant)") + print("\nFuelLib.convert Module API:") + convert_funcs = { "C2K": "(T)", "K2C": "(T)", + "C2F": "(T)", + "F2C": "(T)", + "F2K": "(T)", + "K2F": "(T)", + "epsilon_to_characteristic_temperature": "(epsilon_j_per_mol)", + } + for name, sig_expected in convert_funcs.items(): + self.assertTrue( + hasattr(fl.convert, name), msg=f"fuellib.convert missing: {name}" + ) + func = getattr(fl.convert, name) + actual_sig = _normalize_signature(inspect.signature(func)) + self.assertEqual( + actual_sig, + sig_expected, + msg=f"fuellib.convert.{name} signature changed", + ) + print(f" ✓ {name}{actual_sig}") + + # Check utility submodule + print("\nFuelLib.utility Module API:") + utility_funcs = { "mixing_rule": "(var_n, X, pseudo_prop='arithmetic')", "droplet_volume": "(r)", "droplet_mass": "(fuel, r, Yi, T)", } - - actual = _public_module_functions(fl) - self.assertEqual( - set(actual.keys()), - set(expected.keys()), - msg=( - "FuelLib module public function list changed. " - f"Expected: {sorted(expected.keys())}; Found: {sorted(actual.keys())}" - ), - ) - - for name in sorted(expected.keys()): - actual_sig = _normalize_signature(inspect.signature(actual[name])) + for name, sig_expected in utility_funcs.items(): + self.assertTrue( + hasattr(fl.utility, name), msg=f"fuellib.utility missing: {name}" + ) + func = getattr(fl.utility, name) + actual_sig = _normalize_signature(inspect.signature(func)) self.assertEqual( actual_sig, - expected[name], - msg=f"FuelLib module function signature changed: {name}", + sig_expected, + msg=f"fuellib.utility.{name} signature changed", ) print(f" ✓ {name}{actual_sig}") + # Check constants submodule + print("\nFuelLib.constants Module API:") + constants_vals = { + "k_B": "Boltzmann constant", + "N_A": "Avogadro number", + } + for name in constants_vals.keys(): + self.assertTrue( + hasattr(fl.constants, name), msg=f"fuellib.constants missing: {name}" + ) + val = getattr(fl.constants, name) + self.assertIsInstance( + val, (int, float), msg=f"fuellib.constants.{name} should be numeric" + ) + print(f" ✓ {name}") + def test_fuellib_class_api(self): print("\nFuelLib.fuel Class API:") expected = { @@ -153,24 +221,24 @@ def test_all_fuel_methods_for_single_and_multicomponent(self): # Utility functions (run per fuel for consistent CI grouping) print(" Utility Functions:") - self.assertAlmostEqual(fl.C2K(25.0), 298.15) - print(" ✓ C2K") - self.assertAlmostEqual(fl.K2C(298.15), 25.0) - print(" ✓ K2C") + self.assertAlmostEqual(fl.convert.C2K(25.0), 298.15) + print(" ✓ convert.C2K") + self.assertAlmostEqual(fl.convert.K2C(298.15), 25.0) + print(" ✓ convert.K2C") self.assertAlmostEqual( - fl.droplet_volume(1e-4), 4.0 / 3.0 * np.pi * (1e-4) ** 3 + fl.utility.droplet_volume(1e-4), 4.0 / 3.0 * np.pi * (1e-4) ** 3 ) - print(" ✓ droplet_volume") + print(" ✓ utility.droplet_volume") Xi = fuel.Y2X(Yi) self._assert_finite_and_positive( - fl.mixing_rule(fuel.Tc, Xi, pseudo_prop="arithmetic") + fl.utility.mixing_rule(fuel.Tc, Xi, pseudo_prop="arithmetic") ) - print(" ✓ mixing_rule (arithmetic)") + print(" ✓ utility.mixing_rule (arithmetic)") self._assert_finite_and_positive( - fl.mixing_rule(fuel.Tc, Xi, pseudo_prop="geometric") + fl.utility.mixing_rule(fuel.Tc, Xi, pseudo_prop="geometric") ) - print(" ✓ mixing_rule (geometric)") + print(" ✓ utility.mixing_rule (geometric)") # Composition conversion methods print(" Composition Conversions:") @@ -330,13 +398,13 @@ def test_all_fuel_methods_for_single_and_multicomponent(self): # Droplet helpers print(" Droplet Properties:") - m = fl.droplet_mass(fuel, 2.0e-5, Yi, self.T) + m = fl.utility.droplet_mass(fuel, 2.0e-5, Yi, self.T) self.assertEqual(m.shape, fuel.MW.shape) self.assertTrue(np.all(m >= 0.0)) self.assertTrue( - np.allclose(fl.droplet_mass(fuel, 0.0, Yi, self.T), 0.0) + np.allclose(fl.utility.droplet_mass(fuel, 0.0, Yi, self.T), 0.0) ) - print(" ✓ droplet_mass") + print(" ✓ utility.droplet_mass") if __name__ == "__main__": diff --git a/tests/test_exporters.py b/tests/test_exporters.py new file mode 100644 index 0000000..02c3003 --- /dev/null +++ b/tests/test_exporters.py @@ -0,0 +1,166 @@ +"""Test exporters for FuelLib. + +This test module verifies that the export CLI commands work correctly. +""" + +import subprocess +import sys +import tempfile +import shutil +import os +import fuellib as fl + + +def run_export_command(cmd): + """Run an export command and verify it succeeds. + + :param cmd: Command to run as a list of strings. + :type cmd: list + :raises RuntimeError: If the command fails. + """ + try: + result = subprocess.run(cmd, capture_output=True, text=True, timeout=60) + if result.returncode != 0: + print(f"Command failed: {' '.join(cmd)}") + print(f"stdout: {result.stdout}") + print(f"stderr: {result.stderr}") + raise RuntimeError(f"Export command failed: {' '.join(cmd)}") + print(f"✓ {' '.join(cmd)}") + except subprocess.TimeoutExpired: + raise RuntimeError(f"Export command timed out: {' '.join(cmd)}") + + +def test_pele_individual_component(): + """Test fl-export-pele individual component export.""" + run_export_command(["fl-export-pele", "-f", "posf10264"]) + + +def test_pele_mixture_gcm(): + """Test fl-export-pele mixture export with GCM model.""" + run_export_command(["fl-export-pele", "-f", "posf10264", "-m", "true"]) + + +def test_pele_mixture_mp(): + """Test fl-export-pele mixture export with MP model.""" + run_export_command(["fl-export-pele", "-f", "posf10264", "-m", "true", "-l", "mp"]) + + +def test_pele_mixture_cgs(): + """Test fl-export-pele mixture export with CGS units.""" + run_export_command(["fl-export-pele", "-f", "posf10264", "-m", "true", "-u", "cgs"]) + + +def test_pele_deposit_species(): + """Test fl-export-pele single deposit species.""" + run_export_command(["fl-export-pele", "-f", "posf10264", "-dep", "POSF10264"]) + + +def test_converge_individual_component(): + """Test fl-export-converge individual component export.""" + run_export_command(["fl-export-converge", "-f", "posf10264"]) + + +def test_converge_mixture(): + """Test fl-export-converge mixture export.""" + run_export_command( + [ + "fl-export-converge", + "-f", + "posf10264", + "-m", + "true", + "-t", + "280", + "-T", + "400", + "-s", + "10", + ] + ) + + +def test_pele_custom_fuel_data_dir(): + """Test fl-export-pele with custom fuel data directory (not embedded data).""" + # Create a temporary directory and copy fuelData to it + with tempfile.TemporaryDirectory() as tmpdir: + # Copy the embedded fuelData to a temp location + embedded_fueldata = fl.get_fueldata_dir() + custom_fueldata = os.path.join(tmpdir, "fuelData") + shutil.copytree(embedded_fueldata, custom_fueldata) + + # Export from custom location + run_export_command( + ["fl-export-pele", "-f", "posf10264", "-dir", custom_fueldata] + ) + + +def test_converge_custom_fuel_data_dir(): + """Test fl-export-converge with custom fuel data directory (not embedded data).""" + # Create a temporary directory and copy fuelData to it + with tempfile.TemporaryDirectory() as tmpdir: + # Copy the embedded fuelData to a temp location + embedded_fueldata = fl.get_fueldata_dir() + custom_fueldata = os.path.join(tmpdir, "fuelData") + shutil.copytree(embedded_fueldata, custom_fueldata) + + # Export from custom location + run_export_command( + [ + "fl-export-converge", + "-f", + "posf10264", + "-dir", + custom_fueldata, + "-m", + "true", + "-t", + "280", + "-T", + "400", + "-s", + "10", + ] + ) + + +if __name__ == "__main__": + print("Running exporter tests...\n") + + tests = [ + ( + "fl-export-pele - individual component export", + test_pele_individual_component, + ), + ("fl-export-pele - mixture export with GCM model", test_pele_mixture_gcm), + ("fl-export-pele - mixture export with MP model", test_pele_mixture_mp), + ("fl-export-pele - mixture export with CGS units", test_pele_mixture_cgs), + ("fl-export-pele - single deposit species", test_pele_deposit_species), + ( + "fl-export-pele - custom fuel data directory", + test_pele_custom_fuel_data_dir, + ), + ( + "fl-export-converge - individual component export", + test_converge_individual_component, + ), + ("fl-export-converge - mixture export", test_converge_mixture), + ( + "fl-export-converge - custom fuel data directory", + test_converge_custom_fuel_data_dir, + ), + ] + + failed = [] + for test_name, test_func in tests: + try: + test_func() + except Exception as e: + print(f"✗ {test_name}: {e}") + failed.append(test_name) + + print(f"\n{len(tests) - len(failed)}/{len(tests)} tests passed") + if failed: + print("Failed tests:") + for test_name in failed: + print(f" - {test_name}") + sys.exit(1) diff --git a/tests/test_hc_identification.py b/tests/test_hc_identification.py new file mode 100644 index 0000000..d34d214 --- /dev/null +++ b/tests/test_hc_identification.py @@ -0,0 +1,273 @@ +"""Test hydrocarbon identification: nC, nH, and hc_type determination.""" + +import re +from pathlib import Path +import pytest +import pandas as pd +import fuellib as fl + + +def get_available_fuels(): + """Discover available fuels from fuelData/gcData directory.""" + gcdata_dir = fl.get_fueldata_gc_dir() + fuels = sorted( + [f.name.replace("_init.csv", "") for f in Path(gcdata_dir).glob("*_init.csv")] + ) + return fuels + + +def extract_c_h_from_formula(formula): + """Extract carbon and hydrogen counts from formula string (e.g., C7H8 -> (7, 8)).""" + if not formula or pd.isna(formula): + return None, None + + formula = str(formula).strip() + # Match CnHm pattern + match = re.match(r"C(\d+)H(\d+)", formula) + if match: + return int(match.group(1)), int(match.group(2)) + return None, None + + +def infer_hc_type_from_formula(formula, compound_name=""): + """Infer expected hydrocarbon type from formula.""" + if not formula or pd.isna(formula): + return None + + nc, nh = extract_c_h_from_formula(formula) + if nc is None: + return None + + # Check for aromatic patterns (diaromatics, cycloaromatics, benzenes) + if "Diaromatic" in compound_name or "aromatic" in compound_name.lower(): + return "aromatic" + if "Benzene" in compound_name or "Toluene" in compound_name: + return "aromatic" + + # Check for alkene patterns + if "Alkene" in compound_name: + return "alkene" + + # Check for cycloalkane patterns + if "Cycloparaffin" in compound_name or "Cycloaromatic" in compound_name: + # These have aromatic rings attached, classified as aromatic + if "Cycloaromatic" in compound_name: + return "aromatic" + return "cyclo-alkane" + + # For alkanes, check saturation + # Alkanes: CnH(2n+2) + if nh == 2 * nc + 2: + # Check if it's iso or n based on name + if "Isoparaffin" in compound_name or "iso" in compound_name.lower(): + return "iso-alkane" + elif "n-C" in compound_name or compound_name.startswith("n-"): + return "n-alkane" + else: + # Default branched alkanes to iso-alkane + return "iso-alkane" + + # Monocycloalkanes: CnH(2n) + if "Monocyclo" in compound_name and nh == 2 * nc: + return "cyclo-alkane" + + # Dicycloalkanes: CnH(2n-2) + if "Dicyclo" in compound_name and nh == 2 * nc - 2: + return "cyclo-alkane" + + # Tricycloalkanes: CnH(2n-4) + if "Tricyclo" in compound_name and nh == 2 * nc - 4: + return "cyclo-alkane" + + return None + + +class TestHCIdentification: + """Test suite for hydrocarbon type, carbon, and hydrogen identification.""" + + @pytest.mark.parametrize("fuel_name", get_available_fuels()) + def test_hc_identification(self, fuel_name): + """Comprehensive test for HC identification: nC, nH, hc_type, and compound classification.""" + # Load fuel + fuel = fl.fuel(fuel_name) + + print(f"\n{'='*60}") + print(f"Fuel: {fuel_name}") + print(f"{'='*60}") + print(f"Compounds: {fuel.num_compounds}") + + # === Test 1: nC matches reference formula === + mismatches = [] + for compound, formula, nc_calc in zip(fuel.compounds, fuel.formulas, fuel.nC): + if not formula or pd.isna(formula): + continue + + nc_ref, _ = extract_c_h_from_formula(formula) + + if nc_ref is not None: + tolerance = 2.0 if "Cycloaromatic" in compound else 0.1 + + if abs(nc_calc - nc_ref) > tolerance: + mismatches.append( + f"{compound}: calculated nC={nc_calc:.1f}, expected nC={nc_ref}" + ) + + assert not mismatches, f"Carbon count mismatches:\n" + "\n".join(mismatches) + print(f"✓ nC from decomp matches reference formula") + + # === Test 2: nH matches reference formula === + mismatches = [] + for compound, formula, nh_calc in zip(fuel.compounds, fuel.formulas, fuel.nH): + if not formula or pd.isna(formula): + continue + + _, nh_ref = extract_c_h_from_formula(formula) + + if nh_ref is not None: + tolerance = 2.0 if "Cycloaromatic" in compound else 0.1 + + if abs(nh_calc - nh_ref) > tolerance: + mismatches.append( + f"{compound}: calculated nH={nh_calc:.1f}, expected nH={nh_ref}" + ) + + assert not mismatches, f"Hydrogen count mismatches:\n" + "\n".join(mismatches) + print(f"✓ nH from decomp matches reference formula") + + # === Test 3: hc_type is consistent === + valid_types = {"n-alkane", "iso-alkane", "cyclo-alkane", "alkene", "aromatic"} + + mismatches = [] + for compound, hc_type in zip(fuel.compounds, fuel.hc_type): + if hc_type not in valid_types: + mismatches.append( + f"{compound}: invalid hc_type='{hc_type}' " + f"(must be one of {valid_types})" + ) + + assert not mismatches, f"Invalid hydrocarbon types:\n" + "\n".join(mismatches) + print(f"✓ hc_type from decomp is consistent") + + # === Test 4: hc_type matches formula-derived expectations === + mismatches = [] + for compound, formula, hc_type_calc in zip( + fuel.compounds, fuel.formulas, fuel.hc_type + ): + if not formula or pd.isna(formula): + continue + + hc_type_expected = infer_hc_type_from_formula(formula, compound) + + if hc_type_expected is not None: + if hc_type_calc != hc_type_expected: + mismatches.append( + f"{compound}: calculated hc_type='{hc_type_calc}', " + f"expected hc_type='{hc_type_expected}' " + f"(formula: {formula})" + ) + + assert not mismatches, f"Hydrocarbon type mismatches:\n" + "\n".join(mismatches) + print(f"✓ hc_type from decomp matches formula-derived expectations") + + # === Test 5: Aromatic compounds identified === + aromatic_names = { + compound + for compound, formula in zip(fuel.compounds, fuel.formulas) + if formula + and ( + "Benzene" in compound + or "aromatic" in compound.lower() + or "naphthalene" in formula.lower() + ) + } + + mismatches = [] + for compound, hc_type in zip(fuel.compounds, fuel.hc_type): + if compound in aromatic_names: + if hc_type != "aromatic": + mismatches.append( + f"{compound}: should be aromatic but got '{hc_type}'" + ) + + assert ( + not mismatches + ), f"Aromatic compounds not correctly identified:\n" + "\n".join(mismatches) + aromatic_count = len(aromatic_names) if aromatic_names else 0 + print(f"✓ aromatic compounds identified correctly ({aromatic_count} found)") + + # === Test 6: n-alkane compounds identified === + nalkane_names = { + compound for compound in fuel.compounds if compound.startswith("n-C") + } + + mismatches = [] + for compound, hc_type in zip(fuel.compounds, fuel.hc_type): + if compound in nalkane_names: + if hc_type != "n-alkane": + mismatches.append( + f"{compound}: should be n-alkane but got '{hc_type}'" + ) + + assert ( + not mismatches + ), f"n-alkane compounds not correctly identified:\n" + "\n".join(mismatches) + nalkane_count = len(nalkane_names) if nalkane_names else 0 + print(f"✓ n-alkane compounds identified correctly ({nalkane_count} found)") + + # === Test 7: Cycloalkane compounds identified === + cyclo_names = { + compound + for compound in fuel.compounds + if "cycloparaffin" in compound.lower() + and "aromatic" not in compound.lower() + } + + mismatches = [] + for compound, hc_type in zip(fuel.compounds, fuel.hc_type): + if compound in cyclo_names: + if hc_type != "cyclo-alkane": + mismatches.append( + f"{compound}: should be cyclo-alkane but got '{hc_type}'" + ) + + assert ( + not mismatches + ), f"Cycloalkane compounds not correctly identified:\n" + "\n".join(mismatches) + cyclo_count = len(cyclo_names) if cyclo_names else 0 + print(f"✓ cyclo-alkane compounds identified correctly ({cyclo_count} found)") + + # === Test 7b: iso-alkane compounds identified === + isoalkane_names = { + compound for compound in fuel.compounds if "Isoparaffin" in compound + } + + mismatches = [] + for compound, hc_type in zip(fuel.compounds, fuel.hc_type): + if compound in isoalkane_names: + if hc_type != "iso-alkane": + mismatches.append( + f"{compound}: should be iso-alkane but got '{hc_type}'" + ) + + assert ( + not mismatches + ), f"iso-alkane compounds not correctly identified:\n" + "\n".join(mismatches) + isoalkane_count = len(isoalkane_names) if isoalkane_names else 0 + print(f"✓ iso-alkane compounds identified correctly ({isoalkane_count} found)") + + # === Test 8: Alkene compounds identified === + alkene_names = {compound for compound in fuel.compounds if "Alkene" in compound} + + mismatches = [] + for compound, hc_type in zip(fuel.compounds, fuel.hc_type): + if compound in alkene_names: + if hc_type != "alkene": + mismatches.append( + f"{compound}: should be alkene but got '{hc_type}'" + ) + + assert ( + not mismatches + ), f"Alkene compounds not correctly identified:\n" + "\n".join(mismatches) + alkene_count = len(alkene_names) if alkene_names else 0 + print(f"✓ alkene compounds identified correctly ({alkene_count} found)") diff --git a/tests/test_source_docstrings.py b/tests/test_source_docstrings.py index ea58fb3..8654753 100644 --- a/tests/test_source_docstrings.py +++ b/tests/test_source_docstrings.py @@ -67,16 +67,40 @@ def _iter_api_functions(module_node): class SourceDocstringContractTestCase(unittest.TestCase): def test_source_function_documentation(self): - source_dir = Path(__file__).resolve().parents[1] / "source" + fuellib_dir = Path(__file__).resolve().parents[1] / "fuellib" + + # Check main module, public API modules, exporter scripts, and CLI entry points + py_files = [ + fuellib_dir / "__init__.py", + fuellib_dir / "_data_locator.py", + fuellib_dir / "fuel.py", + fuellib_dir / "convert.py", + fuellib_dir / "utility.py", + fuellib_dir / "exporters" / "pele.py", + fuellib_dir / "exporters" / "converge.py", + fuellib_dir / "cli" / "fuel_manager.py", + fuellib_dir / "cli" / "build_docs.py", + fuellib_dir / "cli" / "clean_docs.py", + fuellib_dir / "cli" / "format_code.py", + ] + total_count = 0 passed_count = 0 current_file = None print("\n") # Add newline to separate from unittest verbose output - for py_file in sorted(source_dir.glob("*.py")): + # Verify all expected files exist before checking docstrings + for py_file in py_files: + self.assertTrue( + py_file.exists(), + msg=f"Expected file not found: {py_file.relative_to(fuellib_dir.parent)} " + f"(packaging issue or accidental deletion?)", + ) + + for py_file in py_files: tree = ast.parse(py_file.read_text(encoding="utf-8"), filename=str(py_file)) - file_label = py_file.relative_to(source_dir.parent) + file_label = py_file.relative_to(fuellib_dir.parent) # Print file header when switching files if current_file != file_label: diff --git a/tests/test_utilities.py b/tests/test_utilities.py new file mode 100644 index 0000000..0d6560d --- /dev/null +++ b/tests/test_utilities.py @@ -0,0 +1,134 @@ +"""Tests for FuelLib utility functions and CLI commands.""" + +import subprocess +import unittest + +import fuellib as fl + + +class TestUtilityFunctions(unittest.TestCase): + """Test standalone utility functions.""" + + def test_epsilon_to_characteristic_temperature(self): + """Test epsilon conversion from J/mol to Kelvin.""" + # Test with a known value + # epsilon = 1000 J/mol + # epsilon_molecule = 1000 / 6.02214076e23 J + # T* = epsilon_molecule / k_B = (1000 / 6.02214076e23) / 1.380649e-23 K + result = fl.convert.epsilon_to_characteristic_temperature(1000.0) + expected = (1000.0 / fl.constants.N_A) / fl.constants.k_B + self.assertAlmostEqual(result, expected, places=10) + + def test_epsilon_to_characteristic_temperature_zero(self): + """Test epsilon conversion with zero input.""" + result = fl.convert.epsilon_to_characteristic_temperature(0.0) + self.assertEqual(result, 0.0) + + def test_epsilon_to_characteristic_temperature_negative(self): + """Test epsilon conversion with negative input.""" + result = fl.convert.epsilon_to_characteristic_temperature(-1000.0) + expected = (-1000.0 / fl.constants.N_A) / fl.constants.k_B + self.assertAlmostEqual(result, expected, places=10) + + def test_C2K(self): + """Test Celsius to Kelvin conversion.""" + # 0°C = 273.15 K + self.assertAlmostEqual(fl.convert.C2K(0.0), 273.15, places=10) + # 25°C = 298.15 K + self.assertAlmostEqual(fl.convert.C2K(25.0), 298.15, places=10) + # 100°C = 373.15 K + self.assertAlmostEqual(fl.convert.C2K(100.0), 373.15, places=10) + + def test_K2C(self): + """Test Kelvin to Celsius conversion.""" + # 273.15 K = 0°C + self.assertAlmostEqual(fl.convert.K2C(273.15), 0.0, places=10) + # 298.15 K = 25°C + self.assertAlmostEqual(fl.convert.K2C(298.15), 25.0, places=10) + # 373.15 K = 100°C + self.assertAlmostEqual(fl.convert.K2C(373.15), 100.0, places=10) + + def test_C2K_K2C_roundtrip(self): + """Test roundtrip conversion between Celsius and Kelvin.""" + original_c = 42.5 + kelvin = fl.convert.C2K(original_c) + result_c = fl.convert.K2C(kelvin) + self.assertAlmostEqual(result_c, original_c, places=10) + + +class TestUtilityCLI(unittest.TestCase): + """Test command-line interface utilities.""" + + def _run_cli_command(self, command, *args): + """Run a CLI command and return stdout.""" + try: + result = subprocess.run( + [command] + list(args), + capture_output=True, + text=True, + timeout=5, + ) + return result.returncode, result.stdout, result.stderr + except FileNotFoundError: + self.skipTest(f"Command '{command}' not found in PATH") + + def test_fl_eps2K_basic(self): + """Test fl-eps2K CLI command.""" + returncode, stdout, stderr = self._run_cli_command("fl-eps2K", "1000.0") + self.assertEqual(returncode, 0, f"stderr: {stderr}") + self.assertIn("Characteristic temperature", stdout) + self.assertIn("K", stdout) + + def test_fl_eps2K_invalid_input(self): + """Test fl-eps2K CLI with invalid input.""" + returncode, stdout, stderr = self._run_cli_command("fl-eps2K", "not_a_number") + self.assertNotEqual(returncode, 0) + self.assertIn("error", stderr) + + def test_fl_eps2K_no_args(self): + """Test fl-eps2K CLI with no arguments.""" + returncode, stdout, stderr = self._run_cli_command("fl-eps2K") + self.assertNotEqual(returncode, 0) + self.assertIn("usage", stderr) + + def test_fl_C2K_basic(self): + """Test fl-C2K CLI command.""" + returncode, stdout, stderr = self._run_cli_command("fl-C2K", "25.0") + self.assertEqual(returncode, 0, f"stderr: {stderr}") + self.assertIn("298.15", stdout) + self.assertIn("K", stdout) + + def test_fl_C2K_invalid_input(self): + """Test fl-C2K CLI with invalid input.""" + returncode, stdout, stderr = self._run_cli_command("fl-C2K", "not_a_number") + self.assertNotEqual(returncode, 0) + self.assertIn("error", stderr) + + def test_fl_C2K_no_args(self): + """Test fl-C2K CLI with no arguments.""" + returncode, stdout, stderr = self._run_cli_command("fl-C2K") + self.assertNotEqual(returncode, 0) + self.assertIn("usage", stderr) + + def test_fl_K2C_basic(self): + """Test fl-K2C CLI command.""" + returncode, stdout, stderr = self._run_cli_command("fl-K2C", "298.15") + self.assertEqual(returncode, 0, f"stderr: {stderr}") + self.assertIn("25.00", stdout) + self.assertIn("C", stdout) + + def test_fl_K2C_invalid_input(self): + """Test fl-K2C CLI with invalid input.""" + returncode, stdout, stderr = self._run_cli_command("fl-K2C", "not_a_number") + self.assertNotEqual(returncode, 0) + self.assertIn("error", stderr) + + def test_fl_K2C_no_args(self): + """Test fl-K2C CLI with no arguments.""" + returncode, stdout, stderr = self._run_cli_command("fl-K2C") + self.assertNotEqual(returncode, 0) + self.assertIn("usage", stderr) + + +if __name__ == "__main__": + unittest.main() diff --git a/tutorials/basic.py b/tutorials/basic.py index 9fd432a..7a30bca 100644 --- a/tutorials/basic.py +++ b/tutorials/basic.py @@ -1,11 +1,4 @@ -import os -import sys - -# Add the FuelLib directory to the Python path -FUELLIB_DIR = os.path.dirname(os.path.dirname(__file__)) -sys.path.append(FUELLIB_DIR) -import paths -import FuelLib as fl +import fuellib as fl # Create a fuel object for the fuel "heptane-decane" fuel = fl.fuel("heptane-decane") diff --git a/tutorials/compositionPlots.py b/tutorials/compositionPlots.py index 2a05525..7ffdf70 100644 --- a/tutorials/compositionPlots.py +++ b/tutorials/compositionPlots.py @@ -1,96 +1,69 @@ -import os -import sys import numpy as np import pandas as pd import re import matplotlib.pyplot as plt -# Add the FuelLib directory to the Python path -FUELLIB_DIR = os.path.dirname(os.path.dirname(__file__)) -sys.path.append(FUELLIB_DIR) -import paths -import FuelLib as fl +import fuellib as fl fuel_name = "posf10325" fuel = fl.fuel(fuel_name) -# Classify compounds into families -aromatic = [ - True if re.search(r"Toluene|Benzene|Aromatic", comp, re.IGNORECASE) else False - for comp in fuel.compounds -] -n_alkane = [ - True if re.search(r"n-C", comp, re.IGNORECASE) else False for comp in fuel.compounds -] -isoalkane = [ - True if re.search(r"Isoparaffin", comp, re.IGNORECASE) else False - for comp in fuel.compounds -] -cycloalkane = [ - True if re.search(r"Cycloparaffin", comp, re.IGNORECASE) else False - for comp in fuel.compounds -] - # Create a DataFrame with the compounds and their families -colNames = ["Compound", "Weight %"] -df = pd.DataFrame({"Compounds": fuel.compounds, "Weight %": fuel.Y_0 * 100}) -# Append classification as a new column +# Use the hydrocarbon type classification from group decompositions family_names = ["n-alkane", "iso-alkane", "cyclo-alkane", "aromatic"] -df["Family"] = np.select( - [n_alkane, isoalkane, cycloalkane, aromatic], family_names, default="unknown" +df = pd.DataFrame( + { + "Compound": fuel.compounds, + "Weight %": fuel.Y_0 * 100, + "Family": fuel.hc_type, + } ) -# Determine carbon number by row: +# Determine carbon number from compound name def determine_carbon_number(compound): + """Extract carbon number from compound name.""" if "Toluene" in compound: return 7 elif "benzene" in compound.lower(): - # Extract the number after "C" and add 7 match = re.search(r"C(\d+)", compound) if match: try: - carbon_number = int(match.group(1)) - return carbon_number + 6 + return int(match.group(1)) + 6 except ValueError: - return np.nan # Handle cases where extraction fails - else: - return np.nan # No match found + return np.nan + return np.nan else: - # Extract the number after "C" in either format match = re.search(r"C(\d+)", compound) if match: try: return int(match.group(1)) except ValueError: - return np.nan # Handle cases where extraction fails - else: - return np.nan # No match found + return np.nan + return np.nan + +df["nC"] = df["Compound"].apply(determine_carbon_number) -# Apply the function to the column and append as a new column -df["nC"] = df.Compounds.apply(determine_carbon_number) +# Remove rows with weight % <= 0.01 +df = df[df["Weight %"] > 0.01] -# Determine relative weight % of each family +# Calculate family weights family_weights = df.groupby("Family")["Weight %"].sum() -# Print the sum of weight % for each family -print("\n" + "=" * 45) +# Print composition table +print(f"\n{'=' * 50}") print("Relative Weight % of Each Compound Family") print(f"Fuel: {fuel_name}") -print("=" * 45) +print("=" * 50) for family, weight in family_weights.items(): print(f" {family:<20} {weight:>8.2f}%") -print("-" * 45) +print("-" * 50) print(f" {'Total':<20} {family_weights.sum():>8.2f}%") -print("=" * 45 + "\n") - -# Remove rows <= 0.01 in weight % column at max(nC) -df = df[df["Weight %"] > 0.01] +print("=" * 50 + "\n") -# Plotting parameters -spacing = [-0.2985, -0.099, 0.099, 0.2985] +# Color scheme colors = { "n-alkane": "#063C61", "iso-alkane": "#2980B9", @@ -98,60 +71,102 @@ def determine_carbon_number(compound): "aromatic": "#7f7f7f", } -# Bar plot of the number of compounds in each family -plt.figure(figsize=(7, 5)) +# Create figure with two subplots side by side +fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5), constrained_layout=True) + +# Plot 1: Bar chart grouped by carbon number +spacing = [-0.2985, -0.099, 0.099, 0.2985] N = df.nC.unique() families_in_data = df["Family"].unique() + for k, family in enumerate(family_names): if family not in families_in_data: - # Only plot families that actually exist in the data continue - nC = df[df["Family"] == family].nC - weight = df[df["Family"] == family]["Weight %"] + df_family = df[df["Family"] == family] + nC = df_family.nC + weight = df_family["Weight %"] - # check duplicate nC values + # Check for duplicate carbon numbers and sum weights if len(nC) != len(set(nC)): - # If there are duplicates, sum the weights for each nC - df_grouped = ( - df[df["Family"] == family].groupby("nC")["Weight %"].sum().reset_index() - ) + df_grouped = df_family.groupby("nC")["Weight %"].sum().reset_index() nC = df_grouped["nC"] weight = df_grouped["Weight %"] - plt.bar( - nC + spacing[k], weight, label=family, alpha=1, color=colors[family], width=0.2 + + ax1.bar( + nC + spacing[k], + weight, + label=family, + alpha=1, + color=colors.get(family, "#7f7f7f"), + width=0.2, ) - plt.xticks(df.nC.unique(), fontsize=14) - plt.xlim(min(N) - 0.5, max(N) + 0.5) - -plt.xlabel("Carbon Number", fontsize=16) -plt.xticks(df.nC.unique(), fontsize=14) -plt.yticks(fontsize=14) -plt.ylabel("Weight %", fontsize=16) -plt.title("Fuel Composition", fontsize=16, fontweight="bold") -plt.legend(fontsize=14) -plt.tight_layout() - -# Plot pie chart of family weights -family_names = family_weights.index.tolist() -plt.figure(figsize=(7, 5)) -plt.pie( - family_weights, + +ax1.set_xlabel("Carbon Number", fontsize=16) +ax1.set_xticks(sorted(N)) +ax1.set_xticklabels(sorted(N), fontsize=14) +ax1.set_xlim(min(N) - 0.5, max(N) + 0.5) +ax1.set_ylabel("Weight %", fontsize=16) +ax1.tick_params(axis="y", labelsize=14) +ax1.grid(axis="y", alpha=0.3) +ax1.legend(fontsize=12, loc="upper left") + +# Plot 2: Pie chart of family composition +# Only include families that have weight > 0 +families_present = [ + f for f in family_names if f in family_weights.index and family_weights[f] > 0 +] +family_weights_sorted = family_weights[families_present] + +# Create pie chart without labels/percentages (we'll add them outside) +wedges, texts = ax2.pie( + family_weights_sorted, labels=None, - autopct="%1.1f%%", + autopct=None, startangle=140, - colors=[colors[family] for family in family_names], - textprops={"fontsize": 16, "weight": "bold", "color": "white"}, + colors=[colors.get(family, "#7f7f7f") for family in family_weights_sorted.index], ) + +# Add percentages outside the pie with arrows +for wedge, value, family in zip( + wedges, family_weights_sorted.values, family_weights_sorted.index +): + angle = (wedge.theta2 + wedge.theta1) / 2 + radius = 1.3 + x = radius * np.cos(np.radians(angle)) + y = radius * np.sin(np.radians(angle)) + + # Determine horizontal alignment based on position + ha = "left" if x > 0 else "right" + + # Add annotation with arrow + ax2.annotate( + f"{value:.1f}%", + xy=(np.cos(np.radians(angle)), np.sin(np.radians(angle))), + xytext=(x, y), + ha=ha, + va="center", + fontsize=14, + fontweight="bold", + arrowprops=dict(arrowstyle="-", color="black", lw=1.5), + ) + +ax2.axis("equal") + +# Add a single figure-level legend for all families legend_handles = [ - plt.Rectangle((0, 0), 1, 1, fc=colors[family]) for family in family_names + plt.Rectangle((0, 0), 1, 1, fc=colors.get(family, "#7f7f7f")) + for family in family_weights_sorted.index ] -plt.legend( +fig.legend( legend_handles, - family_names, - loc="center left", - bbox_to_anchor=(1, 0.5), - fontsize=14, + family_weights_sorted.index, + loc="upper center", + bbox_to_anchor=(0.5, -0.02), + ncol=4, + fontsize=13, + frameon=True, ) -plt.axis("equal") -plt.tight_layout() + +fig.suptitle("Fuel Composition", fontsize=16, fontweight="bold") + plt.show() diff --git a/tutorials/customFuel.py b/tutorials/customFuel.py new file mode 100644 index 0000000..5d09a6e --- /dev/null +++ b/tutorials/customFuel.py @@ -0,0 +1,36 @@ +import fuellib as fl + +# Load an embedded fuel +fuel = fl.fuel("posf10264") + +print(f"Fuel: {fuel.name}") +print(f"Fuel data directory: {fuel.fuelDataDir}") +print(f"GC data directory: {fuel.fuelDataGcDir}") +print(f"Decomposition directory: {fuel.fuelDataDecompDir}") +print(f"Properties directory: {fuel.fuelDataPropsDir}") +print(f"Number of compounds: {fuel.num_compounds}") + +# To use a custom fuel, create a directory structure like: +# customFuels/fuelData/ +# ├── gcData/ +# │ └── myFuel_init.csv +# ├── groupDecompositionData/ +# │ └── myFuel.csv +# └── propertiesData/ (optional) +# └── myFuel.csv +# +# Then load it with: +custom_fuel = fl.fuel("hefa-S1", fuelDataDir="customFuels/fuelData") + +# After loading, the fuel object has the correct directory paths: +custom_fuel.fuelDataDir +custom_fuel.fuelDataGcDir +custom_fuel.fuelDataDecompDir +custom_fuel.fuelDataPropsDir + +print(f"\nFuel: {custom_fuel.name}") +print(f"Fuel data directory: {custom_fuel.fuelDataDir}") +print(f"GC data directory: {custom_fuel.fuelDataGcDir}") +print(f"Decomposition directory: {custom_fuel.fuelDataDecompDir}") +print(f"Properties directory: {custom_fuel.fuelDataPropsDir}") +print(f"Number of compounds: {custom_fuel.num_compounds}") diff --git a/tutorials/hefaBlends.py b/tutorials/hefaBlends.py index 333d179..48ffff5 100644 --- a/tutorials/hefaBlends.py +++ b/tutorials/hefaBlends.py @@ -1,14 +1,9 @@ import os -import sys import numpy as np import pandas as pd import matplotlib.pyplot as plt -# Add the FuelLib directory to the Python path -FUELLIB_DIR = os.path.dirname(os.path.dirname(__file__)) -sys.path.append(FUELLIB_DIR) -from paths import * -import FuelLib as fl +import fuellib as fl # ----------------------------------------------------------------------------- # Calculate mixture properties from the group contribution properties @@ -65,16 +60,18 @@ def getPredAndData(fuel_name, prop_name, blend): jetA = fl.fuel(conv_fuel_name) data_file = "hefa-jet-a-blends.csv" - data = pd.read_csv(os.path.join(FUELDATA_PROPS_DIR, data_file), skiprows=[1]) + data = pd.read_csv( + os.path.join(fl.get_fueldata_props_dir(), data_file), skiprows=[1] + ) col = f"{prop_name}_{fuel_name[5:].upper()}" prop_data = data[col] blend_data = data["HEFA_concentration"] # Separate properties and associated temperatures from data if prop_name == "Density": - T = fl.C2K(15) + T = fl.convert.C2K(15) elif prop_name == "Viscosity": - T = fl.C2K(-20) + T = fl.convert.C2K(-20) # Vector for FuelLib predictions prop_pred = np.zeros_like(blend) @@ -142,7 +139,7 @@ def getPredAndData(fuel_name, prop_name, blend): # Add labels and adjust ticks ax[i].set_xlabel("HEFA Concentration [wt %]", fontsize=fsize) ax[i].set_xticks([0, 20, 40, 60, 80, 100]) - ax[i].set_ylabel(ylab(prop_names[i], fl.K2C(T)), fontsize=fsize) + ax[i].set_ylabel(ylab(prop_names[i], fl.convert.K2C(T)), fontsize=fsize) ax[i].tick_params(labelsize=ticksize) handles, labels = ax[0].get_legend_handles_labels() diff --git a/tutorials/mixtureProperties.py b/tutorials/mixtureProperties.py index 75b86da..08923d3 100644 --- a/tutorials/mixtureProperties.py +++ b/tutorials/mixtureProperties.py @@ -1,14 +1,9 @@ import os -import sys import numpy as np import pandas as pd import matplotlib.pyplot as plt -# Add the FuelLib directory to the Python path -FUELLIB_DIR = os.path.dirname(os.path.dirname(__file__)) -sys.path.append(FUELLIB_DIR) -from paths import * -import FuelLib as fl +import fuellib as fl # ----------------------------------------------------------------------------- # Calculate mixture properties from the group contribution properties @@ -89,19 +84,21 @@ def getPredAndData(fuel_name, prop_name): data_file = f"{fuel_name}.csv" try: - data = pd.read_csv(os.path.join(FUELDATA_PROPS_DIR, data_file), skiprows=[1]) + data = pd.read_csv( + os.path.join(fl.get_fueldata_props_dir(), data_file), skiprows=[1] + ) # Separate properties and associated temperatures from data T_data = data.Temperature[data[prop_name].notna()] prop_data = data[prop_name].dropna() # Vectors for temperature (convert from C to K) - T_pred = fl.C2K(np.linspace(min(T_data), max(T_data), 100)) + T_pred = fl.convert.C2K(np.linspace(min(T_data), max(T_data), 100)) except (FileNotFoundError, KeyError): # If propertyData is not found, set temp min/max from xticks_posf T_data = pd.Series(dtype=float) prop_data = pd.Series(dtype=float) temp_min = min(xticks_posf[prop_name]) temp_max = max(xticks_posf[prop_name]) - T_pred = fl.C2K(np.linspace(temp_min, temp_max, 100)) + T_pred = fl.convert.C2K(np.linspace(temp_min, temp_max, 100)) # Vectors for density, viscosity and vapor pressure pred = np.zeros_like(T_pred) @@ -145,7 +142,7 @@ def getPredAndData(fuel_name, prop_name): # Plot GCM predictions and data ax[i].plot( - fl.K2C(T), + fl.convert.K2C(T), pred, "-", color=line_color,