Skip to content

Commit 5b34d18

Browse files
authored
Updates for WEC-Sim v5.0 (#185)
* update read_wecsim for WEC-Sim v5.0 * add cable class * update notebook with results * add try-except for Morrison (v4.1) vs Morison (v4.2+) * add cable check and dataset to wave tests * update cable dataset
1 parent eadd8b9 commit 5b34d18

File tree

7 files changed

+232
-148
lines changed

7 files changed

+232
-148
lines changed
8.25 MB
Binary file not shown.
-58.4 KB
Binary file not shown.
-1.41 KB
Binary file not shown.
-19.8 MB
Binary file not shown.

examples/wecsim_example.ipynb

Lines changed: 142 additions & 141 deletions
Large diffs are not rendered by default.

mhkit/tests/wave/io/test_wecsim.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def setUpClass(self):
3535
def tearDownClass(self):
3636
pass
3737

38-
### WEC-Sim data, mo mooring
38+
### WEC-Sim data, no mooring
3939
def test_read_wecSim_no_mooring(self):
4040
ws_output = wave.io.wecsim.read_output(join(datadir, 'RM3_matlabWorkspace_structure.mat'))
4141
self.assertEqual(ws_output['wave'].elevation.name,'elevation')
@@ -45,6 +45,19 @@ def test_read_wecSim_no_mooring(self):
4545
self.assertEqual(len(ws_output['mooring']),0)
4646
self.assertEqual(len(ws_output['moorDyn']),0)
4747
self.assertEqual(len(ws_output['ptosim']),0)
48+
self.assertEqual(len(ws_output['cables']),0)
49+
50+
### WEC-Sim data, with cable
51+
def test_read_wecSim_cable(self):
52+
ws_output = wave.io.wecsim.read_output(join(datadir, 'Cable_matlabWorkspace_structure.mat'))
53+
self.assertEqual(ws_output['wave'].elevation.name,'elevation')
54+
self.assertEqual(ws_output['bodies']['body1'].name,'BuoyDraft5cm')
55+
self.assertEqual(ws_output['cables'].name,'Cable')
56+
self.assertEqual(ws_output['constraints']['constraint1'].name,'Mooring')
57+
self.assertEqual(len(ws_output['mooring']),0)
58+
self.assertEqual(len(ws_output['moorDyn']),0)
59+
self.assertEqual(len(ws_output['ptosim']),0)
60+
self.assertEqual(len(ws_output['ptos']),0)
4861

4962
### WEC-Sim data, with mooring
5063
def test_read_wecSim_with_mooring(self):
@@ -56,6 +69,7 @@ def test_read_wecSim_with_mooring(self):
5669
self.assertEqual(len(ws_output['mooring']),40001)
5770
self.assertEqual(len(ws_output['moorDyn']),0)
5871
self.assertEqual(len(ws_output['ptosim']),0)
72+
self.assertEqual(len(ws_output['cables']),0)
5973

6074
### WEC-Sim data, with moorDyn
6175
def test_read_wecSim_with_moorDyn(self):
@@ -67,6 +81,7 @@ def test_read_wecSim_with_moorDyn(self):
6781
self.assertEqual(len(ws_output['mooring']),40001)
6882
self.assertEqual(len(ws_output['moorDyn']),7)
6983
self.assertEqual(len(ws_output['ptosim']),0)
84+
self.assertEqual(len(ws_output['cables']),0)
7085

7186

7287
if __name__ == '__main__':

mhkit/wave/io/wecsim.py

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import numpy as np
33
import scipy.io as sio
44

5+
56
def read_output(file_name):
67
"""
78
Loads the wecSim response class once 'output' has been saved to a `.mat`
@@ -63,7 +64,7 @@ def read_output(file_name):
6364
# forceRadiationDamping: [iterations x 6 double]
6465
# forceAddedMass: [iterations x 6 double]
6566
# forceRestoring: [iterations x 6 double]
66-
# forceMorrisonAndViscous: [iterations x 6 double]
67+
# forceMorisonAndViscous: [iterations x 6 double]
6768
# forceLinearDamping: [iterations x 6 double]
6869
######################################
6970
try:
@@ -79,7 +80,7 @@ def read_output(file_name):
7980
forceRadiationDamping = []
8081
forceAddedMass = []
8182
forceRestoring = []
82-
forceMorrisonAndViscous = []
83+
forceMorisonAndViscous = []
8384
forceLinearDamping = []
8485
for body in range(num_bodies):
8586
name.append(bodies[0][0]['name'][0][body][0])
@@ -92,7 +93,12 @@ def read_output(file_name):
9293
forceRadiationDamping.append(bodies[0][0]['forceRadiationDamping'][0][body])
9394
forceAddedMass.append(bodies[0][0]['forceAddedMass'][0][body])
9495
forceRestoring.append(bodies[0][0]['forceRestoring'][0][body])
95-
forceMorrisonAndViscous.append(bodies[0][0]['forceMorrisonAndViscous'][0][body])
96+
try:
97+
# Format in WEC-Sim responseClass >= v4.2
98+
forceMorisonAndViscous.append(bodies[0][0]['forceMorisonAndViscous'][0][body])
99+
except:
100+
# Format in WEC-Sim responseClass <= v4.1
101+
forceMorisonAndViscous.append(bodies[0][0]['forceMorrisonAndViscous'][0][body])
96102
forceLinearDamping.append(bodies[0][0]['forceLinearDamping'][0][body])
97103
except:
98104
num_bodies = 0
@@ -110,7 +116,7 @@ def _write_body_output(body):
110116
tmp_body[f'forceRadiationDamping_dof{dof+1}'] = forceRadiationDamping[body][:,dof]
111117
tmp_body[f'forceAddedMass_dof{dof+1}'] = forceAddedMass[body][:,dof]
112118
tmp_body[f'forceRestoring_dof{dof+1}'] = forceRestoring[body][:,dof]
113-
tmp_body[f'forceMorrisonAndViscous_dof{dof+1}'] = forceMorrisonAndViscous[body][:,dof]
119+
tmp_body[f'forceMorisonAndViscous_dof{dof+1}'] = forceMorisonAndViscous[body][:,dof]
114120
tmp_body[f'forceLinearDamping_dof{dof+1}'] = forceLinearDamping[body][:,dof]
115121
return tmp_body
116122

@@ -256,7 +262,7 @@ def _write_constraint_output(constraint):
256262

257263

258264
######################################
259-
## import wecSim moopring class
265+
## import wecSim mooring class
260266
#
261267
# name: ''
262268
# time: [iterations x 1 double]
@@ -374,6 +380,67 @@ def _write_mooring_output(mooring):
374380
except:
375381
print("ptosim class not used")
376382
ptosim_output = []
383+
384+
385+
######################################
386+
## import wecSim cable class
387+
#
388+
# name: ''
389+
# time: [iterations x 1 double]
390+
# position: [iterations x 6 double]
391+
# velocity: [iterations x 6 double]
392+
# forcecable: [iterations x 6 double]
393+
######################################
394+
try:
395+
cables = output['cables']
396+
num_cables = len(cables[0][0]['name'][0])
397+
name = []
398+
time = []
399+
position = []
400+
velocity = []
401+
acceleration = []
402+
forcetotal = []
403+
forceactuation = []
404+
forceconstraint = []
405+
for cable in range(num_cables):
406+
name.append(cables[0][0]['name'][0][cable][0])
407+
time.append(cables[0][0]['time'][0][cable])
408+
position.append(cables[0][0]['position'][0][cable])
409+
velocity.append(cables[0][0]['velocity'][0][cable])
410+
acceleration.append(cables[0][0]['acceleration'][0][cable])
411+
forcetotal.append(cables[0][0]['forceTotal'][0][cable])
412+
forceactuation.append(cables[0][0]['forceActuation'][0][cable])
413+
forceconstraint.append(cables[0][0]['forceConstraint'][0][cable])
414+
except:
415+
num_cables = 0
416+
417+
######################################
418+
## create cable_output DataFrame
419+
######################################
420+
def _write_cable_output(cable):
421+
for dof in range(6):
422+
tmp_cable[f'position_dof{dof+1}'] = position[cable][:,dof]
423+
tmp_cable[f'velocity_dof{dof+1}'] = velocity[cable][:,dof]
424+
tmp_cable[f'acceleration_dof{dof+1}'] = acceleration[cable][:,dof]
425+
tmp_cable[f'forcetotal_dof{dof+1}'] = forcetotal[cable][:,dof]
426+
tmp_cable[f'forceactuation_dof{dof+1}'] = forceactuation[cable][:,dof]
427+
tmp_cable[f'forceconstraint_dof{dof+1}'] = forceconstraint[cable][:,dof]
428+
return tmp_cable
429+
430+
if num_cables >= 1:
431+
cable_output = {}
432+
for cable in range(num_cables):
433+
tmp_cable = pd.DataFrame(data = time[0],columns=['time'])
434+
tmp_cable = tmp_cable.set_index('time')
435+
tmp_cable.name = name[cable]
436+
if num_cables == 1:
437+
cable_output = _write_cable_output(cable)
438+
elif num_cables > 1:
439+
cable_output[f'cable{cable+1}'] = _write_cable_output(cable)
440+
else:
441+
print("cable class not used")
442+
cable_output = []
443+
377444

378445

379446
######################################
@@ -385,6 +452,7 @@ def _write_mooring_output(mooring):
385452
'constraints' : constraint_output,
386453
'mooring' : mooring_output,
387454
'moorDyn': moorDyn_output,
388-
'ptosim' : ptosim_output
455+
'ptosim' : ptosim_output,
456+
'cables': cable_output
389457
}
390458
return ws_output

0 commit comments

Comments
 (0)