ptrbortolotti / SONATA

GNU Lesser General Public License v3.0
9 stars 2 forks source link

NREL5MW #11

Open EVElove444 opened 1 month ago

EVElove444 commented 1 month ago

Hello, thank you very much for providing the yaml file of NREL5MW, but I am not sure if the data in NREL5MW is consistent with the Pucheng structure data of OpenFast or SNL61.5m blades? Because we need a baseline blade as a reference to optimize the blade structure.

ptrbortolotti commented 1 month ago

The original design of the SNL61.5 has been imported to windIO to the best of out ability. I am not sure how the BeamDyn file of the NREL5MW was originally developed, but I believe it relied on quite a few assumptions. Overall, we don't expect a 1-1 match between the K and I matrices predicted by SONATAmini from @KIDEVLIN and the older BeamDyn file, nor to the older SNL61.5 data from NuMAD

ptrbortolotti commented 1 month ago

hello, I'm sorry, please reformulate your question as I don't understand what you need

EVElove444 commented 1 month ago

Dear KIDEVLIN,

I hope this message finds you well.

I am currently conducting research using the NREL 5MW reference wind turbine model, with a particular focus on the accuracy of the 6x6 stiffness and mass matrices in the BeamDyn module. I have a few questions that I hope you can assist me with:

Verification of Stiffness and Mass Matrices: How can we ensure that the 6x6 stiffness and mass matrices for the NREL 5MW turbine in BeamDyn are accurate? Are there recommended methods or steps to validate these matrices?

Source of Structural Parameters: Could you provide details about the source or basis for the structural parameters used for the NREL 5MW turbine? Are these parameters derived from specific experimental data or simulation results?

Related Literature or Documentation: Are there any publications, technical reports, or documentation that detail the structural parameters of the NREL 5MW turbine and their application in BeamDyn? Such references would be invaluable for understanding and validating the physical characteristics of the model.

Thank you for taking the time to read this email. I look forward to any information you can provide to ensure the accuracy of my research model. Please let me know if you need any further details.

Best regards,

KIDEVLIN commented 1 month ago

Hello,

Verification of Stiffness and Mass Matrices: The accuracy of the 6x6 stiffness and mass matrices produced by SONATAmini with ANBA4 were verified using a box-beam example here. For a wind turbine application, a comparison using the IEA 22 MW RWT between SONATAmini and a separate cross-sectional solver from DTU produced similar results. I am unaware of any comparisons of the stiffness and mass matrices for the NREL 5 MW. I would visually check the meshing in the cross-sections produced by SONATAmini to ensure accurate results.

Source of Structural Parameters: The original structural properties found here on page 5, were based on a similar-sized LM Glassfiber blade. The internal structure of the 5 MW turbine in the yaml file is based on this paper which defines a shell model of the blade.

EVElove444 commented 1 month ago

Dear Sir,

I hope this message finds you well. blade_section_0.4137931034482759.pdf

I am currently working on calculating the structural information of a blade using Sonata. During the process, I modified the aerodynamic shape of the blade. However, I have encountered an issue where the mesh quality for one of the blade sections is very poor, while the other sections are satisfactory, as shown in the attached image.

Despite my attempts to resolve this issue by reducing the minimum size and adjusting the mesh generation parameters, the problem persists for this specific section. The error continues to affect the quality of this section's mesh significantly.

Could you please provide guidance on how to address this problem?

Thank you very much for your assistance.

Best regards,

EVElove444 commented 1 month ago

Could you please clarify why there is a discrepancy between the airfoil distributions in the YAML file and the design manual? Is there a specific reason for this difference?

EVElove444 commented 1 month ago

Dear Sir,

I hope this message finds you well. blade_section_0.4137931034482759.pdf

I am currently working on calculating the structural information of a blade using Sonata. During the process, I modified the aerodynamic shape of the blade. However, I have encountered an issue where the mesh quality for one of the blade sections is very poor, while the other sections are satisfactory, as shown in the attached image.

Despite my attempts to resolve this issue by reducing the minimum size and adjusting the mesh generation parameters, the problem persists for this specific section. The error continues to affect the quality of this section's mesh significantly.

