Program Listing for File implicit_jacobian.m¶
↰ Return to documentation for file (+Indigo/@RungeKutta/implicit_jacobian.m
)
%> Compute the Jacobian of the system of equations:
%>
%> \f[
%> \mathbf{F}_i\left(\mathbf{x}_k + \Delta t \displaystyle\sum_{j=1}^s
%> a_{ij} \mathbf{K}_j, \, \mathbf{K}_i, \, t_k + c_i \Delta t
%> \right) = \mathbf{0}
%> \f]
%>
%> to be solved in the \f$ \mathbf{K} \f$ variable:
%>
%> \f[
%> \dfrac{\partial \mathbf{F}_i}{\partial \mathbf{K}_i} \left(
%> \mathbf{x}_k + \Delta t \displaystyle\sum_{j=1}^s a_{ij} \mathbf{K}_j,
%> \, \mathbf{K}_i, \, t_k + c_i \Delta t
%> \right)
%> \f]
%>
%> \param i Index of the step to be computed.
%> \param x_i States value at \f$ i \f$-th node.
%> \param K Variable \f$ \mathbf{K} \f$ of the system to be solved.
%> \param t_k Time step \f$ t_k \f$.
%> \param d_t Advancing time step \f$ \Delta t\f$.
%>
%> \return The Jacobian of the system of equations to be solved.
%
function out = implicit_jacobian( this, x_k, K_in, t_k, d_t )
% Extract lengths
nc = length(this.m_c);
nx = length(x_k);
K = reshape(K_in, nx, nc);
% Get the number of veils and linear index-1 variables
num_veil = this.m_sys.get_num_veil();
num_sysy = this.m_sys.get_num_sysy();
% The Jacobian is a square nc*nx (i.e., length(K)) matrix
out = eye(nc*nx);
% Loop through each equation of the system
idx = 1:nx;
for i = 1:nc
t_i = t_k + this.m_c(i) * d_t;
x_i = x_k + K * this.m_A(i,:).';
v_i = this.m_sys.v(x_i, t_i);
y_i = this.m_sys.y(x_i, v_i, t_i);
% Compute the Jacobians with respect to x and x_dot
x_dot_i = K(:,i)./d_t;
JF_x = this.m_sys.JF_x(x_i, x_dot_i, y_i, v_i, t_i);
JF_x_dot = this.m_sys.JF_x_dot(x_i, x_dot_i, y_i, v_i, t_i);
% Add the contribution of linear index-1 variables to the Jacobian
if (num_sysy > 0)
JF_x = JF_x + this.m_sys.JF_y(x_i, x_dot_i, y_i, v_i, t_i) * ...
this.m_sys.Jy_x(x_i, v_i, t_i);
end
% Add the contribution of veils to the Jacobian
if (num_veil > 0)
JF_x = JF_x + this.m_sys.JF_v(x_i, x_dot_i, y_i, v_i, t_i) * ...
this.m_sys.Jv_x(x_i, v_i, t_i);
end
% Derivative of F(x_i, K(:,i)/d_t, t_i)
jdx = 1:nx;
for j = 1:nc
% Combine the Jacobians with respect to x and x_dot to obtain the
% Jacobian with respect to K
if (i == j)
out(idx, jdx) = this.m_A(i,j) * JF_x + JF_x_dot./d_t;
else
out(idx, jdx) = this.m_A(i,j) * JF_x;
end
jdx = jdx + nx;
end
idx = idx + nx;
end
end