Skip to content

Commit 67e88b2

Browse files
committed
FF: clean-up and small fixes
1 parent b6c3ff5 commit 67e88b2

3 files changed

Lines changed: 28 additions & 44 deletions

File tree

openfast_toolbox/fastfarm/AMRWindSimulation.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,8 @@ def write_sampling_params(self, out=None, format='netcdf', overwrite=False):
735735
else:
736736
# full file given
737737
outfile = out
738+
if not os.path.exists(os.path.dirname(outfile)):
739+
os.makedirs(os.path.dirname(outfile))
738740
if not overwrite:
739741
if os.path.isfile(outfile):
740742
raise FileExistsError(f"{str(outfile)} already exists! Aborting...")

openfast_toolbox/fastfarm/FASTFarmCaseCreation.py

Lines changed: 20 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,10 @@ def copyTurbineFilesForEachCase(self, writeFiles=True):
686686
shutilcopy2_untilSuccessful(self.BDfilepath, os.path.join(currPath,self.BDfilename))
687687
shutilcopy2_untilSuccessful(self.BDbladefilepath, os.path.join(currPath,self.BDbladefilename))
688688

689+
# SubDyn
690+
if self.hasSubD and writeFiles:
691+
shutilcopy2_untilSuccessful(self.SubDfilepath, os.path.join(currPath,self.SubDfilename))
692+
689693
# Write updated DISCON
690694
if writeFiles and self.hasController:
691695
if not hasattr(self, 'cpctcqfilepath'):
@@ -1794,12 +1798,6 @@ def getDomainParameters(self):
17941798
# and sweep in yaw do not require extra TurbSim runs
17951799
self.nHighBoxCases = len(np.unique(self.inflow_deg)) # some wind dir might be repeated for sweep on yaws
17961800

1797-
# Old method to get allHighBoxCases. Doesn't work well if I have weird manual sweeps
1798-
allHighBoxCases_old = self.allCases.where(~self.allCases['misalignment'], drop=True).drop_vars('misalignment')\
1799-
.where(self.allCases['nFullAeroDyn']==self.nTurbines, drop=True).drop_vars('ADmodel')\
1800-
.where(self.allCases['nFulllElastoDyn']==self.nTurbines, drop=True).drop_vars('EDmodel')\
1801-
.where(self.allCases['yawCase']==1, drop=True).drop_vars('yawCase')
1802-
18031801
# This is a new method, but I'm not sure if it will work always, so let's leave the one above and check it
18041802
uniquewdir = np.unique(self.allCases.inflow_deg)
18051803
allHighBoxCases = []
@@ -1808,26 +1806,6 @@ def getDomainParameters(self):
18081806
firstCaseWithInflow_i = self.allCases.where(self.allCases['inflow_deg'] == currwdir, drop=True).isel(case=0)
18091807
allHighBoxCases.append(firstCaseWithInflow_i)
18101808
self.allHighBoxCases = xr.concat(allHighBoxCases, dim='case')
1811-
# But, before I change the algorithm, I want to time-test it, so let's compare both ways
1812-
if not self.allHighBoxCases['inflow_deg'].identical(allHighBoxCases_old['inflow_deg']):
1813-
self.allHighBoxCases_old = allHighBoxCases_old
1814-
print(f'!!!!!! WARNING !!!!!!!!!')
1815-
print(f'The new method for computing all the high-box cases is not producing the same set of cases as the old algorithm.')
1816-
print(f'This should only happen if you have complex sweeps that you modified manually after the code creates the initial arrays')
1817-
print(f'Check the variable <obj>.allHighBoxCases_old to see the cases using the old algorithm')
1818-
print(f'Check the variable <obj>.allHighBoxCases to see the cases using the new algorithm')
1819-
print(f'You should check which xr.dataset has the correct, unique inflow_deg values. The correct array will only have unique values')
1820-
print(f'')
1821-
if len(self.allHighBoxCases_old['inflow_deg']) != len(np.unique(self.allHighBoxCases_old['inflow_deg'])):
1822-
print(f' Checking the inflow_deg variable, it looks like the old method has non-unique wind directions. The old method is wrong here.')
1823-
if len(self.allHighBoxCases['inflow_deg']) != len(np.unique(self.allHighBoxCases['inflow_deg'])):
1824-
print(f' Checking the inflow_deg variable, it looks like the new method has non-unique wind directions. The new method is wrong here.')
1825-
else:
1826-
print(' The new method appears to be correct here! Trust but verify')
1827-
print('')
1828-
print(f'!!!!!!!!!!!!!!!!!!!!!!!!')
1829-
print(f'')
1830-
18311809

18321810
if self.nHighBoxCases != len(self.allHighBoxCases.case):
18331811
raise ValueError(f'The number of cases do not match as expected. {self.nHighBoxCases} unique wind directions, but {len(self.allHighBoxCases.case)} unique cases.')
@@ -1931,10 +1909,6 @@ def TS_high_setup(self, writeFiles=True):
19311909

19321910
#todo: Check if the low-res boxes were created successfully
19331911

1934-
if self.ds_high != self.cmax:
1935-
print(f'WARNING: The requested ds_high = {self.ds_high} m is not actually used. The TurbSim ')
1936-
print(f' boxes use the default max chord value ({self.cmax} m here) for the spatial resolution.')
1937-
19381912
# Create symbolic links for the low-res boxes
19391913
self.TS_low_createSymlinks()
19401914

@@ -2303,6 +2277,7 @@ def _FF_setup_LES(self, seedsToKeep=1):
23032277
ff_file['NumPlanes'] = int(np.ceil( 20*D_/(self.dt_low*Vhub_*(1-1/6)) ) )
23042278

