Skip to content

feat: Add TUV-x hook - #173

Open
bbakernoaa wants to merge 121 commits into
ufs-community:developfrom
bbakernoaa:feature/tuv-x
Open

feat: Add TUV-x hook#173
bbakernoaa wants to merge 121 commits into
ufs-community:developfrom
bbakernoaa:feature/tuv-x

Conversation

@bbakernoaa

Copy link
Copy Markdown
Collaborator

CATChem Pull Request & Change Report: MUSICA TUV-x Photolysis Integration (feature/tuv-x)

1. Executive Summary

This branch (feature/tuv-x) implements the end-to-end integration of the MUSICA TUV-x photolysis solver library into the CATChem core atmospheric chemistry engine, alongside establishing comprehensive developer guidelines and operational readiness standards.

By developing the native C++ physical process class catchem::PhotolysisProcess (extending catchem::ProcessInterface), CATChem can now:

  1. Parse TUV-x configurations from the main model YAML.
  2. Construct and manage dynamic meteorological, height, and wavelength grids on the host CPU.
  3. Compute time-dependent, column-wise Solar Zenith Angles (SZA).
  4. Execute the TUV-x solver on column profiles of temperature, air density, oxygen ($O_2$), and ozone ($O_3$).
  5. Interpolate edge-level photolysis rates ($J$-values) to layer midpoints and populate them into dynamically registered diagnostics.

Additionally, this branch introduces robust developer documentation and Copilot instructions to align development with UFS Community standards.


2. Commit-by-Commit History Analysis

The branch was branched off feature/rework and consists of 11 sequential commits:

Commit Hash Author Scope / Title Primary Changes & Contribution
7aee1438 bbakernoaa feat(docs): add comprehensive guidelines... Added extensive developer guidelines under .github/instructions/ for Bash, C++, Fortran, Python, and HPC libraries; established operational readiness standards.
67495c7b bbakernoaa feat(core): propagate config path to state... Extended catchem::StateManager and catchem::Core to accept and store the YAML configuration file path for use during process initialization.
d1add471 bbakernoaa feat(photolysis): add photolysis process class... Created the catchem::PhotolysisProcess class structure extending catchem::ProcessInterface, along with an extern "C" registration hook.
2f45cfaa bbakernoaa feat(photolysis): implement config parsing... Implemented YAML-cpp parsing of the main configuration to extract photolysis options, managed GridMap/Profile/Radiator creation, and registered diagnostics dynamically.
76a85f33 bbakernoaa feat(photolysis): implement column-wise SZA... Added SZA computations per column, mapped box height to km-based grid edges, populated dummy midpoints, and executed column-wise TUV-x solver steps.
5f9d1a22 bbakernoaa build(cmake): integrate photolysis process... Integrated photolysis source and headers into CMake compilation targets and linked yaml-cpp and MUSICA tuv-x libraries.
d8564407 bbakernoaa test(photolysis): add integration tests... Wrote a complete C++ integration test harness (test_catchem_photolysis.cpp) to mock meteorological profiles and verify computed $J$-rates.
ccaa3559 bbakernoaa feat(photolysis): finalize native C-API... Refactored Grid/Profile lifecycle to prevent leaks and introduced safe dynamic registration of temperature, air, $O_2$, and $O_3$ profiles only if missing from config.
f6ffd969 bbakernoaa chore: update descriptions in guidelines... Aligned the .github/instructions/ documentation with formal UFS Community standards.
99ff7c87 bbakernoaa fix: codespell and pre-commit Resolved spelling issues via .codespellrc and ran pre-commit formatting hooks across the repository.
1c5a4787 bbakernoaa add copilot instructions Added .github/copilot-instructions.md to guide AI-assisted development context.

3. Core Architectural Highlights

A. Dynamic Configuration Propagation

  • What: The main model configuration file path is passed from Core to StateManager:
    state_mgr->config_file_path = config_file;
  • Why: This allows any physical process class to dynamically locate and parse its respective sub-configurations during the init phase without needing hardcoded paths.

