Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Constrained pendulum problem #36

Open
wants to merge 32 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
9c47f78
Initial Commit of the constrained pendulum problem
AndreyAPopov May 10, 2022
6d54390
very useful fix for lambda
AndreyAPopov May 10, 2022
0caf7cc
added Z0 and fixed jacobia
AndreyAPopov May 10, 2022
afdfa7e
file renaming
AndreyAPopov May 11, 2022
cd25494
Fixes to some of steven's complains
AndreyAPopov May 11, 2022
f072d66
access fix
AndreyAPopov May 11, 2022
dfee988
final fixes
AndreyAPopov May 12, 2022
13cf20d
Added a bunch of derivatives
AndreyAPopov May 12, 2022
0bc36d2
added vectorization
AndreyAPopov May 12, 2022
42d822f
name changes to make everything consistent
AndreyAPopov May 12, 2022
9b2ee98
one more name fix
AndreyAPopov May 12, 2022
a114be8
fixes to names and argument order
AndreyAPopov May 12, 2022
c3463f3
Added Half-Explicit Jacobian and vector products
AndreyAPopov May 13, 2022
1b997dd
Added all jacobians
AndreyAPopov May 14, 2022
3bd98e8
fixes to jacobians
AndreyAPopov May 14, 2022
5fa4f92
Added an initial implementation of a DAE solver
AndreyAPopov May 15, 2022
90bc7af
fixes to DAE method
AndreyAPopov May 15, 2022
c51c478
Some tests.
AndreyAPopov May 16, 2022
46a4436
moved to symmlq
AndreyAPopov May 16, 2022
d23d13d
Moved to LSQR
AndreyAPopov May 16, 2022
8453493
added a bunch of stuff to the SDIRK method
AndreyAPopov May 16, 2022
7ec54c6
Fixed most issues with dae34, and renamed it
AndreyAPopov May 16, 2022
c5cce23
First commit of ESDIRK method.
AndreyAPopov May 17, 2022
ff96669
replace every solver with bicg
AndreyAPopov May 17, 2022
fc51b18
optimize embedded coefficients
AndreyAPopov May 17, 2022
3c01164
Working codes
AndreyAPopov May 19, 2022
e04aa6c
Newton's method control for Lobatto
AndreyAPopov May 19, 2022
5a2cef0
Increase the number of iterations
AndreyAPopov May 19, 2022
73a155a
slight changes to dae43
AndreyAPopov May 19, 2022
026c815
Added Jacobian storage and recomputation criteria. Added a starting a…
AndreyAPopov May 20, 2022
0e45849
Added sparse support and support for Jacobian decompositions
AndreyAPopov May 20, 2022
2d282cc
Made all changes that steven requested
AndreyAPopov May 23, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/+otp/+pendulumdae/+presets/Canonical.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
classdef Canonical < otp.pendulumdae.PendulumDAEProblem
%CANONICAL The constrained pendulum problem
%
% See
% Hairer, E., Roche, M., Lubich, C. (1989). Description of differential-algebraic problems.
% In: The Numerical Solution of Differential-Algebraic Systems by Runge-Kutta Methods.
% Lecture Notes in Mathematics, vol 1409. Springer, Berlin, Heidelberg.
% https://doi.org/10.1007/BFb0093948

methods
function obj = Canonical
tspan = [0; 10];

params = otp.pendulumdae.PendulumDAEParameters;
params.Mass = 1;
params.Length = 1;
params.Gravity = otp.utils.PhysicalConstants.EarthGravity;

y0 = [sqrt(2)/2; sqrt(2)/2; 0; 0; 0; 0; 0];

obj = [email protected](tspan, y0, params);
end
end
end
11 changes: 11 additions & 0 deletions src/+otp/+pendulumdae/PendulumDAEParameters.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
classdef PendulumDAEParameters
%CONSTRAINEDPENDULUMPARAMETERS
properties
%GRAVITY is acceleration due to gravity
Gravity %MATLAB ONLY: (1,1) {mustBeReal, mustBeFinite, mustBePositive} = 9.8
%MASSE of the node of the pendulum
Mass %MATLAB ONLY: (:,1) {mustBeReal, mustBeFinite, mustBePositive} = 1
%LENGTH to the node of the pendulum
Length %MATLAB ONLY: (:,1) {mustBeReal, mustBeFinite, mustBePositive} = 1
end
end
54 changes: 54 additions & 0 deletions src/+otp/+pendulumdae/PendulumDAEProblem.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
classdef PendulumDAEProblem < otp.Problem
%CONSTRAINEDPENDULUM PROBLEM This is a Hessenberg Index-2 DAE problem posed in terms of three constraints
%

properties (SetAccess=protected)
RHSDifferential
RHSAlgebraic
end

properties (Dependent)
Y0Differential
Z0Algebraic
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not opposed to having these, but if we do include this, I think all DAE problems should have these for consistency. Also, I think Y0Algebraic would be better than Z0Algebraic.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't really differentiate the two. Algebraic implies there is no direct differential equation thus it is a variable obtained from differentiation of the constraint. I think it should stay.

Copy link
Member

@Steven-Roberts Steven-Roberts May 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this naming is pretty clear. It's mostly motivated by established naming conventions. For partitioned problems, we use <property><partition name>. E.g.

RHSStiff and RHSNonstiff
jacobianDifferential and jacobianAlgebraic
Y0Position and Y0Velocity

This is nice for autocompletion as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad I misinterpreted what was being proposed. I thought you wanted Y0Differential -> Y0Algebraic not Z0Algebraic -> Y0Algebraic. I agree on the convention you proposed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking of changing it to that already, glad to see we all think alike

end

methods
function obj = PendulumDAEProblem(timeSpan, y0, parameters)
[email protected]('Constrained Pendulum', 7, timeSpan, y0, parameters);
end
end

methods (Access = protected)
function onSettingsChanged(obj)
m = obj.Parameters.Mass;
l = obj.Parameters.Length;
g = obj.Parameters.Gravity;

% get initial energy
initialconstraints = otp.pendulumdae.constraints([], obj.Y0Differential, g, m, l, 0);
E0 = initialconstraints(3);


% The right hand size in terms of x, y, x', y', and three control parameters z
obj.RHS = otp.RHS(@(t, y) otp.pendulumdae.f(t, y, g, m, l, E0), ...
'Mass', @(t, y) otp.pendulumdae.mass(t, y, g, m, l, E0));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the mass matrix is constant, it can be a matrix instead of a function handle. See

'Mass', otp.zlakinetics.mass([], [], k, K, klA, Ks, pCO2, H), ...
for example

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just copying the pendulum problem, which had @(t,y). I will change


obj.RHSDifferential = otp.RHS(@(t, y) otp.pendulumdae.fdifferential(t, y, g, m, l, E0));

obj.RHSAlgebraic = otp.RHS(@(t, y) otp.pendulumdae.constraints(t, y, g, m, l, E0), ...
'Jacobian', @(t, y) otp.pendulumdae.constraintsjacobian(t, y, g, m, l, E0));
end
end

methods
function y0differential = get.Y0Differential(obj)
y0differential = obj.Y0(1:4);
end

function z0algebraic = get.Z0Algebraic(obj)
z0algebraic = obj.Y0(5:end);
end
end

end

14 changes: 14 additions & 0 deletions src/+otp/+pendulumdae/constraints.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
function c = constraints(~, state, g, m, l, E0)

x = state(1, :);
y = state(2, :);
u = state(3, :);
v = state(4, :);

c1 = x.^2 + y.^2 - l^2;
c2 = 2*(x.*u + y.*v);
c3 = m*(g*(y + l) + 0.5*(u.^2 + v.^2)) - E0;

c = [c1; c2; c3];

end
27 changes: 27 additions & 0 deletions src/+otp/+pendulumdae/constraintsjacobian.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
function dc = constraintsjacobian(~, state, g, m, ~, ~)

x = state(1);
y = state(2);
u = state(3);
v = state(4);

dc1dx = 2*x;
dc1dy = 2*y;
dc1du = 0;
dc1dv = 0;

dc2dx = 2*u;
dc2dy = 2*v;
dc2du = 2*x;
dc2dv = 2*y;

dc3dx = 0;
dc3dy = m*g;
dc3du = m*u;
dc3dv = m*v;

dc = [dc1dx, dc1dy, dc1du, dc1dv; ...
dc2dx, dc2dy, dc2du, dc2dv; ...
dc3dx, dc3dy, dc3du, dc3dv];

end
13 changes: 13 additions & 0 deletions src/+otp/+pendulumdae/f.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
function dfull = f(t, statepluscontrol, g, m, l, E0)

state = statepluscontrol(1:4, :);
control = statepluscontrol(5:end, :);

dstate = otp.pendulumdae.fdifferential(t, state, g, m, l, E0) ...
- otp.pendulumdae.constraintsjacobian(t, state, g, m, l, E0).'*control;

c = otp.pendulumdae.constraints(t, state, g, m, l, E0);

dfull = [dstate; c];

end
19 changes: 19 additions & 0 deletions src/+otp/+pendulumdae/fdifferential.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
function dstate = fdifferential(~, state, g, m, ~, ~)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


x = state(1, :);
y = state(2, :);
u = state(3, :);
v = state(4, :);

lxy2 = x.^2 + y.^2;

lambda = (m/lxy2)*(u.^2 + v.^2) - (g/lxy2)*y;

dx = u;
dy = v;
du = -(lambda/m).*x;
dv = -(lambda/m)*y - g/m;

dstate = [dx; dy; du; dv];

end
5 changes: 5 additions & 0 deletions src/+otp/+pendulumdae/mass.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function M = mass(~, ~, ~, ~, ~, ~)

M = [eye(4), zeros(4, 3); zeros(3, 7)];

end