Skip to content
Snippets Groups Projects
Commit cec2f081 authored by Kyle's avatar Kyle
Browse files

trying to add a gru_actor

parent 33c0c78b
No related branches found
No related tags found
No related merge requests found
#pragma once
#include "caf/all.hpp"
#include "fortran_data_types.hpp"
#include "timing_info.hpp"
#include <chrono>
#include <string>
namespace caf{
struct gru_state {
caf::actor file_access_actor;
caf::actor parent;
int indxGRU; // index for gru part of derived types in FORTRAN
int refGRU; // The actual ID of the GRU we are
int numHRUs;
};
}
\ No newline at end of file
#pragma once
extern "C" {
}
\ No newline at end of file
#include "caf/all.hpp"
#include "gru_actor.hpp"
#include "global.hpp"
#include "message_atoms.hpp"
#include "gru_actor_subroutine_wrappers.hpp"
namespace caf {
behavior gru_actor(stateful_actor<gru_state>* self, int refGRU, int indxGRU,
std::string configPath, int outputStrucSize, caf::actor parent)
}
\ No newline at end of file
!!! Lets try and build this for only the lateral flows case.
!!! If lateral flows exits use the code
module gru_actor
implicit none
! public::run_gru
public::init_basin_for_timestep
contains
subroutine init_basin_for_timestep()
implicit none
! initialize runoff variables
bvarStruct%var(iLookBVAR%basin__SurfaceRunoff)%dat(1) = 0._dp ! surface runoff (m s-1)
bvarStruct%var(iLookBVAR%basin__SoilDrainage)%dat(1) = 0._dp
bvarStruct%var(iLookBVAR%basin__ColumnOutflow)%dat(1) = 0._dp ! outflow from all "outlet" HRUs (those with no downstream HRU)
bvarStruct%var(iLookBVAR%basin__TotalRunoff)%dat(1) = 0._dp
! initialize baseflow variables
bvarStruct%var(iLookBVAR%basin__AquiferRecharge)%dat(1) = 0._dp ! recharge to the aquifer (m s-1)
bvarStruct%var(iLookBVAR%basin__AquiferBaseflow)%dat(1) = 0._dp ! baseflow from the aquifer (m s-1)
bvarStruct%var(iLookBVAR%basin__AquiferTranspire)%dat(1) = 0._dp ! transpiration loss from the aquifer (m s-1)
end subroutine
subroutine run_hru_for_timestep()
implicit none
! initialize runoff variables
bvarStruct%var(iLookBVAR%basin__SurfaceRunoff)%dat(1) = 0._dp ! surface runoff (m s-1)
bvarStruct%var(iLookBVAR%basin__SoilDrainage)%dat(1) = 0._dp
bvarStruct%var(iLookBVAR%basin__ColumnOutflow)%dat(1) = 0._dp ! outflow from all "outlet" HRUs (those with no downstream HRU)
bvarStruct%var(iLookBVAR%basin__TotalRunoff)%dat(1) = 0._dp
! initialize baseflow variables
bvarStruct%var(iLookBVAR%basin__AquiferRecharge)%dat(1) = 0._dp ! recharge to the aquifer (m s-1)
bvarStruct%var(iLookBVAR%basin__AquiferBaseflow)%dat(1) = 0._dp ! baseflow from the aquifer (m s-1)
bvarStruct%var(iLookBVAR%basin__AquiferTranspire)%dat(1) = 0._dp ! transpiration loss from the aquifer (m s-1)
! ----- calculate weighted basin (GRU) fluxes --------------------------------------------------------------------------------------
! increment basin surface runoff (m s-1)
bvarStruct%var(iLookBVAR%basin__SurfaceRunoff)%dat(1) = bvarStruct%var(iLookBVAR%basin__SurfaceRunoff)%dat(1) + fluxStruct%var(iLookFLUX%scalarSurfaceRunoff)%dat(1) * fracHRU
!increment basin soil drainage (m s-1)
bvarStruct%var(iLookBVAR%basin__SoilDrainage)%dat(1) = bvarStruct%var(iLookBVAR%basin__SoilDrainage)%dat(1) + fluxStruct%var(iLookFLUX%scalarSoilDrainage)%dat(1) * fracHRU
! increment aquifer variables -- ONLY if aquifer baseflow is computed individually for each HRU and aquifer is run
! NOTE: groundwater computed later for singleBasin
if(model_decisions(iLookDECISIONS%spatial_gw)%iDecision == localColumn .and. model_decisions(iLookDECISIONS%groundwatr)%iDecision == bigBucket) then
bvarStruct%var(iLookBVAR%basin__AquiferRecharge)%dat(1) = bvarStruct%var(iLookBVAR%basin__AquiferRecharge)%dat(1) + fluxStruct%var(iLookFLUX%scalarSoilDrainage)%dat(1) * fracHRU
bvarStruct%var(iLookBVAR%basin__AquiferTranspire)%dat(1) = bvarStruct%var(iLookBVAR%basin__AquiferTranspire)%dat(1) + fluxStruct%var(iLookFLUX%scalarAquiferTranspire)%dat(1) * fracHRU
bvarStruct%var(iLookBVAR%basin__AquiferBaseflow)%dat(1) = bvarStruct%var(iLookBVAR%basin__AquiferBaseflow)%dat(1) &
+ fluxStruct%var(iLookFLUX%scalarAquiferBaseflow)%dat(1) * fracHRU
end if
! perform the routing
associate(totalArea => bvarStruct%var(iLookBVAR%basin__totalArea)%dat(1) )
! compute water balance for the basin aquifer
if(model_decisions(iLookDECISIONS%spatial_gw)%iDecision == singleBasin)then
message=trim(message)//'multi_driver/bigBucket groundwater code not transferred from old code base yet'
err=20; return
end if
! calculate total runoff depending on whether aquifer is connected
if(model_decisions(iLookDECISIONS%groundwatr)%iDecision == bigBucket) then
! aquifer
bvarStruct%var(iLookBVAR%basin__TotalRunoff)%dat(1) = bvarStruct%var(iLookBVAR%basin__SurfaceRunoff)%dat(1) + bvarStruct%var(iLookBVAR%basin__ColumnOutflow)%dat(1)/totalArea + bvarStruct%var(iLookBVAR%basin__AquiferBaseflow)%dat(1)
else
! no aquifer
bvarStruct%var(iLookBVAR%basin__TotalRunoff)%dat(1) = bvarStruct%var(iLookBVAR%basin__SurfaceRunoff)%dat(1) + bvarStruct%var(iLookBVAR%basin__ColumnOutflow)%dat(1)/totalArea + bvarStruct%var(iLookBVAR%basin__SoilDrainage)%dat(1)
endif
call qOverland(&
! input
model_decisions(iLookDECISIONS%subRouting)%iDecision, & ! intent(in): index for routing method
bvarStruct%var(iLookBVAR%basin__TotalRunoff)%dat(1), & ! intent(in): total runoff to the channel from all active components (m s-1)
bvarStruct%var(iLookBVAR%routingFractionFuture)%dat, & ! intent(in): fraction of runoff in future time steps (m s-1)
bvarStruct%var(iLookBVAR%routingRunoffFuture)%dat, & ! intent(in): runoff in future time steps (m s-1)
! output
bvarStruct%var(iLookBVAR%averageInstantRunoff)%dat(1), & ! intent(out): instantaneous runoff (m s-1)
bvarStruct%var(iLookBVAR%averageRoutedRunoff)%dat(1), & ! intent(out): routed runoff (m s-1)
err,message) ! intent(out): error control
if(err/=0)then; err=20; message=trim(message)//trim(cmessage); return; endif
end associate
end subroutine
end module gru_actor
! the way the lateral flow interface should work seems to be at the level of the hru.
! The HRU would have an interface where it has a donwslope compontent. It would then ask
! for this downslope component. This all does have to be setup before hand so the gru needs to
! set these up because the hrus all need to comptue
! a grus timestep depends on all the hrus
! So the Gru needs to be controlling the hrus. It needs to know which ones have lateral flows and which ones do not.
! This is so the other hrus know they do not need to contact another actor. Otherwise they will have to.
\ No newline at end of file
module hru_actor
implicit none
public::run_hru_for_timestep()
contains
subroutine run_hru_for_timestep()
! local variables:
integer(i4b) :: nSnow
integer(i4b) :: nSoil
integer(i4b) :: nLayers
! *******************************************************************************************
! *** initialize computeVegFlux (flag to indicate if we are computing fluxes over vegetation)
! *******************************************************************************************
! if computeVegFlux changes, then the number of state variables changes, and we need to reoranize the data structures
if(modelTimeStep==1)then
! get vegetation phenology
! (compute the exposed LAI and SAI and whether veg is buried by snow)
call vegPhenlgy(&
! input/output: data structures
model_decisions, & ! intent(in): model decisions
typeStruct, & ! intent(in): type of vegetation and soil
attrStruct, & ! intent(in): spatial attributes
mparStruct, & ! intent(in): model parameters
progStruct, & ! intent(in): model prognostic variables for a local HRU
diagStruct, & ! intent(inout): model diagnostic variables for a local HRU
! output
computeVegFluxFlag, & ! intent(out): flag to indicate if we are computing fluxes over vegetation (.false. means veg is buried with snow)
notUsed_canopyDepth, & ! intent(out): NOT USED: canopy depth (m)
notUsed_exposedVAI, & ! intent(out): NOT USED: exposed vegetation area index (m2 m-2)
fracJulDay, &
yearLength, &
err,cmessage) ! intent(out): error control
if(err/=0)then; message=trim(message)//trim(cmessage); return; endif
! save the flag for computing the vegetation fluxes
if(computeVegFluxFlag) computeVegFlux = yes
if(.not.computeVegFluxFlag) computeVegFlux = no
! define the green vegetation fraction of the grid box (used to compute LAI)
diagStruct%var(iLookDIAG%scalarGreenVegFraction)%dat(1) = greenVegFrac_monthly(timeStruct%var(iLookTIME%im))
end if ! if first timestep
! initialize total inflow for each layer in a soil column
fluxStruct%var(iLookFLUX%mLayerColumnInflow)%dat(:) = 0._dp
! convienence variables
nSnow = indxStruct%var(iLookINDEX%nSnow)%dat(1) ! number of snow layers
nSoil = indxStruct%var(iLookINDEX%nSoil)%dat(1) ! number of soil layers
nLayers = indxStruct%var(iLookINDEX%nLayers)%dat(1) ! total number of layers
computeVegFluxFlag = (ComputeVegFlux == yes)
! water pixel: do nothing
if (typeStruct%var(iLookTYPE%vegTypeIndex) == isWater) return
! get height at bottom of each soil layer, negative downwards (used in Noah MP)
allocate(zSoilReverseSign(nSoil),stat=err)
if(err/=0)then
message=trim(message)//'problem allocating space for zSoilReverseSign'
err=20; return
endif
zSoilReverseSign(:) = -progStruct%var(iLookPROG%iLayerHeight)%dat(nSnow+1:nLayers)
! populate parameters in Noah-MP modules
! Passing a maxSoilLayer in order to pass the check for NROOT, that is done to avoid making any changes to Noah-MP code.
! --> NROOT from Noah-MP veg tables (as read here) is not used in SUMMA
call REDPRM(typeStruct%var(iLookTYPE%vegTypeIndex), & ! vegetation type index
typeStruct%var(iLookTYPE%soilTypeIndex), & ! soil type
typeStruct%var(iLookTYPE%slopeTypeIndex), & ! slope type index
zSoilReverseSign, & ! * not used: height at bottom of each layer [NOTE: negative] (m)
maxSoilLayers, & ! number of soil layers
urbanVegCategory) ! vegetation category for urban areas
! deallocate height at bottom of each soil layer(used in Noah MP)
deallocate(zSoilReverseSign,stat=err)
if(err/=0)then
message=trim(message)//'problem deallocating space for zSoilReverseSign'
err=20; return
endif
! overwrite the minimum resistance
if(overwriteRSMIN) RSMIN = mparStruct%var(iLookPARAM%minStomatalResistance)%dat(1)
! overwrite the vegetation height
HVT(typeStruct%var(iLookTYPE%vegTypeIndex)) = mparStruct%var(iLookPARAM%heightCanopyTop)%dat(1)
HVB(typeStruct%var(iLookTYPE%vegTypeIndex)) = mparStruct%var(iLookPARAM%heightCanopyBottom)%dat(1)
! overwrite the tables for LAI and SAI
if(model_decisions(iLookDECISIONS%LAI_method)%iDecision == specified)then
SAIM(typeStruct%var(iLookTYPE%vegTypeIndex),:) = mparStruct%var(iLookPARAM%winterSAI)%dat(1)
LAIM(typeStruct%var(iLookTYPE%vegTypeIndex),:) = mparStruct%var(iLookPARAM%summerLAI)%dat(1)*greenVegFrac_monthly
end if
! compute derived forcing variables
call derivforce(&
timeStruct%var, & ! vector of time information
forcStruct%var, & ! vector of model forcing data
attrStruct%var, & ! vector of model attributes
mparStruct, & ! data structure of model parameters
progStruct, & ! data structure of model prognostic variables
diagStruct, & ! data structure of model diagnostic variables
fluxStruct, & ! data structure of model fluxes
tmZoneOffsetFracDay,&
err,cmessage) ! error control
if(err/=0)then; err=20; message=trim(message)//trim(cmessage); return; endif
! initialize the number of flux calls
diagStruct%var(iLookDIAG%numFluxCalls)%dat(1) = 0._dp
! run the model for a single HRU
call coupled_em(&
! model control
indxHRU, & ! intent(in): hruID
dt_init, & ! intent(inout): initial time step
dt_init_factor, & ! Used to adjust the length of the timestep in the event of a failure
computeVegFluxFlag, & ! intent(inout): flag to indicate if we are computing fluxes over vegetation
! data structures (input)
typeStruct, & ! intent(in): local classification of soil veg etc. for each HRU
attrStruct, & ! intent(in): local attributes for each HRU
forcStruct, & ! intent(in): model forcing data
mparStruct, & ! intent(in): model parameters
bvarStruct, & ! intent(in): basin-average model variables
! data structures (input-output)
indxStruct, & ! intent(inout): model indices
progStruct, & ! intent(inout): model prognostic variables for a local HRU
diagStruct, & ! intent(inout): model diagnostic variables for a local HRU
fluxStruct, & ! intent(inout): model fluxes for a local HRU
fracJulDay, &
yearLength, &
! error control
err,cmessage) ! intent(out): error control
if(err/=0)then; err=20; message=trim(message)//trim(cmessage); return; endif
! save the flag for computing the vegetation fluxes
if(computeVegFluxFlag) ComputeVegFlux = yes
if(.not.computeVegFluxFlag) ComputeVegFlux = no
! The gru_actor will need the following information
fracHRU = attrStruct%var(iLookATTR%HRUarea) / bvarStruct%var(iLookBVAR%basin__totalArea)%dat(1)
fluxStruct%var(iLookFLUX%scalarSurfaceRunoff)%dat(1)
fluxStruct%var(iLookFLUX%scalarSoilDrainage)%dat(1)
fluxStruct%var(iLookFLUX%scalarAquiferTranspire)%dat(1)
fluxStruct%var(iLookFLUX%scalarAquiferBaseflow)%dat(1)
end subroutine
end module hru_actor
\ No newline at end of file
module job_actor
implicit none
public::init_veg_
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment