Skip to content

Commit

Permalink
feat: modern diag fix and add calls to allocate_diag_field_output_buf…
Browse files Browse the repository at this point in the history
…fers (NOAA-GFDL#1314)
  • Loading branch information
uramirez8707 authored and rem1776 committed May 1, 2024
1 parent aa7cf27 commit bee7d9b
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 61 deletions.
39 changes: 8 additions & 31 deletions diag_manager/fms_diag_field_object.F90
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ module fms_diag_field_object_mod
!! been allocated
logical, allocatable, private :: math_needs_to_be_done !< If true, do math
!! functions. False when done.
logical, allocatable, dimension(:) :: buffer_allocated !< True if a buffer pointed by
logical, allocatable :: buffer_allocated !< True if a buffer pointed by
!! the corresponding index in
!! buffer_ids(:) is allocated.
contains
Expand Down Expand Up @@ -146,6 +146,7 @@ module fms_diag_field_object_mod
procedure :: get_missing_value
procedure :: get_data_RANGE
procedure :: get_axis_id
procedure :: get_data_buffer
procedure :: dump_field_obj
procedure :: get_domain
procedure :: get_type_of_domain
Expand Down Expand Up @@ -629,7 +630,8 @@ end function diag_obj_is_registered
function diag_obj_is_static (this) result (rslt)
class(fmsDiagField_type), intent(in) :: this
logical :: rslt
rslt = this%static
rslt = .false.
if (allocated(this%static)) rslt = this%static
end function diag_obj_is_static

!> @brief Determine if the field is a scalar
Expand Down Expand Up @@ -1276,38 +1278,13 @@ function get_data_buffer (this) &
else
rslt => null()
endif
! select type (db => this%data_buffer)
! type is (real(kind=r4_kind))
! allocate (real(kind=r4_kind) :: rslt(size(this%data_buffer,1), &
! size(this%data_buffer,2), &
! size(this%data_buffer,3), &
! size(this%data_buffer,4) ))
! rslt = this%data_buffer
! type is (real(kind=r8_kind))
! allocate (real(kind=r8_kind) :: rslt(size(this%data_buffer,1), &
! size(this%data_buffer,2), &
! size(this%data_buffer,3), &
! size(this%data_buffer,4) ))
! rslt = this%data_buffer
! type is (integer(kind=i4_kind))
! allocate (integer(kind=i4_kind) :: rslt(size(this%data_buffer,1), &
! size(this%data_buffer,2), &
! size(this%data_buffer,3), &
! size(this%data_buffer,4) ))
! rslt = this%data_buffer
! type is (integer(kind=i8_kind))
! allocate (integer(kind=i8_kind) :: rslt(size(this%data_buffer,1), &
! size(this%data_buffer,2), &
! size(this%data_buffer,3), &
! size(this%data_buffer,4) ))
! rslt = this%data_buffer
! end select
end function get_data_buffer
!> Gets the flag telling if the math functions need to be done
!! \return Copy of math_needs_to_be_done flag
pure logical function get_math_needs_to_be_done(this)
class (fmsDiagField_type), intent(in) :: this !< diag object
get_math_needs_to_be_done = this%math_needs_to_be_done
get_math_needs_to_be_done = .false.
if (allocated(this%math_needs_to_be_done)) get_math_needs_to_be_done = this%math_needs_to_be_done
end function get_math_needs_to_be_done
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!! Allocation checks
Expand Down Expand Up @@ -1494,10 +1471,10 @@ function get_default_missing_value(var_type) &

select case(var_type)
case (r4)
allocate(integer(kind=r4_kind) :: rslt)
allocate(real(kind=r4_kind) :: rslt)
rslt = real(CMOR_MISSING_VALUE, kind=r4_kind)
case (r8)
allocate(integer(kind=r8_kind) :: rslt)
allocate(real(kind=r8_kind) :: rslt)
rslt = real(CMOR_MISSING_VALUE, kind=r8_kind)
case default
end select
Expand Down
1 change: 0 additions & 1 deletion diag_manager/fms_diag_file_object.F90
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,6 @@ subroutine add_axes(this, axis_ids, diag_axis, naxis, yaml_id, buffer_id, output
this%axis_ids = diag_null
endif
endif
return
type is (fmsDiagFile_type)
do i = 1, size(var_axis_ids)
axis_found = .false.
Expand Down
47 changes: 31 additions & 16 deletions diag_manager/fms_diag_object.F90
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,6 @@ integer function fms_register_diag_field_obj &
enddo

!> Allocate and initialize member buffer_allocated of this field
allocate(fieldptr%buffer_allocated(size(diag_field_indices)))
fieldptr%buffer_allocated = .false.

!> Register the data for the field
Expand Down Expand Up @@ -575,6 +574,8 @@ logical function fms_diag_accept_data (this, diag_field_id, field_data, time, is
return
else
!!TODO: Loop through fields and do averages/math functions

call this%allocate_diag_field_output_buffers(field_data, diag_field_id)
do i = 1, size(this%FMS_diag_fields(diag_field_id)%buffer_ids)
buffer_id = this%FMS_diag_fields(diag_field_id)%buffer_ids(i)

Expand Down Expand Up @@ -662,9 +663,9 @@ subroutine fms_diag_send_complete(this, time_step)

diag_field => this%FMS_diag_fields(file_field_ids(ifield))
!> Check if math needs to be done
! math = diag_field%get_math_needs_to_be_done()
math = .false. !TODO: replace this with real thing
math = diag_field%get_math_needs_to_be_done()
calling_math: if (math) then
call this%allocate_diag_field_output_buffers(diag_field%get_data_buffer(), file_field_ids(ifield))
!!TODO: call math functions !!
endif calling_math
!> Clean up, clean up, everybody everywhere
Expand Down Expand Up @@ -1004,9 +1005,12 @@ subroutine allocate_diag_field_output_buffers(this, field_data, field_id)
class(DiagYamlFilesVar_type), pointer :: ptr_diag_field_yaml !< Pointer to a field from yaml fields
integer, allocatable :: axis_ids(:) !< Pointer to indices of axes of the field variable
integer :: var_type !< Stores type of the field data (r4, r8, i4, i8, and string) represented as an integer.
real :: missing_value !< Fill value to initialize output buffers
class(*), allocatable :: missing_value !< Missing value to initialize the data to
character(len=128), allocatable :: var_name !< Field name to initialize output buffers
logical :: is_scalar !< Flag indicating that the variable is a scalar
integer :: yaml_id

if (this%FMS_diag_fields(field_id)%buffer_allocated) return

! Determine the type of the field data
var_type = get_var_type(field_data(1, 1, 1, 1))
Expand All @@ -1015,12 +1019,14 @@ subroutine allocate_diag_field_output_buffers(this, field_data, field_id)
var_name = this%Fms_diag_fields(field_id)%get_varname()

! Get missing value for the field
!TODO class (*) is weird missing_value = this%FMS_diag_fields(field_id)%get_missing_value(var_type)
!!should work ...
if (this%FMS_diag_fields(field_id)%has_missing_value()) then
select type (my_type => this%FMS_diag_fields(field_id)%get_missing_value(var_type))
type is (real(kind=r4_kind))
missing_value = my_type
missing_value = real(my_type, kind=r4_kind)
type is (real(kind=r8_kind))
missing_value = real(my_type)
missing_value = real(my_type, kind=r8_kind)
class default
call mpp_error( FATAL, 'fms_diag_object_mod:allocate_diag_field_output_buffers Invalid type')
end select
Expand All @@ -1036,10 +1042,7 @@ subroutine allocate_diag_field_output_buffers(this, field_data, field_id)
endif

! Determine dimensions of the field
is_scalar = .True.
if (this%FMS_diag_fields(field_id)%has_axis_ids()) then
is_scalar = .False.
endif
is_scalar = this%FMS_diag_fields(field_id)%is_scalar()

! Loop over a number of fields/buffers where this variable occurs
do i = 1, size(this%FMS_diag_fields(field_id)%buffer_ids)
Expand All @@ -1051,16 +1054,23 @@ subroutine allocate_diag_field_output_buffers(this, field_data, field_id)
ndims = size(axis_ids)
endif

ptr_diag_field_yaml => diag_yaml%get_diag_field_from_id(buffer_id)
yaml_id = this%FMS_diag_output_buffers(buffer_id)%get_yaml_id()

ptr_diag_field_yaml => diag_yaml%diag_fields(yaml_id)
num_diurnal_samples = ptr_diag_field_yaml%get_n_diurnal() !< Get number of diurnal samples

! If diurnal axis exists, fill lengths of axes.
if (num_diurnal_samples .ne. 0) then
allocate(axes_length(ndims + 1)) !< Include extra length for the diurnal axis
do j = 1, ndims
axes_length(j) = this%fms_get_axis_length(axis_ids(j))
enddo
!TODO This is going to require more work for when we have subRegion variables
else
allocate(axes_length(ndims))
endif

do j = 1, ndims
axes_length(j) = this%fms_get_axis_length(axis_ids(j))
enddo

if (num_diurnal_samples .ne. 0) then
axes_length(ndims + 1) = num_diurnal_samples
ndims = ndims + 1 !< Add one more dimension for the diurnal axis
endif
Expand All @@ -1069,7 +1079,7 @@ subroutine allocate_diag_field_output_buffers(this, field_data, field_id)
! outputBuffer0d_type, outputBuffer1d_type, outputBuffer2d_type, outputBuffer3d_type,
! outputBuffer4d_type or outputBuffer5d_type.
if (.not. allocated(this%FMS_diag_output_buffers(buffer_id)%diag_buffer_obj)) then
this%FMS_diag_output_buffers(buffer_id) = fms_diag_output_buffer_create_container(ndims)
call fms_diag_output_buffer_create_container(ndims, this%FMS_diag_output_buffers(buffer_id))
end if

ptr_diag_buffer_obj => this%FMS_diag_output_buffers(buffer_id)%diag_buffer_obj
Expand Down Expand Up @@ -1108,7 +1118,12 @@ subroutine allocate_diag_field_output_buffers(this, field_data, field_id)
class default
call mpp_error( FATAL, 'allocate_diag_field_output_buffers: invalid buffer type')
end select

if (allocated(axis_ids)) deallocate(axis_ids)
deallocate(axes_length)
enddo

this%FMS_diag_fields(field_id)%buffer_allocated = .true.
#else
call mpp_error( FATAL, "allocate_diag_field_output_buffers: "//&
"you can not use the modern diag manager without compiling with -Duse_yaml")
Expand Down
23 changes: 11 additions & 12 deletions diag_manager/fms_diag_output_buffer.F90
Original file line number Diff line number Diff line change
Expand Up @@ -174,33 +174,32 @@ end function fms_diag_output_buffer_init
!> Creates a container type encapsulating a new buffer object for the given dimensions.
!! The buffer object will still need to be allocated to a type via allocate_buffer() before use.
!> @result A fmsDiagBufferContainer_type that holds a bufferNd_type, where N is buff_dims
function fms_diag_output_buffer_create_container(buff_dims) &
result(rslt)
integer, intent(in) :: buff_dims !< dimensions
type(fmsDiagOutputBufferContainer_type), allocatable :: rslt
subroutine fms_diag_output_buffer_create_container(buff_dims, buffer_obj)
integer, intent(in) :: buff_dims !< dimensions
type(fmsDiagOutputBufferContainer_type), intent(inout) :: buffer_obj

character(len=5) :: dim_output !< string to output buff_dims on error

allocate(rslt)
select case (buff_dims)
case (0)
allocate(outputBuffer0d_type :: rslt%diag_buffer_obj)
allocate(outputBuffer0d_type :: buffer_obj%diag_buffer_obj)
case (1)
allocate(outputBuffer1d_type :: rslt%diag_buffer_obj)
allocate(outputBuffer1d_type :: buffer_obj%diag_buffer_obj)
case (2)
allocate(outputBuffer2d_type :: rslt%diag_buffer_obj)
allocate(outputBuffer2d_type :: buffer_obj%diag_buffer_obj)
case (3)
allocate(outputBuffer3d_type :: rslt%diag_buffer_obj)
allocate(outputBuffer3d_type :: buffer_obj%diag_buffer_obj)
case (4)
allocate(outputBuffer4d_type :: rslt%diag_buffer_obj)
allocate(outputBuffer4d_type :: buffer_obj%diag_buffer_obj)
case (5)
allocate(outputBuffer5d_type :: rslt%diag_buffer_obj)
allocate(outputBuffer5d_type :: buffer_obj%diag_buffer_obj)
case default
write( dim_output, *) buff_dims
dim_output = adjustl(dim_output)
call mpp_error(FATAL, 'fms_diag_buffer_create_container: invalid number of dimensions given:' // dim_output //&
'. Must be 0-5')
end select
end function fms_diag_output_buffer_create_container
end subroutine fms_diag_output_buffer_create_container

!!--------generic routines for any fmsDiagBuffer_class objects

Expand Down
2 changes: 1 addition & 1 deletion diag_manager/fms_diag_yaml.F90
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ module fms_diag_yaml_mod
character(len=:), allocatable, private :: diag_title !< Experiment name
integer, private, dimension (basedate_size) :: diag_basedate !< basedate array
type(diagYamlFiles_type), allocatable, public, dimension (:) :: diag_files!< History file info
type(diagYamlFilesVar_type), allocatable, private, dimension (:) :: diag_fields !< Diag fields info
type(diagYamlFilesVar_type), allocatable, public, dimension (:) :: diag_fields !< Diag fields info
contains
procedure :: size_diag_files

Expand Down

0 comments on commit bee7d9b

Please sign in to comment.