TUV-x C++ is a modern C++20 translation of the TUV-x (Tropospheric Ultraviolet-Visible) radiative transfer model. This is part of the MUSICA ecosystem and follows MICM's coding patterns.
Reference project: /Users/fillmore/EarthSystem/MICM - consult this for coding style questions.
At the start of each session, read these files for full context:
ARCHITECTURE.md- Component diagram and design philosophyTODO.md- Prioritized next steps and known issuesNUMERICAL-TESTS.md- Validation test specifications
# Configure (from project root)
mkdir build && cd build
cmake .. -DTUVX_ENABLE_TESTS=ON
# Build
make -j4
# Run tests
ctest --output-on-failure
# Build with options
cmake .. -DTUVX_ENABLE_OPENMP=ON -DTUVX_ENABLE_CLANG_TIDY=ON- Functions/Methods:
CamelCase(e.g.,CalculateOpticalDepth) - Classes:
CamelCase(e.g.,WavelengthGrid) - Member variables:
snake_case_with trailing underscore (e.g.,grid_points_) - Constants:
kCamelCaseprefix (e.g.,kBoltzmannConstant) - Macros:
TUVX_UPPER_CASE(e.g.,TUVX_INTERNAL_ERROR) - Namespaces: lowercase (e.g.,
tuvx::constants)
- Headers in
include/tuvx/ - Implementation (if needed) in
src/ - Tests in
test/unit/mirroring include structure - One class per header file typically
#pragma once
#include <system_headers>
#include <tuvx/project_headers.hpp>
namespace tuvx
{
// Allman brace style
class Example
{
public:
void DoSomething();
private:
int value_;
};
} // namespace tuvx- Use
TUVX_INTERNAL_ERROR("message")for unexpected internal states - Error codes defined in
include/tuvx/util/error.hpp - Exceptions inherit from
std::runtime_error - Include file/line info in error messages
- Use
///for Doxygen-style documentation - Document
@brief,@param,@returnfor public APIs - Keep comments concise; code should be self-documenting
#include <tuvx/component.hpp>
#include <gtest/gtest.h>
TEST(ComponentTest, DescriptiveName)
{
// Arrange
auto component = CreateComponent();
// Act
auto result = component.Calculate();
// Assert
EXPECT_NEAR(result, expected, tolerance);
}- Create test file in
test/unit/<category>/test_<name>.cpp - Add to
test/unit/CMakeLists.txt:create_tuvx_test(test_name category/test_name.cpp)
Use constants from tuvx::constants namespace - never hardcode physical values.
Use tuvx::array:: functions for common operations:
Linspace,Logspacefor grid generationMergeSortedfor combining wavelength gridsAlmostEqualfor floating-point comparisonFindStringfor case-insensitive string lookup
This is a header-only library. Implementation goes in headers:
// In header file
inline double Calculate(double x)
{
return x * 2.0;
}- Create header in
include/tuvx/util/ - Add include to
include/tuvx/tuvx.hpp - Create test in
test/unit/util/ - Update
test/unit/CMakeLists.txt
- Create header in
include/tuvx/<component>/ - Create tests in
test/unit/<component>/ - Update ARCHITECTURE.md with component description
Run clang-format before committing:
find include src test -name "*.hpp" -o -name "*.cpp" | xargs clang-format -i- C++20 features used:
<concepts>,<ranges>,std::optional, designated initializers - Google Test for testing
- Optional: OpenMP, MPI
- MICM:
/Users/fillmore/EarthSystem/MICM- Reference for coding patterns - TUV-x Fortran:
/Users/fillmore/EarthSystem/TUV-x- Original implementation to translate
Completed:
- Foundation (utilities, error handling, constants)
- Data structures (grids, profiles, interpolation)
- Cross-sections and quantum yields
- Radiators and radiation field
- Solar position, surface albedo, spherical geometry
- Delta-Eddington solver, photolysis rate calculator
- Model orchestration (TuvModel, ModelConfig, ModelOutput)
In Progress:
- Numerical validation (see NUMERICAL-TESTS.md)
Planned:
- Additional cross-section/quantum yield types
- C/Fortran interfaces, MUSICA API integration
Current test count: 539 tests passing
- Main model:
include/tuvx/model/tuv_model.hpp- TuvModel orchestration class - Configuration:
include/tuvx/model/model_config.hpp- ModelConfig + StandardAtmosphere - Output:
include/tuvx/model/model_output.hpp- ModelOutput with J-value accessors - Solver:
include/tuvx/solver/delta_eddington.hpp- Two-stream RT solver - Photolysis:
include/tuvx/photolysis/photolysis_rate.hpp- J-value calculation - TODO:
TODO.md- Prioritized next steps - Architecture:
ARCHITECTURE.md- Full component diagram - Numerical tests:
NUMERICAL-TESTS.md- Validation test specifications
All major radiators are now integrated. Available radiators:
- O3 - Ozone absorption with temperature-dependent cross-sections
- O2 - Oxygen absorption (Schumann-Runge bands)
- Rayleigh - Molecular scattering (λ^-4 dependence, ω=1, g=0)
- Aerosol - Configurable aerosol (Ångström parameterization)
Usage:
tuvx::TuvModel model(config);
model.UseStandardAtmosphere();
model.AddStandardRadiators(); // O3 + O2 + Rayleigh
model.AddAerosolRadiator(); // Optional: add aerosolsWithout radiators, the model runs with an "empty atmosphere" for backward compatibility.