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() {{:workspaces:mc_plot.png?400 |}}