LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
solver_fluid_iteration.m
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)
3
4% Copyright (c) 2012-2026, Imperial College London
5% All rights reserved.
6
7iter_max = options.iter_max;
8verbose = options.verbose;
9tol = options.tol;
10iter_tol = options.iter_tol;
11stiff = options.stiff;
12timespan = options.timespan;
13
14goon = true; % max stiff solver
15iter = 0;
16allt=[];
17ally =[];
18lastmsg = '';
19t=[];
20xvec_t=[];
21% heuristic to select stiff or non-stiff ODE solver
22nonZeroRates = slowrate(:);
23nonZeroRates = nonZeroRates( nonZeroRates >tol );
24
25nonZeroRates = nonZeroRates(isfinite(nonZeroRates));
26if isempty(nonZeroRates)
27 nonZeroRates = 1; % fallback when all rates are zero or infinite
28end
29%rategap = log10(max(nonZeroRates)/min(nonZeroRates)); % if the max rate is InfRate and the min is 1, then rategap = 6
30
31% init ode
32[ode_h, ~] = solver_fluid_odes(sn, N, Mu, Phi, PH, P, S, sn.sched, sn.schedparam, options);
33
34T0 = timespan(1);
35odeopt = odeset('AbsTol', tol, 'RelTol', tol, 'NonNegative', 1:length(xvec_it{1}));
36T = 0;
37while (isfinite(timespan(2)) && T < timespan(2)) || (goon && iter < iter_max)
38 iter = iter + 1;
39 if toc(Tstart) > max_time
40 goon = false;
41 break;
42 end
43
44 % determine entry state vector in e
45 y0 = xvec_it{iter-1 +1};
46
47 if iter == 1 % first iteration
48 T = min(timespan(2),abs(10/min(nonZeroRates))); % solve ode until T = 1 event with slowest exit rate
49 else
50 T = min(timespan(2),abs(10*iter/min(nonZeroRates)));
51 end
52 trange = [T0, T];
53
54 try
55 if stiff
56 [t_iter, ymean_t_iter] = ode_solve_stiff(ode_h, trange, y0, odeopt, options);
57 else
58 [t_iter, ymean_t_iter] = ode_solve(ode_h, trange, y0, odeopt, options);
59 end
60 catch ME
61 line_printf('\nThe initial point is invalid, Fluid solver switching to default initialization.');
62 odeopt = odeset('AbsTol', tol, 'RelTol', tol, 'NonNegative', 1:length(ydefault));
63 [t_iter, ymean_t_iter] = ode_solve(ode_h, trange, ydefault, odeopt, options);
64 end
65 xvec_t(end+1:end+size(ymean_t_iter,1),:) = ymean_t_iter;
66 t(end+1:end+size(t_iter,1),:) = t_iter;
67 xvec_it{iter +1} = xvec_t(end,:);
68 movedMassRatio = norm(xvec_it{iter +1} - xvec_it{iter-1 +1}, 1) / 2 / sum(xvec_it{iter-1 +1});
69 T0 = T; % for next iteration
70
71 if nargout>3
72 if isempty(allt)
73 allt = t;
74 else
75 allt = [allt; allt(end)+t];
76 end
77 ally = [ally; xvec_t];
78 end
79
80 % check termination condition
81
82 if verbose > 0
83 llmsg = length(lastmsg);
84 if llmsg>0
85 for ib=1:llmsg
86 line_printf('\b');
87 end
88 end
89 end
90
91 if movedMassRatio < iter_tol % converged
92 % stop only if this is not a transient analysis, in which case keep
93 % going until the specified end time
94 end
95
96 if T >= timespan(2)
97 goon = false;
98 end
99end
100
101end