Giter Site home page Giter Site logo

Comments (29)

wrongkindofdoctor avatar wrongkindofdoctor commented on August 15, 2024 2

@marshallward if this is the case, then we probably don't need to worry about integer type definitions. Someone raised the concern with inconsistent Fortran kind definitions at the FMS meeting, so I made sure to mention it in the conversation.

from fms.

ashao avatar ashao commented on August 15, 2024 1

Thank you @wrongkindofdoctor for continuing the dialogue, providing additional the information, and for being willing to discuss alternate ways forward this with us. Thank you also @marshallward for being slightly confused with me, as I also was not quite clear on how the portability issue really would manifest. And to your question, yes it would be adding support for to read in a tuple of 6 integers (representing x, y, z grid indices) in place of (but retaining support for) a tuple of 6 reals (lat/lon/depth ranges). Your suggestion of explicitly typing the INTEGER seems sensible to me at least until we start using grids with 2^63-1 points.

If you think it would be useful to have a meeting to clarify the current limitations and our concerns going forward, I'd suggest the following folks from the MOM6 side:
@ashao: as the original rabble-rouser
@StephenGriffies: who had to fight with the current way of doing this for the OMIP-requested diagnostics
@gustavo-marques: to represent NCAR who will need to go through a similar exercise in their MOM6 configuration
@marshallward: to represent the GFDL MOM6-ers (or alternatively we could just let you know what transpires afterward).

from fms.

nikizadehgfdl avatar nikizadehgfdl commented on August 15, 2024

@underwoo is this the bug being worked at by the MS?

from fms.

underwoo avatar underwoo commented on August 15, 2024

@nikizadehgfdl we are looking at this issue now to see if/how we can resolve this. If you are asking if this is related to the non-combined regional output files not containing the same set of variables/dimensions, I do not have an answer to that ATT. We may be able to determine that as we investigate this issue further.

from fms.

ashao avatar ashao commented on August 15, 2024

@underwoo I was thinking about this problem more and I'm not entirely sure that there's a fully generalizable solution short of doing some kind of interpolation. Perhaps the 'correct' way forward is that instead of specifying the lat/lon of the requested region, the global i,j indices of the requested axes are indicated. This makes it more annoying to add a regionally diagnostic because the user has to look up and set those manually, but it allows more direct control of the output.

from fms.

StephenGriffies avatar StephenGriffies commented on August 15, 2024

FYI @ashao : when I built the diag table for OM4_p25 and OM4_p5, I tweaked the lat/lon values according to what I found when running the model and where the land/sea masks were located. I am fairly confident that one needs to do a similar iterative approach for each topography/grid configuration whereby one looks at land/sea masks carefully and tweaks the lat/lon values in the diag table accordingly. It is too risky to rely solely on diag table without checking the model run, given that topography is so dependent on the grid spacing.

So at least for OM4_p25 and OM4_p5, I hope that the lat/lon settings in the diag table are properly capturing a land-to-land crossing that provides a proper estimate of the transports.

from fms.

ashao avatar ashao commented on August 15, 2024

@StephenGriffies Specifying the i,j indices directly avoids needing to iterative process that you had to do. For the Equatorial Undercurrent, instead of

 "ocean_model_z", "uo",   "uo", "ocean_Pacific_undercurrent",  "all", "mean", "-155. -155. -2. 2. -1 -1",2

you would specify the following

"ocean_model_z", "uo",   "uo", "ocean_Pacific_undercurrent",  "all", "mean", "580 580 496 512 -1 -1",2

The latter means you wouldn't have guess and check what the diagnostic manager is doing and make it unambiguous that the diag table is requesting a rectangular subset of the domain.

Example code to find regional indices

print(np.nonzero( (geolon_u == -155) & (geolat_u >=-2) & (geolat_u <= 2)) )
(array([495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507,
        508, 509, 510, 511]),
 array([579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, 579,
        579, 579, 579, 579]))
# Note need to add 1 because Python uses 0-indexing and Fortran uses 1-indexing

from fms.

StephenGriffies avatar StephenGriffies commented on August 15, 2024

Yes, this is a good point. Very useful Python code @ashao . Many thanks!

from fms.

ashao avatar ashao commented on August 15, 2024

This issue was reraised today at the MOM6 dev meeting in response to @milicak's issue: NOAA-GFDL/MOM6-examples#285.

Generally, it seemed to be preferable to the group to be able to specify the global indices. Has there been any internal discussion about a path/timeline forward to implement a solution within FMS?

from fms.

wrongkindofdoctor avatar wrongkindofdoctor commented on August 15, 2024

Ashao,

Thank you very much for raising the issue and for providing a potential solution to the issue. FMS has experienced some internal personnel shuffling since your initial post, and I am now the manager for the repository, as well as in charge of implementing new I/O interfaces in MOM6. The outcome of the rewrite will be that MOM6 reads and writes netCDF files via direct calls to the new IO in the FMS github repository rather than using the current practice of using a combination of old FMS, mpp, and netCDF calls .

While I have not examined the problem you are having in depth yet, I have had a potentially related issue replacing some of the read_data calls in the super grid initialization scheme because of the way the user-specified domains are indexed, and have been working with the MOM6 developers and @menzel-gfdl to solve the problem.

We have replaced the IO routines in diag_manager in the fms-io-dev branch, and there is a chance that the diag-manager bug you encountered has been fixed. You may want to try doing a git checkout fms-io-dev in your FMS source directory (assuming you are building with the FMS github repo), and recompiling your executable in debug mode.

Below is a snippet from one of the fre-generated build scripts that I'm using to compile a single node (36-pe) ocean-only configuration for testing on Gaea. The script uses the GFDLlist_paths and mkmf tools provided in the mkmf repo to search the $src_dir for the files to add to the component (FMS, MOM6, and ocean_BGC in this case) makefiles, and build the makefiles with gnu 7. Note the presence of -IFMS/fms2_io/include in the mkmf argument list for the FMS repo. If you are using a similar script to build your makefiles, this should be the only line for the FMS repo you have to change after you have switched to the fms-io-dev branch in your $src_dir/FMS :

#!/bin/tcsh -fx
# ---------------- Set build and src directories
set src_dir = /lustre/f2/dev/$USER/MOM6_solo/mom6_solo_compile/src
set bld_dir = /lustre/f2/dev/$USERk/MOM6_solo/mom6_solo_compile/ncrc3.gnu7-debug/exec
# ---------------- Make template
set mkmf_template = /ncrc/home2/fms/local/opt/fre-commands/bronx-15/site/ncrc3/gnu.mk

# ---------------- write main Makefile
sed -e 's/<TAB>/\t/' >$bld_dir/Makefile <<END
# Makefile for Experiment 'mom6_solo_compile'

SRCROOT = $src_dir/
BUILDROOT = $bld_dir/

MK_TEMPLATE = $mkmf_template
include \$(MK_TEMPLATE)

fms_mom6_solo_compile.x: mom6/libmom6.a ocean_BGC/libocean_BGC.a fms/libfms.a
<TAB>\$(LD) \$^ \$(LDFLAGS) -o \$@ \$(STATIC_LIBS)

fms/libfms.a:  FORCE
<TAB>\$(MAKE) SRCROOT=\$(SRCROOT) BUILDROOT=\$(BUILDROOT) MK_TEMPLATE=\$(MK_TEMPLATE)  --directory=fms \$(@F) 

ocean_BGC/libocean_BGC.a: fms/libfms.a FORCE
<TAB>\$(MAKE) SRCROOT=\$(SRCROOT) BUILDROOT=\$(BUILDROOT) MK_TEMPLATE=\$(MK_TEMPLATE)  --directory=ocean_BGC \$(@F) 

mom6/libmom6.a: fms/libfms.a FORCE
<TAB>\$(MAKE) SRCROOT=\$(SRCROOT) BUILDROOT=\$(BUILDROOT) MK_TEMPLATE=\$(MK_TEMPLATE) OPENMP="" --directory=mom6 \$(@F) 

FORCE:

clean:
<TAB>\$(MAKE) --directory=fms clean
<TAB>\$(MAKE) --directory=ocean_BGC clean
<TAB>\$(MAKE) --directory=mom6 clean

localize:
<TAB>\$(MAKE) -f \$(BUILDROOT)fms/Makefile localize
<TAB>\$(MAKE) -f \$(BUILDROOT)ocean_BGC/Makefile localize
<TAB>\$(MAKE) -f \$(BUILDROOT)mom6/Makefile localize

distclean:
<TAB>\$(RM) -r fms
<TAB>\$(RM) -r ocean_BGC
<TAB>\$(RM) -r mom6
<TAB>\$(RM) fms_mom6_solo_compile.x
<TAB>\$(RM) Makefile

END
# ---------------- create component Makefiles
mkdir -p $bld_dir/FMS
list_paths -o $bld_dir/FMS/pathnames_fms $src_dir/FMS $src_dir/FMS/include $src_dir/FMS/mpp/include 
cd $bld_dir
pushd FMS
mkmf -m Makefile -a $src_dir -b $bld_dir -p libfms.a -t $mkmf_template -g -c "-Duse_libMPI -Duse_netCDF -Duse_netCDF3 -DINTERNAL_FILE_NML -g -DMAXFIELDMETHODS_=400" -IFMS/fms2_io/include -IFMS/include -IFMS/mpp/include -Imom6/src/MOM6/pkg/CVMix-src/include $bld_dir/fms/pathnames_fms
popd

mkdir -p $bld_dir/ocean_BGC
list_paths -o $bld_dir/ocean_BGC/pathnames_ocean_BGC $src_dir/ocean_BGC/generic_tracers $src_dir/ocean_BGC/mocsy/src 
cd $bld_dir
pushd ocean_BGC
mkmf -m Makefile -a $src_dir -b $bld_dir -p libocean_BGC.a -t $mkmf_template -g -c "-DINTERNAL_FILE_NML -g" -o "-I$bld_dir/fms" -IFMS/fms2_io/include -IFMS/include -IFMS/mpp/include -Imom6/src/MOM6/pkg/CVMix-src/include $bld_dir/ocean_BGC/pathnames_ocean_BGC
popd

mkdir -p $bld_dir/mom6
list_paths -o $bld_dir/mom6/pathnames_mom6 $src_dir/mom6/src/MOM6/config_src/dynamic $src_dir/mom6/src/MOM6/config_src/solo_driver $src_dir/mom6/src/MOM6/src/*/ $src_dir/mom6/src/MOM6/src/*/*/ $src_dir/mom6/src/MOM6/pkg/CVMix-src/include $src_dir/ocean_BGC/generic_tracers $src_dir/ocean_BGC/mocsy/src 
 setenv MAIN_PROGRAM mom6/MOM_driver.o 
cd $bld_dir
pushd mom6
mkmf -m Makefile -a $src_dir -b $bld_dir -p libmom6.a -t $mkmf_template -g -c "-DINTERNAL_FILE_NML -g -DMAX_FIELDS_=100 -DNOT_SET_AFFINITY -D_USE_MOM6_DIAG -D_USE_GENERIC_TRACER -DUSE_PRECISION=2" -o "-I$bld_dir/fms" -IFMS/fms2_io/include -IFMS/include -IFMS/mpp/include -Imom6/src/MOM6/pkg/CVMix-src/include $bld_dir/mom6/pathnames_mom6
popd
# ---------------- call make on the main Makefile
make  DEBUG=on NETCDF=3 fms_mom6_solo_compile.x

from fms.

ashao avatar ashao commented on August 15, 2024

Thank you @wrongkindofdoctor for your response. Also, my gratitude for taking on the task of overseeing the these improvements to the I/O routines!

From my reading of the diag_manager code on the fms-io-dev branch, I think that the original problem would persist. The fundamental problem is that the get_subfield_size in diag_util.F90 assumes that anything not on a cubed sphere grid, is a regular Cartesian grid.

