diff --git a/docker/Dockerfile b/docker/Dockerfile index 6baec36b..85874c0a 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -27,6 +27,8 @@ COPY . /tuv-x/ RUN mkdir /build \ && cd /build \ && cmake -D CMAKE_BUILD_TYPE=release \ + -D TUVX_INSTALL_INCLUDE_DIR=/usr/local/include \ + -D TUVX_INSTALL_MOD_DIR=/usr/local/include \ /tuv-x \ && make install -j 8 diff --git a/test/regression/CMakeLists.txt b/test/regression/CMakeLists.txt index 947aed05..bc3bc78c 100644 --- a/test/regression/CMakeLists.txt +++ b/test/regression/CMakeLists.txt @@ -4,5 +4,6 @@ add_subdirectory(photolysis_rates) add_subdirectory(dose_rates) add_subdirectory(radiators) +add_subdirectory(solvers) ################################################################################ diff --git a/test/regression/solvers/CMakeLists.txt b/test/regression/solvers/CMakeLists.txt new file mode 100644 index 00000000..9a23ea25 --- /dev/null +++ b/test/regression/solvers/CMakeLists.txt @@ -0,0 +1,11 @@ +################################################################################ +# Test utilities + +include(test_util) + +################################################################################ +# Phototolysis rate regression tests + +create_standard_test(NAME cpp_delta_eddington SOURCES delta_eddington.F90) + +################################################################################ \ No newline at end of file diff --git a/test/regression/solvers/delta_eddington.F90 b/test/regression/solvers/delta_eddington.F90 new file mode 100644 index 00000000..20128eb7 --- /dev/null +++ b/test/regression/solvers/delta_eddington.F90 @@ -0,0 +1,109 @@ +! Copyright (C) 2023-2024 National Center for Atmospheric Research +! SPDX-License-Identifier: Apache-2.0 +program test_cpp_delta_eddington_solver + + use musica_constants, only: dk => musica_dk + use musica_string, only: string_t + + implicit none + + type(string_t) :: config_file_path + + ! Run the TUV 5.4 test + config_file_path = 'examples/tuv_5_4.json' + call test_cpp_delta_eddington_solver_t(config_file_path) + + ! Run the TS1/TSMLT test + config_file_path = 'examples/ts1_tsmlt.json' + call test_cpp_delta_eddington_solver_t(config_file_path) + +contains + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + ! Runs the Fortran-based Delta-Eddington solver under prescribed conditions + ! and then runs the C++-based Delta-Eddington solver under the same + ! conditions, comparing the results. + subroutine test_cpp_delta_eddington_solver_t(config_file_path) + + use tuvx_core, only: core_t + use tuvx_grid, only: grid_t + use tuvx_profile, only: profile_t + use tuvx_solver, only: radiation_field_t + use musica_string, only: string_t + + type(string_t), intent(in) :: config_file_path + + type(core_t), pointer :: core + class(grid_t), pointer :: time + class(profile_t), pointer :: solar_zenith_angle ! [degrees] + class(profile_t), pointer :: earth_sun_distance ! [AU] + type(radiation_field_t), allocatable :: f90_radiation_fields(:), & + cpp_radiation_fields(:) + integer :: i_time + + core => core_t(config_file_path) + time => core%get_grid( "time", "hours" ) + solar_zenith_angle => core%get_profile( "solar zenith angle", "degrees" ) + earth_sun_distance => core%get_profile( "Earth-Sun distance", "AU" ) + + ! Run the solver for each set of conditions + allocate( f90_radiation_fields( time%ncells_ ) ) + do i_time = 1, time%ncells_ + call core%run( solar_zenith_angle%edge_val_( i_time ), & + earth_sun_distance%edge_val_( i_time ) ) + + f90_radiation_fields( i_time ) = core%get_radiation_field( ) + end do + cpp_radiation_fields = & + calculate_cpp_radiation_fields( core, & + solar_zenith_angle%edge_val_, & + earth_sun_distance%edge_val_ ) + call compare_radiation_fields( f90_radiation_fields, cpp_radiation_fields ) + + ! Clean up + deallocate( earth_sun_distance ) + deallocate( solar_zenith_angle ) + deallocate( time ) + deallocate( core ) + + end subroutine test_cpp_delta_eddington_solver_t + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + ! Calculates the radiation field using the C++ Delta-Eddington solver + function calculate_cpp_radiation_fields( tuvx_core, solar_zenith_angle, & + earth_sun_distance) result( radiation_fields ) + + use tuvx_core, only: core_t + use tuvx_profile, only: profile_t + use tuvx_solver, only: radiation_field_t + + type(core_t), intent(in) :: tuvx_core + real(dk), intent(in) :: solar_zenith_angle(:) + real(dk), intent(in) :: earth_sun_distance(:) + type(radiation_field_t), allocatable :: radiation_fields(:) + + ! run the C++ Delta-Eddington solver + allocate( radiation_fields( size( solar_zenith_angle ) ) ) + + end function calculate_cpp_radiation_fields + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + ! Compares the radiation fields calculated by the Fortran and C++ solvers + subroutine compare_radiation_fields( f90_radiation_fields, cpp_radiation_fields ) + + use tuvx_solver, only: radiation_field_t + + type(radiation_field_t), intent(in) :: f90_radiation_fields(:) + type(radiation_field_t), intent(in) :: cpp_radiation_fields(:) + + ! Compare the radiation fields + ! ... + + end subroutine compare_radiation_fields + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +end program test_cpp_delta_eddington_solver \ No newline at end of file