Could you please provide guidance on how to address this problem?

Thank you very much for your assistance.

Best regards,

@KIDEVLIN

KIDEVLIN commented 1 month ago

Hello,

The yaml file was changed because the original yaml file was based on a shell method instead of the solid method that SONATA uses. The shell method defines each layer as a 1D line with a "thickness" which can result in overlapping 2D shapes in the solid method as seen in the picture below. The overlap causes issues in SONATA. To fix this, the trailing edge foam thickness was reduced by half at all radial stations.

image

If the warning "WARNING: No closed section found in segment 0. Segment has been closed." is displayed, the segment of code below in the converter_WT.py file is causing the meshing error. This code was a fix for inputs with layups that have no materials starting at 0 or ending at 1 leading to an open airfoil. The fix finds layups with starts and ends close to 0 and 1 and sets them to 0 and 1. You can fix your meshing issue by checking that the yaml input layup has materials starting and closing at 0 and 1. Another fix could be playing with the tolerances in this code block.

# Finding the minimum start and maximum end value for the layers in each starting segment and assigning starts
# and ends within a tolerance to 0 or 1 respectively
for i in range(len(lst)):
    starts = [lst[i][1].segments[0]['Layup'][j][0] for j in range(len(lst[i][1].segments[0]['Layup']))]
    ends = [lst[i][1].segments[0]['Layup'][j][1] for j in range(len(lst[i][1].segments[0]['Layup']))]
    min_start = min(starts)
    max_end = max(ends)
    if min_start != 0 or max_end != 1:
        print("WARNING: No closed section found in segment 0. Segment has been closed.")
        if lst[i][0]<0.6 or lst[i][0] == 1:
            tolerance = 1e-4
        else:
            tolerance = .05
        for j in range(len(lst[i][1].segments[0]['Layup'])):
            if lst[i][1].segments[0]['Layup'][j][0] <= min_start + tolerance:
                lst[i][1].segments[0]['Layup'][j][0] = 0
            if lst[i][1].segments[0]['Layup'][j][1] >= max_end - tolerance:
                lst[i][1].segments[0]['Layup'][j][1] = 1

I will work on making this fix more robust. Please let me know if this fixes the problem!

EVElove444 commented 1 month ago

I'm sorry I didn't solve this problem. I adjusted the tolerance and the layer thickness in yaml file. But the problem still exists.

KIDEVLIN commented 1 month ago

I want to check that the warning message "No closed section found in segment 0. Segement has been closed" is printed. If the warning is not printed, the problem is somewhere else. If this warning message is printed, that means that the layup in the yaml file is not closed. The code block in my previous message is a temporary fix for yaml input files with unclosed layups. I suggest changing the start and end points of layers in the yaml file to close the layup. For example with the 5MW turbine, the following layers should start at 0 and 1 in the yaml file:

UV_protection:

TE_reinforcement_SS:

TE_reinforcement_PS

Let me know if this fixes the issue or if the warning message is not printed.

EVElove444 commented 1 month ago

Hello, the error has not been resolved. The error message is as follows: Subsequently, I made adjustments to the determine_a_nodes function.

Traceback (most recent call last): File "/home/su/Desktop/SONATA-SONATAmini/examples/6_NEW IEA_5MW/6_sonata_IEA5.py", line 66, in job.blade_gen_section(topo_flag=True, mesh_flag = True) File "/home/su/Desktop/SONATA-SONATAmini/SONATA/classBlade.py", line 503, in blade_gen_section cs.cbm_gen_mesh(*kwargs) File "/home/su/Desktop/SONATA-SONATAmini/SONATA/cbm/classCBM.py", line 290, in cbm_gen_mesh self.mesh.extend(seg.mesh_layers(self.SegmentLst, global_minLen, self.WebLst, display=self.display, l0=self.refL)) File "/home/su/Desktop/SONATA-SONATAmini/SONATA/cbm/topo/segment.py", line 283, in mesh_layers layer.mesh_layer(SegmentLst, global_minLen, display=display, l0=1.5 l0) File "/home/su/Desktop/SONATA-SONATAmini/SONATA/cbm/topo/layer.py", line 273, in mesh_layer self.determine_a_nodes(SegmentLst, global_minLen, display) File "/home/su/Desktop/SONATA-SONATAmini/SONATA/cbm/topo/layer.py", line 229, in determine_a_nodes tmp_nodes = [tmp_layer.a_nodes[0]] + tmp_layer.b_nodes + [tmp_layer.a_nodes[-1]] IndexError: list index out of range

