-
Notifications
You must be signed in to change notification settings - Fork 27
Add more infrastructure for water tracers #82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
d6e357e
Add shr_wtracers_check_tracer_ratios
billsacks 00c3ad9
Add unit tests of shr_wtracers_check_tracer_ratios
billsacks 780def8
Merge remote-tracking branch 'billsacks/water_tracers' into water_tra…
billsacks 6132245
In the init-for-testing, set is_maintask to always true
billsacks 13c4c52
Merge remote-tracking branch 'billsacks/water_tracers' into water_tra…
billsacks 9d288e7
Revert "In the init-for-testing, set is_maintask to always true"
billsacks 51c5e0f
Merge remote-tracking branch 'origin/main' into water_tracers_part2
billsacks efdbd47
Fix formatting of a comment
billsacks 5d6dd22
Introduce shr_wtracers_get_bulk_fieldname subroutine
billsacks fa78e0a
Add a version of shr_wtracers_check_tracer_ratios for 2-d arrays
billsacks 4952bdc
Change dimension order convention for rank-3 tracer fields
billsacks 1af04f1
Merge branch 'main' into water_tracers_part2
billsacks b234928
Simplify conditional for tracer consistency check
billsacks cd98202
Only print water tracer information if shr_log_level > 0
billsacks fa24658
Add unit tests of NaN handling in water tracer checks
billsacks c8b712b
Add more info to shr_aborts from shr_wtracers_mod
billsacks d4c56a0
Add "only" clause to "use shr_wtracers_mod" in unit tests
billsacks c322156
CXX seems like overkill for msg variables; use CX to save some memory
billsacks File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| list(APPEND share_sources | ||
| shr_wtracers_mod.F90) | ||
|
|
||
| sourcelist_to_parent(share_sources) |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| set (pf_sources | ||
| test_shr_wtracers.pf | ||
| ) | ||
|
|
||
| set(sources_needed | ||
| shr_wtracers_mod.F90 | ||
| shr_assert_mod.F90 | ||
| shr_infnan_mod.F90 | ||
| shr_kind_mod.F90 | ||
| shr_log_mod.F90 | ||
| shr_strconvert_mod.F90 | ||
| shr_string_mod.F90 | ||
| shr_sys_mod.nompi_abortthrows.F90 | ||
| shr_abort_mod.abortthrows.F90 | ||
| shr_timer_mod.F90 | ||
| nuopc_shr_methods.F90 | ||
| gptl.F90) | ||
|
|
||
| extract_sources("${sources_needed}" "${share_sources}" test_sources) | ||
|
|
||
| add_pfunit_ctest(shr_wtracers | ||
| TEST_SOURCES "${pf_sources}" | ||
| OTHER_SOURCES "${test_sources}") | ||
|
|
||
| declare_generated_dependencies(shr_wtracers "${share_genf90_sources}") | ||
|
|
||
| target_link_libraries(shr_wtracers esmf) | ||
| # The following adds all dependencies of ESMF, including PIO, NetCDF, etc.: | ||
| target_link_libraries(shr_wtracers ESMF::ESMF) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,292 @@ | ||
| module test_shr_wtracers | ||
|
|
||
| ! Tests of shr_wtracers_mod | ||
|
|
||
| use funit | ||
|
|
||
| use shr_wtracers_mod, only : shr_wtracers_initialized, shr_wtracers_finalize | ||
| use shr_wtracers_mod, only : shr_wtracers_init_directly_for_testing | ||
| use shr_wtracers_mod, only : shr_wtracers_check_tracer_ratios | ||
| use shr_wtracers_mod, only : WATER_SPECIES_NAME_BULK | ||
|
|
||
| use shr_kind_mod, only : r8=>SHR_KIND_R8 | ||
| use shr_infnan_mod, only : assignment(=), nan => shr_infnan_nan | ||
| use ESMF, only : ESMF_SUCCESS | ||
|
|
||
| implicit none | ||
|
|
||
| @TestCase | ||
| type, extends(TestCase) :: TestShrWtracers | ||
| contains | ||
| procedure :: setUp | ||
| procedure :: tearDown | ||
| end type TestShrWtracers | ||
|
|
||
| contains | ||
|
|
||
| subroutine setUp(this) | ||
| class(TestShrWtracers), intent(inout) :: this | ||
| end subroutine setUp | ||
|
|
||
| subroutine tearDown(this) | ||
| class(TestShrWtracers), intent(inout) :: this | ||
|
|
||
| integer :: rc | ||
|
|
||
| if (shr_wtracers_initialized()) then | ||
| call shr_wtracers_finalize(rc) | ||
| end if | ||
| end subroutine tearDown | ||
|
|
||
| ! ------------------------------------------------------------------------ | ||
| ! Tests of shr_wtracers_check_tracer_ratios | ||
| ! ------------------------------------------------------------------------ | ||
|
|
||
| @Test | ||
| subroutine test_shr_wtracers_check_tracer_ratios_both0(this) | ||
| ! The tracer ratio test should pass when both tracer and bulk are 0 | ||
| class(TestShrWtracers), intent(inout) :: this | ||
| integer :: rc | ||
| real(r8) :: bulk(4) | ||
| real(r8) :: tracers(3, 4) | ||
|
|
||
| call shr_wtracers_init_directly_for_testing( & | ||
| water_tracer_names = ["tracer1", "tracer2", "tracer3"], & | ||
| water_tracer_species = [WATER_SPECIES_NAME_BULK, WATER_SPECIES_NAME_BULK, WATER_SPECIES_NAME_BULK], & | ||
| water_tracer_initial_ratios = [2._r8, 2._r8, 2._r8], & | ||
| rc = rc) | ||
| @assertEqual(ESMF_SUCCESS, rc) | ||
|
|
||
| bulk(:) = 0._r8 | ||
| tracers(:,:) = 0._r8 | ||
|
|
||
| ! The test passes if the following call runs successfully without aborting | ||
| call shr_wtracers_check_tracer_ratios(tracers, bulk, "test") | ||
| end subroutine test_shr_wtracers_check_tracer_ratios_both0 | ||
|
|
||
| @Test | ||
| subroutine test_shr_wtracers_check_tracer_ratios_correct(this) | ||
| ! The tracer ratio test should pass when the tracer ratios are correct | ||
| class(TestShrWtracers), intent(inout) :: this | ||
| integer :: rc | ||
| real(r8) :: bulk(4) | ||
| real(r8) :: tracers(3, 4) | ||
| real(r8), parameter :: ratios(3) = [2._r8, 3._r8, 4._r8] | ||
| integer :: i | ||
|
|
||
| call shr_wtracers_init_directly_for_testing( & | ||
| water_tracer_names = ["tracer1", "tracer2", "tracer3"], & | ||
| water_tracer_species = [WATER_SPECIES_NAME_BULK, WATER_SPECIES_NAME_BULK, WATER_SPECIES_NAME_BULK], & | ||
| water_tracer_initial_ratios = ratios, & | ||
| rc = rc) | ||
| @assertEqual(ESMF_SUCCESS, rc) | ||
|
|
||
| bulk(:) = [1._r8, 2._r8, 3._r8, 4._r8] | ||
| do i = 1, 3 | ||
| tracers(i,:) = ratios(i) * bulk(:) | ||
| end do | ||
|
|
||
| ! The test passes if the following call runs successfully without aborting | ||
| call shr_wtracers_check_tracer_ratios(tracers, bulk, "test") | ||
| end subroutine test_shr_wtracers_check_tracer_ratios_correct | ||
|
|
||
| @Test | ||
| subroutine test_shr_wtracers_check_tracer_ratios_differ(this) | ||
| ! The tracer ratio test should fail when some tracer ratio differs from expected | ||
| class(TestShrWtracers), intent(inout) :: this | ||
| integer :: rc | ||
| real(r8) :: bulk(4) | ||
| real(r8) :: tracers(3, 4) | ||
| real(r8), parameter :: ratios(3) = [2._r8, 3._r8, 4._r8] | ||
| integer :: i | ||
|
|
||
| call shr_wtracers_init_directly_for_testing( & | ||
| water_tracer_names = ["tracer1", "tracer2", "tracer3"], & | ||
| water_tracer_species = [WATER_SPECIES_NAME_BULK, WATER_SPECIES_NAME_BULK, WATER_SPECIES_NAME_BULK], & | ||
| water_tracer_initial_ratios = ratios, & | ||
| rc = rc) | ||
| @assertEqual(ESMF_SUCCESS, rc) | ||
|
|
||
| bulk(:) = [1._r8, 2._r8, 3._r8, 4._r8] | ||
| do i = 1, 3 | ||
| tracers(i,:) = ratios(i) * bulk(:) | ||
| end do | ||
| tracers(2,3) = tracers(2,3) * 1.1_r8 | ||
|
|
||
| call shr_wtracers_check_tracer_ratios(tracers, bulk, "test") | ||
| @assertExceptionRaised("ABORTED: shr_wtracers_check_tracer_ratios ERROR: tracer does not agree with bulk water for variable 'test', tracer 'tracer2', at index 3") | ||
| end subroutine test_shr_wtracers_check_tracer_ratios_differ | ||
|
|
||
| @Test | ||
| subroutine test_shr_wtracers_check_tracer_ratios_tracer0(this) | ||
| ! The tracer ratio test should fail when some tracer value is zero despite non-zero bulk | ||
| class(TestShrWtracers), intent(inout) :: this | ||
| integer :: rc | ||
| real(r8) :: bulk(4) | ||
| real(r8) :: tracers(3, 4) | ||
| real(r8), parameter :: ratios(3) = [2._r8, 3._r8, 4._r8] | ||
| integer :: i | ||
|
|
||
| call shr_wtracers_init_directly_for_testing( & | ||
| water_tracer_names = ["tracer1", "tracer2", "tracer3"], & | ||
| water_tracer_species = [WATER_SPECIES_NAME_BULK, WATER_SPECIES_NAME_BULK, WATER_SPECIES_NAME_BULK], & | ||
| water_tracer_initial_ratios = ratios, & | ||
| rc = rc) | ||
| @assertEqual(ESMF_SUCCESS, rc) | ||
|
|
||
| bulk(:) = [1._r8, 2._r8, 3._r8, 4._r8] | ||
| do i = 1, 3 | ||
| tracers(i,:) = ratios(i) * bulk(:) | ||
| end do | ||
| tracers(2,3) = 0._r8 | ||
|
|
||
| call shr_wtracers_check_tracer_ratios(tracers, bulk, "test") | ||
| @assertExceptionRaised("ABORTED: shr_wtracers_check_tracer_ratios ERROR: tracer does not agree with bulk water for variable 'test', tracer 'tracer2', at index 3") | ||
| end subroutine test_shr_wtracers_check_tracer_ratios_tracer0 | ||
|
|
||
| @Test | ||
| subroutine test_shr_wtracers_check_tracer_ratios_bulk0(this) | ||
| ! The tracer ratio test should fail when some bulk value is zero despite non-zero tracer | ||
| class(TestShrWtracers), intent(inout) :: this | ||
| integer :: rc | ||
| real(r8) :: bulk(4) | ||
| real(r8) :: tracers(3, 4) | ||
| real(r8), parameter :: ratios(3) = [2._r8, 3._r8, 4._r8] | ||
| integer :: i | ||
|
|
||
| call shr_wtracers_init_directly_for_testing( & | ||
| water_tracer_names = ["tracer1", "tracer2", "tracer3"], & | ||
| water_tracer_species = [WATER_SPECIES_NAME_BULK, WATER_SPECIES_NAME_BULK, WATER_SPECIES_NAME_BULK], & | ||
| water_tracer_initial_ratios = ratios, & | ||
| rc = rc) | ||
| @assertEqual(ESMF_SUCCESS, rc) | ||
|
|
||
| bulk(:) = [1._r8, 2._r8, 3._r8, 4._r8] | ||
| do i = 1, 3 | ||
| tracers(i,:) = ratios(i) * bulk(:) | ||
| end do | ||
| bulk(3) = 0._r8 | ||
|
|
||
| call shr_wtracers_check_tracer_ratios(tracers, bulk, "test") | ||
| @assertExceptionRaised("ABORTED: shr_wtracers_check_tracer_ratios ERROR: tracer does not agree with bulk water for variable 'test', tracer 'tracer1', at index 3") | ||
| end subroutine test_shr_wtracers_check_tracer_ratios_bulk0 | ||
|
|
||
| @Test | ||
| subroutine test_shr_wtracers_check_tracer_ratios_bothnan(this) | ||
| ! The tracer ratio test should pass when both tracer and bulk are NaN | ||
| class(TestShrWtracers), intent(inout) :: this | ||
| integer :: rc | ||
| real(r8) :: bulk(4) | ||
| real(r8) :: tracers(3, 4) | ||
| real(r8), parameter :: ratios(3) = [2._r8, 3._r8, 4._r8] | ||
| integer :: i | ||
|
|
||
| call shr_wtracers_init_directly_for_testing( & | ||
| water_tracer_names = ["tracer1", "tracer2", "tracer3"], & | ||
| water_tracer_species = [WATER_SPECIES_NAME_BULK, WATER_SPECIES_NAME_BULK, WATER_SPECIES_NAME_BULK], & | ||
| water_tracer_initial_ratios = ratios, & | ||
| rc = rc) | ||
| @assertEqual(ESMF_SUCCESS, rc) | ||
|
|
||
| bulk(:) = [1._r8, 2._r8, 3._r8, 4._r8] | ||
| do i = 1, 3 | ||
| tracers(i,:) = ratios(i) * bulk(:) | ||
| end do | ||
| bulk(3) = nan | ||
| tracers(:,3) = nan | ||
|
|
||
| ! The test passes if the following call runs successfully without aborting | ||
| call shr_wtracers_check_tracer_ratios(tracers, bulk, "test") | ||
| end subroutine test_shr_wtracers_check_tracer_ratios_bothnan | ||
|
|
||
| @Test | ||
| subroutine test_shr_wtracers_check_tracer_ratios_tracernan(this) | ||
| ! The tracer ratio test should fail when some tracer value is NaN despite non-NaN bulk | ||
| class(TestShrWtracers), intent(inout) :: this | ||
| integer :: rc | ||
| real(r8) :: bulk(4) | ||
| real(r8) :: tracers(3, 4) | ||
| real(r8), parameter :: ratios(3) = [2._r8, 3._r8, 4._r8] | ||
| integer :: i | ||
|
|
||
| call shr_wtracers_init_directly_for_testing( & | ||
| water_tracer_names = ["tracer1", "tracer2", "tracer3"], & | ||
| water_tracer_species = [WATER_SPECIES_NAME_BULK, WATER_SPECIES_NAME_BULK, WATER_SPECIES_NAME_BULK], & | ||
| water_tracer_initial_ratios = ratios, & | ||
| rc = rc) | ||
| @assertEqual(ESMF_SUCCESS, rc) | ||
|
|
||
| bulk(:) = [1._r8, 2._r8, 3._r8, 4._r8] | ||
| do i = 1, 3 | ||
| tracers(i,:) = ratios(i) * bulk(:) | ||
| end do | ||
| tracers(2,3) = nan | ||
|
|
||
| call shr_wtracers_check_tracer_ratios(tracers, bulk, "test") | ||
| @assertExceptionRaised("ABORTED: shr_wtracers_check_tracer_ratios ERROR: tracer does not agree with bulk water for variable 'test', tracer 'tracer2', at index 3") | ||
| end subroutine test_shr_wtracers_check_tracer_ratios_tracernan | ||
|
|
||
| ! ------------------------------------------------------------------------ | ||
| ! Tests of shr_wtracers_check_tracer_ratios with 2-d bulk arrays | ||
| ! ------------------------------------------------------------------------ | ||
|
|
||
| @Test | ||
| subroutine test_shr_wtracers_check_tracer_ratios_2d_correct(this) | ||
| ! The tracer ratio test should pass when the tracer ratios are correct (2-d bulk) | ||
| class(TestShrWtracers), intent(inout) :: this | ||
| integer :: rc | ||
| real(r8) :: bulk(2, 4) | ||
| real(r8) :: tracers(2, 3, 4) | ||
| real(r8), parameter :: ratios(3) = [2._r8, 3._r8, 4._r8] | ||
| integer :: i, j | ||
|
|
||
| call shr_wtracers_init_directly_for_testing( & | ||
| water_tracer_names = ["tracer1", "tracer2", "tracer3"], & | ||
| water_tracer_species = [WATER_SPECIES_NAME_BULK, WATER_SPECIES_NAME_BULK, WATER_SPECIES_NAME_BULK], & | ||
| water_tracer_initial_ratios = ratios, & | ||
| rc = rc) | ||
| @assertEqual(ESMF_SUCCESS, rc) | ||
|
|
||
| bulk(1,:) = [1._r8, 2._r8, 3._r8, 4._r8] | ||
| bulk(2,:) = [5._r8, 6._r8, 7._r8, 8._r8] | ||
| do i = 1, 3 | ||
| do j = 1, 2 | ||
| tracers(j,i,:) = ratios(i) * bulk(j,:) | ||
| end do | ||
| end do | ||
|
|
||
| ! The test passes if the following call runs successfully without aborting | ||
| call shr_wtracers_check_tracer_ratios(tracers, bulk, "test") | ||
| end subroutine test_shr_wtracers_check_tracer_ratios_2d_correct | ||
|
|
||
| @Test | ||
| subroutine test_shr_wtracers_check_tracer_ratios_2d_differ(this) | ||
| ! The tracer ratio test should fail when some tracer ratio differs from expected (2-d bulk) | ||
| class(TestShrWtracers), intent(inout) :: this | ||
| integer :: rc | ||
| real(r8) :: bulk(2, 4) | ||
| real(r8) :: tracers(2, 3, 4) | ||
| real(r8), parameter :: ratios(3) = [2._r8, 3._r8, 4._r8] | ||
| integer :: i, j | ||
|
|
||
| call shr_wtracers_init_directly_for_testing( & | ||
| water_tracer_names = ["tracer1", "tracer2", "tracer3"], & | ||
| water_tracer_species = [WATER_SPECIES_NAME_BULK, WATER_SPECIES_NAME_BULK, WATER_SPECIES_NAME_BULK], & | ||
| water_tracer_initial_ratios = ratios, & | ||
| rc = rc) | ||
| @assertEqual(ESMF_SUCCESS, rc) | ||
|
|
||
| bulk(1,:) = [1._r8, 2._r8, 3._r8, 4._r8] | ||
| bulk(2,:) = [5._r8, 6._r8, 7._r8, 8._r8] | ||
| do i = 1, 3 | ||
| do j = 1, 2 | ||
| tracers(j,i,:) = ratios(i) * bulk(j,:) | ||
| end do | ||
| end do | ||
| tracers(2,2,3) = tracers(2,2,3) * 1.1_r8 | ||
|
|
||
| call shr_wtracers_check_tracer_ratios(tracers, bulk, "test") | ||
| @assertExceptionRaised("ABORTED: shr_wtracers_check_tracer_ratios ERROR: tracer does not agree with bulk water for variable 'test', tracer 'tracer2', at index 3") | ||
| end subroutine test_shr_wtracers_check_tracer_ratios_2d_differ | ||
|
nusbaume marked this conversation as resolved.
|
||
|
|
||
| end module test_shr_wtracers | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| # In the real build, gptl would be a separate library. Here, for simplicity, we add the | ||
| # stub version of gptl to the share library. | ||
| list(APPEND share_sources | ||
| gptl.F90) | ||
|
|
||
| sourcelist_to_parent(share_sources) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| This directory contains stubs of the gptl timing library. In real builds, we typically | ||
| link against a pre-built gptl. Here, for simplicity, we facilitate including the necessary | ||
| stubs in the share library so we can avoid linking against an actual gptl. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| ! Stubs of the gptl timing library | ||
|
|
||
| ! Note that in the real gptl, these are defined in C. Here we define them in Fortran for | ||
| ! simplicity, but keep them outside of a module for consistency with their usage (via an | ||
| ! "external" statement rather than a "use" statement). | ||
|
|
||
| function GPTLprint_memusage(msg) result(ierr) | ||
| character(len=*), intent(in) :: msg | ||
| integer :: ierr | ||
|
|
||
| ierr = 0 | ||
| end function GPTLprint_memusage |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.