Skip to content

Commit

Permalink
removed redundant SOF calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
RY4GIT committed Jun 18, 2023
1 parent e48191a commit 3b384f0
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 101 deletions.
Binary file modified __pycache__/bmi_cfe.cpython-38.pyc
Binary file not shown.
Binary file modified __pycache__/cfe.cpython-38.pyc
Binary file not shown.
2 changes: 1 addition & 1 deletion cat58_config_cfe.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@
"stand_alone":1,
"unit_test":1,
"compare_results_file":"cat58_test_compare.csv",
"soil_scheme":"classic"
"soil_scheme":"ode"
}
133 changes: 65 additions & 68 deletions cfe.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@ def calculate_input_rainfall_and_PET(self, cfe_state):
# ____________________________________________________________________________________
def calculate_evaporation_from_rainfall(self, cfe_state):
"""
Calculate evaporation from rainfall
Calculate evaporation from rainfall. If it is raining, take PET from rainfall
"""
cfe_state.actual_et_from_rain_m_per_timestep = 0
if(cfe_state.timestep_rainfall_input_m > 0):
self.et_from_rainfall(cfe_state)

cfe_state.vol_et_from_rain += cfe_state.actual_et_from_rain_m_per_timestep
#cfe_state.vol_et_to_atm += cfe_state.actual_et_from_rain_m_per_
cfe_state.vol_et_to_atm += cfe_state.actual_et_from_rain_m_per_timestep
cfe_state.volout += cfe_state.actual_et_from_rain_m_per_timestep

cfe_state.actual_et_m_per_timestep += cfe_state.actual_et_from_rain_m_per_timestep

# ____________________________________________________________________________________
def calculate_evaporation_from_soil(self, cfe_state):
"""
Expand All @@ -39,27 +41,33 @@ def calculate_evaporation_from_soil(self, cfe_state):
if cfe_state.soil_params['scheme'].lower() == 'classic':

cfe_state.actual_et_from_soil_m_per_timestep = 0
# If the soil moisture storage is more than wilting point, calculate ET from soil
if(cfe_state.soil_reservoir['storage_m'] > cfe_state.soil_reservoir['wilting_point_m']):
self.et_from_soil(cfe_state)

cfe_state.vol_et_from_soil += cfe_state.actual_et_from_soil_m_per_timestep
#cfe_state.vol_et_to_atm += cfe_state.actual_et_from_soil_m_per_timestep;
cfe_state.vol_et_to_atm += cfe_state.actual_et_from_soil_m_per_timestep
cfe_state.volout += cfe_state.actual_et_from_soil_m_per_timestep

cfe_state.actual_et_m_per_timestep = cfe_state.actual_et_from_rain_m_per_timestep + cfe_state.actual_et_from_soil_m_per_timestep
cfe_state.actual_et_m_per_timestep += cfe_state.actual_et_from_soil_m_per_timestep

elif cfe_state.soil_params['scheme'].lower() == 'ode':
None

# ____________________________________________________________________________________
def calculate_the_soil_moisture_deficit(self, cfe_state):
# Calculate the soil moisture deficit
"""
Calculate the soil moisture deficit
"""
cfe_state.soil_reservoir_storage_deficit_m = (cfe_state.soil_params['smcmax'] * cfe_state.soil_params['D'] - \
cfe_state.soil_reservoir['storage_m'])

# ____________________________________________________________________________________
def calculate_infiltration_excess_overland_flow(self, cfe_state):
# Calculates infiltration excess overland flow
"""
Calculates infiltration excess overland flow
by running the partitioning scheme based on the choice set in the Configuration file
"""
if (cfe_state.timestep_rainfall_input_m > 0.0):
if cfe_state.surface_partitioning_scheme == "Schaake":
self.Schaake_partitioning_scheme(cfe_state)
Expand All @@ -74,13 +82,9 @@ def calculate_infiltration_excess_overland_flow(self, cfe_state):
cfe_state.infiltration_depth_m = 0.0

# __________________________________________________________________________________________________________
def calculate_saturation_excess_overland_flow(self, cfe_state):
"""
Calculates saturation excess overland flow (SOF)
If the infiltration is more than the soil moisture deficit, additional SOF occurs
Args:
cfe_state (_type_): _description_
def calculate_saturation_excess_overland_flow_from_soil(self, cfe_state):
""" Calculates saturation excess overland flow (SOF)
If the infiltration is more than the soil moisture deficit, additional runoff (SOF) occurs and soil get saturated
"""
if cfe_state.soil_reservoir_storage_deficit_m < cfe_state.infiltration_depth_m:
cfe_state.surface_runoff_depth_m += (cfe_state.infiltration_depth_m - cfe_state.soil_reservoir_storage_deficit_m)
Expand All @@ -90,62 +94,67 @@ def calculate_saturation_excess_overland_flow(self, cfe_state):

# __________________________________________________________________________________________________________
def calculate_final_infiltration_and_runoff_values(self, cfe_state):
# Final infiltration & runoff values
""" Tracking runoff & infiltraiton volume with final infiltration & runoff values
"""
cfe_state.vol_partition_runoff += cfe_state.surface_runoff_depth_m
cfe_state.vol_partition_infilt += cfe_state.infiltration_depth_m

# __________________________________________________________________________________________________________
def update_flux_perc_m(self, cfe_state):
if cfe_state.current_time_step == 0:
cfe_state.previous_flux_perc_m = cfe_state.flux_perc_m

# _________________________________________________________________________________________________________
def update_soil_and_partition_flux(self, cfe_state):
# If the infiltration flux exceeds soil moisture storage, saturation overlandflow occurs
# TODO: check if it is the same as calculate_saturation_excess_overland_flow
if cfe_state.previous_flux_perc_m > cfe_state.soil_reservoir_storage_deficit_m:
diff = cfe_state.previous_flux_perc_m - cfe_state.soil_reservoir_storage_deficit_m
cfe_state.infiltration_depth_m = cfe_state.soil_reservoir_storage_deficit_m
cfe_state.vol_partition_runoff += diff
cfe_state.vol_partition_infilt -= diff
cfe_state.surface_runoff_depth_m += diff
cfe_state.soil_reservoir_storage_deficit_m = 0

# _____________________________________________________________________________________________________
def update_soil_reservoir_volume(self, cfe_state):
cfe_state.vol_to_soil += cfe_state.infiltration_depth_m
cfe_state.soil_reservoir['storage_m'] += cfe_state.infiltration_depth_m

# __________________________________________________________________________________________________________
def run_soil_moisture_scheme(self, cfe_state):
""" Run the soil moisture scheme based on the choice set in the Configuration file
"""
if cfe_state.soil_params['scheme'].lower() == 'classic':
self.conceptual_reservoir_flux_calc(cfe_state, cfe_state.soil_reservoir)
elif cfe_state.soil_params['scheme'].lower() == 'ode':
self.soil_moisture_flux_calc_with_ode(cfe_state, cfe_state.soil_reservoir)

# ________________________________________________________________________________________________________
def update_outflux_from_soil(self, cfe_state):
cfe_state.flux_perc_m = cfe_state.primary_flux_m #percolation_flux
cfe_state.flux_lat_m = cfe_state.secondary_flux_m # lateral_flux

# TODO: Add actual ET from soil here in case soil ODE is run
# Actual ET from soil here in case soil ODE is run
if cfe_state.soil_params['scheme'].lower() == 'ode':
cfe_state.vol_et_from_soil += cfe_state.actual_et_from_soil_m_per_timestep
cfe_state.vol_et_to_atm += cfe_state.actual_et_from_soil_m_per_timestep
cfe_state.volout += cfe_state.actual_et_from_soil_m_per_timestep
cfe_state.actual_et_m_per_timestep += cfe_state.actual_et_from_soil_m_per_timestep

elif cfe_state.soil_params['scheme'].lower() == 'classic':
None

# ________________________________________________________________________________________________________
def calculate_groundwater_storage_deficit(self, cfe_state):
cfe_state.gw_reservoir_storage_deficit_m = cfe_state.gw_reservoir['storage_max_m'] - cfe_state.gw_reservoir['storage_m']

# __________________________________________________________________________________________________________
def calculate_saturation_excess_overland_flow(self, cfe_state):
def calculate_saturation_excess_overland_flow_from_gw(self, cfe_state):
# When the groundwater storage is full, the overflowing amount goes to direct runoff
if cfe_state.flux_perc_m > cfe_state.gw_reservoir_storage_deficit_m:
diff = cfe_state.flux_perc_m - cfe_state.gw_reservoir_storage_deficit_m
cfe_state.surface_runoff_depth_m += diff
cfe_state.flux_perc_m = cfe_state.gw_reservoir_storage_deficit_m
cfe_state.vol_partition_runoff+=diff
cfe_state.vol_partition_infilt-=diff
cfe_state.gw_reservoir['storage_m'] = cfe_state.gw_reservoir['storage_max_m']
cfe_state.gw_reservoir_storage_deficit_m = 0
cfe_state.vol_partition_runoff += diff
cfe_state.vol_partition_infilt -= diff

# __________________________________________________________________________________________________________
def track_volume_from_percolation_and_lateral_flow(self, cfe_state):
# Finalize the percolation and lateral flow
cfe_state.gw_reservoir['storage_m'] += cfe_state.flux_perc_m
cfe_state.soil_reservoir['storage_m'] -= cfe_state.flux_perc_m
cfe_state.vol_to_gw += cfe_state.flux_perc_m
cfe_state.vol_soil_to_gw += cfe_state.flux_perc_m

cfe_state.gw_reservoir['storage_m'] += cfe_state.flux_perc_m
cfe_state.soil_reservoir['storage_m'] -= cfe_state.flux_perc_m
cfe_state.soil_reservoir['storage_m'] -= cfe_state.flux_lat_m
cfe_state.vol_soil_to_lat_flow += cfe_state.flux_lat_m #TODO add this to nash cascade as input
cfe_state.volout = cfe_state.volout + cfe_state.flux_lat_m
cfe_state.volout += cfe_state.flux_lat_m
# __________________________________________________________________________________________________________

def set_flux_from_deep_gw_to_chan_m(self, cfe_state):
Expand Down Expand Up @@ -180,17 +189,8 @@ def add_up_total_flux_discharge(self, cfe_state):
def update_current_time(self, cfe_state):
cfe_state.current_time_step += 1
cfe_state.current_time += pd.Timedelta(value=cfe_state.time_step_size, unit='s')

# __________________________________________________________________________________________________________
def run_soil_moisture_scheme(self, cfe_state):
""" Run the soil moisture scheme based on the choice set in the Configuration file
"""
if cfe_state.soil_params['scheme'].lower() == 'classic':
self.conceptual_reservoir_flux_calc(cfe_state, cfe_state.soil_reservoir)
elif cfe_state.soil_params['scheme'].lower() == 'ode':
self.soil_moisture_flux_calc_with_ode(cfe_state, cfe_state.soil_reservoir)

# __________________________________________________________________________________________________________


# __________________________________________________________________________________________________________
# __________________________________________________________________________________________________________
# MAIN MODEL FUNCTION
Expand All @@ -204,19 +204,17 @@ def run_cfe(self, cfe_state):
# Infiltration partitioning
self.calculate_the_soil_moisture_deficit(cfe_state)
self.calculate_infiltration_excess_overland_flow(cfe_state)
self.calculate_saturation_excess_overland_flow(cfe_state)
self.calculate_saturation_excess_overland_flow_from_soil(cfe_state)
self.calculate_final_infiltration_and_runoff_values(cfe_state)
self.update_flux_perc_m(cfe_state)
self.update_soil_and_partition_flux(cfe_state)


# Soil moisture reservoir
self.update_soil_reservoir_volume(cfe_state)
self.run_soil_moisture_scheme(cfe_state)
self.update_outflux_from_soil(cfe_state)

# Groundwater reservoir
self.calculate_groundwater_storage_deficit(cfe_state)
self.calculate_saturation_excess_overland_flow(cfe_state)
self.calculate_saturation_excess_overland_flow_from_gw(cfe_state)
self.track_volume_from_percolation_and_lateral_flow(cfe_state)
self.conceptual_reservoir_flux_calc(cfe_state, cfe_state.gw_reservoir)
self.check_is_fabs_less_than_epsilon(cfe_state)
Expand Down Expand Up @@ -307,21 +305,19 @@ def et_from_rainfall(self,cfe_state):
"""
iff it is raining, take PET from rainfall first. Wet veg. is efficient evaporator.
"""

if cfe_state.timestep_rainfall_input_m >0.0:

if cfe_state.timestep_rainfall_input_m > cfe_state.potential_et_m_per_timestep:

cfe_state.actual_et_from_rain_m_per_timestep = cfe_state.potential_et_m_per_timestep
cfe_state.timestep_rainfall_input_m -= cfe_state.actual_et_from_rain_m_per_timestep

else:
# If rainfall exceeds PET, actual AET from rainfall is equal to the PET
if cfe_state.timestep_rainfall_input_m > cfe_state.potential_et_m_per_timestep:
cfe_state.actual_et_from_rain_m_per_timestep = cfe_state.potential_et_m_per_timestep
cfe_state.timestep_rainfall_input_m -= cfe_state.actual_et_from_rain_m_per_timestep

cfe_state.actual_et_from_rain_m_per_timestep = cfe_state.timestep_rainfall_input_m
cfe_state.timestep_rainfall_input_m=0.0
# If rainfall is less than PET, all rainfall gets consumed as AET
else:
cfe_state.actual_et_from_rain_m_per_timestep = cfe_state.timestep_rainfall_input_m
cfe_state.timestep_rainfall_input_m = 0.0

cfe_state.reduced_potential_et_m_per_timestep = cfe_state.potential_et_m_per_timestep - cfe_state.actual_et_from_rain_m_per_timestep

cfe_state.reduced_potential_et_m_per_timestep = cfe_state.potential_et_m_per_timestep-cfe_state.actual_et_from_rain_m_per_timestep

return


Expand Down Expand Up @@ -553,7 +549,7 @@ def Xinanjiang_partitioning_scheme(self,cfe_state):
# __________________________________________________________________________________________________________
def et_from_soil(self,cfe_state):
"""
take AET from soil moisture storage,
Take AET from soil moisture storage,
using Budyko type curve to limit PET if wilting<soilmoist<field_capacity
"""

Expand All @@ -575,7 +571,8 @@ def et_from_soil(self,cfe_state):
cfe_state.actual_et_from_soil_m_per_timestep = np.minimum(Budyko * cfe_state.reduced_potential_et_m_per_timestep,cfe_state.soil_reservoir['storage_m'])

cfe_state.soil_reservoir['storage_m'] -= cfe_state.actual_et_from_soil_m_per_timestep
cfe_state.reduced_potential_et_m_per_timestep = cfe_state.reduced_potential_et_m_per_timestep - cfe_state.actual_et_from_soil_m_per_timestep
cfe_state.reduced_potential_et_m_per_timestep -= cfe_state.actual_et_from_soil_m_per_timestep

return


Expand Down
64 changes: 32 additions & 32 deletions run_cfe_bmi.ipynb

Large diffs are not rendered by default.

0 comments on commit 3b384f0

Please sign in to comment.