This is an old revision of the document!
Table of Contents
Streamflow Uncertainty Analysis Using Crawford Model and MC
1. Model Overview
The Crawford model is a hydrological model used to estimate streamflow by simulating the water balance in a watershed. It incorporates rainfall, evapotranspiration, soil moisture, and groundwater flow to predict runoff and discharge. The model is particularly useful for analyzing the impact of climate and land use changes on water resources. The conceptual model is presented in the adjacent figure.
2. Input Parameters The input parameters and initial parameters are presented below. The Monthly precipitation data is prepared using thession polygon. The potential evapotranspiration is calculated using the Penman-Monteith equation. The monthly observed discharge is the stream flow value of the considered gauge station.
Code for Input Parameters
<input file Python>
import numpy as np # Given Data p_sub = 0.6 Gwf = 0.45 annual_ppt = 2026 C = 0.25 nominal = 400 ground_storage = 17.5 # This is the initial groundwater storage initial_soil_moisture_storage = 350 # January initial value initial_ground_water_storage = 17.5 # Initial groundwater storage in January # Monthly PPT and PET data monthly_ppt = [0.299, 3.585, 18.744, 86.719, 312.905, 461.040, 673.795, 668.385, 325.471, 10.699, 0.665, 0.000] monthly_pet = [16.120, 25.507, 45.706, 72.145, 86.949, 85.707, 74.120, 65.469, 74.508, 51.072, 25.309, 13.315] #Monthly observed discharge at Gaurighat gauge station monthly_obs_discharge = [0.27, 0.22, 0.18, 0.26, 1.24, 2.64, 7.47, 11.7, 6.17, 2.19, 1.87, 0.70]
Crawford Model
This is the main part of the model. This simulates the discharge considering the parameters passed to it.
<Model Preparation>
import numpy as np
import matplotlib.pyplot as plt
# Function encapsulating your discharge calculation logic
def calculate_discharge(p_sub, Gwf, annual_ppt, C, nominal, ground_storage,
initial_soil_moisture_storage, initial_ground_water_storage,
monthly_ppt, monthly_pet, area):
soil_moisture_storage = [initial_soil_moisture_storage]
final_ground_storage = [initial_ground_water_storage]
direct_flow = []
groundwater_flow = []
total_discharge = []
ppt = monthly_ppt[i]
pet = monthly_pet[i]
for i in range(12):
# 1. Storage Ratio
storage_ratio_val = soil_moisture_storage[-1] / nominal
# 2. PPT/PET Ratio
ratio_ppt_pet_val = ppt / pet if pet != 0 else 0
# 3. AET/PET Ratio
if ratio_ppt_pet_val > 1:
ratio_aet_pet_val = 1
elif ratio_ppt_pet_val >= 2:
ratio_aet_pet_val = 0
else:
ratio_aet_pet_val = (1 - storage_ratio_val / 2) * ratio_ppt_pet_val + storage_ratio_val / 2
# 4. AET
aet_val = ratio_aet_pet_val * pet
# 5. Water Balance
water_balance_val = ppt - aet_val
# 6. Excess Moisture Ratio
excess_moisture_ratio_val = 1 / (1 + np.exp(-5.03 * (storage_ratio_val - 1)))
# 7. Excess Moisture
excess_moisture_val = water_balance_val * excess_moisture_ratio_val if water_balance_val > 0 else 0
# 8. Recharge to GW
recharge_to_gw_val = excess_moisture_val * p_sub
# 9. Delta Storage
delta_storage_val = -excess_moisture_val + water_balance_val
# 10. Soil Moisture Storage
soil_moisture_storage_val = soil_moisture_storage[-1] + delta_storage_val
# 11. Initial Groundwater Storage
if i == 0:
initial_gw_storage = ground_storage
else:
initial_gw_storage = final_ground_storage[-1] - groundwater_flow[-1]
# 12. Final Groundwater Storage
final_gw_storage_val = recharge_to_gw_val + initial_gw_storage
# 13. Direct Flow
direct_flow_val = excess_moisture_val - recharge_to_gw_val
# 14. Groundwater Flow
ground_water_flow_val = final_gw_storage_val * Gwf
# 15. Total Discharge
total_discharge_val = direct_flow_val + ground_water_flow_val
# Append the values to their respective lists
soil_moisture_storage.append(soil_moisture_storage_val)
final_ground_storage.append(final_gw_storage_val)
direct_flow.append(direct_flow_val)
groundwater_flow.append(ground_water_flow_val)
total_discharge.append(total_discharge_val)
# Convert to cubic meters per second
cal_discharge = [x * (area * 1000 / 31 / 24 / 60 / 60) for x in total_discharge]
return cal_discharge
Monte Carlo Simulation
In this portion random values are generated based on the user assumptions. The radnodm values are generated for the seven different parameters.
- 1. Monthly ppt
- 2. Monthly pet
- 3. P_sub
- 4. Gwf
- 5. Initial_Soil_moisture_storage
- 6. Initial_ground_water_storage
- 7. nominal
<Code for MC Smulation>
# Monte Carlo Simulation
no_of_simulations = 1000 # Number of Monte Carlo iterations
results = []
for _ in range(no_of_simulations):
# Para-1: Randomly generating monthly ppt data with 20% variation
sampled_monthly_ppt = np.random.normal(monthly_ppt, 0.2 * np.array(monthly_ppt))
# Assuming 20% variation
# Para-2: Randomly generating monthly pet with 20% variation
sampled_monthly_pet = np.random.normal(monthly_pet, 0.2 * np.array(monthly_pet))
# Assuming 20% variation
# Para-3, Para-4: Randomly generate uniform distributions for p_sub and GWF
sampled_p_sub = np.random.uniform(0.5, 0.7) # Uniform between 0.5 and 0.7
sampled_GWf = np.random.uniform(0.4, 0.5) # Uniform between 0.4 and 0.5
# Para-5, Para-6, Para-7: Randomly generate other parameters with uniform distributions
sampled_initial_soil_moisture_storage = np.random.uniform(300, 400) # Uniform between 300 and 400
sampled_initial_ground_water_storage = np.random.uniform(15, 25) # Uniform between 15 and 25
sampled_nominal = np.random.uniform(350, 450) # Uniform between 350 and 450
discharge = calculate_discharge(
sampled_p_sub, sampled_GWf, annual_ppt, C, sampled_nominal, ground_storage,
sampled_initial_soil_moisture_storage, sampled_initial_ground_water_storage,
sampled_monthly_ppt, sampled_monthly_pet, 74.20
)
results.append(discharge)
# Analyze the results (e.g., calculate means and confidence intervals)
results = np.array(results)
mean_discharge = np.mean(results, axis=0)
std_discharge = np.std(results, axis=0)
Plotting the results
<Code for result visualization>
# Plot the results months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
plt.figure(figsize=(10, 6))
plt.plot(months, mean_discharge, label='Mean Discharge', marker='o', color='green')
plt.fill_between(months, mean_discharge - std_discharge, mean_discharge + std_discharge,
color='green', alpha=0.2, label='±1 Std Dev')
#plt.plot(months, monthly_obs_discharge, label='Observed Discharge', marker='o', color='blue')
# Adding labels and title
plt.xlabel('Month')
plt.ylabel('Discharge (m³/s)')
plt.title('Monte Carlo Simulation: Discharge Uncertainty')
plt.legend()

