Skip to content

Commit

Permalink
clean version
Browse files Browse the repository at this point in the history
  • Loading branch information
Yalan Song authored and Yalan Song committed Mar 21, 2024
1 parent f651eed commit 0fa6c88
Show file tree
Hide file tree
Showing 25 changed files with 3,629 additions and 674 deletions.
3 changes: 3 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/HydroDLAdj.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

131 changes: 131 additions & 0 deletions HydroModels/HBV_Module.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import torch
import torch.nn as nn

class HBV_Module(nn.Module):
def __init__(self, climate_data,nfea):
super().__init__()
self.climate_data = climate_data
self.nfea = nfea

def forward(self, y,theta,t,returnFlux=False,aux=None):
##parameters
bs = theta.shape[0]

nfea = self.nfea
theta = theta.view(bs,nfea)
parascaLst = [[1,6], [50,1000], [0.05,0.9], [0.01,0.5], [0.001,0.2], [0.2,1],
[0,10], [0,100], [-2.5,2.5], [0.5,10], [0,0.1], [0,0.2], [0.3,5]] # HBV para

Beta = parascaLst[0][0] + theta[:,0]*(parascaLst[0][1]-parascaLst[0][0])
FC = parascaLst[1][0] + theta[:,1]*(parascaLst[1][1]-parascaLst[1][0])
K0 = parascaLst[2][0] + theta[:,2]*(parascaLst[2][1]-parascaLst[2][0])
K1 = parascaLst[3][0] + theta[:,3]*(parascaLst[3][1]-parascaLst[3][0])
K2 = parascaLst[4][0] + theta[:,4]*(parascaLst[4][1]-parascaLst[4][0])
LP = parascaLst[5][0] + theta[:,5]*(parascaLst[5][1]-parascaLst[5][0])
PERC = parascaLst[6][0] + theta[:,6]*(parascaLst[6][1]-parascaLst[6][0])
UZL = parascaLst[7][0] + theta[:,7]*(parascaLst[7][1]-parascaLst[7][0])
TT = parascaLst[8][0] + theta[:,8]*(parascaLst[8][1]-parascaLst[8][0])
CFMAX = parascaLst[9][0] + theta[:,9]*(parascaLst[9][1]-parascaLst[9][0])
CFR = parascaLst[10][0] + theta[:,10]*(parascaLst[10][1]-parascaLst[10][0])
CWH = parascaLst[11][0] + theta[:,11]*(parascaLst[11][1]-parascaLst[11][0])
BETAET = parascaLst[12][0] + theta[:,12]*(parascaLst[12][1]-parascaLst[12][0])



PRECS = 0
##% stores
SNOWPACK = torch.clamp(y[:,0] , min=PRECS) #SNOWPACK
MELTWATER = torch.clamp(y[:,1], min=PRECS) #MELTWATER
SM = torch.clamp(y[:,2], min=1e-8) #SM
SUZ = torch.clamp(y[:,3] , min=PRECS) #SUZ
SLZ = torch.clamp(y[:,4], min=PRECS) #SLZ
dS = torch.zeros(y.shape[0],y.shape[1]).to(y)
fluxes = torch.zeros((y.shape[0],1)).to(y)

climate_in = self.climate_data[int(t),:,:]; ##% climate at this step
P = climate_in[:,0];
Ep = climate_in[:,2];
T = climate_in[:,1];

##% fluxes functions
flux_sf = self.snowfall(P,T,TT);
flux_refr = self.refreeze(CFR,CFMAX,T,TT,MELTWATER);
flux_melt = self.melt(CFMAX,T,TT,SNOWPACK);
flux_rf = self.rainfall(P,T,TT);
flux_Isnow = self.Isnow(MELTWATER,CWH,SNOWPACK);
flux_PEFF = self.Peff(SM,FC,Beta,flux_rf,flux_Isnow);
flux_ex = self.excess(SM,FC);
flux_et = self.evap(SM,FC,LP,Ep,BETAET);
flux_perc = self.percolation(PERC,SUZ);
flux_q0 = self.interflow(K0,SUZ,UZL);
flux_q1 = self.baseflow(K1,SUZ);
flux_q2 = self.baseflow(K2,SLZ);


#% stores ODEs
dS[:,0] = flux_sf + flux_refr - flux_melt
dS[:,1] = flux_melt - flux_refr - flux_Isnow
dS[:,2] = flux_Isnow + flux_rf - flux_PEFF - flux_ex - flux_et
dS[:,3] = flux_PEFF + flux_ex - flux_perc - flux_q0 - flux_q1
dS[:,4] = flux_perc - flux_q2

fluxes[:,0] =flux_q0 + flux_q1 + flux_q2

if returnFlux:
return fluxes,flux_q0.unsqueeze(-1),flux_q1.unsqueeze(-1),flux_q2.unsqueeze(-1),flux_et.unsqueeze(-1)
else:
return dS,fluxes





def rechange(self, C,NDC,FC,SM,SLZ):
return C*SLZ*(1.0-torch.clamp(SM/(NDC*FC),max = 1.0))



def snowfall(self,P,T,TT):
return torch.mul(P, (T < TT))

def refreeze(self,CFR,CFMAX,T,TT,MELTWATER):
refreezing = CFR * CFMAX * (TT - T)
refreezing = torch.clamp(refreezing, min=0.0)
return torch.min(refreezing, MELTWATER)

def melt(self,CFMAX,T,TT,SNOWPACK):
melt = CFMAX * (T - TT)
melt = torch.clamp(melt, min=0.0)
return torch.min(melt, SNOWPACK)

def rainfall(self,P,T,TT):

return torch.mul(P, (T >= TT))
def Isnow(self,MELTWATER,CWH,SNOWPACK):
tosoil = MELTWATER - (CWH * SNOWPACK)
tosoil = torch.clamp(tosoil, min=0.0)
return tosoil

def Peff(self,SM,FC,Beta,flux_rf,flux_Isnow):
soil_wetness = (SM / FC) ** Beta
soil_wetness = torch.clamp(soil_wetness, min=0.0, max=1.0)
return (flux_rf + flux_Isnow) * soil_wetness

def excess(self,SM,FC):
excess = SM - FC
return torch.clamp(excess, min=0.0)


def evap(self,SM,FC,LP,Ep,BETAET):
evapfactor = (SM / (LP * FC)) ** BETAET
evapfactor = torch.clamp(evapfactor, min=0.0, max=1.0)
ETact = Ep * evapfactor
return torch.min(SM, ETact)

def interflow(self,K0,SUZ,UZL):
return K0 * torch.clamp(SUZ - UZL, min=0.0)
def percolation(self,PERC,SUZ):
return torch.min(SUZ, PERC)

def baseflow(self,K,S):
return K * S
139 changes: 139 additions & 0 deletions HydroModels/HBV_Module_add_cr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import torch
import torch.nn as nn

class HBV_Module_add_cr(nn.Module):
def __init__(self, climate_data,nfea):
super().__init__()
self.climate_data = climate_data
self.nfea = nfea

def forward(self, y,theta,t,returnFlux=False,aux=None):
##parameters
bs = theta.shape[0]

nfea = self.nfea
theta = theta.view(bs,nfea)
parascaLst = [[1,6], [50,1000], [0.05,0.9], [0.01,0.5], [0.001,0.2], [0.2,1],
[0,10], [0,100], [-2.5,2.5], [0.5,10], [0,0.1], [0,0.2], [0.3,5],[0,1],[0.05,0.95]] # HBV para

Beta = parascaLst[0][0] + theta[:,0]*(parascaLst[0][1]-parascaLst[0][0])
FC = parascaLst[1][0] + theta[:,1]*(parascaLst[1][1]-parascaLst[1][0])
K0 = parascaLst[2][0] + theta[:,2]*(parascaLst[2][1]-parascaLst[2][0])
K1 = parascaLst[3][0] + theta[:,3]*(parascaLst[3][1]-parascaLst[3][0])
K2 = parascaLst[4][0] + theta[:,4]*(parascaLst[4][1]-parascaLst[4][0])
LP = parascaLst[5][0] + theta[:,5]*(parascaLst[5][1]-parascaLst[5][0])
PERC = parascaLst[6][0] + theta[:,6]*(parascaLst[6][1]-parascaLst[6][0])
UZL = parascaLst[7][0] + theta[:,7]*(parascaLst[7][1]-parascaLst[7][0])
TT = parascaLst[8][0] + theta[:,8]*(parascaLst[8][1]-parascaLst[8][0])
CFMAX = parascaLst[9][0] + theta[:,9]*(parascaLst[9][1]-parascaLst[9][0])
CFR = parascaLst[10][0] + theta[:,10]*(parascaLst[10][1]-parascaLst[10][0])
CWH = parascaLst[11][0] + theta[:,11]*(parascaLst[11][1]-parascaLst[11][0])
BETAET = parascaLst[12][0] + theta[:,12]*(parascaLst[12][1]-parascaLst[12][0])
C = parascaLst[13][0] + theta[:,13]*(parascaLst[13][1]-parascaLst[13][0])
NDC = parascaLst[14][0] + theta[:,14]*(parascaLst[14][1]-parascaLst[14][0])



PRECS = 0
##% stores
SNOWPACK = torch.clamp(y[:,0] , min=PRECS) #SNOWPACK
MELTWATER = torch.clamp(y[:,1], min=PRECS) #MELTWATER
SM = torch.clamp(y[:,2], min=1e-8) #SM
SUZ = torch.clamp(y[:,3] , min=PRECS) #SUZ
SLZ = torch.clamp(y[:,4], min=PRECS) #SLZ
dS = torch.zeros(y.shape[0],y.shape[1]).to(y)
fluxes = torch.zeros((y.shape[0],1)).to(y)

climate_in = self.climate_data[int(t),:,:]; ##% climate at this step
P = climate_in[:,0];
Ep = climate_in[:,2];
T = climate_in[:,1];

##% fluxes functions

flux_sf = self.snowfall(P,T,TT);
flux_refr = self.refreeze(CFR,CFMAX,T,TT,MELTWATER);
flux_melt = self.melt(CFMAX,T,TT,SNOWPACK);
flux_rf = self.rainfall(P,T,TT);
flux_Isnow = self.Isnow(MELTWATER,CWH,SNOWPACK);
flux_PEFF = self.Peff(SM,FC,Beta,flux_rf,flux_Isnow);
flux_ex = self.excess(SM,FC);
flux_et = self.evap(SM,FC,LP,Ep,BETAET);
flux_perc = self.percolation(PERC,SUZ);
flux_q0 = self.interflow(K0,SUZ,UZL);
flux_q1 = self.baseflow(K1,SUZ);
flux_q2 = self.baseflow(K2,SLZ);
flux_recharge = self.recharge(C,NDC,FC,SM,SLZ)


#% stores ODEs
dS[:,0] = flux_sf + flux_refr - flux_melt
dS[:,1] = flux_melt - flux_refr - flux_Isnow
dS[:,2] = flux_Isnow + flux_rf - flux_PEFF - flux_ex - flux_et + flux_recharge
dS[:,3] = flux_PEFF + flux_ex - flux_perc - flux_q0 - flux_q1
dS[:,4] = flux_perc - flux_q2 - flux_recharge

fluxes[:,0] =flux_q0 + flux_q1 + flux_q2


if returnFlux:
return fluxes,flux_q0.unsqueeze(-1),flux_q1.unsqueeze(-1),flux_q2.unsqueeze(-1),flux_et.unsqueeze(-1)
else:
return dS,fluxes






def recharge(self, C,NDC,FC,SM,SLZ):
return C*SLZ*(1.0-torch.clamp(SM/(NDC*FC),max = 1.0))





def snowfall(self,P,T,TT):
return torch.mul(P, (T < TT))

def refreeze(self,CFR,CFMAX,T,TT,MELTWATER):
refreezing = CFR * CFMAX * (TT - T)
refreezing = torch.clamp(refreezing, min=0.0)
return torch.min(refreezing, MELTWATER)

def melt(self,CFMAX,T,TT,SNOWPACK):
melt = CFMAX * (T - TT)
melt = torch.clamp(melt, min=0.0)
return torch.min(melt, SNOWPACK)

def rainfall(self,P,T,TT):

return torch.mul(P, (T >= TT))
def Isnow(self,MELTWATER,CWH,SNOWPACK):
tosoil = MELTWATER - (CWH * SNOWPACK)
tosoil = torch.clamp(tosoil, min=0.0)
return tosoil

def Peff(self,SM,FC,Beta,flux_rf,flux_Isnow):
soil_wetness = (SM / FC) ** Beta
soil_wetness = torch.clamp(soil_wetness, min=0.0, max=1.0)
return (flux_rf + flux_Isnow) * soil_wetness

def excess(self,SM,FC):
excess = SM - FC
return torch.clamp(excess, min=0.0)


def evap(self,SM,FC,LP,Ep,BETAET):
evapfactor = (SM / (LP * FC)) ** BETAET
evapfactor = torch.clamp(evapfactor, min=0.0, max=1.0)
ETact = Ep * evapfactor
return torch.min(SM, ETact)

def interflow(self,K0,SUZ,UZL):
return K0 * torch.clamp(SUZ - UZL, min=0.0)
def percolation(self,PERC,SUZ):
return torch.min(SUZ, PERC)

def baseflow(self,K,S):
return K * S
Loading

0 comments on commit 0fa6c88

Please sign in to comment.