Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change BD states to follow the blade root reference frame #1771

Merged
merged 9 commits into from
Oct 3, 2023

Conversation

andrew-platt
Copy link
Collaborator

This PR is ready to merge

Feature or improvement description
BeamDyn states have been calculated in a stationary reference frame. This has led to slow convergence or non-convergence with some blades at large angular displacements. This PR changes the reference frame for the states to the blade root motion reference frame.

To accomplish this, the BeamDyn states are now calculated relative to the blade root motion mesh and must be updated to the new reference frame every timestep. The BeamDyn algorithm is now as follows:

  • During Init, store GlbPos, GlbRot, and Glb_crv in OtherStates instead of parameters. These are used in calculations to set outputs, and move inputs into the correct frames.
  • The UpdateStates routine uses the reference frame at time T and calculates the new states at time T+dt. After UpdateStates completes, the reference frame values GlbPos, GlbRot, and Glb_crv are updated to the root motion for time T+dt. The states at T+dt are then shifted to this new reference frame so that the states at T+dt are using the root motion frame at T+dt.
  • The CalcOutput routine is essentially unchanged.

The values for the reference frame (GlbPos, GlbRot, and Glb_crv) are stored in OtherStates instead of parameters so they can be rolled back with the states when the predictor-corrector algorithm is used.

A flag in the source code has also been added to allow reverting to the previous behavior if necessary (not user accessible).

Related issue, if one exists
When the rotor was locked with blades at 180 degrees azimuth (blade 1 pointing straight down), a time domain simulation would fail with non-convergence on blade 2:

FAST_Solution:FAST_AdvanceStates:B2:BD_GA2:BD_DynamicSolutionGA2:Solution does not converge after
the maximum number of iterations

After this update, this simulation now runs to completion (see comments below).

We expect this will help eliminate some non-convergence issues with curved blades during time-domain simulations (we have not fully tested this with all known problematic blades yet).

Impacted areas of the software

  • BeamDyn internal states -- nothing outside of BeamDyn is affected
  • BeamDyn unit tests were updated as necessary -- some routine interfaces changed.

Additional supporting information
The BeamDyn formulation has been using a stationary reference frame for all states. This requires reparamerization of the WM parameters of the states at +/-Pi. This can lead to calculation non-convergence when the turbine is yawed or the blade is pitched away from power (non-convergence typically occurred on blades 2&3). During the initial development of a new tight coupling algorithm in the glue to simultaneously solve all BeamDyn instances along with ElastoDyn, @deslaughter found it difficult to get convergence beyond ~45 degrees of blade pitch, azimuth, or nacelle yaw. This led to questioning if it might be appropriate to change the calculation frame used in BD (requiring changing the states) to be relative to the blade root motion. Rather than try this on the tight coupling only, we added it to the main branch as well for testing.

Test results, if applicable
Test results are identical to before.

andrew-platt and others added 9 commits August 28, 2023 08:59
The reference frame is now moving.  All values from p%GlbRot, p%Glb_crv, and p%GlbPos are now stored as otherstates and get updated at the end of an updatestates routine.

Additional logic and data handling was changed within BD:
 - UpdateStates starts with the initial root position at T, and `q` and `dqdt` are relative to this position/orientation.
 - once UpdateStates converges, the `q` and `dqdt` states are updated to the root position/orientat at T+dt

 - Output calculations (mesh and channel outputs) have been modified
 - Inputs are slightly modified as well

During Init, the values in `q` and `dqdt` are updated twice.  The first time is relative to the reference frame for the meshes, and the second time for the mesh reference frame + displacements.
may have positions in mesh partially correct.  Rotations appear too far though, so something wrong with rotation handling
Some minor cleanup to better match parent branch (deleted blank lines, etc)
@mayankchetan
Copy link
Contributor

This pull request resolves an issue related to simulating a locked rotor with Blade-1 pointing down (180 Deg) in still air. The blades are have a pre-curve and off diagonal terms in the stiffness matrix.

