I've set up a system of differential equations, obtained after discretizing pde, in the following way
dY(1) = terms_starty;
dY(end) = terms_endy;
dY(2:end-1) = (1./Vector1).*(Matrix1*Y+Matrix2*Y);
dZ(1) = terms_startz;
dZ(end) = terms_endz;
dZ(2:end-1) = (1./Vector1).*(Matrix1*Z+Matrix2*Z);
dYZ = [dY dZ];
I'm solving the above system in MATLAB using ode15s.
odeset('abstol', 1e-10, 'reltol', 1e-9)
[t, s] = ode15s(@(t,s) factory(t,s), tspan , s0, options);
The vector Y,Z is of size ~1200 and the number of differential equations is ~2400
The total simulation time takes around 570s when
odeset('abstol', 1e-10, 'reltol', 1e-9)
is used for error settings and it reduces by 5 times when the default error settings are used. I tried to use the profiler and the ode solver takes around 508 s.
I'd like to know if there are ways using which I can speed up the compute time taken by the ode solver. Also, could someone kindly clarify if the ode solver calls BLAS functions for Matrix operations? I'm using version 2019b of MATLAB.
EDIT:
I'm trying to understand how to generate the jpattern
matrix with the simple example below
syms x y z;
F = [x*y, cos(x*z), log(3*x*z*y)]
v = [x y z]
J = jacobian(F,v)
gives,
J =
[ y, x, 0]
[ -z*sin(x*z), 0, -x*sin(x*z)]
[ 1/x, 1/y, 1/z]
From J I'd like to generate the jpattern
matrix of the following form,
jpattern =
[ 1, 1, 0]
[ 1, 0, 1]
[ 1, 1, 1]
But I couldn't find the appropriate command that I could use to convert J
to the form in jpattern
. Basically, I'm trying to find out a way to assign 1 in place of the non-zero entries in J
. Suggestions on how to do this will be really helpful.
EDIT2: I tried to set up the sparsity pattern in the toy model below,
x0 = [1 0 0 0 0 0 0 0 0 0]';
tspan = 0:0.01:5;
f0 = fun(0, x0);
J = odenumjac(fun,{0 x0}, f0);
sparsity_pattern = sparse(J~=0.);
options = odeset('Stats', 'on', 'JPattern', sparsity_pattern);
[t, sol] = ode15s(@(t,x) fun(t,x), tspan , x0);
plot(t, sol)
function f = fun(t,x)
mat1=[
1 -2 1 0 0 0 0 0 0 0;
0 1 -2 1 0 0 0 0 0 0;
0 0 1 -2 1 0 0 0 0 0;
0 0 0 1 -2 1 0 0 0 0;
0 0 0 0 1 -2 1 0 0 0;
0 0 0 0 0 1 -2 1 0 0;
0 0 0 0 0 0 1 -2 1 0;
0 0 0 0 0 0 0 1 -2 1;
];
mat2 = [
1 -1 0 0 0 0 0 0 0 0;
0 1 -1 0 0 0 0 0 0 0;
0 0 1 -1 0 0 0 0 0 0;
0 0 0 1 -1 0 0 0 0 0;
0 0 0 0 1 -1 0 0 0 0;
0 0 0 0 0 1 -1 0 0 0;
0 0 0 0 0 0 1 -1 0 0;
0 0 0 0 0 0 0 1 -1 0;
];
f(1,1) = 0;
f(2:9,1) = mat1*x + mat2*x;
f(10,1) = 2*(x(end-1) - x(end));
end
Unfortunately, I couldn't figure out how to fix the error
Not enough input arguments.
Error in Untitled>fun (line 36)
f(2:9,1) = mat1*x + mat2*x;
Error in Untitled (line 5)
J = odenumjac(fun,{0 x0}, f0);
Suggestions on how to fix this error will be of great help.
I wasn't sure if the vectorization was done right. So I tried the following as well
function df = fun(t,x)
global mat1 mat2
f(1,:) = 0;
f(2:9,:) = mat1*x + mat2*x;
f(10,:) = 2*(x(end-1) - x(end));
df = [f(1, :); f(2:9, :); f(10, :)];
end
This didn't help me either.
Matrix1
andMatrix2
look like? DoY
andZ
interact (if not, solve two smaller ODEs). $\endgroup$