% Reservoir Simulation with Precipitation and Constraints
%
% This MATLAB code simulates the behavior of a reservoir system over a given
% time period, accounting for factors such as precipitation, linear
% reservoir coefficients, upper and lower storage limits, and the presence
% of negative and imaginary numbers. The simulation tracks the changes in
% storage and outflow values for each reservoir over time.
%
% Parameters:
% - x: Number of reservoirs in the system.
% - S0: Initial storage value for each reservoir.
% - dt: Time step duration in days.
% - R0: Precipitation rate in mm/day.
% - A: Linear reservoir coefficient in 1/day.
% - Q0: Initial outflow value in mm/day.
% - Vmax: Upper storage limit for each reservoir.
% - up: Maximum outflow value that triggers reduced precipitation.
% - lo: Minimum storage limit that terminates the simulation.
%
% Variables:
% - A1: Randomized linear coefficients for each reservoir.
% - S1: Randomized initial storage values for each reservoir.
% - Q1: Randomized initial outflow values for each reservoir.
% - N1: Exponent vector for calculating outflow from storage.
% - nu01: Storage and outflow values over time for each reservoir.
% - y: Precipitation factor that controls precipitation.
% - w: Time step index during simulation.
% - z: Reservoir index during simulation.
% - negative_found: Flag indicating if negative storage values were encountered.
% - imaginary_found: Flag indicating if imaginary numbers were encountered.
%
% Simulation Process:
% The code iterates through time steps, updating the storage and outflow
% values for each reservoir using the given parameters. It also checks for
% conditions such as reaching maximum storage, falling below minimum storage,
% and encountering imaginary numbers. If storage becomes negative, it is set
% to zero. The simulation stops when the outflow drops below a threshold.
%
% Author: [Mrutyunjaya Hiremath]
% Date: [11-8-23]
%
% Note: The simulation may terminate due to reaching the lower storage limit
% or encountering imaginary numbers. The code handles negative storage values
% by setting them to zero and provides informative output messages.
clc
close all
%---------setup----------%
x = 4; %numbers of reservoir
S0 = 1.438; % initial storage (mm)
dt = 1; %Timestep (day)
R0 = 2; %precipitation = 2mm/day, it was selected because it was the aveage rainfall in Minnesota
A = 1.202/(1.438*24); %Linear reservoir coefficent (1/day)
Q0 = S0 * A; %initial outflow (mm/day)
y = 1;
A1 = rand(x+1,1);
A1 = A1 * A;
S1 = rand(x+1,1);
S1 = S1 * S0;
Q1 = rand(x+1,1);
Q1 = Q1 * Q0;
t = 20000;
N1 = ones(x+1,1); % Initialize the N1 vector with ones
nu01 = zeros(2,t/dt+1,x+1);
nu01(1,1,:) = S1; %initial storage when t=1
nu01(2,1,:) = Q1; %initial outflow when t=1
y = 1;
Vmax = 7.9022;
up = Vmax; % Upper limit
lo = 0; % Lower Limit
% Initialize flags for negative and imaginary numbers
negative_found = false;
imaginary_found = false;
%---------setup ends----------%
% The loop
for w = 1:t/dt %days of the experiment; time increment
% Calculate storage and outflow for Reservoir 1
nu01(1,w+1,1) = nu01(1,w,1) + Vmax*dt*y - nu01(2,w,1)*dt;
nu01(2,w+1,1) = A1(1) * nu01(1,w+1,1).^N1(1);
% Calculate storage and outflow for Reservoirs 2 to x+1
for z = 2:x+1
nu01(1,w+1,z) = nu01(1,w,z) + Vmax*dt*y - nu01(2,w,z)*dt + nu01(2,w,z-1)*dt;
nu01(2,w+1,z) = A1(z) * nu01(1,w+1,z).^N1(z);
end
% Turn off precipitation after reaching maximum storage
if nu01(2,w,z) > (up - (1e-5))
y = 0;
end
% Correct negative storage values
if sum(nu01(1,w,:) < 0) > 0
nu02 = nu01(1,w,:);
nu02(nu02 < 0) = 0;
nu01(1,w,:) = nu02;
fprintf('Negative storage values corrected in timestep %d\n', w);
negative_found = true;
end
% Check for imaginary numbers
if any(~isreal(nu01(:,w,:)))
fprintf('Imaginary numbers found in timestep %d\n', w);
imaginary_found = true;
end
% Break loop if the condition is met
if nu01(2,w,end) < (lo + (1e-5))
break;
end
end
% Display messages
if ~negative_found && ~imaginary_found
disp('No negative or imaginary numbers found in the array.');
end