@@ -25,6 +25,7 @@ module AbcModule
2525  use  SensHeatModule, only: ShfType, shf_cr
2626  use  ShortwaveModule, only: SwrType, swr_cr
2727  use  LatHeatModule, only: LhfType, lhf_cr
28+   use  LongwaveModule, only: LwrType, lwr_cr
2829  ! use BndModule, only: BndType, AddBndToList, GetBndFromList
2930  ! use TspAptModule, only: TspAptType
3031  use  ObserveModule
@@ -59,32 +60,41 @@ module AbcModule
5960    ! type(TableType), pointer :: inputtab => null() !< input table object
6061
6162    logical , pointer , public  ::  shf_active = > null () ! < logical indicating if a sensible heat flux object is active
62-     logical , pointer , public  ::  swr_active = > null () ! < logical indicating if a shortwave radition  heat flux object is active
63+     logical , pointer , public  ::  swr_active = > null () ! < logical indicating if a shortwave radiation  heat flux object is active
6364    logical , pointer , public  ::  lhf_active = > null () ! < logical indicating if a latent heat flux object is active
65+     logical , pointer , public  ::  lwr_active = > null () ! < logical indicating if a longwave radiation heat flux object is active
6466
67+     
6568    type (ShfType), pointer  ::  shf = > null () !  sensible heat flux (shf) object
6669    type (SwrType), pointer  ::  swr = > null () !  shortwave radiation heat flux (swr) object
6770    type (LhfType), pointer  ::  lhf = > null () !  latent heat flux (lhf) object
71+     type (LwrType), pointer  ::  lwr = > null () !  longwave radiation heat flux (lwr) object
72+     
6873    !  -- abc budget object
6974    type (BudgetObjectType), pointer  ::  budobj = > null () ! < ABC budget object
7075
7176    integer (I4B), pointer  ::  inshf = > null () !  SHF (sensible heat flux utility) unit number (0 if unused)
7277    integer (I4B), pointer  ::  inswr = > null () !  SWR (shortwave radiation heat flux utility) unit number (0 if unused)
7378    integer (I4B), pointer  ::  inlhf = > null () !  LHF (latent heat flux utility) unit number (0 if unused)
79+     integer (I4B), pointer  ::  inlwr = > null () !  LWR (longwave radiation heat flux utility) unit number (0 if unused)
7480
7581    real (DP), pointer  ::  rhoa = > null () ! < desity of air
7682    real (DP), pointer  ::  cpa = > null () ! < heat capacity of air
7783    real (DP), pointer  ::  cd = > null () ! < drag coefficient
7884    real (DP), pointer  ::  wfslope = > null () ! < wind function slope
7985    real (DP), pointer  ::  wfint = > null () ! < wind function intercept
86+     real (DP), pointer  ::  lwrefl = > null () ! < reflectance of longwave radiation by the water surface
87+     real (DP), pointer  ::  emissw = > null () ! < emissivity of water
88+     real (DP), pointer  ::  emissr = > null () ! < emissivity of the riparian canopy
8089
8190    real (DP), dimension (:), pointer , contiguous ::  wspd = > null () ! < wind speed
8291    real (DP), dimension (:), pointer , contiguous ::  tatm = > null () ! < temperature of the atmosphere
8392    real (DP), dimension (:), pointer , contiguous ::  solr = > null () ! < solar radiation
8493    real (DP), dimension (:), pointer , contiguous ::  shd = > null () ! < shade fraction
8594    real (DP), dimension (:), pointer , contiguous ::  swrefl = > null () ! < shortwave reflectance of water surface
8695    real (DP), dimension (:), pointer , contiguous ::  rh = > null () ! < relative humidity
87-     
96+     real (DP), dimension (:), pointer , contiguous ::  atmc = > null () ! < atmospheric composition adjustment
97+ 
8898  contains 
8999
90100    procedure  ::  da = > abc_da
@@ -103,6 +113,7 @@ module AbcModule
103113    procedure , private  ::  abc_shf_term
104114    procedure , private  ::  abc_swr_term
105115    procedure , private  ::  abc_lhf_term
116+     procedure , private  ::  abc_lwr_term
106117    !  -- budget
107118    ! procedure, private :: abc_setup_shfobj
108119    ! procedure, private :: abc_setup_swrobj
@@ -146,6 +157,7 @@ subroutine abc_cr(abc, name_model, inunit, iout, fname, ncv, gwecommon)
146157    call  shf_cr(abc% shf, name_model, inunit, iout, ncv)
147158    call  swr_cr(abc% swr, name_model, inunit, iout, ncv)
148159    call  lhf_cr(abc% lhf, name_model, inunit, iout, ncv)
160+     call  lwr_cr(abc% lwr, name_model, inunit, iout, ncv) 
149161    ! 
150162    !  -- Create time series manager
151163    call  tsmanager_cr(abc% tsmanager, abc% iout, &
@@ -180,6 +192,10 @@ subroutine ar(this)
180192    if  (this% inlhf) then 
181193      call  this% lhf% ar_set_pointers()
182194    end if 
195+     !  -- Set pointers to LWR package variables
196+     if  (this% inlwr) then 
197+       call  this% lwr% ar_set_pointers()
198+     end if 
183199    ! 
184200    !  -- Allocate arrays
185201    ! call this%pbst_allocate_arrays()
@@ -374,6 +390,39 @@ subroutine abc_read_options(this, option, found)
374390        write  (this% iout, ' (4x,a,1pg15.6)'  ) &
375391          " The evaporation wind function intercept has been set to: "  , this% wfint
376392      end if 
393+     case  (' LONGWAVE_REFLECTANCE'  )
394+       this% lwrefl =  this% parser% GetDouble()
395+       if  (this% lwrefl <=  0.0 ) then 
396+         write  (errmsg, ' (a)'  ) ' Specified value for the reflectance of longwave radiation &
397+           &must be greater than 0.0.'  
398+         call  store_error(errmsg)
399+         call  this% parser% StoreErrorUnit()
400+       else 
401+         write  (this% iout, ' (4x,a,1pg15.6)'  ) &
402+           " The reflectance of longwave radiation has been set to: "  , this% lwrefl
403+       end if 
404+     case  (' EMISSIVITY_WATER'  )
405+       this% emissw =  this% parser% GetDouble()
406+       if  (this% emissw <=  0.0 ) then 
407+         write  (errmsg, ' (a)'  ) ' Specified value for the emissivity of water &
408+           &must be greater than 0.0.'  
409+         call  store_error(errmsg)
410+         call  this% parser% StoreErrorUnit()
411+       else 
412+         write  (this% iout, ' (4x,a,1pg15.6)'  ) &
413+           " The emissivity of water has been set to: "  , this% emissw
414+       end if 
415+     case  (' EMISSIVITY_CANOPY'  )
416+       this% emissr =  this% parser% GetDouble()
417+       if  (this% emissr <=  0.0 ) then 
418+         write  (errmsg, ' (a)'  ) ' Specified value for the emissivity of the riparian canopy &
419+           &must be greater than 0.0.'  
420+         call  store_error(errmsg)
421+         call  this% parser% StoreErrorUnit()
422+       else 
423+         write  (this% iout, ' (4x,a,1pg15.6)'  ) &
424+           " The emissivity of the riparian canopy has been set to: "  , this% emissw
425+       end if 
377426    case default 
378427      write  (errmsg, ' (a,a)'  ) ' Unknown ABC option: '  , trim (option)
379428      call  store_error(errmsg)
@@ -402,17 +451,23 @@ subroutine abc_allocate_scalars(this)
402451    call  mem_allocate(this% shf_active, ' SHF_ACTIVE'  , this% memoryPath)
403452    call  mem_allocate(this% swr_active, ' SWR_ACTIVE'  , this% memoryPath)
404453    call  mem_allocate(this% lhf_active, ' LHF_ACTIVE'  , this% memoryPath)
454+     call  mem_allocate(this% lwr_active, ' LWR_ACTIVE'  , this% memoryPath)
405455
406456    call  mem_allocate(this% inshf, ' INSHF'  , this% memoryPath)
407457    call  mem_allocate(this% inswr, ' INSWR'  , this% memoryPath)
408458    call  mem_allocate(this% inlhf, ' INLHF'  , this% memoryPath)
459+     call  mem_allocate(this% inlwr, ' INLWR'  , this% memoryPath)
409460    !  -- allocate SHF specific
410461    call  mem_allocate(this% rhoa, ' RHOA'  , this% memoryPath)
411462    call  mem_allocate(this% cpa, ' CPA'  , this% memoryPath)
412463    call  mem_allocate(this% cd, ' CD'  , this% memoryPath)
413464    !  -- allocate LHF specific
414465    call  mem_allocate(this% wfslope, ' WFSLOPE'  , this% memoryPath)
415466    call  mem_allocate(this% wfint, ' WFINT'  , this% memoryPath)
467+     !  -- allocate LWR specific
468+     call  mem_allocate(this% lwrefl, ' LWREFL'  , this% memoryPath)
469+     call  mem_allocate(this% emissw, ' EMISSW'  , this% memoryPath)
470+     call  mem_allocate(this% emissr, ' EMISSR'  , this% memoryPath)
416471    ! 
417472    !  -- initialize to default values
418473    this% shf_active =  .false. 
@@ -428,6 +483,10 @@ subroutine abc_allocate_scalars(this)
428483    !  -- initalize to LHF specific default values
429484    this% wfslope =  1.383e-01  !  1/mbar Fogg 2023 (change!)
430485    this% wfint =  3.445e-09  !  m/s Fogg 2023 (change!)
486+     !  -- initalize to LWR specific default values
487+     this% lwrefl =  0.03  !  unitless (Anderson, 1954)
488+     this% emissw =  0.95  !  unitless (Dingman, 2015)
489+     this% emissr =  0.97  !  unitless (Sobrino et al, 2005)
431490    ! 
432491    !  -- call standard NumericalPackageType allocate scalars
433492    call  this% BndType% allocate_scalars()
@@ -512,7 +571,40 @@ subroutine abc_allocate_arrays(this)
512571       end do 
513572       call  this% lhf% ar()
514573    end if 
515-     
574+     if  (this% inlwr /=  0 ) then 
575+        call  get_mem_type(' TATM'  , this% memoryPath, var_type)
576+        if  (var_type == ' UNKNOWN'  ) then 
577+          call  mem_allocate(this% tatm, this% ncv, ' TATM'  , this% memoryPath)
578+          do  n =  1 , this% ncv
579+            this% tatm(n) =  DZERO
580+          end do 
581+        end if 
582+        call  mem_allocate(this% rh, this% ncv, ' RH'  , this% memoryPath)
583+        if  (var_type == ' UNKNOWN'  ) then 
584+          call  mem_allocate(this% rh, this% ncv, ' RH'  , this% memoryPath)
585+          do  n =  1 , this% ncv
586+            this% rh(n) =  DZERO
587+          end do 
588+        end if 
589+        call  mem_allocate(this% shd, this% ncv, ' SHD'  , this% memoryPath)
590+        if  (var_type == ' UNKNOWN'  ) then 
591+          call  mem_allocate(this% shd, this% ncv, ' SHD'  , this% memoryPath)
592+          do  n =  1 , this% ncv
593+            this% shd(n) =  DZERO
594+          end do 
595+        end if 
596+        call  mem_allocate(this% atmc, this% ncv, ' ATMC'  , this% memoryPath)
597+        ! 
598+        !  -- initialize
599+        do  n =  1 , this% ncv
600+          this% tatm(n) =  DZERO
601+          this% rh(n) =  DZERO
602+          this% shd(n) =  DZERO
603+          this% atmc(n) =  DZERO
604+        end do 
605+        call  this% lwr% ar()
606+     end if 
607+    
516608    ! ! -- allocate character array for status
517609    ! allocate (this%status(this%ncv))
518610    ! !
@@ -545,20 +637,30 @@ subroutine abc_da(this)
545637      call  this% lhf% da()
546638      deallocate (this% lhf)
547639    end if 
640+     !  -- LWR (longwave radiation heat flux)
641+     if  (this% inlwr /=  0 ) then 
642+       call  this% lwr% da()
643+       deallocate (this% lwr)
644+     end if 
548645    ! 
549646    !  -- Deallocate scalars
550647    call  mem_deallocate(this% ncv)
551648    call  mem_deallocate(this% shf_active)
552649    call  mem_deallocate(this% swr_active)
553650    call  mem_deallocate(this% lhf_active)
651+     call  mem_deallocate(this% lwr_active)
554652    call  mem_deallocate(this% inshf)
555653    call  mem_deallocate(this% inswr)
556654    call  mem_deallocate(this% inlhf)
655+     call  mem_deallocate(this% inlwr)
557656    call  mem_deallocate(this% rhoa)
558657    call  mem_deallocate(this% cpa)
559658    call  mem_deallocate(this% cd)
560659    call  mem_deallocate(this% wfslope)
561660    call  mem_deallocate(this% wfint)
661+     call  mem_deallocate(this% lwrefl)
662+     call  mem_deallocate(this% emissw)
663+     call  mem_deallocate(this% emissr)
562664    ! 
563665    !  -- Deallocate time series manager
564666    deallocate (this% tsmanager)
@@ -572,6 +674,7 @@ subroutine abc_da(this)
572674    call  mem_deallocate(this% swrefl)
573675    call  mem_deallocate(this% solr)
574676    call  mem_deallocate(this% rh)
677+     call  mem_deallocate(this% atmc)
575678    ! 
576679    !  -- Deallocate scalars in TspAptType
577680    call  this% NumericalPackageType% da() !  this may not work -- revisit and cleanup !!!
@@ -580,7 +683,7 @@ subroutine abc_da(this)
580683    ! call pbstbase_da(this)
581684  end  subroutine  abc_da 
582685
583-     ! > @brief Read a ABC-specific option from the OPTIONS block
686+   ! > @brief Read a ABC-specific option from the OPTIONS block
584687  ! !
585688  ! ! Process a single ABC-specific option. Used when reading the OPTIONS block
586689  ! ! of the ABC package input file.
@@ -675,7 +778,24 @@ subroutine abc_lhf_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
675778    ! 
676779  end  subroutine  abc_lhf_term 
677780
678-    ! > @brief Observations
781+   subroutine  abc_lwr_term (this , ientry , n1 , n2 , rrate , rhsval , hcofval )
782+     !  -- dummy
783+     class(AbcType) ::  this
784+     integer (I4B), intent (in ) ::  ientry
785+     integer (I4B), intent (inout ) ::  n1
786+     integer (I4B), intent (inout ) ::  n2
787+     real (DP), intent (inout ), optional  ::  rrate
788+     real (DP), intent (inout ), optional  ::  rhsval
789+     real (DP), intent (inout ), optional  ::  hcofval
790+     !  -- local
791+     real (DP) ::  longwvheat
792+     real (DP) ::  strmtemp
793+     integer (I4B) ::  auxpos
794+     real (DP) ::  sa ! < surface area of stream reach, different than wetted area
795+     ! 
796+   end  subroutine  abc_lwr_term 
797+   
798+   ! > @brief Observations
679799  ! !
680800  ! ! Store the observation type supported by the APT package and override
681801  ! ! BndType%bnd_df_obs
@@ -716,6 +836,8 @@ subroutine abc_rp_obs(this, obsrv, found)
716836    case  (' SWR'  )
717837!       call this%rp_obs_byfeature(obsrv)
718838    case  (' LHF'  )
839+ !       call this%rp_obs_byfeature(obsrv)
840+     case  (' LWR'  )
719841!       call this%rp_obs_byfeature(obsrv)
720842    case default 
721843      found =  .false. 
@@ -763,6 +885,7 @@ subroutine abc_cq(this, ifno, tstrm, abcflx)
763885    real (DP) ::  shflx
764886    real (DP) ::  swrflx
765887    real (DP) ::  lhflx
888+     real (DP) ::  lwrflx
766889    ! 
767890    !  -- calculate sensible heat flux using HGS equation
768891    call  this% shf% shf_cq(ifno, tstrm, shflx)
@@ -772,8 +895,11 @@ subroutine abc_cq(this, ifno, tstrm, abcflx)
772895    ! 
773896    !  -- calculate latent heat flux using Dalton-like mass transfer equation
774897    call  this% lhf% lhf_cq(ifno, tstrm, this% gwecommon% gwerhow, lhflx)
898+     ! 
899+     !  -- calculate longwave radiation
900+     call  this% lwr% lwr_cq(ifno, tstrm, lwrflx)
775901
776-     abcflx =  shflx +  swrflx -  lhflx
902+     abcflx =  shflx +  swrflx -  lhflx  +  lwrflx 
777903  end  subroutine  abc_cq 
778904
779905  ! > @brief Set the stress period attributes based on the keyword
@@ -799,6 +925,7 @@ subroutine abc_set_stressperiod(this, itemno) !, keyword, found) MAKING LIKE PBS
799925    !  <shd> SHADE
800926    !  <swrefl> REFLECTANCE OF SHORTWAVE RADIATION OFF WATER SURFACE
801927    !  <solr> SOLAR RADIATION
928+     !  <atmc> ATMOSPHERIC COMPOSITION 
802929    ! 
803930    !  -- read line
804931    call  this% parser% GetStringCaps(keyword)
@@ -887,6 +1014,17 @@ subroutine abc_set_stressperiod(this, itemno) !, keyword, found) MAKING LIKE PBS
8871014      call  read_value_or_time_series_adv(text, itemno, jj, bndElem, &
8881015                                         this% packName, ' BND'  , this% tsManager, &
8891016                                         this% iprpak, ' RH'  )
1017+     case  (' ATMC'  )
1018+       ierr =  this% abc_check_valid(itemno)
1019+       if  (ierr /=  0 ) then 
1020+         goto  999 
1021+       end if 
1022+       call  this% parser% GetString(text)
1023+       jj =  1 
1024+       bndElem = > this% atmc(itemno)
1025+       call  read_value_or_time_series_adv(text, itemno, jj, bndElem, &
1026+                                          this% packName, ' BND'  , this% tsManager, &
1027+                                          this% iprpak, ' ATMC'  )  
8901028    case default 
8911029      ! 
8921030      !  -- Keyword not recognized so return to caller with found = .false.
0 commit comments