Yaml to OpenFAST input : example?

I have found a number of posts with questions about the creation of a complete OpenFAST model from the yaml output from WISDEM. However, it is still unclear to me how this is done, other than that I know that WEIS is involved.
Can somebody give me a pointer to an example (from the WEIS repository) that actually does this process of generating those input files?

I am really curious to learn what is possible with WEIS.

Thank you in advance and best regards,
Duncan

Hi Duncan,

This example will generate and run OpenFAST models here for the NREL-5MW with the OC3 spar. The other examples in WEIS are similar, and can be adapted to your use case.

This example is for a fixed bottom, onshore turbine.

I hope this helps.

Best, Dan

Hello Daniel,
Thank you so much!
Best regards,
Duncan

Hello Daniel,

I see that the examples are for an ElastoDyn blade model. Can WEIS also convert the yaml from a WISDEM optimization into a BeamDyn blade model?

Best regards,
Duncan

Hello Duncan,
WEIS does not yet fully support BeamDyn. With the code below, you can generate BeamDyn files from the yaml files. Note however that I wrote the script for the IEA22 GitHub - IEAWindTask37/IEA-22-280-RWT: Repository for 22MW offshore reference wind turbine developed by the IEA Wind Task 37, where the yaml was generated at DTU running BECAS. WEIS integrates WISDEM, which integrates PreComp. PreComp ignores shear stiffness, and so you cannot simply go from WEIS to BeamDyn. At NREL, we usually generate BeamDyn files by running SONATA GitHub - ptrbortolotti/SONATA, which is however a fragile code.
I hope this helps.
Best regards,
Pietro

try:
    import ruamel_yaml as ry
except:
    try:
        import ruamel.yaml as ry
    except:
        raise ImportError("No module named ruamel.yaml or ruamel_yaml")
import numpy as np
from weis.aeroelasticse.FAST_writer import InputWriter_OpenFAST


path2yaml = 'IEA-22-280-RWT.yaml'

reader = ry.YAML(typ="safe", pure=True)
with open(path2yaml, "r", encoding="utf-8") as f:
    input_yaml = reader.load(f)


el_props = input_yaml['components']['blade']['elastic_properties_mb']['six_x_six']


# Write BeamDyn file
fst_vt = {}
fst_vt["BeamDyn"] = {}
fst_vt["BeamDyn"]['BldFile'] = 'blade'
fst_vt['BeamDynBlade'] = {}
fst_vt['BeamDynBlade']['station_total'] = len(el_props['reference_axis']['x']['grid'])
fst_vt['Fst'] = {}
fst_vt['outlist'] = {}
fst_vt['outlist']['BeamDyn'] = {}

# BeamDyn options
fst_vt['BeamDyn']['Echo'] = False
fst_vt['BeamDyn']['QuasiStaticInit'] = True
fst_vt['BeamDyn']['rhoinf'] = 0
fst_vt['BeamDyn']['quadrature'] = 2
fst_vt['BeamDyn']['refine'] = "DEFAULT"
fst_vt['BeamDyn']['n_fact'] = "DEFAULT"
fst_vt['BeamDyn']['DTBeam'] = "DEFAULT"
fst_vt['BeamDyn']['load_retries'] = "DEFAULT"
fst_vt['BeamDyn']['NRMax'] = "DEFAULT"
fst_vt['BeamDyn']['stop_tol'] = "DEFAULT"
fst_vt['BeamDyn']['tngt_stf_fd'] = "DEFAULT"
fst_vt['BeamDyn']['tngt_stf_comp'] = "DEFAULT"
fst_vt['BeamDyn']['tngt_stf_pert'] = "DEFAULT"
fst_vt['BeamDyn']['tngt_stf_difftol'] = "DEFAULT"
fst_vt['BeamDyn']['RotStates'] = True
fst_vt['BeamDyn']['member_total'] =  1
fst_vt['BeamDyn']['order_elem'] =  10
fst_vt['BeamDyn']['BldFile'] =  "IEA22_BeamDyn_Blade.dat"
fst_vt['BeamDyn']['UsePitchAct'] =  False
fst_vt['BeamDyn']['PitchJ'] = 0.
fst_vt['BeamDyn']['PitchK'] = 0.
fst_vt['BeamDyn']['PitchC'] = 0.
fst_vt['BeamDyn']['SumPrint'] = False
fst_vt['BeamDyn']['OutFmt'] = "ES10.3E2"
fst_vt['BeamDyn']['NNodeOuts'] = 0
fst_vt['BeamDyn']['OutNd'] = ''
channel_list = ["TipTDxr", "TipTDyr", "TipTDzr", "TipRDxr", "TipRDyr", "TipRDzr", "RootMxr", "RootMyr", "RootMzr"]
fst_vt['outlist']['BeamDyn'] = {}
for channel in channel_list:
    fst_vt['outlist']['BeamDyn'][channel] = True

# BeamDyn 3D reference axis
fst_vt['BeamDyn']['kp_total'] = len(el_props['reference_axis']['x']['grid'])
fst_vt['BeamDyn']['members'] = [{}]
fst_vt['BeamDyn']['members'][0]['kp_xr'] = el_props['reference_axis']['x']['values']
fst_vt['BeamDyn']['members'][0]['kp_yr'] = el_props['reference_axis']['y']['values']
fst_vt['BeamDyn']['members'][0]['kp_zr'] = el_props['reference_axis']['z']['values']
fst_vt['BeamDyn']['members'][0]['initial_twist'] = np.deg2rad(el_props['twist']['values'])

# Rayleigh damping
fst_vt['BeamDynBlade']['damp_type'] = 1


# Tune damping
delta = np.array([0.03, 0.03, 0.03]) # logarithmic decrement, natural log of the ratio of the amplitudes of any two successive peaks. 3% flap and edge torsion
zeta = 1. / np.sqrt(1.+(2.*np.pi / delta)**2.) # damping ratio,  dimensionless measure describing how oscillations in a system decay after a disturbance
# zeta = np.array([0.0015, 0.0015, 0.01]) # Damping ratio edge 0.15% flap 0.15% torsion 1%
# omega = np.array([0.5, 0.7, 5.])*2*np.pi # Frequency (rad/s), flap/edge


# mu1 = 2*zeta[0]/omega[0]
# mu2 = 2*zeta[1]/omega[1]
# mu3 = 2*zeta[2]/omega[2]

mu1 = 2.955e-3 
mu2 = 2.424e-3 
mu3 = 1.0e-8 

fst_vt['BeamDynBlade']['mu1'] = mu1
fst_vt['BeamDynBlade']['mu2'] = mu2
fst_vt['BeamDynBlade']['mu3'] = mu3
fst_vt['BeamDynBlade']['mu4'] = mu2
fst_vt['BeamDynBlade']['mu5'] = mu1
fst_vt['BeamDynBlade']['mu6'] = mu3

# Stiffness in the BD coordinate system
fst_vt['BeamDynBlade']['radial_stations'] = el_props['stiff_matrix']['grid']

Krow = np.array(el_props['stiff_matrix']['values'])
Irow = np.array(el_props['inertia_matrix']['values'])

K = np.zeros((len(Krow),6,6))
I = np.zeros((len(Krow),6,6))
for i in range(len(Krow)):
    K[i,0,:] = Krow[i][:6]
    K[i,1,:] = Krow[i][[1,6,7,8,9,10]]
    K[i,2,:] = Krow[i][[2,7,11,12,13,14]]
    K[i,3,:] = Krow[i][[3,8,12,15,16,17]]
    K[i,4,:] = Krow[i][[4,9,13,16,18,19]]
    K[i,5,:] = Krow[i][[5,10,14,17,19,20]]
    
    I[i,0,:] = Irow[i][:6]
    I[i,1,:] = Irow[i][[1,6,7,8,9,10]]
    I[i,2,:] = Irow[i][[2,7,11,12,13,14]]
    I[i,3,:] = Irow[i][[3,8,12,15,16,17]]
    I[i,4,:] = Irow[i][[4,9,13,16,18,19]]
    I[i,5,:] = Irow[i][[5,10,14,17,19,20]]

fst_vt['BeamDynBlade']['beam_stiff'] = K
fst_vt['BeamDynBlade']['beam_inertia'] = I

fastout = InputWriter_OpenFAST()
fastout.fst_vt = fst_vt
fastout.FAST_runDirectory = 'IEA-22-280-RWT/OpenFAST'
fastout.FAST_namingOut = 'IEA-22-280-RWT'
fastout.update(fst_update={})
fastout.write_BeamDyn()