-
Notifications
You must be signed in to change notification settings - Fork 159
Modern diag manager: add subzaxis #1148
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
Changes from all commits
418dec6
215fb7f
488dfa1
3c45f10
a1fca6d
73354c3
feea901
92145cb
e1c34a9
0d82f45
073d98f
8716fd6
03e7e89
3ac08c6
aee3deb
28afc70
4640c4c
c0fae86
b9c468d
42da9ae
0264ba3
cd34f1f
0c4fe97
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -52,7 +52,7 @@ module fms_diag_axis_object_mod | |
| & get_domain_and_domain_type, diagDomain_t, & | ||
| & DIAGDOMAIN2D_T, fmsDiagSubAxis_type, fmsDiagAxisContainer_type, fmsDiagFullAxis_type, DIAGDOMAINUG_T | ||
| public :: define_new_axis, define_subaxis, parse_compress_att, get_axis_id_from_name, define_diurnal_axis, & | ||
| & fmsDiagDiurnalAxis_type | ||
| & fmsDiagDiurnalAxis_type, create_new_z_subaxis | ||
|
|
||
| !> @} | ||
|
|
||
|
|
@@ -97,6 +97,7 @@ module fms_diag_axis_object_mod | |
| procedure :: get_parent_axis_id | ||
| procedure :: get_subaxes_id | ||
| procedure :: get_axis_name | ||
| procedure :: is_z_axis | ||
| procedure :: write_axis_metadata | ||
| procedure :: write_axis_data | ||
| procedure :: add_structured_axis_ids | ||
|
|
@@ -107,13 +108,13 @@ module fms_diag_axis_object_mod | |
| !> @brief Type to hold the subaxis | ||
| !> @ingroup diag_axis_object_mod | ||
| TYPE, extends(fmsDiagAxis_type) :: fmsDiagSubAxis_type | ||
| CHARACTER(len=:), ALLOCATABLE, private :: subaxis_name !< Name of the subaxis | ||
| INTEGER , private :: starting_index !< Starting index of the subaxis relative to the | ||
| !! parent axis | ||
| INTEGER , private :: ending_index !< Ending index of the subaxis relative to the | ||
| !! parent axis | ||
| type(subRegion_type) , private :: subRegion !< Bounds of the subaxis (lat/lon or indices) | ||
| INTEGER , private :: parent_axis_id !< Id of the parent_axis | ||
| CHARACTER(len=:), ALLOCATABLE , private :: subaxis_name !< Name of the subaxis | ||
| INTEGER , private :: starting_index !< Starting index of the subaxis relative to the | ||
| !! parent axis | ||
| INTEGER , private :: ending_index !< Ending index of the subaxis relative to the | ||
| !! parent axis | ||
| INTEGER , private :: parent_axis_id !< Id of the parent_axis | ||
| real(kind=r4_kind), allocatable, private :: zbounds(:) !< Bounds of the Z axis | ||
| contains | ||
| procedure :: fill_subaxis | ||
| END TYPE fmsDiagSubAxis_type | ||
|
|
@@ -295,11 +296,14 @@ subroutine write_axis_metadata(this, fileobj, parent_axis) | |
| integer :: i !< For do loops | ||
| type(fmsDiagFullAxis_type), pointer :: diag_axis !< Local pointer to the diag_axis | ||
|
|
||
| integer :: type_of_domain !< The type of domain the current axis is in | ||
|
|
||
| select type(this) | ||
| type is (fmsDiagFullAxis_type) | ||
| axis_name => this%axis_name | ||
| axis_length = this%length | ||
| diag_axis => this | ||
| type_of_domain = this%type_of_domain | ||
| type is (fmsDiagSubAxis_type) | ||
| axis_name => this%subaxis_name | ||
| axis_length = this%ending_index - this%starting_index + 1 | ||
|
|
@@ -310,6 +314,7 @@ subroutine write_axis_metadata(this, fileobj, parent_axis) | |
| diag_axis => parent_axis | ||
| end select | ||
| endif | ||
| type_of_domain = NO_DOMAIN !< All subaxes are treated as non-domain decomposed (each rank writes it own file) | ||
| type is (fmsDiagDiurnalAxis_type) | ||
| call this%write_diurnal_metadata(fileobj) | ||
| return | ||
|
|
@@ -324,7 +329,7 @@ subroutine write_axis_metadata(this, fileobj, parent_axis) | |
| call register_axis(fileobj, axis_name, axis_length) | ||
| call register_field(fileobj, axis_name, diag_axis%type_of_data, (/axis_name/)) | ||
| type is (FmsNetcdfDomainFile_t) | ||
| select case (diag_axis%type_of_domain) | ||
| select case (type_of_domain) | ||
| case (NO_DOMAIN) | ||
| !< Here the fileobj is domain decomposed, but the axis is not | ||
| !! Domain decomposed fileobjs can have axis that are not domain decomposed (i.e "Z" axis) | ||
|
|
@@ -336,7 +341,7 @@ subroutine write_axis_metadata(this, fileobj, parent_axis) | |
| call register_field(fileobj, axis_name, diag_axis%type_of_data, (/axis_name/)) | ||
| end select | ||
| type is (FmsNetcdfUnstructuredDomainFile_t) | ||
| select case (diag_axis%type_of_domain) | ||
| select case (type_of_domain) | ||
| case (UG_DOMAIN) | ||
| !< Here the axis is in a unstructured domain | ||
| call register_axis(fileobj, axis_name) | ||
|
|
@@ -676,21 +681,25 @@ end subroutine get_compute_domain | |
|
|
||
| !!!!!!!!!!!!!!!!!! SUB AXIS PROCEDURES !!!!!!!!!!!!!!!!! | ||
| !> @brief Fills in the information needed to define a subaxis | ||
| subroutine fill_subaxis(this, starting_index, ending_index, axis_id, parent_id, parent_axis_name, subRegion) | ||
| class(fmsDiagSubAxis_type), INTENT(INOUT) :: this !< diag_sub_axis obj | ||
| integer , intent(in) :: starting_index !< Starting index of the subRegion for the PE | ||
| integer , intent(in) :: ending_index !< Ending index of the subRegion for the PE | ||
| integer , intent(in) :: axis_id !< Axis id to assign to the subaxis | ||
| integer , intent(in) :: parent_id !< The id of the parent axis, the subaxis belongs to | ||
| type(subRegion_type) , intent(in) :: subRegion !< SubRegion definition as it is defined in the yaml | ||
| character(len=*) , intent(in) :: parent_axis_name !< Name of the parent_axis | ||
| subroutine fill_subaxis(this, starting_index, ending_index, axis_id, parent_id, parent_axis_name, zbounds) | ||
| class(fmsDiagSubAxis_type) , INTENT(INOUT) :: this !< diag_sub_axis obj | ||
| integer , intent(in) :: starting_index !< Starting index of the subRegion for the PE | ||
| integer , intent(in) :: ending_index !< Ending index of the subRegion for the PE | ||
| integer , intent(in) :: axis_id !< Axis id to assign to the subaxis | ||
| integer , intent(in) :: parent_id !< The id of the parent axis, the subaxis belongs to | ||
| character(len=*) , intent(in) :: parent_axis_name !< Name of the parent_axis | ||
| real(kind=r4_kind), optional, intent(in) :: zbounds(2) !< Bounds of the z-axis | ||
|
thomas-robinson marked this conversation as resolved.
|
||
|
|
||
| this%axis_id = axis_id | ||
| this%starting_index = starting_index | ||
| this%ending_index = ending_index | ||
| this%parent_axis_id = parent_id | ||
| this%subRegion = subRegion | ||
| this%subaxis_name = trim(parent_axis_name)//"_sub01" | ||
|
|
||
| if (present(zbounds)) then | ||
| allocate(this%zbounds(2)) | ||
| this%zbounds = zbounds | ||
| endif | ||
| end subroutine fill_subaxis | ||
|
|
||
| !> @brief Get the ntiles in a domain | ||
|
|
@@ -794,6 +803,17 @@ pure function get_axis_name(this, is_regional) & | |
| end select | ||
| end function get_axis_name | ||
|
|
||
| !< @brief Determine if the axis is a Z axis by looking at the cartesian name | ||
| !! @return .True. if the axis is a Z axis | ||
| pure logical function is_z_axis(this) | ||
| class(fmsDiagAxis_type), intent(in) :: this !< Axis object | ||
| is_z_axis = .false. | ||
| select type (this) | ||
| type is (fmsDiagFullAxis_type) | ||
| if (this%cart_name .eq. "Z") is_z_axis = .true. | ||
| end select | ||
| end function | ||
|
|
||
| !> @brief Check if a cart_name is valid and crashes if it isn't | ||
| subroutine check_if_valid_cart_name(cart_name) | ||
| character(len=*), intent(in) :: cart_name | ||
|
|
@@ -920,15 +940,15 @@ subroutine define_subaxis_index(diag_axis, axis_ids, naxis, subRegion, write_on_ | |
| !< If the PE's compute is not inside the subRegion, define a null subaxis and go to the next axis | ||
| if (.not. need_to_define_axis) then | ||
| call define_new_axis(diag_axis, parent_axis, naxis, axis_ids(i), & | ||
| subRegion, diag_null, diag_null) | ||
| diag_null, diag_null) | ||
| cycle | ||
| endif | ||
|
|
||
| !< If it made it to this point, the current PE is in the subRegion! | ||
| write_on_this_pe = .true. | ||
|
|
||
| call define_new_axis(diag_axis, parent_axis, naxis, axis_ids(i), & | ||
| subRegion, starting_index, ending_index) | ||
| starting_index, ending_index) | ||
| end select | ||
| enddo | ||
|
|
||
|
|
@@ -995,7 +1015,7 @@ subroutine define_subaxis_latlon(diag_axis, axis_ids, naxis, subRegion, is_cube_ | |
| write_on_this_pe = .true. | ||
|
|
||
| call define_new_axis(diag_axis, parent_axis, naxis, axis_ids(i), & | ||
| subRegion, starting_index, ending_index) | ||
| starting_index, ending_index) | ||
| end select select_axis_type | ||
| enddo loop_over_axis_ids | ||
| else if_is_cube_sphere | ||
|
|
@@ -1034,24 +1054,25 @@ subroutine define_subaxis_latlon(diag_axis, axis_ids, naxis, subRegion, is_cube_ | |
| write_on_this_pe = .true. | ||
|
|
||
| call define_new_axis(diag_axis, parent_axis, naxis, axis_ids(i), & | ||
| subRegion, starting_index, ending_index) | ||
| starting_index, ending_index) | ||
| end select | ||
| enddo loop_over_axis_ids2 | ||
| endif if_is_cube_sphere | ||
| end subroutine define_subaxis_latlon | ||
|
|
||
| !< Creates a new subaxis and fills it will all the information it needs | ||
| subroutine define_new_axis(diag_axis, parent_axis, naxis, parent_id, subRegion, & | ||
| starting_index, ending_index) | ||
| !> @brief Creates a new subaxis and fills it will all the information it needs | ||
| subroutine define_new_axis(diag_axis, parent_axis, naxis, parent_id, & | ||
| starting_index, ending_index, new_axis_id, zbounds) | ||
|
|
||
| class(fmsDiagAxisContainer_type), target, intent(inout) :: diag_axis(:) !< Diag_axis object | ||
| class(fmsDiagFullAxis_type), intent(inout) :: parent_axis !< The parent axis | ||
| integer, intent(inout) :: naxis !< The number of axis that | ||
| !! have been defined | ||
| integer, intent(in) :: parent_id !< Id of the parent axis | ||
| type(subRegion_type), intent(in) :: subRegion !< SubRegion definition from the yaml | ||
| integer, intent(in) :: starting_index !< PE's Starting index | ||
| integer, intent(in) :: ending_index !< PE's Ending index | ||
| integer, optional, intent(out) :: new_axis_id !< Axis id of the axis this is creating | ||
| real(kind=r4_kind), optional, intent(in) :: zbounds(2) !< Bounds of the Z axis | ||
|
thomas-robinson marked this conversation as resolved.
|
||
|
|
||
| naxis = naxis + 1 !< This is the axis id of the new axis! | ||
|
|
||
|
|
@@ -1062,11 +1083,12 @@ subroutine define_new_axis(diag_axis, parent_axis, naxis, parent_id, subRegion, | |
| !< Allocate the new axis as a subaxis and fill it | ||
| allocate(fmsDiagSubAxis_type :: diag_axis(naxis)%axis) | ||
| diag_axis(naxis)%axis%axis_id = naxis | ||
| if (present(new_axis_id)) new_axis_id = naxis | ||
|
|
||
| select type (sub_axis => diag_axis(naxis)%axis) | ||
| type is (fmsDiagSubAxis_type) | ||
| call sub_axis%fill_subaxis(starting_index, ending_index, naxis, parent_id, & | ||
| parent_axis%axis_name, subRegion) | ||
| parent_axis%axis_name, zbounds) | ||
| end select | ||
| end subroutine define_new_axis | ||
|
|
||
|
|
@@ -1174,6 +1196,68 @@ subroutine write_diurnal_metadata(this, fileobj) | |
| &trim(this%edges_name), str_len=len_trim(this%edges_name)) | ||
| end subroutine write_diurnal_metadata | ||
|
|
||
| !> @brief Creates a new z subaxis to use | ||
| subroutine create_new_z_subaxis(zbounds, var_axis_ids, diag_axis, naxis, file_axis_id, nfile_axis) | ||
| real(kind=r4_kind), intent(in) :: zbounds(2) !< Bounds of the Z axis | ||
|
thomas-robinson marked this conversation as resolved.
|
||
| integer, intent(inout) :: var_axis_ids(:) !< The variable's axis_ids | ||
| class(fmsDiagAxisContainer_type), target, intent(inout) :: diag_axis(:) !< Array of diag_axis objects | ||
| integer, intent(inout) :: naxis !< Number of axis that have been | ||
| !! registered | ||
| integer, intent(inout) :: file_axis_id(:) !< The file's axis_ids | ||
| integer, intent(inout) :: nfile_axis !< Number of axis that have been | ||
| !! defined in file | ||
|
|
||
| class(*), pointer :: zaxis_data(:) !< The data of the full zaxis | ||
| integer :: subaxis_indices(2) !< The starting and ending indices of the subaxis relative to the full | ||
| !! axis | ||
| integer :: i !< For do loops | ||
| integer :: subaxis_id !< The id of the new z subaxis | ||
| logical :: axis_found !< Flag that indicated if the zsubaxis already exists | ||
|
|
||
| !< Determine if the axis was already created | ||
| axis_found = .false. | ||
| do i = 1, nfile_axis | ||
| select type (axis => diag_axis(file_axis_id(i))%axis) | ||
| type is (fmsDiagSubAxis_type) | ||
| if (axis%zbounds(1) .eq. zbounds(1) .and. axis%zbounds(2) .eq. zbounds(2)) then | ||
| axis_found = .true. | ||
| subaxis_id = file_axis_id(i) | ||
| exit | ||
| endif | ||
| end select | ||
| enddo | ||
|
|
||
| !< Determine which of the variable's axis is the zaxis! | ||
| do i = 1, size(var_axis_ids) | ||
| select type (parent_axis => diag_axis(var_axis_ids(i))%axis) | ||
| type is (fmsDiagFullAxis_type) | ||
| if (parent_axis%cart_name .eq. "Z") then | ||
| !< If the axis was previously defined set the var_axis_ids and leave | ||
| if (axis_found) then | ||
| var_axis_ids(i) = subaxis_id | ||
| return | ||
| endif | ||
| zaxis_data => parent_axis%axis_data | ||
|
|
||
| select type(zaxis_data) | ||
| type is (real(kind=r4_kind)) | ||
| !TODO need to include the conversion to "real" because nearest_index doesn't take r4s and r8s | ||
| subaxis_indices(1) = nearest_index(real(zbounds(1)), real(zaxis_data)) | ||
| subaxis_indices(2) = nearest_index(real(zbounds(2)), real(zaxis_data)) | ||
| type is (real(kind=r8_kind)) | ||
| subaxis_indices(1) = nearest_index(real(zbounds(1)), real(zaxis_data)) | ||
| subaxis_indices(2) = nearest_index(real(zbounds(2)), real(zaxis_data)) | ||
|
Comment on lines
+1243
to
+1249
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there may be an issue here with the types and just using
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Once axis_utils2 is updated for mixed mode, the conversion to real can be done correctly: type is (real(kind=r4_kind))
!TODO need to include the conversion to "real" because nearest_index doesn't take r4s and r8s
subaxis_indices(1) = nearest_index(zbounds(1), zaxis_data)
subaxis_indices(2) = nearest_index(zbounds(2), zaxis_data)
type is (real(kind=r8_kind))
subaxis_indices(1) = nearest_index(real(zbounds(1), kind=r8_kind), zaxis_data)
subaxis_indices(2) = nearest_index(real(zbounds(2), kind=r8_kind), zaxis_data)
Right now
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I think I understand now. We need to keep track of this. |
||
| end select | ||
|
|
||
| call define_new_axis(diag_axis, parent_axis, naxis, parent_axis%axis_id, & | ||
| &subaxis_indices(1), subaxis_indices(2), subaxis_id, zbounds) | ||
| var_axis_ids(i) = subaxis_id | ||
| return | ||
| endif | ||
| end select | ||
| enddo | ||
|
|
||
| end subroutine | ||
| #endif | ||
| end module fms_diag_axis_object_mod | ||
| !> @} | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.