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 3 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
22 changes: 22 additions & 0 deletions src/+otp/+constrainedpendulum/+presets/Canonical.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
classdef Canonical < otp.constrainedpendulum.ConstrainedPendulumProblem
%CANONICAL The constrained pendulum problem
%
% See
% Ascher, Uri. "On symmetric schemes and differential-algebraic equations."
% SIAM journal on scientific and statistical computing 10.5 (1989): 937-949.
Copy link
Member

Choose a reason for hiding this comment

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

Is this the right source? I don't see anything on a pendulum.

Copy link
Member

@amitns122 amitns122 May 11, 2022

Choose a reason for hiding this comment

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

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

That is the pendulum problem source.

The Ascher book has a nice formulation as a Hessenberg indeex 2 DAE( linear algebraic variables) we use.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah the citation is wrong.


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

params = otp.constrainedpendulum.ConstrainedPendulumParameters;
params.Mass = 1;
params.Length = 1;
params.Gravity = otp.utils.PhysicalConstants.EarthGravity;

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

obj = [email protected](tspan, y0, params);
Copy link
Member

Choose a reason for hiding this comment

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

Will the solve functionality be disabled for this problem?

Copy link
Member Author

Choose a reason for hiding this comment

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

That is an interesting question. In theory we should be able to add our own small method to OTP to handle these cases

Copy link
Member

Choose a reason for hiding this comment

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

Good point. Here's one idea: Add a HighIndexDAE property to https://github.com/ComputationalScienceLaboratory/ODE-Test-Problems/blob/master/src/%2Botp/%2Butils/Solver.m which simply throws an error message that high-index DAEs are not supported by matlab solvers. Eventually when we have a constrained mechanical system problem, we will support RHS reduced to index-1 which can rely on built-in solvers.

end
end
end
11 changes: 11 additions & 0 deletions src/+otp/+constrainedpendulum/ConstrainedPendulumParameters.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
classdef ConstrainedPendulumParameters
%CONSTRAINEDPENDULUMPARAMETERS
properties
%Gravity defines the magnitude of acceleration towards the ground
Gravity %MATLAB ONLY: (1,1) {mustBeNonnegative}
%Mass defines the mass of the pendulum
Mass %MATLAB ONLY: (1,1) {mustBeNonnegative}
Copy link
Member

Choose a reason for hiding this comment

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

Sharper validation: {mustBeReal, mustBeFinite, mustBePositive}

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Good idea

%Length defines the length of the pendulum
Length %MATLAB ONLY: (1,1) {mustBeNonnegative}
end
end
35 changes: 35 additions & 0 deletions src/+otp/+constrainedpendulum/ConstrainedPendulumProblem.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
classdef ConstrainedPendulumProblem < otp.Problem
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps just PendulumDAEProblem.

Copy link
Member

Choose a reason for hiding this comment

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

This class ought to override internalIndex2label

Copy link
Member Author

Choose a reason for hiding this comment

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

Agree with both

%CONSTRAINEDPENDULUM PROBLEM This is a Hessenberg Index-2 DAE problem posed in terms of three constraints
%

properties
Copy link
Member

Choose a reason for hiding this comment

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

These should have SetAccess = private or protected

Constraints
ConstraintsJacobian
Z0 = [0; 0; 0];
end

methods
function obj = ConstrainedPendulumProblem(timeSpan, y0, parameters)
[email protected]('Constrained Pendulum', 4, 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.constrainedpendulum.constraints([], obj.Y0, g, m, l, 0);
E0 = initialconstraints(3);

obj.RHS = otp.RHS(@(t, y) otp.constrainedpendulum.f(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.

This RHS will lead to confusion as a call to solve will not enforce constraints, right? Ideally, RHS should be in a form that a built-in solver can integrate, but we can let that slide for an index-2 DAE. I suggest the default RHS should use a mass matrix and an f that operates on the full state (diff and alg). Then there can be a RHSDifferential and RHSAlgebraic to get the individual pieces.

Copy link
Member

Choose a reason for hiding this comment

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

Also it looks like 'Vectorized', 'on' can be added to RHS

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 agree with this


obj.Constraints = @(t, y) otp.constrainedpendulum.constraints(t, y, g, m, l, E0);
obj.ConstraintsJacobian = @(t, y) otp.constrainedpendulum.constraintsjacobian(t, y, g, m, l, E0);

end
end
end

14 changes: 14 additions & 0 deletions src/+otp/+constrainedpendulum/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/+constrainedpendulum/constraintsjacobian.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
function dc = constraintsjacobian(~, state, g, m, ~, ~)
Copy link
Member

@Steven-Roberts Steven-Roberts May 11, 2022

Choose a reason for hiding this comment

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

What Jacobian is this exactly? For the DAE
y' = f(y, z)
0 = g(y)
is it g_y or f_z*g_y

Copy link
Member

@amitns122 amitns122 May 11, 2022

Choose a reason for hiding this comment

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

in this formulation. y' = fhat(y) - ((g_y)^T)*z. T is transpose.

so g_y * f_z = g_y*((g_y)^T)

Copy link
Member Author

Choose a reason for hiding this comment

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

this jacobian is actually just g_y

Copy link
Member

Choose a reason for hiding this comment

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

Is this to be the standard for otp when getting the Jacobian for Half-Explicit methods? Or is this an internal functionality of the problem?

Copy link
Member Author

Choose a reason for hiding this comment

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

if the problem is posed in terms of invariants, this should be standard. I might rename it to invariantJacobian


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
19 changes: 19 additions & 0 deletions src/+otp/+constrainedpendulum/f.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
function dstate = f(~, state, g, m, l, ~)

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