Due to the proprietary nature of the wind turbine model, no further details can be shared publicly.

Copy link
Collaborator

@jjonkman jjonkman left a comment

Choose a reason for hiding this comment

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

I'm still not sure I fully understand why this change was needed (I'm not sure what was wrong with the prior approach where the reference frame for the states was not changed every time step), but I'm happy to hear that this change resolves cases where BeamDyn was previously failing to converge. And my understanding is this change also significantly reduces the frequency with which the Jacobian will need to be updated in tight coupling, which makes this change important regardless.

I do have a couple questions on specific details of the implementation. See below.

Moreover, I'm a bit concerned that this change will mess up the BeamDyn linearization capability, especially in regards to RotStates and RelStates (the latter of which is implemented in BeamDyn, but not selectable by the user). Was linearization tested?

! Root displacement is relative to the GlbPos at time T, which is simply the difference between
! the previous root position (GlbPos) and the new extrapolated position (Pos+TransDisp)
dxdt%q(1:3,1) = m%u%RootMotion%TranslationDisp(:,1) + &
matmul(m%u%RootMotion%Position(:,1) - OtherState%GlbPos, OtherState%GlbRot)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't get why TranslationDisp is not within the MATMUL() as TranslationDisp, Position, and GlbPos are all in global coordinates. Likewise in other places. Is this because the input is changed from global to local coordinates in BD_InputGlobalLocal?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Correct. The TranslationDisp was changed in the BD_InputGlobalLocal routine, but the reference Position was not changed.

Removing the BD_InputGlobalLocal routine would really help clean up this logic.

@@ -5149,32 +5161,33 @@ END SUBROUTINE BD_CompTngtStiff
!! 4 Point forces/moments
!! 5 Distributed forces/moments
!! It also transforms the DCM to rotation tensor in the input data structure
SUBROUTINE BD_InputGlobalLocal(p, u)
SUBROUTINE BD_InputGlobalLocal(p, OtherState, u)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I was not previously aware of this routine, but it appears to be in violation of the framework because inputs are supposed to be INTENT(IN) and not changed. Can we rework BeamDyn so that the inputs are not changed? I'm concerned that inputs are generally assumed to be in global coordinates, but are no longer after this change, so, there is likely more potential for misunderstanding and errors.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This routine has been in BeamDyn since ~2013. Now that the reference frame for the states follows the blade root motion, it really should be removed. It will take a little time to do, so perhaps we can do that during the 4.1 tight coupling we can simplify a few things in BD.

@andrew-platt
Copy link
Collaborator Author

andrew-platt commented Oct 3, 2023

My suspicion is that there is something very slightly incorrect in the equations for tangent stiffness matrix that becomes an issue when we have large angular displacements. If this suspicion is correct, it would explain the observations @ashesh2512 made about the difference between the analytical and numerically calculated tangent stiffness matrices. By resetting the states to follow the root motion, we never have a situation with large angular displacements.

I ran a few checks with the BeamDyn linearization regression tests. A few terms in the C and D matrices from the .lin file changed: terms on the order of 1e-13 to 1e-17 changed in the third significant digit. The overall frequencies and damping ratios were identical.

@mayankchetan also did some linearization testing with the IEA 15 MW turbine and saw no substantive change in results from v 3.5.0 (negative damping still occurs exactly as before).

@andrew-platt
Copy link
Collaborator Author

Comparison table from @mayankchetan:
Screenshot 2023-10-03 at 1 15 26 PM
Less than 0.25% change in any natural frequency. The damping ratio for Mode 6 had the largest change (3.28%)

[table would not copy nicely from Teams, hence the picture instead]

@andrew-platt andrew-platt merged commit 1e3a24a into OpenFAST:rc-3.5.1 Oct 3, 2023
@andrew-platt andrew-platt deleted the f/BD_RotRefFrame branch October 3, 2023 20:59
@andrew-platt andrew-platt mentioned this pull request Oct 19, 2023
19 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants