Я делаю временную интеграцию системы ODE, используя жесткий решатель (ode15s). Это работает, но я хочу ускорить процесс.
Система уравнений представлена в виде пространства состояний:
function [dx] = fun(t,x,M,C,K,other_parameters)
% Mx'' + Cx' + Kx = F(t)
% BUNCH OF CALCULATIONS
F = solveP(x,t);
A = [zeros(n) eye(n) ; -M\K -M\C];
b = M\F;
dx = A*x + b
end
Приемная часть здесь - это форсирующая функция F. Она сильно нелинейна и зависит от параметров x и t. Он использует параметры x для решения двумерного уравнения пуассоновского типа (методом конечных объемов). Сила F пропорциональна решению уравнения Пуассона.
function [F] = solveP(x,t)
% initialize solution
Phi = zeros(Ni,Nj);
% solve iteratively
% ...
while (~converged)
% some calculations
% iterative solver
Phi(i,j) = (aE*Phi(i,j+1) + aW*Phi(i,j-1) + aN*Phi(i+1,j) +...
aS*Phi(i-1,j) + S(i,j))/aP;
end
% calculate F
F = sum(Phi(:)); % discrete integration over domain
end
Решение уравнения Пуассона итерационным методом требует начального условия, которое я устанавливаю равным нулю (Phi=zeros(Ni,Nj)
). Я думал, что смогу улучшить скорость вычислений, предоставив лучшую начальную оценку поля ϕ (лучшее начальное условие потребует быстрее, чтобы достичь искомого ответа). Оптимальным начальным условием, которое я могу себе представить (помимо ϕ = 0), является значение поля ϕ, полученное на предыдущей итерации (последнем шаге) решателя од (ϕ(k)_initial=ϕ(k-1)
).
Итог: как мне использовать / сохранить промежуточные значения в решении для оды?
PS: я пытался использовать постоянные переменные, но это не очень хорошее решение. Решатель ode вычисляет функцию в нескольких точках, прежде чем продвинется во времени. Постоянная переменная сохраняет сходящееся поле ϕ каждый раз, когда ода вызывает вызов одефона. Это не совсем то, что я хочу, и на самом деле это дает неправильные ответы, поскольку время идет.