diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 18be543..b20fc9b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,32 +1,29 @@ --- name: Bug report -about: Create a report to help us improve +about: Report a problem to help us improve title: "[bug]" labels: bug assignees: markleader - --- -**Describe the bug** -A clear and concise description of what the bug is. - -- Interface(s) affected: [e.g. Fortran, C, legacy, Python] - -- Is this an issue with backwards-compatibility using the legacy interface? If so, paste the the `.inp` problem file, and the relevant output for inspection. +**Summary** +A clear, concise description of the bug. -**To Reproduce** -Steps to reproduce the behavior: +**Reproduction** +- Interface: [Fortran | C | Python | legacy] +- Minimal input / steps (attach .inp if relevant): +- Command or API call used: **Expected behavior** -A clear and concise description of what you expected to happen. +What you expected to happen. -**Screenshots** -If applicable, add screenshots to help explain your problem. +**Actual behavior** +What happened (include key error messages/output). -**Build architecture (please complete the following information):** - - OS: [e.g. Mac OS, Windows] - - Fortran compiler [e.g. gfortran, ifort] - - Version [e.g. 3.0.0] +**Environment** +- OS: +- CEA version/commit: +- Compiler or Python version (if relevant): **Additional context** -Add any other context about the problem here. +Anything else helpful (optional). diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index f4ca351..84aeed0 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,17 +1,16 @@ --- name: Feature request -about: Suggest an idea for this project +about: Suggest an improvement title: "[feature]" labels: enhancement assignees: '' - --- -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. It is difficult to [...] +**Problem / use case** +What’s hard or missing today? -**Describe the solution you'd like** -A clear and concise description of what you want to happen. +**Proposed solution** +What would you like to see? **Additional context** -Add any other context or screenshots about the feature request here. +Examples, references, or alternatives (optional). diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..e26af8b --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,10 @@ +## Summary + +## Changes + +## Testing +- Not run (explain why) + +## Compatibility / Numerical behavior +- [ ] No expected changes to numerical results +- [ ] Expected changes (explain and provide validation) diff --git a/.github/workflows/basic_build.yml b/.github/workflows/basic_build.yml index ffad312..183eb50 100644 --- a/.github/workflows/basic_build.yml +++ b/.github/workflows/basic_build.yml @@ -36,12 +36,34 @@ jobs: with: python-version: "3.12" - - name: Set up Fortran compiler + - name: Set up Fortran compiler (Unix) + if: runner.os != 'Windows' uses: fortran-lang/setup-fortran@v1 with: compiler: ${{ matrix.toolchain.compiler }} version: ${{ matrix.toolchain.version }} + - name: Set up Fortran compiler (Windows) + if: runner.os == 'Windows' + run: | + # Use pre-installed MinGW on Windows runners to avoid Chocolatey issues + # GitHub Actions windows-latest runners include MinGW in C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin + $mingwPath = "C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin" + if (Test-Path $mingwPath) { + echo "$mingwPath" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + echo "FC=$mingwPath\gfortran.exe" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + } else { + # Fallback: search for gfortran in common locations + $gfortran = Get-Command gfortran -ErrorAction SilentlyContinue + if ($gfortran) { + echo "FC=$($gfortran.Source)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + } else { + Write-Error "gfortran not found on Windows runner" + exit 1 + } + } + shell: pwsh + - name: Install build tools run: | python -m pip install --upgrade pip @@ -52,6 +74,7 @@ jobs: git --version cmake --version ninja --version + if command -v gfortran &> /dev/null; then gfortran --version; fi if [ -n "${FC}" ]; then "${FC}" --version; fi - name: Configure diff --git a/.gitignore b/.gitignore index 48ef9df..ec8e977 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ extern/install *.xlsx *.pdf *.bat +*.lib !sampleThe/*.inp !test/main_interface/*.inp !test/main_interface/reference_output/*.out diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..722aa1c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +All notable user-visible changes to this project are documented here. + +## [Unreleased] + +### Changed + +### Fixed + +### Added + +## [3.0.0] – 2025-12-31 +- Initial public release. diff --git a/CLAUDE.md b/CLAUDE.md index 5afc80d..ef78baf 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,13 +1,133 @@ -# AGENTS - -This repository is a scientific computing library (CEA). Follow these rules: - -- Do NOT modify `thermo.inp` or `trans.inp` unless explicitly instructed. -- Numerical correctness is paramount; preserve bitwise results and scientific behavior. -- Avoid algorithmic changes unless explicitly requested. -- Prefer clarity over cleverness or micro-optimizations. -- Keep changes small and focused; avoid drive-by formatting or whitespace churn. -- Maintain backward compatibility for the legacy user base. -- If numerical behavior might change, call it out and add validation or tests when possible. -- Respect layer boundaries: Fortran core in `source/`, C bindings in `source/bind/c/`, - Python bindings in `source/bind/python/`. +# CLAUDE.md - AI Agent Instructions for CEA + +This repository contains CEA (Chemical Equilibrium with Applications), a NASA scientific computing library for chemical equilibrium calculations. The codebase consists of validated Fortran solvers with C and Python bindings. + +## Core Principles + +1. **Numerical correctness is paramount** - Preserve bitwise results and scientific behavior +2. **Backward compatibility matters** - Legacy user base depends on stable behavior +3. **Clarity over cleverness** - Prefer readable code over micro-optimizations +4. **Small, focused changes** - One concern per change; avoid bundling unrelated work + +## Critical Rules + +### Data Files (DO NOT MODIFY) +- **NEVER** modify `thermo.inp` or `trans.inp` unless explicitly instructed by the user +- **NEVER** modify `data/thermo.inp` or `data/trans.inp` +- These files contain validated thermodynamic and transport property databases + +### Algorithmic Changes +- **AVOID** changing solver algorithms unless explicitly requested +- **AVOID** modifying convergence logic, tolerances, or loop ordering +- **CALL OUT** any changes that might affect numerical behavior +- **ADD** validation tests when numerical behavior might change + +### Code Quality +- **AVOID** drive-by formatting or whitespace changes +- **AVOID** restructuring code for style alone +- **KEEP** diffs minimal and focused +- **PRESERVE** existing naming conventions and patterns + +## Architecture & Layer Boundaries + +``` +source/ - Fortran core (scientific solvers) +source/bind/c/ - C ABI bindings (thin adapters) +source/bind/python/ - Python interface (Cython/NumPy) +data/ - Thermodynamic and transport databases +``` + +**Respect layer boundaries:** +- Do not mix Fortran solver changes with binding changes +- Do not change scientific logic from binding layers +- Keep C bindings thin (no business logic) +- Python layer may add Pythonic conveniences but not alter solver behavior + +## Build System + +- **Build tool**: CMake 3.19+ +- **Languages**: Fortran (core), C (bindings), Python (bindings) +- **Compilers**: Intel and GNU Fortran are primary targets +- **Python build**: scikit-build-core with Ninja generator +- **Presets available**: `core` (Fortran only), `core-c` (Fortran+C), default (all bindings) + +### Python Binding Development +When modifying Python bindings: +1. Changes to `*.pyx` or `*.pxd` files require rebuild +2. Editable installs do not auto-rebuild +3. Rebuild command: `make py-rebuild` (requires Ninja on PATH) +4. Test command: `pytest source/bind/python/tests` +5. Ensure `numpy` is installed in the active Python environment + +## Testing + +- **Run existing tests** before and after changes +- **Add regression tests** for bug fixes when possible +- **Add validation tests** for new features +- **Verify** no unintended behavior changes occur + +Test locations: +- Fortran: Built with `-DCEA_BUILD_TESTING=ON` +- Python: `pytest source/bind/python/tests` +- Legacy CLI validation: `test/main_interface/test_main.py` +- Samples: `samples/` directory contains reference cases + +## Common Scenarios + +### Bug Fixes +- Identify root cause before fixing +- Add regression test if feasible +- Keep fix minimal and focused +- Document what was broken and how it's fixed + +### Documentation +- Improvements always welcome +- Use Markdown or reStructuredText +- Be technically accurate +- Avoid marketing language +- Document assumptions and limitations + +### Interface Improvements (C/Python bindings) +- Allowed and encouraged +- Do not change solver behavior +- Add clear docstrings/comments +- Follow language idioms (Pythonic for Python, etc.) + +### Refactoring +- Discuss with user first for large refactors +- Prove numerical equivalence +- Provide before/after comparison +- Small, incremental refactors preferred + +## What to Call Out + +**Always explicitly mention if your change involves:** +- Floating-point arithmetic reordering +- Loop ordering changes +- Tolerance or convergence criterion modifications +- Changes to thermodynamic assumptions +- Database compilation or access patterns +- Changes that might affect bitwise reproducibility + +## Dependencies + +**Core** (Fortran): No external dependencies +**C bindings**: No additional dependencies +**Python bindings**: Requires: +- Cython +- NumPy +- scikit-build-core +- Ninja (build time) + +## References + +When in doubt, refer to: +- [CONTRIBUTING.md](CONTRIBUTING.md) - Detailed contribution guidelines +- [README.md](README.md) - Build and usage instructions +- `docs/` - Full documentation + +## Summary + +Priority order: **Numerical correctness > Backward compatibility > Performance > Style** + +When uncertain about a change, ask the user first. diff --git a/CMakeLists.txt b/CMakeLists.txt index a19e096..15268fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,27 +79,56 @@ add_subdirectory(extern/fbasics) add_subdirectory(source) # Build the thermodynamic properties database -#configure_file(src/thermo.inp thermo.inp COPYONLY) -#add_custom_target(thermo.lib ALL -# COMMAND cea thermo >/dev/null -# BYPRODUCTS thermo.lib thermo.out -# DEPENDS cea -#) +add_custom_command( + OUTPUT ${CMAKE_BINARY_DIR}/thermo.lib + COMMAND $ --compile-thermo ${CMAKE_SOURCE_DIR}/data/thermo.inp + DEPENDS cea ${CMAKE_SOURCE_DIR}/data/thermo.inp + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Compiling thermodynamic database from thermo.inp" +) # Build the transport properties database -#configure_file(src/trans.inp trans.inp COPYONLY) -#add_custom_target(trans.lib ALL -# COMMAND cea trans >/dev/null -# BYPRODUCTS trans.lib trans.out -# DEPENDS cea -#) +add_custom_command( + OUTPUT ${CMAKE_BINARY_DIR}/trans.lib + COMMAND $ --compile-trans ${CMAKE_SOURCE_DIR}/data/trans.inp + DEPENDS cea ${CMAKE_SOURCE_DIR}/data/trans.inp + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Compiling transport database from trans.inp" +) + +# Create a custom target that depends on both database files +add_custom_target(compile_databases ALL + DEPENDS ${CMAKE_BINARY_DIR}/thermo.lib ${CMAKE_BINARY_DIR}/trans.lib +) + +if(PROJECT_IS_TOP_LEVEL) + add_custom_command(TARGET compile_databases POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_BINARY_DIR}/thermo.lib ${CMAKE_SOURCE_DIR}/data/thermo.lib + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_BINARY_DIR}/trans.lib ${CMAKE_SOURCE_DIR}/data/trans.lib + COMMAND ${CMAKE_COMMAND} -E make_directory + ${CMAKE_SOURCE_DIR}/source/bind/python/cea/data + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_BINARY_DIR}/thermo.lib + ${CMAKE_SOURCE_DIR}/source/bind/python/cea/data/thermo.lib + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_BINARY_DIR}/trans.lib + ${CMAKE_SOURCE_DIR}/source/bind/python/cea/data/trans.lib + COMMENT "Copying compiled databases to source data directory" + ) +endif() #----------------------------------------------------------------------- # Installation #----------------------------------------------------------------------- install( - FILES data/thermo.lib data/trans.lib + FILES ${CMAKE_BINARY_DIR}/thermo.lib ${CMAKE_BINARY_DIR}/trans.lib + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cea +) +install( + FILES ${CMAKE_BINARY_DIR}/thermo.lib ${CMAKE_BINARY_DIR}/trans.lib DESTINATION ${CMAKE_INSTALL_PREFIX}/data ) install(EXPORT cea-config diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 24c109e..0abf2db 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,6 +15,38 @@ CEA is governed by the following priorities: Changes that improve readability, documentation, or interfaces are often welcome. Changes that alter numerical behavior require careful justification and review. +## Getting Started + +### Setting Up Your Development Environment + +1. **Fork and clone the repository** + ```bash + git clone https://github.com/your-username/cea.git + cd cea + ``` + +2. **Choose a development preset** + CEA provides CMake presets for development. For contributors, use one of: + - `dev` – GNU/gfortran with all bindings (recommended for most contributors) + - `dev-intel` – Intel ifort with all bindings + - `dev-ub-hunt` – GNU with undefined behavior detection (for advanced debugging) + +3. **Configure and build** + ```bash + cmake --preset dev + cmake --build build-dev + ``` + +4. **Run tests to verify your setup** + ```bash + cd build-dev + ctest + ``` + +For Python development, see the [Python Binding Rebuilds](#python-binding-rebuilds-editable-installs) section below. + +See [README.md](README.md) for detailed build instructions and requirements. + ## Codebase Overview CEA consists of three primary layers: @@ -50,6 +82,9 @@ Large refactors or algorithmic changes should be discussed before implementation - Why the change is needed - Whether numerical behavior is expected to change This helps avoid duplicated effort and ensures alignment. + Use the issue templates for bug reports and feature requests: + - `.github/ISSUE_TEMPLATE/bug_report.md` + - `.github/ISSUE_TEMPLATE/feature_request.md` 2. **Make Small, Focused Changes** Each pull request should ideally address one concern: @@ -97,6 +132,50 @@ At minimum, contributors should verify that: - Existing tests pass - No unintended behavior changes occur +### Running Tests + +CEA uses pFUnit (part of the Goddard Fortran Ecosystem) for unit testing. Tests are enabled via the `CEA_BUILD_TESTING` CMake option. + +**Prerequisites:** +1. Clone GFE into the `extern/` directory: + ```bash + cd extern + git clone https://github.com/Goddard-Fortran-Ecosystem/GFE.git + cd GFE + git submodule update --init + ``` + +2. Configure CEA with testing enabled (the `dev*` presets enable this by default): + ```bash + cmake --preset dev + cmake --build build-dev + ``` + +**Running all tests:** +```bash +cd build-dev +ctest +``` + +**Running specific tests:** +```bash +# Run core CEA unit tests with verbose output +ctest -R cea_core_test -V + +# Run all main interface tests +ctest -R cea_main_test + +# Run C binding tests +ctest -R cea_bindc +``` + +**Available test suites:** +- `cea_core_test` – Core Fortran solver unit tests +- `cea_main_test*` – Legacy CLI interface tests +- `cea_bindc_*` – C binding validation tests + +For Python tests, see the [Python Binding Rebuilds](#python-binding-rebuilds-editable-installs) section. + ## Python Binding Rebuilds (Editable Installs) The Python package uses scikit-build-core with Ninja. Editable installs do not rebuild on import, @@ -109,6 +188,11 @@ Recommended workflow: - Rebuild the editable install (uses `--no-build-isolation`): `make py-rebuild` - Run Python tests: `pytest source/bind/python/tests` +Python database lookup follows the same precedence as the CLI: current working +directory, `CEA_DATA_DIR` (if set), packaged `cea/data`, then the repo `data/` +directory when running from a source checkout. Set `CEA_DATA_DIR` to point to +custom databases if needed. + If you are unsure how to test a change, ask in the issue or PR. ## Documentation Contributions @@ -140,10 +224,25 @@ There is no strict formatting tool enforced, but contributors should follow exis ## Commit and Pull Request Guidelines +### Branch Naming + +Branch names must use one of the following prefixes: + +- `feat/` – New features +- `fix/` – Bug fixes +- `docs/` – Documentation changes +- `chore/` – Build, tooling, dependencies +- `refactor/` – Code restructuring (no behavior change) +- `test/` – Test additions or improvements +- `exp/` – Experimental work +- `wip/` – Work in progress + +Prefer short, descriptive topic names (e.g., `fix/python-import-error`, `docs/build-instructions`). + ### Commits - Use clear, descriptive commit messages -- Avoid “drive-by” formatting or whitespace changes +- Avoid "drive-by" formatting or whitespace changes ### Pull Requests @@ -154,6 +253,9 @@ Your PR description should include: - Impacted components - Whether numerical behavior changes (yes/no) +The PR template provides a concise checklist: +- `.github/pull_request_template.md` + ## What Not to Change Please do not: diff --git a/README.md b/README.md index 8ad289e..95473d0 100644 --- a/README.md +++ b/README.md @@ -118,25 +118,50 @@ Python example (runs the H2/O2 case after installing the Python bindings): python source/bind/python/cea/samples/h2_02.py -## Manual Database Generation +## Database Generation + CEA requires thermodynamic and transport property databases. When using the -provided CMake build system, these databases are generated automatically during -the build and installed alongside the `cea` executable. However, in many -applications it is necessary to perform calculations with modified versions of -the provided databases. +provided CMake build system, these databases are automatically compiled from +`data/thermo.inp` and `data/trans.inp` during the build process and installed +alongside the `cea` executable. + +### Custom Database Generation -To generate modified databases, run the `cea` program in compilation mode with -the modified `thermo.inp` and `trans.inp` files. See the `data` directory for -baseline versions of these files. This will produce `thermo.lib` and -`trans.lib` in the current directory. +In many applications it is necessary to perform calculations with modified +versions of the provided databases. To generate custom databases, run the `cea` +program in compilation mode with your modified input files: ./cea --compile-thermo path/to/thermo.inp ./cea --compile-trans path/to/trans.inp +This will produce `thermo.lib` and `trans.lib` in the current directory. + To use the customized databases, copy them into the working directory where you will be executing the `cea` program (usually the same directory as the `.inp` problem definition file). Database files in the working directory will take -precedence over the installed database files. +precedence over the installed database files in `/data/`. + +### Database Lookup + +CEA locates `thermo.lib` and `trans.lib` in the following order: + +- For the CLI and C/Fortran APIs: current working directory, `CEA_DATA_DIR` (if + set), `./data`, then `/data`. +- For Python (`cea.init()` with no path): current working directory, + `CEA_DATA_DIR` (if set), packaged `cea/data`, then the repo `data/` directory + when running from a source checkout. + +You can override the search path by setting `CEA_DATA_DIR` or by passing explicit +paths: + +```bash +export CEA_DATA_DIR=/path/to/cea/data +``` + +```python +import cea +cea.init("/path/to/cea/data") +``` ## References diff --git a/data/thermo.lib b/data/thermo.lib deleted file mode 100644 index 34f6d58..0000000 Binary files a/data/thermo.lib and /dev/null differ diff --git a/data/trans.lib b/data/trans.lib deleted file mode 100644 index acc61ef..0000000 Binary files a/data/trans.lib and /dev/null differ diff --git a/source/bind/CMakeLists.txt b/source/bind/CMakeLists.txt index 0978b97..ff38f0e 100644 --- a/source/bind/CMakeLists.txt +++ b/source/bind/CMakeLists.txt @@ -64,12 +64,16 @@ if (CEA_ENABLE_BIND_PYTHON) ${PYTHON_INCLUDE_DIRS} ${NumPy_INCLUDE_DIRS} c) + if(TARGET compile_databases) + add_dependencies(libcea compile_databases) + endif() # the compiled library install(TARGETS libcea DESTINATION lib) install(TARGETS cea_bindc DESTINATION lib) - # default data files - install(FILES ${PROJECT_SOURCE_DIR}/data/thermo.lib DESTINATION data) - install(FILES ${PROJECT_SOURCE_DIR}/data/trans.lib DESTINATION data) + # default data files (compiled during build) + install(FILES ${CMAKE_BINARY_DIR}/thermo.lib DESTINATION data) + install(FILES ${CMAKE_BINARY_DIR}/trans.lib DESTINATION data) + # rest of the pure python package files handled by pip & scikit-build-core endif() @@ -112,4 +116,4 @@ endif() # c) # install(TARGETS cea_matlab DESTINATION cea_matlab) -# endif() \ No newline at end of file +# endif() diff --git a/source/bind/c/bindc.F90 b/source/bind/c/bindc.F90 index b966971..645ba67 100644 --- a/source/bind/c/bindc.F90 +++ b/source/bind/c/bindc.F90 @@ -3,7 +3,7 @@ module cea_bindc use cea, snl => species_name_len, & enl => element_name_len, & wp => real_kind - use cea_param, only: data_dirs, empty_dp, gas_constant + use cea_param, only: empty_dp, gas_constant, get_data_search_dirs use cea_input, only: ReactantInput use cea_mixture, only: names_match use iso_c_binding @@ -302,11 +302,13 @@ function cea_init_thermo(cthermofile) result(ierr) bind(c) character(c_char), intent(in) :: cthermofile(*) character(:), allocatable :: thermofile character(:), allocatable :: resolved + character(:), allocatable :: search_dirs(:) ierr = CEA_SUCCESS call c_copy(cthermofile, thermofile) - resolved = locate(thermofile, data_dirs) + call get_data_search_dirs(search_dirs) + resolved = locate(thermofile, search_dirs) if (is_empty(resolved)) then ierr = CEA_INVALID_FILENAME call log_error('Could not locate thermo database file: '//thermofile) @@ -334,11 +336,13 @@ function cea_init_trans(ctransfile) result(ierr) bind(c) character(c_char), intent(in) :: ctransfile(*) character(:), allocatable :: transfile character(:), allocatable :: resolved + character(:), allocatable :: search_dirs(:) ierr = CEA_SUCCESS call c_copy(ctransfile, transfile) - resolved = locate(transfile, data_dirs) + call get_data_search_dirs(search_dirs) + resolved = locate(transfile, search_dirs) if (is_empty(resolved)) then ierr = CEA_INVALID_FILENAME call log_error('Could not locate transport database file: '//transfile) diff --git a/source/bind/python/CEA.pyx b/source/bind/python/CEA.pyx index 359f1d0..65a0602 100644 --- a/source/bind/python/CEA.pyx +++ b/source/bind/python/CEA.pyx @@ -85,6 +85,8 @@ LOG_INFO = CEA_LOG_INFO LOG_DEBUG = CEA_LOG_DEBUG LOG_NONE = CEA_LOG_NONE +_py_log_level = LOG_WARNING + # Alias the equilibrium problem types TP = CEA_TP HP = CEA_HP @@ -285,8 +287,16 @@ def set_log_level(level): """ cdef cea_err ierr ierr = cea_set_log_level(level) + global _py_log_level + _py_log_level = int(level) return +def _maybe_print_init_path(label, path): + if _py_log_level == LOG_NONE: + return + if path: + print(f"Loaded {label} from: {path}") + def init(path=None, trans=True): """ Initialize the CEA library with thermodynamic and transport data files. @@ -295,7 +305,8 @@ def init(path=None, trans=True): ---------- path : str, optional Path to directory containing thermo.lib and trans.lib files. If None, searches the - current directory, then CEA_DATA_DIR, then the packaged cea/data directory. + current directory, then CEA_DATA_DIR, then the packaged cea/data directory, then + the repo data directory if present. trans : bool, default True Whether to initialize transport properties. Transport data are optional. @@ -315,6 +326,8 @@ def init(path=None, trans=True): if env_dir: candidate_dirs.append(env_dir) + dev_data_dir = None + pkg_data = None try: pkg_data = importlib_resources.files("cea").joinpath("data") @@ -323,7 +336,21 @@ def init(path=None, trans=True): if pkg_data is not None: with importlib_resources.as_file(pkg_data) as pkg_path: + if dev_data_dir is None: + try: + # Find repo root by locating data/thermo.inp for dev-tree runs. + search_root = os.path.dirname(pkg_path) + for _ in range(6): + dev_candidate = os.path.join(search_root, "data") + if os.path.isfile(os.path.join(dev_candidate, "thermo.inp")): + dev_data_dir = dev_candidate + break + search_root = os.path.dirname(search_root) + except Exception: + dev_data_dir = None pkg_dirs = candidate_dirs + [str(pkg_path)] + if dev_data_dir and dev_data_dir not in pkg_dirs: + pkg_dirs.append(dev_data_dir) thermo_path = None trans_path = None for dirname in pkg_dirs: @@ -344,6 +371,7 @@ def init(path=None, trans=True): ierr = cea_init_thermo(cthermo_path.ptr) if ierr != SUCCESS: raise ValueError("Invalid path; thermo.lib not found.") + _maybe_print_init_path("thermo.lib", thermo_path) if trans: if trans_path is None: @@ -359,8 +387,13 @@ def init(path=None, trans=True): "trans.lib could not be initialized; continuing without transport properties.", RuntimeWarning, ) + else: + _maybe_print_init_path("trans.lib", trans_path) return + if dev_data_dir and dev_data_dir not in candidate_dirs: + candidate_dirs.append(dev_data_dir) + thermo_path = None trans_path = None for dirname in candidate_dirs: @@ -381,6 +414,7 @@ def init(path=None, trans=True): ierr = cea_init_thermo(cthermo_path.ptr) if ierr != SUCCESS: raise ValueError("Invalid path; thermo.lib not found.") + _maybe_print_init_path("thermo.lib", thermo_path) if trans: if trans_path is None: @@ -396,22 +430,29 @@ def init(path=None, trans=True): "trans.lib could not be initialized; continuing without transport properties.", RuntimeWarning, ) + else: + _maybe_print_init_path("trans.lib", trans_path) return if type(path) is not str: raise TypeError("init path must be a string to the location of thermo.lib, and optionally trans.lib") - cthermo_path = _CString(path+"/thermo.lib", "init path") + thermo_path = os.path.join(path, "thermo.lib") + trans_path = os.path.join(path, "trans.lib") + cthermo_path = _CString(thermo_path, "init path") ierr = cea_init_thermo(cthermo_path.ptr) if ierr != SUCCESS: raise ValueError("Invalid path; thermo.lib not found.") + _maybe_print_init_path("thermo.lib", thermo_path) if trans: - ctrans_path = _CString(path+"/trans.lib", "init path") + ctrans_path = _CString(trans_path, "init path") ierr = cea_init_trans(ctrans_path.ptr) if ierr != SUCCESS: warnings.warn( "trans.lib not found; continuing without transport properties.", RuntimeWarning, ) + else: + _maybe_print_init_path("trans.lib", trans_path) return def init_thermo(thermofile): diff --git a/source/bind/python/cea/data/thermo.lib b/source/bind/python/cea/data/thermo.lib deleted file mode 100644 index 646e549..0000000 Binary files a/source/bind/python/cea/data/thermo.lib and /dev/null differ diff --git a/source/bind/python/cea/data/trans.lib b/source/bind/python/cea/data/trans.lib deleted file mode 100644 index acc61ef..0000000 Binary files a/source/bind/python/cea/data/trans.lib and /dev/null differ diff --git a/source/bind/python/cea/lib/data/thermo.lib b/source/bind/python/cea/lib/data/thermo.lib deleted file mode 100644 index 646e549..0000000 Binary files a/source/bind/python/cea/lib/data/thermo.lib and /dev/null differ diff --git a/source/bind/python/cea/lib/data/trans.lib b/source/bind/python/cea/lib/data/trans.lib deleted file mode 100644 index acc61ef..0000000 Binary files a/source/bind/python/cea/lib/data/trans.lib and /dev/null differ diff --git a/source/equilibrium.f90 b/source/equilibrium.f90 index dcc8827..c6ed117 100644 --- a/source/equilibrium.f90 +++ b/source/equilibrium.f90 @@ -1842,11 +1842,21 @@ subroutine EqSolution_set_nj(self, solver, nj_init) class(EqSolution), intent(inout), target :: self type(EqSolver), intent(in), target :: solver real(dp), intent(in) :: nj_init(:) + integer :: i + real(dp), parameter :: smalno = 1.0d-6 + real(dp), parameter :: smnol = -13.815511d0 ! Check if nj_init is allocated and has the correct size if (size(nj_init) == solver%num_products) then self%nj = nj_init - self%ln_nj = log(self%nj(:solver%num_gas)) + do i = 1, solver%num_gas + if (self%nj(i) <= 0.0d0) then + self%nj(i) = smalno + self%ln_nj(i) = smnol + else + self%ln_nj(i) = log(self%nj(i)) + end if + end do self%n = sum(self%nj(:solver%num_gas)) else call abort('EqSolution_set_nj: nj_init must be allocated and have size equal to num_products.') diff --git a/source/main.f90 b/source/main.f90 index 5b6f362..934f55a 100644 --- a/source/main.f90 +++ b/source/main.f90 @@ -19,6 +19,7 @@ program cea ! Locals character(:), allocatable :: input_file, thermo_file, trans_file character(:), allocatable :: compile_thermo_input, compile_trans_input + character(:), allocatable :: data_search_dirs(:) type(ThermoDB) :: all_thermo type(TransportDB) :: all_transport type(ProblemDB), allocatable :: problems(:) @@ -57,12 +58,14 @@ program cea call abort('Could not locate input file: '//input_file) end if - thermo_file = locate(thermo_file, data_dirs) + call get_data_search_dirs(data_search_dirs) + + thermo_file = locate(thermo_file, data_search_dirs) if (len(thermo_file) == 0) then call abort('Could not locate thermo file: '//thermo_file) end if - trans_file = locate(trans_file, data_dirs) + trans_file = locate(trans_file, data_search_dirs) if (len(trans_file) == 0) then call log_info('Could not locate transport file: '//trans_file) else diff --git a/source/param.f90.in b/source/param.f90.in index 3a0c862..9e8571f 100644 --- a/source/param.f90.in +++ b/source/param.f90.in @@ -42,4 +42,29 @@ module cea_param real(dp), parameter :: inv_sqrt2 = 1.0d0/sqrt2 real(dp), parameter :: inv_sqrt3 = 1.0d0/sqrt3 +contains + + subroutine get_data_search_dirs(search_dirs) + character(:), allocatable, intent(out) :: search_dirs(:) + character(:), allocatable :: env_dir + integer :: env_status, env_len, max_len + + call get_environment_variable("CEA_DATA_DIR", length=env_len, status=env_status) + if (env_status == 0 .and. env_len > 0) then + allocate(character(env_len) :: env_dir) + call get_environment_variable("CEA_DATA_DIR", value=env_dir) + end if + + if (allocated(env_dir)) then + max_len = max(len(env_dir), len(data_dirs(1))) + allocate(character(max_len) :: search_dirs(size(data_dirs) + 1)) + search_dirs(1) = data_dirs(1) + search_dirs(2) = env_dir + search_dirs(3:) = data_dirs(2:) + else + allocate(character(len(data_dirs(1))) :: search_dirs(size(data_dirs))) + search_dirs = data_dirs + end if + end subroutine + end module diff --git a/test/main_interface/test_main.py b/test/main_interface/test_main.py index d2f6edf..f045a72 100644 --- a/test/main_interface/test_main.py +++ b/test/main_interface/test_main.py @@ -1,5 +1,8 @@ import os +import shutil +import subprocess import warnings +from pathlib import Path import pandas as pd # This program will run the tests in `test_names`, executing the `.inp` files @@ -19,8 +22,10 @@ "example7", # Shock problem "example6" # Deton problem ] -reference_dir = "./reference_output/" -test_dir = "./test_output/" +SCRIPT_DIR = Path(__file__).resolve().parent +REPO_ROOT = SCRIPT_DIR.parent.parent +reference_dir = SCRIPT_DIR / "reference_output" +test_dir = SCRIPT_DIR / "test_output" # Initialize values test_passed = True # Flag for each individual test case @@ -61,13 +66,28 @@ def ref_round(ref_val, test_val): def run_tests(test_names): - run_dir = "~/git/cea/build-dev/source" + run_dir = Path(os.environ.get("CEA_RUN_DIR", "~/git/cea/build-dev/source")).expanduser() + default_exe = run_dir / "cea" + cea_exe = os.environ.get("CEA_EXE") + if cea_exe is None: + if default_exe.exists(): + cea_exe = str(default_exe) + else: + cea_exe = shutil.which("cea") + if cea_exe is None: + raise FileNotFoundError("Could not locate `cea` executable. Set CEA_EXE or CEA_RUN_DIR, or add `cea` to PATH.") + + test_dir.mkdir(parents=True, exist_ok=True) for test in test_names: # Execute the code on the input file print(f"Running {test}") - os.system(run_dir+"/cea"+f" {test}") - os.system(f"mv {test}.out {test_dir}") + input_base = SCRIPT_DIR / test + subprocess.run([cea_exe, str(input_base)], cwd=REPO_ROOT, check=True) + out_file = input_base.with_suffix(".out") + if not out_file.exists(): + raise FileNotFoundError(f"Expected output file not found: {out_file}") + shutil.move(str(out_file), str(test_dir / out_file.name)) print() return @@ -91,10 +111,10 @@ def run_tests(test_names): test_passed = True # Get the validation output - thermo_ref, amounts_ref, transport_ref, rocket_ref, shock_ref, deton_ref = parse_output(reference_dir+f"{test}.out") + thermo_ref, amounts_ref, transport_ref, rocket_ref, shock_ref, deton_ref = parse_output(str(reference_dir / f"{test}.out")) # Get the test output - thermo, amounts, transport, rocket, shock, deton = parse_output(test_dir+f"{test}.out") + thermo, amounts, transport, rocket, shock, deton = parse_output(str(test_dir / f"{test}.out")) # Compare thermo output # --------------------- @@ -333,4 +353,4 @@ def run_tests(test_names): "abs_error": abs_error, "rel_error": rel_error }) -df.to_csv("test_results.csv", index=False) \ No newline at end of file +df.to_csv("test_results.csv", index=False) diff --git a/test/main_interface/test_output/example1.inp b/test/main_interface/test_output/example1.inp deleted file mode 100644 index 1e33d3c..0000000 --- a/test/main_interface/test_output/example1.inp +++ /dev/null @@ -1,25 +0,0 @@ -# EXAMPLE 1: -# (a) Assigned-temperature-and-pressure problem (tp). -# (b) Reactants are H2 and Air. Since "exploded" formulas are not given, -# these formulas will be taken from the thermodynamic data library, -# thermo.lib. -# (c) Calculations are for two equivalence ratios (r,eq.ratio =1,1.5). -# (d) Assigned pressures are 1, 0.1, and 0.01 atm (p(atm)=1,.1,.01). -# (e) Assigned temperatures are 3000 and 2000 K (t(k)=3000,2000). -# (f) 'only' dataset is used to restrict possible products. -# (g) Energy units in the final tables are in calories (calories). - -# 'problem' dataset: - problem case=Example-1 tp p(atm)=1,.1,.01,t(k)=3000,2000, - r,eq.ratio=1,1.5 -# 'reactants' dataset: - reac - fuel= H2 moles = 1. - oxid= Air moles = 1. -# 'only' dataset: - only Ar C CO CO2 H H2 H2O HNO HO2 HNO2 HNO3 N NH - NO N2 N2O3 O O2 OH O3 -# 'output' dataset: - output calories -# 'end' dataset - end \ No newline at end of file diff --git a/test/main_interface/test_output/example1.out b/test/main_interface/test_output/example1.out deleted file mode 100644 index 7818ed1..0000000 --- a/test/main_interface/test_output/example1.out +++ /dev/null @@ -1,93 +0,0 @@ - - REACTANT MOLES ENERGY TEMP - KJ/MOL K - H2 -1.000 -1.000 -1.00 - Air -1.000 -1.000 -1.00 -O/F = 34.29623 % Fuel = 2.83316 r, Eq. Ratio = 1.00000 phi, Eq. Ratio = 1.00000 - - THERMODYNAMIC PROPERTIES - - P, atm 1.00000 1.00000 0.10000 0.10000 0.01000 0.01000 - T, K 3000.00 2000.00 3000.00 2000.00 3000.00 2000.00 - Density, g/cc 0.9178E-4 0.1499E-3 0.8085E-5 0.1496E-4 0.6614E-6 0.1487E-5 - H, cal/g 663.714 -203.569 1369.546 -191.833 2647.099 -164.346 - U, cal/g 399.856 -365.131 1070.016 -353.764 2280.923 -327.156 - G, cal/g -7974.528 -5290.413 -8616.699 -5662.789 -9380.961 -6036.509 - S, cal/g-K 2.8794 2.5434 3.3287 2.7355 4.0094 2.9361 - - M, (1/n) 22.59411 24.60005 19.90339 24.54403 16.28084 24.41160 - (dln(V)/dln(P))t -1.03442 -1.00064 -1.07867 -1.00146 -1.07479 -1.00358 - (dln(V)/dln(T))p 1.69574 1.02048 2.53331 1.04625 2.41333 1.11105 - Cp, cal/g-K 1.68164 0.45516 3.43981 0.52149 3.71682 0.68577 - Gamma_s 1.13119 1.22576 1.12058 1.20263 1.13182 1.16680 - Son. Vel., m/s 1117.505 910.267 1185.051 902.663 1316.829 891.524 - -MOLE FRACTIONS - - Ar 0.007098 0.007728 0.006253 0.007711 0.005115 0.007669 - CO 1.707E-4 1.037E-5 1.842E-4 2.096E-5 1.678E-4 4.081E-5 - CO2 7.108E-5 2.529E-4 2.882E-5 2.417E-4 6.469E-6 2.204E-4 - H 0.040752 8.952E-5 0.142895 4.089E-4 0.318941 0.001859 - H2 0.067277 0.003061 0.082718 0.006384 0.041209 0.013191 - H2O 0.207296 0.342065 0.095791 0.337141 0.011761 0.326373 - HO2 1.026E-5 1.007E-7 5.080E-6 1.027E-7 6.887E-7 1.024E-7 - N 1.058E-5 7.19E-10 3.135E-5 2.270E-9 8.974E-5 7.158E-9 - NO 0.012303 4.834E-4 0.013705 7.215E-4 0.009668 0.001066 - N2 0.585676 0.644136 0.514484 0.642550 0.421584 0.638909 - O 0.015397 2.125E-5 0.057868 1.004E-4 0.142614 4.705E-4 - O2 0.018761 0.001023 0.026501 0.002285 0.016095 0.005016 - OH 0.045174 0.001128 0.059534 0.002435 0.032747 0.005186 - -PRODUCTS WHICH WERE CONSIDERED BUT WHOSE MOLE FRACTIONS -WERE LESS THAN 5.000000E-06 FOR ALL ASSIGNED CONDITIONS - - C HNO HNO2 HNO3 NH - N2O3 O3 - - - - REACTANT MOLES ENERGY TEMP - KJ/MOL K - H2 -1.000 -1.000 -1.00 - Air -1.000 -1.000 -1.00 -O/F = 22.85255 % Fuel = 4.19242 r, Eq. Ratio = 1.50000 phi, Eq. Ratio = 1.50076 - - THERMODYNAMIC PROPERTIES - - P, atm 1.00000 1.00000 0.10000 0.10000 0.01000 0.01000 - T, K 3000.00 2000.00 3000.00 2000.00 3000.00 2000.00 - Density, g/cc 0.8122E-4 0.1297E-3 0.7116E-5 0.1296E-4 0.5672E-6 0.1293E-5 - H, cal/g 718.654 -120.698 1550.122 -116.204 3208.235 -101.779 - U, cal/g 420.475 -307.350 1209.797 -303.012 2781.243 -289.088 - G, cal/g -8818.842 -5830.648 -9545.377 -6260.575 -10424.488 -6691.184 - S, cal/g-K 3.1792 2.8550 3.6985 3.0722 4.5442 3.2947 - - M, (1/n) 19.99355 21.29328 17.51750 21.27547 13.96195 21.21856 - (dln(V)/dln(P))t -1.03310 -1.00019 -1.08571 -1.00061 -1.08710 -1.00198 - (dln(V)/dln(T))p 1.66528 1.00555 2.66772 1.01765 2.64212 1.05696 - Cp, cal/g-K 1.82531 0.46707 4.19285 0.50003 4.92303 0.60765 - Gamma_s 1.13367 1.25288 1.11963 1.23890 1.12959 1.20512 - Son. Vel., m/s 1189.262 989.161 1262.640 984.040 1420.583 971.831 - -MOLE FRACTIONS - - Ar 0.006193 0.006596 0.005426 0.006590 0.004325 0.006573 - CO 1.752E-4 1.563E-4 1.663E-4 1.561E-4 1.428E-4 1.554E-4 - CO2 3.577E-5 6.834E-5 1.856E-5 6.838E-5 4.515E-6 6.850E-5 - H 0.060250 6.212E-4 0.182358 0.001960 0.393121 0.006160 - H2 0.147056 0.147374 0.134716 0.146760 0.062606 0.144895 - H2O 0.222242 0.295081 0.111310 0.294504 0.014651 0.292605 - N 9.904E-6 6.64E-10 2.925E-5 2.099E-9 8.257E-5 6.629E-9 - NO 0.005651 8.003E-6 0.009123 2.535E-5 0.007294 8.057E-5 - N2 0.513557 0.549954 0.447860 0.549485 0.356917 0.547987 - O 0.007552 3.808E-7 0.041288 3.816E-6 0.116937 3.840E-5 - O2 0.004513 3.285E-7 0.013491 3.299E-6 0.010821 3.341E-5 - OH 0.032758 1.403E-4 0.054207 4.437E-4 0.033096 0.001403 - -PRODUCTS WHICH WERE CONSIDERED BUT WHOSE MOLE FRACTIONS -WERE LESS THAN 5.000000E-06 FOR ALL ASSIGNED CONDITIONS - - C HNO HO2 HNO2 HNO3 - NH N2O3 O3 - - diff --git a/test/main_interface/test_output/example2.out b/test/main_interface/test_output/example2.out deleted file mode 100644 index 3a0aacb..0000000 --- a/test/main_interface/test_output/example2.out +++ /dev/null @@ -1,63 +0,0 @@ - - REACTANT MOLES ENERGY TEMP - KJ/MOL K - H2 -1.000 -1.000 -1.00 - Air -1.000 -1.000 -1.00 -O/F = 34.29623 % Fuel = 2.83316 r, Eq. Ratio = 1.00000 phi, Eq. Ratio = 1.00000 - - THERMODYNAMIC PROPERTIES - - P, atm 1.00087 0.10003 0.00999 - T, K 3000.00 3000.00 3000.00 - Density, g/cc 0.9186E-4 0.8088E-5 0.6605E-6 - H, cal/g 663.554 1369.409 2647.694 - U, cal/g 399.704 1069.887 2281.487 - G, cal/g -7974.298 -8616.610 -9381.382 - S, cal/g-K 2.8793 3.3287 4.0097 - - M, (1/n) 22.59479 19.90386 16.27945 - (dln(V)/dln(P))t -1.03441 -1.07867 -1.07476 - (dln(V)/dln(T))p 1.69550 2.53320 2.41268 - Cp, cal/g-K 1.68119 3.43954 3.71555 - Gamma_s 1.13120 1.12058 1.13184 - Son. Vel., m/s 1117.492 1185.037 1316.895 - - TRANSPORT PROPERTIES (GASES ONLY) - CONDUCTIVITY IN UNITS OF MILLICALORIES/(CM)(K)(SEC) - - Visc, Millipoise 0.9358 0.9401 0.9482 - - WITH EQUILIBRIUM REACTIONS - Cp, cal/g-K 1.6812 3.4395 3.7156 - Conductivity 4.4411 9.6448 8.8614 - Prandtl Number 0.3593 0.3377 0.4009 - - WITH FROZEN REACTIONS - Cp, cal/g-K 0.4250 0.4282 0.4368 - Conductivity 0.6290 0.7265 0.8641 - Prandtl Number 0.6322 0.5541 0.4793 - - -MOLE FRACTIONS - - Ar 0.007098 0.006253 0.005114 - CO 1.707E-4 1.842E-4 1.677E-4 - CO2 7.109E-5 2.882E-5 6.463E-6 - H 0.040731 0.142874 0.319015 - H2 0.067266 0.082719 0.041181 - H2O 0.207331 0.095807 0.011743 - HO2 1.026E-5 5.081E-6 6.877E-7 - N 1.057E-5 3.134E-5 8.978E-5 - NO 0.012302 0.013705 0.009665 - N2 0.585694 0.514496 0.421549 - O 0.015389 0.057860 0.142655 - O2 0.018757 0.026501 0.016086 - OH 0.045166 0.059534 0.032727 - -PRODUCTS WHICH WERE CONSIDERED BUT WHOSE MOLE FRACTIONS -WERE LESS THAN 5.000000E-06 FOR ALL ASSIGNED CONDITIONS - - C HNO HNO2 HNO3 NH - N2O3 O3 - - diff --git a/test/main_interface/test_output/example3.out b/test/main_interface/test_output/example3.out deleted file mode 100644 index 9a0c3fb..0000000 --- a/test/main_interface/test_output/example3.out +++ /dev/null @@ -1,84 +0,0 @@ - - REACTANT MOLES ENERGY TEMP - KJ/MOL K - Air -1.000 -1.000 -1.00 - C7H8(L) -1.000 -1.000 -1.00 - C8H18(L),n-octa -1.000 -1.000 -1.00 -O/F = 17.00000 % Fuel = 5.55556 r, Eq. Ratio = 0.85207 phi, Eq. Ratio = 0.85185 - - THERMODYNAMIC PROPERTIES - - P, bar 100.00000 10.00000 1.00000 - T, K 2418.66 2390.59 2338.84 - Density, kg/m^3 0.1443E+2 0.1457E+1 0.1483E+0 - H, kJ/kg 317.838 317.838 317.838 - U, kJ/kg -375.112 -368.523 -356.299 - G, kJ/kg -19437.998 -20787.277 -21879.341 - S, kJ/kg-K 8.1681 8.8284 9.4907 - - M, (1/n) 29.02082 28.95944 28.84624 - (dln(V)/dln(P))t -1.00068 -1.00159 -1.00324 - (dln(V)/dln(T))p 1.01893 1.04474 1.09205 - Cp, kJ/kg-K 1.60941 1.81668 2.20662 - Gamma_s 1.22570 1.20614 1.17999 - Son. Vel., m/s 921.601 909.860 891.894 - -MOLE FRACTIONS - - Ar 0.008862 0.008843 0.008808 - CN 5.85E-14 1.07E-13 1.18E-13 - CO 0.001677 0.004312 0.009186 - CO2 0.115369 0.112487 0.107156 - COOH 5.157E-8 2.327E-8 8.613E-9 - H 2.755E-5 1.238E-4 4.551E-4 - H2 2.506E-4 6.610E-4 0.001484 - H2O 0.102770 0.101361 0.099015 - H2O2 9.879E-7 2.948E-7 8.367E-8 - HCHO,formaldehy 1.71E-11 1.16E-11 5.55E-12 - HCN 1.06E-11 1.18E-11 8.63E-12 - HCO 7.38E-10 8.92E-10 7.60E-10 - HCOOH 6.460E-9 1.641E-9 3.43E-10 - HNC 1.02E-12 1.09E-12 7.48E-13 - HNCO 1.232E-9 5.14E-10 1.64E-10 - HNO 4.220E-7 2.079E-7 9.099E-8 - HNO2 1.850E-6 3.265E-7 5.731E-8 - HNO3 1.130E-9 6.62E-11 4.04E-12 - HO2 7.991E-6 4.257E-6 2.161E-6 - N 1.149E-8 2.742E-8 5.067E-8 - N2 0.735474 0.734034 0.731359 - N2H2 5.17E-13 1.20E-13 2.10E-14 - N2O 3.645E-6 1.113E-6 3.296E-7 - N2O3 2.44E-11 7.71E-13 2.43E-14 - N2O4 3.10E-15 3.28E-17 3.66E-19 - N3 1.23E-12 3.00E-13 5.75E-14 - N3H 3.85E-13 5.23E-14 5.58E-15 - NCO 8.31E-11 5.82E-11 2.95E-11 - NH 2.934E-9 3.864E-9 3.882E-9 - NH2 1.709E-9 1.278E-9 7.37E-10 - NH2NO2 2.44E-15 6.73E-17 1.65E-18 - NH2OH 1.02E-11 1.45E-12 1.68E-13 - NH3 3.891E-9 1.718E-9 6.13E-10 - NO 0.006776 0.006553 0.006145 - NO2 2.347E-5 7.564E-6 2.479E-6 - NO3 1.92E-10 1.95E-11 2.00E-12 - O 1.551E-4 4.311E-4 0.001066 - O2 0.026252 0.027365 0.029599 - O3 1.210E-8 3.720E-9 1.115E-9 - OH 0.002348 0.003816 0.005721 - -PRODUCTS WHICH WERE CONSIDERED BUT WHOSE MOLE FRACTIONS -WERE LESS THAN 1.000000E-15 FOR ALL ASSIGNED CONDITIONS - - (HCOOH)2 C C10H8,naphthale C2 C2H - C2H2,acetylene C2H2,vinylidene C2H3,vinyl C2H4 C2H4O,ethylen-o - C2H5 C2H5OH C2H6 C3H3,1-propynl C3H3,2-propynl - C3H6O,acetone C3H6O,propanal C3H6O,propylox C4H2,butadiyne C4H6,1butyne - C4H6,2butyne C6H14,n-hexane C7H16,2-methylh CH CH2 - CH2CO,ketene CH2OH CH3 CH3CHO,ethanal CH3CN - CH3CO,acetyl CH3COOH CH3N2CH3 CH3O CH3O2CH3 - CH3OCH3 CH3OH CH3OOH CH4 CNCOCN - CNN HCCN HCCO HO(CO)2OH N2H4 - N2O5 NCN O(CH)2O OCCN OHCH2COOH - C(gr) H2O(cr) - - diff --git a/test/main_interface/test_output/get_output.py b/test/main_interface/test_output/get_output.py index 9e46d91..2dc4264 100644 --- a/test/main_interface/test_output/get_output.py +++ b/test/main_interface/test_output/get_output.py @@ -1,13 +1,28 @@ import os +import shutil +import subprocess +from pathlib import Path def run_tests(test_names): - run_dir = "~/git/cea/build-dev/source" + script_dir = Path(__file__).resolve().parent.parent + repo_root = script_dir.parent.parent + run_dir = Path(os.environ.get("CEA_RUN_DIR", "~/git/cea/build-dev/source")).expanduser() + default_exe = run_dir / "cea" + cea_exe = os.environ.get("CEA_EXE") + if cea_exe is None: + if default_exe.exists(): + cea_exe = str(default_exe) + else: + cea_exe = shutil.which("cea") + if cea_exe is None: + raise FileNotFoundError("Could not locate `cea` executable. Set CEA_EXE or CEA_RUN_DIR, or add `cea` to PATH.") for test in test_names: # Execute the code on the input file print(f"Running {test}") - os.system(run_dir+"/cea"+f" {test}") + input_base = script_dir / test + subprocess.run([cea_exe, str(input_base)], cwd=repo_root, check=True) print() return @@ -19,4 +34,4 @@ def run_tests(test_names): # "example10","example11", "example12", # "example13", "example14"] test_names = ["example1"] - run_tests(test_names) \ No newline at end of file + run_tests(test_names) diff --git a/test/main_interface/test_output/thermo.lib b/test/main_interface/test_output/thermo.lib deleted file mode 100644 index 646e549..0000000 Binary files a/test/main_interface/test_output/thermo.lib and /dev/null differ diff --git a/test/main_interface/test_output/trans.lib b/test/main_interface/test_output/trans.lib deleted file mode 100644 index acc61ef..0000000 Binary files a/test/main_interface/test_output/trans.lib and /dev/null differ diff --git a/test/main_interface/thermo.lib b/test/main_interface/thermo.lib deleted file mode 100644 index 646e549..0000000 Binary files a/test/main_interface/thermo.lib and /dev/null differ diff --git a/test/main_interface/trans.lib b/test/main_interface/trans.lib deleted file mode 100644 index acc61ef..0000000 Binary files a/test/main_interface/trans.lib and /dev/null differ