23052279
# Ensure radii outputs are within [0, NumRadii-1]
2280+
ff_file['OutRadii'] = [ff_file['OutRadii']] if isinstance(ff_file['OutRadii'],(float,int)) else ff_file['OutRadii']
23062281
for i, r in enumerate(ff_file['OutRadii']):
23072282
if r > ff_file['NumRadii']-1:
23082283
ff_file['NOutRadii'] = i
@@ -2408,6 +2383,14 @@ def _FF_setup_TS(self):
24082383
ff_file['NumRadii'] = int(np.ceil(3*D_/(2*self.dr) + 1))
24092384
ff_file['NumPlanes'] = int(np.ceil( 20*D_/(self.dt_low*Vhub_*(1-1/6)) ) )
24102385

2386+
# Ensure radii outputs are within [0, NumRadii-1]
2387+
ff_file['OutRadii'] = [ff_file['OutRadii']] if isinstance(ff_file['OutRadii'],(float,int)) else ff_file['OutRadii']
2388+
for i, r in enumerate(ff_file['OutRadii']):
2389+
if r > ff_file['NumRadii']-1:
2390+
ff_file['NOutRadii'] = i
2391+
ff_file['OutRadii'] = ff_file['OutRadii'][:i]
2392+
break
2393+
24112394
# Vizualization outputs
24122395
ff_file['WrDisWind'] = 'False'
24132396
ff_file['WrDisDT'] = ff_file['DT_Low'] # default is the same as DT_Low
@@ -2746,17 +2729,12 @@ def plot(self, figsize=(14,7), fontsize=13, saveFig=True, returnFig=False, figFo
27462729
alphas = np.append(1, np.linspace(0.5,0.2, len(self.wts_rot_ds['inflow_deg'])-1))
27472730

27482731
# low-res box
2749-
try:
2750-
ax.plot([self.TSlowbox.xmin, self.TSlowbox.xmax, self.TSlowbox.xmax, self.TSlowbox.xmin, self.TSlowbox.xmin],
2751-
[self.TSlowbox.ymin, self.TSlowbox.ymin, self.TSlowbox.ymax, self.TSlowbox.ymax, self.TSlowbox.ymin],'--k',lw=2,label='Low')
2752-
except AttributeError:
2753-
print(f'WARNING: The exact limits of the low-res box have not been computed yet. Showing extents given as inputs')
2754-
xmin = self.allCases['Tx'].min()-self.extent_low[0]*self.D
2755-
xmax = self.allCases['Tx'].max()+self.extent_low[1]*self.D
2756-
ymin = self.allCases['Ty'].min()-self.extent_low[2]*self.D
2757-
ymax = self.allCases['Ty'].max()+self.extent_low[3]*self.D
2758-
ax.plot([xmin, xmax, xmax, xmin, xmin],
2759-
[ymin, ymin, ymax, ymax, ymin],'--k',lw=2,label='Low')
2732+
xmin = self.allCases['Tx'].min()-self.extent_low[0]*self.D
2733+
xmax = self.allCases['Tx'].max()+self.extent_low[1]*self.D
2734+
ymin = self.allCases['Ty'].min()-self.extent_low[2]*self.D
2735+
ymax = self.allCases['Ty'].max()+self.extent_low[3]*self.D
2736+
ax.plot([xmin, xmax, xmax, xmin, xmin],
2737+
[ymin, ymin, ymax, ymax, ymin],'--k',lw=2,label='Low')
27602738

27612739

27622740
for j, inflow in enumerate(self.wts_rot_ds['inflow_deg']):
@@ -2807,7 +2785,7 @@ def plot(self, figsize=(14,7), fontsize=13, saveFig=True, returnFig=False, figFo
28072785
handles, labels = plt.gca().get_legend_handles_labels()
28082786
by_label = dict(zip(labels, handles))
28092787
if showLegend:
2810-
plt.legend(by_label.values(), by_label.keys(), loc='upper left', bbox_to_anchor=(1.02,1.015), fontsize=fontsize, ncols=int(self.nTurbines/25))
2788+
plt.legend(by_label.values(), by_label.keys(), loc='upper left', bbox_to_anchor=(1.02,1.015), fontsize=fontsize, ncols=int(np.ceil(self.nTurbines/25)))
28112789

28122790
ax.set_xlabel("x [m]", fontsize=fontsize)
28132791
ax.set_ylabel("y [m]", fontsize=fontsize)

openfast_toolbox/fastfarm/TurbSimCaseCreation.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def discretization(self):
108108
if self.boxType == 'lowres':
109109
self._discretization_lowres()
110110
elif self.boxType == 'highres':
111-
self._discretization_higres()
111+
self._discretization_highres()
112112
else:
113113
raise ValueError("boxType can only be 'lowres' or 'highres'. Stopping.")
114114

@@ -126,17 +126,21 @@ def _discretization_lowres(self):
126126

127127
self.dy = np.floor(self.ds_low/self.ds_high)*self.ds_high
128128
self.dz = np.floor(self.ds_low/self.ds_high)*self.ds_high
129+
self.dt = self.dt_low
129130

130131
def _discretization_highres(self):
131132

132133
# Temporal resolution for high-res
133-
self.dt_high = 1.0/(2.0*self.fmax)
134+
if self.dt_high is None:
135+
self.dt_high = 1.0/(2.0*self.fmax)
134136

135137
# Spatial resolution for high-res
136138
if self.ds_high is None:
137139
self.ds_high = self.cmax
140+
138141
self.dy = self.ds_high
139142
self.dz = self.ds_high
143+
self.dt = self.dt_high
140144

141145

142146
def domainSize(self, zbot):

0 commit comments

Comments
 (0)