Skip to content

Sg/kl model dev#31

Merged
skygering merged 19 commits intokl-model-devfrom
sg/kl-model-dev
Oct 30, 2025
Merged

Sg/kl model dev#31
skygering merged 19 commits intokl-model-devfrom
sg/kl-model-dev

Conversation

@skygering
Copy link
Copy Markdown
Contributor

@skygering skygering commented Oct 15, 2025

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.

If you want more details on best practices, please see the following guide on the Howland Lab Google Drive.

Happy merging!


This PR adds tilt into the k-l model as implemented by @kirbyh. I am opening a PR into the existing kl-dev branch so that it is obvious what is changed from his implementation. When just opening a PR into the main branch, it is much harder to see what the actual changes are.

The changes I made are as follows:

  • For the example, I added a x-z slice to the existing plot and plotted a y-z cross section so that the curled-wake shape is obvious. See images below.
Screenshot 2025-10-15 at 5 23 07 PM Screenshot 2025-10-15 at 5 23 38 PM
  • The actual code changes needed to implement these changes is in CurledWake.py. The big idea is that I put the column of vortices on the z-axis in the "yaw-only" frame and then I rotated it back into the ground frame and used the y and z locations of that rotated line as the vortex positions.
  • I also updated the plotting script so that we can also plot any slice of data. It still defaults to a x-y slice, but the user can pass in one of x, y, or z and it will slice at the provided value.
  • I then had to update your new rotor models to take in tilt. I added in pre_processing calls to the super function. I also updated the UMM code base (see this PR first) slightly for needed function.
  • Finally, I added in tests that ensure that tilt and yaw + tilt are simply just rotated versions of the yaw code and that the UMM rotor models differ with TI and don't differ without TI.

I am also trying to get non-zero TI slices of yawed and tilted turbines to make a nice figure of LES compared to MITWindfarm.

Comment thread mitwindfarm/CurledWake.py
Gamma_0 = 0.5 * D * rotor.REWS * rotor.Ct * np.sin(eff_yaw)
Gamma_i = (
Gamma_0 * 4 * r_i / (self.N_vortex * D**2 * np.sqrt(1 - (2 * r_i / D) ** 2))
Gamma_0 * 4 * r_i / (self.N_vortex * D * np.sqrt(1 - (2 * r_i / D) ** 2))
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.

IMG_8CE22A855DEF-1

I am pretty sure that this should just be over D due to a cancellation with the Reimann sum. This also makes the units work out since gamma_i should be the same units as gamma_0.

@skygering
Copy link
Copy Markdown
Contributor Author

image (1)

@skygering skygering requested a review from kirbyh October 21, 2025 18:48
Comment thread mitwindfarm/CurledWake.py Outdated
kernel_z = np.arange(-10, 11)[None, :] * dz

# turb = ((yG - yt) ** 2 + (zG - zt) ** 2) < R**2
turb = (((yG - yt) / ay) ** 2 + ((zG - zt) / az) ** 2) < 1.0
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This code works for tilt OR yaw but unfortunately does not generalize to tilt and yaw. The initial condition, following Bastankhah and Porte-Agel (2016) should be an ellipse of semi-major radius $r_4$ and semi-minor axis $r_4 \cdot \cos(\gamma_{eff})$. Probably the best way to change this code is to instead pass in ay and the rotation angle about the y-effective axis (seems like this is cos(yaw)cos(tilt)? from UnifiedMomentumModel). Then the equation that should be in line 849 is:

$f(y, z) = \exp\left[-\frac 12 \left(\frac{((y_G-y_t)\sin \alpha - (z_G-z_t)\cos\alpha)^2}{\sigma_{y'}^2}+ \frac{((y_G-y_t)\cos\alpha + (z_G-z_t)\sin\alpha)^2}{\sigma_{z'}^2}\right)\right]$

where $\sigma_{y'} = a_y$ and $\sigma_{z'} = r_4$, and the rotation angle is $\alpha$.

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.

I don't think I fully understand what is going on here, but I will take a look at the paper and try to understand it.

Comment thread mitwindfarm/Rotor.py Outdated
beta=beta, cached=cached, v4_correction=v4_correction, **kwargs
)
self.alpha = alpha

Copy link
Copy Markdown
Member

@kirbyh kirbyh Oct 27, 2025

Choose a reason for hiding this comment

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

Any code that is just

def function(self, *args, **kwargs): 
    return super().function(*args, **kwargs)

is automatically inherited and can be omitted, correct? The code runs if I comment these lines out. And perhaps it is a bit more future-proof

Comment thread mitwindfarm/CurledWake.py Outdated
)
ay = r4 * np.cos(rotor.yaw)
az = r4 # TODO: could factor in rotor tilt later on
az = r4 * np.cos(rotor.tilt)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

See comment in ic_stencil

@skygering skygering mentioned this pull request Oct 27, 2025
5 tasks
Comment thread pyproject.toml
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We can commit these for now, but after updating mitrotor and UMM we'll want to get rid of the branch= flag, maybe hold off on bumping the version until we PR into main

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.

Yep!! It is going to have to be a one-by-one merge again

Copy link
Copy Markdown
Member

@kirbyh kirbyh left a comment

Choose a reason for hiding this comment

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

Looks great! Just one comment on the IC stencil function, which should be a rotated ellipse where r4 is kept as the semi-major axis rather than both the semi-major and semi-minor axis changing due to combined effects of yaw and tilt

@skygering
Copy link
Copy Markdown
Contributor Author

skygering commented Oct 29, 2025

I think that I fixed the problem @kirbyh. See code changes in ic_stencil. I also made a figure with yaw + tilt

curled_windfarm_with_tilt curled_rotors_with_tilt

@skygering
Copy link
Copy Markdown
Contributor Author

UMM_LES_validation_xy UMM_LES_validation_xz UMM_LES_validation_yz

* Update BEM rotor to allow for tilt input

* Update plotting to allow any slice

* Add new yaw and tilt example

* Debugging new tilt example

* Finish debugging MITWindFarm yaw/tilt

* Add in optimization timing

* Add in timing

* Rename example file

* Example cleanup for PR

* New example with yaw and tilt comparisons added

* Clean up pre-merge

* Final example cleanup
@skygering skygering merged commit e97b75d into kl-model-dev Oct 30, 2025
5 checks passed
@skygering skygering deleted the sg/kl-model-dev branch October 30, 2025 04:38
@skygering skygering mentioned this pull request Oct 30, 2025
5 tasks
skygering added a commit that referenced this pull request Oct 30, 2025
* Adding custom Unified + TI for benchmarking with Curled wake model

* Adding numerics utilities for curled wake model marching

* Adding working Curled Wake model code and new CurledWindFarm class

* moved curled wake example to ./examples/

* Plots at hub height slice or arbitrary, user-defined z

* Adding a powerlaw base wind profile to curled wake example

* Adding example comments and changing interpolation function in lmix

* Fix rotor solution indexing

* Sg/kl model dev (#31)

* Finalize first try at implementation with tilt

* Example runs with zero tilt

* Debug plotting with tilt

* Finish testing curled wake model

* Update dependencies

* Add back in factor of D

* Add tests for rotor differences

* Changed tests

* Finish tests and put back in kirby rotor code

* Update gaussian smoothing to account for tilt

* Update UMM compatibility

* Update UMM and MITRotor packages

* Update package version

* Sg/tilted bem dev (#32)

* Update BEM rotor to allow for tilt input

* Update plotting to allow any slice

* Add new yaw and tilt example

* Debugging new tilt example

* Finish debugging MITWindFarm yaw/tilt

* Add in optimization timing

* Add in timing

* Rename example file

* Example cleanup for PR

* New example with yaw and tilt comparisons added

* Clean up pre-merge

* Final example cleanup

* Finalize examples

* Clean up unneeded calls to super

---------

Co-authored-by: Kirby Heck <kirby.heck@gmail.com>
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.

2 participants