NREL / ROSCO_toolbox

A repository for generating ROSCO controller input files and more.
http://rosco-toolbox.readthedocs.io/
Apache License 2.0
23 stars 20 forks source link

DTU 10MW RWT tuning failed #39

Open Christophe-delFosse opened 3 years ago

Christophe-delFosse commented 3 years ago

Dear all,

I am using the DTU 10MW RWT with input files from https://rwt.windenergy.dtu.dk/dtu10mw/dtu-10mw-rwt/-/tree/master/aeroelastic_models/fast/DTU10MWRWT_FAST_v1.00/ReferenceModal that I adapted to be compatible with OpenFAST. I also use the ROSCO controller to run my simulations. The DTU 10MW RWT requires a rotor speed between 6 rpm and 9.6 rpm, but by running my simulations the rotor speed got lower than 6 rpm and consequently the third harmonics of the rotorspeed started to coincide with the tower natural frequency. I wanted to use ROSCO toolbox (develop branch) to tune the controller such that I can avoid this low rotor speed, but I have problems running 'tune_ROSCO.py'. For the NREL 5MW turbine it runs fine, but when I run it for the DTU 10MW RWT I get the following error:

(rosco-env) PS C:\Users\chris\ROSCO_toolbox\Tune_Cases> python tune_ROSCO.py

Loading wind turbine data for NREL's ROSCO tuning and simulation processeses

