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

OpenFAST v3.1.0 #1023

Merged
merged 602 commits into from
Mar 2, 2022
Merged

OpenFAST v3.1.0 #1023

merged 602 commits into from
Mar 2, 2022

Conversation

rafmudaf
Copy link
Collaborator

@rafmudaf rafmudaf commented Mar 2, 2022

Feature or improvement description
Pull request to merge main into dev and create a tagged release for v3.1.0.

Impacted areas of the software

Test results, if applicable
See GitHub Actions

Release checklist:

  • Update the documentation version in docs/conf.py
  • Update the versions in docs/source/user/api_change.rst
  • Verify readthedocs builds correctly
  • Create a tag in OpenFAST
  • Create a merge commit in r-test and add a corresponding tag
  • Compile executables for Windows builds
    • FAST_SFunc.mexw64
    • MAP_X64.dll
    • OpenFAST-Simulink_x64.dll
    • openfast_x64.exe
    • DISCON.dll

Proposed Change Log

General

#707 Add environmental variables to driver input files
#734 OpenFAST Registry algorithm change: simplify USE statements
Others (#826, #835, #836, #911, #918, #971, #1019)

AeroDyn

#688 AeroDyn driver update for multiple wind turbines, with arbitrary motions and geometries
#729 New features for unsteady aerodynamics modeling
#834 Fix AD Driver unallocated variable error with GCC 11
#863 AeroDyn cleanup
#917 AD15: add nodal outputs for VUnd{xyz}i in global coords
#919 Segment treecode
#920 Update in Computing Default Unsteady Airfoil Coefficients
#922 [BugFix] Minor bugfix in AirfoilInfo
#982 [BugFix] AD15 nacelle reference position was set to hub position
#1001 Remove conditional statement for initialization of BEMT variable
#1009 [BugFix] Nacelle position set inconsistently by glue code and AeroDyn driver

BeamDyn

#996 [BugFix] BeamDyn nodal outputs occasionally segfaulted

FAST Farm

#839 Fix Bug in FAST.Farm Causing Wake Bounce-Back
#860 Fix some memory leaks in FAST.Farm
#895 [BugFix] incorrect init of aggregated output index arrays in FAST.Farm
#923 [BugFix] error handling in AWAE module

HydroDyn

#756 HydroDyn primary input file passing and parsing
#831 HydroDyn Input/Output meshes: change from SWL to MSL for consistency with OF glue code
#838 [BugFix] segmentation fault in HD linearization
#915 [BugFix] Incorrect reference frame used in HD for WAMIT/WAMIT2
#998 Fix HydroDyn summary file nodal data is incorrect when Member is flipped

InflowWind

#720 inflowWind C-bound interface and python wrapper
#929 Fix issue with uninitialized variables in InflowWind's Direct Scaling method

NWTC Library

#1002 Increase line length in FileInfo parsing methods

OpenFAST Library

#716 [BugFix] Fix C++ API for restart, Error handling in FAST Library, and AeroDyn echo file lock
#958 Lin: CalcSteady, forcing linearization at end of simulation

ServoDyn

#902 Fixes for Intel in debug mode
#930 Stop OpenFAST for Simulink simulation when trim solution has been found

SubDyn

#859 Various improvements to SubDyn

Documentation

#740 Guidelines for performance considerations with Fortran
#753 Migrate the HydroDyn Manual to readthedocs
#805 Include legacy documentation in pdf and MS Word format - General & ElastoDyn
#828 Add instructions for adding new regression test cases
#858 Documentation for ExtPtfm
#951 Corrected the description of SkewModFactor in Documentation
#1020 Document AD outputs

andrew-platt and others added 30 commits August 6, 2021 14:20
- The entries for the new `UAStartRad` and `UAEndRad` were added to the tables prior to release of v2.6.0 and 3.0.0 when this development branch was created.
Pin docutils version
Add sphinx theme to extensions
AeroDyn driver update for multiple wind turbines, with arbitrary motions and geometries
@jjonkman
Copy link
Collaborator

Dear @icnosvbovwb,

Yes, that looks correct to me, assuming your loads from Simulink are specified in global coordinates and you only have one tower-based StC (so, j is always 1).

Time does not need to be explicitly defined in these equations because SUBROUTINE ED_InputSolve() is called at distinct time steps.

Best regards,

@jjonkman
Copy link
Collaborator

Dear @icnosvbovwb,

You are changing the value of y_SrvD, so, you must make this variable INTENT(INOUT) in its deceleration earlier in SUBROUTINE ED_InputSolve(). And can you confirm the size of the array you added, m_FAST%ExternInput%ForceTLD?

I've sent you the Seismic archive of FAST v7 via WeTransfer.

Best regards,

@jjonkman
Copy link
Collaborator

Dear @icnosvbovwb,

Variables u_SrvD%ExternalForceTLD and m_FAST%ExternalInput%ForceTLD are variables you added to the source code correct? What size did you allocate them to?

Best regards,

@jjonkman
Copy link
Collaborator

Please share the ALLOCATE statements you used for variables u_SrvD%ExternalForceTLD and m_FAST%ExternalInput%ForceTLD.

Best regards,

@jjonkman
Copy link
Collaborator

You have not actually shared an ALLOCATE statement. Did you ALLOCATE these arrays? If not, that is likely the problem.

Best regards,

@jjonkman
Copy link
Collaborator

It looks like you've created the arrays as allocatable, {:}, in the registry rather than fixed size, so, you must declare the size of the arrays via ALLOCATE statements. Alternatively you can declare the arrays to have 6 elements by changing {:} to {6} in the registry.

Best regards,

@icnosvbovwb
Copy link

Dear @jjonkman
Thank you for your suggestions. I successfully solved the problem according to your suggestions. Then I recently started to try to add the seismic function in SoilDyn.f90. Do you have any specific suggestions? I guess UserPtfmLd_ Seismic.f90 should be modified, but I don't know how to start.

@jjonkman
Copy link
Collaborator

Dear @icnosvbovwb,

NREL has not yet coupled the Seismic functionality of FAST v7 into OpenFAST, and so, cannot provide detailed guidance on doing that. That said, similar questions have been asked before, e.g. see: #617 and on our forum, e.g. see: https://forums.nrel.gov/t/running-examples-with-the-seismic-module/1846.

Best regards,

@jjonkman
Copy link
Collaborator

Dear @icnosvbovwb,

I'm not following; I don't see that you actually shared an error.

Best regards,

@jjonkman
Copy link
Collaborator

Dear @icnosvbovwb,

I'm not sure I understand enough about what you are doing to provide clear guidance. But the direction cosine matrix (the transpose of the rotation matrix--i.e., the transformation matrix such that premultiplication of a vector in global coordinates will convert the vector to local coordinates--is stored in the Orientation field of the platform motion point mesh output of ElastoDyn (PlatformPtMesh). This matrix--dependent on the platform roll, pitch, and yaw angles--is documented as Eq. (2-2) in my PhD-thesis turned NREL report: http://www.nrel.gov/docs/fy08osti/41958.pdf.

Best regards,

@jjonkman
Copy link
Collaborator

Dear @icnosvbovwb,

Here are my responses:
Q1. The answer depends on which ElastoDyn outputs you are using to output the tower-top velocity. Which ones are you using? This documentation lists the coordinate system of each ElastoDyn output: https://openfast.readthedocs.io/en/main/_downloads/3f19498a5dc774461e022b671ff01ec6/OutListParameters.xlsx.
Q2. I explained in my post above how to convert a vector from global to local coordinates. Using the transpose of the direction cosine matrix (DCM) provides the rotation matrix, through which premultiplication of a vector in local coordinates will convert the vector to global coordinates. The DCM for the tower top will depend on the tower-top rotations, and if you have enabled the platform DOFs as well, will depend on those as well.
Q3. Yes. For a tower-based StC, the StC location is positioned relative to the tower-base. If the tower-base is located at (0,0,10) m, then an StC located at (StC_P_X,StC_P_Y,StC_P_Z) = (0,0,2)m would be located at (0,0,12) m in global coordinates.

Best regards,

@jjonkman
Copy link
Collaborator

Dear @icnosvbovwb,

Here are my responses:
Q1: ElastoDyn output YawBrTVxp is expressed in the tower-top/base-plate (p) coordinate system, which is a local coordinate system. You'd need to convert this velocity to global coordinates if that is what you want.

Q2: The substructure-based StC will apply loads to the substructure while the tower-based StC will applied loads to the tower. Even if location of both StCs is the same, the responses may still differ as a result of the point of application of the StC load.

Best regards,

@jjonkman
Copy link
Collaborator

Dear @icnosvbovwb,

I've already summarized how to convert a vector from local to global coordinates.

Best regards,

@jjonkman
Copy link
Collaborator

Dear @icnosvbovwb,

You can use the Fortran intrinsic function MATMUL() to premultiply a matrix with a vector and you can use the intrinsic function TRANSPOSE() to take the transpose of the DCM. But m%AllOuts(YawBrTDzp) is a scalar, not a vector.

While the velocity of the tower nodes is certainly calculated within the source code, ElastoDyn does not have write outputs for the velocity of tower nodes, so, accessing these velocities would certainly require a source code change.

Best regards,

@jjonkman
Copy link
Collaborator

Dear @icnosvbovwb,

I see two problems with your change: (1) m%AllOuts(YawBrTVxp) is a scalar, not a vector and (2) y%PlatformPtMesh%Orientation(:,:,1) represents the coordinate system of the platform (floating substructure), not the tower-top / base-plate coordinate system (p). Please note that velocity vector m%RtHS%LinVelE0 is already in global coordinates, except that the second element is along global Z and the third element is along negative global Y (the global coordinate system used within ElastoDyn is different than the global coordinate system used by OpenFAST). So, if you want write outputs YawBrTVxp, YawBrTVyp, and YawBrTVzp expressed in global coordinates instead of local p coordinates, you can use:

m$AllOuts(YawBrTVxp) = m%RtHS%LinVelE0(1)  ! Global X
m$AllOuts(YawBrTVyp) = -m%RtHS%LinVelE0(3) ! Global Y
m$AllOuts(YawBrTVzp) = m%RtHS%LinVelE0(2)  ! Global Z

Best regards,

@jjonkman
Copy link
Collaborator

Dear @icnosvbovwb,

I agree with your response to Q3, which answers Q1 and Q2. Regarding Q4, the input to the TLCD would not be the same in these two cases because for a substructure-based TLCD (NumSStC = 1), the input to the TLCD is coming from the substructure (so, a large, rigid moment arm between the substructure and TLCD would be assumed) and for the tower-based TLCD (NumTStC = 1), the input to the TLCD is coming from the tower (and so, includes tower flexibility, when enabled).

Best regards,

@jjonkman
Copy link
Collaborator

Yes, that is correct.

@jjonkman
Copy link
Collaborator

Dear @icnosvbovwb,

I'm sorry, but I'm not familiar enough with the design of TLDC systems to comment if your response is expected given the inputs that you've set.

Best regards,

@jjonkman
Copy link
Collaborator

Dear @icnosvbovwb,

ElastoDyn output YawBrTVxp is the absolute velocity of the yaw bearing expressed in the x-axis of the tower-top coordinate system, which is what I expect you want. QD_TFA1 is the first-time derivative of the degree of freedom (DOF) associated with the first bending mode of the tower. QD_TFA1 could be less than YawBrTVxp because (1) other DOFs play a role in the tower-top velocity (such as the second bending mode and the platform DOFs) and (2) the coordinate system is a bit different between the two outputs.

Best regards,

@jjonkman
Copy link
Collaborator

jjonkman commented Jul 9, 2023

Dear @icnosvbovwb,

Your first four questions seem to be focused on your own experiment, so, they would be better answered by you than me.

Regarding (5), the tower base coordinate system in ElastoDyn is aligned with global coordinates when the platform motion is zero.

Regarding (6), the write outputs available in the OutList of ElastoDyn are used only for writing to the output file and are not used for other purposes.

Best regards,

@jjonkman
Copy link
Collaborator

Dear @icnosvbovwb,

To answer your question, please clarify how you've modified the source code of OpenFAST to apply the force and moment signals from Simulink to the structural module of OpenFAST.

Best regards,

@jjonkman
Copy link
Collaborator

Dear @icnosvbovwb,

It looks like you are directly summing your commands from Simulink to the y_SrvD%TStCLoadMesh output of the StC module. This output is expressed in the global coordinate system and can be thought of as the load applied to the tower from the StC.

Best regards,

@jjonkman
Copy link
Collaborator

Dear @icnosvbovwb,

I'm not an expert on the TLCD functionality of the StC submodel of ServoDyn. I would suggest reviewing the TLCD theory basis documented here: https://openfast.readthedocs.io/en/main/source/user/servodyn-stc/StC_TLCD_Theory.html. I don't see that this theory explicitly states how the TLCD equations of motion are related to the resultant StC force and moment outputs, but that is spelled out in the implementation that you can find in routine StC_CalcOutput() of source file StrucCntrl.f90.

Best regards,

@jjonkman
Copy link
Collaborator

jjonkman commented Aug 3, 2023

Dear @icnosvbovwb,

The PrescribedForcesCoord switch in the StC input file determines whether the applied loads are in the global or local coordinate system. But if I understand your changes correctly (that you are adding ForceTLD and MomentTLD to the tower loads output from StC and applied as input to the tower in ElastoDyn within the OpenFAST glue code), the mapping within the OpenFAST glue code is always in global coordinates (as if PrescribedForcesCoord = 1, regardless of its setting). So, ForceTLD and MomentTLD must also be in global coordinates.

Moreover, if you want to apply loads at two different locations along the tower (tower top and tower base), you must have two tower-based StCs (NumTStC = 2) and two sets of ForceTLD and MomentTLD inputs from Simulink, each added to the distinct instances of the tower-based StCs.

Best regards,

@jjonkman
Copy link
Collaborator

jjonkman commented Aug 4, 2023

Dear @icnosvbovwb,

Overall, your approach looks OK, But I agree that an extra set of inputs must be provided, as in your Figure 5; the source code in your Figure 4 needs to be changed. You can see in your Figure 4 a loop through index j, i.e,.

do j=1,size(y_SrvD%TStCLoadMesh)

This is the loop through each tower-based StC, one for the tower-top and one of the tower base (that is, size(y_SrvD%TStCLoadMesh) = NumTStC = 2 in your case). In your current code, you assign the same loads from Simulink to both of these StCs, so, both the tower top and tower base are receiving the same loads. You'll need to change this source code so that each StC receives unique inputs from Simulink.

Best regards,

@jjonkman
Copy link
Collaborator

jjonkman commented Aug 4, 2023

Yes, that looks good to me.

@jjonkman
Copy link
Collaborator

jjonkman commented Aug 7, 2023

Add parentheses around each test condition and using double equals, i.e., IF (J==1) THEN and ELSEIF (J==2) THEN

@jjonkman
Copy link
Collaborator

jjonkman commented Aug 7, 2023

Can you share your your complete set of updates to the ED_InputSolve() routine?

@jjonkman
Copy link
Collaborator

jjonkman commented Aug 7, 2023

You need to change the END you added in the IF test to ENDIF.

@icnosvbovwb
Copy link

Dear @jjonkman
Thank you for your help. Under your guidance, I have resolved the compilation issue.
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment