Source code for bemio.io.aqwa

# Copyright 2014 the National Renewable Energy Laboratory

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import numpy as np

from bemio.data_structures import bem

from math import ceil

[docs]class AqwaOutput(object): ''' Class to read and interact with AQWA simulation data Parameters: hydro_file : str Name of the AQWA .AH1 output file list_file : str Name of the AQWA .LIS output file scale : bool, optional Boolean value to determine if the hydrodynamic data is scaled. See the bemio.data_structures.bem.scale function for more information Examples: The following example assumes there are AQWA output files named aqwa.LIS and aqwa.LS1 >>> aqwa_data = AqwaOutput(hydro_file=aqwa.LS1, list_file=aqwa.LIS) ''' def __init__(self, hydro_file, list_file, scale=False): print '\nReading the AQWA results in the ' + hydro_file + ' file' self.files = bem.generate_file_names(hydro_file) self.scaled_at_read = scale self.scaled = True self.body = {} self._read(list_file) def _read(self,list_file): code = 'AQWA' with open(self.files['out'],'r') as fid: raw = fid.readlines() first_line = 0 for i, line in enumerate(raw): if (first_line == 0) and (line[0] == "*"): continue else: first_line += 1 if first_line == 1: tmp = np.array(raw[i].split()).astype(np.float) num_bodies = int(tmp[0]) num_wave_directions = int(tmp[1]) num_frequencies = int(tmp[2]) num_lines_wave_directions = int(ceil(num_wave_directions/6.)) num_lines_frequencies = int(ceil(num_frequencies/6.)) for j in range(num_lines_wave_directions): if j == 0: wave_directions = tmp[3:] else: tmp = np.array(raw[i+j].split()).astype(np.float) np.append(wave_directions,tmp) for j in range(num_lines_frequencies): tmp = np.array(raw[i + num_lines_wave_directions + j].split()).astype(np.float) if j == 0: frequencies = tmp else: frequencies = np.append(frequencies,tmp) if 'GENERAL' in line: tmp = np.array(raw[i+1].split()).astype(np.float) water_depth = tmp[0] density = tmp[1] gravity = tmp[2] # symmetry = tmp[3] if 'DRAFT' in line: draft = {} for iBod in range(num_bodies): tmp = np.array(raw[i + iBod + 1].split()).astype(np.float) tmp2 = int(tmp[0]) draft[tmp2] = tmp[1] if 'COG' in line: cg = {} for iBod in range(num_bodies): tmp = np.array(raw[i + iBod + 1].split()).astype(np.float) tmp2 = int(tmp[0]) cg[tmp2] = tmp[1:] if line.split()[0] == 'MASS': mass_matrix = {} for iBod in range(num_bodies): for iRow in range(6): tmp = np.array(raw[i + iBod*6 + iRow + 1].split()).astype(np.float) if iRow == 0: tmp2 = int(tmp[0]) mass_matrix[tmp2] = tmp[1:] else: mass_matrix[tmp2] = np.vstack([mass_matrix[tmp2],tmp]) if 'HYDSTIFFNESS' in line: stiffness_matrix = {} for iBod in range(num_bodies): for iRow in range(6): tmp = np.array(raw[i + iBod*6 + iRow + 1].split()).astype(np.float) if iRow == 0: tmp2 = int(tmp[0]) stiffness_matrix[tmp2] = tmp[1:] else: stiffness_matrix[tmp2] = np.vstack([stiffness_matrix[tmp2],tmp]) if 'ADDEDMASS' in line: added_mass = {} for iBod1 in range(num_bodies): for iBod2 in range(num_bodies): for iFreq in range(num_frequencies): for iRow in range(6): tmp = np.array(raw[i + iBod1*(num_bodies*num_frequencies*6) + iBod2*num_frequencies*6 + iFreq*6 + iRow + 1].split()).astype(np.float) if (iBod2==0) and (iFreq==0) and (iRow==0): tmp2 = tmp[0:3].astype(np.float).astype(np.int) added_mass[tmp2[0]] = np.zeros([6,6*num_bodies,num_frequencies]) added_mass[tmp2[0]][:,iBod2*6+iRow,iFreq] = tmp[3:] elif iRow == 0: tmp2 = tmp[0:3].astype(np.float).astype(np.int) added_mass[tmp2[0]][:,iBod2*6+iRow,iFreq] = tmp[3:] else: added_mass[tmp2[0]][:,iBod2*6+iRow,iFreq] = tmp if 'DAMPING' in line: radiation_damping = {} for iBod1 in range(num_bodies): for iBod2 in range(num_bodies): for iFreq in range(num_frequencies): for iRow in range(6): tmp = np.array(raw[i + iBod1*(num_bodies*num_frequencies*6) + iBod2*num_frequencies*6 + iFreq*6 + iRow + 1].split()).astype(np.float) if (iBod2==0) and (iFreq==0) and (iRow==0): tmp2 = tmp[0:3].astype(np.float).astype(np.int) radiation_damping[tmp2[0]] = np.zeros([6,6*num_bodies,num_frequencies]) radiation_damping[tmp2[0]][:,iBod2*6+iRow,iFreq] = tmp[3:] elif iRow == 0: tmp2 = tmp[0:3].astype(np.float).astype(np.int) radiation_damping[tmp2[0]][:,iBod2*6+iRow,iFreq] = tmp[3:] else: radiation_damping[tmp2[0]][:,iBod2*6+iRow,iFreq] = tmp if 'FIDD' in line: fidd = {} for iBod in range(num_bodies): tmp = np.array(raw[i + iBod + 1].split()).astype(np.float) tmp2 = int(tmp[0]) fidd[tmp2] = tmp[1:] if 'FORCERAO' in line: excitation_magnitude = {} excitation_phase = {} for iBod in range(num_bodies): for iDir in range(num_wave_directions): for iFreq in range(num_frequencies): tmp1_1 = np.array(raw[i + iBod*(num_wave_directions*num_frequencies*2) + iDir*num_frequencies*2 + iFreq*2 + 1].split()).astype(np.float) tmp1_2 = np.array(raw[i + iBod*(num_wave_directions*num_frequencies*2) + iDir*num_frequencies*2 + iFreq*2 + 2].split()).astype(np.float) tmp2 = tmp1_1[0:3].astype(np.float).astype(np.int) if (iDir==0) and (iFreq==0): excitation_magnitude[tmp2[0]] = np.zeros([6,num_wave_directions,num_frequencies]) excitation_phase[tmp2[0]] = np.zeros([6,num_wave_directions,num_frequencies]) excitation_magnitude[tmp2[0]][:,tmp2[1]-1,tmp2[2]-1] = tmp1_1[3:] excitation_phase[tmp2[0]][:,tmp2[1]-1,tmp2[2]-1] = tmp1_2 with open(list_file,'r') as fid: raw_list = fid.readlines() bod_count = 1 disp_vol = {} for i, line in enumerate(raw_list): if 'MESH BASED DISPLACEMENT' in line: disp_vol[bod_count] = np.array(line.split())[-1].astype(float) bod_count += 1 for i in xrange(num_bodies): print 'body' + str(i+1) + ':' self.body[i] = bem.HydrodynamicData() self.body[i].scaled = self.scaled self.body[i].rho = density self.body[i].g = gravity self.body[i].wave_dir = wave_directions self.body[i].num_bodies = num_bodies self.body[i].cg = cg[i+1] self.body[i].cb = 'not_defined' self.body[i].k = stiffness_matrix[i+1] self.body[i].T = 2*np.pi/frequencies self.body[i].w = frequencies self.body[i].wp_area = 'not_defined' self.body[i].buoy_force = 'not_defined' self.body[i].disp_vol = disp_vol[i+1] self.body[i].water_depth = water_depth self.body[i].body_num = i self.body[i].name = 'body' + str(i+1) self.body[i].bem_code = code self.body[i].bem_raw_data = raw self.body[i].am.all = added_mass[i+1] print ' * Setting added mass at infinite frequency to added mass at omega = ' + str(frequencies[-1]) self.body[i].am.inf = added_mass[i+1][:,:,-1] print ' * Setting added mass at zero frequency to added mass at omega = ' + str(frequencies[0]) self.body[i].am.zero = added_mass[i+1][:,:,0] self.body[i].rd.all = radiation_damping[i+1] self.body[i].ex.mag = excitation_magnitude[i+1] self.body[i].ex.phase = excitation_phase[i+1] print ' * Calculating real and imaginary excitation components.' self.body[i].ex.re = self.body[i].ex.mag * np.cos(self.body[i].ex.phase) self.body[i].ex.im = self.body[i].ex.mag * np.sin(self.body[i].ex.phase) self.body[i].scale(self.scaled_at_read)
[docs]def read(hydro_file, list_file, scale=False): ''' Function to read AQWA data into a data object of type(AqwaOutput) Parameters: hydro_file : str Name of the AQWA .AH1 output file list_file : str Name of the AQWA .LIS output file scale : bool, optional Boolean value to determine if the hydrodynamic data is scaled. See the bemio.data_structures.bem.scale function for more information Returns: aqwa_data A AqwaOutput object that contains hydrodynamic data Examples: The following example assumes there are AQWA output files named aqwa.LIS and aqwa.LS1 >>> aqwa_data = read(hydro_file=aqwa.LS1, list_file=aqwa.LIS) ''' aqwa_data = AqwaOutput(hydro_file, list_file, scale) return aqwa_data