Skip to content

Sg/floris interface - #17

Merged
skygering merged 53 commits into
masterfrom
sg/floris_interface
Aug 12, 2026
Merged

Sg/floris interface#17
skygering merged 53 commits into
masterfrom
sg/floris_interface

Conversation

@skygering

@skygering skygering commented Jan 8, 2026

Copy link
Copy Markdown
Contributor

You're making a pull request to a branch (probably main) of MITWindFarm. Please ensure you have done the following.

  • Request a review from other Howland Lab members who use MITWindFarm.
  • Add at least a sentence on your change to the documentation (probably the quickstart guide).
  • Add tests for your new functionality.
  • Make sure the tests pass and the documentation notebook still runs.
  • Get approval from the folks you requested a review from.

This is not ready to merge!! This is a draft of an interface for using MITRotor within FLORIS.

I have written the interface to include the following three function:

  • power
  • thrust_coefficent
  • axial_induction

The new user-defined rotor operation models, MITRotorTurbine, takes in the following optional arguments:

This follows the outline laid out in this branch of FLORIS and in this example within the branch.

The default rotor is the IEA 15 MW. The control right now is just a trajectory (based on wind speed) that is interpolated based on Figure 2 here. If a user wants to use a different turbine, they also need to provide two trajectory CSV files.

I have written a small test suite to confirm that the thrust coefficient and axial induction produced by FLORIS with MITRotor is nearly the same as just MITRotor by itself. I also checked that the leading turbine's power decreases with yaw (and second turbine's power increases if first turbine is yawed).

I also tried to compare with a plot from the IEA 15MW technical report. The below is figure 3-2 on page 20.
Screenshot 2026-01-07 at 7 44 18 PM

It seems like we are in the right ballpark, although the ranges of pitch and tsr don't really fully overlap for wind speeds run (between 5m/s and 25m/s).
Screenshot 2026-01-07 at 7 45 01 PM

I also plotted the interpolators for pitch and tsr that I created just to make sure that was looking alright. Compare to figure 2:
Screenshot 2026-01-07 at 7 49 53 PM

@skygering
skygering requested review from jaimeliew1 and removed request for jaimeliew1 January 8, 2026 00:23
@skygering
skygering marked this pull request as draft January 8, 2026 00:23
x = x[idx]
y = y[idx]
# return interpolator for y
return interp1d(x, y, kind="linear", fill_value="extrapolate", bounds_error=False) # TODO: should fill_value be extrapolate?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should fill_value be extrapolate?

# calculate rotor area
rotor_area = np.pi * self.bem_model.rotor.R**2

# loop over flow conditions -> TODO: should this be vectorized?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be vectorized?

pitch = np.deg2rad(self._pitch_interp(vel))
tsr = self._tsr_interp(vel)
# solve BEM
bem_sol = self.bem_model(pitch, tsr, yaw = yaw, tilt = tilt)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to limit or control the number of fixed point iterations?

@skygering

Copy link
Copy Markdown
Contributor Author

I improved my validation figures! The "Floris" lines are FLORIS used with the MITRotor interface.

example_5_pitch_tsr_interpolation example_5_IEA15mw_CT_CP

@skygering

Copy link
Copy Markdown
Contributor Author
example_5_IEA15mw_CT_CP

@misi9170

Copy link
Copy Markdown

Just a heads up that I made a few updates to the FLORIS branch that this works off, but I've rerun both your example and some integration tests on my side and everything is still working as it should be.

Regarding the failing tests: FLORIS no longer supports python version 3.9 as of FLORIS v4.6, as python 3.9 is now at end of life.

* Attempt at vecotization in pre-process

* Working through initial 2 turbine test

* Working with 10x speedup for rotor, 2x slowdown for annulus

* Vectorization working with Np as the first axis

* Fixed some tests with float input, but needs more work

* Updated example 6 to include LUT example

* Time vectorized code

* Fix example timing script

* All tests pass, other than new dimensional tests

* Vectorization complete

* Clean up BEM tests
@skygering

Copy link
Copy Markdown
Contributor Author

This PR is now done. It covers a lot of ground, including both an interface for FLORIS and ROSCO. It also adds in the LUT functionality. There are examples for all of these use cases and all existing tests run as well.

@skygering

Copy link
Copy Markdown
Contributor Author

Here are the outputs of the examples:

Example 6

In the first example, we are simply testing that MITRotor and FLORIS using MITRotor return the same values when using the same 1D control scheme.
example_6_IEA15mw_CT_CP
example_6_pitch_tsr_interpolation

Example 7

In this example, we are testing the timing and values generated by the LUT vs direct calculations. Note that the rotor-averaged and annulus-averaged have different values, but this has to do with averaging not the LUT.
example_7_floris_cp_vals
example_7_floris_runtimes

Example 8

Finally, in this example, ROSCO was used to create a 2D control scheme by wind speed and yaw. We can see the scheme and how they compare to the scheme in the ROSCO paper, as well as the C_T, C_P, and power both at zero and non-zero yaw.
example_8_IEA15mw_controls-4
example_8_IEA15mw_CT_CP-3
example_8_IEA15mw_CT_CP_yawed-5

@skygering
skygering marked this pull request as ready for review August 3, 2026 14:00
@skygering
skygering requested a review from iupfal August 7, 2026 15:12
@skygering

Copy link
Copy Markdown
Contributor Author

Note that this does not utilize MITRotor's BEM ability to account for sheer and veer. That can be added later.

@iupfal iupfal left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work comments here:

  1. Make FLORIS and ROSCO optional dependencies
  2. Add in test to make sure vectorized solve is the same as looped
  3. Note in code that BEM doesn't use sheer/veer
  4. ROSCO calculate misspelling

@skygering
skygering requested a review from iupfal August 11, 2026 21:37

@iupfal iupfal left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issues have been addressed

@skygering
skygering merged commit 132bff8 into master Aug 12, 2026
5 checks passed
@skygering
skygering deleted the sg/floris_interface branch August 12, 2026 10:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants