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

Use temporary mesh for HD low-pass filter initialization #2421

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 24 additions & 7 deletions modules/openfast-library/src/FAST_Subs.f90
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, SED, BD, S
TYPE(FAST_InitData) :: Init !< Initialization data for all modules


type(MeshType) :: PtfmPtMesh_tmp ! temporary mesh for initializing low-pass filter for HD
REAL(ReKi) :: AirDens ! air density for initialization/normalization of ExternalInflow data
REAL(DbKi) :: dt_IceD ! tmp dt variable to ensure IceDyn doesn't specify different dt values for different legs (IceDyn instances)
REAL(DbKi) :: dt_BD ! tmp dt variable to ensure BeamDyn doesn't specify different dt values for different instances
Expand Down Expand Up @@ -1662,18 +1663,32 @@ SUBROUTINE FAST_InitializeAll( t_initial, p_FAST, y_FAST, m_FAST, ED, SED, BD, S
! ----------------------------------------------------------------------------
IF ( (p_FAST%CompHydro == Module_HD) .AND. (HD%p%PotMod == 1_IntKi) ) THEN
IF ( HD%p%WAMIT(1)%ExctnDisp == 2_IntKi ) THEN
! Set the initial displacement of ED%PlatformPtMesh here to use MeshMapping
ED%y%PlatformPtMesh%TranslationDisp(:,1) = Init%OutData_ED%PlatformPos(1:3)
! Make a temporary copy of the PlatformPtMesh -- we don't want to change an output
! NOTE: disposal of the temporary mesh done in Cleanup
call MeshCopy( ED%y%PlatformPtMesh, PtfmPtMesh_tmp, MESH_NEWCOPY, ErrStat2, ErrMsg2 )
call SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName )
if (ErrStat >= AbortErrLev) then
call Cleanup()
return
endif
!FIXME: if SD is used, need to create a temporary mapping here as it doesn't exist
!else, make copy of meshmapdata

! Set the initial displacement of PtfmPtMesh_tmp here to use MeshMapping
PtfmPtMesh_tmp%TranslationDisp(:,1) = Init%OutData_ED%PlatformPos(1:3)
CALL SmllRotTrans( 'initial platform rotation ', &
REAL(Init%OutData_ED%PlatformPos(4),R8Ki), &
REAL(Init%OutData_ED%PlatformPos(5),R8Ki), &
REAL(Init%OutData_ED%PlatformPos(6),R8Ki), &
ED%y%PlatformPtMesh%Orientation(:,:,1), '', ErrStat2, ErrMsg2 )
PtfmPtMesh_tmp%Orientation(:,:,1), '', ErrStat2, ErrMsg2 )
CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName )
ED%y%PlatformPtMesh%TranslationDisp(1,1) = ED%y%PlatformPtMesh%TranslationDisp(1,1) + ED%y%PlatformPtMesh%Orientation(3,1,1) * ED%p%PtfmRefzt
ED%y%PlatformPtMesh%TranslationDisp(2,1) = ED%y%PlatformPtMesh%TranslationDisp(2,1) + ED%y%PlatformPtMesh%Orientation(3,2,1) * ED%p%PtfmRefzt
ED%y%PlatformPtMesh%TranslationDisp(3,1) = ED%y%PlatformPtMesh%TranslationDisp(3,1) + ED%y%PlatformPtMesh%Orientation(3,3,1) * ED%p%PtfmRefzt - ED%p%PtfmRefzt
CALL Transfer_PlatformMotion_to_HD( ED%y%PlatformPtMesh, HD%Input(1), MeshMapData, ErrStat2, ErrMsg2 )
PtfmPtMesh_tmp%TranslationDisp(1,1) = PtfmPtMesh_tmp%TranslationDisp(1,1) + PtfmPtMesh_tmp%Orientation(3,1,1) * ED%p%PtfmRefzt
PtfmPtMesh_tmp%TranslationDisp(2,1) = PtfmPtMesh_tmp%TranslationDisp(2,1) + PtfmPtMesh_tmp%Orientation(3,2,1) * ED%p%PtfmRefzt
PtfmPtMesh_tmp%TranslationDisp(3,1) = PtfmPtMesh_tmp%TranslationDisp(3,1) + PtfmPtMesh_tmp%Orientation(3,3,1) * ED%p%PtfmRefzt - ED%p%PtfmRefzt

!FIXME: manually use a temporary mapping here instead of the call
! CALL Transfer_PlatformMotion_to_HD( PtfmPtMesh_tmp, HD%Input(1), MeshMapData, ErrStat2, ErrMsg2 )
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm trying to understand what this code is doing. From my initial look, it seems like this work could be happening inside ED_Init and HD_Init:

  1. ED initial output translation displacements are getting modified based on ED InitOutput data
  2. HD initial input guess is getting modified based on the modified ED initial output, and
  3. HD states are getting modified based on the changed initial HD Input

I would think we could send HD_Init the information from the mesh and do these calculations inside HD_Init (this would also remove some duplication in the HD driver). It's quite likely I'm missing something to explain why it was done this way.

However, with the code change here, I don't think it will give the same results as before:

  1. ED%y isn't modified (a temp mesh is modified, but not actually used elsewhere);
  2. HD%Input(1) isn't getting modified (it's commented out in line 1690); and
  3. HD%xd is not using the expected values of HD%Input(1) below (e.g. line 1699) because of item 2

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I made a temporary commit late on Friday with notes on things I thought need to be done. A few things were deleted during that commit as @luwang00 and I were figuring out the issue we had. So what is here is an in between broken state of code.

Basically what should be happening here is the setting of some state information for the low pass yaw filter (I suspect it needs to be only close enough, but not exct). I don't think we actually want to change the ED%y at all.

I like the suggestion of handling this inside the HD_Init routine. That would certainly be cleaner at the glue code level, and likely will work better with tight coupling.

Copy link
Contributor

@luwang00 luwang00 Sep 27, 2024

Choose a reason for hiding this comment

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

Hi @andrew-platt and @bjonkman, thanks for the comments and discussions and sorry for the delay on this. I think my initial plan of using mesh mapping to compute the initial potential-flow body positions is making things more complicated than it needs to be. I also like the plan of moving the initialization calculation out of the glue-code and into HydroDyn_Init.

Following your suggestions, I reimplemented the initialization here luwang00@be8a671. It's working correctly based on my tests. This updated implementation should fix several issues:

  • ED%y is no longer modified.
  • It does not rely on mesh mapping, so it works with ED+HD and ED+SD+HD (tested).
  • SmllRotTrans is replaced with EulerConstructZYX to support large platform rotation.

Please let me know if you see any problems with this new implementation. If it checks out, we can update this pull request with luwang00@be8a671. Not sure what's the best way to do this. @andrew-platt, can you help with this? Thanks!


CALL SetErrStat( ErrStat2, ErrMsg2, ErrStat, ErrMsg, RoutineName )
IF (ErrStat >= AbortErrLev) THEN
CALL Cleanup()
Expand Down Expand Up @@ -1794,6 +1809,8 @@ SUBROUTINE Cleanup()
! data that they point to:
CALL FAST_DestroyInitData( Init, ErrStat2, ErrMsg2 )
CALL SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName)
call MeshDestroy(PtfmPtMesh_tmp, ErrStat2, ErrMsg2) ! No harm in destroying this even if never initialized
call SetErrStat(ErrStat2,ErrMsg2,ErrStat,ErrMsg,RoutineName)

END SUBROUTINE Cleanup

Expand Down