def determine_a_nodes(self, SegmentLst, global_minLen, display=None):
    """ """
    unmeshed_ids = []
    for seg in SegmentLst:
        if seg.LayerLst:
            unmeshed_ids.append(int(seg.LayerLst[-1].ID + 1))

    new_a_nodes = []
    for iv_counter, iv in enumerate(self.inverse_ivLst):
        if int(iv[2]) in unmeshed_ids:
            eq_nodes = []
            BSplineLst = self.a_BSplineLst
            iv_BSplineLst = trim_BSplineLst(BSplineLst, iv[0], iv[1], self.S1, self.S2)
            if iv_counter == 0 and len(self.inverse_ivLst) > 1:
                IncStart = True
                IncEnd = False

            elif iv_counter == 0 and len(self.inverse_ivLst) == 1:
                IncStart = True
                IncEnd = True

            elif iv_counter == len(self.inverse_ivLst) - 1 and len(self.inverse_ivLst) > 1:
                if iv_counter == len(self.inverse_ivLst) - 1 and iv[1] == 1 and self.inverse_ivLst[0][0] == 0:
                    IncStart = False
                    IncEnd = False
                else:
                    IncStart = False
                    IncEnd = True

            else:
                IncStart = False
                IncEnd = False

            eq_nodes = equidistant_nodes_on_BSplineLst(iv_BSplineLst, True, IncStart, IncEnd, minLen=global_minLen,
                                                       LayerID=self.ID)
            new_a_nodes.extend(eq_nodes)

        else:
            print(f"Attempting to find layer with ID {iv[2]}")
            tmp_layer = get_layer(int(iv[2]), SegmentLst)
            if tmp_layer is None:
                print(f"Layer with ID {iv[2]} not found in SegmentLst.")
                continue

            print(f"Found layer with ID {tmp_layer.ID}")
            iv_BSplineLst = trim_BSplineLst(self.a_BSplineLst, iv[0], iv[1], self.S1, self.S2)
            isClosed = iv_BSplineLst[0].StartPoint().IsEqual(iv_BSplineLst[-1].EndPoint(), 1e-5)

            if isClosed:
                tmp_nodes = tmp_layer.b_nodes
            else:
                print(f"tmp_layer.a_nodes: {tmp_layer.a_nodes}")
                print(f"tmp_layer.b_nodes: {tmp_layer.b_nodes}")
                if tmp_layer.a_nodes and tmp_layer.b_nodes:
                    tmp_nodes = [tmp_layer.a_nodes[0]] + tmp_layer.b_nodes + [tmp_layer.a_nodes[-1]]
                else:
                    print(f"Layer {tmp_layer.ID} has empty nodes.")
                    continue

            print(f"tmp_nodes: {tmp_nodes}")
            disco_nodes = grab_nodes_on_BSplineLst(tmp_nodes, iv_BSplineLst)
            new_a_nodes.extend(disco_nodes)
            try:
                tmp_nodes = [tmp_layer.a_nodes[0]] + tmp_layer.b_nodes + [tmp_layer.a_nodes[-1]]
            except IndexError as e:
                print(f"IndexError: {e}")
                print(f"tmp_layer.a_nodes: {tmp_layer.a_nodes}")
                print(f"tmp_layer.b_nodes: {tmp_layer.b_nodes}")
                raise

    self.a_nodes = remove_duplicates_from_list_preserving_order(new_a_nodes)
    self.a_nodes = merge_nodes_if_too_close(self.a_nodes, self.a_BSplineLst, global_minLen, 0.01)

I also changed the thickness of the trailing edge material in the YAML file, but the generated diagram still has errors. The airfoil shapes at both ends are incorrect, although the code does not report any errors.

1 2

KIDEVLIN commented 1 month ago

Hi, I don't know what is happening here. The purpose of the section of the function determine_a_nodes with the error transfers nodes from one segment to the current segment (nodes from where web segments meet the spar cap). It looks like it is trying to transfer nodes on a web that does not exist. If you send me the YAML file you are using as input, I can try to debug the issue.

KIDEVLIN commented 1 month ago

Hello, I think I found the issue! The only changes between the original YAML file and your new file was updating the airfoil coordinates. Plotting the new coordinates shows that there was an overlap at the trailing edge shown in the image below. This caused SONATA to think that the pressure side of the airfoil was actually the suction side. I applied a change to check and fix this issue automatically. The fix will be pushed here but if you do not want to wait, just change the interpolate_shapes function in the classAirfoil file to:

def interpolate_shapes(self, af1, af2, t):
    """Interpolate between shape1 and shape2 based on parameter t (0 <= t <= 1)."""
    # Ensure both shapes have the same number of points
    if np.mean(af1[int(len(af1)*1/6):int(len(af1)*1/3), 1]) < 0:
        af1 = np.flip(af1,0)
    if np.mean(af2[int(len(af2)*1/6):int(len(af2)*1/3), 1]) < 0:
        af2 = np.flip(af2,0)
    num_points = max(len(af1), len(af2))
    af1 = self.normalize_points(af1, num_points)
    af2 = self.normalize_points(af2, num_points)

    # Interpolate between shapes
    interpolated_shape = (1 - t) * af1 + t * af2

    # Adjust to maintain the property that the first and last y values average to 0
    avg_y = (interpolated_shape[0, 1] + interpolated_shape[-1, 1]) / 2
    interpolated_shape[0, 1] -= avg_y
    interpolated_shape[-1, 1] -= avg_y

    return interpolated_shape

image

Let me know if this helps.

KIDEVLIN commented 1 month ago

Hello, I think I found the issue! The only changes between the original YAML file and your new file was updating the airfoil coordinates. Plotting the new coordinates shows that there was an overlap at the trailing edge shown in the image below. This caused SONATA to think that the pressure side of the airfoil was actually the suction side. I applied a change to check and fix this issue automatically. The fix will be pushed here but if you do not want to wait, just change the interpolate_shapes function in the classAirfoil file to:

def interpolate_shapes(self, af1, af2, t):
    """Interpolate between shape1 and shape2 based on parameter t (0 <= t <= 1)."""
    # Ensure both shapes have the same number of points
    if np.mean(af1[int(len(af1)*1/6):int(len(af1)*1/3), 1]) < 0:
        af1 = np.flip(af1,0)
    if np.mean(af2[int(len(af2)*1/6):int(len(af2)*1/3), 1]) < 0:
        af2 = np.flip(af2,0)
    num_points = max(len(af1), len(af2))
    af1 = self.normalize_points(af1, num_points)
    af2 = self.normalize_points(af2, num_points)

    # Interpolate between shapes
    interpolated_shape = (1 - t) * af1 + t * af2

    # Adjust to maintain the property that the first and last y values average to 0
    avg_y = (interpolated_shape[0, 1] + interpolated_shape[-1, 1]) / 2
    interpolated_shape[0, 1] -= avg_y
    interpolated_shape[-1, 1] -= avg_y

    return interpolated_shape

image

Let me know if this helps.

This code has been edited to allow for circular airfoil inputs.

EVElove444 commented 1 month ago

Dear KIDEVLIN,

I hope this message finds you well. I wanted to express my sincere thanks for your assistance with the airfoil issue; it has been resolved successfully.

However, I have encountered a new problem related to the image generation part of the job.blade_plot_beam_props() command. The error code is as follows, and despite numerous attempts to modify it, I have not been able to resolve the issue.

Thank you very much for your attention to this matter.

Best regards, RuntimeError: latex was not able to process the following string: b'\\begin{minipage}[b]{10cm} \\underline{\\textbf{Description:}} \\\\The 6x6 sectional stiffness matrix, TS (Timoshenko Stiffness Matrix) (1-extension; 2,3-shear, 4-twist; 5,6-bending) relates the sectional axial strain, $\\epsilon_1$, transverse shearing strains, $\\epsilon_2$ and $\\epsilon_3$, twisting curvatures, $\\kappa_1$ and two bending curvatures, $\\kappa_2$ and $\\kappa_3$, to the axial force, $F_1$, transverse shear forces, $F_2$ and $F_3$, twisting moment, $M_1$, and two bending moments, $M_2$ and $M3$. The relationship between these sectional strains and sectional stress resultants takes the form of asymmetric, 6x6 matrix: \\\\$$ \\left( \\begin{matrix} F{1} \\\\ F{2} \\\\ F{3} \\\\ M{1} \\\\ M{2} \\\\ M{3} \\end{matrix} \\right) = \\left( \\begin{matrix} k{11} & k{12} & k{13} & k{14} & k{15} & k{16} \\\\ k{12} & k{22} & k{23} & k{24} & k{25} & k{26} \\\\ k{13} & k{23} & k{33} & k{34} & k{35} & k{36} \\\\ k{14} & k{24} & k{34} & k{44} & k{45} & k{46} \\\\ k{15} & k{25} & k{35} & k{45} & k{55} & k{56} \\\\ k{16} & k{26} & k{36} & k{46} & k{56} & k{66} \\end{matrix} \\right) \\cdot \\left( \\begin{matrix} \\epsilon{1} \\\\ \\epsilon{2} \\\\ \\epsilon{3} \\\\ \\kappa{1} \\\\ \\kappa{2} \\\\ \\kappa_{3} \\end{matrix} \\right) $$ \\end{minipage} '

Here is the full command invocation and its output:

latex -interaction=nonstopmode --halt-on-error --output-directory=tmpxbqmgplb 127908b223a4cf777898c60ef5e3e286.tex