Loading FAST model: DTU_10MW_RWT.fst Traceback (most recent call last): File "tune_ROSCO.py", line 43, in turbine.load_from_fast(path_params['FAST_InputFile'], \ File "C:\Users\chris\anaconda3\envs\rosco-env\lib\site-packages\rosco_toolbox-2.1.0-py3.8.egg\ROSCO_toolbox\turbine.py", line 169, in load_from_fast fast.execute() File "C:\Users\chris\anaconda3\envs\rosco-env\lib\site-packages\rosco_toolbox-2.1.0-py3.8.egg\ROSCO_toolbox\ofTools\fast_io\FAST_reader.py", line 410, in execute self.read_AeroDyn14() File "C:\Users\chris\anaconda3\envs\rosco-env\lib\site-packages\rosco_toolbox-2.1.0-py3.8.egg\ROSCO_toolbox\ofTools\fast_io\FAST_reader.py", line 967, in read_AeroDyn14 for i in range(self.fst_vt['AeroDynBlade']['NumFoil']): KeyError: 'NumFoil'

I edited the following lines in FAST_reader.py: Line 967 for i in range(self.fst_vt['AeroDynBlade']['NumFoil']): Line 967 for i in range(self.fst_vt['AeroDyn14']['NumFoil']): Line 976 ad_tower_file = os.path.join(self.FAST_directory, self.fst_vt['aerodyn']['TwrFile']) Line 976 ad_tower_file = os.path.join(self.FAST_directory, self.fst_vt['AeroDyn14']['TwrFile'])

But then I run into the following error:

(rosco-env) PS C:\Users\chris\ROSCO_toolbox\Tune_Cases> python tune_ROSCO.py

Loading wind turbine data for NREL's ROSCO tuning and simulation processeses

Loading FAST model: DTU_10MW_RWT.fst Loading rotor performace data from text file: D:\OpenFAST_DTU_10MW_RWT\DAT_files\Cp_Ct_Cq.DTU10MW.txt Unable to import mpi4py. Parallel processing unavailable. Unable to import petsc4py. Parallel processing unavailable. Unable to import petsc4py. Parallel processing unavailable. WARNING: Be sure to pip install simpy and marmot-agents for offshore BOS runs Traceback (most recent call last): File "tune_ROSCO.py", line 43, in turbine.load_from_fast(path_params['FAST_InputFile'], \ File "C:\Users\chris\anaconda3\envs\rosco-env\lib\site-packages\rosco_toolbox-2.1.0-py3.8.egg\ROSCO_toolbox\turbine.py", line 204, in load_from_fast self.load_blade_info() File "C:\Users\chris\anaconda3\envs\rosco-env\lib\site-packages\rosco_toolbox-2.1.0-py3.8.egg\ROSCO_toolbox\turbine.py", line 506, in load_blade_info r0 = np.array(self.fast.fst_vt['AeroDynBlade']['BlSpn']) KeyError: 'BlSpn'

Is it possible that the ROSCO toolbox is not compatible with AeroDyn v14? Can someone please help me with this issue?

Thank you in advance!

Sincerely, Christophe

dzalkind commented 3 years ago

Hi Christophe,

We try to keep up to date with the latest release of OpenFAST. Currently, the ROSCO_toolbox is compatible with OpenFAST v2.5.0 and I'm not sure how much AeroDyn v14 is supported anymore. There don't seem to be many (or any) reg-tests using it.

I have tried in the past to read in AeroDyn v14 files, but did not have much success. I ended up converting the files manually to v15. So, the short answer to your question is that I don't think we support AeroDyn v15 in the ROSCO toolbox :-)

If you're looking for a similar model to the DTU 10 MW, I have heard that this is an updated version: https://github.com/IEAWindTask37/IEA-10.0-198-RWT/tree/master/openfast. I have used this model with the ROSCO toolbox.

Best, Dan

nikhar-abbas commented 3 years ago

@Christophe-delFosse,

Wanted to check in - did this get sorted? Will close the issue if so.

Thanks, Nikhar

Christophe-delFosse commented 3 years ago

Dear @nikhar-abbas

I was not able to convert the AeroDyn v14 files to AeroDyn v15 for the DTU 10 MW RWT. Using the IEA 10 MW RWT (updated version of DTU 10 MW RWT) is not an option for my research subject. Is there any way I could still use ROSCO toolbox to tune the DTU 10 MW RWT with AeroDyn v14 input files?

One problem with the DTU 10 MW RWT input file to ROSCO that is available in the parameter_files folder of ROSCO was that the rotor speed went below the allowed range of 6-9.6 rpm. I changed line 57 of the DISCON.IN input file as follows:

old: 17.96935000000 ! VS_MinOMSpd - Optimal mode minimum speed, cut-in speed towards optimal mode gain path, [rad/s]

new: 31.41592654000 ! VS_MinOMSpd - Optimal mode minimum speed, cut-in speed towards optimal mode gain path, [rad/s]

This allowed me to limit the rotor speed to values above 6 rpm and avoid problems with natural frequencies. However, I'm not sure if this is a good approach. How was the DISCON.IN file in ROSCO/parameter_files/DTU10MW/ created? Did you use an AeroDyn v15 input file for the DTU 10MW RWT? Could you help me to run ROSCO toolbox for this turbine please?

Thank you in advance!

Best Christophe

nikhar-abbas commented 3 years ago

Hi Christophe, Okay, the issue might be rooted in the fact that the AeroDyn14 files do not contain all of the information needed to run cc-blade. Fortunately, we already have the rotor performance tables for the DTU10MW here.

So, something that might work is to simple comment out the line in which the blade information is loaded in load_from_fast, here: https://github.com/NREL/ROSCO_toolbox/blob/8ac261d15354dcbdfa645af75a74de29a23c55a6/ROSCO_toolbox/turbine.py#L204.

When you do this, please make sure that you are appropriately pointing to the Cp_Ct_Cq.DTU10MW.txt file when you run load_from_fast, and that you specify rot_source='txt' so that the script does not try to run cc-blade.

As far as the minimum rotor speed is concerned, this is simply because of an error when initializing the tuning process. The vs_minspd parameter should be defined here.

Hopefully this fixes things - let me know.

Cheers, Nikhar

Christophe-delFosse commented 3 years ago

Thank you! It works now.

Christophe-delFosse commented 3 years ago

Dear @nikhar-abbas

When I'm tuning the ROSCO controller for the DTU 10 MW RWT, I now get the following warnings:

C:\Users\chris\anaconda3\lib\site-packages\rosco_toolbox-2.2.0-py3.7.egg\ROSCO_toolbox\controller.py:562: RuntimeWarning: divide by zero encountered in true_divide self.Kp = 1/B (2zeta*om_n + A) C:\Users\chris\anaconda3\lib\site-packages\rosco_toolbox-2.2.0-py3.7.egg\ROSCO_toolbox\controller.py:563: RuntimeWarning: divide by zero encountered in true_divide self.Ki = om_n**2/B Writing new controller parameter file parameter file: DISCON.IN.

In the DISCON.IN file I get 'Inf' values for PC_GS_KP and PC_GS_KI. What could be the cause of this issue?

Sincerely, Christophe

Christophe-delFosse commented 3 years ago

Dear @nikhar-abbas ,

I set the minimal rotor speed to 6 rpm and ran a simulation with turbulent inflow generated by TurbSim (NTM, class A). What I see is that the rotor speed often goes below 6 rpm (see figure below). Is there a way to tune the ROSCO controller to strictly avoid going below 6 rpm? I want to achieve this because for lower rotorspeeds, the rotor frequency harmonics get closer to the tower natural frequency, which triggers high peaks in the tower base side-side moment (see figure below) and the tower base fore-aft moment. This in turn leads to an overestimation of the tower damage equivalent loads (see figure below).

rotorspeed_timeseries

TwrBsSS_timeseries

DEL_validation

Thank you in advance for your help!

Sincerely, Christophe

nikhar-abbas commented 3 years ago

Hi Christophe, This looks like it might be related to the specific tuning of ROSCO. The provided input files for the DTU10MW were not tested in specific relation to the standard DTU controller, just simply tuned to something that might work and provide a starting point.

I would suggest updating some of the tuning values, particularly the pc_omega, pc_zeta,vs_omega, andvs_zetato try to achieve better results here. Note thatvs_omegaandvs_zetawill only change things in below rated operation ifVS_ControlMode=2/3`.

As far as the dips below the minimum rotor speed are concerned, increasing vs_omega might help that a little bit. The minimum rotor speed is enforced by a lower bound on the reference rotor speed reference error for either the TSR tracking controller or region 1.5 PI controller (here: https://github.com/NREL/ROSCO/blob/e53ff37a50ced633873a324386f279404953fe52/src/ReadSetParameters.f90#L274). So, this is of course subject to turbine dynamics and the speed at which the pitch controller is reacting.

Cheers, Nikhar

dzalkind commented 3 years ago

Christophe,

You could also try increasing the minimum rotor speed above 6 rpm to something like 6.25 rpm to make sure it doesn't dip below 6 rpm. The rotor speed can't be perfectly regulated to the minimum speed in turbulence.

Also, be sure to remove startup transients from your DEL calculations.

Dan

Christophe-delFosse commented 3 years ago

Dear @nikhar-abbas and @dzalkind,

I understand that tuning the omega and zeta values will help to limit the rotor speed to 6 rpm. However, I am also concerned about the higher windspeeds, because the tower lifetime fatigue loads are also way higher than the reference values form the DTU report there. The comparison of lifetime fatigue loads is based on Design Load Case DLC 1.2 from the IEC 61400-1 standard. For every simulation of 1200 seconds, I remove the 600 seconds start-up transient and keep 600 seconds of valuable simulation time to calculate fatigue loads.

Do you think that using another controller like the DRC_Fortran baseline controller from https://github.com/TUDelft-DataDrivenControl/DRC_Fortran will significantly reduce the tower fatigue loads? Or does changing the controller only have minor influence on the fatigue loads?

Thank you for your help!

Sincerely, Christophe

dzalkind commented 3 years ago

Christophe,

Typically, when there are large discrepancies between loads, like you are seeing, we compare the timeseries. Then, you can start to pinpoint the differences between the DELs, whether they are modeling differences (like using HAWC2 vs. OpenFAST) or control differences (DTU controller vs. ROSCO). It's hard to pinpoint these differences from a single aggregated metric like DELs. If you want to compare to the DTU 10MW report, it might be good to reproduce their results.

Side-to-side tower loads are largely driven by an overlap in the tower natural frequency and rotor period (1P or 3P). I don't think that the DRC_Fortran controller has any speed avoidance control. ROSCO is largely based on the DRC_Fortran controller and has more features. The DTU controller may have some frequency avoidance.

If you're interested in controls and this issue of frequency avoidance, I'd start here by altering the torque control set points to avoid certain generator speeds: https://github.com/NREL/ROSCO/blob/e53ff37a50ced633873a324386f279404953fe52/src/ReadSetParameters.f90#L254

I hope this helps.

Best, Dan

Christophe-delFosse commented 3 years ago

Dear @dzalkind,

Thank you for your response. I have one more question on the ROSCO controller tuning. I see that below rated wind speeds there is no pitching. This results in a difference with the basic DTU wind energy controller as shown in the figures below: pitch_wsp rpm_wsp How can I tune the ROSCO controller in such a way that the pitching below rated wind speeds is similar to the basic DTU wind energy controller and that the rotor speed also matches the one from the basic controller?

Sincerely, Christophe

rdamiani commented 3 years ago

Folks, vs_minspd: 104.5 # Minimum rotor speed [rad/s], seems to point to rotor minimum speed. However, you are then comparing to generator speed in controller.py if self.vs_minspd: self.vs_minspd = np.maximum(self.vs_minspd, (turbine.TSR_operational * turbine.v_min / turbine.rotor_radius) * Ng) else: self.vs_minspd = (turbine.TSR_operational * turbine.v_min / turbine.rotor_radius) * Ng self.pc_minspd = self.vs_minspd

So to me it looks like vs_minspd should be generator minimum speed.