CLAWRIM Wiki

The Computational Lab for Advanced Water Resources Informatics and Modeling

User Tools

Site Tools


projects:streamflow_uncertainty_analysis_using_crawford_model_and_mc

This is an old revision of the document!


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()

projects/streamflow_uncertainty_analysis_using_crawford_model_and_mc.1736371987.txt.gz · Last modified: by hcho

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki