diff --git a/.github/workflows/GCC.yml b/.github/workflows/GCC.yml index 0da81e763..5f3891684 100644 --- a/.github/workflows/GCC.yml +++ b/.github/workflows/GCC.yml @@ -32,7 +32,7 @@ jobs: submodules: recursive - name: install-cmake - run: | + run: | cd ${{ github.workspace }} curl -f -s -S -R -L https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-Linux-x86_64.tar.gz | tar -zx echo "${{ github.workspace }}/cmake-3.29.2-linux-x86_64/bin" >> $GITHUB_PATH @@ -78,7 +78,7 @@ jobs: sudo apt-get install doxygen graphviz - name: install-cmake - run: | + run: | cd ${{ github.workspace }} curl -f -s -S -R -L https://github.com/Kitware/CMake/releases/download/v3.29.2/cmake-3.29.2-Linux-x86_64.tar.gz | tar -zx echo "${{ github.workspace }}/cmake-3.29.2-linux-x86_64/bin" >> $GITHUB_PATH @@ -105,7 +105,6 @@ jobs: git clone https://github.com/NOAA-EMC/CMakeModules git clone --recurse-submodules https://github.com/NOAA-PSL/stochastic_physics stochastic_physics_repo mkdir ${GITHUB_WORKSPACE}/build - sed -i 's/doc /upp_doc /' upp/docs/CMakeLists.txt cd ${GITHUB_WORKSPACE}/build export CC=mpicc export CXX=mpicxx diff --git a/io/module_fv3_io_def.F90 b/io/module_fv3_io_def.F90 index ce600d8e1..05d7c5fbe 100644 --- a/io/module_fv3_io_def.F90 +++ b/io/module_fv3_io_def.F90 @@ -12,89 +12,91 @@ module module_fv3_io_def !> Number of processors used in the forecast grid component integer :: num_pes_fcst - !> Number of write tasks per write group. + !> Number of write tasks per write group. integer :: wrttasks_per_group !> Number of the write groups - integer :: write_groups + integer :: write_groups - !> Current write group - integer :: n_group + !> Current write group + integer :: n_group !> Number of history files - integer :: num_files + integer :: num_files !> Number of the ESMF field bundles for physics fields - integer :: nbdlphys + integer :: nbdlphys !> IAU running window length - integer :: iau_offset + integer :: iau_offset !> Logical variable to decide if full time (HH.MM.SS) is used in the history !! file names - logical :: lflname_fulltime + logical :: lflname_fulltime !> Logical variable to decide if unlimited time dimension is used - logical :: time_unlimited + logical :: time_unlimited + !> Directory name for model history output files + character(len=esmf_maxstr) :: fv3atm_output_dir !> Base names for model history output files - character(len=esmf_maxstr),dimension(:),allocatable :: filename_base + character(len=esmf_maxstr),dimension(:),allocatable :: filename_base - !> Output file format - character(len=esmf_maxstr),dimension(:),allocatable :: output_file + !> Output file format + character(len=esmf_maxstr),dimension(:),allocatable :: output_file !> The first write task in a write group - integer,dimension(:),allocatable :: lead_wrttask + integer,dimension(:),allocatable :: lead_wrttask !> The last write task in a write group - integer,dimension(:),allocatable :: last_wrttask + integer,dimension(:),allocatable :: last_wrttask !> Output grid type, e.g. "gaussian_grid" - character(len=esmf_maxstr),dimension(:),allocatable :: output_grid + character(len=esmf_maxstr),dimension(:),allocatable :: output_grid !> The i-dimension in the output grid - integer,dimension(:),allocatable :: imo + integer,dimension(:),allocatable :: imo !> The j-dimension in the output grid - integer,dimension(:),allocatable :: jmo + integer,dimension(:),allocatable :: jmo !> Longitude of the center point in the output grid - real,dimension(:),allocatable :: cen_lon + real,dimension(:),allocatable :: cen_lon !> Latitude of the center pointer in the output grid - real,dimension(:),allocatable :: cen_lat + real,dimension(:),allocatable :: cen_lat !> Longitude of the first grid point in the output grid - real,dimension(:),allocatable :: lon1 + real,dimension(:),allocatable :: lon1 !> Latitude of the first pointer in the output grid - real,dimension(:),allocatable :: lat1 + real,dimension(:),allocatable :: lat1 !> Longitude of the last grid point in the output grid - real,dimension(:),allocatable :: lon2 + real,dimension(:),allocatable :: lon2 !> Latitude of the last pointer in the output grid - real,dimension(:),allocatable :: lat2 + real,dimension(:),allocatable :: lat2 !> Longitude increment - real,dimension(:),allocatable :: dlon + real,dimension(:),allocatable :: dlon !> Latitude increment - real,dimension(:),allocatable :: dlat + real,dimension(:),allocatable :: dlat !> The first latitude from the pole at which the secant cone cuts the sphere - real,dimension(:),allocatable :: stdlat1 + real,dimension(:),allocatable :: stdlat1 !> The second latitude from the pole at which the secant cone cuts the sphere - real,dimension(:),allocatable :: stdlat2 + real,dimension(:),allocatable :: stdlat2 !> x-direction grid length - real,dimension(:),allocatable :: dx + real,dimension(:),allocatable :: dx !> y-direction grid length - real,dimension(:),allocatable :: dy + real,dimension(:),allocatable :: dy !> Deflate level to use, 0 means no deflate. integer,dimension(:),allocatable :: ideflate diff --git a/io/module_wrt_grid_comp.F90 b/io/module_wrt_grid_comp.F90 index eb3ccd8dc..5a3945714 100644 --- a/io/module_wrt_grid_comp.F90 +++ b/io/module_wrt_grid_comp.F90 @@ -28,13 +28,13 @@ module module_wrt_grid_comp ! use mpi_f08 use esmf - use fms_mod, only : uppercase - use fms - use mpp_mod, only : mpp_init, mpp_error + use fms, only : fms_init, fms_end, fms_mpp_uppercase, fms_mpp_error, FATAL + use fms, only : NO_CALENDAR, JULIAN, GREGORIAN, THIRTY_DAY_MONTHS, NOLEAP use write_internal_state use module_fv3_io_def, only : num_pes_fcst, & n_group, num_files, & + fv3atm_output_dir, & filename_base, output_grid, output_file, & imo,jmo,ichunk2d,jchunk2d, & ichunk3d,jchunk3d,kchunk3d, & @@ -282,6 +282,15 @@ subroutine wrt_initialize_p1(wrt_comp, imp_state_write, exp_state_write, clock, if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, & line=__LINE__, file=__FILE__)) return + call ESMF_ConfigGetAttribute(config=CF,value=fv3atm_output_dir, & + label ='fv3atm_output_dir:', default='./', rc=rc) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return + + ! Make sure fv3atm_output_dir ends with '/' + if (fv3atm_output_dir(len(trim(fv3atm_output_dir)):len(trim(fv3atm_output_dir))) /= '/') then + fv3atm_output_dir = trim(fv3atm_output_dir) // '/' + end if + if( wrt_int_state%write_dopost ) then #ifdef INLINE_POST call ESMF_ConfigGetAttribute(config=CF,value=wrt_int_state%post_namelist,default='itag', & @@ -2140,7 +2149,7 @@ subroutine wrt_run(wrt_comp, imp_state_write, exp_state_write,clock,rc) wend = MPI_Wtime() if (mype == lead_write_task) then !** write out inline post log file - open(newunit=nolog,file='log.atm.inlinepost.f'//trim(cfhour),form='FORMATTED') + open(newunit=nolog,file=trim(fv3atm_output_dir)//'log.atm.inlinepost.f'//trim(cfhour),form='FORMATTED') write(nolog,"('completed: fv3atm')") write(nolog,"('forecast hour: ',f10.3)") nfhour write(nolog,"('valid time: ',6(i4,2x))") wrt_int_state%fdate(1:6) @@ -2313,7 +2322,7 @@ subroutine wrt_run(wrt_comp, imp_state_write, exp_state_write,clock,rc) endif else ! history bundle - filename = trim(wrtFBName)//'f'//trim(cfhour)//'.nc' + filename = trim(fv3atm_output_dir)//trim(wrtFBName)//'f'//trim(cfhour)//'.nc' endif if(mype == lead_write_task) print *,'in wrt run,filename= ',nbdl,trim(filename) @@ -2444,7 +2453,7 @@ subroutine wrt_run(wrt_comp, imp_state_write, exp_state_write,clock,rc) if (out_phase == 1 .and. mype == lead_write_task) then !** write history log file - open(newunit=nolog, file='log.atm.f'//trim(cfhour)) + open(newunit=nolog, file=trim(fv3atm_output_dir)//'log.atm.f'//trim(cfhour)) write(nolog,"('completed: fv3atm')") write(nolog,"('forecast hour: ',f10.3)") nfhour write(nolog,"('valid time: ',6(i4,2x))") wrt_int_state%fdate(1:6) diff --git a/io/post_fv3.F90 b/io/post_fv3.F90 index c0ba56dda..c07fad471 100644 --- a/io/post_fv3.F90 +++ b/io/post_fv3.F90 @@ -2,9 +2,9 @@ module post_fv3 use mpi_f08 - use module_fv3_io_def, only : wrttasks_per_group, filename_base, & - lon1, lat1, lon2, lat2, dlon, dlat, & - cen_lon, cen_lat, dxin=>dx, dyin=>dy, & + use module_fv3_io_def, only : wrttasks_per_group, fv3atm_output_dir, & + lon1, lat1, lon2, lat2, dlon, dlat, & + cen_lon, cen_lat, dxin=>dx, dyin=>dy, & stdlat1, stdlat2, output_grid use write_internal_state, only : wrt_internal_state @@ -199,6 +199,8 @@ subroutine post_run_fv3(wrt_int_state,grid_id,mype,mpicomp,lead_write, & if (grid_id > 1) then write(post_fname, '(A,I2.2)') trim(post_fname)//".nest", grid_id endif + post_fname = trim(fv3atm_output_dir)//trim(post_fname) + if (mype==0) print *,'post_fname=',trim(post_fname) call process(kth,kpv,th(1:kth),pv(1:kpv),iostatusD3D) @@ -996,13 +998,13 @@ subroutine set_postvars_fv3(wrt_int_state,grid_id,mype,mpicomp) endif ! Maximum hail diameter (mm) since last output - if(trim(fieldname)=='hailcast_dhail') then + if(trim(fieldname)=='hailcast_dhail') then !$omp parallel do default(none) private(i,j) shared(jsta,jend,ista,iend,hail_maxhailcast,arrayr42d,fillValue,spval) - do j=jsta,jend + do j=jsta,jend do i=ista, iend hail_maxhailcast(i,j)=arrayr42d(i,j) if(abs(arrayr42d(i,j)-fillValue) < small) hail_maxhailcast(i,j)=spval - enddo + enddo enddo endif @@ -1182,7 +1184,7 @@ subroutine set_postvars_fv3(wrt_int_state,grid_id,mype,mpicomp) enddo endif - !Accumulated snowfall + !Accumulated snowfall if(trim(fieldname)=='tsnowp') then !$omp parallel do default(none) private(i,j) shared(jsta,jend,ista,iend,spval,snow_acm,arrayr42d,sm,fillValue) do j=jsta,jend @@ -1193,7 +1195,7 @@ subroutine set_postvars_fv3(wrt_int_state,grid_id,mype,mpicomp) enddo endif - !Snowfall bucket + !Snowfall bucket if(trim(fieldname)=='tsnowpb') then !$omp parallel do default(none) private(i,j) shared(jsta,jend,ista,iend,spval,snow_bkt,arrayr42d,sm,fillValue) do j=jsta,jend @@ -1204,7 +1206,7 @@ subroutine set_postvars_fv3(wrt_int_state,grid_id,mype,mpicomp) enddo endif - !Accumulated graupel + !Accumulated graupel if(trim(fieldname)=='frozr') then !$omp parallel do default(none) private(i,j) shared(jsta,jend,ista,iend,spval,acgraup,arrayr42d,sm,fillValue) do j=jsta,jend @@ -1215,7 +1217,7 @@ subroutine set_postvars_fv3(wrt_int_state,grid_id,mype,mpicomp) enddo endif - !Graupel bucket + !Graupel bucket if(trim(fieldname)=='frozrb') then !$omp parallel do default(none) private(i,j) shared(jsta,jend,ista,iend,spval,graup_bucket,arrayr42d,sm,fillValue) do j=jsta,jend @@ -1226,7 +1228,7 @@ subroutine set_postvars_fv3(wrt_int_state,grid_id,mype,mpicomp) enddo endif - !Accumulated freezing rain + !Accumulated freezing rain if(trim(fieldname)=='frzr') then !$omp parallel do default(none) private(i,j) shared(jsta,jend,ista,iend,spval,acfrain,arrayr42d,sm,fillValue) do j=jsta,jend @@ -1265,7 +1267,7 @@ subroutine set_postvars_fv3(wrt_int_state,grid_id,mype,mpicomp) do j=jsta,jend do i=ista, iend graupelnc(i,j) = arrayr42d(i,j) - if (abs(arrayr42d(i,j)-fillValue) < small) graupelnc(i,j) = spval + if (abs(arrayr42d(i,j)-fillValue) < small) graupelnc(i,j) = spval enddo enddo endif @@ -1589,7 +1591,7 @@ subroutine set_postvars_fv3(wrt_int_state,grid_id,mype,mpicomp) sllevel(7) = 1.0 sllevel(8) = 1.6 sllevel(9) = 3.0 - endif + endif ! liquid volumetric soil mpisture in fraction if(trim(fieldname)=='soill1') then @@ -2340,7 +2342,7 @@ subroutine set_postvars_fv3(wrt_int_state,grid_id,mype,mpicomp) endif !FV3R if(rdaod) then - ! MERRA2 aerosols + ! MERRA2 aerosols if(trim(fieldname)=='aod550') then !$omp parallel do default(none) private(i,j) shared(jsta,jend,ista,iend,spval,aod550,arrayr42d,fillValue) do j=jsta,jend @@ -2370,7 +2372,7 @@ subroutine set_postvars_fv3(wrt_int_state,grid_id,mype,mpicomp) enddo enddo endif - + if(trim(fieldname)=='su_aod550') then !$omp parallel do default(none) private(i,j) shared(jsta,jend,ista,iend,spval,su_aod550,arrayr42d,fillValue) do j=jsta,jend @@ -2434,24 +2436,24 @@ subroutine set_postvars_fv3(wrt_int_state,grid_id,mype,mpicomp) enddo enddo endif - enddo + enddo do K = 1, nbin_du if ( K == 1) VarName='dust1dp' if ( K == 2) VarName='dust2dp' - if ( K == 3) VarName='dust3dp' + if ( K == 3) VarName='dust3dp' if ( K == 4) VarName='dust4dp' - if ( K == 5) VarName='dust5dp' - + if ( K == 5) VarName='dust5dp' + if(trim(fieldname)==VarName) then !$omp parallel do default(none) private(i,j,K) shared(jsta,jend,ista,iend,spval,dudp,arrayr42d,fillvalue) do j=jsta,jend do i=ista, iend dudp(i,j,K) = arrayr42d(i,j) if( abs(arrayr42d(i,j)-fillValue) < small) dudp(i,j,K) = spval - enddo - enddo - endif + enddo + enddo + endif enddo do K = 1, nbin_du @@ -2478,16 +2480,16 @@ subroutine set_postvars_fv3(wrt_int_state,grid_id,mype,mpicomp) if ( K == 3) VarName='dust3wtc' if ( K == 4) VarName='dust4wtc' if ( K == 5) VarName='dust5wtc' - + if(trim(fieldname)==VarName) then !$omp parallel do default(none) private(i,j,K) shared(jsta,jend,ista,iend,spval,dusv,arrayr42d,fillvalue) do j=jsta,jend do i=ista, iend dusv(i,j,K) = arrayr42d(i,j) if( abs(arrayr42d(i,j)-fillValue) < small) dusv(i,j,K) = spval - enddo - enddo - endif + enddo + enddo + endif enddo do K = 1, nbin_ss @@ -4151,7 +4153,7 @@ subroutine set_postvars_fv3(wrt_int_state,grid_id,mype,mpicomp) enddo endif - else if (nasa_on) then + else if (nasa_on) then if(trim(fieldname)=='so4') then !$omp parallel do default(none) private(i,j,l) shared(lm,jsta,jend,ista,iend,suso,arrayr43d,fillvalue,spval) do l=1,lm @@ -4382,7 +4384,7 @@ subroutine set_postvars_fv3(wrt_int_state,grid_id,mype,mpicomp) ! print *,'in post_gfs,ths=',maxval(ths(1:im,jsta:jend)), & ! minval(ths(1:im,jsta:jend)) -! compute cwm and max qrain in the column to be used later in precip type computation +! compute cwm and max qrain in the column to be used later in precip type computation do j=jsta,jend do i=ista,iend qrmax(i,j)=0. @@ -4469,7 +4471,7 @@ subroutine set_postvars_fv3(wrt_int_state,grid_id,mype,mpicomp) do j=jsta,jend do i=ista, iend if(snacc_land(i,j)