Skip to content

Commit f9aeabf

Browse files
MShabarajleonqujtgrasb
authored
Floating OWC example using the two rigid body approach v2 (#77)
* Adds Floating OWC Example * Adding the test17a.out file from WAMIT * Fixing the bemio.m file for the test17a.out WAMIT output * Fixing the bemio.m file for test17a.out: warnings off * Updated test17a.out WAMIT file * Updated bemio.m file * Modifying the .gitignore file to ignore the exception for the test17a.h5 file Deleting the test17a.out and adding the test17a.h5 file * Adding files from the original orificeModel example * Move products file * Removing MCR test case * Remove unnecessary nested folders and add floating OWC to test * Add back h5 file and readme * Asserts that MoorDyn is installed to run the OWC_W2W test * Updates to Matlab 2024b * Typo fix * Modifies the workflow to copy MoorDyn if OWC is being tested * Modifies the readMe file * Skips the OWC and MoorDyn tests for Ubuntu * fixed github workflows * fixed github workflows * Deleted calcTurbPower.m as it is no longer needed * fixed github workflows * fixed github workflows * fixed github workflows --------- Co-authored-by: jleonqu <jleonqu@sandia.gov> Co-authored-by: jtgrasb <87095491+jtgrasb@users.noreply.github.com>
1 parent 546d4d2 commit f9aeabf

17 files changed

Lines changed: 72058 additions & 11 deletions

File tree

.github/workflows/run-tests-reusable.yml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,14 @@ jobs:
2727
matrix:
2828
folder: ${{ fromJSON(inputs.folder) }}
2929
os: [ubuntu-latest, windows-latest]
30-
release: [R2023b]
30+
release: [R2024b]
3131
include: ${{ fromJSON(inputs.include) }}
3232
exclude:
3333
- os: ubuntu-latest
3434
folder: Mooring
35+
- os: ubuntu-latest
36+
folder: OWC
37+
- folder: Paraview_Visualization
3538
name: "${{ matrix.folder }} - ${{ matrix.os }} - ${{ matrix.release }}"
3639
timeout-minutes: 45
3740
steps:
@@ -50,13 +53,13 @@ jobs:
5053
ref: ${{ inputs.base_ref }}
5154
path: './WEC-Sim'
5255
- name: Check out MoorDyn
53-
if: matrix.folder == 'Mooring'
56+
if: matrix.folder == 'Mooring' || matrix.folder == 'OWC'
5457
uses: actions/checkout@v4
5558
with:
5659
repository: WEC-Sim/MoorDyn
5760
path: './MoorDyn'
5861
- name: Copy MoorDyn Files
59-
if: matrix.folder == 'Mooring'
62+
if: matrix.folder == 'Mooring' || matrix.folder == 'OWC'
6063
run: |
6164
cp * ../WEC-Sim/source/functions/moorDyn
6265
ls ../WEC-Sim/source/functions/moorDyn
68.7 KB
Binary file not shown.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
Mooring line data file for MoorDyn in libmoordyn.dll
2+
---------------------- LINE TYPES -----------------------------------------------------
3+
LineType Diam Mass/m EA BA/-zeta EI Cd Ca CdAx CaAx
4+
(-) (m) (kg/m) (N) (N-s/-) (N-m^2) (-) (-) (-) (-)
5+
Chain 0.032 34.82 1.5e6 -0.8 1e4 1.6 1.0 0.5 0.5
6+
---------------------------- BODIES -----------------------------------------------------
7+
ID Attachment X0 Y0 Z0 r0 p0 y0 Mass CG* I* Volume CdA* Ca
8+
(#) (-) (m) (m) (m) (deg) (deg) (deg) (kg) (m) (kg-m^2) (m^3) (m^2) (-)
9+
1 Coupled 0 0 -2.58 0 0 0 2.914e6 -31.96 1.53e9 2.9013e3 0 0
10+
---------------------- POINTS -----------------------------------------------------
11+
ID Attachment X Y Z Mass Volume CdA CA
12+
(#) (word/ID) (m) (m) (m) (kg) (mˆ3) (m^2) (-)
13+
1 Body1 -9.28 0 -2.58 0 0 0 0
14+
2 Fixed -211.2 0 -80.0 0 0 0 0
15+
3 Body1 4.64 8.04 -2.58 0 0 0 0
16+
4 Fixed 105.6 182.9 -80.0 0 0 0 0
17+
5 Body1 4.64 -8.04 -2.58 0 0 0 0
18+
6 Fixed 105.6 -182.9 -80.00 0 0 0 0
19+
7 Free -53 0 -25.00 4030.46 0.0305 0 1
20+
8 Free 26.5 45.9 -25.00 4030.46 0.0305 0 1
21+
9 Free 27.5 -45.9 -25.00 4030.46 0.0305 0 1
22+
10 Free -85 0 -15.00 36139.83 0.2241 0 1
23+
11 Free 42.5 73.61 -15.00 36139.83 0.2241 0 1
24+
12 Free 42.5 -73.61 -15.00 36139.83 0.2241 0 1
25+
---------------------- LINES -----------------------------------------------------
26+
ID LineType AttachA AttachB UnstrLen NumSegs LineOutputs
27+
(#) (-) (#) (#) (m) (-) (-)
28+
1 Chain 2 10 143.28 15 tp
29+
2 Chain 4 11 143.28 15 tp
30+
3 Chain 6 12 143.28 15 tp
31+
4 Chain 10 7 37.01 5 tp
32+
5 Chain 11 8 37.01 5 tp
33+
6 Chain 12 9 37.01 5 tp
34+
7 Chain 7 1 50.4 8 tp
35+
8 Chain 8 3 50.4 8 tp
36+
9 Chain 9 5 50.4 8 tp
37+
---------------------- SOLVER OPTIONS-----------------------------------------
38+
0.0005 dtM - time step to use in mooring integration
39+
0 WaveKin - wave kinematics flag (0=neglect, the only option currently supported)
40+
3.0e6 kBot - bottom stiffness
41+
3.0e5 cBot - bottom damping
42+
80 WtrDpth - water depth
43+
5.0 CdScaleIC - factor by which to scale drag coefficients during dynamic relaxation IC gen
44+
0.001 threshIC - threshold for IC con
45+
300.0 TmaxIC - max time for ic gen (s)
46+
2 writeLog - Write a log file
47+
0 WriteUnits - 0: do not write the units header on the output files
48+
-------------------------- OUTPUTS --------------------------------
49+
FairTen1
50+
FairTen2
51+
FairTen3
52+
FairTen3
53+
FairTen5
54+
FairTen6
55+
--------------------- need this line ------------------

OWC/FloatingOWC_W2W/OWC_rigid.slx

246 KB
Binary file not shown.

OWC/FloatingOWC_W2W/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Oscillating Water Column
2+
3+
**Authors:** Mohamed Shabara, Jeff Grasberger and Jorge Leon-Quiroga
4+
5+
**Version:** WEC-Sim v6.1.x
6+
7+
**Geometry:** Floating OWC Rigid Body Approach
8+
9+
This model simulates a Floating Oscillating Water Column (OWC) device using a rigid-body approach.
10+
It incorporates performance curves for both a Wells Turbine and a generator, providing a realistic
11+
representation of their dynamic behavior. Additionally, the model accounts for the presence of a
12+
mooring system to ensure the stability of the floating body.
13+
14+
An optimal control strategy is implemented to maximize turbine efficiency by dynamically adjusting system parameters based on operating speed.
15+
16+
This model is based on the research detailed in:
17+
Shabara, Mohamed A., et al. "Optimal Control of Floating Oscillating Water Column Wave Energy Converters." 2025 American Control Conference (ACC), IEEE, 2025.
18+
19+
**Acknowledgment:** This material is based upon work supported by the U.S.
20+
Department of Energy’s Office of Energy Efficiency and Renewable Energy
21+
under the Water Power Technologies Office Award Number DE-EE0008895

OWC/FloatingOWC_W2W/fitCurves.m

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
function [phiInt, piInt, etaInt] = fitCurves(psiInstantaneous, psiVec, etaTurbVec, piVarVec, phiVec)
2+
% psiInstantaneous = clip(psiInstantaneous, min(psi), max(psi));
3+
if psiInstantaneous > max(psiVec)
4+
psiInstantaneous = max(psiVec);
5+
elseif psiInstantaneous < min(psiVec)
6+
psiInstantaneous = min(psiVec);
7+
end
8+
9+
% Interpolate for the phi Value
10+
phiInt = interp1(psiVec, phiVec, psiInstantaneous);
11+
12+
% Interpolate for the Pi Value
13+
piInt = interp1(psiVec, piVarVec, psiInstantaneous);
14+
15+
% Interpolate for the eta Value
16+
etaInt = interp1(psiVec, etaTurbVec, psiInstantaneous);
17+
18+
end
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
function [psi, etaTurb, phi, piVar] = fittingFunctions()
2+
% Curve splitting
3+
psi1 = [0.008, 0.009];
4+
mu_turb1 = [0, 0.100];
5+
m1 = (mu_turb1(2) - mu_turb1(1)) / (psi1(2) - psi1(1));
6+
q1 = mu_turb1(1) - m1 * psi1(1);
7+
8+
psi2 = [0.009, 0.0128];
9+
mu_turb2 = [0.100, 0.200];
10+
m2 = (mu_turb2(2) - mu_turb2(1)) / (psi2(2) - psi2(1));
11+
q2 = mu_turb2(1) - m2 * psi2(1);
12+
13+
psi3 = [0.0128, 0.0199];
14+
mu_turb3 = [0.200, 0.300];
15+
m3 = (mu_turb3(2) - mu_turb3(1)) / (psi3(2) - psi3(1));
16+
q3 = mu_turb3(1) - m3 * psi3(1);
17+
18+
psi4 = [0.0199, 0.0404];
19+
mu_turb4 = [0.300, 0.500];
20+
m4 = (mu_turb4(2) - mu_turb4(1)) / (psi4(2) - psi4(1));
21+
q4 = mu_turb4(1) - m4 * psi4(1);
22+
23+
psi5 = [0.0404, 0.0634, 0.0878];
24+
mu_turb5 = [0.500, 0.595, 0.500];
25+
pp = polyfit(psi5, mu_turb5, 2);
26+
27+
psi6 = [0.0878, 0.1141];
28+
mu_turb6 = [0.500, 0.300];
29+
m6 = (mu_turb6(2) - mu_turb6(1)) / (psi6(2) - psi6(1));
30+
q6 = mu_turb6(1) - m6 * psi6(1);
31+
32+
psi7 = [0.1141, 0.1192];
33+
mu_turb7 = [0.300, 0.273];
34+
m7 = (mu_turb7(2) - mu_turb7(1)) / (psi7(2) - psi7(1));
35+
q7 = mu_turb7(1) - m7 * psi7(1);
36+
37+
psi9 = [0.2122, 0.3];
38+
mu_turb9 = [0.0016, 0.0];
39+
m9 = (mu_turb9(2) - mu_turb9(1)) / (psi9(2) - psi9(1));
40+
q9 = mu_turb9(1) - m9 * psi9(1);
41+
42+
psi10 = [0.1, 0.114];
43+
Pi_turb = [0.3156, 0.3170];
44+
m10 = (Pi_turb(2) - Pi_turb(1)) / (psi10(2) - psi10(1));
45+
q10 = Pi_turb(1) - m10*psi10(1);
46+
47+
m = [m1, m2, m3, m4, 0, m6, m7, 0, m9, m10];
48+
q = [q1, q2, q3, q4, 0, q6, q7, 0, q9, q10];
49+
50+
% Compute the dimensionless functions
51+
psi = linspace(-0.3, 0.3, 5000);
52+
etaTurb = zeros('like',psi);
53+
phi = zeros('like',psi);
54+
piVar = zeros('like',psi);
55+
56+
for ii = 1:length(psi)
57+
PSI = abs(psi(ii));
58+
59+
if PSI >= .008 && PSI < 0.009
60+
ETA_turb = m(1) * PSI + q(1);
61+
elseif PSI >= .009 && PSI < 0.0128
62+
ETA_turb = m(2) * PSI + q(2);
63+
elseif PSI >= .0128 && PSI < 0.0199
64+
ETA_turb = m(3) * PSI + q(3);
65+
elseif PSI >= .0199 && PSI <= 0.0404
66+
ETA_turb = m(4) * PSI + q(4);
67+
elseif PSI > .0404 && PSI < 0.0878
68+
ETA_turb = pp(1) * PSI^2 + pp(2) * PSI + pp(3);
69+
elseif PSI >= .0878 && PSI < 0.1141
70+
ETA_turb = m(6) * PSI + q(6);
71+
elseif PSI >= .1141 && PSI <= 0.1192
72+
ETA_turb = m(7) * PSI + q(7);
73+
elseif PSI >= .1192 && PSI <= 0.2122
74+
ETA_turb = 200.6*exp(PSI*-55.35);
75+
elseif PSI > .2122 && PSI <= 0.3
76+
ETA_turb = m(9) * PSI + q(9);
77+
else
78+
ETA_turb = 0;
79+
end
80+
81+
etaTurb(ii) = ETA_turb;
82+
83+
end
84+
85+
for ii = 1:length(psi)
86+
PSI = abs(psi(ii));
87+
88+
if PSI >= 0 && PSI <= 0.1
89+
PHI = 0.7750*PSI;
90+
else
91+
corr = 0.00167;
92+
PHI = -2.503*PSI^2 + 1.608*PSI - 0.05664 - corr;
93+
end
94+
95+
phi(ii) = PHI;
96+
97+
if PSI > .1 && PSI <= 0.114
98+
piVar(ii) = (m(10) * PSI + q(10)) / 100;
99+
else
100+
piVar(ii) = etaTurb(ii) * PSI * PHI;
101+
end
102+
end
103+
end

OWC/FloatingOWC_W2W/genPower.m

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
function P_gen = genPower(omega, T_ctrl, TgenMax, PgenTated)
2+
3+
term1 = 6.280e-10 * omega^5 - 1.003e-6 * omega^4 + 4.416e-4 * omega^3 - 0.07028 * omega^2 + 2.106 * omega;
4+
term2 = -0.06941 * T_ctrl^2 - 6.014 * T_ctrl - 4.664e-8 * omega^4 * T_ctrl + 1.79e-8 * omega^3 * T_ctrl^2;
5+
term3 = + 2.089e-5 * omega^3 * T_ctrl - 9.816e-6 * omega^2 * T_ctrl^2 - 0.003354 * omega^2 * T_ctrl;
6+
term4 = + 0.001292 * omega * T_ctrl^2 + 1.189 * omega * T_ctrl - 139.3;
7+
8+
tmp = term1 + term2 + term3 + term4;
9+
10+
P_gen = min(tmp, TgenMax * omega);
11+
12+
end

0 commit comments

Comments
 (0)