Warning: This document is for an old version of WecOptTool.

2. Example

This section explains and expands upon the example.m example file provided in the root directory of the WecOptTool source code. This example considers the DOE Reference Model 3 (RM3) device.

See the entire example file
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
% Copyright 2020 National Technology & Engineering Solutions of Sandia, 
% LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the 
% U.S. Government retains certain rights in this software.
%
% This file is part of WecOptTool.
% 
%     WecOptTool is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
% 
%     WecOptTool is distributed in the hope that it will be useful,
%     but WITHOUT ANY WARRANTY; without even the implied warranty of
%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%     GNU General Public License for more details.
% 
%     You should have received a copy of the GNU General Public License
%     along with WecOptTool.  If not, see <https://www.gnu.org/licenses/>.

%% Suppress warnings
warning('off', 'WaveSpectra:NoWeighting')

%% Create an RM3 study object
study = WecOptTool.RM3Study();

%% Create Bretschnider spectrum from WAFO
%S = bretschneider([],[8,10],0);

%% Alternatively load a single example spectrum
% S = WecOptLib.tests.data.exampleSpectrum();

%% Or load an example with multiple sea-states (8 differing spectra)
S = WecOptLib.tests.data.example8Spectra();

%% Add spectra to study
study.addSpectra(S);

%% Add a controller to the study
cc = WecOptTool.control.ComplexConjugate();
study.addControl(cc);

%% Add geometry design variables (parametric)
x0 = [5, 7.5, 1.125, 42];
lb = [4.5, 7, 1.00, 41];
ub = [5.5, 8, 1.25, 43];

parametric = WecOptTool.geom.Parametric(x0, lb, ub);
study.addGeometry(parametric);

%% Add geometry design variables (scalar)
% x0 = 1.;
% lb = 0.5;
% ub = 2;
% 
% scalar = WecOptTool.geom.Scalar(x0, lb, ub);
% study.addGeometry(scalar);

%% Set up some optimisation options for fmincon
options = optimoptions('fmincon');
options.MaxFunctionEvaluations = 5; % set artificial low for fast running
options.UseParallel = true;

%% Run the study
WecOptTool.run(study, options);

%% Print the results
WecOptTool.result(study);

%% Plot the results
WecOptTool.plot(study);

%% Re-enable warnings
warning('on', 'WaveSpectra:NoWeighting')

The general concept of WecOptTool is illustrated in the diagram below. In the upper left-hand corner, an optimization algorithm controls the selection of a set of design variables. In this diagram, some geometric design variables, \(r_1, r_2, d_1, d_2\), are considered along with constraints on the power take-off (PTO) max force, \(F_{max}\), and max stroke \(\Delta x_{max}\) and an operational constraint, \(H_{s,max}\). The device defined by these design variables is passed to the grey evaluation block. Here, Nemoh is used to compute the linear wave-body interaction properties using the boundary element method (BEM). Next, using these properties and some set of sea states, one of three controllers (ProportionalDamping, ComplexConjugate, PseudoSpectral) are used to compute the resulting dynamics. From on these dynamics and some model for cost (e.g., based on the size dimensions and the capabilities of the PTO) can be combine to produce an objective function, which is returned to the optimization solver.

Conceptual illustration of WecOptTool functionality

2.1. Create an RM3Study Object

The RM3Study class allows the user to configure a simulation to their specifications. Once instantiated, an RM3Study object can be modified using other classes (as described below), and once prepared is passed to the main functions of the toolbox.

22
warning('off', 'WaveSpectra:NoWeighting')

2.2. Define a Sea-State

WecOptTool can simulate single or multiple spectra sea states, where weightings can be provided to indicate the relative likelihood of each spectra. The following lines from example.m provide means of using the WAFO MATLAB toolbox or preset spectra from WecOptTool.

25
26
27
28
29
30
31
study = WecOptTool.RM3Study();

%% Create Bretschnider spectrum from WAFO
%S = bretschneider([],[8,10],0);

%% Alternatively load a single example spectrum
% S = WecOptLib.tests.data.exampleSpectrum();

Spectra are formatted following the convention of the WAFO MATLAB toolbox, but can be generated in via any means (e.g., from buoy measurements) as long as the structure includes the S.S, S.w, and S.phi fields.

S =

  struct with fields:

       S: [257×1 double]
       w: [257×1 double]
      tr: []
       h: Inf
    type: 'freq'
     phi: 0
    norm: 0
    note: 'Bretschneider, Hm0 = 4, Tp = 5'
    date: '25-Mar-2020 13:08:28'

In the active code above from example.m, there are eight spectra loaded into a struct array. These can be plotted using standard MATLAB commands.

figure
hold on
grid on
arrayfun(@(x) plot(x.w,x.S,'DisplayName',x.note), S)
legend()
xlim([0,3])
xlabel('Freq. [rad/s]')
ylabel('Spect. density [m^2 rad/s]')
Eight spectra consider in example.m

The desired spectrum or spectra can then be added to the study object.

34
S = WecOptLib.tests.data.example8Spectra();

2.3. Add a controller to the study

WecOptTool allows for three types of controllers:

  • ProportionalDamping: Resistive damping (i.e., a proportional feedback on velocity) (see, e.g., [Falnes]). Here, the power take-off (PTO) force is set as

    \[F_u(\omega) = -B_{PTO}(\omega)u(\omega)\]

    where \(B_{PTO}\) is a constant chosen to maximize absorbed power and \(u(\omega)\) is the velocity.

  • ComplexConjugate: Optimal power absorption through impedance matching (see, e.g., [Falnes]). The intrinsic impedance is given by

    \[Z_i(\omega) = B(\omega) + i \left( \omega{}(m + A(\omega)) - \frac{K_{HS}}{\omega}\right) ,\]

    where \(\omega\) is the radial frequency, \(B(\omega)\) is the radiation damping, \(m\) is the rigid body mass, \(A(\omega)\) is the added mass, and \(K_{HS}\) is the hydrostatic stiffness. Optimal power transfer occurs when the PTO force, \(F_u\) is set such that

    \[F_u(\omega) = -Z_i^*(\omega)u(\omega) ,\]

    where \(u(\omega)\) is the velocity.

  • PseudoSpectral: Constrained optimal power absorption [Bacelli]. This is a numerical optimal control algorithm capable of dealing with both constraints and nonlinear dynamics. This approach is based on pseudo spectral optimal control.

The controllers are defined as classes in the control sub-package.

37
38
39
study.addSpectra(S);

%% Add a controller to the study

2.4. Define design variables

As shown in the diagram below, for RM3 study considered in example.m the design variables are the radius of the surface float, r1, the radius of the heave plate, r2, the draft of the surface float, d1, and the depth of the heave plate, d2, such that x = [r1, r2, d1, d2]. The optimization algorithm will attempt to find the values of x that minimize the objective function.

Note

Objective function: The built-in objective function of example.m is set to maximize absorbed power. This function can be altered better approximate a more meaningful objective (e.g., levelized cost of energy).

RM3 device parametric dimensions

The initial values,``x0``, lower bounds, lb, and upper bounds, ub of the design variables can be set as follows.

41
42
43
44
45
46
study.addControl(cc);

%% Add geometry design variables (parametric)
x0 = [5, 7.5, 1.125, 42];
lb = [4.5, 7, 1.00, 41];
ub = [5.5, 8, 1.25, 43];

Alternatively, a simpler study with a single scalar design variable can be employed. In this case, instead of scaling various dimensions of the device individually, the entire device is scaled based on a single design variable.

49
50
51
52
53
54
55
study.addGeometry(parametric);

%% Add geometry design variables (scalar)
% x0 = 1.;
% lb = 0.5;
% ub = 2;
% 

The options for design variables are defined as classes in the geom sub-package.

2.5. Set optimization solver and options

MATLAB’s fmincon optimization solver is used in example.m.

Note

The MaxFunctionEvaluations is set to 5 in example.m to permit relatively quick runs, but can be increased to allow for a potentially better solution (with the other options left as-is, this should require 150 function evaluations).

Progression of objective function value for RM3 example
57
58
59
60
% study.addGeometry(scalar);

%% Set up some optimisation options for fmincon
options = optimoptions('fmincon');

2.6. Run the study and view results

The study can be run() and reviewed (with result() and plot()) as follows:

62
63
64
65
66
67
68
options.UseParallel = true;

%% Run the study
WecOptTool.run(study, options);

%% Print the results
WecOptTool.result(study);

From result(), we can see that the study has produced the following design.

Optimal solution is:
r1: 5 [m]
r2: 7.5 [m]
d1: 1.125 [m]
d2: 42 [m]
Optimal function value is: 2202421.2193 [W]

From plot(), we can review the spectral distribution of energy absorbed by the resulting design for each of the eight sea states.

Absorbed Spectral power distribution for each sea state
[Falnes](1, 2) Falnes, Johannes. Ocean waves and oscillating systems: linear interactions including wave-energy extraction. Cambridge University Press, 2002.
[Bacelli]Bacelli, Giorgio, and John V. Ringwood. “Numerical optimal control of wave energy converters.” IEEE Transactions on Sustainable Energy 6.2 (2014): 294-302.