Repository navigation
LARGe FARM setup using openfast toolbox #76
Description
Activity
Hi Frederico,
To answer your question on the OpenFAST repository (although I think you already figured it out): the workflow is not to use your inp to generate your fstf. The workflow is to use the python-based specification of your farm and atmospheric conditions, and the toolbox will generate TurbSim input files or AMR-Wind sampling input file (depending on what was requested), as well as all the FAST.Farm input files needed. Some settings in the fstf are only active depending on the choice of other variables. This is usually indicated as comments and you if such part is not used, then the values on the fstf do not matter. You are correct that if
Mod_AmbWindis1(meaning VTK inflow), then the lines 20-34 are not used, but rather 15-18.I will take a look at your input and try to reproduce your issue now.
Reacted by fbelli997I had to modify your input to be able to run since not all files were provided. Unclear where exactly it stopped, as the last information printed is about the FFfilename. I'm not able to reproduce it using https://github.com/OpenFAST/openfast_toolbox/blob/main/data/IEA15MW/FF.fstf as a starting point. It could be stopping at the libdiscon or on other places. Can you provide a self-contained example that is able to reproduce the issue at hand?
Dear rthedin,
If I understand correctly, you are asking me to provide you the "template_toolbox_folder" to run my input file, right?
these are the zip folders including all the files I'm currently using in the .py:template_for_toolbox.zip
LARGE_FARM_SampleFiles.zipLet me know whether it is enough to run it.
Thank you in advance for your help,Best regards,
FedericoThanks for the files. I was able to reproduce it with a few small changes to your input.
The issue is on the format of MoorDyn, and how the toolbox parses tables. On your input, you have under
POINTSthe following line:ID Type X Y Z M V CdA CAFor this toolbox, the
Typeentry means it will know how many lines are to be read, based on the a priori reading ofNTypesorNConnects, as correctly indicated in the error message. The header above is typical of MoorDyn v1, which does have theNConnectsvalue:
---------------------- POINT PROPERTIES ----------------------------------------------------- 12 NConnects - number of connections including anchors and fairleads Node Type X Y Z M V FX FY FZ CdA Ca However, on MoorDyn v2, the length of the tables are not known ahead of time, and it is handled as it should by the toolbox. Since it does not have
Typeon the header, it reads as it goes, not expecting to know the length. This is how a MoorDyn v2 considered by the toolbox looks like:
---------------------- POINTS -------------------------------- ID Attachment X Y Z M V CdA CA Now, the problem is that you somehow mixed and matched inputs from different versions of MoorDyn. You have:
---------------------- POINTS -------------------------------- ID Type X Y Z M V CdA CAwhich means
IDfrom MoorDyn v2, butTypefrom MoorDyn v1. As you can now see, theType/Attachmentdifference is problematic. The behavior considered by this toolbox is consistent with the documentation for MoorDyn and inputs, as given here.When it can't read, there is a hook for pdb, which is what you see printed on your error message.
openfast_toolbox/openfast_toolbox/io/fast_input_file.py
Lines 846 to 849 in d34b283
try: d['value'], d['tabColumnNames'], d['tabUnits'] = parseFASTNumTable(self.filename,lines[i:i+nTabLines+nHeaders+nOffset],nTabLines,i, nHeaders, tableType=tab_type, nOffset=nOffset, varNumLines=d['tabDimVar']) except: import pdb; pdb.set_trace() No fix is required on the toolbox. You have an issue on your input file. If you replace "Type" with "Attachment" on line 9 of your MoorDyn input file, it will work as expected.
Finally, a couple of notes on your input deck:
-
You requested
PotMod1 on HydroDyn but did not give thehydroDataPathon the templates. I have now added a check for that. If you requestPotMod 1, you have to give the hydro data. I changedPotModto 0 on your inputs since I do not have your hydroData files. (you can get the latest version with the additional checks on FF: Add AMReX support #77) -
In your fst file, you have
CompSeaState, and not the correctCompSeaSt. Similar forSeaStateFileandSeaStFile. The toolbox will crash and tell you that.
-
Dear rthedin,
Thank you very much for your feedback, I'll try to fix my files and run again the toolbox. I'll let you know as soon as possible.
Kind regards,
FedericoDear rthedin,
It looks like I succesfully generated most of the files requested for a FASTfarm simulation, however, i still receive this error:
[ OK ] All OpenFAST files were copied successfully. Traceback (most recent call last): File "c:\Users\fbell\openfast_toolbox\openfast_toolbox\fastfarm\examples\LARGE_FARM_FASTFarm_LES_driven.py", line 288, in <module> amr, ffcase = main(test=False) ^^^^^^^^^^^^^^^^ File "c:\Users\fbell\openfast_toolbox\openfast_toolbox\fastfarm\examples\LARGE_FARM_FASTFarm_LES_driven.py", line 273, in main ffcase.FF_setup() # Write FAST.Farm input files ^^^^^^^^^^^^^^^^^ File "c:\users\fbell\openfast_toolbox\openfast_toolbox\fastfarm\FASTFarmCaseCreation.py", line 2666, in FF_setup self._FF_setup_LES(**kwargs) File "c:\users\fbell\openfast_toolbox\openfast_toolbox\fastfarm\FASTFarmCaseCreation.py", line 2726, in _FF_setup_LES self._symlink(src, dst) File "c:\users\fbell\openfast_toolbox\openfast_toolbox\fastfarm\FASTFarmCaseCreation.py", line 929, in _symlink raise Exception(error) Exception: Src file not found: /full/path/to/LES/case/.../LESboxes\LowIt seems like he is looking for the precursor vtk files, is that correct?
Actually I don't still have them since I haven't run the LES yet.
However, I successfully generated this file:FF_boxes.i
including all the informations of the LES box.
Should my next step be running the LES simulation using AMR-wind, right?
Then, once the VTK files are available, should I place them in the LESboxes\Low (and corresponding high-resolution) folders and run LARGE_FARM_FASTFarm_LES_driven.py again to generate the remaining files? Is that correct?This workflow seems a bit unusual to me, so I just want to make sure I am understanding it correctly.
Thanks in advance.
Kind regards,
Federico
You did not paste the entire message log given. The first few lines should have
[WARN] The LES path <path> does not exist, which gets triggered on these lines:
openfast_toolbox/openfast_toolbox/fastfarm/FASTFarmCaseCreation.py
Lines 750 to 752 in d34b283
for p in self.inflowPath: if not os.path.isdir(p): WARN(f'The LES path {p} does not exist')
The exception printed there gets triggered exactly when it can't find the path. The error message is correct and indicates it is unable to find source files. There is askipchecksoption on the constructor if you want to skip certain checks. Keep in mind, though, that since you are on a Windows machine, the toolbox will perform copies instead of symbolic links. Symbolic links are successfully created even though whatever they are pointing to does not exist. That is the reason we can use theskipchecks. With a Windows machine, theskipchecksmight not be super useful as you will still run into issues when it tries to copy a file that does not exist. I unfortunately do not have a Windows machine available to test/debug Windows-only issues.The input
FF_boxes.ishould be appended to your AMR-Wind input file, which, in turn, should have settings exactly like you setup on your example (prob_lo,prob_hi, etc). So yes, the next step is to run the AMR-Wind.The output of AMR-Wind will not be in VTK format. This option of VTK is code-agnostic, so you are able to run whatever LES code you prefer, and process the data into the correct VTK format. FAST.Farm requires a very specific file and directory convention for the VTK files, outlined here. So after the execution of AMR-Wind, you will need to read the data, format, save VTK, and re-arrange the directory structure as required by FAST.Farm.
There is an example SLURM script to process the AMR-Wind data in parallel on the repo, here. This script requires routines to read/process AMR-Wind data available in the
windtoolsrepository, so you will need to grab that too. After the VTK is saved, you will need to make sure the naming convention is correct following the link above. We have scripts to do it with symbolic links; however, as you're on Windows, you will need to rename them all.With all of that said, we have a very recent capability of directly using native AMReX data directly as outputted by AMR-Wind, skipping all this intermediate processing. That option is documented here and updated toolbox to handle it is currently PR #77.
Dear Rthedin,
I noticed that the
FF_boxes.ifile generated 48 different high-resolution domains, which I assume are computed independently. I was wondering whether it is really necessary to simulate all the high-resolution boxes for each turbine.Since with
ModAmbWind = 3I generate two.btsfiles, one for the high-resolution domain and one for the low-resolution domain, I was thinking that I could simply copy the high-resolution file and rename it for each turbine.Best regards,
FedericoThe high-res boxes are used for aero-servo-elastic computation. If you give the very same one, all the turbines are seeing the same background field plus whatever wake there might be exist. If there is no wake, all turbines responses would be exactly the same. You absolutely need these boxes to be different. The background turbulence on the low- and high-res need to match. Which is why on TurbSim runs you run first the low-res, extract time-series exactly where your turbine is, and the re-run TurbSim in constrained turbulence mode.
Dear Rthedin,
I generated the inflow field with AMR-Wind using a fixed time step of 0.1 s. From the OpenFAST toolbox, I obtained sampling frequencies of 0.3 and 0.9 for the high- and low-resolution precursor wind domains, respectively.
After generating the wind in native binary files, I post-processed all of them into VTK format, and the folder containing all the files has a size of 38 GB for 10 minutes of wind.
I successfully ran FAST.Farm, and the results seem correct.
Now, considering moving ahead to the 48-wind-turbine farm case, I was thinking of running at least 1800 s of simulation and discarding the first 600 s. Do you think this is enough to let the wake develop properly, or should I consider simulating at least 3600 s instead?
Moreover, do you think that the size of the VTK folder will be around 48 times larger than the case I am currently considering? Taking into account:
3 turbines instead of 48 (16 times more)
1800 s instead of 600 s (3 times more)
I was expecting something smaller in terms of the size of the VTK precursor. Does this align with previous simulations you have run?
Best regards,
FedericoThe VTK approach is indeed a very disk-intensive operation. One way to reduce the disk is the number of significant digits that are printed to the actual ASCII-based VTK file-- that is something I regularly do and would recommend. The scaling is not perfectly linear because there is only one low-res and that will have a different size if you have more turbines. You can use a linear scaling for the high-res. You would also have to check if that 30GB are coming mostly from low- or high-res to get a better estimate.
Dear Rthedin,
One more question regarding the "max_level" parameter set on the spinup and precursor wind. In AMR wind I set max_level = 0 and grid spacing = 20 for the low resolution domain and 5 for the high resolution domain.
Is that correct? or should I set max_level = 2 to effectively get the refinment on the mesh during the AMR-wind precursor simulation?I leave you the precursor wind I run here below for having a nice feedback.
`#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨#
SIMULATION CONTROL
#.......................................#
time.stop_time = 4200.0 # Production: spin-up (3600s) + 1 hour sampling [s]
time.max_step = -1 # Max number of time steps; -1 means termination set by timestamps
time.fixed_dt = 0.1 # Use this constant dt if > 0
time.cfl = 0.95 # CFL factor, will produce warnings if exceeded using fixed_dttime.plot_interval = 20 # Steps between plot files
time.checkpoint_interval = 20 # Steps between checkpoint files
ABL.bndry_file = bndry_file.native
ABL.bndry_io_mode = 0 # 0 = write, 1 = read
ABL.bndry_planes = xlo
ABL.bndry_output_start_time = 3600
ABL.bndry_var_names = velocity temperature tkeincflo.physics = ABL
io.restart_file = ../spinup/chk07200
turbulence.model = OneEqKsgsM84 # For neutral ABL, use "Smagorinsky"
TKE.source_terms = KsgsM84Src
incflo.gravity = 0. 0. -9.81 # Gravitational force (3D)
incflo.density = 1.225 # Reference density; make sure this agrees with OpenFAST values
transport.viscosity = 1.0e-5 # Dynamic viscosity [N-s/m^2]
transport.laminar_prandtl = 0.7
transport.turbulent_prandtl = 0.3333
transport.reference_temperature = 290#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨#
GEOMETRY & BCs
#.......................................#
geometry.prob_lo = 0.0 0.0 0.0
geometry.prob_hi = 5120.0 2560.0 1280.0
amr.n_cell = 256 128 64
amr.max_level = 0 # Max AMR level in hierarchy
geometry.is_periodic = 1 1 0 # Periodicity x y z (0/1)zlo.type = wall_model
zhi.type = slip_wall
zhi.temperature_type = fixed_gradient
zhi.temperature = 0.003#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨#
PHYSICS
#.......................................#
ICNS.source_terms = BoussinesqBuoyancy CoriolisForcing ABLForcing
incflo.velocity = 8.0 0.0 0.0
ABLForcing.abl_forcing_height = 155
CoriolisForcing.latitude = 36.607322 # Southern Great Plains
CoriolisForcing.north_vector = 0.0 1.0 0.0
CoriolisForcing.east_vector = 1.0 0.0 0.0
ABL.temperature_heights = 0.0 600.0 700.0 1700.0 # Make sure top height >= the domain height
ABL.temperature_values = 290.0 290.0 298.0 301.0
ABL.perturb_temperature = true
ABL.cutoff_height = 50.0
ABL.perturb_velocity = true
ABL.perturb_ref_height = 50.0
ABL.Uperiods = 4.0
ABL.Vperiods = 4.0
ABL.deltaU = 1.0
ABL.deltaV = 1.0
ABL.kappa = .40
ABL.surface_roughness_z0 = 0.01 # [m]
ABL.surface_temp_flux = 0.05 # Surface temperature flux [K-m/s]#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨#
POST-Processing
#.......................................#
Sampling info generated by AMRWindSamplingCreation.py on 2026-03-27 16:44:34
incflo.post_processing = box_lr box_hr # averaging
---- Low-res sampling parameters ----
box_lr.output_format = netcdf
box_lr.output_frequency = 9
box_lr.fields = velocity
box_lr.labels = LowLow sampling grid spacing = 25.0 m
box_lr.Low.type = PlaneSampler
box_lr.Low.num_points = 184 59
box_lr.Low.origin = 65.0000 265.0000 10.0000
box_lr.Low.axis1 = 4575.0000 0.0 0.0
box_lr.Low.axis2 = 0.0 1450.0000 0.0
box_lr.Low.offset_vector = 0.0 0.0 1.0
box_lr.Low.offsets = 0.0 25.0 50.0 75.0 100.0 125.0 150.0 175.0 200.0 225.0 250.0 275.0 300.0 325.0 350.0 375.0 400.0 425.0 450.0 475.0 500.0 525.0 550.0 575.0 600.0 625.0 650.0 675.0 700.0 725.0 750.0---- High-res sampling parameters ----
box_hr.output_format = native
box_hr.output_frequency = 3
box_hr.fields = velocity
box_hr.labels = HighT1_inflow0deg HighT2_inflow0deg HighT3_inflow0degTurbine T1 with base at (x,y,z) = (800.0000, 1000.0000, 0.0000), with hh = 150, D = 240, grid spacing = 5.0 m
box_hr.HighT1_inflow0deg.type = PlaneSampler
box_hr.HighT1_inflow0deg.num_points = 59 59
box_hr.HighT1_inflow0deg.origin = 652.5000 852.5000 2.5000
box_hr.HighT1_inflow0deg.axis1 = 290.0000 0.0 0.0
box_hr.HighT1_inflow0deg.axis2 = 0.0 290.0000 0.0
box_hr.HighT1_inflow0deg.offset_vector = 0.0 0.0 1.0
box_hr.HighT1_inflow0deg.offsets = 0.0 5.0 10.0 15.0 20.0 25.0 30.0 35.0 40.0 45.0 50.0 55.0 60.0 65.0 70.0 75.0 80.0 85.0 90.0 95.0 100.0 105.0 110.0 115.0 120.0 125.0 130.0 135.0 140.0 145.0 150.0 155.0 160.0 165.0 170.0 175.0 180.0 185.0 190.0 195.0 200.0 205.0 210.0 215.0 220.0 225.0 230.0 235.0 240.0 245.0 250.0 255.0 260.0 265.0 270.0 275.0 280.0 285.0 290.0 295.0Turbine T2 with base at (x,y,z) = (2000.0000, 1000.0000, 0.0000), with hh = 150, D = 240, grid spacing = 5.0 m
box_hr.HighT2_inflow0deg.type = PlaneSampler
box_hr.HighT2_inflow0deg.num_points = 59 59
box_hr.HighT2_inflow0deg.origin = 1852.5000 852.5000 2.5000
box_hr.HighT2_inflow0deg.axis1 = 290.0000 0.0 0.0
box_hr.HighT2_inflow0deg.axis2 = 0.0 290.0000 0.0
box_hr.HighT2_inflow0deg.offset_vector = 0.0 0.0 1.0
box_hr.HighT2_inflow0deg.offsets = 0.0 5.0 10.0 15.0 20.0 25.0 30.0 35.0 40.0 45.0 50.0 55.0 60.0 65.0 70.0 75.0 80.0 85.0 90.0 95.0 100.0 105.0 110.0 115.0 120.0 125.0 130.0 135.0 140.0 145.0 150.0 155.0 160.0 165.0 170.0 175.0 180.0 185.0 190.0 195.0 200.0 205.0 210.0 215.0 220.0 225.0 230.0 235.0 240.0 245.0 250.0 255.0 260.0 265.0 270.0 275.0 280.0 285.0 290.0 295.0Turbine T3 with base at (x,y,z) = (3200.0000, 1000.0000, 0.0000), with hh = 150, D = 240, grid spacing = 5.0 m
box_hr.HighT3_inflow0deg.type = PlaneSampler
box_hr.HighT3_inflow0deg.num_points = 59 59
box_hr.HighT3_inflow0deg.origin = 3052.5000 852.5000 2.5000
box_hr.HighT3_inflow0deg.axis1 = 290.0000 0.0 0.0
box_hr.HighT3_inflow0deg.axis2 = 0.0 290.0000 0.0
box_hr.HighT3_inflow0deg.offset_vector = 0.0 0.0 1.0
box_hr.HighT3_inflow0deg.offsets = 0.0 5.0 10.0 15.0 20.0 25.0 30.0 35.0 40.0 45.0 50.0 55.0 60.0 65.0 70.0 75.0 80.0 85.0 90.0 95.0 100.0 105.0 110.0 115.0 120.0 125.0 130.0 135.0 140.0 145.0 150.0 155.0 160.0 165.0 170.0 175.0 180.0 185.0 190.0 195.0 200.0 205.0 210.0 215.0 220.0 225.0 230.0 235.0 240.0 245.0 250.0 255.0 260.0 265.0 270.0 275.0 280.0 285.0 290.0 295.0
`Thank you in advance,
kind regards,
Federico
Dear all,
I would like to share with you the discussion I started on the openFAST repository.
OpenFAST/openfast#3245 (comment)
In this discussion I'm asking some information for the setup of AMR-wind and you suggested me to use this toolbox to having a good setup of all the files for the simulation.
I started using the 2 example as you suggested (Ex1FASTFarm_discretization and Ex3_AMRWindSamplingSetup) and then I moved forward modifying the EX2b_FASTFarm_LES_driven that you can find linked here below:
LARGE_FARM_FASTFarm_LES_driven.py
Actually, I'm receiving this message:
and it got stuck on this message.
am I doing something wrong?
Can you please check if the data I'm including in the python file are correct?
I'm open to any suggestion.
thank you in advance for you help,
kind regards,
Federico