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));
26%rategap = log10(max(nonZeroRates)/min(nonZeroRates)); % if the max rate is InfRate and the min is 1, then rategap = 6
27
28% init ode
29[ode_h, ~] = solver_fluid_odes(sn, N, Mu, Phi, PH, P, S, sn.sched, sn.schedparam, options);
30
31T0 = timespan(1);
32odeopt = odeset('AbsTol', tol, 'RelTol', tol, 'NonNegative', 1:length(xvec_it{1}));
33T = 0;
34while (isfinite(timespan(2)) && T < timespan(2)) || (goon && iter < iter_max)
35 iter = iter + 1;
36 if toc(Tstart) > max_time
37 goon = false;
38 break;
39 end
40
41 % determine entry state vector in e
42 y0 = xvec_it{iter-1 +1};
43
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
46 else
47 T = min(timespan(2),abs(10*iter/min(nonZeroRates)));
48 end
49 trange = [T0, T];
50
51 try
52 if stiff
53 [t_iter, ymean_t_iter] = ode_solve_stiff(ode_h, trange, y0, odeopt, options);
54 else
55 [t_iter, ymean_t_iter] = ode_solve(ode_h, trange, y0, odeopt, options);
56 end
57 catch ME
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);
61 end
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
67
68 if nargout>3
69 if isempty(allt)
70 allt = t;
71 else
72 allt = [allt; allt(end)+t];
73 end
74 ally = [ally; xvec_t];
75 end
76
77 % check termination condition
78
79 if verbose > 0
80 llmsg = length(lastmsg);
81 if llmsg>0
82 for ib=1:llmsg
83 line_printf('\b');
84 end
85 end
86 end
87
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
91 end
92
93 if T >= timespan(2)
94 goon = false;
95 end
96end
97
98end