This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2022/dev/Debian) (preloaded format=latex) restricted \write18 enabled. entering extended mode (./127908b223a4cf777898c60ef5e3e286.tex LaTeX2e <2021-11-15> patch level 1 L3 programming layer <2022-01-21> (/usr/share/texlive/texmf-dist/tex/latex/base/article.cls Document Class: article 2021/10/04 v1.4n Standard LaTeX document class (/usr/share/texlive/texmf-dist/tex/latex/base/size10.clo)) (/usr/share/texlive/texmf-dist/tex/latex/type1cm/type1cm.sty) (/usr/share/texmf/tex/latex/cm-super/type1ec.sty (/usr/share/texlive/texmf-dist/tex/latex/base/t1cmr.fd)) (/usr/share/texlive/texmf-dist/tex/latex/base/inputenc.sty) (/usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty (/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty) (/usr/share/texlive/texmf-dist/tex/generic/iftex/ifvtex.sty (/usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty))) (/usr/share/texlive/texmf-dist/tex/latex/underscore/underscore.sty) (/usr/share/texlive/texmf-dist/tex/latex/base/textcomp.sty) (/usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-dvips.def) No file 127908b223a4cf777898c60ef5e3e286.aux. geometry driver: auto-detecting geometry detected driver: dvips

Underfull \hbox (badness 10000) in paragraph at lines 29--29

! Misplaced alignment tab character &. l.29 ...} \right) = \left( \begin{matrix} k{11} & k{12} & k{13} & k{14} ... No pages of output. Transcript written on tmpxbqmgplb/127908b223a4cf777898c60ef5e3e286.log.

KIDEVLIN commented 1 month ago

Dear KIDEVLIN,

I hope this message finds you well. I wanted to express my sincere thanks for your assistance with the airfoil issue; it has been resolved successfully.

However, I have encountered a new problem related to the image generation part of the job.blade_plot_beam_props() command. The error code is as follows, and despite numerous attempts to modify it, I have not been able to resolve the issue.

Thank you very much for your attention to this matter.

Best regards, RuntimeError: latex was not able to process the following string: b'\begin{minipage}[b]{10cm} \underline{\textbf{Description:}} \\The 6x6 sectional stiffness matrix, TS (Timoshenko Stiffness Matrix) (1-extension; 2,3-shear, 4-twist; 5,6-bending) relates the sectional axial strain, e p s i l o n 1 , transverse shearing strains, e p s i l o n 2 and e p s i l o n 3 , twisting curvatures, k a p p a 1 and two bending curvatures, k a p p a 2 and k a p p a 3 , to the axial force, F 1 , transverse shear forces, F 2 and F 3 , twisting moment, M 1 , and two bending moments, M 2 and M 3 . The relationship between these sectional strains and sectional stress resultants takes the form of asymmetric, 6x6 matrix: \\$$ \left( \begin{matrix} F{1} \\ F{2} \\ F{3} \\ M{1} \\ M{2} \\ M{3} \end{matrix} \right) = \left( \begin{matrix} k{11} & k{12} & k{13} & k{14} & k{15} & k{16} \\ k{12} & k{22} & k{23} & k{24} & k{25} & k{26} \\ k{13} & k{23} & k{33} & k{34} & k{35} & k{36} \\ k{14} & k{24} & k{34} & k{44} & k{45} & k{46} \\ k{15} & k{25} & k{35} & k{45} & k{55} & k{56} \\ k{16} & k{26} & k{36} & k{46} & k{56} & k{66} \end{matrix} \right) \cdot \left( \begin{matrix} \epsilon{1} \\ \epsilon{2} \\ \epsilon{3} \\ \kappa{1} \\ \kappa{2} \\ \kappa{3} \end{matrix} \right) $$ \end{minipage} '

Here is the full command invocation and its output:

latex -interaction=nonstopmode --halt-on-error --output-directory=tmpxbqmgplb 127908b223a4cf777898c60ef5e3e286.tex

This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2022/dev/Debian) (preloaded format=latex) restricted \write18 enabled. entering extended mode (./127908b223a4cf777898c60ef5e3e286.tex LaTeX2e <2021-11-15> patch level 1 L3 programming layer <2022-01-21> (/usr/share/texlive/texmf-dist/tex/latex/base/article.cls Document Class: article 2021/10/04 v1.4n Standard LaTeX document class (/usr/share/texlive/texmf-dist/tex/latex/base/size10.clo)) (/usr/share/texlive/texmf-dist/tex/latex/type1cm/type1cm.sty) (/usr/share/texmf/tex/latex/cm-super/type1ec.sty (/usr/share/texlive/texmf-dist/tex/latex/base/t1cmr.fd)) (/usr/share/texlive/texmf-dist/tex/latex/base/inputenc.sty) (/usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty (/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty) (/usr/share/texlive/texmf-dist/tex/generic/iftex/ifvtex.sty (/usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty))) (/usr/share/texlive/texmf-dist/tex/latex/underscore/underscore.sty) (/usr/share/texlive/texmf-dist/tex/latex/base/textcomp.sty) (/usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-dvips.def) No file 127908b223a4cf777898c60ef5e3e286.aux. geometry driver: auto-detecting geometry detected driver: dvips

Underfull \hbox (badness 10000) in paragraph at lines 29--29

! Misplaced alignment tab character &. l.29 ...} \right) = \left( \begin{matrix} k{11} & k{12} & k{13} & k{14} ... No pages of output. Transcript written on tmpxbqmgplb/127908b223a4cf777898c60ef5e3e286.log.

Hello, I am glad the flipped airfoil fix worked. I have not tried to use this plotting function, but it looks like the issue is with the latex formatting. I would copy-paste the output into latex which may give a better understanding of what the error is. I have instead been using pyDatView to help visualize the outputs.

EVElove444 commented 3 weeks ago

@KIDEVLIN Dear KIDEVLIN, I wonder if SONATA can calculate the modal information(Natural frequencies) of blades. I want to use modal data to verify whether the modeling is accurate. How to directly derive the calculated data of EI22,EI33,GJ,EA and other sections?EI22,EI33,GJ,EA.

ptrbortolotti commented 3 weeks ago

Hello @EVElove444, SONATA does not include a beam model. SONATA though generates a BeamDyn file. You can then run https://github.com/OpenFAST/openfast, and OpenFAST allows you to linearize the model. This is one of many papers showing the results of linearizing OpenFAST https://iopscience.iop.org/article/10.1088/1742-6596/2767/2/022018/meta

EVElove444 commented 3 weeks ago

Hello, I used the BeamDyn data calculated by the MREL5MW blade model provided by you and the BeamDyn data provided by the NREL5MW case in openfast to calculate the rotational speed and blade displacement under different wind speeds, respectively, but the results show that there is a huge difference between them. Can you explain this problem? Only the BeamDyn file was changed in the simulation.We want to calculate the rotational speed of the blade when it vibrates. Figure 1 provides you with BeamDyn calculated from the blade data.We want to calculate the rotational speed of the blade when it vibrates. `W7$T}$(~_K6HR{83AZS)EY

Figure 2 shows the case in openfast. ZYN}M%19%{7W(_ %7BN%GG

ptrbortolotti commented 3 weeks ago

I suppose your inputs to BeamDyn are very different... please check the stiffness and inertia matrices between standard NREL5MW and your new file. You can use https://github.com/ebranlard/pyDatView for the comparison

EVElove444 commented 3 weeks ago

@KIDEVLIN There is a huge difference between the BeanDyn calculated by the NREL5MW.yaml file and the BeamDyn data given in the openfast case (nreloffsshrbsline5mw beamdyn blade). How should this explain this problem? Most researchers directly use Nreloffshrbsline 5 MW BeamDyn blade data to calculate. Our research needs to recalculate beamdyn because it involves changing the structure of the blade. Now there is a huge gap between the two, and we have not changed the structure of the blade at present. k66 k55 k44 k33 k22 K11

_20240824111953

EVElove444 commented 3 weeks ago

@KIDEVLIN There is a huge difference between the BeanDyn calculated by the NREL5MW.yaml file and the BeamDyn data given in the openfast case (nreloffsshrbsline5mw beamdyn blade). How should this explain this problem? Most researchers directly use Nreloffshrbsline 5 MW BeamDyn blade data to calculate. Our research needs to recalculate beamdyn because it involves changing the structure of the blade. Now there is a huge gap between the two, and we have not changed the structure of the blade at present. k66 k55 k44 k33 k22 K11

_20240824111953

@ptrbortolotti @KIDEVLIN

EVElove444 commented 3 weeks ago

@KIDEVLIN @ptrbortolotti Is this problem currently unsolvable?

ptrbortolotti commented 3 weeks ago

hello and happy Monday. I am not entirely sure where the differences come from. The problem is certainly not unsolvable, although @KIDEVLIN has now moved on to his next position and he's no longer available to help. I assume that the problem is quite simply related to the inputs and to the meshing. The reference 5MW BeamDyn file you refer to, which I believe is this one https://github.com/OpenFAST/r-test/blob/548bf2143633a7066f4582167fdf4180951fd7f6/glue-codes/openfast/5MW_Baseline/NRELOffshrBsline5MW_BeamDyn_Blade.dat, was generated adopting several simplifications. I am not entirely sure what these were actually, as they are not documented as far as I'm aware. I simply know that NREL did not have an accurate cross sectional solver in-house at the time this file was generated. I believe it was created by running PreComp and then assuming some values for the shear terms (PreComp only estimates the 4x4 K matrix). You can verify this statement with the fact that the matrix only has diagonal terms. Overall, the "reference" 5MW BeamDyn file is actually not a very good reference. @KIDEVLIN has helped go past this point by loading the blade geometrical description of the NREL5MW into SONATA. The original file is here https://github.com/WISDEM/WISDEM/blob/master/examples/02_reference_turbines/nrel5mw.yaml, and again this was our best representation in yaml format of the 61.5 m blade designed at Sandia in NuMAD. There could be discrepancies between the original design and the one described in the yaml. Lastly, @KIDEVLIN had to manipulate the file to make sure that SONATA could read the file and generate the K and I matrices successfully. Some things he had to improve were linked to the geometry of the trailing edge, which has originally been modeled with shell elements at Sandia and therefore lacks the level of details required by SONATA, which uses planar FE elements.

My recommendation is to compare the input yaml files that you are loading into SONATA to see if there are major discrepancies between the original design released by Sandia and what SONATA sees. SONATA should be generating plots of the cross sections and you can visualize the geometries there. We will also run this comparison, but it will take me at least a few days to get to do that as I have more urgent tasks

I hope this helps

EVElove444 commented 3 weeks ago

Could you please clarify why there is a discrepancy between the airfoil distributions in the YAML file and the design manual? Is there a specific reason for this difference? Is this the reason?

EVElove444 commented 3 weeks ago

I don't know the logic of generating. yaml. Compared with the yaml file provided by https://github.com/wisdem/blob/master/examples/02 reference turbines/nrel5mw.YAML, the definition of materials is more detailed. So I can't verify it. This job depends on you.

ptrbortolotti commented 3 weeks ago

Could you please clarify why there is a discrepancy between the airfoil distributions in the YAML file and the design manual? Is there a specific reason for this difference? Is this the reason?

I'm sorry, I don't know... again the NREL5MW is an outdated model that is no longer actively maintained. It is also not a very relevant model to represent offshore wind turbines in 2024

ptrbortolotti commented 3 weeks ago

I don't know the logic of generating. yaml. Compared with the yaml file provided by https://github.com/wisdem/blob/master/examples/02 reference turbines/nrel5mw.YAML, the definition of materials is more detailed. So I can't verify it. This job depends on you.

This online documentation helps understanding the structure of yaml files https://windio.readthedocs.io/en/latest/

EVElove444 commented 2 weeks ago

@ptrbortolotti Hello, I have checked the .yaml file and the .https://github.com/wisdem/blob/master/examples/02 reference turbines file over the past few days, and the results indicate that there are no significant differences between them. However, the calculation results differ greatly. Have you identified the specific issue?

ptrbortolotti commented 2 weeks ago

you could install https://github.com/WISDEM/WISDEM and run this example https://github.com/WISDEM/WISDEM/blob/master/examples/02_reference_turbines/nrel5mw_driver.py. in the outputs you will have the stiffnesses predicted by PreComp, which you could compare to the ones predicted by SONATA/ANBA

a similar exercise consists of installing https://github.com/WISDEM/weis and run this example https://github.com/WISDEM/WEIS/tree/main/examples/03_NREL5MW_OC3_spar you will get an elastodyn blade file, and again you can compare mass and stiffness distributions

EVElove444 commented 2 weeks ago

@KIDEVLIN NREL5MW.yaml文件计算出来的BeanDyn和openfast案例给出的BeamDyn数据(nreloffshrbsline5mw_beamdyn_blade)差距巨大,这该怎么解释这个问题呢?大部分研究者都是直接用Nreloffshrbsline5MW_BeamDyn_blade数据来计算,而我们的研究因为涉及到改变叶片的结构,所以需要重新计算beamdyn,现在两者差距巨大,而我们目前还没有改变叶片的结构。 K66型 K55系列 K44型 K33型 k22 K11

_20240824111953

I calculated the stiffness data for SNL61.5m using precomp in NUMAD and compared it to the stiffness data in ElastoDyn given by openfast. The gap is still large compared to SONATA. Do you maintain the 5MW model in sonata? fig_EdgStff fig_FlpStff fig_EAStff fig_GJStff

ptrbortolotti commented 2 weeks ago

can you please add the line corresponding to sonata to this plot?

EVElove444 commented 2 weeks ago

Hello, I compared the openfast data, in which the picture name and legend are very clear, please check I calculated the stiffness data for SNL61.5m using precomp in NUMAD 微信截图_20240831204701

K33 k44 K55 K66

ptrbortolotti commented 2 weeks ago

Ok this helps thank you. It looks like the older BeamDyn file is the outlier, whereas SONATA and OpenFAST elastodyn are rather close. would you agree?

EVElove444 commented 2 weeks ago

Sorry, there is a problem with the data just now. Now I have corrected it. The data shows that the total ElastoDyn and BeamDyn data of openfast are exactly the same. The data calculated by precomp is also similar to the data calculated by sonata, but there is a big difference with the openfast data. The EAstff data is very different.Strangely, I only replaced the BeamDyn file calculated using sonata, and the calculation results of openfast were greatly different. K33 K44 K55 K66