Skip to content

Commit 10919fa

Browse files
committed
Merge branch 'master' into QG-docs
2 parents 15df5ee + 0b2bf99 commit 10919fa

File tree

160 files changed

+2299
-1162
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

160 files changed

+2299
-1162
lines changed

.github/workflows/docs.yml renamed to .github/workflows/documentation.yml

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Build Documentation
1+
name: Documentation
22

33
on:
44
workflow_dispatch:
@@ -20,24 +20,28 @@ jobs:
2020
runs-on: ubuntu-latest
2121
steps:
2222
- name: Checkout Repo
23-
uses: actions/checkout@v3
23+
uses: actions/checkout@v4
2424

2525
- name: Install Python
26-
uses: actions/setup-python@v4
26+
uses: actions/setup-python@v5
2727
with:
28-
python-version: 3.x
28+
python-version: 3.12
2929
cache: 'pip'
3030

3131
- name: Install Python Packages
3232
working-directory: ./docs
3333
run: make install
3434

35+
- name: Lint
36+
working-directory: ./docs
37+
run: make lint
38+
3539
- name: Build with Sphinx
3640
working-directory: ./docs
3741
run: make
3842

3943
- name: Upload Artifact
40-
uses: actions/upload-pages-artifact@v1
44+
uses: actions/upload-pages-artifact@v3
4145
with:
4246
path: ./docs/build
4347

@@ -51,4 +55,4 @@ jobs:
5155
steps:
5256
- name: Deploy to GitHub Pages
5357
id: deployment
54-
uses: actions/deploy-pages@v2
58+
uses: actions/deploy-pages@v4

.github/workflows/tests.yml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,24 @@ on:
88

99
jobs:
1010
octave:
11-
runs-on: ubuntu-latest
11+
strategy:
12+
matrix:
13+
os: [ubuntu-22.04, ubuntu-24.04]
14+
runs-on: ${{ matrix.os }}
1215
steps:
1316
- name: Checkout Repo
14-
uses: actions/checkout@v3
17+
uses: actions/checkout@v4
18+
1519
- name: Install Octave
1620
run: |
1721
sudo apt-get update
1822
sudo apt-get install -y octave
23+
1924
- name: Run OTP tests
2025
run: octave --eval "addpath(genpath('.')); runalltests"
26+
27+
- name: Install OTP
28+
run: octave --eval "OTP.install"
29+
30+
- name: Load OTP
31+
run: octave --eval "pkg load 'ode test problems'"

CONTRIBUTING.md

Lines changed: 64 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,171 +1,142 @@
11
# Contributing Guide
22

3-
This guide provides instructions for submitting and formatting new code in `OTP`.
3+
This guide provides instructions for submitting and formatting new code in OTP.
44

55
## Submitting Changes
66

7-
Changes to `OTP` should be proposed as a pull request and undergo a review process before being merged. New code must be free of warnings and errors and adhere to the style guidelines (see also [The style guidelines](## Style guidelines)).
7+
Changes to OTP should be proposed as a pull request and undergo a review process before being merged. New code must be free of warnings and errors and adhere to the [style guidelines](#style-guidelines).
88

99
## Creating a Problem
1010

11-
Each problem defines a package under `+otp` that contains all files used by the problem. To add a new test problem follow these steps:
11+
Each problem defines a package under `+otp` that contains all files used by the problem. When creating a new problem we recommend duplicating an existing problem package, e.g., [Lorenz63](https://github.com/ComputationalScienceLaboratory/ODE-Test-Problems/blob/master/toolbox/+otp/+lorenz63) or [Brusselator](https://github.com/ComputationalScienceLaboratory/ODE-Test-Problems/blob/master/toolbox/+otp/+brusselator), then renaming and editing the contents as needed.
1212

13-
1. Check out the latest version of `OTP`:
13+
To add a new test problem from scratch follow these steps:
14+
15+
1. Check out the latest version of OTP:
1416

1517
```bash
1618
git clone https://github.com/ComputationalScienceLaboratory/ODE-Test-Problems.git
1719
cd ODE-Test-Problems/
1820
```
1921

20-
2. Create a new folder in the `src/+opt/` directory. Follow the same naming conventions as the existing problems. Start the name with `+` to maintain the structure of the Matlab/Octave package. Also create a subfolder named `+presets` in the new problem folder:
22+
2. Create a new folder in the `toolbox/+opt/` directory with a name that starts with `+` to indicate it is a package. Also create a subfolder named `+presets` in the new problem folder:
2123

2224
```bash
23-
mkdir src/+opt/+newtest
24-
mkdir src/+opt/+newtest/+presets
25-
cd src/+opt/+newtest/
25+
mkdir toolbox/+opt/+example
26+
cd toolbox/+opt/+example
27+
mkdir +presets
2628
```
2729

28-
3. The minimal set of files needed inside the problem folder to set up a new test problem are:
29-
* The right-hand-side function named as `f.m`
30-
* The problem class to initialize problem objects and its methods and properties
31-
* The parameters class defines the parameters of the new problem
32-
* A `Canonical.m` preset inside the `+presets` subfolder to set the initial condition and parameters in your case
33-
34-
```bash
35-
touch f.m
36-
touch NewTestProblem.m
37-
touch NewTestParameters.m
38-
touch +presets/Canonical.m
39-
```
30+
3. The minimal set of files needed inside the problem folder to set up a new example problem are:
31+
* The right-hand side (RHS) function named as `f.m`
32+
* The problem class to specify properties, override plotting and solver options, and convert parameters into arguments for RHS functions
33+
* The parameters class
34+
* A `Canonical.m` preset inside the `+presets` subfolder to set standard initial condition and parameters.
4035

41-
## The Right-hand-side Structure
36+
```bash
37+
touch f.m ExampleProblem.m ExampleParameters.m +presets/Canonical.m
38+
```
4239

43-
The right-hand-side structure provides various derivatives of the problem. They are implemented in separate function files. The right-hand-side function `f.m`, which is the time-derivative of the state `y` is defined as a function with at least two arguments `f(t,y)`. If the right-hand-side function needs other parameters they can also be passed to this function:
40+
### The RHS Function
4441

45-
```Matlab
42+
The RHS function `f.m`, which is the time-derivative of the state `y`, is defined as a function with at least two arguments. If parameters are needed, they can be added as arguments.
4643

47-
function dy = f(t, y, Param1, ...)
48-
dy = ...
44+
```matlab
45+
function dy = f(t, y, param1, ...)
46+
dy = ...
4947
end
50-
5148
```
5249

53-
For more information about this formulation please refer to our [paper](https://github.com/ComputationalScienceLaboratory/ODE-Test-Problems/blob/master/paper/paper.md).
54-
55-
## The Problem Class
50+
Other functions associated with an `otp.RHS` like the Jacobian and mass matrix should be implemented in separate `.m` files with the same function signature as `f.m`.
5651

57-
A problem package must contain a class named `<Name>Problem.m` that is a subclass of `otp.Problem`. There are two
58-
methods that must be implemented: the constructor and `onSettingsChanged`. Optionally, one can override functions such as `internalPlot` and `internalSolve` to provide problem-specific defaults. Partitioned problems can add custom right-hand-side functions
59-
as class properties with private write access. The property name should start with `RHS`, e.g., `RHSStiff`.
52+
### The Problem Class
6053

61-
The template for a new class of problems called `NewTest` looks like:
54+
A problem package must contain a class named `<Name>Problem.m` that is a subclass of `otp.Problem`. There are two methods that must be implemented: the constructor and `onSettingsChanged`. Optionally, one can override functions such as `internalPlot` and `internalSolve` to provide problem-specific defaults. Partitioned problems can add custom RHS functions as class properties with private write access. The property name should start with `RHS`, e.g., `RHSStiff`.
6255

63-
```Matlab
64-
65-
classdef NewTestProblem < otp.Problem
56+
A basic template for a new class of problems called `Example` looks like
6657

58+
```matlab
59+
classdef ExampleProblem < otp.Problem
6760
methods
68-
function obj = NewTestProblem(timeSpan, y0, parameters)
69-
obj@otp.Problem('New Test', [], timeSpan, y0, parameters);
61+
function obj = ExampleProblem(timeSpan, y0, parameters)
62+
obj@otp.Problem('Example', [], timeSpan, y0, parameters);
63+
% The second argument specifies the number of variables in the problem is arbitrary
7064
end
7165
end
7266
7367
methods (Access=protected)
7468
function onSettingsChanged(obj)
69+
% Parameters are stored in the obj.Parameters structure. We can assign them to individual variables to be
70+
% used in function calls
71+
param1 = obj.Parameters.Param1;
7572
76-
% parameters are stored in the obj.Parameters structure
77-
% We can assign them to individual variables
78-
% to be used in function calls
79-
80-
Param1 = obj.Parameters.Param1; % ...
81-
82-
83-
% set up the right-hand-side function wrapper
84-
obj.RHS = otp.RHS(@(t, y) otp.newtest.f(t, y, Param1), 1:obj.NumVars);
73+
% set up the RHS function wrapper
74+
obj.RHS = otp.RHS(@(t, y) otp.example.f(t, y, param1));
8575
end
8676
8777
% set up internal plot function
8878
function fig = internalPlot(obj, t, y, varargin)
89-
fig = internalPlot@otp.Problem(obj, t, y, ...
90-
'xscale', 'log', 'yscale', 'log', varargin{:});
79+
fig = internalPlot@otp.Problem(obj, t, y, 'xscale', 'log', 'yscale', 'log', varargin{:});
9180
end
9281
9382
% set up internal movie function
9483
function mov = internalMovie(obj, t, y, varargin)
95-
mov = internalMovie@otp.Problem(obj, t, y, ...
96-
'xscale', 'log', 'yscale', 'log', varargin{:});
84+
mov = internalMovie@otp.Problem(obj, t, y,, 'xscale', 'log', 'yscale', 'log', varargin{:});
9785
end
9886
9987
% set up internal solver
10088
function sol = internalSolve(obj, varargin)
10189
% Set tolerances due to the very small scales
102-
sol = internalSolve@otp.Problem(obj, ...
103-
'AbsTol', 1e-50, varargin{:});
90+
sol = internalSolve@otp.Problem(obj, 'AbsTol', 1e-50, varargin{:});
10491
end
10592
end
10693
end
107-
10894
```
10995

110-
## The Parameters Class
111-
112-
A problem package must also contain a class named `<Name>Parameters.m`. It only needs to provide public properties for each of the problem parameters; no constructor or methods are needed. Note that property validation is currently not supported in Octave. Therefore, we use a custom comment syntax that is parsed by the installer to optionally include validation. The following is an example of a parameter class with property validation:
96+
### The Parameters Class
11397

98+
A problem package must also contain a class named `<Name>Parameters.m` that is a subclass of `otp.Parameters`. It needs to provide public properties for each of the problem parameters and a constructor which forwards arguments to the superclass constructor; no methods are needed. Note that property validation is currently not supported in Octave. Therefore, we use a custom comment syntax that is parsed by the installer to optionally include validation. The following is an example of a parameter class with property validation:
11499

115-
```Matlab
116-
117-
classdef NewTestParameters
118-
119-
%NewTestParameters
100+
```matlab
101+
classdef ExampleParameters
120102
properties
121-
Param1 %MATLAB ONLY: (1,1) {mustBeNumeric, mustBeReal, mustBeNonnegative}
103+
Param1 %MATLAB ONLY: (1,1) {mustBeReal, mustBeNonnegative}
122104
end
123-
end
124105
106+
methods
107+
function obj = ExampleParameters(varargin)
108+
obj = obj@otp.Parameters(varargin{:});
109+
end
110+
end
111+
end
125112
```
126113

127-
## Adding presets
128-
129-
Within a problem package, there should be a subpackage named `+presets`. This contains subclasses of `<Name>Problem`
130-
that specify the timespan, initial conditions, and parameters. Typically, only the constructor needs to be implemented
131-
in a preset class.
114+
### Adding presets
132115

133-
In our example, we add the `Canonical.m` preset inside the `+presets` subfolder containing:
116+
Within a problem package, there should be a subpackage named `+presets`. This contains subclasses of `<Name>Problem` that specify the time span, initial conditions, and parameters. Typically, only the constructor needs to be implemented in a preset class.
134117

135-
```Matlab
118+
In our example, we add a `Canonical.m` preset inside the `+presets` subfolder.
136119

137-
classdef Canonical < otp.newtest.NewTestProblem
120+
```matlab
121+
classdef Canonical < otp.example.ExampleProblem
138122
139123
methods
140-
function obj = Canonical
141-
params = otp.newtest.NewTestParameters;
142-
params.Param1 = ...
143-
124+
function obj = Canonical(varargin)
144125
y0 = ...
145126
tspan = ...
146127
147-
obj = obj@otp.newtest.NewTestProblem(tspan, y0, params);
128+
% Specify a default value for Param1 which can be overridden by a name-value pair passed to this constructor
129+
params = otp.example.ExampleParameters('Param1', pi, varargin{:});
130+
131+
obj = obj@otp.example.ExampleProblem(tspan, y0, params);
148132
end
149133
end
150134
end
151-
152-
153135
```
154-
## Copying the Problem Template
155-
156-
When creating a new problem, we
157-
recommend duplicating an existing problem package, then renaming and editing the contents as needed.
158-
159-
[This is a minimal example of](https://github.com/ComputationalScienceLaboratory/ODE-Test-Problems/tree/81cf4e473c34fe04d70280d0a78222a4c75fd775/src/%2Botp/%2Bnewtest) the completed test problem started in this tutorial. It implements the trivial ODE $y'(t) = 1, y(0) = 1$ and can be used as a template to implement simple test problems.
160-
161-
162-
An example of a more sophisticated problem with implemented Jacobians is the [Lorenz63 problem](https://github.com/ComputationalScienceLaboratory/ODE-Test-Problems/blob/master/src/+otp/+lorenz63). For an example of split right-hand-side PDE, see [the Brusselator problem]( https://github.com/ComputationalScienceLaboratory/ODE-Test-Problems/blob/master/src/+otp/+brusselator).
163-
164136

165137
## Style Guidelines
166138

167-
In order for this project to maintain a consistent coding style, the following conventions should be used. These
168-
standards match those most commonly used in MATLAB's code and documentation.
139+
In order for this project to maintain a consistent coding style, the following conventions should be used. These standards largely match those most commonly used in MATLAB's code and documentation.
169140

170141
### Line Formatting
171142

@@ -205,8 +176,7 @@ car = struct('make', 'Ford', 'modelYear', 2020);
205176

206177
### Packages
207178

208-
Package names should be completely lowercase and start with a plus symbol. No capitalization or special character is
209-
used to distinguish between words.
179+
Package names should be completely lowercase and start with a plus symbol. No capitalization or special character is used to distinguish between words.
210180

211181
```matlab
212182
% Example
@@ -216,8 +186,7 @@ help otp.utils.PhysicalConstants
216186

217187
### Classes
218188

219-
Class names and properties should be written in Pascal case. When the name contains an acronym, all letters should be
220-
capitalized. Methods should be written in camel case.
189+
Class names and properties should be written in Pascal case. When the name contains an acronym, all letters should be capitalized. Methods should be written in camel case.
221190

222191
```matlab
223192
% Examples
@@ -239,7 +208,3 @@ classdef ODETestProblems
239208
...
240209
end
241210
```
242-
243-
244-
## Creating Documentation
245-

DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Name: ODE Test Problems
2-
Version: 0.0.1
3-
Date: May 10, 2023
2+
Version: 0.3.0
3+
Date: March 26, 2024
44
depends: octave (>= 6.4.0)
55
Author: Steven Roberts, Andrey A. Popov, Arash Sarshar, Adrian Sandu
66
Maintainer: Steven Roberts

0 commit comments

Comments
 (0)