IF ( INDEX(lowercase(axis_domain_name(1)), 'cubed') == 0 .AND. &
& INDEX(lowercase(axis_domain_name(2)), 'cubed') == 0 ) THEN
DO i = 1, SIZE(axes(:))
global_axis_size = get_axis_global_length(axes(i))
output_fields(outnum)%output_grid%subaxes(i) = -1
CALL get_diag_axis_cart(axes(i), cart)
SELECT CASE(cart)
CASE ('X')
! <ERROR STATUS="FATAL">wrong order of axes. X should come first.</ERROR>
IF( i.NE.1 ) CALL error_mesg('diag_util_mod::get_subfield_size',&
& 'wrong order of axes, X should come first',FATAL)
ALLOCATE(global_lon(global_axis_size))
CALL get_diag_axis_data(axes(i),global_lon)
IF( INT(start(i)) == grv .AND. INT(end(i)) == grv ) THEN
gstart_indx(i) = 1
gend_indx(i) = global_axis_size
output_fields(outnum)%output_grid%subaxes(i) = axes(i)
ELSE
gstart_indx(i) = get_index(start(i),global_lon)
gend_indx(i) = get_index(END(i),global_lon)
END IF
ALLOCATE(subaxis_x(gstart_indx(i):gend_indx(i)))
subaxis_x=global_lon(gstart_indx(i):gend_indx(i))
CASE ('Y')
! <ERROR STATUS="FATAL">wrong order of axes, Y should come second.</ERROR>
IF( i.NE.2 ) CALL error_mesg('diag_util_mod::get_subfield_size',&
& 'wrong order of axes, Y should come second',FATAL)
ALLOCATE(global_lat(global_axis_size))
CALL get_diag_axis_data(axes(i),global_lat)
IF( INT(start(i)) == grv .AND. INT(END(i)) == grv ) THEN
gstart_indx(i) = 1
gend_indx(i) = global_axis_size
output_fields(outnum)%output_grid%subaxes(i) = axes(i)
ELSE
gstart_indx(i) = get_index(start(i),global_lat)
gend_indx(i) = get_index(END(i),global_lat)
END IF
ALLOCATE(subaxis_y(gstart_indx(i):gend_indx(i)))
subaxis_y=global_lat(gstart_indx(i):gend_indx(i))
CASE ('Z')
! <ERROR STATUS="FATAL">wrong values in vertical axis of region</ERROR>
IF ( start(i)*END(i)<0. ) CALL error_mesg('diag_util_mod::get_subfield_size',&
& 'wrong values in vertical axis of region',FATAL)
IF ( start(i)>=0. .AND. END(i)>0. ) THEN
ALLOCATE(global_depth(global_axis_size))
CALL get_diag_axis_data(axes(i),global_depth)
gstart_indx(i) = get_index(start(i),global_depth)
gend_indx(i) = get_index(END(i),global_depth)
ALLOCATE(subaxis_z(gstart_indx(i):gend_indx(i)))
subaxis_z=global_depth(gstart_indx(i):gend_indx(i))
output_fields(outnum)%output_grid%subaxes(i) =&
& diag_subaxes_init(axes(i),subaxis_z, gstart_indx(i),gend_indx(i))
DEALLOCATE(subaxis_z,global_depth)
ELSE ! regional vertical axis is the same as global vertical axis
gstart_indx(i) = 1
gend_indx(i) = global_axis_size
output_fields(outnum)%output_grid%subaxes(i) = axes(i)
! <ERROR STATUS="FATAL">i should equal 3 for z axis</ERROR>
IF( i /= 3 ) CALL error_mesg('diag_util_mod::get_subfield_size',&
& 'i should equal 3 for z axis', FATAL)
END IF
CASE default
! <ERROR STATUS="FATAL">Wrong axis_cart</ERROR>
CALL error_mesg('diag_util_mod::get_subfield_size', 'Wrong axis_cart', FATAL)
END SELECT
END DO
DO i = 1, SIZE(axes(:))
IF ( gstart_indx(i) == -1 .OR. gend_indx(i) == -1 ) THEN
! <ERROR STATUS="FATAL">
! can not find gstart_indx/gend_indx for <output_fields(outnum)%output_name>,
! check region bounds for axis <i>.
! </ERROR>
WRITE(msg,'(A,I2)') ' check region bounds for axis ', i
CALL error_mesg('diag_util_mod::get_subfield_size', 'can not find gstart_indx/gend_indx for '&
& //TRIM(output_fields(outnum)%output_name)//','//TRIM(msg), FATAL)
END IF
END DO
ELSE ! cubed sphere
.

Currently, the diagnostic manager only knows about the placeholder lon, lat 1d vectors for any non-cubed sphere grid. For any other irregular grid (like the tripolar one used in the OM4 and SPEAR configurations), this will necessarily yield incorrect results in

INTEGER FUNCTION get_index(number, array)
REAL, INTENT(in) :: number
REAL, INTENT(in), DIMENSION(:) :: array
INTEGER :: i, n
LOGICAL :: found
n = SIZE(array(:))
! check if array is monotonous
DO i = 2, n-1
IF( (array(i-1)<array(i).AND.array(i)>array(i+1)) .OR. (array(i-1)>array(i).AND.array(i)<array(i+1))) THEN
! <ERROR STATUS="FATAL">array NOT monotonously ordered</ERROR>
CALL error_mesg('diag_util_mod::get_index', 'array NOT monotonously ordered',FATAL)
END IF
END DO
get_index = -1
found = .FALSE.
! search in increasing array
DO i = 1, n-1
IF ( (array(i)<=number).AND.(array(i+1)>= number) ) THEN
IF( number - array(i) <= array(i+1) - number ) THEN
get_index = i
found=.TRUE.
ELSE
get_index = i+1
found=.TRUE.
ENDIF
EXIT
END IF
END DO
! if not found, search in decreasing array
IF( .NOT.found ) THEN
DO i = 1, n-1
IF ( (array(i)>=number).AND.(array(i+1)<= number) ) THEN
IF ( array(i)-number <= number-array(i+1) ) THEN
get_index = i
found = .TRUE.
ELSE
get_index = i+1
found = .TRUE.
END IF
EXIT
END IF
END DO
END IF
! if still not found, is it less than the first element
! or greater than last element? (Increasing Array)
! But it must be within 2x the axis spacing
! i.e. array(1)-(array(3)-array(1)).LT.number .AND. or 2*array(1)-array(3).LT.number
IF ( .NOT. found ) THEN
IF ( 2*array(1)-array(3).LT.number .AND. number.LT.array(1) ) THEN
get_index = 1
found = .TRUE.
ELSE IF ( array(n).LT.number .AND. number.LT.2*array(n)-array(n-2) ) THEN
get_index = n
found = .TRUE.
ELSE
found = .FALSE.
END IF
END IF
! if still not found, is it greater than the first element
! or less than the last element? (Decreasing Array)
! But it must be within 2x the axis spacing (see above)
IF ( .NOT. found ) THEN
IF ( 2*array(1)-array(3).GT.number .AND. number.GT.array(1) ) THEN
get_index = 1
found = .TRUE.
ELSE IF ( array(n).GT.number .AND. number.GT.2*array(n)-array(n-2) ) THEN
get_index = n
found = .TRUE.
ELSE
found = .FALSE.
END IF
END IF
END FUNCTION get_index

As mentioned previously and confirmed yesterday in our discussions with @StephenGriffies, @Hallberg-NOAA, @adcroft, @gmarques, and others: the most accurate way forward would be for the user to specify the global indices directly. This allows us to ensure that something like a strait transport diagnostic is a fully 'connected' line instead of a potential error in double-counting an algorithm that tries to map the requested lat/lon of the line to the closest point in the true 2D lat/lon arrays

My thought for a relatively 'easy' way forward would be to create a new coord_type in diag_data.F90 (call it coord_type_indices) which would store the spatial_ops part of the field specification if it was all integers

     TYPE coord_type_indices
        INTEGER :: xbegin
        INTEGER :: xend
        INTEGER :: ybegin
        INTEGER :: yend
        INTEGER :: zbegin
        INTEGER :: zend
     END TYPE coord_type_indices

Then it seems like to implement this feature fully, requires at least 3 steps

  1. coord_type_indices would need to be added to field_description_type,
  2. Change init_output_field to basically do nothing if it coord_type_indices is populated
  3. Modify get_subfield_size to just use the information in coord_type_indices

There is some ambiguity if the user wanted a regional subset whose lat/lon/depth were all whole numbers. For example, if someone wanted to take a subset of temperature in the region spanned by 10E-20E, 20N-40N, 10-50m and wrote the field line as 10 20 20 40 10 50 then what would actually be output was the temp(20:40,10:20,10:50) instead of the actual geographic location. That being said, so long as this behavior is documented that you must provide all reals or all integers it 1) could be guarded against or 2) left as an exercise to the user.

from fms.

wrongkindofdoctor avatar wrongkindofdoctor commented on August 15, 2024

Thanks for providing the code that is causing the issue. I'll discuss your suggested fix with @thomas-robinson, and we'll determine how to proceed.

from fms.

ashao avatar ashao commented on August 15, 2024

Thanks, I'll pass it along at the next MOM6 dev meeting

from fms.

wrongkindofdoctor avatar wrongkindofdoctor commented on August 15, 2024

@underwoo Per the suggestions from other team members, @thomas-robinson and I will check to see whether horiz_interp has capability to support indexing on the tripolar grid. FMS will not support user-specified indices because the number of bytes associated with a particular integer KIND is compiler-dependent, and the indices themselves are resolution-dependent; the implementation is, therefore, tricky and error-prone.

from fms.

StephenGriffies avatar StephenGriffies commented on August 15, 2024

I observe that we have documented (verbally from savvy users/developers) errors with the current setup, whereas well documented user-specified indices would have resolved the problem with these folks. My hope is that a desire to realize code that is not "tricky and error-prone" is in turn not going to indefinitely compromise the current need to resolve the present code setup, which can be classified as "very trick and very error-prone."

from fms.

ashao avatar ashao commented on August 15, 2024

The resolution-dependence of the indices was discussed and deemed a desirable aspect of it. I'm not entirely sure how reading in user supplied indices would really affect portability between compilers, so long as the KIND of integer when compiled was 16-bits or more. Could you clarify what you mean by this? For some quantities like transports through straits where it really does matter what the actual prognostic transport is, I'm leary of relying on horiz_interp because of the risk of double-counting transports.

Maybe this would be a good time for some of the MOM6 and FMS folks should get together and make sure we're all on the same page.

from fms.

ashao avatar ashao commented on August 15, 2024

BTW, it should be @gustavo-marques, not gmarques who should be tagged in this as well.

from fms.

wrongkindofdoctor avatar wrongkindofdoctor commented on August 15, 2024

@ashao @gustavo-marques
I think a face-to-face meeting is a good idea, and will email both of you, and a couple of other FMS folks who may want to attend, to coordinate a time.
The Fortran integer definition portability issue is described here (scroll down to the second answer). While the larger concern is ensuring correct indexing, the lack of standard definitions for integer KIND means that users will have to double check that the compiler indices correspond to the correct KIND value (e.g., integer (kind=4) is a 4-byte integer).

from fms.

marshallward avatar marshallward commented on August 15, 2024

Are we not just talking about specifying grid points, which are pairs (tuples) of integers? I don't see what this problem has to do with integer type.

If there's some constraint that I don't understand, can we not just use use iso_fortran_env, only : int64? AFAIK MOM6 and FMS are both already doing this.

from fms.

ashao avatar ashao commented on August 15, 2024

I also wanted to slightly push back on the characterization that ensuring correct indexing due to resolution dependence would be a new potential source of error. The current diag_manager is currently forcing users to 'guess and check' in an unclear way.

@StephenGriffies mentioned that he had 'trick' the current FMS implementation by deliberately putting in incorrect longitudinal/latitudinal extents for the straits in order to get the full transport. For example in the current OM4_025 configuration, the eastern extent for Fram Strait is specified at 0E, which geographically is in the middle of the strait, but because of the issue detailed here, the actual output will return diagnostics which span the entirety of the strait.

https://github.com/NOAA-GFDL/MOM6-examples/blob/2ba372d642b1e7fe01bed15b927e0d7627c26cf7/ice_ocean_SIS2/OM4_025/diag_table.MOM6#L295-L300

from fms.

thomas-robinson avatar thomas-robinson commented on August 15, 2024

It seems as thought diag_manager is having difficulty supporting the lat/lon of the tripolar grid, which needs to be fixed. You are supposed to give lat/lon which are reals, but if you specify indices, then you will be sending integers. What happens next is unknown and compiler dependent. Will it fail because there is no routine that accepts integers? Will it cast the values to real and then proceed? If you manage to get the routine to work, how will it know if you are sending it grid index values or lat/lon coordinates?

The diag_manager must support the tripolar grid and work correctly if you provide the correct lat/lon values. You shouldn't need to trick it. If you have to trick it, then we need to fix it. It makes more sense to me to fix what is already there instead of having code that doesn't work half of the time and writing new code.

from fms.

marshallward avatar marshallward commented on August 15, 2024

Looking at data_table.F90, it seems that FMS is parsing the coords as a string, saves it to spatial_ops inside of a field_description_type struct, which is then moved into regional_coords if not none, which is finally where the data is saved in a coord_type as a 6-tuple of reals.

It seems that this process could be interrupted at the spatial_ops -> regional_coords conversion to save the tuple as integers rather than floats if there were some way to signal this method. Since we're talking about a generic string, there ought to be a number of options here.

I also don't foresee any portability issues, since we're relying on Fortran runtime to do the string->number conversions.

But I also agree that it ought to work under tripole grids, and if the problem is as @ashao described where it's using the axis -- whch is largeely nonsense in the tripole region -- rather than the grid, then that would be the problem.

from fms.

ashao avatar ashao commented on August 15, 2024

@thomas-robinson you raise good points and I agree that 1) it will take a bit of code to figure out if the user is specifying a tuple of REALs or INTEGERS, but again I don't really see how this is a portability problem and 2) that the code should be fixed (or at least hard fail) for the tripolar grid.

@marshallward: That was essentially what I was thinking that it would be an intercept of whether the indices should be computed or not based on the parsed type of the tuple. One way to distinguish it would be to parse the tuple and check to see if all of them are INTEGER.

do k=1,6
  read(*,'(I)',iostat=err) index_int
  if (err .ne. 0) then
    is_coords = .true.
    exit
enddo
! Sprinkle the rest of magic to make this work

Here's another use case to support regional subsetting by indices:
The fundamental problem regardless of whether the algorithm is 'fixed' or not is that specifying a [minlon maxlon minlat maxlat] assumes that a rectangular box can be defined exactly on a discrete, irregular grid. For some applications, it's probably 'good enough' to have something that's not quite a connected line to form the boundary of regional subset. However this is an acute problem for diagnostics which might be used to do drive regional models. For example, imagine that global OM4_025 is being used to drive a regional model which is a perfect integer refinement of the OM4_025 grid. If that integer refinement is 1 (e.g., for example the Baltic_OM4_025 case which is literally a manually snipped out part of the domain, though it doesn't have open boundaries), hypothetically we could get bit-for-bit reproducibility with enough time resolution/output at the boundary. However, if the regional subset does not return output exactly at the boundaries, this reproducibility is impossible to achieve. For integer refinements > 1, if the extracted line has a 'jag' in it (i.e. the cells at the boundary are not direct U-point or V-point neighbors, the physical state of the boundary is not consistent and spurious divergences would be calculated.

@wrongkindofdoctor, @thomas-robinson : would it be a good time to split this into two issues to better keep track of the conversations? 1) Bugfix: regional subsetting based on geographic extent for the tripolar grid 2) Feature request: Option to subset of domain to be specified by grid indices

Again thank you to the two of you for continuing the discussion

from fms.

wrongkindofdoctor avatar wrongkindofdoctor commented on August 15, 2024

@ashao Yes, I think we need another issue, so please open a new one tagged as feature request for indexing based on the geographic extent of the tripolar grid (or however you think the request should be titled for clarity).

The current issue (the option to subset a domain on the tripolar grid) would be an enhancement of the new indexing scheme, so I'l remove the bug tag.

from fms.

ashao avatar ashao commented on August 15, 2024

@wrongkindofdoctor, I think it's actually the opposite way around :). This one is the bug-fix and the new one will be a feature request. Really shows how far off I've dragged the conversation.

from fms.

ashao avatar ashao commented on August 15, 2024

Just to really reorient the conversation here:
It seems like to support the tripolar grid, the 2d-arrays specifying the lat,lon of every grid point need to be passed in. There is already precedent for this because the 'cubed sphere' is already supported. I wonder if that routine could be generalized to work with any irregular grid.

from fms.

thomas-robinson avatar thomas-robinson commented on August 15, 2024

@uramirez8707 has added this feature to the new diag manager. You can see it's type here

type subRegion_type
INTEGER :: grid_type !< Flag indicating the type of region,
!! acceptable values are latlon_gridtype, index_gridtype,
!! null_gridtype
class(*), allocatable :: corners(:,:)!< (x, y) coordinates of the four corner of the region
integer :: tile !< Tile number of the sub region
!! required if using the "index" grid type
end type subRegion_type
. You will be able to pass in the grid_type as index_gridtype and then give the i,j values. I believe you set it in the diag_table.yaml file.

from fms.

ashao avatar ashao commented on August 15, 2024

@thomas-robinson @uramirez8707: that's great! Looking forward to trying this out. Feel free to close out this issue if you feel that it's appropriate.

from fms.

uramirez8707 avatar uramirez8707 commented on August 15, 2024

Fixed in #1505

from fms.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.