1function [xvec_it, xvec_t, t, iter] = solver_fluid_iteration(sn, N, Mu, Phi, PH,
P, S, xvec_it, ydefault, slowrate, Tstart, max_time, options)
2% [XVEC_IT, XVEC_T, T, ITER] = SOLVER_FLUID_ITERATION(QN, N, MU, PHI, PH,
P, S, YMEAN, YDEFAULT, SLOWRATE, TSTART, MAX_TIME, OPTIONS)
4% Copyright (c) 2012-2026, Imperial College London
7iter_max = options.iter_max;
8verbose = options.verbose;
10iter_tol = options.iter_tol;
12timespan = options.timespan;
14goon =
true; % max stiff solver
21% heuristic to select stiff or non-stiff ODE solver
22nonZeroRates = slowrate(:);
23nonZeroRates = nonZeroRates( nonZeroRates >tol );
25nonZeroRates = nonZeroRates(isfinite(nonZeroRates));
26%rategap = log10(max(nonZeroRates)/min(nonZeroRates)); %
if the max rate
is InfRate and the min
is 1, then rategap = 6
29[ode_h, ~] = solver_fluid_odes(sn, N, Mu, Phi, PH,
P, S, sn.sched, sn.schedparam, options);
32odeopt = odeset(
'AbsTol', tol,
'RelTol', tol,
'NonNegative', 1:length(xvec_it{1}));
34while (isfinite(timespan(2)) && T < timespan(2)) || (goon && iter < iter_max)
36 if toc(Tstart) > max_time
41 % determine entry state vector in e
42 y0 = xvec_it{iter-1 +1};
44 if iter == 1 % first iteration
45 T = min(timespan(2),abs(10/min(nonZeroRates))); % solve ode until T = 1
event with slowest exit rate
47 T = min(timespan(2),abs(10*iter/min(nonZeroRates)));
53 [t_iter, ymean_t_iter] = ode_solve_stiff(ode_h, trange, y0, odeopt, options);
55 [t_iter, ymean_t_iter] = ode_solve(ode_h, trange, y0, odeopt, options);
58 line_printf(
'\nThe initial point is invalid, Fluid solver switching to default initialization.');
59 odeopt = odeset(
'AbsTol', tol,
'RelTol', tol,
'NonNegative', 1:length(ydefault));
60 [t_iter, ymean_t_iter] = ode_solve(ode_h, trange, ydefault, odeopt, options);
62 xvec_t(end+1:end+size(ymean_t_iter,1),:) = ymean_t_iter;
63 t(end+1:end+size(t_iter,1),:) = t_iter;
64 xvec_it{iter +1} = xvec_t(end,:);
65 movedMassRatio = norm(xvec_it{iter +1} - xvec_it{iter-1 +1}, 1) / 2 / sum(xvec_it{iter-1 +1});
66 T0 = T; %
for next iteration
72 allt = [allt; allt(end)+t];
74 ally = [ally; xvec_t];
77 % check termination condition
80 llmsg = length(lastmsg);
88 if movedMassRatio < iter_tol % converged
89 % stop only
if this is not a transient analysis, in which
case keep
90 % going until the specified end time