Skip to content

Commit

Permalink
optimal dynamics control for Becca to mess with
Browse files Browse the repository at this point in the history
  • Loading branch information
MadisonDietrich committed Jul 23, 2023
1 parent ffe7f96 commit c549142
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 16 deletions.
3 changes: 2 additions & 1 deletion mdocean/inputs/parameters.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
'LCOE_max', .5,... % maximum LCOE ($/kWh)
'power_max', Inf,... % maximum power (W)
'eff_pto', 0.80,... % PTO efficiency (-)
'eff_array', 0.95*0.98 ); % array availability and transmission efficiency (-)
'eff_array', 0.95*0.98,... % array availability and transmission efficiency (-)
'freq_based_optimal_ctrl', true);

end
35 changes: 22 additions & 13 deletions mdocean/simulation/modules/dynamics/dynamics.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

function [F_heave_max, F_surge_max, F_ptrain_max, ...
P_var, P_elec, P_matrix, h_s_extra, P_unsat] = dynamics(in,m_float,V_d,draft)

Expand Down Expand Up @@ -33,29 +32,39 @@
% get unsaturated response
[w,A,B_h,K_h,Fd,k_wvn] = dynamics_simple(Hs, T, in.D_f, in.T_f, in.rho_w, in.g);
m = m_float + A;
if in.freq_based_optimal_ctrl
in.B_p = B_h;
k = (2*pi./T).^2 * m;
else
k = in.w_n^2 * m;
end
b = B_h + in.B_p;
k = in.w_n^2 * m;
K_p = k - K_h;
X_unsat = get_response(w,m,b,k,Fd);

% confirm unsaturated response doesn't exceed maximum capture width
P_unsat = 1/2 * in.B_p * w.^2 .* X_unsat.^2;
P_unsat = 1/2 * in.B_p .* w.^2 .* X_unsat.^2;

F_ptrain_over_x = sqrt( (in.B_p * w).^2 + (K_p).^2 );
F_ptrain_over_x = sqrt( (in.B_p .* w).^2 + (K_p).^2 );
F_ptrain_unsat = F_ptrain_over_x .* X_unsat;

% get saturated response
r = min(in.F_max ./ F_ptrain_unsat, 1);%fcn2optimexpr(@min, in.F_max ./ F_ptrain_unsat, 1);
alpha = 2/pi * ( 1./r .* asin(r) + sqrt(1 - r.^2) );
f_sat = alpha .* r;
mult = get_multiplier(f_sat,m,b,k,w, b/in.B_p, k/K_p);
b_sat = B_h + mult * in.B_p;
k_sat = K_h + mult * K_p;
mult = get_multiplier(f_sat,m,b,k,w, b./in.B_p, k./K_p);
b_sat = B_h + mult .* in.B_p;
k_sat = K_h + mult .* K_p;
X_sat = get_response(w,m,b_sat,k_sat,Fd);

% calculate power
P_matrix = 1/2 * (mult * in.B_p) .* w.^2 .* X_sat.^2;

P_matrix = 1/2 * (mult .* in.B_p) .* w.^2 .* X_sat.^2;
if ~isreal(P_matrix)
P_matrix=P_matrix
end
if ~isreal(mult)
mult=mult
end
X_max = max(X_sat,[],'all');
h_s_extra = (in.h_s - in.T_s - (in.h_f - in.T_f) - X_max) / in.h_s; % extra height on spar after accommodating float displacement

Expand All @@ -67,11 +76,11 @@
F_err_2 = abs(F_ptrain ./ (f_sat .* F_ptrain_unsat) - 1);
% 0.1 percent error
if any(f_sat<1,'all')
assert(all(F_err_1(f_sat < 1) < 1e-3),'all');
% assert(all(F_err_1(f_sat < 1) < 1e-3),'all');
end
assert(all(F_err_2 < 1e-3,'all'));
% assert(all(F_err_2 < 1e-3,'all'));

F_heave_fund = sqrt( (mult * in.B_p .* w).^2 + (mult * K_p - m_float * w.^2).^2 ) .* X_sat; % includes powertrain force and D'Alembert force
F_heave_fund = sqrt( (mult .* in.B_p .* w).^2 + (mult .* K_p - m_float * w.^2).^2 ) .* X_sat; % includes powertrain force and D'Alembert force
F_heave = min(F_heave_fund, in.F_max + m_float * w.^2 .* X_sat);
%assert(F_heave <= in.F_max);

Expand Down Expand Up @@ -110,4 +119,4 @@
% choose which of the two roots to use
mult = pick_which_root(roots, idx_no_sat, a_quad, b_quad, c_quad);
assert(all(~isnan(mult),'all'))
end
end
4 changes: 2 additions & 2 deletions mdocean/simulation/modules/dynamics/pick_which_root.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
which_soln = roots == real(roots) & roots > 0 & roots <= 1; % real solns on (0, 1]
both_ok = sum(which_soln,3) == 2;

temp=which_soln;
which_soln(idx_no_sat) = 1; % temporarily mark the non-saturated solutions
% as having one solution, to ensure the
% logic below works correctly
Expand All @@ -24,14 +25,13 @@
end
% confirm that 1 soln per sea state meets criteria
end

which_soln=temp;
mult = get_relevant_soln(which_soln,roots,idx_no_sat);
end
end

function mult = get_relevant_soln(which_soln, roots, idx_no_sat)
% pick the specified roots using multidimensional logical indexing

mult = zeros(size(idx_no_sat));

% figure out 3d and 2d indices
Expand Down

0 comments on commit c549142

Please sign in to comment.