diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 12cd28cc..f9a5d637 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,7 +43,7 @@ jobs: DEBUG: 0 FC: ${{ matrix.compiler }} - - name: Non-NetCDF comile and run + - name: Non-NetCDF compile and run run: | make clean make diff --git a/README.md b/README.md index 2ab11a84..9c7fd2d0 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ Current Canopy-App components: **Current Canopy-App Output:** Outputs 3D canopy winds, canopy vertical/eddy diffusivity values, and canopy photolysis attenuation correction factors, and 2D Wind Adjustment Factor (WAF). - Namelist Option : `file_out` Prefix string (e.g., 'test') used for output file name (Currently in both 1D txt or 2D NetCDF format (only when 2D NCF input is used, i.e., infmt_opt=0). + Namelist Option : `file_out` Prefix string (e.g., 'test') used for output file name (Currently 1D txt output with input 1D data, or 2D NetCDF output when 2D NCF input is used, i.e., infmt_opt=0). **Table 1. Canopy-App Required Input Variables** diff --git a/canopy_alloc.F90 b/canopy_alloc.F90 index f05916b0..05d3a74e 100644 --- a/canopy_alloc.F90 +++ b/canopy_alloc.F90 @@ -19,7 +19,7 @@ SUBROUTINE canopy_alloc !------------------------------------------------------------------------------- if(.not.allocated(variables)) allocate(variables(nlat*nlon)) - if(.not.allocated(variables_2d)) allocate(variables_2d(nlat,nlon)) + if(.not.allocated(variables_2d)) allocate(variables_2d(nlon,nlat)) !------------------------------------------------------------------------------- ! Allocate arrays for Internal Canopy Distribution Variables @@ -38,11 +38,11 @@ SUBROUTINE canopy_alloc if(.not.allocated(canBOT)) allocate(canBOT(modlays)) if(.not.allocated(canTOP)) allocate(canTOP(modlays)) if(.not.allocated(canWIND)) allocate(canWIND(nlat*nlon,modlays)) - if(.not.allocated(canWIND_3d)) allocate(canWIND_3d(nlat,nlon,modlays)) + if(.not.allocated(canWIND_3d)) allocate(canWIND_3d(nlon,nlat,modlays)) if(.not.allocated(dx)) allocate(dx(nlat*nlon)) - if(.not.allocated(dx_2d)) allocate(dx_2d(nlat,nlon)) + if(.not.allocated(dx_2d)) allocate(dx_2d(nlon,nlat)) if(.not.allocated(waf)) allocate(waf(nlat*nlon)) - if(.not.allocated(waf_2d)) allocate(waf_2d(nlat,nlon)) + if(.not.allocated(waf_2d)) allocate(waf_2d(nlon,nlat)) end if @@ -54,7 +54,7 @@ SUBROUTINE canopy_alloc write(*,*) 'Canopy eddy Kz option selected' write(*,*) '-------------------------------' if(.not.allocated(Kz)) allocate(Kz(nlat*nlon,modlays)) - if(.not.allocated(Kz_3d)) allocate(Kz_3d(nlat,nlon,modlays)) + if(.not.allocated(Kz_3d)) allocate(Kz_3d(nlon,nlat,modlays)) end if @@ -66,7 +66,7 @@ SUBROUTINE canopy_alloc write(*,*) 'Canopy photolysis option selected' write(*,*) '-------------------------------' if(.not.allocated(rjcf)) allocate(rjcf(nlat*nlon,modlays)) - if(.not.allocated(rjcf_3d)) allocate(rjcf_3d(nlat,nlon,modlays)) + if(.not.allocated(rjcf_3d)) allocate(rjcf_3d(nlon,nlat,modlays)) end if diff --git a/canopy_calcs.F90 b/canopy_calcs.F90 index a4e11648..0697cb42 100644 --- a/canopy_calcs.F90 +++ b/canopy_calcs.F90 @@ -47,8 +47,8 @@ SUBROUTINE canopy_calcs ! ... Main loop through model grid cells for 2D input/output - do j=1, nlon - do i=1, nlat + do i=1, nlon + do j=1, nlat hcmref = variables_2d(i,j)%fh ubzref = variables_2d(i,j)%ws @@ -128,7 +128,7 @@ SUBROUTINE canopy_calcs end if !Contiguous Canopy else - write(*,*) 'Warning VIIRS VTYPE ', vtyperef, ' is not supported...continue' +! write(*,*) 'Warning VIIRS VTYPE ', vtyperef, ' is not supported...continue' end if !Vegetation types else write(*,*) 'Wrong LU_OPT choice of ', lu_opt, ' in namelist...exiting' @@ -233,7 +233,7 @@ SUBROUTINE canopy_calcs end if !Contiguous Canopy else - write(*,*) 'Warning VIIRS VTYPE ', vtyperef, ' is not supported...continue' +! write(*,*) 'Warning VIIRS VTYPE ', vtyperef, ' is not supported...continue' end if !Vegetation types else write(*,*) 'Wrong LU_OPT choice of ', lu_opt, ' in namelist...exiting' @@ -339,7 +339,7 @@ SUBROUTINE canopy_calcs end if !Contiguous Canopy else - write(*,*) 'Warning VIIRS VTYPE ', vtyperef, ' is not supported...continue' +! write(*,*) 'Warning VIIRS VTYPE ', vtyperef, ' is not supported...continue' end if !Vegetation types else write(*,*) 'Wrong LU_OPT choice of ', lu_opt, ' in namelist...exiting' diff --git a/canopy_canopts_mod.F90 b/canopy_canopts_mod.F90 index 038c9fdf..40d2d0bd 100644 --- a/canopy_canopts_mod.F90 +++ b/canopy_canopts_mod.F90 @@ -8,7 +8,7 @@ MODULE canopy_canopts_mod use canopy_const_mod, ONLY: rk IMPLICIT NONE -!! .... defines canopy optionss (read from user namelist) +!! .... defines canopy options (read from user namelist) integer :: infmt_opt !Integer for choosing 1D or 2D input file format (default = 0, 2D) integer :: href_opt !Integer for using set href in namelist (=0) or array from file(=1) (default = 0) real(rk) :: href_set !Set reference Height above canopy @ 10 m (m) diff --git a/canopy_const_mod.F90 b/canopy_const_mod.F90 index 458d1649..571132d1 100644 --- a/canopy_const_mod.F90 +++ b/canopy_const_mod.F90 @@ -15,7 +15,7 @@ MODULE canopy_const_mod ! Cambridge Univ. Press, 206 pp, 1995. ! Snyder, J.P., "Map Projections-A Working Manual, U.S. Geological Survey ! Paper 1395 U.S.GPO, Washington, DC, 1987. -! Stull, R. B., "An Introduction to Bounday Layer Meteorology", Kluwer, +! Stull, R. B., "An Introduction to Boundary Layer Meteorology", Kluwer, ! Dordrecht, 1988 !------------------------------------------------------------------------------- diff --git a/canopy_dxcalc_mod.F90 b/canopy_dxcalc_mod.F90 index 3b2a474d..d724a8b3 100644 --- a/canopy_dxcalc_mod.F90 +++ b/canopy_dxcalc_mod.F90 @@ -96,17 +96,17 @@ SUBROUTINE CANOPY_CALCDX_2D(DXOPT, DXSET, NLAT, NLON, LAT, LON, DX ) ! Local variables integer :: i,j ! NLON,NLAT - do j=1, NLON - do i=1, NLAT + do i=1, NLON + do j=1, NLAT if (DXOPT .eq. 0) then !user set to calculate dx grid cell distance from grid lons if (NLON .gt. 1) then !convert grid points to distances using Haversine formula (m) - if (i .lt. NLAT ) then !inside LON inside domain + if (i .lt. NLON ) then !inside LON inside domain DX(i,j) = CalcDX(LAT(i,j), abs(LON(i+1,j) - LON(i,j))) - else if (i .eq. NLAT ) then !at the domain edge --set to NLAT-1 - DX(i,j) = DX(NLAT-1,j) - else if (j .eq. NLON ) then !at the domain edge --set to NLON-1 - DX(i,j) = DX(i,NLON-1) + else if (i .eq. NLON ) then !at the domain edge --set to NLON-1 + DX(i,j) = DX(NLON-1,j) + else if (j .eq. NLAT ) then !at the domain edge --set to NLAT-1 + DX(i,j) = DX(i,NLAT-1) end if else !single grid cell/point, use namelist defined dx resolution (m) for cell write(*,*) 'DX_OPT_2D set to calc, but nlon or nlat <= 1...setting dx = ', & diff --git a/canopy_eddy_mod.F90 b/canopy_eddy_mod.F90 index fd594b36..090bf95e 100644 --- a/canopy_eddy_mod.F90 +++ b/canopy_eddy_mod.F90 @@ -38,7 +38,7 @@ SUBROUTINE CANOPY_EDDYX( HCM, ZK, USTAR, MOL, KZ ) real(rk) :: rr ! sigma parameter R (Makar et al., 2017) real(rk) :: aa ! sigma parameter A (Makar et al., 2017) real(rk) :: bb ! sigma parameter B (Makar et al., 2017) - real(rk) :: sigma ! eulerian vertial velocity (m/s) + real(rk) :: sigma ! eulerian vertical velocity (m/s) ! Citation: !Makar, P., Staebler, R., Akingunola, A. et al. The effects of forest canopy shading and turbulence on boundary layer ozone. diff --git a/canopy_ncf_io_mod.F90 b/canopy_ncf_io_mod.F90 index 9f8ffa23..eb33b8f6 100644 --- a/canopy_ncf_io_mod.F90 +++ b/canopy_ncf_io_mod.F90 @@ -131,8 +131,8 @@ SUBROUTINE get_var_2d_real_cdf (cdfid, var, dum2d, it, rcode) INTEGER, INTENT(OUT) :: rcode CHARACTER(LEN=*), INTENT(IN) :: var - nx = SIZE(dum2d,2) - ny = SIZE(dum2d,1) + nx = SIZE(dum2d,1) + ny = SIZE(dum2d,2) rcode = nf90_inq_varid (cdfid, var, id_data) IF ( rcode /= nf90_noerr ) then @@ -164,8 +164,8 @@ SUBROUTINE get_var_2d_int_cdf (cdfid, var, idum2d, it, rcode) INTEGER, INTENT(OUT) :: rcode CHARACTER(LEN=*), INTENT(IN) :: var - nx = SIZE(idum2d,2) - ny = SIZE(idum2d,1) + nx = SIZE(idum2d,1) + ny = SIZE(idum2d,2) rcode = nf90_inq_varid (cdfid, var, id_data) IF ( rcode /= nf90_noerr ) RETURN @@ -1321,9 +1321,14 @@ SUBROUTINE canopy_write_ncf (OUTPREFX) ! Write variables. !------------------------------------------------------------------------------- + write(*,*) 'Writing NetCDF Output' + write(*,*) '-------------------------------' + !------------------------------------------------------------------------------- ! Time-independent 2d fields at cell centers. !------------------------------------------------------------------------------- + write(*,*) 'Writing Time-independent 2d fields' + write(*,*) '-------------------------------' DO n = 1, nfld2dxy var = TRIM(fld2dxy(n)%fldname) @@ -1340,6 +1345,8 @@ SUBROUTINE canopy_write_ncf (OUTPREFX) !------------------------------------------------------------------------------- ! Time-varying 2d fields at cell centers. !------------------------------------------------------------------------------- + write(*,*) 'Writing Time-varying 2d fields' + write(*,*) '-------------------------------' DO n = 1, nfld2dxyt nn = ntot + n @@ -1357,8 +1364,10 @@ SUBROUTINE canopy_write_ncf (OUTPREFX) ntot = ntot + nfld2dxyt !------------------------------------------------------------------------------- - ! Time-independent 3d fields at cell centers. + ! Time-varying 3d fields at cell centers. !------------------------------------------------------------------------------- + write(*,*) 'Writing Time-varying 3d fields' + write(*,*) '-------------------------------' DO n = 1, nfld3dxyzt nn = ntot + n diff --git a/canopy_profile_mod.F90 b/canopy_profile_mod.F90 index cd5c83d9..f78b4717 100644 --- a/canopy_profile_mod.F90 +++ b/canopy_profile_mod.F90 @@ -247,8 +247,8 @@ SUBROUTINE CANOPY_ZPD( ZHC, FCLAI, UBZREF, Z0GHC, & real(rk) :: qstar ! Total Reynolds stress term real(rk) :: fafraczInt_tota ! Numerator term of term B for d/h (Eq. 15 Massman et al.) real(rk) :: fafraczInt_totb ! Denominator term of term B for d/h (Eq. 15 Massman et al.) - real(rk) :: cstress ! Suface stress at/above canopy height (nondimensional) - real(rk) :: drag ! Drag area index (i.e., wind speed attentuation) (nondimensional) + real(rk) :: cstress ! Surface stress at/above canopy height (nondimensional) + real(rk) :: drag ! Drag area index (i.e., wind speed attenuation) (nondimensional) real(rk) :: nrat ! Ratio of drag/cstress (nondimensional) real(rk) :: z0_set ! set roughness length (m) real(rk) :: uc ! initial guess of wind speed at canopy height (m/s) from log-profile @@ -294,7 +294,7 @@ SUBROUTINE CANOPY_ZPD( ZHC, FCLAI, UBZREF, Z0GHC, & uc = UBZREF end if - !Solve for final z0 and zpd esimates: + !Solve for final z0 and zpd estimates: ustrmod = uc*(0.38 - (0.38 + (vonk/log(Z0GHC)))*exp(-1.0*(15.0*drag))) cstress = (2.0*(ustrmod**2.0))/(uc**2.0) nrat = drag/cstress diff --git a/canopy_txt_io_mod.F90 b/canopy_txt_io_mod.F90 index efeed0cb..498a164b 100644 --- a/canopy_txt_io_mod.F90 +++ b/canopy_txt_io_mod.F90 @@ -52,66 +52,72 @@ SUBROUTINE write_txt(TXTPREFX) !Local variables integer k, loc - if (ifcanwind) then - write(*,*) 'Writing canopy wind output' + if (infmt_opt .eq. 1) then !only output text with 1D input + + write(*,*) 'Writing Text Output' write(*,*) '-------------------------------' + + if (ifcanwind) then + write(*,*) 'Writing canopy wind output' + write(*,*) '-------------------------------' ! ... save as text file - open(10, file=TRIM(TXTPREFX)//'_output_canopy_wind.txt') - write(10, '(a30, f6.1, a2)') 'Reference height, h: ', href_set, 'm' - write(10, '(a30, i6)') 'Number of model layers: ', modlays - write(10, '(a8, a9, a12, a15)') 'Lat', 'Lon', 'Height (m)', 'WS (m/s)' - do loc=1, nlat*nlon - do k=1, modlays - write(10, '(f8.2, f9.2, f12.2, es15.7)') variables(loc)%lat, variables(loc)%lon, & - zk(k), canWIND(loc, k) + open(10, file=TRIM(TXTPREFX)//'_output_canopy_wind.txt') + write(10, '(a30, f6.1, a2)') 'Reference height, h: ', href_set, 'm' + write(10, '(a30, i6)') 'Number of model layers: ', modlays + write(10, '(a8, a9, a12, a15)') 'Lat', 'Lon', 'Height (m)', 'WS (m/s)' + do loc=1, nlat*nlon + do k=1, modlays + write(10, '(f8.2, f9.2, f12.2, es15.7)') variables(loc)%lat, variables(loc)%lon, & + zk(k), canWIND(loc, k) + end do end do - end do - end if + end if ! ... save as text file - if (ifcanwaf) then - write(*,*) 'Writing canopy WAF output' - write(*,*) '-------------------------------' - open(11, file=TRIM(TXTPREFX)//'_output_waf.txt') - write(11, '(a30, f6.1)') 'Reference height, h: ', href_set, 'm' - write(11, '(a8, a9, a19, a11)') 'Lat', 'Lon', 'Canopy height (m)', 'WAF' - do loc=1, nlat*nlon - write(11, '(f8.2, f9.2, f19.2, es15.7)') variables(loc)%lat, variables(loc)%lon, hcmref, waf(loc) - end do - end if + if (ifcanwaf) then + write(*,*) 'Writing canopy WAF output' + write(*,*) '-------------------------------' + open(11, file=TRIM(TXTPREFX)//'_output_waf.txt') + write(11, '(a30, f6.1)') 'Reference height, h: ', href_set, 'm' + write(11, '(a8, a9, a19, a11)') 'Lat', 'Lon', 'Canopy height (m)', 'WAF' + do loc=1, nlat*nlon + write(11, '(f8.2, f9.2, f19.2, es15.7)') variables(loc)%lat, variables(loc)%lon, hcmref, waf(loc) + end do + end if - if (ifcaneddy) then - write(*,*) 'Writing canopy eddy diffusivity scaling values' - write(*,*) '-------------------------------' + if (ifcaneddy) then + write(*,*) 'Writing canopy eddy diffusivity scaling values' + write(*,*) '-------------------------------' ! ... save as text file - open(12, file=TRIM(TXTPREFX)//'_output_eddy_Kz.txt') - write(12, '(a30, f6.1, a2)') 'Reference height, h: ', href_set, 'm' - write(12, '(a30, i6)') 'Number of model layers: ', modlays - write(12, '(a8, a9, a12, a15)') 'Lat', 'Lon', 'Height (m)', 'Kz' - do loc=1, nlat*nlon - do k=1, modlays - write(12, '(f8.2, f9.2, f12.2, es15.7)') variables(loc)%lat, variables(loc)%lon, & - zk(k), Kz(loc,k) + open(12, file=TRIM(TXTPREFX)//'_output_eddy_Kz.txt') + write(12, '(a30, f6.1, a2)') 'Reference height, h: ', href_set, 'm' + write(12, '(a30, i6)') 'Number of model layers: ', modlays + write(12, '(a8, a9, a12, a15)') 'Lat', 'Lon', 'Height (m)', 'Kz' + do loc=1, nlat*nlon + do k=1, modlays + write(12, '(f8.2, f9.2, f12.2, es15.7)') variables(loc)%lat, variables(loc)%lon, & + zk(k), Kz(loc,k) + end do end do - end do - end if + end if - if (ifcanphot) then - write(*,*) 'Writing canopy photolysis correction factors' - write(*,*) '-------------------------------' + if (ifcanphot) then + write(*,*) 'Writing canopy photolysis correction factors' + write(*,*) '-------------------------------' ! ... save as text file - open(13, file=TRIM(TXTPREFX)//'_output_phot.txt') - write(13, '(a30, f6.1, a2)') 'Reference height, h: ', href_set, 'm' - write(13, '(a30, i6)') 'Number of model layers: ', modlays - write(13, '(a8, a9, a12, a15)') 'Lat', 'Lon', 'Height (m)', 'rjcf' - do loc=1, nlat*nlon - do k=1, modlays - write(13, '(f8.2, f9.2, f12.2, es15.7)') variables(loc)%lat, variables(loc)%lon, & - zk(k), rjcf(loc,k) + open(13, file=TRIM(TXTPREFX)//'_output_phot.txt') + write(13, '(a30, f6.1, a2)') 'Reference height, h: ', href_set, 'm' + write(13, '(a30, i6)') 'Number of model layers: ', modlays + write(13, '(a8, a9, a12, a15)') 'Lat', 'Lon', 'Height (m)', 'rjcf' + do loc=1, nlat*nlon + do k=1, modlays + write(13, '(f8.2, f9.2, f12.2, es15.7)') variables(loc)%lat, variables(loc)%lon, & + zk(k), rjcf(loc,k) + end do end do - end do - end if + end if + end if END SUBROUTINE write_txt !------------------------------------------------------------------------------- diff --git a/canopy_waf_mod.F90 b/canopy_waf_mod.F90 index 7574484b..f282be41 100644 --- a/canopy_waf_mod.F90 +++ b/canopy_waf_mod.F90 @@ -53,7 +53,7 @@ SUBROUTINE CANOPY_FLAMEH( FLAMEH_OPT, FLAMEH_SET, DX, MODRES, & write(*,*) 'Wrong FLAMEH_OPT choice of ', FLAMEH_OPT, ' in namelist...exiting' call exit(2) end if - if (FLAMEH .le. MODRES) then !flameh beween first (z=0) and second layer height + if (FLAMEH .le. MODRES) then !flameh between first (z=0) and second layer height MIDFLAMEPOINT = 2 !do not put at z = 0, but rather in second layer else flamelays = floor(FLAMEH/MODRES) + 1 !force full flame layers @@ -100,7 +100,7 @@ SUBROUTINE CANOPY_WAF( HCM, LAMDARS, RSL_OPT, HREF, FLAMEH, FIRETYPE, & ! Local variables real(rk) :: term1 ! Major Term1 in WAF calculation (Eqs. 17 and 18 Massman et al. 2017) real(rk) :: term2 ! Major Term2 in WAF calculation (Eqs. 17 and 18 Massman et al. 2017) - real(rk) :: delta ! Ratio parmeter used in WAF for above-canopy (Eq. 18 Massman et al.) + real(rk) :: delta ! Ratio parameter used in WAF for above-canopy (Eq. 18 Massman et al.) real(rk) :: lamda_rs ! local values for influence of roughness sublayer (nondimensional) ! Citation: diff --git a/canopy_wind_mod.F90 b/canopy_wind_mod.F90 index 81ec304a..421afce0 100644 --- a/canopy_wind_mod.F90 +++ b/canopy_wind_mod.F90 @@ -36,7 +36,7 @@ SUBROUTINE CANOPY_WIND( HCM, ZK, FAFRACK, UBZREF, Z0GHC, & REAL(RK), INTENT( IN ) :: Z0GHC ! Ratio of ground roughness length to canopy top height (nondimensional) REAL(RK), INTENT( IN ) :: CDRAG ! Drag coefficient (nondimensional) REAL(RK), INTENT( IN ) :: PAI ! Total plant/foliage area index (nondimensional) - REAL(RK), INTENT( IN ) :: HREF ! Reference Height above canopy asssociated with ref wind speed (m) + REAL(RK), INTENT( IN ) :: HREF ! Reference Height above canopy associated with ref wind speed (m) REAL(RK), INTENT( IN ) :: D_H ! Zero plane displacement heights (nondimensional) REAL(RK), INTENT( IN ) :: ZO_H ! Surface (soil+veg) roughness lengths (nondimensional) REAL(RK), INTENT( IN ) :: MOL ! Model input Monin-Obukhov Length @@ -48,8 +48,8 @@ SUBROUTINE CANOPY_WIND( HCM, ZK, FAFRACK, UBZREF, Z0GHC, & real(rk) :: ustrmod ! Friction Velocity parameterization based on Massman 2017 (m/s) real(rk) :: z0g ! Ground roughness length based on z0g/HCCM ratio (m) real(rk) :: zkhcm ! Current zk/hcm ratio (nondimensional) - real(rk) :: cstress ! Suface stress at/above canopy height (nondimensional) - real(rk) :: drag ! Drag area index (i.e., wind speed attentuation) (nondimensional) + real(rk) :: cstress ! Surface stress at/above canopy height (nondimensional) + real(rk) :: drag ! Drag area index (i.e., wind speed attenuation) (nondimensional) real(rk) :: nrat ! Ratio of drag/cstress (nondimensional) real(rk) :: canbot ! Logarithmic wind speed that is dominant near the ground (nondimensional) real(rk) :: cantop ! Hyperbolic cosine wind speed that is dominant near the top of canopy (nondimensional) @@ -78,12 +78,12 @@ SUBROUTINE CANOPY_WIND( HCM, ZK, FAFRACK, UBZREF, Z0GHC, & CANBOT_OUT = canbot ! Nondimensional canopy wind speed term that dominates near the top of the canopy: ! Assume the drag area distribution over depth of canopy can be approx. p1=0 (no shelter factor) and d1=0 - ! (no drag coefficient relation to wind speed) -- thus no intergration then required in Eq. (4) of Massman et al. + ! (no drag coefficient relation to wind speed) -- thus no integration then required in Eq. (4) of Massman et al. drag = CDRAG*PAI !first adjust reference wind down to canopy top wind using MOST (with no RSL effects) zpd = D_H*HCM !zero-plane displacement height (not scaled to HCM) - z0m = ZO_H*HCM !aerodynamic roughness lengh (not scaled to HCM) + z0m = ZO_H*HCM !aerodynamic roughness length (not scaled to HCM) if((HCM-zpd) <= 0.) then write(*,*) "critical problem: hcan <= zpd" call exit(1)