Hi,
I am currently running MoorDyn v1 as a simple library called from Matlab. My goal is to implement a particle filter algorithm on my model which requires that I compute mooring loads for a number of state updates. For example, given the state vector of displacements & velocities at time t1, I would like to compute mooring loads for a set of state vectors at t2. My understanding of MoorDyn is that it is storing internally its state vector and updating that when LinesCalc is called, implying that calling LinesCalc multiple times is not a viable option. I tested this with the following Matlab script:
% Check if MoorDyn can be called multiple times per update for SRCKF
clear all; close all; clc;
%% ----- Unload MoorDyn if Still Loaded ----- %%
if libisloaded('MoorDyn_Win64')
calllib('MoorDyn_Win64','LinesClose');
unloadlibrary('MoorDyn_Win64')
end
%% ----- Init Constants & Sim Parameters ----- %%
% MoorDyn parameters
dll_path = 'MoorDyn_Win64.dll';
header_path = 'MoorDyn.h';
% Simulation parameters
dt = 0.0125;
time = [0:dt:20];
% Displacements
X = [linspace(0,25,length(time));
repmat(zeros(1,length(time)),[5,1])];
% Velocities
XD = zeros(size(X));
%% ----- Baseline Simulation ----- %%
% Load in MoorDyn
[notfound,warnings] = loadlibrary(dll_path,header_path);
% Prepare pointer
Fmooring_pointer = zeros(1,6);
Fmooring_pointer = libpointer('doublePtr',Fmooring_pointer);
% Init MoorDyn
load_status = calllib('MoorDyn_Win64','LinesInit',zeros(6,1),zeros(6,1));
% Simulate surge displacement
Last_time = 0;
for i = 1:length(time)
% Compute mooring loads
calllib('MoorDyn_Win64','LinesCalc',X(:,i),XD(:,i),Fmooring_pointer,Last_time,dt);
% Extract mooring forces
Baseline_Force(:,i) = Fmooring_pointer.Value;
% Store last time
Last_time = time(i);
end
% Unload MoorDyn & clear pointer
if libisloaded('MoorDyn_Win64')
calllib('MoorDyn_Win64','LinesClose');
unloadlibrary('MoorDyn_Win64')
end
clear Fmooring_pointer
%% ----- Vary Surge Simulation ----- %%
% Load in MoorDyn
[notfound,warnings] = loadlibrary(dll_path,header_path);
% Prepare pointer
Fmooring_pointer = zeros(1,6);
Fmooring_pointer = libpointer('doublePtr',Fmooring_pointer);
% Init MoorDyn
load_status = calllib('MoorDyn_Win64','LinesInit',zeros(6,1),zeros(6,1));
% Simulate surge displacement w/ 3 points per step
Last_time = 0;
for i = 1:length(time)
% Compute mooring loads
calllib('MoorDyn_Win64','LinesCalc',X(:,i) + 0.5*X(:,i),XD(:,i),Fmooring_pointer,Last_time,dt);
calllib('MoorDyn_Win64','LinesCalc',X(:,i) - 0.5*X(:,i),XD(:,i),Fmooring_pointer,Last_time,dt);
calllib('MoorDyn_Win64','LinesCalc',X(:,i),XD(:,i),Fmooring_pointer,Last_time,dt);
% Extract mooring forces
Middle_Force(:,i) = Fmooring_pointer.Value;
% Store last time
Last_time = time(i);
end
% Unload MoorDyn & clear pointer
if libisloaded('MoorDyn_Win64')
calllib('MoorDyn_Win64','LinesClose');
unloadlibrary('MoorDyn_Win64')
end
clear Fmooring_pointer
%% ----- Confirm MoorDyn Unloaded ----- %%
if libisloaded('MoorDyn_Win64')
calllib('MoorDyn_Win64','LinesClose');
unloadlibrary('MoorDyn_Win64')
end
%% ----- Plot Results Comparison ----- %%
% DOF titles
DOFs = {'Surge','Sway','Heave','Roll','Pitch','Yaw'};
% Generate plots
for i = [1,3,5]
figure
gca; hold on; box on;
plot(time,Baseline_Force(i,:),'DisplayName','Baseline')
plot(time,Middle_Force(i,:),'DisplayName','Multiple')
xlabel('Time [s]')
ylabel('Mooring Load [N]')
title(sprintf('%s Mooring Force',DOFs{i}))
legend
end
Which produced the following plots in Surge, Heave, and Pitch:
My current thought on how to get around this is to run MoorDyn for all displacement combinations within a reasonable range, and fit polynomials to each element of the 6x6 mooring stiffness array for quick computing of mooring forces from displacement. While this would neglect dynamic effects, at high sample rates I’m thinking this might be OK. My question is therefore twofold: firstly, is there potentially a way around this approach to use the MoorDyn library directly? Closing and re-initializing the lines for each would not be feasible. And secondly, if not, thoughts on my alternate approach?
Best,
Ian