B. Safe Grid & Profile Lifecycle Management

  • What: Dynamic initialization creates local Grid objects (e.g., height and wavelength), populates edges/midpoints, adds them to GridMap, and then safely deletes the local pointers:
    musica::AddGrid(grids, height_grid, &err);
    musica::DeleteGrid(height_grid, &err); // Prevent memory leaks
  • Why: Once added, the GridMap clones or assumes ownership of the grid memory.

C. Host-Configuration Reconciliation

  • What: The process checks the parsed TUV-x configuration file for pre-defined profiles. If key profiles (like temperature, air, O2, O3) are not defined in the configuration, the solver pre-registers them dynamically on the fly:
    if (config_defined_profiles.find(name) == config_defined_profiles.end()) {
        musica::Profile* new_prof = musica::CreateProfile(name, units, grid, &err);
        musica::SetProfileMidpointValues(new_prof, dummy.data(), num_vals, &err);
        musica::AddProfile(profiles, new_prof, &err);
    }
  • Why: This ensures maximum robustness against partial configuration files, avoiding segmentation faults inside the Fortran/C++ core.

D. Multi-column SZA & Edge-to-Midpoint Interpolation

  • What:
    • Iterates column-by-column, converting LAT/LON and simulation time into a Solar Zenith Angle (SZA) via state->time.get_cos_sza(...).
    • Maps physical layer thickness (BXHEIGHT in meters) into km-based grid edges.
    • Solves the column-wise radiative transfer equation.
    • Interpolates resulting edge-level photolysis rates to layer midpoints and pushes them back into the DiagManager:
    double rate_midpoint = 0.5 * (edge_photolysis_rates[idx_edge1] + edge_photolysis_rates[idx_edge2]);

4. Verification and Testing

A dedicated integration test test_catchem_photolysis was implemented to verify correctness:

  1. Dynamic Registration: Verifies that photolysis is registered in the C++ registry.
  2. Mock Simulation Setup: configures a single column with 3 vertical layers, set at noon during summer (2026-07-13 12:00:00) to guarantee solar radiation.
  3. Mock Meteorology: Populates pedagogical profiles for LAT ($40.0^\circ$), LON ($-105.0^\circ$), T ($280.0\text{ K}$), and AIRDEN ($1.2\text{ kg/m}^3$).
  4. Execution: Spins up run_timestep(3600.0).
  5. Rate Verification: Asserts that computed $J$-rates are:
    • Dynamically registered under diagnostic fields (photolysis_rate_jfoo).
    • Finite and non-negative.
    • Non-zero for positive solar elevation angles.

The integration test successfully compiles and passes under the workspace CTest suite:


5. Metadata and Classification

Type of Change

  • New feature (adds photolysis solver functionality and dynamic profiles)
  • Maintenance (developer instructions, Copilot configurations, pre-commit fixes)

Change Characteristics

  • Is this a breaking change? No. All existing physical adapters (dust, carbchem, wetdep, settling) remain fully preserved.
  • Does this change require a documentation update? Yes, and comprehensive documentation has been completed in this branch.

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • New and existing tests pass with my changes
  • I have made corresponding changes to the documentation if necessary

