Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
418dec6
write the time data based on how FMS is compiled
uramirez8707 Feb 1, 2023
215fb7f
Implement capability to specifiy which time in a time average period …
uramirez8707 Feb 1, 2023
488dfa1
Fix race conditions + add send_data tests
uramirez8707 Feb 2, 2023
3c45f10
Merge branch 'fix_race+tests' of github.com:uramirez8707/FMS into tim…
uramirez8707 Feb 6, 2023
a1fca6d
Attempt to add the diurnal axis
uramirez8707 Feb 6, 2023
73354c3
Remote extra whitespace
uramirez8707 Feb 6, 2023
feea901
Attempt to add the sub z axis
uramirez8707 Feb 6, 2023
92145cb
Fix line length limit
uramirez8707 Feb 6, 2023
e1c34a9
fix so that the correct metadata for a sub z axis gets written
uramirez8707 Feb 6, 2023
0d82f45
Fix so that you don't write both the sub z axis and the zaxis
uramirez8707 Feb 6, 2023
073d98f
Add edges_names when defining the diurnal axis
uramirez8707 Feb 7, 2023
8716fd6
Merge branch 'add_diurnal_axis' of github.com:uramirez8707/FMS into a…
uramirez8707 Feb 7, 2023
03e7e89
Merge branch 'dmUpdate' of github.com:NOAA-GFDL/FMS into time_io_update
uramirez8707 Feb 10, 2023
3ac08c6
Fix string length and added some more documentation updates
uramirez8707 Feb 21, 2023
aee3deb
Merge branch 'time_io_update' of github.com:uramirez8707/FMS into add…
uramirez8707 Feb 22, 2023
28afc70
Merge branch 'dmUpdate' of github.com:NOAA-GFDL/FMS into add_diurnal_…
uramirez8707 Feb 22, 2023
4640c4c
Merge branch 'dmUpdate' of github.com:NOAA-GFDL/FMS into add_diurnal_…
uramirez8707 Mar 6, 2023
c0fae86
simplify the register_field call
uramirez8707 Mar 7, 2023
b9c468d
gnu compile fix?
uramirez8707 Mar 7, 2023
42da9ae
Merge branch 'add_diurnal_axis' of github.com:uramirez8707/FMS into a…
uramirez8707 Mar 7, 2023
0264ba3
Merge branch 'dmUpdate' of github.com:NOAA-GFDL/FMS into add_subzaxis
uramirez8707 Mar 7, 2023
cd34f1f
Remove things that Tom is not going to like, add some documentation, …
uramirez8707 Mar 8, 2023
0c4fe97
Remove a # to prevent possible issues
uramirez8707 Mar 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 112 additions & 28 deletions diag_manager/fms_diag_axis_object.F90
Original file line number Diff line number Diff line change
Expand Up @@ -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

!> @}

Expand Down Expand Up @@ -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
Expand All @@ -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
Comment thread
thomas-robinson marked this conversation as resolved.
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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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
Comment thread
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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Comment thread
thomas-robinson marked this conversation as resolved.

naxis = naxis + 1 !< This is the axis id of the new axis!

Expand All @@ -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

Expand Down Expand Up @@ -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
Comment thread
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
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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 real()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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 nearest_index only takes in "reals", so this won't compile ...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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
!> @}
Expand Down
20 changes: 16 additions & 4 deletions diag_manager/fms_diag_field_object.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1026,10 +1026,22 @@ subroutine get_dimnames(this, diag_axis, field_yaml, unlim_dimname, dimnames, is

allocate(dimnames(naxis))

do i = 1, size(this%axis_ids)
axis_ptr => diag_axis(this%axis_ids(i))
dimnames(i) = axis_ptr%axis%get_axis_name(is_regional)
enddo
!< Duplicated do loops for performance
if (field_yaml%has_var_zbounds()) then
do i = 1, size(this%axis_ids)
axis_ptr => diag_axis(this%axis_ids(i))
if (axis_ptr%axis%is_z_axis()) then
dimnames(i) = axis_ptr%axis%get_axis_name(is_regional)//"_sub01"
else
dimnames(i) = axis_ptr%axis%get_axis_name(is_regional)
endif
enddo
else
do i = 1, size(this%axis_ids)
axis_ptr => diag_axis(this%axis_ids(i))
dimnames(i) = axis_ptr%axis%get_axis_name(is_regional)
enddo
endif

!< The second to last dimension is always the diurnal axis
if (field_yaml%has_n_diurnal()) then
Expand Down
Loading