Effacer les filtres
Effacer les filtres

Unable to meet integration tolerances without reducing the step size

4 vues (au cours des 30 derniers jours)
MAYUR MARUTI DHIRDE
MAYUR MARUTI DHIRDE le 9 Déc 2023
Commenté : Torsten le 10 Déc 2023
Nx = 50; % Number of grid points
L = 5000; % Length of the spatial domain
dx = L / (Nx-1); % Spatial step size
x = linspace(0, L, Nx); % Spatial points
A=0.1963;
f = 0.008;
D = 500e-3;
rho=1.2;
c = 348.5;
P_atm = 1.013e5; % Atmospheric pressure in Pa
tspan = [0, 3600]; % Time span
% Initial conditions
P0 = 5e6*ones(Nx,1); % Initial condition for pressure (P)
m0 = zeros(Nx, 1); % Initial condition for mass flow rate (m)
% Initial conditions vector
u0 = [P0; m0];
options = odeset('RelTol', 1e-6, 'AbsTol', 1e-6);
% Solve the system of ODEs using ode15s
[t, u] = ode15s(@(t, u) MyODEs(t, u, Nx, dx, f, c, D), tspan, u0,options);
Warning: Failure at t=8.024469e+02. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (1.818989e-12) at time t.
% Extract the solutions for P and m
P_solution = u(:, 1:Nx);
m_solution = u(:, Nx + 1:end);
%% when m =kg/s*m^2
Q_n= (m_solution./rho);
Q=(Q_n .*A);
% nodes_to_plot = 1:7:Nx;
%
% % Plotting P_solution for selected nodes with transparency
% figure;
% hold on;
% colors = rand(length(nodes_to_plot), 3);
% for idx = 1:length(nodes_to_plot)
% i = nodes_to_plot(idx);
% plot(t, P_solution(:, i), 'LineWidth', 0.5, 'DisplayName', ['Node ' num2str(i)], 'Color', colors(idx,:), 'LineStyle', '-');
% end
% hold off;
% xlabel('Time (t)');
% ylabel('Pressure (P)');
% title('Pressure (P) at Selected Nodes over Time');
% legend('show');
% % Choose Node 1 (x = 1) for plotting
node1_idx = 25;
% % Extract the pressure and Q values at Node 1
Q_node1 = Q(:, node1_idx);
figure;
plot(t, Q_node1 , 'LineWidth', 2);
xlabel('Time (t)');
ylabel('Q at Node 1');
title('Q at Node 1 over Time with covective term');
% Set up the system of ODEs including the boundary condition ODEs
function dudt = MyODEs(t, u, Nx, dx, f, c, D)
P = u(1:Nx);
m = u(Nx + 1:end);
dPdt = zeros(Nx, 1);
dmdt = zeros(Nx, 1);
% Boundary Condition
P(1) = 5e6; % P(1) boundary condition
% Nozzle at i=25 (Algebraic relationships)
p_hst = 503.51e3; % p_hst = rho * g * d (where d = 40m)
Cd = 0.55;
gamma = 1.4;
rho1 = 1.2;
% Mass flowrate of nozzle
m_nz = Cd * sqrt((2 * gamma / (gamma - 1)) * P(25) * rho1 * (1 - (P(25) / p_hst)^((gamma - 1) / gamma)) * (P(25) / p_hst)^(2 / gamma));
% Equation
dPdt(25) =-c^2 * (3*m(25) - 4*m(24) + m(23)) / (2*dx); % Backward discretization of dP/dt at i=25
dmdt(25) =-(2*m(25)*c^2/P(25)*((- 3*m(25)+4*m(26)-m(27)) / (2 * dx)))+(c^2*m(25)^2/P(25)^2)*((- 3*P(25)+ 4*P(26)-P(27)) / (2*dx)) - ((-3*P(25)+4*P(26)-P(27)) / (2*dx)) - (f * m(25) * abs(m(25)) * c^2) / (2 *D* (P(25))); % Forward discretization for dm/dt at i=26
dmdt(1) =-(2*m(1)*c^2/P(1)*((- 3*m(1)+4*m(2)-m(3)) / (2 * dx)))+(c^2*m(1)^2/P(1)^2)*((- 3*P(1)+ 4*P(2)-P(3)) / (2*dx)) - ((-3*P(1)+4*P(2)-P(3)) / (2*dx)) - (f * m(1) * abs(m(1)) * c^2) / (2 *D* (P(1))); % Forward discretization for dm/dt at i=1
% Update m(Nx) based on the time t and the specified conditions
for i = 1:length(t)
if t(i) < 600
m(Nx) = 0;
elseif t(i) < 1800
m(Nx) = 509.28; %509.28 kg/s*m^2;
else
m(Nx) = 0;
end
end
% Equations
dPdt(Nx) =-c^2 * (3*m(Nx) - 4*m(Nx - 1) + m(Nx-2)) / (2*dx); % Backward discretization of dP/dt at i=Nx
% Central discretization for in-between grid points (i=2 to 49)
for i = 2:49
if i == 25
% Skip the calculation for dPdt(25) since it's already calculated outside the loop
% dPdt(25) = ...;
% dmdt(25) =.....;
elseif i == 24
m(i)= m(25)+m_nz;% Two mass flow rate enter m(25) and m_nz
else
% Calculate dP/dt and dm/dt for in-between grid points using central discretization
dPdt(i) = -c^2 * (m(i+1) - m(i-1)) / (2 * dx); % Central discretization of dP/dt
dmdt(i) =-2*m(i)*c^2/P(i)*((m(i + 1) - m(i - 1)) / (2 * dx))+(c^2*m(i)^2/P(i)^2)*(P(i+1) - P(i-1)) / (2*dx) - (P(i+1) - P(i-1)) / (2*dx) - (f * m(i) * abs(m(i))* c^2 ) /( 2*D*P(i)); % Central discretization of dm/dt
end
end
% Combine dPdt and dmdt into a single vector
dudt = [dPdt; dmdt];
end
%% Due to this condition ,i am getting warning that integration tolerance cannot be meet
% The logic mass flowrate entering at node 24 , is summation of m(25)+ m_nz
%elseif i == 24
%m(i)= m(25)+m_nz;% Two mass flow rate enter m(25) and m_nz

