Skip to content

Commit

Permalink
fvcom_tools - Add option to process 'cold' or 'warm' restart files (#595
Browse files Browse the repository at this point in the history
)

Also, allow the user to select a specific time slice through the command line.

Fixes #586
  • Loading branch information
dmwright526 committed Nov 5, 2021
1 parent 005d210 commit 5f34ba1
Show file tree
Hide file tree
Showing 9 changed files with 649 additions and 175 deletions.
21 changes: 17 additions & 4 deletions sorc/fvcom_tools.fd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ set(fortran_src
kinds.f90
module_ncio.f90
module_nwp_base.f90
module_nwp.f90
process_FVCOM.f90)
module_nwp.f90)
# process_FVCOM.f90)

set(exe_src process_FVCOM.f90)

if(CMAKE_Fortran_COMPILER_ID MATCHES "^(Intel)$")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -r8")
Expand All @@ -18,15 +19,27 @@ elseif(CMAKE_Fortran_COMPILER_ID MATCHES "^(GNU|Clang|AppleClang)$")
endif()

set(exe_name fvcom_to_FV3)
add_executable(${exe_name} ${fortran_src})

add_library(fvcom_tools_lib STATIC ${fortran_src})
add_executable(${exe_name} ${exe_src})

set(mod_dir "${CMAKE_CURRENT_BINARY_DIR}/mod")
set_target_properties(fvcom_tools_lib PROPERTIES Fortran_MODULE_DIRECTORY ${mod_dir})
target_include_directories(fvcom_tools_lib INTERFACE ${mod_dir})

target_link_libraries(
${exe_name}
# ${exe_name}
fvcom_tools_lib
PUBLIC
MPI::MPI_Fortran
NetCDF::NetCDF_Fortran)

target_link_libraries(${exe_name} PRIVATE fvcom_tools_lib)

install(TARGETS ${exe_name} RUNTIME DESTINATION ${exec_dir})

# If doxygen documentation we enabled, build it.
if(ENABLE_DOCS)
add_subdirectory(docs)
endif()

66 changes: 48 additions & 18 deletions sorc/fvcom_tools.fd/docs/user_guide.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,48 @@

# fvcom_tools

# Introduction

The process_FVCOM.f90 program replaces lake surface and lake ice
temperature along with aerial ice concentration generated from the
Great Lakes Operational Forecast System (GLOFS) in an FV3 surface
restart file. See [fvcom documentation](@ref fvcom_readme).

This document is part of the <a href="../index.html">UFS_UTILS
documentation</a>.

The fvcom_tools program is part of the [NCEPLIBS
UFS_UTILS](https://github.com/NOAA-EMC/UFS_UTILS) project.



@brief replaces lake surface and lake ice temperature @anchor user_guide

**fvcom_to_FV3.exe**

**Introduction:**
This code replaces lake surface and lake ice temperature along
with aerial ice concentration generated from Great Lakes
Operational Forecast System (GLOFS), an FVCOM-based model, into
sfc_data.nc.
**NOTE** that the variables in the input files must reside on
the same grid. This means data from FVCOM must be horizontally
interpolated to the FV3 grid. This routine will also force a
minimum ice concentration of 15%. If ice concentration is less
than 15% in FVCOM, it will be set to 0% to avoid FV3 from
changing values less than 15% to 15% and generating unrealistic
lake ice temperatures.

**Library Dependencies:**
Installation depends on the netCDF library and cmake.

**Running:**
This routine will take four variables from the command line:
1. Name of FV3 sfc data file (e.g. sfc_data.tile7.halo0.nc)
which is generated from chgres_cube.exe.
2. Name of FVCOM data file in netcdf format (e.g. fvcom.nc)
3. "warm" or "cold" start. "warm" start will read in
sfc_data.nc files generated from a restart of UFS-SRW.
"cold" start will read in sfc_data.nc files generated
from chgres_cube.
4. String of time slice to use in the fvcom.nc file. This string
should match exactly what is in the Times variable of the .nc file.
To run the script, use the following example, modifying file
names as needed:
./fvcom_to_FV3 sfc_data.tile7.halo0.nc fvcom.nc cold \
2020-01-31T18:00:00.000000
Output will be to the sfc data file and include lake surface
and lake ice temperature, and lake ice concentration from the
first time in the FVCOM file.


This routine is *strongly* based upon Eric James' (ESRL/GSL) work
to update HRRR/WRF Great Lakes' temperature data with FVCOM.
It also relies heavily on Ming Hu's (ESRL/GSL) ncio module.

**For more information, please contact:**
David Wright
University of Michigan and GLERL
dmwright@umich.edu
41 changes: 0 additions & 41 deletions sorc/fvcom_tools.fd/fvcom_readme.md

This file was deleted.

85 changes: 66 additions & 19 deletions sorc/fvcom_tools.fd/module_ncio.f90
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,10 @@ module module_ncio
procedure :: replace_var_nc_char_3d !< Replace 3D character type variable. @return
procedure :: handle_err !< Handle netCDF errors. @return
procedure :: convert_theta2t_2dgrid !< Convert theta T (Kelvin) to T (deg C). @return
procedure :: add_new_var => add_new_var_3d !< Add a new 3d variable to output file. @return
generic :: add_new_var => add_new_var_2d, &
add_new_var_3d !< Add a new 2d or 3d variable to ouput file. @return
procedure :: add_new_var_2d !< Add a new 2d variable to output file. @return
procedure :: add_new_var_3d !< Add a new 3d variable to output file. @return
end type ncio

contains
Expand Down Expand Up @@ -1306,10 +1309,10 @@ subroutine get_var_nc_double_2d(this,varname,nd1,nd2,field)
field(:,j)=temp(istart:iend)
enddo
!
if(this%debug_level>100) then
write(*,*) trim(thissubname),' show samples:'
write(*,*) 'max,min:',maxval(field(:,:)),minval(field(:,:))
endif
! if(this%debug_level>100) then
! write(*,*) trim(thissubname),' show samples:'
! write(*,*) 'max,min:',maxval(field(:,:)),minval(field(:,:))
! endif
else
write(*,*) trim(thissubname),' ERROR: dimension does not match.'
write(*,*) nd1,this%ends(1),nd2,this%ends(2)
Expand Down Expand Up @@ -1362,12 +1365,12 @@ subroutine get_var_nc_double_3d(this,varname,nd1,nd2,nd3,field)
enddo
enddo
!
if(this%debug_level>100) then
write(*,*) trim(thissubname),' show samples:'
do k=1,nd3
write(*,*) 'k,max,min:',k,maxval(field(:,:,k)),minval(field(:,:,k))
enddo
endif
! if(this%debug_level>100) then
! write(*,*) trim(thissubname),' show samples:'
! do k=1,nd3
! write(*,*) 'k,max,min:',k,maxval(field(:,:,k)),minval(field(:,:,k))
! enddo
! endif
else
write(*,*) trim(thissubname),' ERROR: dimension does not match.'
write(*,*) nd1,this%ends(1),nd2,this%ends(2),nd3,this%ends(3)
Expand Down Expand Up @@ -1441,6 +1444,7 @@ subroutine get_var_nc_double(this,varname,ilength,field)
if(status /= nf90_NoErr) call this%handle_err(status)
do i=1,nDims
dimname=" "
write(*,*) 'dimids(i) = ', dimids(i)
status = nf90_inquire_dimension(ncid, dimids(i), dimname, len = ndim)
if (status /= nf90_noerr) call this%handle_err(status)
ends(i)=ndim
Expand Down Expand Up @@ -2271,10 +2275,10 @@ subroutine get_var_nc_char_2d(this,varname,nd1,nd2,field)
field(:,j)=temp(istart:iend)
enddo
!
if(this%debug_level>100) then
write(*,*) trim(thissubname),' show samples:'
write(*,*) field(1,1)
endif
! if(this%debug_level>100) then
! write(*,*) trim(thissubname),' show samples:'
! write(*,*) field(1,1)
! endif
else
write(*,*) trim(thissubname),' ERROR: dimension does not match.'
write(*,*) nd1,this%ends(1),nd2,this%ends(2)
Expand Down Expand Up @@ -2327,10 +2331,10 @@ subroutine get_var_nc_char_3d(this,varname,nd1,nd2,nd3,field)
enddo
enddo
!
if(this%debug_level>100) then
write(*,*) trim(thissubname),' show samples:'
write(*,*) field(1,1,1)
endif
! if(this%debug_level>100) then
! write(*,*) trim(thissubname),' show samples:'
! write(*,*) field(1,1,1)
! endif
else
write(*,*) trim(thissubname),' ERROR: dimension does not match.'
write(*,*) nd1,this%ends(1),nd2,this%ends(2),nd3,this%ends(3)
Expand Down Expand Up @@ -2542,4 +2546,47 @@ subroutine add_new_var_3d(this,varname,dname1,dname2,dname3,lname,units)

end subroutine add_new_var_3d

!> Add a new variable to sfc_data.nc with dimensions (yaxis_1,
!! xaxis_1).
!!
!! @param this instance of an ncio class
!! @param[in] varname Name of variable to be created in netcdf file
!! @param[in] dname1 1st dimension name
!! @param[in] dname2 2nd dimension name
!! @param[in] lname long name output for netcdf variable
!! @param[in] units units to use in netcdf variable
!!
!! @author David.M.Wright org: UM/GLERL @date 2021-10-07
subroutine add_new_var_2d(this,varname,dname1,dname2,lname,units)
implicit none
!
class(ncio) :: this
character(len=*),intent(in) :: varname,dname1,dname2 &
,lname,units
integer :: status, ncid, dim1id, dim2id, varid

status = nf90_redef(this%ncid) !Enter Define Mode
if (status /= nf90_noerr) call this%handle_err(status)

status = nf90_inq_dimid(this%ncid, dname1, dim1id)
if (status /= nf90_noerr) call this%handle_err(status)
status = nf90_inq_dimid(this%ncid, dname2, dim2id)
if (status /= nf90_noerr) call this%handle_err(status)

status = nf90_def_var(this%ncid, varname, nf90_double, &
(/ dim1id, dim2id /), varid)
if (status /= nf90_noerr) call this%handle_err(status)

status = nf90_put_att(this%ncid, varid, 'long_name', lname)
if (status /= nf90_noerr) call this%handle_err(status)
status = nf90_put_att(this%ncid, varid, 'units', units)
if (status /= nf90_noerr) call this%handle_err(status)

status = nf90_enddef(this%ncid) !Exit Define Mode and
! return to Data Mode
if (status /= nf90_noerr) call this%handle_err(status)

end subroutine add_new_var_2d


end module module_ncio
Loading

0 comments on commit 5f34ba1

Please sign in to comment.