Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor openfast/openfast_python/openfast_io/turbsim_file.py #2577

Merged
merged 4 commits into from
Dec 23, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 42 additions & 23 deletions openfast_python/openfast_io/turbsim_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"""
import pandas as pd
import numpy as np
import argparse
import os
import struct
import time
Expand All @@ -16,13 +17,13 @@
File=dict

class TurbSimFile(File):
"""
"""
Read/write a TurbSim turbulence file (.bts). The object behaves as a dictionary.

Main keys
---------
- 'u': velocity field, shape (3 x nt x ny x nz)
- 'y', 'z', 't': space and time coordinates
- 'y', 'z', 't': space and time coordinates
- 'dt', 'ID', 'info'
- 'zTwr', 'uTwr': tower coordinates and field if present (3 x nt x nTwr)
- 'zHub', 'uHub': height and velocity at a reference point (usually not hub)
Expand All @@ -36,7 +37,7 @@ class TurbSimFile(File):

ts = TurbSimFile('Turb.bts')
print(ts.keys())
print(ts['u'].shape)
print(ts['u'].shape)


"""
Expand All @@ -55,7 +56,7 @@ def __init__(self,filename=None, **kwargs):
self.read(filename, **kwargs)

def read(self, filename=None, header_only=False):
""" read BTS file, with field:
""" read BTS file, with field:
u (3 x nt x ny x nz)
uTwr (3 x nt x nTwr)
"""
Expand All @@ -69,15 +70,15 @@ def read(self, filename=None, header_only=False):
raise EmptyFileError('File is empty:',self.filename)

scl = np.zeros(3, np.float32); off = np.zeros(3, np.float32)
with open(self.filename, mode='rb') as f:
with open(self.filename, mode='rb') as f:
# Reading header info
ID, nz, ny, nTwr, nt = struct.unpack('<h4l', f.read(2+4*4))
dz, dy, dt, uHub, zHub, zBottom = struct.unpack('<6f' , f.read(6*4) )
scl[0],off[0],scl[1],off[1],scl[2],off[2] = struct.unpack('<6f' , f.read(6*4))
nChar, = struct.unpack('<l', f.read(4))
info = (f.read(nChar)).decode()
# Reading turbulence field
if not header_only:
if not header_only:
u = np.zeros((3,nt,ny,nz))
uTwr = np.zeros((3,nt,nTwr))
# For loop on time (acts as buffer reading, and only possible way when nTwr>0)
Expand All @@ -95,7 +96,7 @@ def read(self, filename=None, header_only=False):
self['info'] = info
self['ID'] = ID
self['dt'] = dt
self['y'] = np.arange(ny)*dy
self['y'] = np.arange(ny)*dy
self['y'] -= np.mean(self['y']) # y always centered on 0
self['z'] = np.arange(nz)*dz +zBottom
self['t'] = np.arange(nt)*dt
Expand All @@ -104,7 +105,7 @@ def read(self, filename=None, header_only=False):
self['uHub'] = uHub

def write(self, filename=None):
"""
"""
write a BTS file, using the following keys: 'u','z','y','t','uTwr'
u (3 x nt x ny x nz)
uTwr (3 x nt x nTwr)
Expand Down Expand Up @@ -151,7 +152,7 @@ def write(self, filename=None):
# Providing estimates of uHub and zHub even if these fields are not used
zHub,uHub, bHub = self.hubValues()

with open(self.filename, mode='wb') as f:
with open(self.filename, mode='wb') as f:
f.write(struct.pack('<h4l', self['ID'], nz, ny, nTwr, nt))
f.write(struct.pack('<6f', dz, dy, dt, uHub, zHub, z0)) # NOTE uHub, zHub maybe not used
f.write(struct.pack('<6f', scl[0],off[0],scl[1],off[1],scl[2],off[2]))
Expand Down Expand Up @@ -258,14 +259,12 @@ def __repr__(self):
s+=' ux: min: {}, max: {}, mean: {} \n'.format(np.min(ux), np.max(ux), np.mean(ux))
s+=' uy: min: {}, max: {}, mean: {} \n'.format(np.min(uy), np.max(uy), np.mean(uy))
s+=' uz: min: {}, max: {}, mean: {} \n'.format(np.min(uz), np.max(uz), np.mean(uz))

return s

def toDataFrame(self):
dfs={}

ny = len(self['y'])
nz = len(self['y'])
# Index at mid box
iy,iz = self._iMid()

Expand All @@ -275,13 +274,13 @@ def toDataFrame(self):
ti = s/m*100
Cols=['z_[m]','u_[m/s]','v_[m/s]','w_[m/s]','sigma_u_[m/s]','sigma_v_[m/s]','sigma_w_[m/s]','TI_[%]']
data = np.column_stack((self['z'],m[0,:],m[1,:],m[2,:],s[0,:],s[1,:],s[2,:],ti[0,:]))
dfs['VertProfile'] = pd.DataFrame(data = data ,columns = Cols)
dfs['VertProfile'] = pd.DataFrame(data = data, columns = Cols)

# Mid time series
u = self['u'][:,:,iy,iz]
Cols=['t_[s]','u_[m/s]','v_[m/s]','w_[m/s]']
data = np.column_stack((self['t'],u[0,:],u[1,:],u[2,:]))
dfs['MidLine'] = pd.DataFrame(data = data ,columns = Cols)
dfs['MidLine'] = pd.DataFrame(data = data, columns = Cols)

# Hub time series
#try:
Expand All @@ -295,25 +294,45 @@ def toDataFrame(self):
# pass
return dfs

def compute_rot_avg(self,R):
'''
def compute_rot_avg(self, R):
'''
Compute rotor average wind speed, where R is the rotor radius
'''

self['rot_avg'] = np.zeros((3,len(self['t'])))

for i in range(3):
u_ = self['u'][i,:,:,:]
z_hub = self['zHub']
yy, zz = np.meshgrid(self['y'],self['z'])
rotor_ind = np.sqrt(yy**2 + (zz - z_hub)**2) < R
yy, zz = np.meshgrid(self['y'], self['z'])
rotor_ind = (yy**2 + (zz - z_hub)**2) < R**2

u_rot = []
for u_plane in u_:
u_rot.append(u_plane[rotor_ind].mean())
u_rot = [u_plane[rotor_ind].mean() for u_plane in u_]

self['rot_avg'][i,:] = u_rot


def main():
# Create argument parser
parser = argparse.ArgumentParser(
description="Read an OpenFAST .bts wind field files")
parser.add_argument(
"input_file",
type=str,
help="Path to the input .bts file."
)

# Parse arguments
args = parser.parse_args()

# Process input and output files
input_file = args.input_file
# ts = TurbSimFile('../_tests/TurbSim.bts')
ts = TurbSimFile(input_file)
df = ts.toDataFrame()
print(df['VertProfile'].info())
print(df['MidLine'].info())


if __name__=='__main__':
ts = TurbSimFile('../_tests/TurbSim.bts')
main()