Réponses (1)

Walter Roberson
Walter Roberson le 9 Déc 2023
[t, u] = ode15s(@(t, u) MyODEs(t, u, Nx, dx, f, c, D), tspan, u0,options);
ode15s is defined as passing a scalar value as the first parameter -- so t will be scalar.
for i = 1:length(t)
length(t) is guaranteed to be 1 -- unless, that is, you are somehow calling MyODEs from your own custom driver.
if t(i) < 600
m(Nx) = 0;
elseif t(i) < 1800
m(Nx) = 509.28; %509.28 kg/s*m^2;
else
m(Nx) = 0;
end
All of the ode*() variable-step routines are based upon mathematics that requires that the ode function have continuous first two derivatives. But when you have that kind of if statement, you have an abrupt jump in your m(Nx) value, leading to discontinuity in your first derivatives. When you are fortunate, ode15s will notice the discontunity and give you an error message about failing on integration tolerances. When you are not fortunately, ode15s will fail to notice and will keep going and confidently give you the wrong answer.
Your transitions are at specific times. You need to divide your integration up into three parts: 0 to 600, 600 to 1800, then over 1800. You will need three different ode*() calls with three different tspan for this. You would parameterize the call to myODEs according to what the current m(Nx) value should be for that tspan.
I notice by the way that you loop over i = 1:length(t) but your assignments to m are not indexed by i or an expression dependent on i: they are indexed at the constant value Nx . Nx does not change inside the loop, so the value of m(Nx) is going to come out according to whatever was assigned for the last t value, t(end) . There is no point in checking the other t(i) values: you would get the same effect if you had for i = length(t) instead. You should rethink that logic... especially in view of the fact that as discussed above, t will only ever be scalar unless you are calling the function "manually".
  22 commentaires
MAYUR MARUTI DHIRDE
MAYUR MARUTI DHIRDE le 10 Déc 2023
% Set up the system of ODEs including the boundary condition ODEs
function dudt = MyODEs(t, u, Nx, dx, f, c, D)
P = u(1:Nx);
m = u(Nx + 1:end);
dPdt = zeros(Nx, 1);
dmdt = zeros(Nx, 1);
% Calculate dPdt(25) using previous known m(24)
dPdt(25) = -c^2 * (3 * m(25) - 4 * m(24) + m(23)) / (2 * dx);
% Boundary Condition
P(1) = 5e6; % P(1) boundary condition
% Nozzle at i=25 (Algebraic relationships)
p_hst = 503.51e3; % p_hst = rho * g * d (where d = 40m)
Cd = 0.55;
gamma = 1.4;
rho1 = 1.2;
% Mass flowrate of nozzle
m_nz = Cd * sqrt((2 * gamma / (gamma - 1)) * P(25) * rho1 * (1 - (P(25) / p_hst)^((gamma - 1) / gamma)) * (P(25) / p_hst)^(2 / gamma));
% Manipulate m at node position 24
manipulated_m_24 = m(25) + m_nz;
m(24) = manipulated_m_24;
% Setting derivatives at manipulated positions to zero
dPdt(24) = 0;
dmdt(24) = 0;
% Calculation for dmdt(25) and dmdt(1)
dmdt(25) = -(2 * m(25) * c^2 / P(25) * ((-3 * m(25) + 4 * m(26) - m(27)) / (2 * dx))) + (c^2 * m(25)^2 / P(25)^2) * ((-3 * P(25) + 4 * P(26) - P(27)) / (2 * dx)) - ((-3 * P(25) + 4 * P(26) - P(27)) / (2 * dx)) - (f * m(25) * abs(m(25)) * c^2) / (2 * D * (P(25))); % Forward discretization for dm/dt at i=25
dmdt(1) = -(2 * m(1) * c^2 / P(1) * ((-3 * m(1) + 4 * m(2) - m(3)) / (2 * dx))) + (c^2 * m(1)^2 / P(1)^2) * ((-3 * P(1) + 4 * P(2) - P(3)) / (2 * dx)) - ((-3 * P(1) + 4 * P(2) - P(3)) / (2 * dx)) - (f * m(1) * abs(m(1)) * c^2) / (2 * D * (P(1))); % Forward discretization for dm/dt at i=1
% Calculation for dPdt(Nx)
dPdt(Nx) = -c^2 * (3 * m(Nx) - 4 * m(Nx - 1) + m(Nx - 2)) / (2 * dx); % Backward discretization of dP/dt at i=Nx
% Loop for calculating derivatives from i=2 to i=49
for i = 2:49
if i == 24 || i == 25
% Skip calculation or set to zero if needed for i=24 and i=25
dPdt(i) = 0;
dmdt(i) = 0;
else
% Calculate dP/dt and dm/dt for other grid points using your scheme
dPdt(i) = -c^2 * (m(i + 1) - m(i - 1)) / (2 * dx); % Calculation for dP/dt at other points
dmdt(i) = -2 * m(i) * c^2 / P(i) * ((m(i + 1) - m(i - 1)) / (2 * dx)) + (c^2 * m(i)^2 / P(i)^2) * (P(i + 1) - P(i - 1)) / (2 * dx) - (P(i + 1) - P(i - 1)) / (2 * dx) - (f * m(i) * abs(m(i)) * c^2) / (2 * D * P(i)); % Calculation for dm/dt at other points
end
end
% Combine dPdt and dmdt into a single vector
dudt = [dPdt; dmdt];
end
%%
Warning: Failure at t=3.776956e+02. Unable to meet integration tolerances without reducing the step size below the
smallest value allowed (9.094947e-13) at time t.
Torsten
Torsten le 10 Déc 2023
You first set
dPdt(25) = -c^2 * (3 * m(25) - 4 * m(24) + m(23)) / (2 * dx)
, but then reset it to 0 in
if i == 24 || i == 25
% Skip calculation or set to zero if needed for i=24 and i=25
dPdt(i) = 0;
dmdt(i) = 0;
else
...
If you set dPdt(25) = 0, you must fix a value for P(25) in your code since P(25) won't remain at its initial value of 5e6.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Mathematics and Optimization dans Help Center et File Exchange

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by