diff --git a/include/musica/tuvx/tuvx.hpp b/include/musica/tuvx/tuvx.hpp index c4fd9e18..7fe798b2 100644 --- a/include/musica/tuvx/tuvx.hpp +++ b/include/musica/tuvx/tuvx.hpp @@ -54,8 +54,12 @@ namespace musica /// @param photolysis_rate_constants Photolysis rate constant for each layer and reaction [s^-1] /// @param heating_rates Heating rates for each layer and reaction [K/s] /// @param error Error struct to indicate success or failure - void Run(const double solar_zenith_angle, const double earth_sun_distance, - double * const photolysis_rate_constants, double * const heating_rates, Error * const error); + void Run( + const double solar_zenith_angle, + const double earth_sun_distance, + double *const photolysis_rate_constants, + double *const heating_rates, + Error *const error); ~TUVX(); @@ -76,19 +80,37 @@ namespace musica GridMap *GetGridMap(TUVX *tuvx, Error *error); ProfileMap *GetProfileMap(TUVX *tuvx, Error *error); RadiatorMap *GetRadiatorMap(TUVX *tuvx, Error *error); - void RunTuvx(TUVX *tuvx, const double solar_zenith_angle, const double earth_sun_distance, - double * const photolysis_rate_constants, double * const heating_rates, Error * const error); + void RunTuvx( + TUVX *tuvx, + const double solar_zenith_angle, + const double earth_sun_distance, + double *const photolysis_rate_constants, + double *const heating_rates, + Error *const error); // for use by musica interanlly. If tuvx ever gets rewritten in C++, these functions will // go away but the C API will remain the same and downstream projects (like CAM-SIMA) will // not need to change - void *InternalCreateTuvx(const char *config_path, std::size_t config_path_length, void *grid_map, void *profile_map, void *radiator_map, int *number_of_layers, int *error_code); + void *InternalCreateTuvx( + const char *config_path, + std::size_t config_path_length, + void *grid_map, + void *profile_map, + void *radiator_map, + int *number_of_layers, + int *error_code); void InternalDeleteTuvx(void *tuvx, int *error_code); void *InternalGetGridMap(void *tuvx, int *error_code); void *InternalGetProfileMap(void *tuvx, int *error_code); void *InternalGetRadiatorMap(void *tuvx, int *error_code); - void InternalRunTuvx(void *tuvx, const int number_of_layers, const double solar_zenith_angle, const double earth_sun_distance, - double *photolysis_rate_constants, double *heating_rates, int *error_code); + void InternalRunTuvx( + void *tuvx, + const int number_of_layers, + const double solar_zenith_angle, + const double earth_sun_distance, + double *photolysis_rate_constants, + double *heating_rates, + int *error_code); #ifdef __cplusplus } diff --git a/src/test/unit/tuvx/tuvx_run_from_config.cpp b/src/test/unit/tuvx/tuvx_run_from_config.cpp index 807d0e76..b01f4405 100644 --- a/src/test/unit/tuvx/tuvx_run_from_config.cpp +++ b/src/test/unit/tuvx/tuvx_run_from_config.cpp @@ -4,7 +4,6 @@ using namespace musica; - // Expected values for photolysis rate constants and heating rates // were determined by running the stand-alone TUV-x model with the fixed configuration. const double expected_photolysis_rate_constants[2][4] = { @@ -20,117 +19,117 @@ const double expected_heating_rates[2][4] = { // using the TUVX C API with a fixed configuration file class TuvxRunTest : public ::testing::Test { - protected: - TUVX* tuvx; - GridMap* grids_from_host; - ProfileMap* profiles_from_host; - RadiatorMap* radiators_from_host; - GridMap* grids_in_tuvx; - ProfileMap* profiles_in_tuvx; - RadiatorMap* radiators_in_tuvx; - int number_of_layers; - int number_of_wavelengths; - int number_of_reactions; - double *photolysis_rate_constants; - double *heating_rates; - - // the function that google test actually calls before each test - void SetUp() override - { - tuvx = nullptr; - grids_from_host = nullptr; - profiles_from_host = nullptr; - radiators_from_host = nullptr; - grids_in_tuvx = nullptr; - profiles_in_tuvx = nullptr; - radiators_in_tuvx = nullptr; - number_of_layers = 0; - number_of_wavelengths = 0; - number_of_reactions = 0; - photolysis_rate_constants = nullptr; - heating_rates = nullptr; - } - - void SetUp(const char* config_path) + protected: + TUVX* tuvx; + GridMap* grids_from_host; + ProfileMap* profiles_from_host; + RadiatorMap* radiators_from_host; + GridMap* grids_in_tuvx; + ProfileMap* profiles_in_tuvx; + RadiatorMap* radiators_in_tuvx; + int number_of_layers; + int number_of_wavelengths; + int number_of_reactions; + double* photolysis_rate_constants; + double* heating_rates; + + // the function that google test actually calls before each test + void SetUp() override + { + tuvx = nullptr; + grids_from_host = nullptr; + profiles_from_host = nullptr; + radiators_from_host = nullptr; + grids_in_tuvx = nullptr; + profiles_in_tuvx = nullptr; + radiators_in_tuvx = nullptr; + number_of_layers = 0; + number_of_wavelengths = 0; + number_of_reactions = 0; + photolysis_rate_constants = nullptr; + heating_rates = nullptr; + } + + void SetUp(const char* config_path) + { + Error error; + grids_from_host = CreateGridMap(&error); + ASSERT_TRUE(IsSuccess(error)); + profiles_from_host = CreateProfileMap(&error); + ASSERT_TRUE(IsSuccess(error)); + radiators_from_host = CreateRadiatorMap(&error); + ASSERT_TRUE(IsSuccess(error)); + tuvx = CreateTuvx(config_path, grids_from_host, profiles_from_host, radiators_from_host, &error); + if (!IsSuccess(error)) { - Error error; - grids_from_host = CreateGridMap(&error); - ASSERT_TRUE(IsSuccess(error)); - profiles_from_host = CreateProfileMap(&error); - ASSERT_TRUE(IsSuccess(error)); - radiators_from_host = CreateRadiatorMap(&error); - ASSERT_TRUE(IsSuccess(error)); - tuvx = CreateTuvx(config_path, grids_from_host, profiles_from_host, radiators_from_host, &error); - if (!IsSuccess(error)) - { - std::cerr << "Error creating TUVX instance: " << error.message_.value_ << std::endl; - } - ASSERT_TRUE(IsSuccess(error)); - grids_in_tuvx = GetGridMap(tuvx, &error); - ASSERT_TRUE(IsSuccess(error)); - profiles_in_tuvx = GetProfileMap(tuvx, &error); - ASSERT_TRUE(IsSuccess(error)); - radiators_in_tuvx = GetRadiatorMap(tuvx, &error); - ASSERT_TRUE(IsSuccess(error)); - number_of_layers = 3; - number_of_wavelengths = 5; - number_of_reactions = 2; - photolysis_rate_constants = new double[(number_of_layers + 1) * number_of_reactions]; - heating_rates = new double[(number_of_layers + 1) * number_of_reactions]; - DeleteError(&error); + std::cerr << "Error creating TUVX instance: " << error.message_.value_ << std::endl; } + ASSERT_TRUE(IsSuccess(error)); + grids_in_tuvx = GetGridMap(tuvx, &error); + ASSERT_TRUE(IsSuccess(error)); + profiles_in_tuvx = GetProfileMap(tuvx, &error); + ASSERT_TRUE(IsSuccess(error)); + radiators_in_tuvx = GetRadiatorMap(tuvx, &error); + ASSERT_TRUE(IsSuccess(error)); + number_of_layers = 3; + number_of_wavelengths = 5; + number_of_reactions = 2; + photolysis_rate_constants = new double[(number_of_layers + 1) * number_of_reactions]; + heating_rates = new double[(number_of_layers + 1) * number_of_reactions]; + DeleteError(&error); + } - void SetUp(const char* config_path, GridMap* grids, ProfileMap* profiles, RadiatorMap* radiators) + void SetUp(const char* config_path, GridMap* grids, ProfileMap* profiles, RadiatorMap* radiators) + { + Error error; + grids_from_host = grids; + profiles_from_host = profiles; + radiators_from_host = radiators; + tuvx = CreateTuvx(config_path, grids, profiles, radiators, &error); + if (!IsSuccess(error)) { - Error error; - grids_from_host = grids; - profiles_from_host = profiles; - radiators_from_host = radiators; - tuvx = CreateTuvx(config_path, grids, profiles, radiators, &error); - if (!IsSuccess(error)) - { - std::cerr << "Error creating TUVX instance: " << error.message_.value_ << std::endl; - } - ASSERT_TRUE(IsSuccess(error)); - grids_in_tuvx = GetGridMap(tuvx, &error); - ASSERT_TRUE(IsSuccess(error)); - profiles_in_tuvx = GetProfileMap(tuvx, &error); - ASSERT_TRUE(IsSuccess(error)); - radiators_in_tuvx = GetRadiatorMap(tuvx, &error); - ASSERT_TRUE(IsSuccess(error)); - number_of_layers = 3; - number_of_wavelengths = 5; - number_of_reactions = 2; - photolysis_rate_constants = new double[(number_of_layers + 1) * number_of_reactions]; - heating_rates = new double[(number_of_layers + 1) * number_of_reactions]; - DeleteError(&error); + std::cerr << "Error creating TUVX instance: " << error.message_.value_ << std::endl; } - - void TearDown() override + ASSERT_TRUE(IsSuccess(error)); + grids_in_tuvx = GetGridMap(tuvx, &error); + ASSERT_TRUE(IsSuccess(error)); + profiles_in_tuvx = GetProfileMap(tuvx, &error); + ASSERT_TRUE(IsSuccess(error)); + radiators_in_tuvx = GetRadiatorMap(tuvx, &error); + ASSERT_TRUE(IsSuccess(error)); + number_of_layers = 3; + number_of_wavelengths = 5; + number_of_reactions = 2; + photolysis_rate_constants = new double[(number_of_layers + 1) * number_of_reactions]; + heating_rates = new double[(number_of_layers + 1) * number_of_reactions]; + DeleteError(&error); + } + + void TearDown() override + { + if (tuvx == nullptr) { - if (tuvx == nullptr) - { - return; - } - Error error; - DeleteTuvx(tuvx, &error); - ASSERT_TRUE(IsSuccess(error)); - DeleteGridMap(grids_from_host, &error); - ASSERT_TRUE(IsSuccess(error)); - DeleteProfileMap(profiles_from_host, &error); - ASSERT_TRUE(IsSuccess(error)); - DeleteRadiatorMap(radiators_from_host, &error); - ASSERT_TRUE(IsSuccess(error)); - DeleteGridMap(grids_in_tuvx, &error); - ASSERT_TRUE(IsSuccess(error)); - DeleteProfileMap(profiles_in_tuvx, &error); - ASSERT_TRUE(IsSuccess(error)); - DeleteRadiatorMap(radiators_in_tuvx, &error); - ASSERT_TRUE(IsSuccess(error)); - delete[] photolysis_rate_constants; - delete[] heating_rates; - DeleteError(&error); + return; } + Error error; + DeleteTuvx(tuvx, &error); + ASSERT_TRUE(IsSuccess(error)); + DeleteGridMap(grids_from_host, &error); + ASSERT_TRUE(IsSuccess(error)); + DeleteProfileMap(profiles_from_host, &error); + ASSERT_TRUE(IsSuccess(error)); + DeleteRadiatorMap(radiators_from_host, &error); + ASSERT_TRUE(IsSuccess(error)); + DeleteGridMap(grids_in_tuvx, &error); + ASSERT_TRUE(IsSuccess(error)); + DeleteProfileMap(profiles_in_tuvx, &error); + ASSERT_TRUE(IsSuccess(error)); + DeleteRadiatorMap(radiators_in_tuvx, &error); + ASSERT_TRUE(IsSuccess(error)); + delete[] photolysis_rate_constants; + delete[] heating_rates; + DeleteError(&error); + } }; TEST_F(TuvxRunTest, CreateTuvxInstanceWithJsonConfig) @@ -145,8 +144,14 @@ TEST_F(TuvxRunTest, CreateTuvxInstanceWithJsonConfig) { for (int j = 0; j < number_of_layers + 1; j++) { - EXPECT_NEAR(photolysis_rate_constants[i * (number_of_layers + 1) + j], expected_photolysis_rate_constants[i][j], expected_photolysis_rate_constants[i][j] * 1.0e-5); - EXPECT_NEAR(heating_rates[i * (number_of_layers + 1) + j], expected_heating_rates[i][j], expected_heating_rates[i][j] * 1.0e-5); + EXPECT_NEAR( + photolysis_rate_constants[i * (number_of_layers + 1) + j], + expected_photolysis_rate_constants[i][j], + expected_photolysis_rate_constants[i][j] * 1.0e-5); + EXPECT_NEAR( + heating_rates[i * (number_of_layers + 1) + j], + expected_heating_rates[i][j], + expected_heating_rates[i][j] * 1.0e-5); } } DeleteError(&error); @@ -216,8 +221,14 @@ TEST_F(TuvxRunTest, CreateTuvxInstanceWithJsonConfigAndHostData) { for (int j = 0; j < number_of_layers + 1; j++) { - EXPECT_NEAR(photolysis_rate_constants[i * (number_of_layers + 1) + j], expected_photolysis_rate_constants[i][j], expected_photolysis_rate_constants[i][j] * 1.0e-5); - EXPECT_NEAR(heating_rates[i * (number_of_layers + 1) + j], expected_heating_rates[i][j], expected_heating_rates[i][j] * 1.0e-5); + EXPECT_NEAR( + photolysis_rate_constants[i * (number_of_layers + 1) + j], + expected_photolysis_rate_constants[i][j], + expected_photolysis_rate_constants[i][j] * 1.0e-5); + EXPECT_NEAR( + heating_rates[i * (number_of_layers + 1) + j], + expected_heating_rates[i][j], + expected_heating_rates[i][j] * 1.0e-5); } } GetGridEdges(heights, height_edges, 4, &error); diff --git a/src/tuvx/tuvx.cpp b/src/tuvx/tuvx.cpp index 4e2fc44f..3a2b3a9b 100644 --- a/src/tuvx/tuvx.cpp +++ b/src/tuvx/tuvx.cpp @@ -66,8 +66,13 @@ namespace musica return tuvx->CreateRadiatorMap(error); } - void RunTuvx(TUVX * const tuvx, const double solar_zenith_angle, const double earth_sun_distance, - double * const photolysis_rate_constants, double * const heating_rates, Error * const error) + void RunTuvx( + TUVX *const tuvx, + const double solar_zenith_angle, + const double earth_sun_distance, + double *const photolysis_rate_constants, + double *const heating_rates, + Error *const error) { DeleteError(error); tuvx->Run(solar_zenith_angle, earth_sun_distance, photolysis_rate_constants, heating_rates, error); @@ -100,7 +105,14 @@ namespace musica return; } - tuvx_ = InternalCreateTuvx(config_path, strlen(config_path), grids->grid_map_, profiles->profile_map_, radiators->radiator_map_, &(this->number_of_layers_), &parsing_status); + tuvx_ = InternalCreateTuvx( + config_path, + strlen(config_path), + grids->grid_map_, + profiles->profile_map_, + radiators->radiator_map_, + &(this->number_of_layers_), + &parsing_status); if (parsing_status == 1) { *error = Error{ 1, CreateString(MUSICA_ERROR_CATEGORY), CreateString("Failed to create tuvx instance") }; @@ -160,13 +172,24 @@ namespace musica return radiator_map; } - void TUVX::Run(const double solar_zenith_angle, const double earth_sun_distance, - double * const photolysis_rate_constants, double * const heating_rates, Error * const error) + void TUVX::Run( + const double solar_zenith_angle, + const double earth_sun_distance, + double *const photolysis_rate_constants, + double *const heating_rates, + Error *const error) { *error = NoError(); int error_code = 0; double sza_degrees = solar_zenith_angle * 180.0 / std::numbers::pi; - InternalRunTuvx(tuvx_, this->number_of_layers_, sza_degrees, earth_sun_distance, photolysis_rate_constants, heating_rates, &error_code); + InternalRunTuvx( + tuvx_, + this->number_of_layers_, + sza_degrees, + earth_sun_distance, + photolysis_rate_constants, + heating_rates, + &error_code); if (error_code != 0) { *error = Error{ 1, CreateString(MUSICA_ERROR_CATEGORY), CreateString("Failed to run TUV-x") };