Skip to content
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

Convert real(kind_phys) vegetation, slope and soil type arrays into integer arrays #730

Merged
merged 13 commits into from
Oct 4, 2021

Conversation

climbfuji
Copy link
Collaborator

@climbfuji climbfuji commented Sep 15, 2021

Description

This PR removes all persistent Fortran "real" vegetation, slope and soil type arrays and replaces them with the existing (interstitial) "integer" arrays (these become persistent).

There are code changes that need to be discussed, because they are only required for achieving 100% identical output. Without these code changes (related to adding the vtype_save etc variables), the model execution is still giving the same results (in terms of checksums at the end of the model runs), but the vtype, stype, slope data in the surface restart/diag files are different. This is because of code that was previously called in GFS_surface_generic_pre_run and was duplicated in sfc_drv_ruc_init and that modified the interstitial variables (but not the persistent variables). Using the _save routines makes it possible to get the same (b4b) data in all output files.

The code that modifies the vtype etc. variables is now contained in one subroutine that gets called by GFS_surface_generic_pre_init and GFS_surface_generic_pre_run and no longer in sfc_drv_ruc_init , which is much more consistent and less confusing (all code in one place).

Changes in this PR:

  • Make vegetation, slope and soil type integers
  • Update physics/GFS_debug.F90 to reflect the recent changes to the GFS DDTs from this PR and previous PRs
  • Add logic to save and restore vegetation/soil/slope types before/after surface physics
  • Move code that modifies vegetation/soil/slope types into a separate subroutine in module GFS_surface_generic_pre that now gets called only by GFS_surface_generic_pre_init and GFS_surface_generic_pre_run, no longer by sfc_drv_ruc_init

Additional last minute changes (no code changes, no effect on results etc):

  • Cleanup work: fix typos in comments, remove old dependencies and comments in source code and metadata files

Issues

Fixes #704

Associated PRs

#730
NOAA-EMC/fv3atm#388
ufs-community/ufs-weather-model#804

Testing

For regression testing, see ufs-community/ufs-weather-model#804

@climbfuji
Copy link
Collaborator Author

@yangfanglin @SMoorthi-emc @HelinWei-NOAA @tanyasmirnova @junwang-noaa @DusanJovic-NOAA @grantfirl @ligiabernardet @llpcarson - the next PRs to go into the ufs-weather-model, fv3atm and ccpp-physics are to convert real(kind_phys) vegetation, slope and soil type arrays into integer arrays:

#730
NOAA-EMC/fv3atm#388
ufs-community/ufs-weather-model#804

I had opened these PRs for reviews a while ago, but haven't received any feedback yet. The way it is implemented now is to make sure that there are no changes to the input and output streams in the UFS, and that all regression tests pass with b4b identical results. If, in the future, someone wants to use integer data in the input and output streams instead of real data, then this can be implemented easily.

Can I please ask you to review my PRs and provide feedback? Please make sure to read the description in each of them, as they describe in detail what has been done and why. Thanks very much in advance!


!$OMP parallel do num_threads(nthreads) default(none) private(i) &
!$OMP shared(im, isot, ivegsrc, islmsk, vtype, stype, slope)
do i=1,im
Copy link
Collaborator

@grantfirl grantfirl Sep 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't have anything to do with this PR, but I'm curious why this logic is necessary (temporarily changing soil, vegetation, and slope for the case of sea ice). Is this a workaround because the soil, vegetation, and slope datasets don't have entries for sea-ice, so this is the next best way to handle that? This is probably a stupid question, but could this logic be avoided by adding values to the soil, vegetation, etc. datasets for sea-ice?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this data comes from the initial conditions. These have zeros for veg/soil/slop types over ice, but internally we need to match them with what the LSM lookup tables want.

Copy link
Collaborator

@grantfirl grantfirl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any problems with this.

Copy link
Collaborator

@tanyasmirnova tanyasmirnova left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The integer veg. and soil types make a lot of sense to me, and I agree with most of the changes. Put a couple questions in the comments.

stype_save(:) = stype(:)
slope_save(:) = slope(:)

call update_vegetation_soil_slope_type(nthreads, im, isot, ivegsrc, islmsk, vtype, stype, slope)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are soil and vegetation types get updated?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the name is misleading, as you figured out yourself below, it's just filling in water and ice values for slope/veg/soil type, because the input data only has zeros. If you don't do this, then RUC LSM for example will crash, because it will look for vegtype(0) at some place (which is out of bounds).

!$OMP end parallel do

end subroutine update_vegetation_soil_slope_type

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it looks like update_vegetation_soil_slope_type just fills in the values for water and ice?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct - should I rename the subroutine?

vtype(:) = vtype_save(:)
stype(:) = stype_save(:)
slope(:) = slope_save(:)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not clear why we need to return to original values with zero values for water, etc.?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that the output that gets written to disk is b4b identical with the current code. Otherwise there would be 17s, 9s etc instead of zeros. It wouldn't affect any ufs restartt run, but I don't know about other downstream applications.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, thank you for the explanation.

! integer to real/double precision
slpfcs = real(slope)
vegfcs = real(vtype)
sltfcs = real(stype)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not clear why we have to do conversion to double-precision real.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because sfcsub.F expects real arrays and not integer arrays, unfortunately. Changing sfcsub.F to use integers for these arrays would be a lot of work.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, sounds good.

Copy link
Collaborator

@tanyasmirnova tanyasmirnova left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@climbfuji Dom, thank for answering the questions. It makes sense to me now.

! Save current values of vegetation, soil and slope type
vtype_save(:) = vtype(:)
stype_save(:) = stype(:)
slope_save(:) = slope(:)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@climbfuji Can you clarify when the GFS_surface_generic_pre_init will be called and when the GFS_surface_generic_pre_run will be called? I assume they can't be called together.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GFS_surface_generic_pre_init will be called during the physics initialization phase, look for

   ! Initialize the CCPP physics
   call CCPP_step (step="physics_init", nblks=Atm_block%nblks, ierr=ierr)
   if (ierr/=0)  call mpp_error(FATAL, 'Call to CCPP physics_init step failed')

in atmos_model.F90, around line 709 in subroutine atmos_model_init.

GFS_surface_generic_pre_init will be called in each time step, look for lines

      call mpp_clock_begin(physClock)
      call CCPP_step (step="physics", nblks=Atm_block%nblks, ierr=ierr)
      if (ierr/=0)  call mpp_error(FATAL, 'Call to CCPP physics step failed')
      call mpp_clock_end(physClock)

in atmos_model.F90, around line 340 in subroutine update_atmos_radiation_physics.

GFS_surface_generic_pre_init and GFS_surface_generic_post_init will thus be called only once at the beginning of the run, while GFS_surface_generic_pre_run and GFS_surface_generic_post_run are called at every time step.

To be clear, that whole complicated code around saving the original values of soil/vegetation/slope type in the pre step and restoring them in the post step is only so that the output doesn't change compared to the current code. If I was allowed to change the output, i.e. have the update soil/vegetation/slope values over ice and water in the output files instead of zeros like in the initial conditions, this code would be a lot easier, faster, and would require less memory.

@climbfuji climbfuji merged commit 2ececb0 into NCAR:main Oct 4, 2021
@climbfuji climbfuji deleted the vegetation_soil_slope_type_integer branch June 27, 2022 03:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Remove real land/sea/ice mask, use integer variable instead
4 participants