Skip to content
This repository was archived by the owner on Nov 27, 2023. It is now read-only.

Commit 4ed2a24

Browse files
committed
FF: Add mod_wake option and curled wake parameters
1 parent b3f6bb8 commit 4ed2a24

File tree

1 file changed

+28
-13
lines changed

1 file changed

+28
-13
lines changed

pyFAST/fastfarm/FASTFarmCaseCreation.py

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def getMultipleOf(val, multipleof):
2424

2525
class FFCaseCreation:
2626

27-
def __init__(self, path, wts, cmax, fmax, Cmeander, tmax, zbot, vhub, shear, TIvalue, inflow_deg, dt_high_les, ds_high_les, extent_high, dt_low_les, ds_low_les, extent_low, ffbin, yaw_init=None, ADmodel=None, EDmodel=None, nSeeds=6, LESpath=None, sweepWakeSteering=False, sweepYawMisalignment=False, seedValues=None, refTurb_rot=0, verbose=0):
27+
def __init__(self, path, wts, cmax, fmax, Cmeander, tmax, zbot, vhub, shear, TIvalue, inflow_deg, dt_high_les, ds_high_les, extent_high, dt_low_les, ds_low_les, extent_low, ffbin, mod_wake=1, yaw_init=None, ADmodel=None, EDmodel=None, nSeeds=6, LESpath=None, sweepWakeSteering=False, sweepYawMisalignment=False, seedValues=None, refTurb_rot=0, verbose=0):
2828
'''
2929
Full setup of a FAST.Farm simulations, can create setups for LES- or TurbSim-driven scenarios.
3030
@@ -56,6 +56,7 @@ def __init__(self, path, wts, cmax, fmax, Cmeander, tmax, zbot, vhub, shear, TIv
5656
self.extent_low = extent_low
5757
self.extent_high = extent_high
5858
self.ffbin = ffbin
59+
self.mod_wake = mod_wake
5960
self.yaw_init = yaw_init
6061
self.ADmodel = ADmodel
6162
self.EDmodel = EDmodel
@@ -153,7 +154,7 @@ def _checkInputs(self):
153154
# Check the ds and dt for the high- and low-res boxes
154155
if not (np.array(self.extent_low)>=0).all():
155156
raise ValueError(f'The array for low-res box extents should be given with positive values')
156-
if self.dt_low_les%(self.dt_high_les-1e-15) > 1e-14:
157+
if self.dt_low_les%(self.dt_high_les-1e-15) > 1e-12:
157158
raise ValueError(f'The temporal resolution dT_Low should be a multiple of dT_High')
158159
if self.dt_low_les < self.dt_high_les:
159160
raise ValueError(f'The temporal resolution dT_High should not be greater than dT_Low on the LES side')
@@ -208,6 +209,10 @@ def _checkInputs(self):
208209
if self.refTurb_rot >= self.nTurbines:
209210
raise ValueError(f'The index for the reference turbine for the farm to be rotated around is greater than the number of turbines')
210211

212+
# Check the wake model (1:Polar; 2:Curl; 3:Cartesian)
213+
if self.mod_wake not in [1,2,3]:
214+
raise ValueError(f'Wake model `mod_wake` should be 1 (Polar), 2 (Curl), or 3 (Cartesian). Received {self.mod_wake}.')
215+
211216
# Set aux variable
212217
self.templateFilesCreatedBool = False
213218
self.TSlowBoxFilesCreatedBool = False
@@ -1033,7 +1038,7 @@ def TS_high_get_time_series(self):
10331038
# Get indices of the half height position (TurbSim's hub height)
10341039
jMid, kMid = bts.iMid
10351040

1036-
# Get time series at the box center to get mean vhub and create time array. JJ: get at the Turbsim hub height
1041+
# Get time series at the box center to get mean vhub and create time array.
10371042
#Vhub = bts['u'][0,:,jTurb,kTurb]
10381043
Vmid = bts['u'][0,:,jMid,kMid]
10391044
time = bts.t
@@ -1234,9 +1239,9 @@ def FF_setup(self, outlistFF=None, **kwargs):
12341239
# "WkAxsXT1D1 , WkAxsXT1D2 , WkAxsXT1D3 , WkAxsXT1D4 , WkAxsXT1D5 , WkAxsXT1D6 , WkAxsXT1D7",
12351240
# "WkAxsYT1D1 , WkAxsYT1D2 , WkAxsYT1D3 , WkAxsYT1D4 , WkAxsYT1D5 , WkAxsYT1D6 , WkAxsYT1D7",
12361241
# "WkAxsZT1D1 , WkAxsZT1D2 , WkAxsZT1D3 , WkAxsZT1D4 , WkAxsZT1D5 , WkAxsZT1D6 , WkAxsZT1D7",
1237-
# "WkPosXT1D1 , WkPosXT1D2 , WkPosXT1D3 , WkPosXT1D4 , WkPosXT1D5 , WkPosXT1D6 , WkPosXT1D7",
1238-
# "WkPosYT1D1 , WkPosYT1D2 , WkPosYT1D3 , WkPosYT1D4 , WkPosYT1D5 , WkPosYT1D6 , WkPosYT1D7",
1239-
# "WkPosZT1D1 , WkPosZT1D2 , WkPosZT1D3 , WkPosZT1D4 , WkPosZT1D5 , WkPosZT1D6 , WkPosZT1D7",
1242+
"WkPosXT1D1 , WkPosXT1D2 , WkPosXT1D3 , WkPosXT1D4 , WkPosXT1D5 , WkPosXT1D6 , WkPosXT1D7 , WkPosXT1D8 , WkPosXT1D9",
1243+
"WkPosYT1D1 , WkPosYT1D2 , WkPosYT1D3 , WkPosYT1D4 , WkPosYT1D5 , WkPosYT1D6 , WkPosYT1D7 , WkPosYT1D8 , WkPosYT1D9",
1244+
"WkPosZT1D1 , WkPosZT1D2 , WkPosZT1D3 , WkPosZT1D4 , WkPosZT1D5 , WkPosZT1D6 , WkPosZT1D7 , WkPosZT1D8 , WkPosZT1D9",
12401245
# "WkDfVxT1N01D1, WkDfVxT1N02D1, WkDfVxT1N03D1, WkDfVxT1N04D1, WkDfVxT1N05D1, WkDfVxT1N06D1, WkDfVxT1N07D1, WkDfVxT1N08D1, WkDfVxT1N09D1, WkDfVxT1N10D1, WkDfVxT1N11D1, WkDfVxT1N12D1, WkDfVxT1N13D1, WkDfVxT1N14D1, WkDfVxT1N15D1, WkDfVxT1N16D1, WkDfVxT1N17D1, WkDfVxT1N18D1, WkDfVxT1N19D1, WkDfVxT1N20D1",
12411246
# "WkDfVxT1N01D2, WkDfVxT1N02D2, WkDfVxT1N03D2, WkDfVxT1N04D2, WkDfVxT1N05D2, WkDfVxT1N06D2, WkDfVxT1N07D2, WkDfVxT1N08D2, WkDfVxT1N09D2, WkDfVxT1N10D2, WkDfVxT1N11D2, WkDfVxT1N12D2, WkDfVxT1N13D2, WkDfVxT1N14D2, WkDfVxT1N15D2, WkDfVxT1N16D2, WkDfVxT1N17D2, WkDfVxT1N18D2, WkDfVxT1N19D2, WkDfVxT1N20D2",
12421247
# "WkDfVxT1N01D3, WkDfVxT1N02D3, WkDfVxT1N03D3, WkDfVxT1N04D3, WkDfVxT1N05D3, WkDfVxT1N06D3, WkDfVxT1N07D3, WkDfVxT1N08D3, WkDfVxT1N09D3, WkDfVxT1N10D3, WkDfVxT1N11D3, WkDfVxT1N12D3, WkDfVxT1N13D3, WkDfVxT1N14D3, WkDfVxT1N15D3, WkDfVxT1N16D3, WkDfVxT1N17D3, WkDfVxT1N18D3, WkDfVxT1N19D3, WkDfVxT1N20D3",
@@ -1385,8 +1390,13 @@ def _FF_setup_LES(self, seedsToKeep=1):
13851390
ff_file['SC_FileName'] = '/path/to/SC_DLL.dll'
13861391

13871392
# Wake dynamics
1388-
ff_file['dr'] = self.cmax
1389-
ff_file['NumRadii'] = int(np.ceil(3*D_/(2*self.cmax) + 1))
1393+
ff_file['Mod_Wake'] = self.mod_wake
1394+
if self.mod_wake == 1: # Polar model
1395+
self.dr = self.cmax
1396+
else: # Curled; Cartesian
1397+
self.dr = round(self.D/10)
1398+
ff_file['dr'] = self.dr
1399+
ff_file['NumRadii'] = int(np.ceil(3*D_/(2*self.dr) + 1))
13901400
ff_file['NumPlanes'] = int(np.ceil( 20*D_/(self.dt_low_les*Vhub_*(1-1/6)) ) )
13911401

13921402
# Vizualization outputs
@@ -1457,7 +1467,7 @@ def _FF_setup_TS(self):
14571467

14581468
# Open saved file and change additional values manually or make sure we have the correct ones
14591469
ff_file = FASTInputFile(outputFSTF)
1460-
ff_file['InflowFile'] = f'"../{self.IWfilename}"' #!!!!!!!! this path is not filled. should it be?
1470+
ff_file['InflowFile'] = f'"../{self.IWfilename}"'
14611471
#ff_file['DT']=1.0
14621472
ff_file['Mod_AmbWind'] = 3 # 1: LES boxes; 2: single TurbSim; 3: multiple TurbSim
14631473
ff_file['TMax'] = self.tmax
@@ -1466,9 +1476,14 @@ def _FF_setup_TS(self):
14661476
ff_file['UseSC'] = False
14671477
ff_file['SC_FileName'] = '/path/to/SC_DLL.dll'
14681478

1469-
# Wake dynamics # !!!!!!!!!!!!!!!!!!!!!! are these values good? (Emmanuel's sample file had 3, 50, 80. KS had 5, 75, 80)
1470-
ff_file['dr'] = self.cmax
1471-
ff_file['NumRadii'] = int(np.ceil(3*D_/(2*self.cmax) + 1))
1479+
# Wake dynamics
1480+
ff_file['Mod_Wake'] = self.mod_wake
1481+
if self.mod_wake == 1: # Polar model
1482+
self.dr = self.cmax
1483+
else: # Curled; Cartesian
1484+
self.dr = round(self.D/10)
1485+
ff_file['dr'] = self.dr
1486+
ff_file['NumRadii'] = int(np.ceil(3*D_/(2*self.dr) + 1))
14721487
ff_file['NumPlanes'] = int(np.ceil( 20*D_/(dt_low_desired*Vhub_*(1-1/6)) ) )
14731488

14741489
# Vizualization outputs
@@ -1484,7 +1499,7 @@ def _FF_setup_TS(self):
14841499
# Modify wake outputs
14851500
ff_file['NOutDist'] = 7
14861501
ff_file['OutDist'] = ' '.join(map(str, [1,1.5,2,2.5,3,3.5,4]*D_))
1487-
# Mofidy wind output # !!!!! JJ why only 9?
1502+
# Mofidy wind output
14881503
ff_file['NWindVel'] = 9
14891504
ff_file['WindVelX'] = ' '.join(map(str, xWT[:9]))
14901505
ff_file['WindVelY'] = ' '.join(map(str, yWT[:9]))

0 commit comments

Comments
 (0)