├── .github
└── pull_request_template.md
├── .gitignore
├── .travis.yml
├── .travis
└── key.enc
├── COPYING
├── README.md
├── dependencyCheck.m
├── docs
├── _static
│ ├── WecOptToolFlowChart.svg
│ ├── WecOptToolFlowChartCode.svg
│ ├── WecOptTool_algorithmDiagram.svg
│ ├── WecOptTool_webinar_2020_09_29.pdf
│ ├── example_meshes.svg
│ ├── example_optimplotfval.svg
│ ├── example_rm3Parametric.svg
│ ├── example_spectra.svg
│ ├── example_spectralPowerPlot.svg
│ └── theme_overrides.css
├── conf.py
├── contents.rst
├── index.rst
└── user
│ ├── 1setup.rst
│ ├── 2optimization.rst
│ ├── 3model.rst
│ ├── 4cite.rst
│ ├── 5resources.rst
│ ├── 6api.rst
│ ├── 7license.rst
│ ├── 8references.rst
│ └── WecOptTool_refs.bib
├── examples
├── RM3
│ ├── RM3_BEM.mat
│ ├── basic.m
│ ├── designDevice.m
│ ├── optimization.m
│ └── simulateDevice.m
└── WaveBot
│ ├── Performance.m
│ ├── README.md
│ ├── WaveBot_caseA.m
│ ├── WaveBot_caseB.m
│ ├── WaveBot_caseC.m
│ ├── designDevice.m
│ └── simulateDevice.m
├── installNemoh.m
├── runTests.m
├── tests
├── AutoFolderMule.m
├── AutoFolderTest.m
├── PlotsTest.m
├── SeaStateTest.m
├── base
│ └── TempFolderTest.m
├── examples
│ ├── RM3
│ │ ├── ExamplesTest.m
│ │ ├── ParametricTest.m
│ │ ├── optionsTest.m
│ │ └── parametricBugTest.m
│ └── WaveBot
│ │ └── ExamplesTest.m
├── math
│ └── bisectionTest.m
├── meshes.mat
├── meshsolver
│ ├── getNemohCylinderTest.m
│ ├── getNemohSphereTest.m
│ └── getNemohTest.m
├── scriptsTest.m
├── system
│ ├── getFoldersTest.m
│ ├── hasToolboxTest.m
│ ├── isParallelTest.m
│ ├── readConfigTest.m
│ └── writeConfigTest.m
├── testHydrodynamics.m
└── validation
│ ├── mustBeEqualLengthTest.m
│ └── mustBeFunctionHandleTest.m
└── toolbox
└── +WecOptTool
├── +base
├── Mesher.m
├── NEMOH.m
├── Solver.m
└── TempFolder.m
├── +geometry
└── existingNEMOH.m
├── +math
├── bisection.m
└── isClose.m
├── +mesh
└── AxiMesh.m
├── +plot
├── plotMesh.m
└── powerPerFreq.m
├── +solver
├── NEMOH.m
├── nemohcalbody.txt
├── nemohcalfooter.txt
└── nemohcalheader.txt
├── +system
├── getFolders.m
├── getSrcRootPath.m
├── getUserPath.m
├── hasToolbox.m
├── isParallel.m
├── readConfig.m
├── rmdirRetry.m
└── writeConfig.m
├── +validation
├── mustBeEqualLength.m
└── mustBeFunctionHandle.m
├── +vendor
└── +WEC_Sim
│ ├── LICENSE
│ ├── NOTICE
│ ├── Normalize.m
│ └── Read_NEMOH.m
├── AutoFolder.m
├── Hydrodynamics.m
├── SeaState.m
├── data
├── 8spectra.mat
└── spectrum.mat
├── mesh.m
└── solver.m
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ## Description
2 |
3 | Please include a summary of the change and which (if any) issue is fixed.
4 |
5 | Fixes # (issue)
6 |
7 | ## Checklist:
8 |
9 | - [ ] All new files contain the GPL header
10 | - [ ] If `examples/RM3/optimization.m` has been modified, the content / line
11 | numbers in `docs/user/optimization.rst` are still valid or have been fixed
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.aux
2 | *.fls
3 | *.lof
4 | *.log
5 | *.out
6 | *.synctex.gz
7 | *.synctex
8 | *.blg
9 | *.lot
10 | *.bbl
11 | *.fdb_latexmk
12 | Thumbs.db
13 | *.DS_Store
14 | *.dvi
15 | *.tiw
16 | *.toc
17 | *.dmp
18 | *.bak
19 | *.tps
20 | *.tcp
21 | *.asv
22 | *.m~
23 | *.spl
24 | *.orig
25 |
26 | # NEMOH
27 | ~nemoh_runs/
28 |
29 | # Tests
30 | test_results/
31 | test_results.pdf
32 |
33 | # local sphinx build folder
34 | docs/_build
35 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 |
2 | language: minimal
3 |
4 | stages:
5 | - test
6 | - pages
7 |
8 | jobs:
9 | include:
10 | - stage: test
11 | language: matlab
12 | before_install:
13 | - sudo apt-get -y install gfortran
14 | install:
15 | - git clone --depth 1 https://github.com/LHEEA/Nemoh.git NEMOH
16 | - cd NEMOH
17 | - make
18 | - cd ..
19 | - matlab -batch "addpath(genpath('toolbox')), savepath pathdef.m;"
20 | - matlab -batch "installNemoh('$TRAVIS_BUILD_DIR/NEMOH/bin'), dependencyCheck;"
21 | script:
22 | - matlab -batch "results = runTests('reportHTML', false, 'reportPDF', false), assertSuccess(results);"
23 | if: branch = master
24 | - stage: pages
25 | language: python
26 | install:
27 | - pip install click colorama colorclass future "sphinx==1.8.5" "sphinxcontrib-bibtex==0.4.2"
28 | sphinx_rtd_theme sphinxcontrib-matlabdomain
29 | - pip install git+git://github.com/SuperKogito/sphinxcontrib-pdfembed
30 | - pip install https://github.com/H0R5E/sphinxcontrib-versioning/archive/v1.8.5_support.zip
31 | script:
32 | - eval "$(ssh-agent -s)"; touch .travis/key; chmod 0600 .travis/key
33 | - openssl aes-256-cbc -d -K $encrypted_c97e05834f48_key -iv $encrypted_c97e05834f48_iv < .travis/key.enc > .travis/key
34 | && ssh-add .travis/key # Use && to prevent ssh-add from prompting during pull requests.
35 | - git config --global user.email "builds@travis-ci.com"
36 | - git config --global user.name "Travis CI"
37 | - git remote set-url --push origin "git@github.com:$TRAVIS_REPO_SLUG"
38 | - sphinx-versioning push -abt -e .nojekyll -e README.md docs gh-pages .
39 | if: (branch = master AND type = push) OR tag IS present
40 |
--------------------------------------------------------------------------------
/.travis/key.enc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SNL-WaterPower/WecOptTool-MATLAB/0a9faa189f8570444fac5ebe0da2a9fcd94958eb/.travis/key.enc
--------------------------------------------------------------------------------
/dependencyCheck.m:
--------------------------------------------------------------------------------
1 | function dependencyCheck()
2 | % Check that all dependencies are licensed and installed
3 |
4 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
5 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
6 | % U.S. Government retains certain rights in this software.
7 | %
8 | % This file is part of WecOptTool.
9 | %
10 | % WecOptTool is free software: you can redistribute it and/or
11 | % modify it under the terms of the GNU General Public License as
12 | % published by the Free Software Foundation, either version 3 of
13 | % the License, or (at your option) any later version.
14 | %
15 | % WecOptTool is distributed in the hope that it will be useful,
16 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | % GNU General Public License for more details.
19 | %
20 | % You should have received a copy of the GNU General Public
21 | % License along with WecOptTool. If not, see
22 | % .
23 |
24 | import WecOptTool.system.hasToolbox
25 |
26 | allfoundflag = true;
27 |
28 | fprintf('\nWecOptTool Dependency Checker\n');
29 | fprintf('-------------------------------\n');
30 |
31 | %% Required Products
32 |
33 | fprintf('\n');
34 | fprintf('Required\n');
35 | fprintf('--------\n');
36 |
37 | %% Optimisation Toolbox
38 |
39 | [optimBoxFound, ...
40 | optimBoxLicensed, ...
41 | optimBoxInstalled] = hasToolbox("Optimization_Toolbox", ...
42 | "Optimization Toolbox");
43 |
44 | print_dependency("Optimization Toolbox", ...
45 | optimBoxInstalled, ...
46 | optimBoxLicensed);
47 |
48 | allfoundflag = allfoundflag && optimBoxFound;
49 |
50 | %% Nemoh
51 |
52 | nemohExistFlag = WecOptTool.base.NEMOH.isNemohInPath();
53 | print_dependency("NEMOH", nemohExistFlag);
54 |
55 | %% Optional Products
56 |
57 | fprintf('\n');
58 | fprintf('Optional\n');
59 | fprintf('--------\n');
60 |
61 | %% Parallel Computing Toolbox
62 |
63 | [~, ...
64 | parallelBoxLicensed, ...
65 | parallelBoxInstalled] = hasToolbox("Distrib_Computing_Toolbox", ...
66 | "Parallel Computing Toolbox");
67 |
68 | print_dependency("Parallel Toolbox", ...
69 | parallelBoxInstalled, ...
70 | parallelBoxLicensed);
71 |
72 | %% Global Optimization Toolbox
73 |
74 | [~, ...
75 | globOptBoxLicensed, ...
76 | globOptBoxInstalled] = hasToolbox("GADS_Toolbox", ...
77 | "Global Optimization Toolbox");
78 |
79 | print_dependency("Global Optimization Toolbox", ...
80 | globOptBoxInstalled, ...
81 | globOptBoxLicensed);
82 |
83 | %% WAFO
84 |
85 | wafoFunction = 'bretschneider';
86 | wafoPath = fullfile('wafo', 'spec','bretschneider.m');
87 |
88 | wafoCheck = lower(which(wafoFunction));
89 | wafoInstalled = contains(wafoCheck, wafoPath) && ...
90 | (exist(wafoCheck, 'file') == 2);
91 |
92 | print_dependency("WAFO", wafoInstalled);
93 |
94 | %% End matter
95 |
96 | fprintf('\n')
97 |
98 | % Warn if execution not possible
99 | if ~allfoundflag
100 | warning("Mandatory dependencies are missing!")
101 | end
102 |
103 | end
104 |
105 | function print_dependency(name, installed, licensed, options)
106 |
107 | arguments
108 | name
109 | installed
110 | licensed = true
111 | options.columns = 45
112 | end
113 |
114 | name = name + ":";
115 |
116 | if licensed && installed
117 | nChars = options.columns - 6;
118 | fprintf('%-*s Found\n', nChars, name);
119 | elseif ~licensed && installed
120 | nChars = options.columns - 11;
121 | fprintf('%-*s Unlicensed\n', nChars, name);
122 | else
123 | nChars = options.columns - 14;
124 | fprintf('%-*s Not Installed\n', nChars, name);
125 | end
126 |
127 | end
128 |
--------------------------------------------------------------------------------
/docs/_static/WecOptTool_webinar_2020_09_29.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SNL-WaterPower/WecOptTool-MATLAB/0a9faa189f8570444fac5ebe0da2a9fcd94958eb/docs/_static/WecOptTool_webinar_2020_09_29.pdf
--------------------------------------------------------------------------------
/docs/_static/theme_overrides.css:
--------------------------------------------------------------------------------
1 | /* override table width restrictions */
2 | @media screen and (min-width: 767px) {
3 |
4 | .wy-table-responsive table td {
5 | /* !important prevents the common CSS stylesheets from overriding
6 | this as on RTD they are loaded after this stylesheet */
7 | white-space: normal !important;
8 | }
9 |
10 | .wy-table-responsive {
11 | overflow: visible !important;
12 | }
13 | }
14 |
15 | li {
16 | text-align:left;
17 | }
18 |
19 | body {
20 | text-align:justify;
21 | }
22 |
23 | clickme {
24 | color: #2980b9;
25 | text-decoration: none;
26 | cursor: pointer;
27 | }
28 |
--------------------------------------------------------------------------------
/docs/contents.rst:
--------------------------------------------------------------------------------
1 | .. toctree::
2 | :maxdepth: 1
3 | :numbered:
4 | :caption: User Guide
5 |
6 | user/1setup
7 | user/2optimization
8 | user/3model
9 | user/4cite
10 | user/5resources
11 | user/6api
12 | user/7license
13 | user/8references
14 |
15 | .. toctree::
16 | :hidden:
17 | :caption: External
18 |
19 | GitHub Repository
20 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | ##########
2 | WecOptTool
3 | ##########
4 |
5 | The WEC Design Optimization MATLAB Toolbox (WecOptTool) allows users to perform wave energy converter (WEC) device design optimization studies while including different control strategies.
6 | In particular, this tool's key feature is the usage of a pseudo spectral solution method capable of dealing with both constraints and nonlinear dynamics.
7 | This allows for the optimization study to find the best possible power capture performance within the system constraints (e.g., maximum power take-off force).
8 |
9 | Applications of WecOptTool include design optimization studies of the `WaveBot`_ point absorber and `RM3`_ point absorber (see the :ref:`optimization` section for further details).
10 | These examples illustrate how WecOptTool can be applied to arbitrary devices of the user's choosing (see the :ref:`model` section).
11 |
12 | Developers
13 | ==========
14 |
15 | WecOptTool is developed by `Sandia National Laboratories`_, with support from `Data Only Greater`_.
16 | The developers would also like to acknowledge benefit from past collaborations with the `Oregon State University Design Engineering Lab`_.
17 |
18 | .. include:: contents.rst
19 |
20 | Sandia National Laboratories is a multi-mission laboratory managed and operated
21 | by National Technology and Engineering Solutions of Sandia, LLC., a wholly
22 | owned subsidiary of Honeywell International, Inc., for the U.S. Department of
23 | Energy's National Nuclear Security Administration under contract DE-NA0003525.
24 |
25 | .. _Data Only Greater: https://www.dataonlygreater.com
26 | .. _Oregon State University Design Engineering Lab: https://design.engr.oregonstate.edu
27 | .. _RM3: https://tethys-engineering.pnnl.gov/signature-projects/rm3-wave-point-absorber
28 | .. _Sandia National Laboratories: https://www.sandia.gov
29 | .. _WaveBot: https://tethys-engineering.pnnl.gov/signature-projects/advanced-wec-dynamics-controls
--------------------------------------------------------------------------------
/docs/user/1setup.rst:
--------------------------------------------------------------------------------
1 | *****
2 | Setup
3 | *****
4 |
5 | Dependencies
6 | ============
7 |
8 | The following table displays the required and optional dependencies for
9 | WecOptTool.
10 |
11 | .. table::
12 | :widths: 35, 55, 10
13 |
14 | +----------------------+-------------------------------------------------------------+--------------+
15 | | Dependency | Website | Required?\* |
16 | +======================+=============================================================+==============+
17 | | MATLAB | https://www.mathworks.com/products/matlab.html | yes [#f1]_ |
18 | +----------------------+-------------------------------------------------------------+--------------+
19 | | MATLAB Optimization | https://www.mathworks.com/products/optimization.html | yes |
20 | | Toolbox | | |
21 | +----------------------+-------------------------------------------------------------+--------------+
22 | | NEMOH | https://github.com/LHEEA/Nemoh | yes |
23 | +----------------------+-------------------------------------------------------------+--------------+
24 | | WAFO | https://github.com/wafo-project/wafo | optional |
25 | +----------------------+-------------------------------------------------------------+--------------+
26 | | MATLAB Parallel | https://www.mathworks.com/products/parallel-computing.html | optional |
27 | | Computing Toolbox | | |
28 | +----------------------+-------------------------------------------------------------+--------------+
29 | | MATLAB Global | https://www.mathworks.com/products/global-optimization.html | optional |
30 | | Optimization Toolbox | | |
31 | +----------------------+-------------------------------------------------------------+--------------+
32 |
33 | \* The values in the Required column have the following meanings:
34 | * **yes** indicates dependencies that must be installed to use the
35 | WecOptTool toolbox
36 | * **optional** indicates dependencies that are used on a case by case basis,
37 | in the examples
38 |
39 | .. _user-setup-download:
40 |
41 | Download
42 | ========
43 |
44 | .. raw:: html
45 |
46 | Get the stable version
47 |
48 | The latest stable version of WecOptTool can be downloaded by clicking `HERE `__.
49 |
50 | Details of this and previous stable releases can be found in the `Releases `__ section of the GitHub repository.
51 |
52 | .. raw:: html
53 |
54 |
55 |
56 | .. raw:: html
57 |
58 | Get the development version
59 |
60 | To get the latest development version of WecOptTool, clone or download the WecOptTool GitHub repository using the '`Clone or download `__' button.
61 |
62 | Note that, although the developers endeavor to ensure that the development version is not broken, bugs or unexpected behavior may occur, so please beware.
63 |
64 | Please see the "Contributing" section of the source code's `README.md`_ file for details on how to contribute to the code development.
65 |
66 | .. raw:: html
67 |
68 |
69 |
70 | Install
71 | =======
72 |
73 | .. note::
74 | Unexpected behavior may occur if multiple versions of the toolbox are installed. Please following the :ref:`user-setup-uninstall` instructions to uninstall any previous versions of WecOptTool first.
75 |
76 | #. **Download the WecOptTool software**: See the :ref:`user-setup-download` section. If required, unzip the archive to a path of your choosing (i.e. ``/path/to/WecOptTool``). |br| |br|
77 |
78 | #. **Add WecOptTool to your MATLAB path**: Add the WecOptTool toolbox to your MATLAB path using the MATLAB command prompt:
79 |
80 | .. code:: matlab
81 |
82 | >> addpath(genpath('/path/to/WecOptTool/toolbox'));
83 | >> savepath;
84 |
85 | Alternatively the "Set Path" graphical tool can be used to add the toolbox.
86 | |br| |br|
87 |
88 | #. **Prepare Nemoh**: Follow the OS dependent instructions for setting up
89 | NEMOH:
90 |
91 | .. raw:: html
92 |
93 | Windows
94 |
95 | Executables are provided in the ‘Release’ directory of the NEMOH source code.
96 | These are installed into WecOptTool using the ``installNemoh.m`` MATLAB script, run from the WecOptTool root directory, using the MATLAB command prompt as follows:
97 |
98 | .. code:: matlab
99 |
100 | >> cd /path/to/WecOptTool
101 | >> installNemoh('/path/to/NEMOH/Release');
102 |
103 | .. raw:: html
104 |
105 |
106 |
107 | .. raw:: html
108 |
109 | Linux
110 |
111 | To set up NEMOH for Linux, first, use a command window to compile the executables (you will need gfortran or the Intel FORTRAN compiler):
112 |
113 | ::
114 |
115 | $ cd /path/to/NEMOH
116 | $ make
117 |
118 | Executables will be created a new directory called ‘bin’, which must then be installed into WecOptTool using the ``installNemoh.m`` MATLAB script, run from the WecOptTool root directory using the MATLAB command prompt:
119 |
120 | .. code:: matlab
121 |
122 | >> cd /path/to/WecOptTool
123 | >> installNemoh('/path/to/NEMOH/bin');
124 |
125 | .. raw:: html
126 |
127 |
128 |
129 | #. **Verify dependencies installation:** You can verify that the dependencies have been installed correctly by running the
130 | ``dependencyCheck.m`` script provided in the root directory of the WecOptTool source code.
131 | The script is called as follows using the MATLAB command prompt:
132 |
133 | .. code:: matlab
134 |
135 | >> cd /path/to/WecOptTool
136 | >> dependencyCheck
137 |
138 | and successful output may look like this:
139 |
140 | .. code::
141 |
142 | WecOptTool Dependency Checker
143 | -------------------------------
144 |
145 | Required
146 | --------
147 | Optimization Toolbox: Found
148 | NEMOH: Found
149 |
150 | Optional
151 | --------
152 | Parallel Toolbox: Found
153 | Global Optimization Toolbox: Not Installed
154 | WAFO: Found
155 |
156 |
157 | #. **(optional) Run functionality tests:** A test suite is available to verify that the code is operational.
158 | A script is provided in the root directory of the WecOptTool source code and is run from the MATLAB command window, as follows:
159 |
160 | .. code:: matlab
161 |
162 | >> cd /path/to/WecOptTool
163 | >> runTests;
164 |
165 | There should be no *Failed* or *Incomplete* tests at the end of the run.
166 | For example:
167 |
168 | .. code::
169 |
170 | Totals:
171 | 91 Passed, 0 Failed, 0 Incomplete.
172 | 195.0643 seconds testing time.
173 |
174 | .. _user-setup-uninstall:
175 |
176 | Uninstall
177 | =========
178 |
179 | Uninstall a previous version of WecOptTool using the MATLAB command prompt:
180 |
181 | .. code:: matlab
182 |
183 | >> rmpath(genpath('/path/to/WecOptTool/toolbox'));
184 |
185 | Alternatively the "Set Path" graphical tool can be used to remove the toolbox.
186 |
187 | .. _README.md: https://github.com/SNL-WaterPower/WecOptTool/blob/master/README.md
188 |
189 | .. rubric:: Footnotes
190 |
191 | .. [#f1] The WecOptTool developers are endeavoring to ensure that this
192 | software is compatible with the latest version of MATLAB (and the
193 | toolbox dependencies). Unfortunately, this may mean that backwards
194 | compatibility with older versions of MATLAB is not possible. See the
195 | `MATLAB Version Support Policy
196 | `__
197 | page for further details.
198 |
199 | .. |br| raw:: html
200 |
201 |
202 |
--------------------------------------------------------------------------------
/docs/user/3model.rst:
--------------------------------------------------------------------------------
1 | .. _model:
2 |
3 | **********************
4 | WEC Model Architecture
5 | **********************
6 |
7 | This section provides an overview of how a typical WecOptTool model is programmed.
8 | WecOptTool is currently structured as a set of examples, all of which follow a similar format and can thus rely on common utilities.
9 | It is envisioned that the structure of WecOptTool may some day be consolidated based on experience in developing these examples.
10 |
11 | Introduction
12 | ============
13 |
14 | The WaveBot example :cite:`Coe2020initial` will be used to illustrate these concepts in more detail.
15 | The process for performing a study in WecOptTool can be broken into three distinct steps, which correlate to three files in the WaveBot example:
16 |
17 | * **Designing the device** - |designDevice.m|_ creates the device based on a set of design variables
18 | * **Simulating device response** - |simulateDevice.m|_ simulates device performance
19 | * **Reporting results** - |Performance.m|_ a class for storing and plotting performance data
20 |
21 | The diagram below shows the responsibilities that each of these steps take within the context of the overall work-flow.
22 | The **Designing the device** step takes user inputs regarding the configuration of the device and calculates the hydrodynamic parameters of that design.
23 | In the diagram below, the processes bounded by **rectangle 1** are encapsulated by this step.
24 | **Simulating device response** takes information about the sea state and controller type, and finds the optimal power output for the given hydrodynamic parameters, encapsulating the processes in **rectangle 2**.
25 | Finally, the processes in **rectangle 3** will use metrics that are calculated in the **Reporting results** step, e.g., to find the average power.
26 |
27 | .. image:: /_static/WecOptToolFlowChartCode.svg
28 | :alt: Steps for implementing the WecOptTool functionality
29 |
30 | Designing the device
31 | ====================
32 |
33 | .. raw:: html
34 |
35 | See the entire file
36 |
37 | .. literalinclude:: /../examples/WaveBot/designDevice.m
38 | :language: matlab
39 | :linenos:
40 |
41 | .. raw:: html
42 |
43 |
44 |
45 | The **Designing the device** step codifies the user inputs for the **Geometry**, **Power take off**, and **Kinematics** of the WEC.
46 | With some important caveats, this step can be seen as analogous to building the physical device.
47 | This step can include [#f1]_ generating a panelized representation of the WEC's hull and calling a BEM code (e.g., NEMOH) to estimate the hydrodynamic coefficients.
48 | We can see from the signature of |designDevice.m|_ that it will return a :mat:class:`~+WecOptTool.Hydrodynamics` object.
49 |
50 | .. code:: matlab
51 |
52 | hydro = designDevice(type, varargin)
53 |
54 | Simulating device response
55 | ==========================
56 |
57 | .. raw:: html
58 |
59 | See the entire file
60 |
61 | .. literalinclude:: /../examples/WaveBot/simulateDevice.m
62 | :language: matlab
63 | :linenos:
64 |
65 | .. raw:: html
66 |
67 |
68 |
69 | To find the performance of a device, a separate step (**Simulating device response**) is used.
70 | For WaveBot, this is codified in the |simulateDevice.m|_, function, which has the following signature:
71 |
72 | .. code:: matlab
73 |
74 | performance = simulateDevice(hydro, seastate, controlType, options)
75 |
76 | The arguments for |simulateDevice.m|_ are:
77 |
78 | * ``hydro`` - a :mat:class:`~+WecOptTool.Hydrodynamics` object containing hydrodynamic coefficients produced by |designDevice.m|_
79 | * ``seastate`` - a :mat:class:`~+WecOptTool.SeaState` object (see :ref:`seastate`)
80 | * ``controlType`` - string specifying the control type (see :ref:`controlledPerformance`)
81 | * ``options`` - name-value pair arguments for additional settings
82 |
83 | The ``options`` argument can be used to define device properties that are not directly related to the hydrodynamics.
84 | For example, in the WaveBot example the user can set the maximum displacement (``Zmax``) and maximum PTO force (``Fmax``) at this point.
85 | Additionally, solver settings such as the linear interpolation method (``interMethod``) can be defined.
86 |
87 | Reporting results
88 | =================
89 |
90 | .. raw:: html
91 |
92 | See the entire file
93 |
94 | .. literalinclude:: /../examples/WaveBot/Performance.m
95 | :language: matlab
96 | :linenos:
97 |
98 | .. raw:: html
99 |
100 |
101 |
102 | The WaveBot example includes the |Performance.m|_ class for storing and reporting results.
103 | As a final step after simulations are completed, |simulateDevice.m|_ populates the fields of this object for return to the user.
104 | In addition to storing the results in a systematic structure, this class also provides some basic plotting functionality.
105 |
106 | .. rubric:: Footnotes
107 |
108 | .. [#f1] Note that since the hydrodynamics are linear, global scalings of the device can be analyzed without rerunning a BEM calculation.
109 |
110 | .. |designDevice.m| replace:: ``designDevice.m``
111 | .. _designDevice.m: https://github.com/SNL-WaterPower/WecOptTool/blob/master/examples/WaveBot/designDevice.m
112 | .. |simulateDevice.m| replace:: ``simulateDevice.m``
113 | .. _simulateDevice.m: https://github.com/SNL-WaterPower/WecOptTool/blob/master/examples/WaveBot/simulateDevice.m
114 | .. |Performance.m| replace:: ``Performance.m``
115 | .. _Performance.m: https://github.com/SNL-WaterPower/WecOptTool/blob/master/examples/WaveBot/Performance.m
116 |
--------------------------------------------------------------------------------
/docs/user/4cite.rst:
--------------------------------------------------------------------------------
1 | *****************
2 | Citing WecOptTool
3 | *****************
4 |
5 | If WecOptTool has been significant in your research, and you would like to acknowledge the project in your academic publication, we suggest citing the following paper:
6 |
7 | * Coe, R.G., Bacelli, G., Olson, S. *et al.* Initial conceptual demonstration of control co-design for WEC optimization.
8 | J. Ocean Eng. Mar. Energy **6**, 441–449 (2020). `https://doi.org/10.1007/s40722-020-00181-9 `__.
9 |
10 | *In BibTeX format*::
11 |
12 | @article{ Coe2020initial,
13 | author = {Ryan G. Coe and Giorgio Bacelli and Sterling Olson and Vincent S. Neary
14 | and Mathew B. R. Topper},
15 | doi = {10.1007/s40722-020-00181-9},
16 | journal = {Journal of Ocean Engineering and Marine Energy},
17 | month = {November},
18 | number = {4},
19 | pages = {441-449},
20 | title = {Initial conceptual demonstration of control co-design for {WEC} optimization},
21 | volume = {6},
22 | year = {2020}
23 | }
24 |
--------------------------------------------------------------------------------
/docs/user/5resources.rst:
--------------------------------------------------------------------------------
1 | *********
2 | Resources
3 | *********
4 |
5 | This page provides additional resources for users of WecOptTool.
6 |
7 | Webinar
8 | =======
9 |
10 | A one hour webinar :cite:`coe2020webinar` was presented on September 29th 2020. This webinar provides interested users with a tutorial and background.
11 |
12 | :pdfembed:`src:../_static/WecOptTool_webinar_2020_09_29.pdf#view=fitH&zoom=scale&toolbar=1, height:450, width:100%, align:middle`
13 |
14 | Additional Reading
15 | ==================
16 |
17 | The following references specifically focusing on WecOptTool are available:
18 |
19 | * **Optimal control of wave energy converters** :cite:`Bacelli2014` - While written years before the development of WecOptTool, Giorgio Bacelli's doctoral thesis provides much of the framework upon which WecOptTool is based.
20 | * **Initial conceptual demonstration of control co-design for WEC optimization** :cite:`Coe2020initial` - This paper presents the basic framework of WecOptTool along with a series of examples using the Sandia WaveBot.
21 |
--------------------------------------------------------------------------------
/docs/user/6api.rst:
--------------------------------------------------------------------------------
1 | .. _api:
2 |
3 | ***
4 | API
5 | ***
6 |
7 | WecOptTool
8 | ----------
9 |
10 | .. mat:autoclass:: +WecOptTool.AutoFolder
11 | :members:
12 |
13 | .. mat:autoclass:: +WecOptTool.Hydrodynamics
14 | :members:
15 |
16 | .. mat:autoclass:: +WecOptTool.SeaState
17 | :members:
18 |
19 | .. mat:autofunction:: +WecOptTool.mesh
20 |
21 | .. mat:autofunction:: +WecOptTool.solver
22 |
23 | WecOptTool.geometry
24 | -------------------
25 |
26 | The geometry package provides predefined geometry generation functions.
27 |
28 | .. mat:automodule:: +WecOptTool.+geometry
29 | :members:
30 |
31 | WecOptTool.plot
32 | ---------------
33 |
34 | .. mat:automodule:: +WecOptTool.+plot
35 | :members:
36 |
37 | WecOptTool.math
38 | ---------------
39 |
40 | .. mat:automodule:: +WecOptTool.+math
41 | :members:
42 |
43 | WecOptTool.mesh
44 | ---------------
45 |
46 | The mesh subpackage provides mesh generation classes, that provide the standard method ``makeMesh``.
47 |
48 | .. mat:automodule:: +WecOptTool.+mesh
49 | :members:
50 |
51 | WecOptTool.solver
52 | -----------------
53 |
54 | The solver subpackage provides hydrodynamic solver classes, that provide the standard method ``getHydro``.
55 |
56 | .. mat:automodule:: +WecOptTool.+solver
57 | :members:
58 |
59 | WecOptTool.base
60 | ---------------
61 |
62 | The base subpackage provides base classes used in other classes.
63 |
64 | .. mat:automodule:: +WecOptTool.+base
65 | :members:
66 |
--------------------------------------------------------------------------------
/docs/user/7license.rst:
--------------------------------------------------------------------------------
1 | *******
2 | License
3 | *******
4 |
5 | Copyright |copy| |year| 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.
6 |
7 | 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.
8 |
9 | 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.
10 |
11 | You should have received a copy of the GNU General Public License along with WecOptTool.
12 | If not, see .
13 |
14 | .. |copy| unicode:: U+000A9 .. COPYRIGHT SIGN
15 | .. |year| date:: %Y
16 |
--------------------------------------------------------------------------------
/docs/user/8references.rst:
--------------------------------------------------------------------------------
1 | **********
2 | References
3 | **********
4 |
5 | This page list supporting references for WecOptTool.
6 |
7 | .. bibliography:: WecOptTool_refs.bib
8 | :style: unsrt
9 |
--------------------------------------------------------------------------------
/docs/user/WecOptTool_refs.bib:
--------------------------------------------------------------------------------
1 |
2 | @phdthesis{Bacelli2014,
3 | Address = {Maynooth, Ireland},
4 | Author = {Bacelli, Giorgio},
5 | School = {National University of Ireland, Maynooth},
6 | Title = {Optimal control of wave energy converters},
7 | Type = {{PhD}},
8 | Url = {http://mural.maynoothuniversity.ie/6753/},
9 | Year = {2014}}
10 |
11 | @misc{coe2020webinar,
12 | Author = {Ryan G. Coe and Giorgio Bacelli and Sterling Olson and Vincent S. Neary and Mathew B. R. Topper},
13 | Doi = {10.13140/RG.2.2.16353.94564},
14 | Howpublished = {Online},
15 | Month = {September},
16 | Title = {{WecOptTool Sept. 2020 Webinar}},
17 | Year = {2020}}
18 |
19 | @article{Coe2020initial,
20 | Author = {Ryan G. Coe and Giorgio Bacelli and Sterling Olson and Vincent S. Neary and Mathew B. R. Topper},
21 | Doi = {10.1007/s40722-020-00181-9},
22 | Journal = {Journal of Ocean Engineering and Marine Energy},
23 | Title = {{Initial conceptual demonstration of control co-design for WEC optimization}},
24 | month = {November},
25 | number = {4},
26 | pages = {441-449},
27 | volume = {6},
28 | Year = {2020}}
29 |
30 | @book{Falnes2002,
31 | Address = {Cambridge; New York},
32 | Author = {Johannes Falnes},
33 | Doi = {10.1017/CBO9780511754630},
34 | Publisher = {Cambridge University Press},
35 | Title = {Ocean Waves and Oscillating Systems},
36 | Year = {2002}}
37 |
38 | @article{Bacelli2014a,
39 | Author = {Bacelli, Giorgio and Ringwood, John V},
40 | Doi = {10.1109/TSTE.2014.2371536},
41 | Journal = {IEEE Transactions on Sustainable Energy},
42 | Number = {2},
43 | Pages = {294--302},
44 | Publisher = {IEEE},
45 | Title = {Numerical optimal control of wave energy converters},
46 | Volume = {6},
47 | Year = {2014}}
48 |
--------------------------------------------------------------------------------
/examples/RM3/RM3_BEM.mat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SNL-WaterPower/WecOptTool-MATLAB/0a9faa189f8570444fac5ebe0da2a9fcd94958eb/examples/RM3/RM3_BEM.mat
--------------------------------------------------------------------------------
/examples/RM3/basic.m:
--------------------------------------------------------------------------------
1 |
2 | clear controlParams performances r
3 |
4 | % Create an example SeaState object
5 | SS = WecOptTool.SeaState.exampleSpectrum("resampleByError", 0.1);
6 |
7 | controlParams.type = 'CC';
8 | controlParams(2).type = 'P';
9 | controlParams(3).type = 'PS';
10 | controlParams(3).params = {10 1e9};
11 |
12 | deviceHydro = designDevice('scalar', 1);
13 |
14 | for i = 1:length(controlParams)
15 |
16 | disp("Simulation " + (i) + " of " + length(controlParams))
17 |
18 | for j = 1:length(SS)
19 |
20 | if ~isempty(controlParams(i).params)
21 | performances(j) = simulateDevice(deviceHydro, ...
22 | SS(j), ...
23 | controlParams(i).type, ...
24 | controlParams(i).params{:});
25 | else
26 | performances(j) = simulateDevice(deviceHydro, ...
27 | SS(j), ...
28 | controlParams(i).type);
29 | end
30 |
31 | end
32 |
33 | r(i) = sum(aggregateSeaStates(SS, performances));
34 |
35 | end
36 |
37 | function out = aggregateSeaStates(seastate, performances)
38 | pow = sum(performances.powPerFreq);
39 | out = dot(pow, [seastate.mu]) / sum([seastate.mu]);
40 | end
41 |
42 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
43 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
44 | % U.S. Government retains certain rights in this software.
45 | %
46 | % This file is part of WecOptTool.
47 | %
48 | % WecOptTool is free software: you can redistribute it and/or modify
49 | % it under the terms of the GNU General Public License as published by
50 | % the Free Software Foundation, either version 3 of the License, or
51 | % (at your option) any later version.
52 | %
53 | % WecOptTool is distributed in the hope that it will be useful,
54 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
55 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
56 | % GNU General Public License for more details.
57 | %
58 | % You should have received a copy of the GNU General Public License
59 | % along with WecOptTool. If not, see .
60 |
--------------------------------------------------------------------------------
/examples/RM3/designDevice.m:
--------------------------------------------------------------------------------
1 | function [hydro, meshes] = designDevice(type, varargin)
2 |
3 | meshes = [];
4 |
5 | switch type
6 |
7 | case 'existing'
8 | hydro = WecOptTool.geometry.existingNEMOH(varargin{:});
9 | case 'scalar'
10 | hydro = getHydroScalar(varargin{:});
11 | case 'parametric'
12 | [hydro, meshes] = getHydroParametric(varargin{:});
13 |
14 | end
15 |
16 | end
17 |
18 | function hydro = getHydroScalar(lambda)
19 |
20 | % Get data file path
21 | p = mfilename('fullpath');
22 | [filepath, ~, ~] = fileparts(p);
23 | dataPath = fullfile(filepath, 'RM3_BEM.mat');
24 |
25 | mf = matfile(dataPath);
26 | hydro = mf.hydro;
27 |
28 | % dimensionalize w/ WEC-Sim built-in function
29 | hydro.rho = 1025;
30 | hydro.g = 9.81;
31 | % hydro = Normalize(hydro); % TODO - this doesn't work for our data
32 | % that was produced w/ WAMIT...
33 |
34 | % scale by scaling factor lambda
35 | hydro.Vo = hydro.Vo .* lambda^3;
36 | hydro.C = hydro.C .* lambda^2;
37 | hydro.B = hydro.B .* lambda^2.5;
38 | hydro.A = hydro.A .* lambda^3;
39 | hydro.ex = complex(hydro.ex_re,hydro.ex_im) .* lambda^2;
40 | hydro = rmfield(hydro,{'ex_re','ex_im'});
41 | end
42 |
43 |
44 | function [hydro, meshes] = getHydroParametric(folder, r1, r2, d1, d2, w)
45 |
46 | % Float
47 |
48 | rf = [0 r1 r1 0];
49 | zf = [0 0 -d1 -d1];
50 |
51 | % Heave plate
52 |
53 | thk = 1;
54 | rs = [0 r2 r2 0];
55 | zs = [-d2 -d2 -d2-thk -d2-thk];
56 |
57 | % Mesh
58 | ntheta = 20;
59 | nfobj = 200;
60 | zG = 0;
61 |
62 | meshes = WecOptTool.mesh("AxiMesh", ...
63 | folder, ...
64 | rf, ...
65 | zf, ...
66 | ntheta, ...
67 | nfobj, ...
68 | zG, ...
69 | 1);
70 | meshes(2) = WecOptTool.mesh("AxiMesh", ...
71 | folder, ...
72 | rs, ...
73 | zs, ...
74 | ntheta, ...
75 | nfobj, ...
76 | zG, ...
77 | 2);
78 |
79 | hydro = WecOptTool.solver("NEMOH", folder, meshes, w);
80 |
81 | end
82 |
83 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
84 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
85 | % U.S. Government retains certain rights in this software.
86 | %
87 | % This file is part of WecOptTool.
88 | %
89 | % WecOptTool is free software: you can redistribute it and/or modify
90 | % it under the terms of the GNU General Public License as published by
91 | % the Free Software Foundation, either version 3 of the License, or
92 | % (at your option) any later version.
93 | %
94 | % WecOptTool is distributed in the hope that it will be useful,
95 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
96 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
97 | % GNU General Public License for more details.
98 | %
99 | % You should have received a copy of the GNU General Public License
100 | % along with WecOptTool. If not, see .
101 |
--------------------------------------------------------------------------------
/examples/RM3/optimization.m:
--------------------------------------------------------------------------------
1 | %% optimization.m
2 | % Example of an optimization study
3 |
4 | %% Define and store sea state of interest
5 |
6 | % Create Bretschnider spectrum from WAFO and trim off frequencies that
7 | % have less that 1% of the max spectral density
8 | % S = bretschneider([],[8,10],0);
9 | % SS = WecOptTool.SeaState(S, "trimFrequencies", 0.01)
10 |
11 | % Load an example with multiple sea-states (8 differing spectra) and trim
12 | % off frequencies that have less that 1% of the max spectral density
13 | SS = WecOptTool.SeaState.example8Spectra("trimFrequencies", 0.01);
14 |
15 | %% Create a folder for storing intermediate files
16 | folder = WecOptTool.AutoFolder();
17 |
18 | %% Optimization Setup
19 |
20 | % Add geometry design variables (parametric)
21 | x0 = [5, 7.5, 1.125, 42];
22 | lb = [4.5, 7, 1.00, 41];
23 | ub = [5.5, 8, 1.25, 43];
24 |
25 | % Define optimisation options
26 | opts = optimoptions('fmincon');
27 | opts.FiniteDifferenceType = 'central';
28 | opts.UseParallel = true;
29 | opts.MaxFunctionEvaluations = 5; % set artificial low for fast running
30 | opts.Display = 'iter';
31 |
32 | % Enable dynamic plotting
33 | % opts.PlotFcn = {@optimplotx,@optimplotfval};
34 |
35 | % Define unused parameters
36 | A = [];
37 | B = [];
38 | Aeq = [];
39 | Beq = [];
40 | NONLCON = [];
41 |
42 | %% Optimization Execution
43 |
44 | % Create simple objective function handle
45 | objFun = @(x) myWaveBotObjFun(x, SS, folder);
46 |
47 | % Call the solver
48 | [x, fval] = fmincon(objFun, x0, A, B, Aeq, Beq, lb, ub, NONLCON, opts);
49 |
50 | %% Recover device object of best simulation and plot its power per freq
51 | %% and mesh
52 | performances = folder.recoverVar("performances");
53 |
54 | for i = 1:length(performances)
55 | test = performances{i};
56 | if isequal(test(1).x, x)
57 | bestPerformances = test;
58 | break
59 | end
60 | end
61 |
62 | WecOptTool.plot.powerPerFreq(bestPerformances);
63 | WecOptTool.plot.plotMesh(bestPerformances(1).meshes);
64 |
65 | %% Define objective function
66 | % This can take any form that complies with the requirements of the MATLAB
67 | % optimization functions
68 |
69 | function fval = myWaveBotObjFun(x, seastate, folder)
70 |
71 | w = seastate.getRegularFrequencies(0.5);
72 | geomParams = [folder.path num2cell(x) w];
73 |
74 | [deviceHydro, meshes] = designDevice('parametric', geomParams{:});
75 |
76 | for j = 1:length(seastate)
77 | performances(j) = simulateDevice(deviceHydro, ...
78 | seastate(j), ...
79 | 'CC');
80 | end
81 |
82 | fval = -1 * weightedPower(seastate, performances);
83 |
84 | [performances(:).w] = seastate.w;
85 | performances(1).x = x;
86 | performances(1).meshes = meshes;
87 |
88 | folder.stashVar(performances);
89 |
90 | end
91 |
92 | function out = weightedPower(seastate, performances)
93 | pow = sum([performances.powPerFreq]);
94 | out = dot(pow, [seastate.mu]) / sum([seastate.mu]);
95 | end
96 |
97 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
98 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
99 | % U.S. Government retains certain rights in this software.
100 | %
101 | % This file is part of WecOptTool.
102 | %
103 | % WecOptTool is free software: you can redistribute it and/or modify
104 | % it under the terms of the GNU General Public License as published by
105 | % the Free Software Foundation, either version 3 of the License, or
106 | % (at your option) any later version.
107 | %
108 | % WecOptTool is distributed in the hope that it will be useful,
109 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
110 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
111 | % GNU General Public License for more details.
112 | %
113 | % You should have received a copy of the GNU General Public License
114 | % along with WecOptTool. If not, see .
115 |
--------------------------------------------------------------------------------
/examples/WaveBot/Performance.m:
--------------------------------------------------------------------------------
1 | classdef Performance < handle
2 |
3 | properties
4 | w (:,:) double {mustBeFinite,mustBeReal,mustBePositive}
5 | ph (:,:) double {mustBeFinite,mustBeReal}
6 | eta (:,:) double {mustBeFinite}
7 | F0 (:,:) double {mustBeFinite}
8 | u (:,:) double {mustBeFinite}
9 | pos (:,:) double {mustBeFinite}
10 | Zpto (:,:) double {}
11 | Fpto (:,:) double {mustBeFinite}
12 | pow (:,:) double {mustBeFinite}
13 | name (1,:) char = 'tmp'
14 | date (1,1) double {mustBeFinite,mustBePositive} = now
15 | end
16 |
17 | methods
18 |
19 | function plotTime(obj, t, options)
20 |
21 | arguments
22 | obj
23 | t = 0:0.05:obj(1).getRepeatPer()
24 | options.Interpreter = 'none'
25 | options.FontSize = 11
26 | end
27 |
28 | fig = figure('Name','Performance.plotTime');
29 | fig.Position = fig.Position .* [1 1 1 1.5];
30 | movegui(fig, 'onscreen');
31 |
32 | % fields for plotting
33 | fns = {'eta','F0','pos','u','Fpto','pow'};
34 |
35 | for ii = 1:length(fns)
36 | ax(ii) = subplot(length(fns), 1, ii);
37 | hold on
38 | grid on
39 | end
40 |
41 | for jj = 1:length(obj)
42 |
43 | for ii = 1:length(fns)
44 | timeRes.(fns{ii}) = getTimeRes(obj(jj),fns{ii}, t);
45 | plot(ax(ii),t,timeRes.(fns{ii}))
46 | ylabel(ax(ii), ...
47 | fns{ii}, ...
48 | 'Interpreter', options.Interpreter, ...
49 | 'FontSize', options.FontSize)
50 | end
51 |
52 | for ii = 1:length(ax) - 1
53 | set(ax(ii),'XTickLabel',[])
54 | end
55 |
56 | linkaxes(ax,'x')
57 | xlabel(ax(end), ...
58 | 'Time [s]', ...
59 | 'Interpreter', options.Interpreter, ...
60 | 'FontSize', options.FontSize)
61 |
62 | end
63 |
64 | xlim([t(1), t(end)])
65 |
66 | if length(obj) > 1
67 | l1 = legend(ax(1), ...
68 | {obj.name}, ...
69 | 'Interpreter', options.Interpreter, ...
70 | 'FontSize', options.FontSize);
71 | set(l1, 'NumColumns', length(obj))
72 | end
73 |
74 | end
75 |
76 | function plotFreq(obj, fig, options)
77 |
78 | arguments
79 | obj
80 | fig = figure;
81 | options.Interpreter = 'none'
82 | options.FontSize = 11
83 | end
84 |
85 | set(fig,'Name','Performance.plotFreq');
86 |
87 | fns = {'F0','u','Fpto'};
88 | mrks = {'o','.','+','s'};
89 |
90 | n = length(obj);
91 | for jj = 1:n
92 | for ii = 1:length(fns)
93 |
94 | fv = obj(jj).(fns{ii})(:,1); % use the first column if this is PS
95 |
96 | % mag plot
97 | ax(jj,1) = subplot(2,n,sub2ind([n,2],jj,1));
98 | title(obj(jj).name, ...
99 | 'Interpreter', options.Interpreter, ...
100 | 'FontSize', options.FontSize)
101 | hold on
102 | grid on
103 |
104 | stem(ax(jj,1), ...
105 | obj(jj).w, ...
106 | mag2db(abs(fv)), ...
107 | mrks{ii}, ...
108 | 'DisplayName', fns{ii}, ...
109 | 'MarkerSize', 8, ...
110 | 'Color', 'b')
111 |
112 | % phase plot
113 | ax(jj,2) = subplot(2,n,sub2ind([n,2],jj,2));
114 | hold on
115 | grid on
116 |
117 | stem(ax(jj,2), ...
118 | obj(jj).w, ...
119 | angle(fv), ...
120 | mrks{ii}, ...
121 | 'DisplayName', fns{ii}, ...
122 | 'MarkerSize', 8, ...
123 | 'Color', 'b')
124 |
125 | ylim(ax(jj,2),[-pi,pi])
126 |
127 | end
128 |
129 | xlabel(ax(jj,2), ...
130 | 'Frequency [rad/s]', ...
131 | 'Interpreter', options.Interpreter, ...
132 | 'FontSize', options.FontSize)
133 |
134 | end
135 |
136 | ylabel(ax(1,1), ...
137 | 'Magnitude [dB]', ...
138 | 'Interpreter', options.Interpreter, ...
139 | 'FontSize', options.FontSize)
140 | ylabel(ax(1,2), ...
141 | 'Angle [rad]', ...
142 | 'Interpreter', options.Interpreter, ...
143 | 'FontSize', options.FontSize)
144 | legend(ax(n,1), ...
145 | 'Interpreter', options.Interpreter, ...
146 | 'FontSize', options.FontSize)
147 | linkaxes(ax, 'x')
148 | linkaxes(ax(:,1), 'y')
149 |
150 | end
151 |
152 | function T = summary(obj)
153 |
154 | if length(obj) > 1
155 | for ii = 1:length(obj)
156 | Tr(ii,:) = summary(obj(ii));
157 | end
158 |
159 | % augment names if they are the same
160 | if any(strcmp(obj(1).name, {obj(2:end).name}))
161 | for ii = 1:length(obj)
162 | rnames{ii} = [obj(ii).name, '_', num2str(ii)];
163 | end
164 | else
165 | rnames = {obj.name};
166 | end
167 |
168 | Tr.Properties.RowNames = rnames;
169 | mT = Tr;
170 |
171 | if nargout
172 | T = mT;
173 | else
174 | disp(mT)
175 | end
176 |
177 | return
178 |
179 | else
180 | rnames = {obj.name};
181 | end
182 |
183 | trep = obj.getRepeatPer();
184 | t = linspace(0,trep,1e3);
185 |
186 | for jj = 1:size(obj.ph,2) % for each phase in PS cases
187 |
188 | tmp.pow_avg(jj) = sum(real(obj.pow(:,jj)));
189 |
190 | pow_t = getTimeRes(obj, 'pow', t, jj);
191 | tmp.pow_max(jj) = max(abs(pow_t));
192 |
193 | try
194 | tmp.pow_thd(jj) = thd(pow_t);
195 | catch ME
196 | warning(ME.message)
197 | tmp.pow_thd(jj) = NaN;
198 | end
199 |
200 | pos_t = getTimeRes(obj, 'pos', t, jj);
201 | tmp.pos_max(jj) = max(abs(pos_t));
202 |
203 | vel_t = getTimeRes(obj, 'u', t, jj);
204 | tmp.vel_max(jj) = max(abs(vel_t));
205 |
206 | Fpto_t = getTimeRes(obj, 'Fpto', t, jj);
207 | tmp.Fpto_max(jj) = max(abs(Fpto_t));
208 | end
209 |
210 | fn = fieldnames(tmp);
211 | for kk = 1:length(fn)
212 | out.(fn{kk}) = mean(tmp.(fn{kk}), 2);
213 | end
214 |
215 | rnames = reshape(rnames,[],1);
216 |
217 | mT = table(out.pow_avg(:),out.pow_max(:),out.pow_thd(:),...
218 | out.pos_max(:),out.vel_max(:),out.Fpto_max(:),...
219 | 'VariableNames',...
220 | {'AvgPow','|MaxPow|','PowTHD_dBc','MaxPos','MaxVel','MaxPTO'},...
221 | 'RowNames',rnames);
222 |
223 | if nargout
224 | T = mT;
225 | else
226 | disp(mT)
227 | end
228 |
229 | end
230 |
231 | end
232 |
233 | methods (Access=protected)
234 |
235 | function [tRep] = getRepeatPer(obj)
236 | tRep = 2*pi/(obj.w(2) - obj.w(1));
237 | end
238 |
239 | function [timeRes] = getTimeRes(obj, fn, t_vec, ph_idx)
240 | if nargin < 4
241 | ph_idx = 1;
242 | end
243 |
244 | if strcmp(fn,'pow')
245 | vel = obj.getTimeRes('u',t_vec);
246 | f = obj.getTimeRes('Fpto',t_vec);
247 | timeRes = vel .* f;
248 | else
249 | timeRes = zeros(size(t_vec));
250 | fv = obj.(fn)(:,ph_idx); % use the first column if this is PS
251 | for ii = 1:length(obj.w) % for each freq. TODO - use IFFT
252 | timeRes = timeRes ...
253 | + real(fv(ii) * exp(1i * obj.w(ii) * t_vec));
254 | end
255 | end
256 | end
257 |
258 | % function checkSizes(varargin) % TODO
259 | % n = length(varargin);
260 | % for ii = 1:n
261 | % if ~isequal(varargin(varargin{ii}),size(varargin{1}))
262 | % error('Frequency vectors must have same size')
263 | % end
264 | % end
265 | % end
266 |
267 | end
268 | end
269 |
270 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
271 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
272 | % U.S. Government retains certain rights in this software.
273 | %
274 | % This file is part of WecOptTool.
275 | %
276 | % WecOptTool is free software: you can redistribute it and/or
277 | % modify it under the terms of the GNU General Public License as
278 | % published by the Free Software Foundation, either version 3 of
279 | % the License, or (at your option) any later version.
280 | %
281 | % WecOptTool is distributed in the hope that it will be useful,
282 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
283 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
284 | % GNU General Public License for more details.
285 | %
286 | % You should have received a copy of the GNU General Public
287 | % License along with WecOptTool. If not, see
288 | % .
289 |
--------------------------------------------------------------------------------
/examples/WaveBot/README.md:
--------------------------------------------------------------------------------
1 | # WaveBot
2 |
3 | This example was developed in conjuction with the following journal paper, which is avaialable at .
4 |
5 | ```
6 | @Article{WecDesignOptimizationTool,
7 | author = "Ryan G. Coe and Giorgio Bacelli and Sterling Olson and Vincent S. Neary and Mathew B. R. Topper",
8 | title = {Initial conceptual demonstration of control co-design for {WEC} optimization},
9 | year = {2020},
10 | journal= {Journal of Ocean Engineering and Marine Energy},
11 | month = {November},
12 | volume = {6},
13 | number = {4},
14 | pages = {441-449},
15 | doi = {10.1007/s40722-020-00181-9}
16 | }
17 | ```
18 |
--------------------------------------------------------------------------------
/examples/WaveBot/WaveBot_caseA.m:
--------------------------------------------------------------------------------
1 | % Case A
2 | % This case study shows a comparison between the different controllers
3 | % currently available in WecOptTool. This is NOT an optimization study.
4 | % Instead, a single device design is simulated in a sea state using each of
5 | % the three controllers. The purpose of this study is to demonstrate some
6 | % of the basic differences between these three controller types:
7 | %
8 | % CC complex conjugate control
9 | % P proportional damping
10 | % PS pseudo-spectral numerical optimal control
11 |
12 | % Copyright 2020 National Technology & Engineering Solutions of Sandia, LLC
13 | % (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S.
14 | % Government retains certain rights in this software.
15 | %
16 | % This file is part of WecOptTool.
17 | %
18 | % WecOptTool is free software: you can redistribute it and/or modify it
19 | % under the terms of the GNU General Public License as published by the
20 | % Free Software Foundation, either version 3 of the License, or (at
21 | % your option) any later version.
22 | %
23 | % WecOptTool is distributed in the hope that it will be useful, but
24 | % WITHOUT ANY WARRANTY; without even the implied warranty of
25 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 | % General Public License for more details.
27 | %
28 | % You should have received a copy of the GNU General Public License
29 | % along with WecOptTool. If not, see .
30 |
31 | %% define sea state of interest
32 |
33 | dw = 0.3142;
34 | nf = 50;
35 | w = dw * (1:nf)';
36 | A = 0.125/2;
37 | wp = w(6);
38 | fp = wp/(2*pi);
39 | Tp = 1/fp;
40 | SS = WecOptTool.SeaState.regularWave(w,[A,Tp]);
41 |
42 | %% Create device and define controllers
43 |
44 | controlType{1} = 'CC';
45 | controlType{2} = 'P';
46 | controlType{3} = 'PS';
47 |
48 | % constraints for PS, zmax: max stroke (inactive); fmax: max PTO force
49 | zmax = 1e10;
50 | fmax = 2e3;
51 |
52 | % make a WaveBot using the 'base' dimensions
53 | designType = 'scalar';
54 | scalarVal = 1;
55 | folder = WecOptTool.AutoFolder();
56 | deviceHydro = designDevice(designType, folder.path, scalarVal, w);
57 |
58 | %% Run simulations
59 |
60 | clear r
61 | for ii = 1:length(controlType)
62 | disp("Simulation " + (ii) + " of " + length(controlType))
63 | rng(3) % run same wave phasing for each case
64 | r(ii) = simulateDevice(deviceHydro,SS,controlType{ii}, ...
65 | 'interpMethod', 'nearest', ...
66 | 'Zmax', zmax, ...
67 | 'Fmax', fmax);
68 | r(ii).name = controlType{ii};
69 | end
70 |
71 | %% plot freq. domain results
72 |
73 | r.plotFreq('Interpreter', 'latex')
74 |
75 | fig = gcf;
76 | fig.Position = fig.Position .* [1 1 1.5 0.5];
77 | delete(findobj(fig, 'Type', 'Legend'))
78 |
79 | % Rewrite legend
80 | ax = findobj(gcf, 'Type', 'axes');
81 | l1 = legend(ax(end), '$F_e$', '$u$', '$F_u$');
82 | set(l1, 'Interpreter', 'latex')
83 |
84 | % label x-axis with integer multiples of fundamental freq.
85 | intf = 1:2:8;
86 | xt = [0 (1:2:8) * 2 * pi / Tp];
87 | xtl{1} = 0;
88 | xtl{2} = sprintf('$\\omega_0$');
89 |
90 | for ii = 1:length(intf) - 1
91 | xtl{ii+2} = sprintf('%i $\\omega_0$', intf(ii+1));
92 | end
93 |
94 | for ii = 1:length(ax)
95 | set(ax(ii), 'XTick', xt)
96 | set(ax(ii), 'XTickLabel', xtl)
97 | set(ax(ii), 'TickLabelInterpreter', 'latex');
98 | end
99 |
100 | for ii = [2,4,6]
101 | set(ax(ii), 'XTickLabel', [])
102 | end
103 |
104 | % export_fig('WaveBot_caseA_freq.pdf','-transparent')
105 |
106 | %% plot time domain results
107 |
108 | fs = 15;
109 | r.plotTime(0:0.01:10, 'Interpreter', 'latex', 'FontSize', fs);
110 | fig = gcf;
111 | ax = findall(fig, 'type', 'axes');
112 |
113 | % thicker lines
114 | lh = findobj(fig, 'Type', 'line');
115 | for ii = 1:numel(lh)
116 | lh(ii).LineWidth=2;
117 | end
118 |
119 | % plot PTO force limits and add annotations
120 | hp(1) = plot(ax(2), xlim, fmax * ones(2,1), 'k--');
121 | hp(2) = plot(ax(2), xlim, -1 * fmax * ones(2,1), 'k--');
122 | uistack(hp,'bottom');
123 | annotation(fig, ...
124 | 'textarrow', ...
125 | [0.648214285714286 0.573214285714286], ...
126 | [0.361904761904762 0.328571428571429], ...
127 | 'String', '$F_u^{\textrm{{max}}}$', ...
128 | 'Interpreter', 'latex', ...
129 | 'FontSize', 18);
130 | annotation(fig, ...
131 | 'arrow', ...
132 | [0.648214285714286 0.528571428571429], ...
133 | [0.36031746031746 0.288888888888889]);
134 |
135 | % Rewrite y-axis labels
136 | ylabel(ax(1), '$P$ [W]', 'Interpreter', 'latex', 'FontSize', fs)
137 | ylabel(ax(2), '$F_u$ [N]', 'Interpreter', 'latex', 'FontSize', fs)
138 | ylabel(ax(3), '$u$ [m/s]', 'Interpreter', 'latex', 'FontSize', fs)
139 | ylabel(ax(4), '$z$ [m]', 'Interpreter', 'latex', 'FontSize', fs)
140 | ylabel(ax(5), '$F_e$ [N]', 'Interpreter', 'latex', 'FontSize', fs)
141 | ylabel(ax(6), '$\eta$ [m]', 'Interpreter', 'latex', 'FontSize', fs)
142 |
143 | % export_fig('WaveBot_caseA_time.pdf','-transparent')
144 |
145 | %% report results in a table
146 |
147 | summary(r)
148 |
--------------------------------------------------------------------------------
/examples/WaveBot/WaveBot_caseB.m:
--------------------------------------------------------------------------------
1 | % Case B
2 | % This case performs three optimization studies (one using each of the
3 | % three control types: P, CC, and PS). The objective function is a simple
4 | % ratio of average power and a polynomial of submerged hull volume. The
5 | % goal behind this study is to illustrate how the different control types
6 | % result in different optimal designs.
7 |
8 | % Copyright 2020 National Technology & Engineering Solutions of Sandia, LLC
9 | % (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S.
10 | % Government retains certain rights in this software.
11 | %
12 | % This file is part of WecOptTool.
13 | %
14 | % WecOptTool is free software: you can redistribute it and/or modify it
15 | % under the terms of the GNU General Public License as published by the
16 | % Free Software Foundation, either version 3 of the License, or (at
17 | % your option) any later version.
18 | %
19 | % WecOptTool is distributed in the hope that it will be useful, but
20 | % WITHOUT ANY WARRANTY; without even the implied warranty of
21 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 | % General Public License for more details.
23 | %
24 | % You should have received a copy of the GNU General Public License
25 | % along with WecOptTool. If not, see .
26 |
27 | %% define sea state of interest
28 |
29 | dw = 0.3142;
30 | nf = 50;
31 | w = dw * (1:nf)';
32 | A = 0.125/2;
33 | wp = w(6);
34 | fp = wp/(2*pi);
35 | Tp = 1/fp;
36 | SS = WecOptTool.SeaState.regularWave(w,[A,Tp]);
37 |
38 | %% set up device types
39 |
40 | controlType{1} = 'CC';
41 | controlType{2} = 'P';
42 | controlType{3} = 'PS';
43 |
44 | % constraints for PS, zmax: max stroke; fmax: max PTO force (inactive)
45 | zmax = 0.6;
46 | fmax = 1e10;
47 |
48 | folder = WecOptTool.AutoFolder();
49 |
50 | %% create set of devices (run hydrodynamics)
51 |
52 | % outer radius of WaveBot
53 | rmin = 0.25;
54 | rmax = 2;
55 | r0 = 0.88; % nominal radius
56 | radii = sort([linspace(rmin,rmax,19), r0]);
57 |
58 | clear deviceHydro
59 | for idx = 1:length(radii)
60 | radius = radii(idx);
61 | disp("Running BEM for case " + (idx) + " of " + length(radii))
62 | deviceHydro(idx) = designDevice('parametric', folder.path, ...
63 | radius, 0.35, 0.16, 0.53, w);
64 | end
65 |
66 | %% simulate performance
67 |
68 | clear r
69 | for ii = 1:length(controlType)
70 | for jj = 1:length(radii)
71 | rng(3) % run same wave phasing for each case
72 | disp("Monte-carlo for " + controlType{ii} + ", case " + (jj) + " of " + length(radii))
73 | r(jj,ii) = simulateDevice(deviceHydro(jj),SS,controlType{ii},...
74 | 'interpMethod','nearest','Zmax',zmax,...
75 | 'Fmax',fmax);
76 | r(jj,ii).name = [controlType{ii}, '_', num2str(radii(jj))];
77 | end
78 | end
79 |
80 | %% set up optimization problems
81 |
82 | x0 = 2;
83 | A = [];
84 | B = [];
85 | Aeq = [];
86 | Beq = [];
87 | LB = min(radii);
88 | UB = max(radii);
89 | NONLCON = [];
90 | opts = optimset('fminbnd');
91 | opts.UseParallel = true;
92 | opts.Display = 'iter';
93 | opts.PlotFcn = {@optimplotx,@optimplotfval};
94 |
95 | %% run optimization solver (for each control type)
96 |
97 | clear fval x_opt exitflag output optSimres
98 | for ii = 1:length(controlType)
99 | disp("fminbnd for " + controlType{ii})
100 |
101 | % find optimal geometry for each control type
102 | [x_opt(ii), fval(ii), exitflag(ii), output(ii)] = ...
103 | fminbnd(@(x) myWaveBotObjFun(x,w,SS,controlType{ii},zmax,fmax,...
104 | folder.path),LB,UB,opts);
105 |
106 | % get full results for optimal geometry
107 | [~, optSimres(ii), optHydro(ii)] = ...
108 | myWaveBotObjFun(x_opt(ii),w,SS,controlType{ii},zmax,fmax,folder.path);
109 | end
110 |
111 | %% plot results
112 |
113 | fig = figure('Name','WaveBot_caseB');
114 | fig.Position = fig.Position .* [1, 1, 1, 1.5];
115 |
116 | mys = {'log','linear','log','log'};
117 | for ii = 1:4
118 | ax(ii) = subplot(4,1,ii);
119 | set(ax(ii),'yscale',mys{ii})
120 | grid on
121 | hold on
122 | end
123 |
124 | mkrs = {'^','o','s'};
125 |
126 | % plot Monte-Carlo results
127 | for ii = 1:size(r,2)
128 |
129 | SMRY = summary(r(:,ii));
130 | pow = abs(SMRY.AvgPow);
131 | vol = arrayfun(@(x) deviceHydro(x).Vo, 1:length(radii))';
132 | pos = SMRY.MaxPos;
133 | obfn = pow ./ (0.88 + radii(:)).^3;
134 |
135 | semilogy(ax(1), radii, pow, 'Marker', mkrs{ii},'LineWidth',1.5)
136 | plot(ax(2), radii, vol, 'Marker', mkrs{ii},'LineWidth',1.5)
137 | semilogy(ax(3), radii, pos, 'Marker', mkrs{ii},'LineWidth',1.5)
138 | semilogy(ax(4), radii, obfn, 'Marker', mkrs{ii},'LineWidth',1.5)
139 | end
140 |
141 |
142 | for jj = 1:length(ax)
143 | set(ax(jj),'ColorOrderIndex',1)
144 | end
145 |
146 | % plot optimal solutions
147 | for ii = 1:length(optSimres)
148 |
149 | SMRY = summary(optSimres(ii));
150 | pow = abs(SMRY.AvgPow);
151 | vol = optHydro(ii).Vo;
152 | pos = SMRY.MaxPos;
153 | obfn = -1*fval(ii);
154 |
155 | stem(ax(1), x_opt(ii), pow, 'Marker', mkrs{ii},...
156 | 'LineWidth',2,'MarkerSize',10)
157 | stem(ax(2), x_opt(ii), vol, 'Marker', mkrs{ii},...
158 | 'LineWidth',2,'MarkerSize',10)
159 | stem(ax(3), x_opt(ii), pos, 'Marker', mkrs{ii},...
160 | 'LineWidth',2,'MarkerSize',10)
161 | stem(ax(4), x_opt(ii), obfn, 'Marker', mkrs{ii},...
162 | 'LineWidth',2,'MarkerSize',10)
163 | end
164 |
165 | fs = 15;
166 |
167 | ylabel(ax(1),'Avg. pow [W]','interpreter','latex','FontSize',fs)
168 | ylabel(ax(2),'Vol. [m$^3$]','interpreter','latex','FontSize',fs)
169 | ylabel(ax(3),'Pos. amp. [m]','interpreter','latex','FontSize',fs)
170 | ylabel(ax(4),'$-1\cdot{}$Obj. fun. [W/m$^3$]','interpreter','latex','FontSize',fs)
171 |
172 | set(ax(1:3),'XTickLabel',[])
173 |
174 | l1 = legend(ax(1),'CC','P','PS');
175 | set(l1,'location','southeast')
176 | xlabel('Outer radius, $r_1$ [m]','interpreter','latex','FontSize',fs)
177 | linkaxes(ax,'x')
178 | xlim([0.25, max(radii)])
179 |
180 | annotation(gcf,'textarrow',[0.808928571428571 0.728571428571429],...
181 | [0.49047619047619 0.434920634920635],'String','$z^{\textrm{{max}}}$',...
182 | 'Interpreter','latex',...
183 | 'FontSize',18);
184 | h = plot(ax(3),[0,1e10],zmax * ones(2,1),'k--');
185 | uistack(h,'bottom');
186 |
187 | % export_fig('WaveBot_caseB_results.pdf','-transparent')
188 |
189 | %% Plot geometries cross sections
190 |
191 | fig = figure('name','WaveBot_caseB_geometrities');
192 | fig.Position = fig.Position .*[1,1,1.5,0.75];
193 | hold on
194 | grid on
195 | ax = gca;
196 |
197 | % Plot optimal solutions
198 | for ii = 1:length(controlType)
199 | radiusOpt = x_opt(ii);
200 | xCoords = [0, radiusOpt, radiusOpt, 0.35, 0];
201 | yCoords = [0.2, 0.2, -0.16, -0.53, -0.53];
202 | p(ii) = plot(ax, xCoords, yCoords, 'Marker', mkrs{ii},...
203 | 'LineWidth',2,'MarkerSize',10,...
204 | 'DisplayName', controlType{ii});
205 | end
206 |
207 | % Plot all solutions
208 | for ii = 1:length(radii)
209 | baseN = length(controlType);
210 | radius = radii(ii);
211 | xCoords = [0, radius, radius, 0.35, 0];
212 | yCoords = [0.2, 0.2, -0.16, -0.53, -0.53];
213 | if ii+baseN == 8+baseN
214 | p(ii+baseN) = plot(ax,xCoords, yCoords, 'ks-',...
215 | 'DisplayName','Original');
216 | else
217 | p(ii+baseN) = plot(ax,xCoords, yCoords, 'bo-', ...
218 | 'DisplayName',num2str(ii));
219 | end
220 | end
221 |
222 | l1 = legend([p(1), p(2), p(3), p(4), p(8+baseN)],...
223 | 'CC','P','PS', ...
224 | 'WecOptTool study geometries', 'Original geometry (Coe et al. 2016)');
225 | set(l1,'location','southeast')
226 |
227 | xlabel('$r$ [m]','interpreter','latex')
228 | ylabel('$z$ [m]','interpreter','latex')
229 | axis equal
230 | ylim([-0.6, 0])
231 | xlim([0, rmax])
232 |
233 | % export_fig('WaveBot_caseB_geometries.pdf','-transparent')
234 |
235 | %% objective function
236 |
237 | function [fval, simRes, deviceHydro] = myWaveBotObjFun(x,w,SS,controlType,zmax,fmax,folderPath)
238 |
239 | % create device and simulate performance the parametric input is
240 | % [r1, r2, d1, d2] (all positive); here we specify only r1
241 | deviceHydro = designDevice('parametric', folderPath, ...
242 | x, 0.35, 0.16, 0.53, w);
243 |
244 | simRes = simulateDevice(deviceHydro, ...
245 | SS, ...
246 | controlType, ...
247 | 'interpMethod','nearest', ...
248 | 'Zmax',zmax, ...
249 | 'Fmax',fmax);
250 | if strcmp(controlType,'PS')
251 | pow =simRes.pow(:,1);
252 | else
253 | pow = simRes.pow;
254 | end
255 |
256 | % objective function value
257 | p_bar = sum(real(pow)); % average power
258 | fval = 1 * p_bar ./ (0.88 + x).^3; % r1 = 0.88 is as-built WaveBot
259 | end
260 |
--------------------------------------------------------------------------------
/examples/WaveBot/WaveBot_caseC.m:
--------------------------------------------------------------------------------
1 | % Case C
2 | % This case performs a single multiobjective optimization study using a PS
3 | % controller with a constrained maximum force. The free design variables
4 | % are:
5 | %
6 | % r outer radius of the hull
7 | % FuMax maximum PTO force
8 | %
9 | % The multi-objective study finds the Pareto front for the following
10 | % responses:
11 | %
12 | % Pbar average absorbed power
13 | % volFun (r_0 + r)^3, where r_0 = 0.88
14 | % zMax maximum displacement
15 |
16 | % Copyright 2020 National Technology & Engineering Solutions of Sandia, LLC
17 | % (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S.
18 | % Government retains certain rights in this software.
19 | %
20 | % This file is part of WecOptTool.
21 | %
22 | % WecOptTool is free software: you can redistribute it and/or modify it
23 | % under the terms of the GNU General Public License as published by the
24 | % Free Software Foundation, either version 3 of the License, or (at
25 | % your option) any later version.
26 | %
27 | % WecOptTool is distributed in the hope that it will be useful, but
28 | % WITHOUT ANY WARRANTY; without even the implied warranty of
29 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30 | % General Public License for more details.
31 | %
32 | % You should have received a copy of the GNU General Public License
33 | % along with WecOptTool. If not, see .
34 |
35 | %% define sea state of interest
36 |
37 | dw = 0.3142;
38 | nf = 50;
39 | w = dw * (1:nf)';
40 | A = 0.125/2;
41 | wp = w(6);
42 | fp = wp/(2*pi);
43 | Tp = 1/fp;
44 | SS = WecOptTool.SeaState.regularWave(w,[A,Tp]);
45 |
46 | %% set up optimization problem
47 |
48 | rmin = 0.25;
49 | rmax = 2;
50 | r0 = 0.88;
51 | zlim = 1e4; % (inactive)
52 |
53 | nvars = 2;
54 | A = [];
55 | B = [];
56 | Aeq = [];
57 | Beq = [];
58 | LB = [rmin, 1e2];
59 | UB = [rmax, 1e3];
60 | NONLCON = [];
61 | opts = optimoptions('paretosearch');
62 | opts.UseParallel = true;
63 | opts.Display = 'iter';
64 | opts.PlotFcn = @psplotparetof;
65 | % opts.MaxFunctionEvaluations = 10; % for debugging
66 |
67 | %% run optimization solver
68 |
69 | folder = WecOptTool.AutoFolder();
70 |
71 | rng(3)
72 | [x,fval,exitflag,output,residuals] = ...
73 | paretosearch(@(x) myWaveBotObjFun(x,w,SS, zlim,folder.path),nvars,...
74 | A,B,Aeq,Beq,LB,UB,NONLCON,opts);
75 |
76 | % Optimized values
77 | radiiOpt = x(:,1);
78 | fmaxOpt = x(:,2);
79 | % Optimized results
80 | pBar = fval(:,1);
81 | vol = fval(:,2);
82 | zmax = fval(:,3);
83 |
84 | %% Plot 3D
85 |
86 | knee_idx = 36; % a potential single solution on the Pareto front
87 |
88 | figure('color','white')
89 | hold on
90 | grid on
91 |
92 | % Pareto front
93 | scatter3(-pBar, vol, zmax, 75, zmax, 'filled','LineWidth',0.5,...
94 | 'MarkerEdgeColor','k','MarkerFaceAlpha',0.5);
95 |
96 | % potential single solution
97 | scatter3(-pBar(knee_idx), vol(knee_idx), zmax(knee_idx),150,...
98 | 'marker','+','MarkerEdgeColor','k','LineWidth',2);
99 |
100 | view([13, 18])
101 |
102 | cb = colorbar;
103 | cb.Label.Interpreter = 'latex';
104 | cb.Label.String = ('Max. PTO stroke, $z^{\textrm{max}}$ [m]');
105 | xlabel('Neg. avg. power, $ - \bar{P}$ [W]', 'interpreter','latex')
106 | ylabel('Vol. fun, $(r_0 + r)^3$ [m$^3$]', 'interpreter','latex')
107 | zlabel('Max. PTO stroke, $z^{\textrm{max}}$ [m]', 'interpreter','latex')
108 |
109 | %% Plot 2D
110 |
111 | fig = figure();
112 | fig.Position = fig.Position .* [1 1 1.5 1]*1;
113 |
114 | tiledlayout(3,4,'TileSpacing','compact','Padding','compact')
115 | axb = nexttile([3,2]);
116 |
117 | hold on
118 | grid on
119 | scatter(axb, pBar,vol,75,zmax,...
120 | 'filled',...
121 | 'MarkerEdgeColor','k',...
122 | 'MarkerFaceAlpha',0.5);
123 |
124 | scatter(axb, pBar(knee_idx),vol(knee_idx),200,...
125 | 'marker','+','MarkerEdgeColor','k','LineWidth',1.5);
126 |
127 |
128 | xlabel('Avg. power, $ \bar{P}$ [W]', 'interpreter','latex')
129 | ylabel('Vol. fun, $(r_0 + r)^3$ [m$^3$]', 'interpreter','latex')
130 |
131 | cb = colorbar;
132 | cb.Label.Interpreter = 'latex';
133 | cb.Label.String = ('Max. PTO stroke, $z^{\textrm{max}}$ [m]');
134 | cb.Location = 'northoutside';
135 |
136 | set(gca,'Yscale','log')
137 |
138 | ylim([min(vol), Inf])
139 |
140 | % annotations
141 | annotation(fig,'textarrow',[0.0813492063492065 0.113095238095238],...
142 | [0.81825396825397 0.554761904761905],'TextEdgeColor',[0 0 0],...
143 | 'TextBackgroundColor',[1 1 1],...
144 | 'String',{'Smaller stroke,','larger vol.'},...
145 | 'HorizontalAlignment','center');
146 | annotation(fig,'textarrow',[0.0726190476190479 0.0821428571428572],...
147 | [0.276984126984128 0.104761904761905],'TextEdgeColor',[0 0 0],...
148 | 'TextBackgroundColor',[1 1 1],...
149 | 'String',{'Larger stroke,','smaller vol.'},...
150 | 'HorizontalAlignment','center');
151 |
152 | rlbs = {'$\bar{P}$','$(r_0 + r)^3$','$z^{\textrm{max}}$'};
153 | xlbs = {'Outer radius, $r$ [m]','Max. PTO force, $F_u^{max}$ [N]'};
154 |
155 | for kk = 1:2*3
156 | ax(kk) = nexttile();
157 | end
158 | ax = reshape(ax,[2,3]);
159 |
160 | for ii = 1:size(x,2)
161 | for jj = 1:size(fval,2)
162 | hold(ax(ii,jj),'on')
163 | scatter(ax(ii,jj),x(:,ii),fval(:,jj),[],zmax,...
164 | 'filled',...
165 | 'MarkerEdgeColor','k',...
166 | 'MarkerFaceAlpha',0.25);
167 |
168 | scatter(ax(ii,jj),x(knee_idx,ii),fval(knee_idx,jj),200,...
169 | 'marker','+',...
170 | 'MarkerEdgeColor','k',...
171 | 'LineWidth',1.5);
172 |
173 | if jj ~= size(fval,2)
174 | set(ax(ii,jj),'XTickLabel',[])
175 | end
176 |
177 | if ii == 1
178 | ylabel(ax(ii,jj),rlbs{jj}, 'interpreter','latex')
179 | end
180 | end
181 | xlabel(ax(ii,jj),xlbs{ii}, 'interpreter','latex')
182 | end
183 |
184 | % exportgraphics(fig, 'WaveBot_caseC_results.pdf','ContentType','vector')
185 |
186 | %% objective function
187 |
188 | function [fval] = myWaveBotObjFun(x,w,SS,zmax,folderPath)
189 |
190 | r1 =x(1);
191 | fmax =x(2);
192 |
193 | % create device and simulate performance the parametric input is
194 | % [r1, r2, d1, d2] (all positive); here we specify only r1
195 |
196 | deviceHydro = designDevice('parametric', folderPath, ...
197 | r1, 0.35, 0.16, 0.53, w);
198 |
199 | simRes = simulateDevice(deviceHydro, ...
200 | SS, ...
201 | 'PS', ...
202 | 'interpMethod','nearest', ...
203 | 'Zmax',zmax, ...
204 | 'Fmax',fmax);
205 | % objective function value
206 | SMRY = summary(simRes);
207 |
208 | pow =simRes.pow(:,1);
209 | p_bar = sum(real(pow)); % average power
210 |
211 | fval(1) = 1 * p_bar;
212 | fval(2) = (0.88 + r1).^3;% r1 = 0.88 is the as-built WaveBot
213 | fval(3) = SMRY.MaxPos;
214 |
215 | end
216 |
--------------------------------------------------------------------------------
/examples/WaveBot/designDevice.m:
--------------------------------------------------------------------------------
1 | function hydro = designDevice(type, varargin)
2 | % WaveBot WEC based on the Sandia "WaveBot" device.
3 | %
4 | % The WaveBot is a model-scale wave energy converter (WEC) tested in
5 | % the Navy's Manuevering and Sea Keeping (MASK) basin. Reports and
6 | % papers about the WaveBot are available at advweccntrls.sandia.gov.
7 |
8 | switch type
9 |
10 | case 'existing'
11 | hydro = WecOptTool.geometry.existingNEMOH(varargin{:});
12 | case 'scalar'
13 | hydro = getHydroScalar(varargin{:});
14 | case 'parametric'
15 | hydro = getHydroParametric(varargin{:});
16 | otherwise
17 | error('WecOptTool:UnknownGeometryType',...
18 | 'Invalid geometry type')
19 | end
20 |
21 | end
22 |
23 | function hydro = getHydroScalar(folder, lambda, w)
24 |
25 | if w(1) == 0
26 | error('WecOptTool:UnknownGeometryType',...
27 | 'Invalid frequency vector') % TODO - more checks
28 | end
29 |
30 | r = lambda * [0, 0.88, 0.88, 0.35, 0];
31 | z = lambda * [0.2, 0.2, -0.16, -0.53, -0.53];
32 |
33 | % Mesh
34 | ntheta = 20;
35 | nfobj = 200;
36 | zG = 0;
37 |
38 | meshes = WecOptTool.mesh("AxiMesh", ...
39 | folder, ...
40 | r, ...
41 | z, ...
42 | ntheta, ...
43 | nfobj, ...
44 | zG, ...
45 | 1);
46 |
47 | hydro = WecOptTool.solver("NEMOH", folder, meshes, w);
48 |
49 | end
50 |
51 | function hydro = getHydroParametric(folder, r1, r2, d1, d2, w)
52 |
53 | if w(1) == 0
54 | w = w(2:end);
55 | end
56 |
57 | r = [0, r1, r1, r2, 0];
58 | z = [0.2, 0.2, -d1, -d2, -d2];
59 |
60 | % Mesh
61 | ntheta = 20;
62 | nfobj = 200;
63 | zG = 0;
64 |
65 | meshes = WecOptTool.mesh("AxiMesh", ...
66 | folder, ...
67 | r, ...
68 | z, ...
69 | ntheta, ...
70 | nfobj, ...
71 | zG, ...
72 | 1);
73 |
74 | hydro = WecOptTool.solver("NEMOH", folder, meshes, w);
75 |
76 | end
77 |
78 |
79 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
80 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
81 | % U.S. Government retains certain rights in this software.
82 | %
83 | % This file is part of WecOptTool.
84 | %
85 | % WecOptTool is free software: you can redistribute it and/or modify
86 | % it under the terms of the GNU General Public License as published by
87 | % the Free Software Foundation, either version 3 of the License, or
88 | % (at your option) any later version.
89 | %
90 | % WecOptTool is distributed in the hope that it will be useful,
91 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
92 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
93 | % GNU General Public License for more details.
94 | %
95 | % You should have received a copy of the GNU General Public License
96 | % along with WecOptTool. If not, see .
97 |
--------------------------------------------------------------------------------
/installNemoh.m:
--------------------------------------------------------------------------------
1 | function installNemoh(nemohPath)
2 | % Adds Nemoh executables path to WecOptTool
3 | %
4 | % Args:
5 | % nemohPath (string):
6 | % path to (platform dependent) NEMOH executables
7 | %
8 |
9 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
10 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
11 | % U.S. Government retains certain rights in this software.
12 | %
13 | % This file is part of WecOptTool.
14 | %
15 | % WecOptTool is free software: you can redistribute it and/or
16 | % modify it under the terms of the GNU General Public License as
17 | % published by the Free Software Foundation, either version 3 of
18 | % the License, or (at your option) any later version.
19 | %
20 | % WecOptTool is distributed in the hope that it will be useful,
21 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
22 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 | % GNU General Public License for more details.
24 | %
25 | % You should have received a copy of the GNU General Public
26 | % License along with WecOptTool. If not, see
27 | % .
28 |
29 | % Check if the a current path is set
30 | try
31 | oldNemohPath = WecOptTool.system.readConfig('nemohPath');
32 | catch
33 | oldNemohPath = "";
34 | end
35 |
36 | % Update the config file
37 | WecOptTool.system.writeConfig('nemohPath', nemohPath)
38 |
39 | % Check installation
40 | nemohExistFlag = WecOptTool.base.NEMOH.isNemohInPath();
41 |
42 | if nemohExistFlag
43 |
44 | fprintf('Successfully Installed Nemoh\n');
45 |
46 | else
47 |
48 | msg = ['Nemoh not found. Please check the specified path ' ...
49 | 'and try again. \n'];
50 | fprintf(msg);
51 |
52 | % Revert back to the old config
53 | WecOptTool.system.writeConfig('nemohPath', oldNemohPath)
54 |
55 | end
56 |
57 | end
58 |
59 |
--------------------------------------------------------------------------------
/runTests.m:
--------------------------------------------------------------------------------
1 | function results = runTests(options)
2 |
3 | arguments
4 | options.reportHTML = true
5 | options.reportPDF = true
6 | end
7 |
8 | import matlab.unittest.TestRunner;
9 | import matlab.unittest.TestSuite;
10 | import matlab.unittest.plugins.TestReportPlugin;
11 |
12 | % Define test suite
13 | suite = TestSuite.fromFolder('tests', ...
14 | 'IncludingSubfolders', true);
15 |
16 | % Build the runner
17 | runner = TestRunner.withTextOutput;
18 |
19 | p = mfilename('fullpath');
20 | [filepath, ~, ~] = fileparts(p);
21 |
22 | % Add HTML plugin
23 | if options.reportHTML
24 | htmlFolder = fullfile(filepath,'test_results');
25 | plugin = TestReportPlugin.producingHTML(htmlFolder);
26 | runner.addPlugin(plugin);
27 | end
28 |
29 | % Add PDF plugin
30 | if options.reportPDF
31 | pdfFile = fullfile(filepath,'test_results.pdf');
32 | plugin = TestReportPlugin.producingPDF(pdfFile);
33 | runner.addPlugin(plugin);
34 | end
35 |
36 | % Run the tests
37 | results = runner.run(suite);
38 |
39 | end
40 |
41 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
42 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
43 | % U.S. Government retains certain rights in this software.
44 | %
45 | % This file is part of WecOptTool.
46 | %
47 | % WecOptTool is free software: you can redistribute it and/or modify
48 | % it under the terms of the GNU General Public License as published by
49 | % the Free Software Foundation, either version 3 of the License, or
50 | % (at your option) any later version.
51 | %
52 | % WecOptTool is distributed in the hope that it will be useful,
53 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
54 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55 | % GNU General Public License for more details.
56 | %
57 | % You should have received a copy of the GNU General Public License
58 | % along with WecOptTool. If not, see .
59 |
60 |
--------------------------------------------------------------------------------
/tests/AutoFolderMule.m:
--------------------------------------------------------------------------------
1 | classdef AutoFolderMule < WecOptTool.AutoFolder
2 |
3 | properties
4 | varsPathPublic
5 | end
6 |
7 | methods
8 | function value = get.varsPathPublic(obj)
9 | value = obj.varsPath;
10 | end
11 | end
12 |
13 | end
14 |
15 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
16 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
17 | % U.S. Government retains certain rights in this software.
18 | %
19 | % This file is part of WecOptTool.
20 | %
21 | % WecOptTool is free software: you can redistribute it and/or modify
22 | % it under the terms of the GNU General Public License as published by
23 | % the Free Software Foundation, either version 3 of the License, or
24 | % (at your option) any later version.
25 | %
26 | % WecOptTool is distributed in the hope that it will be useful,
27 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
28 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 | % GNU General Public License for more details.
30 | %
31 | % You should have received a copy of the GNU General Public License
32 | % along with WecOptTool. If not, see .
33 |
--------------------------------------------------------------------------------
/tests/AutoFolderTest.m:
--------------------------------------------------------------------------------
1 | function tests = AutoFolderTest()
2 | tests = functiontests(localfunctions);
3 | end
4 |
5 | function testPathDestructor(testCase)
6 |
7 | % Directory build
8 | autoFolder = WecOptTool.AutoFolder();
9 | assertTrue(testCase, isfolder(autoFolder.path))
10 | testDir = autoFolder.path;
11 |
12 | % Trigger destructor
13 | clear autoFolder
14 |
15 | verifyEqual(testCase, isfolder(testDir), false)
16 |
17 | end
18 |
19 | function testVarsPathExists(testCase)
20 |
21 | % Directory build
22 | autoFolder = AutoFolderMule();
23 | verifyTrue(testCase, isfolder(autoFolder.varsPathPublic))
24 |
25 | end
26 |
27 | function testVarsPathDestructor(testCase)
28 |
29 | % Directory build
30 | autoFolder = AutoFolderMule();
31 | assertTrue(testCase, isfolder(autoFolder.varsPathPublic))
32 | testDir = autoFolder.varsPathPublic;
33 |
34 | % Trigger destructor
35 | clear autoFolder
36 |
37 | verifyEqual(testCase, isfolder(testDir), false)
38 |
39 | end
40 |
41 | function testStashVar(testCase)
42 |
43 | autoFolder = AutoFolderMule();
44 | myData.value = "Test";
45 | autoFolder.stashVar(myData)
46 | folders = WecOptTool.system.getFolders(autoFolder.varsPathPublic, ...
47 | "absPath", true);
48 | files = dir(fullfile(folders{1}, '*.mat'));
49 | verifySubstring(testCase, files.name, "myData.mat")
50 |
51 | end
52 |
53 | function testRecoverVar(testCase)
54 |
55 | autoFolder = AutoFolderMule();
56 | myData.value = "Test";
57 | autoFolder.stashVar(myData)
58 | test = autoFolder.recoverVar("myData");
59 | verifyEqual(testCase, test{1}, myData)
60 |
61 | end
62 |
63 | function testArchive(testCase)
64 |
65 | import matlab.unittest.fixtures.TemporaryFolderFixture
66 |
67 | tempFixture = testCase.applyFixture( ...
68 | TemporaryFolderFixture('PreservingOnFailure', true, ...
69 | 'WithSuffix', 'testStudySaveNEMOH'));
70 |
71 | autoFolder = WecOptTool.AutoFolder();
72 |
73 | filePath = fullfile(autoFolder.path, 'changing.txt');
74 | fileID = fopen(filePath,'w');
75 | fmt = '%5d %5d %5d %5d\n';
76 | fprintf(fileID,fmt, magic(4));
77 | fclose(fileID);
78 |
79 | % Copy data
80 | testDir = fullfile(tempFixture.Folder, "test");
81 | autoFolder.archive(testDir);
82 |
83 | verifyTrue(testCase, isfolder(testDir))
84 | rmdir(testDir, 's')
85 |
86 | end
87 |
88 | function testArchiveNoCopy(testCase)
89 |
90 | import matlab.unittest.fixtures.TemporaryFolderFixture
91 |
92 | tempFixture = testCase.applyFixture( ...
93 | TemporaryFolderFixture('PreservingOnFailure', true, ...
94 | 'WithSuffix', 'testStudyNoSopyNEMOH'));
95 |
96 | autoFolder = WecOptTool.AutoFolder();
97 |
98 | % Attempt to copy data
99 | testDir = fullfile(tempFixture.Folder, "test");
100 | autoFolder.archive(testDir);
101 |
102 | verifyFalse(testCase, isfolder(testDir))
103 |
104 | end
105 |
106 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
107 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
108 | % U.S. Government retains certain rights in this software.
109 | %
110 | % This file is part of WecOptTool.
111 | %
112 | % WecOptTool is free software: you can redistribute it and/or modify
113 | % it under the terms of the GNU General Public License as published by
114 | % the Free Software Foundation, either version 3 of the License, or
115 | % (at your option) any later version.
116 | %
117 | % WecOptTool is distributed in the hope that it will be useful,
118 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
119 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
120 | % GNU General Public License for more details.
121 | %
122 | % You should have received a copy of the GNU General Public License
123 | % along with WecOptTool. If not, see .
124 |
--------------------------------------------------------------------------------
/tests/PlotsTest.m:
--------------------------------------------------------------------------------
1 | classdef PlotsTest < matlab.unittest.TestCase
2 |
3 | properties
4 | OriginalDefault
5 | end
6 |
7 | methods (TestMethodSetup)
8 | function killPlots (~)
9 | set(0,'DefaultFigureVisible','off');
10 | end
11 | end
12 |
13 | methods (TestMethodTeardown)
14 | function loadPlots (~)
15 | set(0,'DefaultFigureVisible','on');
16 | end
17 | end
18 |
19 | methods(TestClassSetup)
20 | function captureVisibility(testCase)
21 | testCase.OriginalDefault = get(0,'DefaultFigureVisible');
22 | end
23 | end
24 |
25 | methods(TestClassTeardown)
26 | function checkVisibilityRestored(testCase)
27 | testCase.assertEqual(get(0,'DefaultFigureVisible'), ...
28 | testCase.OriginalDefault);
29 | end
30 | end
31 |
32 | methods(Test)
33 |
34 | function testPowerPerFreqSingleSpectrum(testCase)
35 |
36 | % Fake some inputs
37 | spectrum = WecOptTool.SeaState.exampleSpectrum();
38 | input.w = spectrum.w;
39 | input.powPerFreq = spectrum.S;
40 |
41 | WecOptTool.plot.powerPerFreq(input);
42 |
43 | end
44 |
45 | function testPowerPerFreqMultiSpectra(testCase)
46 |
47 | % Fake some inputs
48 | spectra = WecOptTool.SeaState.example8Spectra();
49 | NSS = length(spectra);
50 |
51 | for i = 1:NSS
52 | spectrum = spectra(i);
53 | input(i).w = spectrum.w;
54 | input(i).powPerFreq = spectrum.S(2:end);
55 | end
56 |
57 | WecOptTool.plot.powerPerFreq(input);
58 |
59 | end
60 |
61 | function testPlotMesh(testCase)
62 |
63 | meshes = load('meshes.mat');
64 | WecOptTool.plot.plotMesh(meshes.meshes);
65 |
66 | end
67 |
68 | function testPlotMeshEmpty(testCase)
69 | WecOptTool.plot.plotMesh([]);
70 | end
71 |
72 | end
73 |
74 | end
75 |
76 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
77 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
78 | % U.S. Government retains certain rights in this software.
79 | %
80 | % This file is part of WecOptTool.
81 | %
82 | % WecOptTool is free software: you can redistribute it and/or modify
83 | % it under the terms of the GNU General Public License as published by
84 | % the Free Software Foundation, either version 3 of the License, or
85 | % (at your option) any later version.
86 | %
87 | % WecOptTool is distributed in the hope that it will be useful,
88 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
89 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
90 | % GNU General Public License for more details.
91 | %
92 | % You should have received a copy of the GNU General Public License
93 | % along with WecOptTool. If not, see .
94 |
--------------------------------------------------------------------------------
/tests/base/TempFolderTest.m:
--------------------------------------------------------------------------------
1 | function tests = TempFolderTest()
2 | tests = functiontests(localfunctions);
3 | end
4 |
5 | function testFolderExists(testCase)
6 |
7 | tempFolder = WecOptTool.base.TempFolder();
8 | verifyTrue(testCase, isfolder(tempFolder.path))
9 |
10 | end
11 |
12 | function testBase(testCase)
13 |
14 | tempFolder = WecOptTool.base.TempFolder(tempdir);
15 | verifySubstring(testCase, tempFolder.path, tempdir)
16 |
17 | end
18 |
19 |
20 | function testUnique(testCase)
21 |
22 | tempFolder1 = WecOptTool.base.TempFolder();
23 | tempFolder2 = WecOptTool.base.TempFolder();
24 |
25 | verifyNotEqual(testCase, tempFolder1.path, tempFolder2.path)
26 |
27 | end
28 |
29 | function testBaseUnique(testCase)
30 |
31 | tempFolder1 = WecOptTool.base.TempFolder(tempdir);
32 | tempFolder2 = WecOptTool.base.TempFolder(tempdir);
33 |
34 | verifyNotEqual(testCase, tempFolder1.path, tempFolder2.path)
35 |
36 | end
37 |
38 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
39 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
40 | % U.S. Government retains certain rights in this software.
41 | %
42 | % This file is part of WecOptTool.
43 | %
44 | % WecOptTool is free software: you can redistribute it and/or modify
45 | % it under the terms of the GNU General Public License as published by
46 | % the Free Software Foundation, either version 3 of the License, or
47 | % (at your option) any later version.
48 | %
49 | % WecOptTool is distributed in the hope that it will be useful,
50 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
51 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52 | % GNU General Public License for more details.
53 | %
54 | % You should have received a copy of the GNU General Public License
55 | % along with WecOptTool. If not, see .
56 |
--------------------------------------------------------------------------------
/tests/examples/RM3/ExamplesTest.m:
--------------------------------------------------------------------------------
1 | classdef ExamplesTest < matlab.unittest.TestCase
2 |
3 | properties
4 | OriginalDefault
5 | end
6 |
7 | methods (TestMethodSetup)
8 | function killPlots (~)
9 | set(0,'DefaultFigureVisible','off');
10 | end
11 | end
12 |
13 | methods(TestClassSetup)
14 |
15 | function captureVisibility(testCase)
16 | testCase.OriginalDefault = get(0,'DefaultFigureVisible');
17 | end
18 |
19 | end
20 |
21 | methods(TestClassTeardown)
22 | function checkVisibilityRestored(testCase)
23 | set(0,'DefaultFigureVisible',testCase.OriginalDefault);
24 | testCase.assertEqual(get(0,'DefaultFigureVisible'), ...
25 | testCase.OriginalDefault);
26 | end
27 | end
28 |
29 | methods(Test)
30 |
31 | function testBasic(testCase)
32 |
33 | examplePath = fullfile(WecOptTool.system.getSrcRootPath(), ...
34 | "examples", ...
35 | "RM3", ...
36 | "basic.m");
37 |
38 | % This fills the function namespace with the variables defined
39 | % in the example
40 | run(examplePath);
41 |
42 | verifyEqual(testCase, ...
43 | r(1), 4.046658023714033e+06, ...
44 | 'RelTol', 5 * eps)
45 |
46 | end
47 |
48 | function testOptimization(testCase)
49 |
50 | examplePath = fullfile(WecOptTool.system.getSrcRootPath(), ...
51 | "examples", ...
52 | "RM3", ...
53 | "optimization.m");
54 |
55 | % This fills the function namespace with the variables defined
56 | % in the example
57 | run(examplePath);
58 |
59 | verifyEqual(testCase, ...
60 | bestPerformances(1).x, [5 7.5 1.125 42], ...
61 | 'RelTol', 5 * eps)
62 |
63 |
64 | end
65 |
66 | end
67 |
68 | end
69 |
70 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
71 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
72 | % U.S. Government retains certain rights in this software.
73 | %
74 | % This file is part of WecOptTool.
75 | %
76 | % WecOptTool is free software: you can redistribute it and/or modify
77 | % it under the terms of the GNU General Public License as published by
78 | % the Free Software Foundation, either version 3 of the License, or
79 | % (at your option) any later version.
80 | %
81 | % WecOptTool is distributed in the hope that it will be useful,
82 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
83 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
84 | % GNU General Public License for more details.
85 | %
86 | % You should have received a copy of the GNU General Public License
87 | % along with WecOptTool. If not, see .
88 |
--------------------------------------------------------------------------------
/tests/examples/RM3/ParametricTest.m:
--------------------------------------------------------------------------------
1 | classdef ParametricTest < matlab.unittest.TestCase
2 |
3 | properties
4 | SS
5 | performanceCC
6 | performanceP
7 | performancePS
8 | folder
9 | rundir
10 | end
11 |
12 | methods(TestClassSetup)
13 |
14 | function getPower(testCase)
15 |
16 | import matlab.unittest.fixtures.PathFixture
17 |
18 | addFolder = fullfile(WecOptTool.system.getSrcRootPath(), ...
19 | "examples", ...
20 | "RM3");
21 | testCase.applyFixture(PathFixture(addFolder));
22 |
23 | testCase.SS = WecOptTool.SeaState.exampleSpectrum( ...
24 | "extendFrequencies", 2, ...
25 | "resampleByStep", 0.05);
26 | w = testCase.SS.getRegularFrequencies(0.5);
27 | testCase.folder = WecOptTool.AutoFolder();
28 |
29 | deviceHydro = designDevice('parametric', ...
30 | testCase.folder.path, ...
31 | 10, 15, 3, 42, ...
32 | w);
33 |
34 | testCase.rundir = deviceHydro.runDirectory;
35 |
36 | testCase.performanceP = simulateDevice(deviceHydro, ...
37 | testCase.SS, ...
38 | 'P');
39 |
40 | testCase.performanceCC = simulateDevice(deviceHydro, ...
41 | testCase.SS, ...
42 | 'CC');
43 |
44 | delta_Zmax = 10;
45 | delta_Fmax = 1e9;
46 |
47 | testCase.performancePS = simulateDevice(deviceHydro, ...
48 | testCase.SS, ...
49 | 'PS', ...
50 | delta_Zmax, ...
51 | delta_Fmax, ...
52 | 'iter', ...
53 | 1e-4);
54 |
55 | end
56 |
57 | end
58 |
59 | methods(Test)
60 |
61 | function test_existingRunFiles(testCase)
62 |
63 | tol = 1e-12;
64 | madeFile = testCase.rundir;
65 |
66 | deviceHydro = designDevice('existing', madeFile);
67 | newPerformance = simulateDevice(deviceHydro, ...
68 | testCase.SS, ...
69 | 'CC');
70 |
71 | verifyEqual(testCase, ...
72 | testCase.performanceCC, ...
73 | newPerformance, ...
74 | 'RelTol', tol);
75 |
76 | end
77 |
78 | function test_runParametric(testCase)
79 |
80 | expSol = 4.759798816032207e+06;
81 | pow = sum(testCase.performanceCC.powPerFreq);
82 | verifyEqual(testCase, pow, expSol, 'RelTol', 0.001)
83 |
84 | end
85 |
86 | function test_bounds(testCase)
87 |
88 | % Test that P <= CC
89 | lower = sum(testCase.performanceP.powPerFreq);
90 | upper = sum(testCase.performanceCC.powPerFreq);
91 | verifyGreaterThanOrEqual(testCase, upper, lower)
92 |
93 | end
94 |
95 |
96 | function test_lower_bound(testCase)
97 |
98 | % The P controller should be the lower bound for PS
99 | expSol = sum(testCase.performanceP.powPerFreq);
100 | pow = sum(testCase.performancePS.powPerFreq);
101 | verifyGreaterThanOrEqual(testCase, pow, expSol)
102 |
103 | end
104 |
105 | function test_upper_bound(testCase)
106 |
107 | % The CC controller should be the upper bound for PS
108 | expSol = sum(testCase.performanceCC.powPerFreq);
109 | pow = sum(testCase.performancePS.powPerFreq);
110 | verifyLessThanOrEqual(testCase, pow, expSol)
111 |
112 | end
113 |
114 | end
115 |
116 | end
117 |
118 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
119 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
120 | % U.S. Government retains certain rights in this software.
121 | %
122 | % This file is part of WecOptTool.
123 | %
124 | % WecOptTool is free software: you can redistribute it and/or modify
125 | % it under the terms of the GNU General Public License as published by
126 | % the Free Software Foundation, either version 3 of the License, or
127 | % (at your option) any later version.
128 | %
129 | % WecOptTool is distributed in the hope that it will be useful,
130 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
131 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
132 | % GNU General Public License for more details.
133 | %
134 | % You should have received a copy of the GNU General Public License
135 | % along with WecOptTool. If not, see .
136 |
--------------------------------------------------------------------------------
/tests/examples/RM3/optionsTest.m:
--------------------------------------------------------------------------------
1 | function tests = optionsTest()
2 | tests = functiontests(localfunctions);
3 | end
4 |
5 | function testVerify_CC(testCase)
6 |
7 | import matlab.unittest.fixtures.PathFixture
8 |
9 | addFolder = fullfile(WecOptTool.system.getSrcRootPath(), ...
10 | "examples", ...
11 | "RM3");
12 | testCase.applyFixture(PathFixture(addFolder));
13 |
14 | SS = WecOptTool.SeaState.exampleSpectrum();
15 |
16 | deviceHydro = designDevice('scalar', 1);
17 | performance = simulateDevice(deviceHydro, SS, 'CC');
18 | pow = sum(performance.powPerFreq);
19 |
20 | expSol = 4.072835515358689e+06;
21 | verifyEqual(testCase, pow, expSol, 'RelTol', 0.001)
22 |
23 | end
24 |
25 | function testVerify_damping(testCase)
26 |
27 | import matlab.unittest.fixtures.PathFixture
28 |
29 | addFolder = fullfile(WecOptTool.system.getSrcRootPath(), ...
30 | "examples", ...
31 | "RM3");
32 | testCase.applyFixture(PathFixture(addFolder));
33 |
34 | SS = WecOptTool.SeaState.exampleSpectrum();
35 |
36 | deviceHydro = designDevice('scalar', 1);
37 | performance = simulateDevice(deviceHydro, SS, 'P');
38 | pow = sum(performance.powPerFreq);
39 |
40 | expSol = 2.144693683724375e+06;
41 | verifyEqual(testCase, pow, expSol, 'RelTol', 0.001)
42 |
43 | end
44 |
45 | % function testVerify_SeaStates(testCase)
46 | % % Load Sea States
47 | % SS = load('Y:\WecOptTool\toolbox\+WecOptLib\+tests\+data\sea-states.mat');
48 | %
49 | % %S.ph = rand(length(S.w),1)* 2 * pi;
50 | % RM3Device = WecOptLib.models.RM3DeviceModel();
51 | % WECpow = RM3Device.getPower(S,'P','scalar',1);
52 | % expSol = -1.349990052717686e+06;
53 | % verifyEqual(testCase, WECpow, expSol, 'RelTol', 0.001)
54 | % end
55 |
56 | function testVerify_PS(testCase)
57 |
58 | import matlab.unittest.fixtures.PathFixture
59 |
60 | addFolder = fullfile(WecOptTool.system.getSrcRootPath(), ...
61 | "examples", ...
62 | "RM3");
63 | testCase.applyFixture(PathFixture(addFolder));
64 |
65 | SS = WecOptTool.SeaState.exampleSpectrum("resampleByError", 0.08);
66 |
67 | deviceHydro = designDevice('scalar', 1);
68 | performance = simulateDevice(deviceHydro, SS, 'PS', 10, 1e9);
69 | pow = sum(performance.powPerFreq);
70 |
71 | expSol = 4.072812570315526e+06;
72 | verifyEqual(testCase, pow, expSol, 'RelTol', 0.001)
73 |
74 | end
75 |
76 | function test_RM3_mass(testCase)
77 |
78 | import matlab.unittest.fixtures.PathFixture
79 |
80 | addFolder = fullfile(WecOptTool.system.getSrcRootPath(), ...
81 | "examples", ...
82 | "RM3");
83 | testCase.applyFixture(PathFixture(addFolder));
84 |
85 | deviceHydro = designDevice('scalar', 1);
86 | mass = sum(deviceHydro.Vo * deviceHydro.rho);
87 |
88 | expSol = 1.652838125000000e6;
89 | verifyEqual(testCase, mass, expSol, 'RelTol', 0.001)
90 |
91 | end
92 |
93 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
94 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
95 | % U.S. Government retains certain rights in this software.
96 | %
97 | % This file is part of WecOptTool.
98 | %
99 | % WecOptTool is free software: you can redistribute it and/or modify
100 | % it under the terms of the GNU General Public License as published by
101 | % the Free Software Foundation, either version 3 of the License, or
102 | % (at your option) any later version.
103 | %
104 | % WecOptTool is distributed in the hope that it will be useful,
105 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
106 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
107 | % GNU General Public License for more details.
108 | %
109 | % You should have received a copy of the GNU General Public License
110 | % along with WecOptTool. If not, see .
111 |
--------------------------------------------------------------------------------
/tests/examples/RM3/parametricBugTest.m:
--------------------------------------------------------------------------------
1 | function tests = parametricBugTest()
2 | tests = functiontests(localfunctions);
3 | end
4 |
5 | function test_damping_warning(testCase)
6 |
7 | import matlab.unittest.fixtures.PathFixture
8 |
9 | addFolder = fullfile(WecOptTool.system.getSrcRootPath(), ...
10 | "examples", ...
11 | "RM3");
12 | testCase.applyFixture(PathFixture(addFolder));
13 |
14 | SS = WecOptTool.SeaState.exampleSpectrum("extendFrequencies", 2, ...
15 | "resampleByStep", 0.05);
16 |
17 | w = SS.getRegularFrequencies(0.5);
18 | folder = WecOptTool.AutoFolder();
19 |
20 | deviceHydro = designDevice('parametric', ...
21 | folder.path, ...
22 | 14.76, 15.71, 2.58, 37.27, ...
23 | w);
24 |
25 | testf = @() simulateDevice(deviceHydro, ...
26 | SS, ...
27 | 'P');
28 | verifyWarning(testCase, testf, 'WecOptTool:RM3:BadDamping');
29 |
30 | end
31 |
32 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
33 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
34 | % U.S. Government retains certain rights in this software.
35 | %
36 | % This file is part of WecOptTool.
37 | %
38 | % WecOptTool is free software: you can redistribute it and/or modify
39 | % it under the terms of the GNU General Public License as published by
40 | % the Free Software Foundation, either version 3 of the License, or
41 | % (at your option) any later version.
42 | %
43 | % WecOptTool is distributed in the hope that it will be useful,
44 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
45 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46 | % GNU General Public License for more details.
47 | %
48 | % You should have received a copy of the GNU General Public License
49 | % along with WecOptTool. If not, see .
50 |
--------------------------------------------------------------------------------
/tests/examples/WaveBot/ExamplesTest.m:
--------------------------------------------------------------------------------
1 | classdef ExamplesTest < matlab.unittest.TestCase
2 |
3 | properties
4 | OriginalDefault
5 | end
6 |
7 | methods (TestMethodSetup)
8 | function killPlots (~)
9 | set(0,'DefaultFigureVisible','off');
10 | end
11 | end
12 |
13 | methods(TestClassSetup)
14 |
15 | function captureVisibility(testCase)
16 | testCase.OriginalDefault = get(0,'DefaultFigureVisible');
17 | end
18 |
19 | end
20 |
21 | methods(TestClassTeardown)
22 | function checkVisibilityRestored(testCase)
23 | set(0,'DefaultFigureVisible',testCase.OriginalDefault);
24 | testCase.assertEqual(get(0,'DefaultFigureVisible'), ...
25 | testCase.OriginalDefault);
26 | end
27 | end
28 |
29 | methods(Test)
30 |
31 | function testWaveBot_caseA(testCase)
32 |
33 | examplePath = fullfile(WecOptTool.system.getSrcRootPath(), ...
34 | "examples", ...
35 | "WaveBot", ...
36 | "WaveBot_caseA.m");
37 |
38 | % This fills the function namespace with the variables defined
39 | % in the example
40 | run(examplePath);
41 |
42 | verifyEqual(testCase, length(r), 3)
43 |
44 | end
45 |
46 | end
47 |
48 | end
49 |
50 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
51 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
52 | % U.S. Government retains certain rights in this software.
53 | %
54 | % This file is part of WecOptTool.
55 | %
56 | % WecOptTool is free software: you can redistribute it and/or modify
57 | % it under the terms of the GNU General Public License as published by
58 | % the Free Software Foundation, either version 3 of the License, or
59 | % (at your option) any later version.
60 | %
61 | % WecOptTool is distributed in the hope that it will be useful,
62 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
63 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
64 | % GNU General Public License for more details.
65 | %
66 | % You should have received a copy of the GNU General Public License
67 | % along with WecOptTool. If not, see .
68 |
--------------------------------------------------------------------------------
/tests/math/bisectionTest.m:
--------------------------------------------------------------------------------
1 | function tests = bisectionTest()
2 | tests = functiontests(localfunctions);
3 | end
4 |
5 | function testIdentity(testCase)
6 |
7 | import matlab.unittest.constraints.IsEqualTo
8 | import matlab.unittest.constraints.AbsoluteTolerance
9 |
10 | f = @(x) x;
11 | result = WecOptTool.math.bisection(f, -1, 1);
12 |
13 | testCase.assertThat(result, ...
14 | IsEqualTo(0, 'Within', AbsoluteTolerance(1e-10)))
15 |
16 | end
17 |
18 | function testParabola(testCase)
19 |
20 | import matlab.unittest.constraints.IsEqualTo
21 | import matlab.unittest.constraints.AbsoluteTolerance
22 |
23 | f = @(x) x^2 - 1;
24 | result = WecOptTool.math.bisection(f, 0, 10);
25 |
26 | testCase.assertThat(result, ...
27 | IsEqualTo(1, 'Within', AbsoluteTolerance(1e-10)))
28 |
29 | end
30 |
31 | function testBadInterval(testCase)
32 |
33 | f = @(x) x;
34 | eID = "WecOptTool:bisection:badInterval";
35 | verifyError(testCase, ...
36 | @() WecOptTool.math.bisection(f, 0.5, 1), ...
37 | eID)
38 |
39 | end
40 |
41 | function testSearchSpaceClosed(testCase)
42 |
43 | function f = step(x)
44 | if x > 0
45 | f = 1;
46 | else
47 | f = -1;
48 | end
49 | end
50 |
51 | eID = "WecOptTool:bisection:searchSpaceClosed";
52 | verifyError(testCase, ...
53 | @() WecOptTool.math.bisection(@step, -1, 1), ...
54 | eID)
55 |
56 | end
57 |
58 | function testTooManyIterations(testCase)
59 |
60 | function f = step(x)
61 | if x > 0
62 | f = 1;
63 | else
64 | f = -1;
65 | end
66 | end
67 |
68 | eID = "WecOptTool:bisection:tooManyIterations";
69 | verifyError(testCase, ...
70 | @() WecOptTool.math.bisection(@step, -1, 1, ...
71 | "nmax", 2), ...
72 | eID)
73 |
74 | end
75 |
76 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
77 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
78 | % U.S. Government retains certain rights in this software.
79 | %
80 | % This file is part of WecOptTool.
81 | %
82 | % WecOptTool is free software: you can redistribute it and/or modify
83 | % it under the terms of the GNU General Public License as published by
84 | % the Free Software Foundation, either version 3 of the License, or
85 | % (at your option) any later version.
86 | %
87 | % WecOptTool is distributed in the hope that it will be useful,
88 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
89 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
90 | % GNU General Public License for more details.
91 | %
92 | % You should have received a copy of the GNU General Public License
93 | % along with WecOptTool. If not, see .
94 |
--------------------------------------------------------------------------------
/tests/meshes.mat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SNL-WaterPower/WecOptTool-MATLAB/0a9faa189f8570444fac5ebe0da2a9fcd94958eb/tests/meshes.mat
--------------------------------------------------------------------------------
/tests/meshsolver/getNemohCylinderTest.m:
--------------------------------------------------------------------------------
1 | classdef getNemohCylinderTest < matlab.unittest.TestCase
2 | % Notes:
3 | %
4 | % Tests cylinder shaped geometries
5 | %
6 | % All test functions use a relative tolerance. to adjust the tolerance,
7 | % modify the `tol` property of the class.
8 | %
9 | % Currently all verifications are based off of run data from a working
10 | % version. A more analytic approach may be taken at a later date.
11 |
12 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
13 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
14 | % U.S. Government retains certain rights in this software.
15 | %
16 | % This file is part of WecOptTool.
17 | %
18 | % WecOptTool is free software: you can redistribute it and/or
19 | % modify it under the terms of the GNU General Public License as
20 | % published by the Free Software Foundation, either version 3 of
21 | % the License, or (at your option) any later version.
22 | %
23 | % WecOptTool is distributed in the hope that it will be useful,
24 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
25 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 | % GNU General Public License for more details.
27 | %
28 | % You should have received a copy of the GNU General Public
29 | % License along with WecOptTool. If not, see
30 | % .
31 |
32 | properties
33 | tol = .001
34 | w = linspace(0.1,1,10)
35 | hydro
36 | end
37 |
38 | methods(TestClassSetup)
39 |
40 | function runNEMOH(testCase)
41 |
42 | import matlab.unittest.fixtures.TemporaryFolderFixture
43 | tempFixture = testCase.applyFixture( ...
44 | TemporaryFolderFixture('PreservingOnFailure', true, ...
45 | 'WithSuffix', 'testCylinderM'));
46 |
47 | r = [0 1 1 0];
48 | z = [.5 .5 -.5 -.5];
49 | ntheta = 20;
50 | nfobj = 200;
51 | zG = 0;
52 |
53 | meshes = WecOptTool.mesh("AxiMesh", ...
54 | tempFixture.Folder, ...
55 | r, ...
56 | z, ...
57 | ntheta, ...
58 | nfobj, ...
59 | zG, ...
60 | 1);
61 |
62 | testCase.hydro = WecOptTool.solver("NEMOH", ...
63 | tempFixture.Folder, ...
64 | meshes, ...
65 | testCase.w);
66 |
67 | end
68 |
69 | end
70 |
71 | methods(Test)
72 |
73 | function testCylinderM(testCase)
74 |
75 | mAct = testCase.hydro.Vo * testCase.hydro.rho;
76 | mExp = 1602.74022500000;
77 |
78 | verifyEqual(testCase, mAct, mExp, 'RelTol', testCase.tol)
79 |
80 | end
81 |
82 |
83 | function testCylinderA(testCase)
84 |
85 | AAct = squeeze(testCase.hydro.A(3,3,:)) * testCase.hydro.rho;
86 |
87 | %expected value off of previous runs
88 | AExp = [2.449950000000000e+03;...
89 | 2.466340000000000e+03;...
90 | 2.479139000000000e+03;...
91 | 2.502448000000000e+03;...
92 | 2.518107000000000e+03;...
93 | 2.526768000000000e+03;...
94 | 2.530628000000000e+03;...
95 | 2.526432000000000e+03;...
96 | 2.514688000000000e+03;...
97 | 2.496468000000000e+03];
98 |
99 | verifyEqual(testCase, AAct, AExp, 'RelTol', testCase.tol)
100 |
101 | end
102 |
103 | function testCylinderAinf(testCase)
104 |
105 | AinfAct = testCase.hydro.Ainf(3,3) * testCase.hydro.rho;
106 | AinfExp = 2.496468000000000e+03;
107 |
108 | verifyEqual(testCase, AinfAct, AinfExp, 'RelTol', testCase.tol)
109 |
110 | end
111 |
112 | function testCylinderB(testCase)
113 |
114 | BAct = squeeze(testCase.hydro.B(3,3,:)).*testCase.w' * ...
115 | testCase.hydro.rho;
116 | BExp = [0.509248900000000;...
117 | 4.04226400000000;...
118 | 13.4646100000000;...
119 | 31.3241400000000;...
120 | 59.7084300000000;...
121 | 100.121500000000;...
122 | 153.377200000000;...
123 | 219.584900000000;...
124 | 298.097900000000;...
125 | 387.615300000000];
126 |
127 | verifyEqual(testCase, BAct, BExp, 'RelTol', testCase.tol)
128 |
129 | end
130 |
131 | function testCylinderEx(testCase)
132 |
133 | ExAct = squeeze(testCase.hydro.ex(3,1,:)) * ...
134 | testCase.hydro.rho * ...
135 | testCase.hydro.g;
136 | ExExp = [31405.2399999587 + 0.0509254181638977i;...
137 | 31283.0899895515 + 0.808531169306684i;...
138 | 31078.8897373919 + 4.04019042295150i;...
139 | 30790.5674486798 + 12.5344804511268i;...
140 | 30419.5153310345 + 29.8738322913427i;...
141 | 29967.3696654497 + 60.1343427919986i;...
142 | 29435.7036000245 + 107.528514833500i;...
143 | 28829.1224344311 + 176.055037363224i;...
144 | 28152.4237611598 + 269.115469988388i;...
145 | 27410.4363488219 + 389.247231437354i];
146 |
147 | verifyEqual(testCase, ExAct, ExExp, 'RelTol', testCase.tol);
148 |
149 | end
150 |
151 | function testCylinderC(testCase)
152 |
153 | CAct = testCase.hydro.C(3,3) * testCase.hydro.rho * ...
154 | testCase.hydro.g;
155 | CExp = 3.144575000000000e+04;
156 | verifyEqual(testCase, CAct, CExp, 'RelTol', testCase.tol);
157 |
158 | end
159 |
160 | end
161 |
162 | end
163 |
164 |
165 |
--------------------------------------------------------------------------------
/tests/meshsolver/getNemohSphereTest.m:
--------------------------------------------------------------------------------
1 | classdef getNemohSphereTest < matlab.unittest.TestCase
2 | % Notes:
3 | %
4 | % Tests sphere shaped geometries.
5 | %
6 | % All test functions use a relative tolerance. to adjust the tolerance,
7 | % modify the `tol` property of the class.
8 | %
9 | % Currently all verifications are based off of run data from a working
10 | % version. A more analytic approach may be taken at a later date.
11 |
12 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
13 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
14 | % U.S. Government retains certain rights in this software.
15 | %
16 | % This file is part of WecOptTool.
17 | %
18 | % WecOptTool is free software: you can redistribute it and/or
19 | % modify it under the terms of the GNU General Public License as
20 | % published by the Free Software Foundation, either version 3 of
21 | % the License, or (at your option) any later version.
22 | %
23 | % WecOptTool is distributed in the hope that it will be useful,
24 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
25 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 | % GNU General Public License for more details.
27 | %
28 | % You should have received a copy of the GNU General Public
29 | % License along with WecOptTool. If not, see
30 | % .
31 |
32 | properties
33 | tol = .001
34 | w = linspace(0.1,1,10)
35 | hydro
36 | end
37 |
38 | methods(TestClassSetup)
39 |
40 | function runNEMOH(testCase)
41 |
42 | import matlab.unittest.fixtures.TemporaryFolderFixture
43 | tempFixture = testCase.applyFixture( ...
44 | TemporaryFolderFixture('PreservingOnFailure', true, ...
45 | 'WithSuffix', 'testCylinderM'));
46 |
47 | n = 40;
48 |
49 | % using n points, preallocating space for speed.
50 | z = 1:n;
51 | r = 1:n;
52 |
53 | % want the top and bottom of sphere to be accounted for
54 | z(1) = 1;
55 | z(n) = -1;
56 | r(1) = 0;
57 | r(n) = 0;
58 |
59 | %chebyshev node formula:
60 | %for k in 1..n
61 | %zk = cos((2k-1)/2n*pi)
62 |
63 | %using n-2 chebyshev nodes, to round out the array of size n
64 |
65 | for k = 1:(n-2)
66 | zk = cos((2*k-1)/(2*(n-2)) * pi);
67 | z(k+1) = zk;
68 | r(k+1) = sqrt(1 - zk^2);
69 | end
70 |
71 | ntheta = 20;
72 | nfobj = 200;
73 | zG = 0;
74 |
75 | meshes = WecOptTool.mesh("AxiMesh", ...
76 | tempFixture.Folder, ...
77 | r, ...
78 | z, ...
79 | ntheta, ...
80 | nfobj, ...
81 | zG, ...
82 | 1);
83 |
84 | testCase.hydro = WecOptTool.solver("NEMOH", ...
85 | tempFixture.Folder, ...
86 | meshes, ...
87 | testCase.w);
88 |
89 | end
90 |
91 | end
92 |
93 | methods(Test)
94 |
95 | function testSphereA(testCase)
96 |
97 | AAct = squeeze(testCase.hydro.A(3,3,:)) * testCase.hydro.rho;
98 | AExp = [1.805080000000000e+03;...
99 | 1.822259000000000e+03;...
100 | 1.846489000000000e+03;...
101 | 1.866336000000000e+03;...
102 | 1.882618000000000e+03;...
103 | 1.893489000000000e+03;...
104 | 1.897963000000000e+03;...
105 | 1.895358000000000e+03;...
106 | 1.884580000000000e+03;...
107 | 1.866094000000000e+03];
108 |
109 | verifyEqual(testCase, AAct, AExp, 'RelTol', testCase.tol)
110 |
111 | end
112 |
113 | function testSphereAinf(testCase)
114 |
115 | AinfAct = testCase.hydro.Ainf(3,3) * testCase.hydro.rho;
116 | AinfExp = 1.866094000000000e+03;
117 |
118 | verifyEqual(testCase, AinfAct, AinfExp, 'RelTol', testCase.tol)
119 |
120 | end
121 |
122 | function testSphereB(testCase)
123 |
124 | BAct = squeeze(testCase.hydro.B(3,3,:)).*testCase.w' * ...
125 | testCase.hydro.rho;
126 | BExp = [0.517412700000000;...
127 | 4.108027000000001;...
128 | 13.687960000000000;...
129 | 31.861250000000002;...
130 | 60.774350000000000;...
131 | 1.019905000000000e+02;...
132 | 1.564007000000000e+02;...
133 | 2.241753000000000e+02;...
134 | 3.047622000000000e+02;...
135 | 3.969600000000000e+02];
136 |
137 | verifyEqual(testCase, BAct, BExp, 'RelTol', testCase.tol);
138 |
139 | end
140 |
141 | function testSphereEx(testCase)
142 |
143 | ExAct = squeeze(testCase.hydro.ex(3,1,:)) * ...
144 | testCase.hydro.rho * testCase.hydro.g;
145 | ExExp = [3.135264999995731e+04 + 5.174237563772652e-02i;...
146 | 3.123397998919338e+04 + 8.216251484554422e-01i;...
147 | 3.103439972829488e+04 + 4.106630071455531e+00i;...
148 | 3.075387735867814e+04 + 1.274604976429039e+01i;...
149 | 3.039233480194188e+04 + 3.039422925936637e+01i;...
150 | 2.995119743334907e+04 + 6.122006325009694e+01i;...
151 | 2.943299609927892e+04 + 1.095575640094596e+02i;...
152 | 2.884138117499728e+04 + 1.795407533474796e+02i;...
153 | 2.818175074881988e+04 + 2.747483930624004e+02i;...
154 | 2.745981680392228e+04 + 3.979351517871062e+02i];
155 |
156 | verifyEqual(testCase, ExAct, ExExp, 'RelTol', testCase.tol)
157 |
158 | end
159 |
160 | function testSphereC(testCase)
161 |
162 | CAct = testCase.hydro.C(3,3) * testCase.hydro.rho * ...
163 | testCase.hydro.g;
164 | CExp = 3.139205000000000e+04;
165 |
166 | verifyEqual(testCase, CAct, CExp, 'RelTol', testCase.tol)
167 |
168 | end
169 |
170 | end
171 |
172 | end
173 |
174 |
175 |
--------------------------------------------------------------------------------
/tests/meshsolver/getNemohTest.m:
--------------------------------------------------------------------------------
1 | function tests = getNemohTest
2 | tests = functiontests(localfunctions);
3 | end
4 |
5 | function testNoExtraFigures(testCase)
6 |
7 | import matlab.unittest.fixtures.TemporaryFolderFixture
8 |
9 | tempFixture = testCase.applyFixture( ...
10 | TemporaryFolderFixture('PreservingOnFailure', true, ...
11 | 'WithSuffix', 'testNoExtraFigures'));
12 |
13 | h = findobj('type','figure');
14 | nExpected = length(h);
15 |
16 | w = 0.1;
17 | r=[0 1 1 0];
18 | z=[.5 .5 -.5 -.5];
19 |
20 | ntheta = 20;
21 | nfobj = 200;
22 | zG = 0;
23 |
24 | meshes = WecOptTool.mesh("AxiMesh", ...
25 | tempFixture.Folder, ...
26 | r, ...
27 | z, ...
28 | ntheta, ...
29 | nfobj, ...
30 | zG, ...
31 | 1);
32 |
33 | WecOptTool.solver("NEMOH", ...
34 | tempFixture.Folder, ...
35 | meshes, ...
36 | w);
37 |
38 | h = findobj('type','figure');
39 | nActual = length(h);
40 |
41 | verifyEqual(testCase, nActual, nExpected)
42 |
43 | end
44 |
45 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
46 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
47 | % U.S. Government retains certain rights in this software.
48 | %
49 | % This file is part of WecOptTool.
50 | %
51 | % WecOptTool is free software: you can redistribute it and/or modify
52 | % it under the terms of the GNU General Public License as published by
53 | % the Free Software Foundation, either version 3 of the License, or
54 | % (at your option) any later version.
55 | %
56 | % WecOptTool is distributed in the hope that it will be useful,
57 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
58 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
59 | % GNU General Public License for more details.
60 | %
61 | % You should have received a copy of the GNU General Public License
62 | % along with WecOptTool. If not, see .
63 |
--------------------------------------------------------------------------------
/tests/scriptsTest.m:
--------------------------------------------------------------------------------
1 | function tests = scriptsTest()
2 | tests = functiontests(localfunctions);
3 | end
4 |
5 | function testDependencyCheck(testCase)
6 |
7 | srcRootPath = WecOptTool.system.getSrcRootPath();
8 | cd(srcRootPath);
9 | verifyWarningFree(testCase, @dependencyCheck);
10 |
11 | end
12 |
13 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
14 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
15 | % U.S. Government retains certain rights in this software.
16 | %
17 | % This file is part of WecOptTool.
18 | %
19 | % WecOptTool is free software: you can redistribute it and/or modify
20 | % it under the terms of the GNU General Public License as published by
21 | % the Free Software Foundation, either version 3 of the License, or
22 | % (at your option) any later version.
23 | %
24 | % WecOptTool is distributed in the hope that it will be useful,
25 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
26 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 | % GNU General Public License for more details.
28 | %
29 | % You should have received a copy of the GNU General Public License
30 | % along with WecOptTool. If not, see .
31 |
--------------------------------------------------------------------------------
/tests/system/getFoldersTest.m:
--------------------------------------------------------------------------------
1 | function tests = getFoldersTest()
2 | tests = functiontests(localfunctions);
3 | end
4 |
5 | function testNotFolder(testCase)
6 |
7 | import matlab.unittest.fixtures.TemporaryFolderFixture
8 | tempFixture = testCase.applyFixture( ...
9 | TemporaryFolderFixture('PreservingOnFailure', true, ...
10 | 'WithSuffix', 'testNotFolder'));
11 |
12 | dummyFile = fullfile(tempFixture.Folder, "dummy.txt");
13 | fclose(fopen(dummyFile, 'w'));
14 | assertTrue(testCase, isfile(dummyFile))
15 |
16 | folderNames = WecOptTool.system.getFolders(dummyFile);
17 | verifyEmpty(testCase, folderNames)
18 |
19 | end
20 |
21 | function testEmptyFolder(testCase)
22 |
23 | import matlab.unittest.fixtures.TemporaryFolderFixture
24 | tempFixture = testCase.applyFixture( ...
25 | TemporaryFolderFixture('PreservingOnFailure', true, ...
26 | 'WithSuffix', 'testNotFolder'));
27 |
28 | dummyFile = fullfile(tempFixture.Folder, "dummy.txt");
29 | fclose(fopen(dummyFile, 'w'));
30 | assertTrue(testCase, isfile(dummyFile))
31 |
32 | folderNames = WecOptTool.system.getFolders(tempFixture.Folder);
33 | verifyEmpty(testCase, folderNames)
34 |
35 | end
36 |
37 | function testRelativePaths(testCase)
38 |
39 | import matlab.unittest.fixtures.TemporaryFolderFixture
40 | tempFixture = testCase.applyFixture( ...
41 | TemporaryFolderFixture('PreservingOnFailure', true, ...
42 | 'WithSuffix', 'testNotFolder'));
43 |
44 | % Make some folders to test
45 | nFolders = 5;
46 | expected = cell(1, nFolders);
47 |
48 | for i = 1:nFolders
49 |
50 | folderName = sprintf('dummy%d', i);
51 | absFolderPath = fullfile(tempFixture.Folder, folderName);
52 | mkdir(absFolderPath);
53 |
54 | assertTrue(testCase, isfolder(absFolderPath))
55 | expected{i} = folderName;
56 |
57 | end
58 |
59 | folderNames = WecOptTool.system.getFolders(tempFixture.Folder);
60 | verifyEqual(testCase, folderNames, expected)
61 |
62 | end
63 |
64 |
65 | function testAbsolutePaths(testCase)
66 |
67 | import matlab.unittest.fixtures.TemporaryFolderFixture
68 | tempFixture = testCase.applyFixture( ...
69 | TemporaryFolderFixture('PreservingOnFailure', true, ...
70 | 'WithSuffix', 'testNotFolder'));
71 |
72 | % Make some folders to test
73 | nFolders = 5;
74 | expected = cell(1, nFolders);
75 |
76 | for i = 1:nFolders
77 |
78 | folderName = sprintf('dummy%d', i);
79 | absFolderPath = fullfile(tempFixture.Folder, folderName);
80 | mkdir(absFolderPath);
81 |
82 | assertTrue(testCase, isfolder(absFolderPath))
83 | expected{i} = absFolderPath;
84 |
85 | end
86 |
87 | folderNames = WecOptTool.system.getFolders(tempFixture.Folder, ...
88 | "absPath", true);
89 | verifyEqual(testCase, folderNames, expected)
90 |
91 | end
92 |
93 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
94 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
95 | % U.S. Government retains certain rights in this software.
96 | %
97 | % This file is part of WecOptTool.
98 | %
99 | % WecOptTool is free software: you can redistribute it and/or modify
100 | % it under the terms of the GNU General Public License as published by
101 | % the Free Software Foundation, either version 3 of the License, or
102 | % (at your option) any later version.
103 | %
104 | % WecOptTool is distributed in the hope that it will be useful,
105 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
106 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
107 | % GNU General Public License for more details.
108 | %
109 | % You should have received a copy of the GNU General Public License
110 | % along with WecOptTool. If not, see .
111 |
--------------------------------------------------------------------------------
/tests/system/hasToolboxTest.m:
--------------------------------------------------------------------------------
1 | function tests = hasToolboxTest()
2 | tests = functiontests(localfunctions);
3 | end
4 |
5 | function testhasParallelToolbox(testCase)
6 |
7 | import matlab.unittest.constraints.IsSubsetOf
8 | import WecOptTool.system.hasToolbox
9 |
10 | [combined, ...
11 | licensed, ...
12 | installed] = hasToolbox("Distrib_Computing_Toolbox", ...
13 | "Parallel Computing Toolbox");
14 |
15 | testCase.verifyThat(combined, IsSubsetOf(logical([0;1])));
16 | testCase.verifyThat(licensed, IsSubsetOf(logical([0;1])));
17 | testCase.verifyThat(installed, IsSubsetOf(logical([0;1])));
18 |
19 | end
20 |
21 | % Copyright 2020 Sandia National Labs
22 | %
23 | % This file is part of WecOptTool.
24 | %
25 | % WecOptTool is free software: you can redistribute it and/or modify
26 | % it under the terms of the GNU General Public License as published by
27 | % the Free Software Foundation, either version 3 of the License, or
28 | % (at your option) any later version.
29 | %
30 | % WecOptTool is distributed in the hope that it will be useful,
31 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
32 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 | % GNU General Public License for more details.
34 | %
35 | % You should have received a copy of the GNU General Public License
36 | % along with Foobar. If not, see .
37 |
--------------------------------------------------------------------------------
/tests/system/isParallelTest.m:
--------------------------------------------------------------------------------
1 | function tests = isParallelTest()
2 | tests = functiontests(localfunctions);
3 | end
4 |
5 | function testIsParallelTrue(testCase)
6 |
7 | import WecOptTool.system.hasToolbox
8 |
9 | installed = hasToolbox("Distrib_Computing_Toolbox", ...
10 | "Parallel Computing Toolbox");
11 | testCase.assumeTrue(installed, 'Parallel toolbox not available')
12 |
13 | tests = zeros(1, 2);
14 |
15 | parfor i = 1:length(tests)
16 |
17 | % Check if the pool is working. If not, assume that the test passes.
18 | p = gcp('nocreate')
19 |
20 | if isempty(p)
21 | tests(i) = true;
22 | else
23 | tests(i) = WecOptTool.system.isParallel();
24 | end
25 |
26 | end
27 |
28 | verifyEqual(testCase, all(tests), true)
29 |
30 | end
31 |
32 | function testIsParallelFalse(testCase)
33 |
34 | tests = zeros(1, 2);
35 |
36 | for i = 1:length(tests)
37 | tests(i) = WecOptTool.system.isParallel();
38 | end
39 |
40 | verifyEqual(testCase, any(tests), false)
41 |
42 | end
43 |
44 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
45 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
46 | % U.S. Government retains certain rights in this software.
47 | %
48 | % This file is part of WecOptTool.
49 | %
50 | % WecOptTool is free software: you can redistribute it and/or modify
51 | % it under the terms of the GNU General Public License as published by
52 | % the Free Software Foundation, either version 3 of the License, or
53 | % (at your option) any later version.
54 | %
55 | % WecOptTool is distributed in the hope that it will be useful,
56 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
57 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
58 | % GNU General Public License for more details.
59 | %
60 | % You should have received a copy of the GNU General Public License
61 | % along with WecOptTool. If not, see .
62 |
--------------------------------------------------------------------------------
/tests/system/readConfigTest.m:
--------------------------------------------------------------------------------
1 | function tests = readConfigTest
2 | tests = functiontests(localfunctions);
3 | end
4 |
5 | function testReadConfigNoDir(testCase)
6 |
7 | func = @() WecOptTool.system.readConfig("test", 'configDir', "");
8 | eID = 'WecOptTool:readConfig:missingDirectory';
9 | verifyError(testCase, func, eID)
10 |
11 | end
12 |
13 | function testReadConfigNoFile(testCase)
14 |
15 | import matlab.unittest.fixtures.TemporaryFolderFixture
16 |
17 | tempFixture = testCase.applyFixture( ...
18 | TemporaryFolderFixture('PreservingOnFailure', true, ...
19 | 'WithSuffix', 'testReadConfigNoFile'));
20 |
21 | func = @() WecOptTool.system.readConfig( ...
22 | "test", ...
23 | 'configDir', tempFixture.Folder);
24 | eID = 'WecOptTool:readConfig:missingFile';
25 | verifyError(testCase, func, eID)
26 |
27 | end
28 |
29 | function testReadConfigNoKey(testCase)
30 |
31 | import matlab.unittest.fixtures.TemporaryFolderFixture
32 | import matlab.unittest.constraints.IsFile
33 |
34 | tempFixture = testCase.applyFixture( ...
35 | TemporaryFolderFixture('PreservingOnFailure', true, ...
36 | 'WithSuffix', 'testReadConfigNoKey'));
37 |
38 | WecOptTool.system.writeConfig("test", 1, ...
39 | 'configDir', tempFixture.Folder)
40 |
41 | filePath = fullfile(tempFixture.Folder, 'config.json');
42 | testCase.verifyThat(filePath, IsFile)
43 |
44 | func = @() WecOptTool.system.readConfig( ...
45 | "wrongkey", ...
46 | 'configDir', tempFixture.Folder);
47 | eID = 'WecOptTool:readConfig:missingKey';
48 | verifyError(testCase, func, eID)
49 |
50 | end
51 |
52 | function testReadConfig(testCase)
53 |
54 | import matlab.unittest.fixtures.TemporaryFolderFixture
55 | import matlab.unittest.constraints.IsFile
56 | import matlab.unittest.constraints.IsEqualTo
57 |
58 | tempFixture = testCase.applyFixture( ...
59 | TemporaryFolderFixture('PreservingOnFailure', true, ...
60 | 'WithSuffix', 'testReadConfig'));
61 |
62 | expected = 1;
63 | WecOptTool.system.writeConfig("test", expected, ...
64 | 'configDir', tempFixture.Folder)
65 |
66 | filePath = fullfile(tempFixture.Folder, 'config.json');
67 | testCase.verifyThat(filePath, IsFile)
68 |
69 | actual = WecOptTool.system.readConfig( ...
70 | "test", ...
71 | 'configDir', tempFixture.Folder);
72 |
73 | testCase.verifyThat(actual, IsEqualTo(expected))
74 |
75 | end
76 |
77 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
78 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
79 | % U.S. Government retains certain rights in this software.
80 | %
81 | % This file is part of WecOptTool.
82 | %
83 | % WecOptTool is free software: you can redistribute it and/or modify
84 | % it under the terms of the GNU General Public License as published by
85 | % the Free Software Foundation, either version 3 of the License, or
86 | % (at your option) any later version.
87 | %
88 | % WecOptTool is distributed in the hope that it will be useful,
89 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
90 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
91 | % GNU General Public License for more details.
92 | %
93 | % You should have received a copy of the GNU General Public License
94 | % along with WecOptTool. If not, see .
95 |
--------------------------------------------------------------------------------
/tests/system/writeConfigTest.m:
--------------------------------------------------------------------------------
1 | function tests = writeConfigTest
2 | tests = functiontests(localfunctions);
3 | end
4 |
5 | function testWriteConfigNew(testCase)
6 |
7 | import matlab.unittest.fixtures.TemporaryFolderFixture
8 | import matlab.unittest.constraints.IsFile
9 | import matlab.unittest.constraints.IsEqualTo
10 |
11 | tempFixture = testCase.applyFixture( ...
12 | TemporaryFolderFixture('PreservingOnFailure', true, ...
13 | 'WithSuffix', 'testWriteConfigNew'));
14 |
15 | WecOptTool.system.writeConfig("test", 1, ...
16 | 'configDir', tempFixture.Folder)
17 |
18 | filePath = fullfile(tempFixture.Folder, 'config.json');
19 | testCase.verifyThat(filePath, IsFile)
20 |
21 | fileID = fopen(filePath);
22 | tline = fgetl(fileID);
23 | fclose(fileID);
24 |
25 | expVal = '{"test":1}';
26 | testCase.verifyThat(tline, IsEqualTo(expVal))
27 |
28 | end
29 |
30 | function testWriteConfigExists(testCase)
31 |
32 | import matlab.unittest.fixtures.TemporaryFolderFixture
33 | import matlab.unittest.constraints.IsFile
34 | import matlab.unittest.constraints.IsEqualTo
35 |
36 | tempFixture = testCase.applyFixture( ...
37 | TemporaryFolderFixture('PreservingOnFailure', true, ...
38 | 'WithSuffix', 'testWriteConfigExists'));
39 |
40 | WecOptTool.system.writeConfig("test", 1, ...
41 | 'configDir', tempFixture.Folder)
42 |
43 | filePath = fullfile(tempFixture.Folder, 'config.json');
44 | testCase.verifyThat(filePath, IsFile)
45 |
46 | fileID = fopen(filePath);
47 | tline = fgetl(fileID);
48 | fclose(fileID);
49 |
50 | expVal = '{"test":1}';
51 | testCase.verifyThat(tline, IsEqualTo(expVal))
52 |
53 | WecOptTool.system.writeConfig("new", 2, ...
54 | 'configDir', tempFixture.Folder)
55 |
56 | filePath = fullfile(tempFixture.Folder, 'config.json');
57 | testCase.verifyThat(filePath, IsFile)
58 |
59 | fileID = fopen(filePath);
60 | tline = fgetl(fileID);
61 | fclose(fileID);
62 |
63 | expVal = '{"test":1,"new":2}';
64 | testCase.verifyThat(tline, IsEqualTo(expVal))
65 |
66 | end
67 |
68 | function testWriteConfigRemove(testCase)
69 |
70 | import matlab.unittest.fixtures.TemporaryFolderFixture
71 | import matlab.unittest.constraints.IsFile
72 | import matlab.unittest.constraints.IsEqualTo
73 |
74 | tempFixture = testCase.applyFixture( ...
75 | TemporaryFolderFixture('PreservingOnFailure', true, ...
76 | 'WithSuffix', 'testWriteConfigRemove'));
77 |
78 | WecOptTool.system.writeConfig("test", 1, ...
79 | 'configDir', tempFixture.Folder)
80 |
81 | filePath = fullfile(tempFixture.Folder, 'config.json');
82 | testCase.verifyThat(filePath, IsFile)
83 |
84 | fileID = fopen(filePath);
85 | tline = fgetl(fileID);
86 | fclose(fileID);
87 |
88 | expVal = '{"test":1}';
89 | testCase.verifyThat(tline, IsEqualTo(expVal))
90 |
91 | WecOptTool.system.writeConfig("test", "", ...
92 | 'configDir', tempFixture.Folder)
93 |
94 | filePath = fullfile(tempFixture.Folder, 'config.json');
95 | testCase.verifyThat(filePath, IsFile)
96 |
97 | fileID = fopen(filePath);
98 | tline = fgetl(fileID);
99 | fclose(fileID);
100 |
101 | expVal = '{}';
102 | testCase.verifyThat(tline, IsEqualTo(expVal))
103 |
104 | end
105 |
106 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
107 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
108 | % U.S. Government retains certain rights in this software.
109 | %
110 | % This file is part of WecOptTool.
111 | %
112 | % WecOptTool is free software: you can redistribute it and/or modify
113 | % it under the terms of the GNU General Public License as published by
114 | % the Free Software Foundation, either version 3 of the License, or
115 | % (at your option) any later version.
116 | %
117 | % WecOptTool is distributed in the hope that it will be useful,
118 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
119 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
120 | % GNU General Public License for more details.
121 | %
122 | % You should have received a copy of the GNU General Public License
123 | % along with WecOptTool. If not, see .
124 |
--------------------------------------------------------------------------------
/tests/testHydrodynamics.m:
--------------------------------------------------------------------------------
1 | function tests = testHydrodynamics
2 | tests = functiontests(localfunctions);
3 | end
4 |
5 | function testNegativeRadDamping(testCase)
6 | % this case is known to produce radiation values in the diagonal terms less
7 | % than zero
8 |
9 | import matlab.unittest.fixtures.TemporaryFolderFixture
10 |
11 | tempFixture = testCase.applyFixture( ...
12 | TemporaryFolderFixture( ...
13 | 'PreservingOnFailure', true, ...
14 | 'WithSuffix', 'testNegativeRadDampingKnownBad'));
15 |
16 | w = [0.5:0.5:5.5];
17 | rf = [0, 5, 5, 0];
18 | rs = [0, 7.5, 7.5, 0];
19 | zf = [0, 0, -1.1250, -1.1250];
20 | zs = [-42, -42, -43, -43];
21 |
22 | % Mesh
23 | ntheta = 20;
24 | nfobj = 200;
25 | zG = 0;
26 |
27 | meshes = WecOptTool.mesh("AxiMesh", ...
28 | tempFixture.Folder, ...
29 | rf, ...
30 | zf, ...
31 | ntheta, ...
32 | nfobj, ...
33 | zG, ...
34 | 1);
35 | meshes(2) = WecOptTool.mesh("AxiMesh", ...
36 | tempFixture.Folder, ...
37 | rs, ...
38 | zs, ...
39 | ntheta, ...
40 | nfobj, ...
41 | zG, ...
42 | 2);
43 |
44 | hydro = WecOptTool.solver("NEMOH", tempFixture.Folder, meshes, w);
45 |
46 | data = struct();
47 | data = WecOptTool.vendor.WEC_Sim.Read_NEMOH(data, ...
48 | hydro.runDirectory);
49 |
50 | rawBdiag = cell2mat(arrayfun(@(x) diag(data.B(:,:,x)), ...
51 | 1:size(data.B,3), ...
52 | 'UniformOutput', false));
53 |
54 | hydroBdiag = cell2mat(arrayfun(@(x) diag(hydro.B(:,:,x)), ...
55 | 1:size(data.B,3), ...
56 | 'UniformOutput', false));
57 |
58 | verifyTrue(testCase, any(any(rawBdiag < 0)));
59 | verifyGreaterThanOrEqual(testCase, hydroBdiag, 0);
60 |
61 | end
62 |
63 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
64 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
65 | % U.S. Government retains certain rights in this software.
66 | %
67 | % This file is part of WecOptTool.
68 | %
69 | % WecOptTool is free software: you can redistribute it and/or modify
70 | % it under the terms of the GNU General Public License as published by
71 | % the Free Software Foundation, either version 3 of the License, or
72 | % (at your option) any later version.
73 | %
74 | % WecOptTool is distributed in the hope that it will be useful,
75 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
76 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
77 | % GNU General Public License for more details.
78 | %
79 | % You should have received a copy of the GNU General Public License
80 | % along with WecOptTool. If not, see .
81 | %
82 |
--------------------------------------------------------------------------------
/tests/validation/mustBeEqualLengthTest.m:
--------------------------------------------------------------------------------
1 | function tests = mustBeEqualLengthTest()
2 | tests = functiontests(localfunctions);
3 | end
4 |
5 | function test_mustBeEqualLength_scalar(testCase)
6 | x=1.0;
7 | y=2.0;
8 | verifyWarningFree(testCase, ...
9 | @() WecOptTool.validation.mustBeEqualLength(x,y))
10 | end
11 |
12 | function test_mustBeEqualLength_array(testCase)
13 | x=ones(1,5);
14 | y=zeros(1,5);
15 | verifyWarningFree(testCase, ...
16 | @() WecOptTool.validation.mustBeEqualLength(x,y))
17 | end
18 |
19 | function test_mustBeEqualLength_mixed(testCase)
20 | x = WecOptTool.SeaState.example8Spectra();
21 | y = zeros(length(x),1);
22 | verifyWarningFree(testCase, ...
23 | @() WecOptTool.validation.mustBeEqualLength(x,y))
24 | end
25 |
26 | function test_mustBeEqualLength_error(testCase)
27 | x=1.0;
28 | y=[2, 3];
29 | eID = 'WecOptTool:Validation:NotEqualLength';
30 | verifyError(testCase, ...
31 | @() WecOptTool.validation.mustBeEqualLength(x,y), ...
32 | eID)
33 | end
34 |
35 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
36 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
37 | % U.S. Government retains certain rights in this software.
38 | %
39 | % This file is part of WecOptTool.
40 | %
41 | % WecOptTool is free software: you can redistribute it and/or modify
42 | % it under the terms of the GNU General Public License as published by
43 | % the Free Software Foundation, either version 3 of the License, or
44 | % (at your option) any later version.
45 | %
46 | % WecOptTool is distributed in the hope that it will be useful,
47 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
48 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
49 | % GNU General Public License for more details.
50 | %
51 | % You should have received a copy of the GNU General Public License
52 | % along with WecOptTool. If not, see .
53 |
--------------------------------------------------------------------------------
/tests/validation/mustBeFunctionHandleTest.m:
--------------------------------------------------------------------------------
1 | function tests = mustBeFunctionHandleTest()
2 | tests = functiontests(localfunctions);
3 | end
4 |
5 | function testIsFunctionHandle(~)
6 | a = @(x) x^2;
7 | WecOptTool.validation.mustBeFunctionHandle(a)
8 | end
9 |
10 | function testIsNotFunctionHandle(testCase)
11 | a = 1;
12 | eID = 'WecOptTool:Validation:NotFunctionHandle';
13 | verifyError(testCase, ...
14 | @() WecOptTool.validation.mustBeFunctionHandle(a), ...
15 | eID)
16 | end
17 |
18 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
19 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
20 | % U.S. Government retains certain rights in this software.
21 | %
22 | % This file is part of WecOptTool.
23 | %
24 | % WecOptTool is free software: you can redistribute it and/or modify
25 | % it under the terms of the GNU General Public License as published by
26 | % the Free Software Foundation, either version 3 of the License, or
27 | % (at your option) any later version.
28 | %
29 | % WecOptTool is distributed in the hope that it will be useful,
30 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
31 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 | % GNU General Public License for more details.
33 | %
34 | % You should have received a copy of the GNU General Public License
35 | % along with WecOptTool. If not, see .
36 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+base/Mesher.m:
--------------------------------------------------------------------------------
1 | classdef (Abstract) Mesher < WecOptTool.base.TempFolder
2 | % Abstract class for creating new mesher classes
3 | %
4 | % A single method should be implemented, called ``makeMesh`` that
5 | % creates a mesh using any particular external tool
6 | %
7 | % --
8 | %
9 | % See also WecOptTool.mesh
10 | %
11 | % --
12 |
13 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
14 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
15 | % U.S. Government retains certain rights in this software.
16 | %
17 | % This file is part of WecOptTool.
18 | %
19 | % WecOptTool is free software: you can redistribute it and/or
20 | % modify it under the terms of the GNU General Public License as
21 | % published by the Free Software Foundation, either version 3 of
22 | % the License, or (at your option) any later version.
23 | %
24 | % WecOptTool is distributed in the hope that it will be useful,
25 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
26 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 | % GNU General Public License for more details.
28 | %
29 | % You should have received a copy of the GNU General Public
30 | % License along with WecOptTool. If not, see
31 | % .
32 |
33 | methods (Abstract)
34 | mesh = makeMesh(obj, varagin)
35 | end
36 |
37 | end
38 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+base/NEMOH.m:
--------------------------------------------------------------------------------
1 | classdef NEMOH < handle
2 | % Base class containing NEMOH helpers
3 | %
4 | % --
5 | %
6 | % NEMOH Methods:
7 | % isNemohInPath - Determine if the NEMOH executables can be found.
8 | %
9 | % See also WecOptTool.mesh.AxiMesh, WecOptTool.solver.NEMOH
10 | %
11 | % --
12 |
13 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
14 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
15 | % U.S. Government retains certain rights in this software.
16 | %
17 | % This file is part of WecOptTool.
18 | %
19 | % WecOptTool is free software: you can redistribute it and/or
20 | % modify it under the terms of the GNU General Public License as
21 | % published by the Free Software Foundation, either version 3 of
22 | % the License, or (at your option) any later version.
23 | %
24 | % WecOptTool is distributed in the hope that it will be useful,
25 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
26 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 | % GNU General Public License for more details.
28 | %
29 | % You should have received a copy of the GNU General Public
30 | % License along with WecOptTool. If not, see
31 | % .
32 |
33 | methods (Static)
34 |
35 | function inpath = isNemohInPath()
36 | % Determine if the NEMOH executables can be found.
37 | %
38 | % Returns:
39 | % logical: true if executables found, otherwise false.
40 | %
41 |
42 | startdir = pwd;
43 | inpath = 1;
44 |
45 | try
46 | nemohPath = WecOptTool.system.readConfig('nemohPath');
47 | catch
48 | inpath = 0;
49 | cd(startdir);
50 | return
51 | end
52 |
53 | rundir = tempname;
54 | [status, ~, message] = mkdir(rundir);
55 |
56 | if ~status || strcmp(message, 'MATLAB:MKDIR:DirectoryExists')
57 | errStr = "Failed to create unique folder";
58 | error('WecOptTool:AutoFolder:NoUniqueFolder', errStr)
59 | end
60 |
61 | cd(rundir);
62 |
63 | windows_exes = ["Mesh", "postProcessor", "preProcessor", "Solver"];
64 | unix_exes = ["mesh", "postProc", "preProc", "solver"];
65 |
66 | if ispc
67 |
68 | for exe = windows_exes
69 |
70 | exePath = fullfile(nemohPath, exe);
71 | [status, result] = system(exePath);
72 |
73 | if ~(status == 0 || contains(result, 'ID.dat'))
74 | inpath = 0;
75 | cd(startdir);
76 | return
77 | end
78 |
79 | end
80 |
81 | else
82 |
83 | for exe = unix_exes
84 |
85 | exePath = fullfile(nemohPath, exe);
86 | [status, result] = system(exePath);
87 |
88 | if ~(status == 0 || contains(result, 'ID.dat'))
89 | inpath = 0;
90 | cd(startdir);
91 | return
92 | end
93 |
94 | end
95 |
96 | end
97 |
98 | cd(startdir);
99 | WecOptTool.system.rmdirRetry(rundir);
100 |
101 | end
102 |
103 | end
104 |
105 | end
106 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+base/Solver.m:
--------------------------------------------------------------------------------
1 | classdef (Abstract) Solver < WecOptTool.base.TempFolder
2 | % Abstract class for creating new solver classes
3 | %
4 | % A single method should be implemented, called ``getHydro`` that
5 | % solves the hydrodynamics for a given mesh using any particular
6 | % external tool
7 | %
8 | % --
9 | %
10 | % See also WecOptTool.mesh
11 | %
12 | % --
13 |
14 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
15 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
16 | % U.S. Government retains certain rights in this software.
17 | %
18 | % This file is part of WecOptTool.
19 | %
20 | % WecOptTool is free software: you can redistribute it and/or
21 | % modify it under the terms of the GNU General Public License as
22 | % published by the Free Software Foundation, either version 3 of
23 | % the License, or (at your option) any later version.
24 | %
25 | % WecOptTool is distributed in the hope that it will be useful,
26 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
27 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 | % GNU General Public License for more details.
29 | %
30 | % You should have received a copy of the GNU General Public
31 | % License along with WecOptTool. If not, see
32 | % .
33 |
34 | methods (Abstract)
35 | hydro = getHydro(obj, meshes, varagin)
36 | end
37 |
38 | end
39 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+base/TempFolder.m:
--------------------------------------------------------------------------------
1 | classdef TempFolder < handle
2 | % Superclass for classes requiring temporary storage
3 | %
4 | % Arguments:
5 | % base (string, optional):
6 | % Parent for temporary folder, default is tempdir
7 | %
8 | % Attributes:
9 | % path (string): path to temporary folder
10 | %
11 |
12 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
13 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
14 | % U.S. Government retains certain rights in this software.
15 | %
16 | % This file is part of WecOptTool.
17 | %
18 | % WecOptTool is free software: you can redistribute it and/or
19 | % modify it under the terms of the GNU General Public License as
20 | % published by the Free Software Foundation, either version 3 of
21 | % the License, or (at your option) any later version.
22 | %
23 | % WecOptTool is distributed in the hope that it will be useful,
24 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
25 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 | % GNU General Public License for more details.
27 | %
28 | % You should have received a copy of the GNU General Public
29 | % License along with WecOptTool. If not, see
30 | % .
31 | properties
32 | path
33 | end
34 |
35 | methods
36 |
37 | function obj = TempFolder(base)
38 |
39 | arguments
40 | base string = "";
41 | end
42 |
43 | if (base == "")
44 | obj.path = tempname;
45 | else
46 | obj.path = tempname(base);
47 | end
48 |
49 | obj.mkdirSafe(obj.path);
50 |
51 | end
52 |
53 | end
54 |
55 | methods (Static, Access=protected)
56 |
57 | function mkdirSafe(path)
58 |
59 | [status, ~, message] = mkdir(path);
60 |
61 | if ~status || strcmp(message, 'MATLAB:MKDIR:DirectoryExists')
62 | errStr = "Failed to create unique folder";
63 | error('WecOptTool:TempFolder:NoUniqueFolder', errStr)
64 | end
65 |
66 | end
67 |
68 | end
69 |
70 | end
71 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+geometry/existingNEMOH.m:
--------------------------------------------------------------------------------
1 | function hydro = existingNEMOH(nemohFolder)
2 | % A predefined geometry callback for reading an existing NEMOH
3 | % solution.
4 | %
5 | % Arguments:
6 | % nemohFolder (string):
7 | % Path to the folder containing existing NEMOH output files
8 | %
9 | % Returns:
10 | % :mat:class:`+WecOptTool.Hydrodynamics`: Hydrodynamics object
11 | %
12 | % --
13 | % See also WecOptTool.Hydrodynamics
14 | % --
15 |
16 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
17 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
18 | % U.S. Government retains certain rights in this software.
19 | %
20 | % This file is part of WecOptTool.
21 | %
22 | % WecOptTool is free software: you can redistribute it and/or
23 | % modify it under the terms of the GNU General Public License as
24 | % published by the Free Software Foundation, either version 3 of
25 | % the License, or (at your option) any later version.
26 | %
27 | % WecOptTool is distributed in the hope that it will be useful,
28 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
29 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 | % GNU General Public License for more details.
31 | %
32 | % You should have received a copy of the GNU General Public
33 | % License along with WecOptTool. If not, see
34 | % .
35 |
36 | data = struct();
37 | data = WecOptTool.vendor.WEC_Sim.Read_NEMOH(data, ...
38 | nemohFolder);
39 | hydro = WecOptTool.Hydrodynamics(data, ...
40 | "solverName", "NEMOH", ...
41 | "runDirectory", nemohFolder);
42 |
43 | end
44 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+math/bisection.m:
--------------------------------------------------------------------------------
1 | function c = bisection(f, a, b, options)
2 | % Bisection method
3 | %
4 | % Args:
5 | % f (double): real valued function
6 | % a (double): search space lower boundary
7 | % b (double): search space upper boundary
8 | % tol (optional, double): solution tolerance, default = 1e-10
9 | % nmax (optional, int): maximum number of operations, default = 1e4
10 | %
11 | % Returns:
12 | % double: root of f
13 | %
14 | % Note:
15 | % The given interval boundaries must satisfy f(a) * f(b) <= 0
16 | %
17 |
18 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
19 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
20 | % U.S. Government retains certain rights in this software.
21 | %
22 | % This file is part of WecOptTool.
23 | %
24 | % WecOptTool is free software: you can redistribute it and/or
25 | % modify it under the terms of the GNU General Public License as
26 | % published by the Free Software Foundation, either version 3 of
27 | % the License, or (at your option) any later version.
28 | %
29 | % WecOptTool is distributed in the hope that it will be useful,
30 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
31 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 | % GNU General Public License for more details.
33 | %
34 | % You should have received a copy of the GNU General Public
35 | % License along with WecOptTool. If not, see
36 | % .
37 |
38 | arguments
39 | f {WecOptTool.validation.mustBeFunctionHandle};
40 | a {mustBeNumeric, mustBeFinite};
41 | b {mustBeNumeric, mustBeFinite, mustBeGreaterThan(b, a)};
42 | options.tol {mustBeNumeric, ...
43 | mustBePositive, ...
44 | mustBeFinite, ...
45 | mustBeNonzero} = 1e-10;
46 | options.nmax {mustBeInteger, ...
47 | mustBePositive, ...
48 | mustBeFinite, ...
49 | mustBeNonzero} = 1e4;
50 | end
51 |
52 | if f(a) * f(b) > 0
53 | eID = "WecOptTool:bisection:badInterval";
54 | error(eID, "Incorrect initial interval [a, b]")
55 | end
56 |
57 | n = 1;
58 |
59 | while n < options.nmax
60 |
61 | c = (a + b) / 2;
62 |
63 | if abs(f(c)) < options.tol
64 | return
65 | elseif (b - a) / 2 < eps
66 | eID = "WecOptTool:bisection:searchSpaceClosed";
67 | error(eID, 'Search space closed before finding a solution')
68 | end
69 |
70 | n = n + 1;
71 |
72 | if sign(f(c)) == sign(f(a))
73 | a = c;
74 | else
75 | b = c;
76 | end
77 |
78 | end
79 |
80 | eID = "WecOptTool:bisection:tooManyIterations";
81 | error(eID, 'Number of iterations exceeded')
82 |
83 | end
84 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+math/isClose.m:
--------------------------------------------------------------------------------
1 | function result = isClose(a, b, varargin)
2 | % Determine if two values are numerically close (but perhaps not
3 | % exactly equal).
4 | %
5 | % Args:
6 | % a (double): first value to compare
7 | % b (double): second value to compare
8 | % rtol (double, optional): relative tolerence, default = 1e-05
9 | % atol (double, optional): absolute tolerance, default = 1e-08
10 | %
11 | % Returns:
12 | % logical: true if a is within given tolerances of b
13 | %
14 | % Note:
15 | % Derived from the similar named `numpy routine
16 | % `_
17 | %
18 |
19 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
20 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
21 | % U.S. Government retains certain rights in this software.
22 | %
23 | % This file is part of WecOptTool.
24 | %
25 | % WecOptTool is free software: you can redistribute it and/or
26 | % modify it under the terms of the GNU General Public License as
27 | % published by the Free Software Foundation, either version 3 of
28 | % the License, or (at your option) any later version.
29 | %
30 | % WecOptTool is distributed in the hope that it will be useful,
31 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
32 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 | % GNU General Public License for more details.
34 | %
35 | % You should have received a copy of the GNU General Public
36 | % License along with WecOptTool. If not, see
37 | % .
38 | %
39 | % Copyright (C) 2005-2020, NumPy Developers.
40 | % All rights reserved.
41 | %
42 | % Redistribution and use in source and binary forms, with or without
43 | % modification, are permitted provided that the following conditions
44 | % are met:
45 | %
46 | % * Redistributions of source code must retain the above copyright
47 | % notice, this list of conditions and the following disclaimer.
48 | %
49 | % * Redistributions in binary form must reproduce the above copyright
50 | % notice, this list of conditions and the following disclaimer in the
51 | % documentation and/or other materials provided with the distribution.
52 | %
53 | % * Neither the name of the NumPy Developers nor the names of any
54 | % contributors may be used to endorse or promote products derived from
55 | % this software without specific prior written permission.
56 | %
57 | % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
58 | % "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
59 | % LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
60 | % FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
61 | % COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
62 | % INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
63 | % BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64 | % LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
65 | % CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 | % LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
67 | % ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
68 | % POSSIBILITY OF SUCH DAMAGE.
69 |
70 | defaultAtol = 1e-08;
71 | defaultRtol = 1e-05;
72 |
73 | p = inputParser;
74 |
75 | addParameter(p, 'rtol', defaultRtol);
76 | addParameter(p, 'atol', defaultAtol);
77 | parse(p, varargin{:});
78 |
79 | result = abs(a - b) <= (p.Results.atol + p.Results.rtol * abs(b));
80 |
81 | end
82 |
83 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+plot/plotMesh.m:
--------------------------------------------------------------------------------
1 | function plotMesh(meshses, newFig)
2 | % Plot the given meshes on a single 3D axis.
3 | %
4 | % Arguments:
5 | % meshses (struct):
6 | % Struct array containing mesh description with fields as
7 | % described below
8 | % newFig (logical):
9 | % If true a new figure is created
10 | %
11 | % The meshes struct must contain the following fields:
12 | %
13 | % ============ ================ ======================================
14 | % **Variable** **Format** **Description**
15 | % bodyNum int32 body number
16 | % name char array name of the mesh
17 | % nodes Nx4 table table of N node positions with columns ID, x, y, z
18 | % panels Mx4 int32 array array of M panels where each row contains the 4 connected node IDs
19 | % xzSymmetric logical body is symmetric in xz plane (half mesh)
20 | % zG double z-coordinate of the bodies centre of gravity
21 | % ============ ================ ======================================
22 | %
23 |
24 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
25 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
26 | % U.S. Government retains certain rights in this software.
27 | %
28 | % This file is part of WecOptTool.
29 | %
30 | % WecOptTool is free software: you can redistribute it and/or
31 | % modify it under the terms of the GNU General Public License as
32 | % published by the Free Software Foundation, either version 3 of
33 | % the License, or (at your option) any later version.
34 | %
35 | % WecOptTool is distributed in the hope that it will be useful,
36 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
37 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 | % GNU General Public License for more details.
39 | %
40 | % You should have received a copy of the GNU General Public
41 | % License along with WecOptTool. If not, see
42 | % .
43 |
44 | arguments
45 | meshses
46 | newFig = true
47 | end
48 |
49 | if isempty(meshses)
50 | return
51 | end
52 |
53 | if newFig
54 | figure
55 | ax1 = axes;
56 | view(ax1, 3)
57 | end
58 |
59 | hold on
60 |
61 | for mesh = meshses
62 | plotSingleMesh(ax1, mesh);
63 | end
64 |
65 | xlabel("x")
66 | ylabel("y")
67 | zlabel("z")
68 |
69 | axis image
70 |
71 | hold off
72 |
73 | end
74 |
75 | function plotSingleMesh(ax, mesh)
76 |
77 | n = size(mesh.panels, 1);
78 |
79 | X = zeros(4, n);
80 | Y = zeros(4, n);
81 | Z = zeros(4, n);
82 |
83 | for i = 1:n
84 | X(:, i) = mesh.nodes(mesh.panels(i, :), :).x;
85 | Y(:, i) = mesh.nodes(mesh.panels(i, :), :).y;
86 | Z(:, i) = mesh.nodes(mesh.panels(i, :), :).z;
87 | end
88 |
89 | fill3(ax, X, Y, Z, 'r')
90 |
91 | if ~mesh.xzSymmetric
92 | return
93 | end
94 |
95 | for i = 1:n
96 | Y(:, i) = -mesh.nodes(mesh.panels(i, :), :).y;
97 | end
98 |
99 | fill3(ax, X, Y, Z, 'r')
100 |
101 | end
102 |
103 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+plot/powerPerFreq.m:
--------------------------------------------------------------------------------
1 | function powerPerFreq(input)
2 | % Plots power per frequency for a simulated device.
3 | %
4 | % Arguments:
5 | % input (struct):
6 | % A struct array with fields defined in the table below
7 | %
8 | % ============ ================ =====================================
9 | % **Variable** **Format** **Description**
10 | % w Nx1 double array N sea-state frequencie
11 | % powPerFreq Nx1 double array Power production per frequency
12 | % ============ ================ =====================================
13 | %
14 |
15 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
16 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
17 | % U.S. Government retains certain rights in this software.
18 | %
19 | % This file is part of WecOptTool.
20 | %
21 | % WecOptTool is free software: you can redistribute it and/or
22 | % modify it under the terms of the GNU General Public License as
23 | % published by the Free Software Foundation, either version 3 of
24 | % the License, or (at your option) any later version.
25 | %
26 | % WecOptTool is distributed in the hope that it will be useful,
27 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
28 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 | % GNU General Public License for more details.
30 | %
31 | % You should have received a copy of the GNU General Public
32 | % License along with WecOptTool. If not, see
33 | % .
34 |
35 | % Number of Sea-States
36 | NSS = length(input);
37 |
38 | multiSeaState = false;
39 | if NSS>1
40 | multiSeaState = true;
41 | end
42 |
43 | figure
44 |
45 | if multiSeaState
46 |
47 | hold on
48 |
49 | for i = 1 : NSS
50 |
51 | freq = input(i).w;
52 |
53 | % Trim off zero frequencies
54 | if abs(freq(1)) <= eps
55 | freq = freq(2:end);
56 | end
57 |
58 | powPerFreq = input(i).powPerFreq;
59 | plot(freq, powPerFreq,'DisplayName',int2str(i))
60 |
61 | end
62 |
63 | legend()
64 |
65 | else
66 |
67 | freq = input(1).w;
68 | powPerFreq = input(1).powPerFreq;
69 | plot(freq, powPerFreq)
70 |
71 | end
72 |
73 | xlabel('Frequency [$\omega$]','Interpreter','latex')
74 | ylabel('Power [$W]$','Interpreter','latex')
75 | grid
76 |
77 | end
78 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+solver/nemohcalbody.txt:
--------------------------------------------------------------------------------
1 | --- Body %i ------------------------------------------------------------------
2 | '%s' ! Name of mesh file
3 | %-12i %-12i ! Number of points and number of panels
4 | 6 ! Number of degrees of freedom
5 | 1 1. 0. 0. 0. 0. 0. ! Surge
6 | 1 0. 1. 0. 0. 0. 0. ! Sway
7 | 1 0. 0. 1. 0. 0. 0. ! Heave
8 | 2 1. 0. 0. 0. 0. %-9.4f ! Roll about a point
9 | 2 0. 1. 0. 0. 0. %-9.4f ! Pitch about a point
10 | 2 0. 0. 1. 0. 0. %-9.4f ! Yaw about a point
11 | 6 ! Number of resulting generalised forces
12 | 1 1. 0. 0. 0. 0. 0. ! Force in x direction
13 | 1 0. 1. 0. 0. 0. 0. ! Force in y direction
14 | 1 0. 0. 1. 0. 0. 0. ! Force in z direction
15 | 2 1. 0. 0. 0. 0. %-9.4f ! Moment force in x direction about a point
16 | 2 0. 1. 0. 0. 0. %-9.4f ! Moment force in y direction about a point
17 | 2 0. 0. 1. 0. 0. %-9.4f ! Moment force in z direction about a point
18 | 0 ! Number of lines of additional information
19 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+solver/nemohcalfooter.txt:
--------------------------------------------------------------------------------
1 | --- Load cases to be solved --------------------------------------------------
2 | %-4i %-11.4f %-11.4f ! Number of wave frequencies, Min, and Max (rad/s)
3 | 1 0. 0. ! Number of wave directions, Min and Max (degrees)
4 | --- Post processing ----------------------------------------------------------
5 | 0 0.1 10. ! IRF ! IRF calculation (0 for no calculation), time step and duration
6 | 0 ! Show pressure
7 | 0 0. 180. ! Kochin function ! Number of directions of calculation (0 for no calculations), Min and Max (degrees)
8 | 0 50 400. 400. ! Free surface elevation ! Number of points in x direction (0 for no calcutions) and y direction and dimensions of domain in x and y direction
9 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+solver/nemohcalheader.txt:
--------------------------------------------------------------------------------
1 | --- Environment --------------------------------------------------------------
2 | %-15.4f ! RHO ! KG/M**3 ! Fluid specific volume
3 | %-15.4f ! G ! M/S**2 ! Gravity
4 | 0. ! DEPTH ! M ! Water depth
5 | 0. 0. ! XEFF YEFF ! M ! Wave measurement point
6 | --- Description of floating bodies -------------------------------------------
7 | %d ! Number of bodies
8 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+system/getFolders.m:
--------------------------------------------------------------------------------
1 | function folderNames = getFolders(baseFolder, varargin)
2 | % Returns folder names found at a given folder path (excludes '.'
3 | % and '..')
4 | %
5 | % Args:
6 | % baseFolder (character vector | string scalar):
7 | % folder path used for search
8 | % varargin: name-value pair options. See below.
9 | %
10 | % The following options are supported:
11 | %
12 | % absPath (logical):
13 | % If true, the absolute path to the folders is returned. Defaults
14 | % to false.
15 | %
16 | % Returns:
17 | % cell array: Discovered folder names
18 | %
19 |
20 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
21 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
22 | % U.S. Government retains certain rights in this software.
23 | %
24 | % This file is part of WecOptTool.
25 | %
26 | % WecOptTool is free software: you can redistribute it and/or
27 | % modify it under the terms of the GNU General Public License as
28 | % published by the Free Software Foundation, either version 3 of
29 | % the License, or (at your option) any later version.
30 | %
31 | % WecOptTool is distributed in the hope that it will be useful,
32 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
33 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34 | % GNU General Public License for more details.
35 | %
36 | % You should have received a copy of the GNU General Public
37 | % License along with WecOptTool. If not, see
38 | % .
39 |
40 | p = inputParser;
41 |
42 | defaultAbsPath = false;
43 | validCharString = @(x) ischar(x) | isstring(x);
44 |
45 | addRequired(p, 'baseFolder', validCharString);
46 | addParameter(p, 'absPath', defaultAbsPath, @islogical);
47 |
48 | parse(p, baseFolder, varargin{:});
49 |
50 | validBaseFolder = p.Results.baseFolder;
51 |
52 | if ~isfolder(validBaseFolder)
53 | folderNames = {};
54 | return
55 | end
56 |
57 | d = dir(validBaseFolder);
58 | dfolders = d([d(:).isdir] == 1);
59 | dfolders = dfolders(~ismember({dfolders(:).name}, {'.', '..'}));
60 |
61 | relativeFolderNames = {dfolders(:).name};
62 |
63 | if ~p.Results.absPath
64 | folderNames = relativeFolderNames;
65 | return
66 | end
67 |
68 | folderNames = cell(1, length(relativeFolderNames));
69 |
70 | for i = 1:length(relativeFolderNames)
71 | folderNames{i} = fullfile(validBaseFolder, relativeFolderNames{i});
72 | end
73 |
74 | end
75 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+system/getSrcRootPath.m:
--------------------------------------------------------------------------------
1 | function [srcRootPath] = getSrcRootPath()
2 | % Return path to WecOptTool src code root directory
3 |
4 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
5 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
6 | % U.S. Government retains certain rights in this software.
7 | %
8 | % This file is part of WecOptTool.
9 | %
10 | % WecOptTool is free software: you can redistribute it and/or
11 | % modify it under the terms of the GNU General Public License as
12 | % published by the Free Software Foundation, either version 3 of
13 | % the License, or (at your option) any later version.
14 | %
15 | % WecOptTool is distributed in the hope that it will be useful,
16 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | % GNU General Public License for more details.
19 | %
20 | % You should have received a copy of the GNU General Public
21 | % License along with WecOptTool. If not, see
22 | % .
23 |
24 | p = mfilename('fullpath');
25 | [pDir, ~, ~] = fileparts(p);
26 | parts = strsplit(pDir, filesep);
27 | srcRootPath = fullfile(parts{1:end-3});
28 |
29 | % Linux requires a leading slash
30 | if ~ispc
31 | srcRootPath = [filesep, srcRootPath];
32 | end
33 |
34 | end
35 |
36 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+system/getUserPath.m:
--------------------------------------------------------------------------------
1 | function [WOTDataPath] = getUserPath()
2 | % Return path to WecOptTool user data directory
3 |
4 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
5 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
6 | % U.S. Government retains certain rights in this software.
7 | %
8 | % This file is part of WecOptTool.
9 | %
10 | % WecOptTool is free software: you can redistribute it and/or
11 | % modify it under the terms of the GNU General Public License as
12 | % published by the Free Software Foundation, either version 3 of
13 | % the License, or (at your option) any later version.
14 | %
15 | % WecOptTool is distributed in the hope that it will be useful,
16 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | % GNU General Public License for more details.
19 | %
20 | % You should have received a copy of the GNU General Public
21 | % License along with WecOptTool. If not, see
22 | % .
23 |
24 | if ispc
25 | appDataPath = getenv('APPDATA');
26 | WOTDataPath = fullfile(appDataPath, 'WecOptTool');
27 | else
28 | appDataPath = getenv('HOME');
29 | WOTDataPath = fullfile(appDataPath, '.wecopttool');
30 | end
31 | end
32 |
33 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+system/hasToolbox.m:
--------------------------------------------------------------------------------
1 | function [combined, licensed, installed] = hasToolbox(licenseName, ...
2 | installedName)
3 | % Check if an extension toolbox is installed
4 | %
5 | % Arguments:
6 | % licenseName (string):
7 | % the licence name (normally with underscores)
8 | % installedName (string):
9 | % the toolbox name (as given by the ver command)
10 | %
11 | % Returns:
12 | % (): outputs are:
13 | %
14 | % combined (logical): true if toolbox is licensed and installed
15 | % licensed (logical): true is toolbox is licensed
16 | % installed (logical): true is toolbox is installed
17 | %
18 |
19 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
20 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
21 | % U.S. Government retains certain rights in this software.
22 | %
23 | % This file is part of WecOptTool.
24 | %
25 | % WecOptTool is free software: you can redistribute it and/or
26 | % modify it under the terms of the GNU General Public License as
27 | % published by the Free Software Foundation, either version 3 of
28 | % the License, or (at your option) any later version.
29 | %
30 | % WecOptTool is distributed in the hope that it will be useful,
31 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
32 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 | % GNU General Public License for more details.
34 | %
35 | % You should have received a copy of the GNU General Public
36 | % License along with WecOptTool. If not, see
37 | % .
38 |
39 | licensed = logical(license('test', licenseName));
40 |
41 | installedProducts = ver;
42 | installedNames = {installedProducts(:).Name};
43 | installed = false;
44 |
45 | for name = installedNames
46 | if contains(name, installedName)
47 | installed = true;
48 | break
49 | end
50 | end
51 |
52 | combined = licensed && installed;
53 |
54 | end
55 |
56 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+system/isParallel.m:
--------------------------------------------------------------------------------
1 | function result = isParallel()
2 | % Determine if the current process is being run in parallel
3 |
4 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
5 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
6 | % U.S. Government retains certain rights in this software.
7 | %
8 | % This file is part of WecOptTool.
9 | %
10 | % WecOptTool is free software: you can redistribute it and/or
11 | % modify it under the terms of the GNU General Public License as
12 | % published by the Free Software Foundation, either version 3 of
13 | % the License, or (at your option) any later version.
14 | %
15 | % WecOptTool is distributed in the hope that it will be useful,
16 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | % GNU General Public License for more details.
19 | %
20 | % You should have received a copy of the GNU General Public
21 | % License along with WecOptTool. If not, see
22 | % .
23 |
24 | import WecOptTool.system.hasToolbox
25 |
26 | hasParallelToolbox = hasToolbox("Distrib_Computing_Toolbox", ...
27 | "Parallel Computing Toolbox");
28 |
29 | if ~hasParallelToolbox
30 | result = false;
31 | return
32 | end
33 |
34 | result = ~isempty(getCurrentTask());
35 |
36 | end
37 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+system/readConfig.m:
--------------------------------------------------------------------------------
1 | function value = readConfig(key, varargin)
2 | % Read the value for the given key in the config file
3 |
4 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
5 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
6 | % U.S. Government retains certain rights in this software.
7 | %
8 | % This file is part of WecOptTool.
9 | %
10 | % WecOptTool is free software: you can redistribute it and/or
11 | % modify it under the terms of the GNU General Public License as
12 | % published by the Free Software Foundation, either version 3 of
13 | % the License, or (at your option) any later version.
14 | %
15 | % WecOptTool is distributed in the hope that it will be useful,
16 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | % GNU General Public License for more details.
19 | %
20 | % You should have received a copy of the GNU General Public
21 | % License along with WecOptTool. If not, see
22 | % .
23 |
24 | % Default directory for config
25 | WOTDataPath = WecOptTool.system.getUserPath();
26 |
27 | p = inputParser;
28 | validText = @(x) isstring(x) || ischar(x);
29 | addRequired(p, 'key', validText);
30 | addParameter(p, 'configDir', WOTDataPath, validText);
31 | parse(p, key, varargin{:});
32 |
33 | if ~exist(p.Results.configDir, 'dir')
34 | errStr = "Config directory '" + p.Results.configDir + ...
35 | "' does not exist";
36 | errStr = strrep(errStr, '\', '\\');
37 | error('WecOptTool:readConfig:missingDirectory', errStr)
38 | end
39 |
40 | configPath = fullfile(p.Results.configDir, 'config.json');
41 |
42 | if ~exist(configPath, 'file')
43 | errStr = "Config file 'config.json' does not exist";
44 | error('WecOptTool:readConfig:missingFile', errStr)
45 | end
46 |
47 | config = jsondecode(fileread(configPath));
48 |
49 | if ~isfield(config, p.Results.key)
50 | errStr = "Config file does contain key: " + p.Results.key;
51 | error('WecOptTool:readConfig:missingKey', errStr)
52 | end
53 |
54 | value = config.(p.Results.key);
55 |
56 | end
57 |
58 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+system/rmdirRetry.m:
--------------------------------------------------------------------------------
1 | function rmdirRetry(dirPath)
2 | % Calls rmdir with 's' option in a retry loop
3 |
4 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
5 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
6 | % U.S. Government retains certain rights in this software.
7 | %
8 | % This file is part of WecOptTool.
9 | %
10 | % WecOptTool is free software: you can redistribute it and/or
11 | % modify it under the terms of the GNU General Public License as
12 | % published by the Free Software Foundation, either version 3 of
13 | % the License, or (at your option) any later version.
14 | %
15 | % WecOptTool is distributed in the hope that it will be useful,
16 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | % GNU General Public License for more details.
19 | %
20 | % You should have received a copy of the GNU General Public
21 | % License along with WecOptTool. If not, see
22 | % .
23 |
24 | maxRetries = 59;
25 | nRetries = 0;
26 |
27 | while nRetries < maxRetries
28 | try
29 | rmdir(dirPath, 's');
30 | return
31 | catch
32 | pause(1)
33 | nRetries = nRetries + 1;
34 | end
35 | end
36 |
37 | rmdir(dirPath, 's');
38 |
39 | end
40 |
41 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+system/writeConfig.m:
--------------------------------------------------------------------------------
1 | function writeConfig(key, value, varargin)
2 | % Add given key with given value to config file
3 |
4 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
5 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
6 | % U.S. Government retains certain rights in this software.
7 | %
8 | % This file is part of WecOptTool.
9 | %
10 | % WecOptTool is free software: you can redistribute it and/or
11 | % modify it under the terms of the GNU General Public License as
12 | % published by the Free Software Foundation, either version 3 of
13 | % the License, or (at your option) any later version.
14 | %
15 | % WecOptTool is distributed in the hope that it will be useful,
16 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | % GNU General Public License for more details.
19 | %
20 | % You should have received a copy of the GNU General Public
21 | % License along with WecOptTool. If not, see
22 | % .
23 |
24 | % Default directory for config
25 | WOTDataPath = WecOptTool.system.getUserPath();
26 |
27 | p = inputParser;
28 | validText = @(x) isstring(x) || ischar(x);
29 | addRequired(p, 'key', validText);
30 | addRequired(p, 'value');
31 | addParameter(p, 'configDir', WOTDataPath, validText);
32 | parse(p, key, value, varargin{:});
33 |
34 | % Check if the user data directory exists and make if necessary
35 | if ~exist(p.Results.configDir, 'dir')
36 | mkdir(p.Results.configDir)
37 | end
38 |
39 | % Check if the config file exists and read
40 | configPath = fullfile(p.Results.configDir, 'config.json');
41 |
42 | if exist(configPath, 'file')
43 | config = jsondecode(fileread(configPath));
44 | else
45 | config = struct(char(p.Results.key), p.Results.value);
46 | end
47 |
48 | if strcmp(p.Results.value, "")
49 | config = rmfield(config, p.Results.key);
50 | else
51 | config.(p.Results.key) = p.Results.value;
52 | end
53 |
54 | % Convert to JSON text and save
55 | jsonConfig = jsonencode(config);
56 | fid = fopen(configPath, 'w');
57 | fprintf(fid, '%s', jsonConfig);
58 | fclose(fid);
59 |
60 | end
61 |
62 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+validation/mustBeEqualLength.m:
--------------------------------------------------------------------------------
1 | function mustBeEqualLength(x, y)
2 | % Returns an error if x and y are not of equal lengths
3 |
4 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
5 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
6 | % U.S. Government retains certain rights in this software.
7 | %
8 | % This file is part of WecOptTool.
9 | %
10 | % WecOptTool is free software: you can redistribute it and/or
11 | % modify it under the terms of the GNU General Public License as
12 | % published by the Free Software Foundation, either version 3 of
13 | % the License, or (at your option) any later version.
14 | %
15 | % WecOptTool is distributed in the hope that it will be useful,
16 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | % GNU General Public License for more details.
19 | %
20 | % You should have received a copy of the GNU General Public
21 | % License along with WecOptTool. If not, see
22 | % .
23 |
24 | msg = 'Inputs must be of equal length';
25 | ID = 'WecOptTool:Validation:NotEqualLength';
26 | assert(length(x)==length(y),ID,msg);
27 |
28 | end
29 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+validation/mustBeFunctionHandle.m:
--------------------------------------------------------------------------------
1 | function mustBeFunctionHandle(input)
2 | % Returns an error if input is not a function handle
3 |
4 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
5 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
6 | % U.S. Government retains certain rights in this software.
7 | %
8 | % This file is part of WecOptTool.
9 | %
10 | % WecOptTool is free software: you can redistribute it and/or
11 | % modify it under the terms of the GNU General Public License as
12 | % published by the Free Software Foundation, either version 3 of
13 | % the License, or (at your option) any later version.
14 | %
15 | % WecOptTool is distributed in the hope that it will be useful,
16 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | % GNU General Public License for more details.
19 | %
20 | % You should have received a copy of the GNU General Public
21 | % License along with WecOptTool. If not, see
22 | % .
23 |
24 | if ~isa(input, 'function_handle')
25 | error('WecOptTool:Validation:NotFunctionHandle', ...
26 | 'Input must be a function handle')
27 | end
28 |
29 | end
30 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+vendor/+WEC_Sim/NOTICE:
--------------------------------------------------------------------------------
1 | WEC-Sim (Wave Energy Converter SIMulator)
2 | Copyright 2014 the National Renewable Energy Laboratory and Sandia Corporation
3 |
4 | Sandia and NREL Developers:
5 | Yi-Hsiang Yu (National Renewable Energy Laboratory)
6 | Kelley Ruehl (Sandia National Laboratories)
7 | Michael Lawson (National Renewable Energy Laboratory)
8 | Carlos Michelen (Sandia National Laboratories)
9 | Jennifer Van Rij (National Renewable Energy Laboratory)
10 | Nathan Tom (National Renewable Energy Laboratory)
11 |
12 | See list of external contributors on the WEC-Sim webite.
13 |
14 | Several libraries developed by external parties are used by WEC-Sim. License information for these libraries is as follows:
15 | source/functions/import_stl_fast/import_stl_fast.m - see license in import_stl_fast.m
16 |
17 | Modifications March 2020
18 | National Technology & Engineering Solutions of Sandia, LLC (NTESS)
19 | --------------------------------------------------------------------------
20 | + Read_NEMOH.m and Normalize.m packaged within WecOptTool
21 | + Minor modification was made to Read_NEMOH.m to access package namespace
22 | + Remove waitbar call in Read_NEMOH.m
23 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/+vendor/+WEC_Sim/Normalize.m:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SNL-WaterPower/WecOptTool-MATLAB/0a9faa189f8570444fac5ebe0da2a9fcd94958eb/toolbox/+WecOptTool/+vendor/+WEC_Sim/Normalize.m
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/AutoFolder.m:
--------------------------------------------------------------------------------
1 | classdef AutoFolder < WecOptTool.base.TempFolder
2 | % Class that creates unique temporary folders, which are deleted
3 | % upon object destruction.
4 | %
5 | % Attributes:
6 | % path (string): path to unique folder for storage
7 | %
8 | % --
9 | %
10 | % AutoFolder Methods:
11 | % stashVar - store a variable for recovery later
12 | % recoverVar - retrieve stashed variable
13 | % archive - Save the folder and contents
14 | %
15 | % --
16 |
17 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
18 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
19 | % U.S. Government retains certain rights in this software.
20 | %
21 | % This file is part of WecOptTool.
22 | %
23 | % WecOptTool is free software: you can redistribute it and/or
24 | % modify it under the terms of the GNU General Public License as
25 | % published by the Free Software Foundation, either version 3 of
26 | % the License, or (at your option) any later version.
27 | %
28 | % WecOptTool is distributed in the hope that it will be useful,
29 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
30 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 | % GNU General Public License for more details.
32 | %
33 | % You should have received a copy of the GNU General Public
34 | % License along with WecOptTool. If not, see
35 | % .
36 |
37 | properties (Access = protected)
38 | varsPath
39 | end
40 |
41 | methods
42 |
43 | function obj = AutoFolder()
44 |
45 | obj = obj@WecOptTool.base.TempFolder();
46 | obj.varsPath = tempname;
47 | obj.mkdirSafe(obj.varsPath);
48 |
49 | end
50 |
51 | function stashVar(obj, variable)
52 | % Store a variable for recovery later.
53 | %
54 | % Arguments:
55 | % variable: variable to store
56 | %
57 | % Note:
58 | % A new stash is created every time a variable is stored,
59 | % so multiple values may be returned by
60 | % :mat:meth:`.recoverVar`
61 | %
62 |
63 | arguments
64 | obj
65 | variable {mustBeNonempty}
66 | end
67 |
68 | resultsFolder = tempname(obj.varsPath);
69 | mkdir(resultsFolder);
70 | etcPath = fullfile(resultsFolder, inputname(2) + ".mat");
71 | save(etcPath, "variable");
72 |
73 | end
74 |
75 | function result = recoverVar(obj, variableName)
76 | % Recover stashed variable
77 | %
78 | % Arguments:
79 | % variableName (string): variable to recover
80 | %
81 | % Returns:
82 | % cell array:
83 | % cell array containing all stored version of given
84 | % variable name
85 | %
86 |
87 | arguments
88 | obj
89 | variableName string {mustBeNonempty}
90 | end
91 |
92 | pDirs = WecOptTool.system.getFolders(obj.varsPath, ...
93 | "absPath", true);
94 | nDirs = length(pDirs);
95 | result = {};
96 |
97 | for i = 1:nDirs
98 | dir = pDirs{i};
99 | fileName = fullfile(dir, variableName + ".mat");
100 | if isfile(fileName)
101 | result = [result, {load(fileName).variable}];
102 | end
103 | end
104 |
105 | end
106 |
107 | function archive(obj, targetPath)
108 | % Save the folder and contents
109 | %
110 | % Args:
111 | % targetPath (string): Path to destination folder
112 | %
113 | % Note:
114 | % If there are no files to copy this function will not
115 | % make the destination folder
116 | %
117 |
118 | arguments
119 | obj
120 | targetPath string
121 | end
122 |
123 | if length(dir(obj.path)) == 2
124 | return
125 | end
126 |
127 | copyfile(obj.path, targetPath);
128 |
129 | end
130 |
131 | end
132 |
133 | methods (Access = protected)
134 |
135 | function obj = rmFolders(obj)
136 | if isfolder(obj.path)
137 | WecOptTool.system.rmdirRetry(obj.path);
138 | end
139 | if isfolder(obj.varsPath)
140 | WecOptTool.system.rmdirRetry(obj.varsPath);
141 | end
142 | end
143 |
144 | function delete(obj)
145 | if ~WecOptTool.system.isParallel()
146 | obj.rmFolders();
147 | end
148 | end
149 |
150 | end
151 |
152 | end
153 |
154 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/Hydrodynamics.m:
--------------------------------------------------------------------------------
1 | classdef Hydrodynamics
2 | % Data type for storage of solver hydrodynamics output.
3 | %
4 | % This data type defines a set of parameters that are common to the
5 | % description of wave device hydrodynamics parameters, such as in
6 | % `WEC-Sim's BEMIO `_.
7 | %
8 | % The following parameters must be provided within the input struct,
9 | % which map directly to class attributes (see below):
10 | %
11 | % * ex
12 | % * g
13 | % * rho
14 | % * w
15 | % * A
16 | % * Ainf
17 | % * B
18 | % * C
19 | % * Nb
20 | % * Nh
21 | % * Nf
22 | % * Vo
23 | %
24 | % Note:
25 | % Any negative radiation damping coefficients detected for
26 | % individual bodies will be set to zero, automatically.
27 | %
28 | % Arguments:
29 | % hydroData (struct):
30 | % A struct containing the required fields
31 | % options: name-value pair options. See below.
32 | %
33 | % The following options are supported:
34 | %
35 | % solverName (string):
36 | % The name of the solver used to generate the data
37 | % runDirectory (string):
38 | % Path to the directory containing the solver's output files
39 | %
40 | % Attributes:
41 | % base (struct):
42 | % copy of the input struct
43 | % ex (array of double):
44 | % complex excitation force or torque ([6*Nb,Nh,Nf])
45 | % g (double):
46 | % gravitational acceleration
47 | % rho (double):
48 | % water density
49 | % w (array of double):
50 | % simulated wave frequencies ([1,Nf])
51 | % A (array of double):
52 | % radiation added mass ([6*Nb,6*Nb,Nf])
53 | % Ainf (array of double):
54 | % infinite frequency added mass ([6*Nb,6*Nb])
55 | % B (array of double):
56 | % radiation wave damping ([6*Nb,6*Nb,Nf])
57 | % C (array of double):
58 | % hydrostatic restoring stiffness ([6,6,Nb])
59 | % Nb (int32):
60 | % number of bodies
61 | % Nh (int32):
62 | % number of wave headings
63 | % Nf (int32):
64 | % number of wave frequencies
65 | % Vo (array of double):
66 | % displaced volume ([1,Nb])
67 | % solverName (string):
68 | % name of solver used to generate hydrodyamic parameters.
69 | % Default is "Unknown".
70 | % runDirectory (string):
71 | % path to folder containing output files of the hydrodynamic
72 | % solver. Defaults to "".
73 | %
74 | % --
75 | %
76 | % Hydrodynamics Properties:
77 | % S - spectral density
78 | % base - copy of the input struct
79 | % ex - complex component of excitation force or torque ([6*Nb,Nh,Nf])
80 | % g - gravitational acceleration
81 | % rho - water density
82 | % w - simulated wave frequencies ([1,Nf])
83 | % A - radiation added mass ([6*Nb,6*Nb,Nf])
84 | % Ainf - infinite frequency added mass ([6*Nb,6*Nb])
85 | % B - radiation wave damping ([6*Nb,6*Nb,Nf])
86 | % C - hydrostatic restoring stiffness ([6,6,Nb])
87 | % Nb - number of bodies
88 | % Nh - number of wave headings
89 | % Nf - number of wave frequencies
90 | % Vo - displaced volume ([1,Nb])
91 | % solverName - name of solver used to generate hydrodyamic parameters. Default is "Unknown".
92 | % runDirectory - Path to folder containing output files of the hydrodynamic solver. Defaults to "".
93 | %
94 | % --
95 |
96 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
97 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
98 | % U.S. Government retains certain rights in this software.
99 | %
100 | % This file is part of WecOptTool.
101 | %
102 | % WecOptTool is free software: you can redistribute it and/or
103 | % modify it under the terms of the GNU General Public License as
104 | % published by the Free Software Foundation, either version 3 of
105 | % the License, or (at your option) any later version.
106 | %
107 | % WecOptTool is distributed in the hope that it will be useful,
108 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
109 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
110 | % GNU General Public License for more details.
111 | %
112 | % You should have received a copy of the GNU General Public
113 | % License along with WecOptTool. If not, see
114 | % .
115 |
116 | properties
117 | base
118 | ex
119 | g
120 | rho
121 | w
122 | A
123 | Ainf
124 | B
125 | C
126 | Nb
127 | Nh
128 | Nf
129 | Vo
130 | solverName
131 | runDirectory
132 | end
133 |
134 | methods
135 |
136 | function obj = Hydrodynamics(hydroData, options)
137 |
138 | arguments
139 | hydroData
140 | options.solverName = "Unknown"
141 | options.runDirectory = ""
142 | end
143 |
144 | obj.base = hydroData;
145 | obj.ex = complex(hydroData.ex_re, hydroData.ex_im);
146 | obj.g = hydroData.g;
147 | obj.rho = hydroData.rho;
148 | obj.w = hydroData.w;
149 | obj.A = hydroData.A;
150 | obj.Ainf = hydroData.Ainf;
151 | obj.B = obj.checkDamping(hydroData.B);
152 | obj.C = hydroData.C;
153 | obj.Nb = hydroData.Nb;
154 | obj.Nh = hydroData.Nh;
155 | obj.Nf = hydroData.Nf;
156 | obj.Vo = hydroData.Vo;
157 | obj.solverName = options.solverName;
158 | obj.runDirectory = options.runDirectory;
159 |
160 | end
161 |
162 | end
163 |
164 | methods (Static, Access=private)
165 |
166 | function newB = checkDamping(B)
167 | % Checks that diagonal radiation damping always positive
168 |
169 | newB = B;
170 |
171 | for ii = 1:size(B, 1)
172 | Bdiag = squeeze(B(ii,ii,:));
173 | Bdiag(Bdiag < 0) = 0;
174 | newB(ii,ii,:) = Bdiag;
175 | end
176 |
177 | end
178 |
179 | end
180 |
181 | end
182 |
183 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/data/8spectra.mat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SNL-WaterPower/WecOptTool-MATLAB/0a9faa189f8570444fac5ebe0da2a9fcd94958eb/toolbox/+WecOptTool/data/8spectra.mat
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/data/spectrum.mat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SNL-WaterPower/WecOptTool-MATLAB/0a9faa189f8570444fac5ebe0da2a9fcd94958eb/toolbox/+WecOptTool/data/spectrum.mat
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/mesh.m:
--------------------------------------------------------------------------------
1 | function mesh = mesh(meshName, folder, varargin)
2 | % Make a mesh using shortcuts to the ``makeMesh`` method of the
3 | % defined Mesher concrete classes in the :mat:mod:`+WecOptTool.+mesh`
4 | % package.
5 | %
6 | % Arguments:
7 | % meshName (string):
8 | % Meshing routine to use. Current options are:
9 | %
10 | % * AxiMesh (:mat:class:`+WecOptTool.+mesh.AxiMesh`)
11 | %
12 | % folder (string):
13 | % Path to the folder to store output files
14 | % varargin:
15 | % Arguments to pass to the meshing routine. See the
16 | % ``makeMesh`` method of the chosen mesher class for details.
17 | %
18 | % Returns:
19 | % struct:
20 | % A mesh description with fields as described below
21 | %
22 | % ============ ================ ======================================
23 | % **Variable** **Format** **Description**
24 | % bodyNum int32 body number
25 | % name char array name of the mesh
26 | % nodes Nx4 table table of N node positions with columns ID, x, y, z
27 | % panels Mx4 int32 array array of M panels where each row contains the 4 connected node IDs
28 | % xzSymmetric logical body is symmetric in xz plane (half mesh)
29 | % zG double z-coordinate of the bodies centre of gravity
30 | % ============ ================ ======================================
31 | %
32 | % --
33 | %
34 | % See also WecOptTool.mesh.AxiMesh
35 | %
36 | % --
37 |
38 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
39 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
40 | % U.S. Government retains certain rights in this software.
41 | %
42 | % This file is part of WecOptTool.
43 | %
44 | % WecOptTool is free software: you can redistribute it and/or
45 | % modify it under the terms of the GNU General Public License as
46 | % published by the Free Software Foundation, either version 3 of
47 | % the License, or (at your option) any later version.
48 | %
49 | % WecOptTool is distributed in the hope that it will be useful,
50 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
51 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52 | % GNU General Public License for more details.
53 | %
54 | % You should have received a copy of the GNU General Public
55 | % License along with WecOptTool. If not, see
56 | % .
57 |
58 | fullQName = "WecOptTool.mesh." + meshName;
59 | meshHandle = str2func(fullQName);
60 | mesher = meshHandle(folder);
61 | mesh = mesher.makeMesh(varargin{:});
62 |
63 | end
64 |
--------------------------------------------------------------------------------
/toolbox/+WecOptTool/solver.m:
--------------------------------------------------------------------------------
1 | function hydro = solver(solverName, folder, varargin)
2 | % Solve a mesh using shortcuts to the ``getHydro`` method of the
3 | % defined Solver concrete classes in the :mat:mod:`+WecOptTool.+solver`
4 | % package.
5 | %
6 | % Arguments:
7 | % solverName (string):
8 | % Solver routine to use. Current options are:
9 | %
10 | % * NEMOH (:mat:class:`+WecOptTool.+solver.NEMOH`)
11 | %
12 | % folder (string):
13 | % Path to the folder to store output files
14 | % varargin:
15 | % Arguments to pass to the solver routine. See the ``getHydro``
16 | % method of the chosen solver class for details.
17 | %
18 | % Returns:
19 | % struct: Output struct from chosen solver
20 | %
21 | % --
22 | %
23 | % See also WecOptTool.solver.NEMOH
24 | %
25 | % --
26 |
27 | % Copyright 2020 National Technology & Engineering Solutions of Sandia,
28 | % LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
29 | % U.S. Government retains certain rights in this software.
30 | %
31 | % This file is part of WecOptTool.
32 | %
33 | % WecOptTool is free software: you can redistribute it and/or
34 | % modify it under the terms of the GNU General Public License as
35 | % published by the Free Software Foundation, either version 3 of
36 | % the License, or (at your option) any later version.
37 | %
38 | % WecOptTool is distributed in the hope that it will be useful,
39 | % but WITHOUT ANY WARRANTY; without even the implied warranty of
40 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41 | % GNU General Public License for more details.
42 | %
43 | % You should have received a copy of the GNU General Public
44 | % License along with WecOptTool. If not, see
45 | % .
46 |
47 | fullQName = "WecOptTool.solver." + solverName;
48 | solverHandle = str2func(fullQName);
49 | solver = solverHandle(folder);
50 | hydro = solver.getHydro(varargin{:});
51 |
52 | end
53 |
--------------------------------------------------------------------------------