bbakernoaa and others added 30 commits April 13, 2026 10:39
- Add Intel oneAPI Linux build and test workflow (.github/workflows/intel_oneapi.yml)
- Add Intel Linux build and test workflow (.github/workflows/ubuntu_intel.yml)
- Add NUOPC interface presentation documentation
- Refactor ProcessFactory_Mod.F90 and ProcessRegistry_Mod.F90 for improved module organization
- Update UnitConversion_Mod.F90 with enhanced conversion utilities
- Update met_utilities_mod.F90 and utilities_mod.F90 for consistency
- Update SettlingScheme_GOCART_Mod.F90 settling process implementation
- Update CMakeLists.txt build configuration
- Update catchem.F90 API module
- Remove init_mod.F90 (functionality consolidated into other modules)
- Enables CI/CD testing with Intel compilers alongside existing GCC workflows
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
- Add comprehensive error handling and context tracking to create_process function
- Implement automatic met field allocation for created processes
- Add case-insensitive unit handling for pressure conversions (Pa, hPa, Torr, mmHg)
- Add case-insensitive unit handling for temperature conversions (K, C, F)
- Expand documentation with detailed parameter descriptions and accepted unit variants
- Update utility function docs to reflect all supported unit options
- Improve error reporting with specific guidance for unknown processes
- Delete intel_oneapi.yml workflow file
- Delete ubuntu_intel.yml workflow file
- Remove newline at end of ci.yml file
- Consolidate Intel compiler testing into main CI pipeline
- Add missing newline character at end of .github/workflows/ci.yml
- Ensures proper file formatting and consistency with Unix conventions
- Add settling_scheme=2 parameter to Chem_SettlingSimple call for GOCART scheme
- Add settling_scheme=2 parameter to Chem_Settling call for GOCART scheme
- Include inline comments documenting hardcoded settling_scheme=2 for GOCART scheme
- Ensures consistent settling scheme specification across both settling calculation paths
- Add Kokkos GPU/parallel computing framework with CMake configuration and C++17 support
- Create new kokkos interop layer with dispatch modules for drydep, seasalt, settling, and wetdep processes
- Implement KokkosDispatch_Mod.F90 for Fortran-C++ interoperability and kernel dispatching
- Add settling physics module (SettlingPhysics_Mod.F90) with Kokkos-optimized computations
- Refactor ColumnInterface_Mod into VirtualColumn_Mod for improved architecture
- Remove deprecated ColumnInterface_Mod and consolidate column processing logic
- Add comprehensive test suite for Kokkos CPU/GPU dispatch and numerical equivalence validation
- Update CMakeLists.txt with ENABLE_KOKKOS option and conditional C++ standard configuration
- Add Kokkos 4.3.0 to Spack environment configuration with serial and OpenMP backends
- Update documentation with revised roadmap timelines and field compatibility tables
- Add .kiro/ to .gitignore for IDE artifacts
- Update process interface templates and build system for Kokkos integration
…egration

- Remove CATChemAPI_Mod.F90 high-level API module (replaced by StateContainer architecture)
- Remove catchem.F90 wrapper module (consolidated into core modules)
- Update kokkos_common.hpp with improved GPU/parallel computing support
- Simplify API surface by eliminating redundant abstraction layers
- Align codebase with modern StateContainer-based architecture
Co-authored-by: Zachary Moon <zachary.moon@noaa.gov>
…build configuration

- Move SettlingPhysics_Mod.F90 from root to schemes/ subdirectory for better organization
- Remove unused Process.H header file with macro definitions
- Update CMakeLists.txt to reflect new SettlingPhysics_Mod.F90 location in schemes group
- Reorder function parameters in VirtualColumn_Mod.F90 for consistency (rc moved after optional parameters)
- Add conditional Kokkos linking support to process generator CMakeLists template
- Improves code organization by grouping scheme-specific modules together
- Split set() command across multiple lines for better formatting
- Improve code organization and consistency with CMake style guidelines
- Enhance maintainability of settling scheme sources configuration
- Add solar_zenith_angle subroutine to met_utilities_mod for computing SZA and cosine values
- Implement GOCART2G-compatible solar declination algorithm with Fourier coefficients
- Add optional column_id parameter to VirtualColumn initialization for per-column state tracking
- Update ProcessManager to pass column_id when creating virtual columns from batch processing
- Make column_id optional in StateManager's create_virtual_column subroutine
- Add SO4chemPhysics_Mod.F90 module for SO4 chemistry physics calculations
- Update SO4chem CMakeLists.txt to include new physics module in build
- Simplify ProcessSO4chemInterface to use ProcessInterface instead of ColumnProcessInterface
- Add test_SO4chemPhysics.F90 for physics module unit tests
- Update test fixtures in test_GridManager and test_VirtualColumn for new signatures
- Align continuation lines in multi-line expressions to improve readability
- Standardize indentation in SO4chemPhysics_Mod.F90 for arithmetic operations
- Standardize indentation in test_SO4chemPhysics.F90 for consistency with main module
- Improve visual alignment of operator precedence and expression structure
…C interface

fix(settling): guard against non-positive layer pressure thickness to prevent NaN/Inf
…on, and HPC libraries; establish operational readiness standards
@bbakernoaa
bbakernoaa changed the base branch from main to develop July 22, 2026 15:51
@bbakernoaa

Copy link
Copy Markdown
Collaborator Author

This should not go in until after #136

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants