Source code for mhkit.wave.io.wecsim

import pandas as pd
import numpy as np
import scipy.io as sio


[docs]def read_output(file_name): """ Loads the wecSim response class once 'output' has been saved to a `.mat` structure. NOTE: Python is unable to import MATLAB objects. MATLAB must be used to save the wecSim object as a structure. Parameters ------------ file_name: string Name of wecSim output file saved as a `.mat` structure Returns --------- ws_output: dict Dictionary of pandas DataFrames, indexed by time (s) """ ws_data = sio.loadmat(file_name) output = ws_data['output'] ###################################### ## import wecSim wave class # type: '' # time: [iterations x 1 double] # elevation: [iterations x 1 double] ###################################### try: wave = output['wave'] wave_type = wave[0][0][0][0][0][0] time = wave[0][0]['time'][0][0].squeeze() elevation = wave[0][0]['elevation'][0][0].squeeze() ###################################### ## create wave_output DataFrame ###################################### wave_output = pd.DataFrame(data = time,columns=['time']) wave_output = wave_output.set_index('time') wave_output['elevation'] = elevation wave_output.name = wave_type except: print("wave class not used") wave_output = [] ###################################### ## import wecSim body class # name: '' # time: [iterations x 1 double] # position: [iterations x 6 double] # velocity: [iterations x 6 double] # acceleration: [iterations x 6 double] # forceTotal: [iterations x 6 double] # forceExcitation: [iterations x 6 double] # forceRadiationDamping: [iterations x 6 double] # forceAddedMass: [iterations x 6 double] # forceRestoring: [iterations x 6 double] # forceMorisonAndViscous: [iterations x 6 double] # forceLinearDamping: [iterations x 6 double] ###################################### try: bodies = output['bodies'] num_bodies = len(bodies[0][0]['name'][0]) name = [] time = [] position = [] velocity = [] acceleration = [] forceTotal = [] forceExcitation = [] forceRadiationDamping = [] forceAddedMass = [] forceRestoring = [] forceMorisonAndViscous = [] forceLinearDamping = [] for body in range(num_bodies): name.append(bodies[0][0]['name'][0][body][0]) time.append(bodies[0][0]['time'][0][body]) position.append(bodies[0][0]['position'][0][body]) velocity.append(bodies[0][0]['velocity'][0][body]) acceleration.append(bodies[0][0]['acceleration'][0][body]) forceTotal.append(bodies[0][0]['forceTotal'][0][body]) forceExcitation.append(bodies[0][0]['forceExcitation'][0][body]) forceRadiationDamping.append(bodies[0][0]['forceRadiationDamping'][0][body]) forceAddedMass.append(bodies[0][0]['forceAddedMass'][0][body]) forceRestoring.append(bodies[0][0]['forceRestoring'][0][body]) try: # Format in WEC-Sim responseClass >= v4.2 forceMorisonAndViscous.append(bodies[0][0]['forceMorisonAndViscous'][0][body]) except: # Format in WEC-Sim responseClass <= v4.1 forceMorisonAndViscous.append(bodies[0][0]['forceMorrisonAndViscous'][0][body]) forceLinearDamping.append(bodies[0][0]['forceLinearDamping'][0][body]) except: num_bodies = 0 ###################################### ## create body_output DataFrame ###################################### def _write_body_output(body): for dof in range(6): tmp_body[f'position_dof{dof+1}'] = position[body][:,dof] tmp_body[f'velocity_dof{dof+1}'] = velocity[body][:,dof] tmp_body[f'acceleration_dof{dof+1}'] = acceleration[body][:,dof] tmp_body[f'forceTotal_dof{dof+1}'] = forceTotal[body][:,dof] tmp_body[f'forceExcitation_dof{dof+1}'] = forceExcitation[body][:,dof] tmp_body[f'forceRadiationDamping_dof{dof+1}'] = forceRadiationDamping[body][:,dof] tmp_body[f'forceAddedMass_dof{dof+1}'] = forceAddedMass[body][:,dof] tmp_body[f'forceRestoring_dof{dof+1}'] = forceRestoring[body][:,dof] tmp_body[f'forceMorisonAndViscous_dof{dof+1}'] = forceMorisonAndViscous[body][:,dof] tmp_body[f'forceLinearDamping_dof{dof+1}'] = forceLinearDamping[body][:,dof] return tmp_body if num_bodies >= 1: body_output = {} for body in range(num_bodies): tmp_body = pd.DataFrame(data = time[0],columns=['time']) tmp_body = tmp_body.set_index('time') tmp_body.name = name[body] if num_bodies == 1: body_output = _write_body_output(body) elif num_bodies > 1: body_output[f'body{body+1}'] = _write_body_output(body) else: print("body class not used") body_output = [] ###################################### ## import wecSim pto class # name: '' # time: [iterations x 1 double] # position: [iterations x 6 double] # velocity: [iterations x 6 double] # acceleration: [iterations x 6 double] # forceTotal: [iterations x 6 double] # forceActuation: [iterations x 6 double] # forceConstraint: [iterations x 6 double] # forceInternalMechanics: [iterations x 6 double] # powerInternalMechanics: [iterations x 6 double] ###################################### try: ptos = output['ptos'] num_ptos = len(ptos[0][0]['name'][0]) name = [] time = [] position = [] velocity = [] acceleration = [] forceTotal = [] forceActuation = [] forceConstraint = [] forceInternalMechanics = [] powerInternalMechanics= [] for pto in range(num_ptos): name.append(ptos[0][0]['name'][0][pto][0]) time.append(ptos[0][0]['time'][0][pto]) position.append(ptos[0][0]['position'][0][pto]) velocity.append(ptos[0][0]['velocity'][0][pto]) acceleration.append(ptos[0][0]['acceleration'][0][pto]) forceTotal.append(ptos[0][0]['forceTotal'][0][pto]) forceActuation.append(ptos[0][0]['forceActuation'][0][pto]) forceConstraint.append(ptos[0][0]['forceConstraint'][0][pto]) forceInternalMechanics.append(ptos[0][0]['forceInternalMechanics'][0][pto]) powerInternalMechanics.append(ptos[0][0]['powerInternalMechanics'][0][pto]) except: num_ptos = 0 ###################################### ## create pto_output DataFrame ###################################### def _write_pto_output(pto): for dof in range(6): tmp_pto[f'position_dof{dof+1}'] = position[pto][:,dof] tmp_pto[f'velocity_dof{dof+1}'] = velocity[pto][:,dof] tmp_pto[f'acceleration_dof{dof+1}'] = acceleration[pto][:,dof] tmp_pto[f'forceTotal_dof{dof+1}'] = forceTotal[pto][:,dof] tmp_pto[f'forceTotal_dof{dof+1}'] = forceTotal[pto][:,dof] tmp_pto[f'forceActuation_dof{dof+1}'] = forceActuation[pto][:,dof] tmp_pto[f'forceConstraint_dof{dof+1}'] = forceConstraint[pto][:,dof] tmp_pto[f'forceInternalMechanics_dof{dof+1}'] = forceInternalMechanics[pto][:,dof] tmp_pto[f'powerInternalMechanics_dof{dof+1}'] = powerInternalMechanics[pto][:,dof] return tmp_pto if num_ptos >= 1: pto_output = {} for pto in range(num_ptos): tmp_pto = pd.DataFrame(data = time[0],columns=['time']) tmp_pto = tmp_pto.set_index('time') tmp_pto.name = name[pto] if num_ptos == 1: pto_output = _write_pto_output(pto) elif num_ptos > 1: pto_output[f'pto{pto+1}'] = _write_pto_output(pto) else: print("pto class not used") pto_output = [] ###################################### ## import wecSim constraint class # # name: '' # time: [iterations x 1 double] # position: [iterations x 6 double] # velocity: [iterations x 6 double] # acceleration: [iterations x 6 double] # forceConstraint: [iterations x 6 double] ###################################### try: constraints = output['constraints'] num_constraints = len(constraints[0][0]['name'][0]) name = [] time = [] position = [] velocity = [] acceleration = [] forceConstraint = [] for constraint in range(num_constraints): name.append(constraints[0][0]['name'][0][constraint][0]) time.append(constraints[0][0]['time'][0][constraint]) position.append(constraints[0][0]['position'][0][constraint]) velocity.append(constraints[0][0]['velocity'][0][constraint]) acceleration.append(constraints[0][0]['acceleration'][0][constraint]) forceConstraint.append(constraints[0][0]['forceConstraint'][0][constraint]) except: num_constraints = 0 ###################################### ## create constraint_output DataFrame ###################################### def _write_constraint_output(constraint): for dof in range(6): tmp_constraint[f'position_dof{dof+1}'] = position[constraint][:,dof] tmp_constraint[f'velocity_dof{dof+1}'] = velocity[constraint][:,dof] tmp_constraint[f'acceleration_dof{dof+1}'] = acceleration[constraint][:,dof] tmp_constraint[f'forceConstraint_dof{dof+1}'] = forceConstraint[constraint][:,dof] return tmp_constraint if num_constraints >= 1: constraint_output = {} for constraint in range(num_constraints): tmp_constraint = pd.DataFrame(data = time[0],columns=['time']) tmp_constraint = tmp_constraint.set_index('time') tmp_constraint.name = name[constraint] if num_constraints == 1: constraint_output = _write_constraint_output(constraint) elif num_constraints > 1: constraint_output[f'constraint{constraint+1}'] = _write_constraint_output(constraint) else: print("constraint class not used") constraint_output = [] ###################################### ## import wecSim mooring class # # name: '' # time: [iterations x 1 double] # position: [iterations x 6 double] # velocity: [iterations x 6 double] # forceMooring: [iterations x 6 double] ###################################### try: moorings = output['mooring'] num_moorings = len(moorings[0][0]['name'][0]) name = [] time = [] position = [] velocity = [] forceMooring = [] for mooring in range(num_moorings): name.append(moorings[0][0]['name'][0][mooring][0]) time.append(moorings[0][0]['time'][0][mooring]) position.append(moorings[0][0]['position'][0][mooring]) velocity.append(moorings[0][0]['velocity'][0][mooring]) forceMooring.append(moorings[0][0]['forceMooring'][0][mooring]) except: num_moorings = 0 ###################################### ## create mooring_output DataFrame ###################################### def _write_mooring_output(mooring): for dof in range(6): tmp_mooring[f'position_dof{dof+1}'] = position[mooring][:,dof] tmp_mooring[f'velocity_dof{dof+1}'] = velocity[mooring][:,dof] tmp_mooring[f'forceMooring_dof{dof+1}'] = forceMooring[mooring][:,dof] return tmp_mooring if num_moorings >= 1: mooring_output = {} for mooring in range(num_moorings): tmp_mooring = pd.DataFrame(data = time[0],columns=['time']) tmp_mooring = tmp_mooring.set_index('time') tmp_mooring.name = name[mooring] if num_moorings == 1: mooring_output = _write_mooring_output(mooring) elif num_moorings > 1: mooring_output[f'mooring{mooring+1}'] = _write_mooring_output(mooring) else: print("mooring class not used") mooring_output = [] ###################################### ## import wecSim moorDyn class # # Lines: [1×1 struct] # Line1: [1×1 struct] # Line2: [1×1 struct] # Line3: [1×1 struct] # Line4: [1×1 struct] # Line5: [1×1 struct] # Line6: [1×1 struct] ###################################### try: moorDyn = output['moorDyn'] num_lines = len(moorDyn[0][0][0].dtype) - 1 # number of moorDyn lines Lines = moorDyn[0][0]['Lines'][0][0][0] signals = Lines.dtype.names num_signals = len(Lines.dtype.names) data = Lines[0] time = data[0] Lines = pd.DataFrame(data = time,columns=['time']) Lines = Lines.set_index('time') for signal in range(1,num_signals): Lines[signals[signal]] = data[signal] moorDyn_output= {'Lines': Lines} Line_num_output = {} for line_num in range(1,num_lines+1): tmp_moordyn = moorDyn[0][0][f'Line{line_num}'][0][0][0] signals = tmp_moordyn.dtype.names num_signals = len(tmp_moordyn.dtype.names) data = tmp_moordyn[0] time = data[0] tmp_moordyn = pd.DataFrame(data = time,columns=['time']) tmp_moordyn = tmp_moordyn.set_index('time') for signal in range(1,num_signals): tmp_moordyn[signals[signal]] = data[signal] Line_num_output[f'Line{line_num}'] = tmp_moordyn moorDyn_output.update(Line_num_output) except: print("moorDyn class not used") moorDyn_output = [] ###################################### ## import wecSim ptosim class # # name: '' # pistonCF: [1×1 struct] # pistonNCF: [1×1 struct] # checkValve: [1×1 struct] # valve: [1×1 struct] # accumulator: [1×2 struct] # hydraulicMotor: [1×1 struct] # rotaryGenerator: [1×1 struct] # pmLinearGenerator: [1×1 struct] # pmRotaryGenerator: [1×1 struct] # motionMechanism: [1×1 struct] ###################################### try: ptosim = output['ptosim'] num_ptosim = len(ptosim[0][0]['name'][0]) # number of ptosim print("ptosim class output not supported at this time") except: print("ptosim class not used") ptosim_output = [] ###################################### ## import wecSim cable class # # name: '' # time: [iterations x 1 double] # position: [iterations x 6 double] # velocity: [iterations x 6 double] # forcecable: [iterations x 6 double] ###################################### try: cables = output['cables'] num_cables = len(cables[0][0]['name'][0]) name = [] time = [] position = [] velocity = [] acceleration = [] forcetotal = [] forceactuation = [] forceconstraint = [] for cable in range(num_cables): name.append(cables[0][0]['name'][0][cable][0]) time.append(cables[0][0]['time'][0][cable]) position.append(cables[0][0]['position'][0][cable]) velocity.append(cables[0][0]['velocity'][0][cable]) acceleration.append(cables[0][0]['acceleration'][0][cable]) forcetotal.append(cables[0][0]['forceTotal'][0][cable]) forceactuation.append(cables[0][0]['forceActuation'][0][cable]) forceconstraint.append(cables[0][0]['forceConstraint'][0][cable]) except: num_cables = 0 ###################################### ## create cable_output DataFrame ###################################### def _write_cable_output(cable): for dof in range(6): tmp_cable[f'position_dof{dof+1}'] = position[cable][:,dof] tmp_cable[f'velocity_dof{dof+1}'] = velocity[cable][:,dof] tmp_cable[f'acceleration_dof{dof+1}'] = acceleration[cable][:,dof] tmp_cable[f'forcetotal_dof{dof+1}'] = forcetotal[cable][:,dof] tmp_cable[f'forceactuation_dof{dof+1}'] = forceactuation[cable][:,dof] tmp_cable[f'forceconstraint_dof{dof+1}'] = forceconstraint[cable][:,dof] return tmp_cable if num_cables >= 1: cable_output = {} for cable in range(num_cables): tmp_cable = pd.DataFrame(data = time[0],columns=['time']) tmp_cable = tmp_cable.set_index('time') tmp_cable.name = name[cable] if num_cables == 1: cable_output = _write_cable_output(cable) elif num_cables > 1: cable_output[f'cable{cable+1}'] = _write_cable_output(cable) else: print("cable class not used") cable_output = [] ###################################### ## create wecSim output DataFrame of Dict ###################################### ws_output = {'wave' : wave_output, 'bodies' : body_output, 'ptos' : pto_output, 'constraints' : constraint_output, 'mooring' : mooring_output, 'moorDyn': moorDyn_output, 'ptosim' : ptosim_output, 'cables': cable_output } return ws_output