-
Notifications
You must be signed in to change notification settings - Fork 136
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
Unstructured grid files axis #1114
Changes from all commits
deb196e
9596033
fab037c
1216773
cf55696
c39c5cf
28c666b
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 | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -49,7 +49,7 @@ module fms_diag_axis_object_mod | |||||||
public :: fmsDiagAxis_type, fms_diag_axis_object_init, fms_diag_axis_object_end, & | ||||||||
& get_domain_and_domain_type, diagDomain_t, & | ||||||||
& DIAGDOMAIN2D_T, fmsDiagSubAxis_type, fmsDiagAxisContainer_type, fmsDiagFullAxis_type, DIAGDOMAINUG_T | ||||||||
public :: define_new_axis, define_subaxis | ||||||||
public :: define_new_axis, define_subaxis, parse_compress_att, get_axis_id_from_name | ||||||||
|
||||||||
!> @} | ||||||||
|
||||||||
|
@@ -96,6 +96,9 @@ module fms_diag_axis_object_mod | |||||||
procedure :: get_axis_name | ||||||||
procedure :: write_axis_metadata | ||||||||
procedure :: write_axis_data | ||||||||
procedure :: add_structured_axis_ids | ||||||||
procedure :: get_structured_axis | ||||||||
procedure :: is_unstructured_grid | ||||||||
END TYPE fmsDiagAxis_type | ||||||||
|
||||||||
!> @brief Type to hold the subaxis | ||||||||
|
@@ -138,6 +141,8 @@ module fms_diag_axis_object_mod | |||||||
TYPE(fmsDiagAttribute_type),allocatable , private :: attributes(:) !< Array to hold user definable attributes | ||||||||
INTEGER , private :: num_attributes !< Number of defined attibutes | ||||||||
INTEGER , private :: domain_position !< The position in the doman (NORTH, EAST or CENTER) | ||||||||
integer, allocatable , private :: structured_ids(:) !< If the axis is in the unstructured grid, | ||||||||
!! this is the axis ids of the structured axis | ||||||||
|
||||||||
contains | ||||||||
|
||||||||
|
@@ -160,7 +165,7 @@ module fms_diag_axis_object_mod | |||||||
!!!!!!!!!!!!!!!!! DIAG AXIS PROCEDURES !!!!!!!!!!!!!!!!! | ||||||||
!> @brief Initialize the axis | ||||||||
subroutine register_diag_axis_obj(this, axis_name, axis_data, units, cart_name, long_name, direction,& | ||||||||
& set_name, Domain, Domain2, DomainU, aux, req, tile_count, domain_position ) | ||||||||
& set_name, Domain, Domain2, DomainU, aux, req, tile_count, domain_position, axis_length ) | ||||||||
class(fmsDiagFullAxis_type),INTENT(out) :: this !< Diag_axis obj | ||||||||
CHARACTER(len=*), INTENT(in) :: axis_name !< Name of the axis | ||||||||
class(*), INTENT(in) :: axis_data(:) !< Array of coordinate values | ||||||||
|
@@ -177,6 +182,7 @@ subroutine register_diag_axis_obj(this, axis_name, axis_data, units, cart_name, | |||||||
CHARACTER(len=*), INTENT(in), OPTIONAL :: req !< Required field names. | ||||||||
INTEGER, INTENT(in), OPTIONAL :: tile_count !< Number of tiles | ||||||||
INTEGER, INTENT(in), OPTIONAL :: domain_position !< Domain position, "NORTH" or "EAST" | ||||||||
integer, intent(in), optional :: axis_length !< The length of the axis size(axis_data(:)) | ||||||||
|
||||||||
this%axis_name = trim(axis_name) | ||||||||
this%units = trim(units) | ||||||||
|
@@ -187,12 +193,14 @@ subroutine register_diag_axis_obj(this, axis_name, axis_data, units, cart_name, | |||||||
|
||||||||
select type (axis_data) | ||||||||
type is (real(kind=r8_kind)) | ||||||||
allocate(real(kind=r8_kind) :: this%axis_data(size(axis_data))) | ||||||||
allocate(real(kind=r8_kind) :: this%axis_data(axis_length)) | ||||||||
this%axis_data = axis_data | ||||||||
this%length = axis_length | ||||||||
uramirez8707 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
this%type_of_data = "double" !< This is what fms2_io expects in the register_field call | ||||||||
type is (real(kind=r4_kind)) | ||||||||
allocate(real(kind=r4_kind) :: this%axis_data(size(axis_data))) | ||||||||
allocate(real(kind=r4_kind) :: this%axis_data(axis_length)) | ||||||||
this%axis_data = axis_data | ||||||||
this%length = axis_length | ||||||||
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. This is optional. What happens if it's not included? 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. Changed it to a required argument FMS/diag_manager/diag_axis.F90 Lines 143 to 145 in cf55696
|
||||||||
this%type_of_data = "float" !< This is what fms2_io expects in the register_field call | ||||||||
class default | ||||||||
call mpp_error(FATAL, "The axis_data in your diag_axis_init call is not a supported type. & | ||||||||
|
@@ -226,8 +234,6 @@ subroutine register_diag_axis_obj(this, axis_name, axis_data, units, cart_name, | |||||||
if (present(domain_position)) this%domain_position = domain_position | ||||||||
call check_if_valid_domain_position(this%domain_position) | ||||||||
|
||||||||
this%length = size(axis_data) | ||||||||
|
||||||||
this%direction = 0 | ||||||||
if (present(direction)) this%direction = direction | ||||||||
call check_if_valid_direction(this%direction) | ||||||||
|
@@ -309,15 +315,15 @@ subroutine write_axis_metadata(this, fileobj, parent_axis) | |||||||
end select | ||||||||
type is (FmsNetcdfUnstructuredDomainFile_t) | ||||||||
select case (diag_axis%type_of_domain) | ||||||||
case (NO_DOMAIN) | ||||||||
!< Here the fileobj is in the unstructured domain, but the axis is not | ||||||||
!< Unstructured domain fileobjs can have axis that are not domain decomposed (i.e "Z" axis) | ||||||||
call register_axis(fileobj, axis_name, axis_length) | ||||||||
call register_field(fileobj, axis_name, diag_axis%type_of_data, (/axis_name/)) | ||||||||
case (UG_DOMAIN) | ||||||||
!< Here the axis is in a unstructured domain | ||||||||
call register_axis(fileobj, axis_name) | ||||||||
call register_field(fileobj, axis_name, diag_axis%type_of_data, (/axis_name/)) | ||||||||
case default | ||||||||
!< Here the fileobj is in the unstructured domain, but the axis is not | ||||||||
!< Unstructured domain fileobjs can have axis that are not domain decomposed (i.e "Z" axis) | ||||||||
call register_axis(fileobj, axis_name, axis_length) | ||||||||
call register_field(fileobj, axis_name, diag_axis%type_of_data, (/axis_name/)) | ||||||||
end select | ||||||||
end select | ||||||||
|
||||||||
|
@@ -383,6 +389,44 @@ subroutine write_axis_data(this, fileobj, parent_axis) | |||||||
end select | ||||||||
end subroutine write_axis_data | ||||||||
|
||||||||
!< @brief Determine if the axis is in the unstructured grid | ||||||||
!! @return .True. if the axis is in unstructured grid | ||||||||
pure logical function is_unstructured_grid(this) | ||||||||
class(fmsDiagAxis_type), target, INTENT(in) :: this !< diag_axis obj | ||||||||
|
||||||||
is_unstructured_grid = .false. | ||||||||
select type (this) | ||||||||
type is (fmsDiagFullAxis_type) | ||||||||
is_unstructured_grid = trim(this%cart_name) .eq. "U" | ||||||||
end select | ||||||||
end function is_unstructured_grid | ||||||||
|
||||||||
!< @brief Adds the structured axis ids to the axis object | ||||||||
subroutine add_structured_axis_ids(this, axis_ids) | ||||||||
class(fmsDiagAxis_type), target, INTENT(inout) :: this !< diag_axis obj | ||||||||
integer, intent(in) :: axis_ids(2) !< axis ids to add to the axis object | ||||||||
|
||||||||
select type (this) | ||||||||
type is (fmsDiagFullAxis_type) | ||||||||
allocate(this%structured_ids(2)) | ||||||||
this%structured_ids = axis_ids | ||||||||
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. this%structured_ids should be allocated here and then set to axis_ids. |
||||||||
end select | ||||||||
end subroutine add_structured_axis_ids | ||||||||
|
||||||||
!< @brief Get the structured axis ids from the axis object | ||||||||
!! @return the structured axis ids | ||||||||
pure function get_structured_axis(this) & | ||||||||
result(rslt) | ||||||||
class(fmsDiagAxis_type), target, INTENT(in) :: this !< diag_axis obj | ||||||||
integer :: rslt(2) | ||||||||
|
||||||||
rslt = diag_null | ||||||||
select type (this) | ||||||||
type is (fmsDiagFullAxis_type) | ||||||||
rslt = this%structured_ids | ||||||||
end select | ||||||||
end function get_structured_axis | ||||||||
|
||||||||
!> @brief Get the starting and ending indices of the global io domain of the axis | ||||||||
subroutine get_global_io_domain(this, global_io_index) | ||||||||
class(fmsDiagFullAxis_type), intent(in) :: this !< diag_axis obj | ||||||||
|
@@ -972,6 +1016,48 @@ pure function get_subaxes_id(this) & | |||||||
|
||||||||
end function | ||||||||
|
||||||||
!< @brief Parses the "compress" attribute to get the names of the two axis | ||||||||
!! @return the names of the structured axis | ||||||||
pure function parse_compress_att(compress_att) & | ||||||||
result(axis_names) | ||||||||
class(*), intent(in) :: compress_att(:) !< The compress attribute to parse | ||||||||
character(len=120) :: axis_names(2) | ||||||||
|
||||||||
integer :: ios !< Errorcode after parsing the compress attribute | ||||||||
|
||||||||
select type (compress_att) | ||||||||
type is (character(len=*)) | ||||||||
read(compress_att(1),*, iostat=ios) axis_names | ||||||||
if (ios .ne. 0) axis_names = "" | ||||||||
class default | ||||||||
axis_names = "" | ||||||||
end select | ||||||||
end function parse_compress_att | ||||||||
|
||||||||
!< @brief Determine the axis id of a axis | ||||||||
!! @return Axis id | ||||||||
pure function get_axis_id_from_name(axis_name, diag_axis, naxis) & | ||||||||
result(axis_id) | ||||||||
class(fmsDiagAxisContainer_type), intent(in) :: diag_axis(:) !< Array of axis object | ||||||||
character(len=*), intent(in) :: axis_name !< Name of the axis | ||||||||
integer, intent(in) :: naxis !< Number of axis that have been registered | ||||||||
integer :: axis_id | ||||||||
|
||||||||
integer :: i !< For do loops | ||||||||
|
||||||||
axis_id = diag_null | ||||||||
do i = 1, naxis | ||||||||
select type(axis => diag_axis(i)%axis) | ||||||||
type is (fmsDiagFullAxis_type) | ||||||||
if (trim(axis%axis_name) .eq. trim(axis_name)) then | ||||||||
axis_id = i | ||||||||
return | ||||||||
endif | ||||||||
end select | ||||||||
enddo | ||||||||
|
||||||||
end function get_axis_id_from_name | ||||||||
|
||||||||
#endif | ||||||||
end module fms_diag_axis_object_mod | ||||||||
!> @} | ||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,7 +30,8 @@ module fms_diag_object_mod | |
& get_diag_files_id, diag_yaml | ||
use fms_diag_axis_object_mod, only: fms_diag_axis_object_init, fmsDiagAxis_type, fmsDiagSubAxis_type, & | ||
&diagDomain_t, get_domain_and_domain_type, diagDomain2d_t, & | ||
&fmsDiagAxisContainer_type, fms_diag_axis_object_end, fmsDiagFullAxis_type | ||
&fmsDiagAxisContainer_type, fms_diag_axis_object_end, fmsDiagFullAxis_type, & | ||
&parse_compress_att, get_axis_id_from_name | ||
use fms_diag_buffer_mod | ||
#endif | ||
#if defined(_OPENMP) | ||
|
@@ -373,7 +374,7 @@ end function fms_register_static_field | |
!> @brief Wrapper for the register_diag_axis subroutine. This is needed to keep the diag_axis_init | ||
!! interface the same | ||
!> @return Axis id | ||
FUNCTION fms_diag_axis_init(this, axis_name, axis_data, units, cart_name, long_name, direction,& | ||
FUNCTION fms_diag_axis_init(this, axis_name, axis_data, units, cart_name, axis_length, long_name, direction,& | ||
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. Why change the interface? 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. This is now a required arugment, so the interface changed. |
||
& set_name, edges, Domain, Domain2, DomainU, aux, req, tile_count, domain_position ) & | ||
& result(id) | ||
|
||
|
@@ -382,6 +383,7 @@ FUNCTION fms_diag_axis_init(this, axis_name, axis_data, units, cart_name, long_n | |
CLASS(*), INTENT(in) :: axis_data(:) !< Array of coordinate values | ||
CHARACTER(len=*), INTENT(in) :: units !< Units for the axis | ||
CHARACTER(len=1), INTENT(in) :: cart_name !< Cartesian axis ("X", "Y", "Z", "T", "U", "N") | ||
integer, intent(in) :: axis_length !< The length of the axis size(axis_data(:)) | ||
CHARACTER(len=*), INTENT(in), OPTIONAL :: long_name !< Long name for the axis. | ||
CHARACTER(len=*), INTENT(in), OPTIONAL :: set_name !< Name of the parent axis, if it is a subaxis | ||
INTEGER, INTENT(in), OPTIONAL :: direction !< Indicates the direction of the axis | ||
|
@@ -423,7 +425,7 @@ FUNCTION fms_diag_axis_init(this, axis_name, axis_data, units, cart_name, long_n | |
endif | ||
call axis%register(axis_name, axis_data, units, cart_name, long_name=long_name, & | ||
& direction=direction, set_name=set_name, Domain=Domain, Domain2=Domain2, DomainU=DomainU, aux=aux, & | ||
& req=req, tile_count=tile_count, domain_position=domain_position) | ||
& req=req, tile_count=tile_count, domain_position=domain_position, axis_length=axis_length) | ||
|
||
id = this%registered_axis | ||
call axis%set_axis_id(id) | ||
|
@@ -629,6 +631,9 @@ subroutine fms_diag_axis_add_attribute(this, axis_id, att_name, att_value) | |
character(len=*), intent(in) :: att_name !< Name of the attribute | ||
class(*), intent(in) :: att_value(:) !< The attribute value to add | ||
|
||
character(len=20) :: axis_names(2) !< Names of the uncompress axis | ||
integer :: uncmx_ids(2) !< Ids of the uncompress axis | ||
integer :: j !< For do loops | ||
#ifndef use_yaml | ||
CALL MPP_ERROR(FATAL,"You can not use the modern diag manager without compiling with -Duse_yaml") | ||
#else | ||
|
@@ -638,6 +643,25 @@ subroutine fms_diag_axis_add_attribute(this, axis_id, att_name, att_value) | |
select type (axis => this%diag_axis(axis_id)%axis) | ||
type is (fmsDiagFullAxis_type) | ||
call axis%add_axis_attribute(att_name, att_value) | ||
|
||
!! Axis that are in the "unstructured" domain require a "compress" attribute for the | ||
!! combiner and PP. This attribute is passed in via a diag_axis_add_attribute call in the model code | ||
!! The compress attribute indicates the names of the axis that were compressed | ||
!! For example grid_index:compress = "grid_yt grid_xt" | ||
!! The metadata and the data for these axis also needs to be written to the file | ||
if (trim(att_name) .eq. "compress") then | ||
!< If the attribute is the "compress" attribute, get the axis names, | ||
!! and the ids of the axis and add it to the axis object so it can be written to netcdf files | ||
!! that use this axis | ||
axis_names = parse_compress_att(att_value) | ||
do j = 1, size(axis_names) | ||
uncmx_ids(j) = get_axis_id_from_name(axis_names(j), this%diag_axis, this%registered_axis) | ||
if (uncmx_ids(j) .eq. diag_null) call mpp_error(FATAL, & | ||
&"Error parsing the compress attribute for axis: "//trim(axis%get_axis_name())//& | ||
&". Be sure that the axes in the compress attribute are registered") | ||
enddo | ||
call axis%add_structured_axis_ids(uncmx_ids) | ||
endif | ||
end select | ||
#endif | ||
end subroutine fms_diag_axis_add_attribute | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is a bug with a SPECIFIC gnu version, do we need to fix it or can we just say it's not compatible with that version? Is this a C5, CI, or dev box compiler?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The version of gnu is what we used in the CI
I can also reproduce in the dev box.