.. _BET_Tutorial: .. |deg| unicode:: U+000B0 .. DEGREE SIGN :ltrim: Blade Element Theory using the XV-15 rotor ========================================== This tutorial aims to provide guidance for blade element theory (BET) simulations for each step of the process, from mesh generation, setting up the input files through to the simulation output and postprocessing. For a refresher on BET implementation, please see the :ref:`Capabilities ` and :ref:`Knowledge Base ` pages. The example used for this tutorial will be the XV-15 rotor blade, which is also used for the :ref:`sliding interface tutorial ` for rotating geometry simulations and the :ref:`BET case study `. For this case we will be generating a simple wing, very much like what is done in the :ref:`ONERA M6 Wing Quick Start `. We will be using the :ref:`automated meshing toolchain ` to generate the mesh. The configuration used in this tutorial is shown in :numref:`Fig1_Config` with a view from behind :numref:`bet_x_view` and a side view :numref:`bet_side_view`. .. _Fig1_Config: .. figure:: Figures/BETConfig.png :align: center :scale: 60% BET tutorial case configuration visualized using Q-criterion contoured by Mach number. The tutorial will cover steady-state BET Disk simulations, but most of the explanations are also applicable to transient BET Line simulations. .. _bet_tutorial_preprocess: Preprocessing ~~~~~~~~~~~~~~ The first section of the tutorial focuses on the geometry and mesh generation. The geometry model is built in :ref:`Engineering Sketch Pad (ESP) `. The surface and volume mesh parameters input files are discussed :ref:`below `. .. _bet_tutorial_csm_download: The basic wing model CAD generation file we will use can be found in this `BET_tutorial_wing.csm `_ file. While the mesh can be generated manually using numerous meshing software, we will be using our automated meshing toolchain, which takes an ESP CAD model from a CSM file as an input. To use the automated meshing framework, at least one no-slip wall must be present in the simulation and should not cross-over the BET disk region. This can be either a hub for isolated rotor simulations or other vehicle elements such as a wing, tail etc. For best practices and recommendations on how to generate meshes for BET simulations, please see the :ref:`Knowledge Base `. .. _bet_tutorial_mesh_creation: The mesh unit used for this tutorial is meters. The first step is to define the extent and spacing of the refinement region in the volume mesh where the BET disk will be placed. The XV-15 rotor blade has a radius of 3.81 meters, with the root of the blades at 0.3429 meters radius. Hence, following the :ref:`recommendations ` mentioned above, our rotor disk refinement region should have the following dimensions: * Radially, we want the refinement region in the mesh to start at the disk center and go beyond 1.1 * the rotor disk radius to about 4.25 meters. * In the axial (thickness) direction, we should chose a value between 10\% and 15\% of the rotor radius; so we picked a 12\% rotor radius value for the actual BET disk thickness in the simulation. Because the mesh refinement region should be slightly larger then the BET disk we will assume a value of 16\% rotor radius thickness for the refinement region in the mesh. Hence, our refinement region will be 3.81 * 16\% ~= 0.6m thick in the x-axis direction. * Since we want at least 20 nodes across the BET disk thickness we use a spacing of 0.02, which leads to 30 nodes across the refinement region in the mesh. * To maintain a good aspect ratio, the spacing in the radial direction is set to 0.03, leading to approximately 4.25/0.03 = 142 nodes in the radial direction in the refinement region. * In the circumferential direction, we use a spacing of 0.06 leading to approximately 445 nodes along the perimeter. * For the hub we will implement it directly within the BET/AD formulation. This means defining polars and blade geometry all the way to the center of the propeller at r=0. The resulting :code:`rotorDisks` section of the volume meshing input json file looks like this: .. literalinclude:: Files/BET_tutorial_rotorDisks.json :linenos: .. _file_downL: To generate our mesh we will use our :ref:`automated tool chain ` to generate the geometry and the mesh. To that end we will need the BET_tutorial_wing.csm ESP input file we :ref:`downloaded above `. We will also use the following `BET_tutorial_surface.json `_ file to generate the surface mesh on the wing, and the following `BET_tutorial_volume.json `_ file to generate the volume mesh. The latter contains the volume mesh settings discussed above that we will apply for the BET disk region outlined above. As we have shown in our :ref:`automated tool chain quickstart` tutorial, generating a mesh via the WEB UI requires just a few clicks. The same can be said if you prefer to use the python API where, as shown in our :ref:`Python-based quickstart `, these two lines of code will generate the mesh using Flow360: .. _python_mesh_generate: .. code-block:: python surfaceMeshId = flow360client.NewSurfaceMeshFromGeometry("BET_tutorial_wing.csm", "BET_tutorial_surface.json") volumeMeshId = flow360client.NewMeshFromSurface(surfaceMeshId=surfaceMeshId, config="BET_tutorial_volume.json") You now have a valid surface mesh of the wing that you can refer to with the :code:`surfaceMeshId` variable and a volume mesh available via the :code:`volumeMeshId` variable. This volume mesh identifier will be needed below when we submit the actual simulation. Following the process described above we obtain meshes that look like the figures below. As we can see, the generated BET disk refinement region is a structured mesh with an unstructured refinement region around the BET disk and wing. We can see that the mesh has over 20 nodes in the axial direction within the BET disk. .. _Fig2_BETMeshFigure: .. figure:: Figures/volumeMeshYSlice.png :align: center :scale: 70% Slice of the volume mesh at wing mid-span (y=5), showing the BET disk refinement region in the axial direction. Notice the structured :code:`rotorDisks` refinement region within an unstructured :code:`refinement` region to better capture the physics of interest. .. _Fig3_BETMeshFigure2: .. figure:: Figures/volumeMeshXSlice.png :align: center :scale: 70% Slice of the volume mesh at the BET disk center (x=-2), showing the BET disk refinement region in the radial and azimuthal direction. .. _bet_tutorial_json_generate: Flow360 BET Configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The next step is to define the inputs to the Flow360.json file. This tutorial is primarily focused on defining the inputs to the :code:`BETDisks` section of the Flow360.json file. Details for other sections can be found in :ref:`Solver Configuration `. Firstly, we will discuss the :ref:`BET disk input data `. The following information is required to run a BET disk simulation within Flow360: Rotor geometric and performance information ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - The :code:`NumberOfBlades` and rotor :code:`radius` define the basic rotor properties. Rotor :code:`radius` should be in :ref:`grid units `, aka :math:`L_{gridUnit}` . - :code:`centerOfRotation` and :code:`axisOfRotation` define the location of the BET disk in your mesh along with the :ref:`thrust axis ` vector aka :code:`axisOfRotation`. - :code:`chords` and :code:`twists` distributions versus radius. These two lists define the twist and chord profile vs span of the blade. The twists are used by the BET implementation to know the local angle of attack that a given section would be seeing. The chords are used to know how large the propeller would be at that section. See figures :numref:`twistVspanPlot` and :numref:`chordVspanPlot` for an example of the twist and chord distribution of the XV15 propellers. - :code:`rotationDirectionRule` defines :ref:`which way the propeller is turning `. - :code:`omega` is the nondimensional :ref:`rotation speed`. .. _bet_thickness: Rotor disk :code:`thickness` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The rotor disk :code:`thickness`, along with the rotor radius define the shape of the cylinder within which the BET formulation will add energy to the flow to simulate the propeller. The center of rotation and axis of rotation define where in space that cylinder is located. Therefore we should make sure that the BET implementation cylinder region is fully enclosed inside the volume mesh refinement region we defined :ref:`above `. Hence the :code:`thickness` should be slightly less then the :ref:`mesh refinement recommended values `. :code:`bladeLineChord` ^^^^^^^^^^^^^^^^^^^^^^ This is used only for time accurate blade line simulations. When doing steady state BET disk simulation, :code:`bladeLineChord` can be ignored or set to 0. Blade :code:`tipGap` ^^^^^^^^^^^^^^^^^^^^ The BET disk formulation has a tip loss correction to account for 3D flow effects near the tip of the blade. If some external feature (duct, shroud, cowling, nacelle, etc.) affects that 3D tip loss, the user can vary the :ref:`tipGap ` parameter to decrease the amount of 3D tip losses all the way to 0 if desired. :code:`nLoadingNodes` and :code:`chordRef` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ These values are used to define the output variables. - :code:`nLoadingNodes` is the number of spanwise nodes that will be used to report propeller sectional loads Ct vs span and Cq vs span values in the **bet_forces_v2.csv** BET output file. Its format is described in details :ref:`here `. - The reference :code:`chordRef` is used to display the resulting Ct and Cq values on the blade's 2D section. It is used to :ref:`calculate the dimensional thrust and torque values` from the output nondimensional Ct and Cq values. The blade MAC is typically an appropriate value. Rotor aerodynamic information ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ To know the performance of the propeller's cross section, :code:`sectionalPolars` are required. They are entered as lift and drag polars for the various radial stations corresponding to a 3 dimensional lookup table in the Mach, Reynolds numbers and Alpha space. These are used by the BET implementation to interpolate the local lift and drag that a given section of the propeller would be experiencing. When starting a BET disk simulation, the hardest part to get right is usually the rotor aerodynamic information. The sectional polars must be obtained and are used as the primary information of the rotor aerodynamic characteristics for BET disk simulations. To obtain the sectional polars and arrange them properly into the BETDisks section of the Flow360.json file, a number of options are available: - One could setup a scripting process to extract the lift and drag coefficients across a range of alphas, Mach and Reynolds numbers and save them in the correct format into the :code:`BETDisks` section of the Flow360.json file as :ref:`defined here ` - The second option is to use the :ref:`ready made translators` we can provide you. This option is highly recommended especially if you have already done some analysis on your propeller using one of the codes or data sources we provide translators for. The BET inputs for this tutorial have been generated using the XROTOR translator. The sectional polars are provided at 5 sectional radii. For your own cases, if you choose not to use one of our translators and instead create your own scripts to define the :code:`BETDisks` section of the Flow360.json input files then please be aware that their are a few :ref:`best practices ` that need to be taken into account when creating the :code:`sectionalPolars`. .. _otherBETParameters: JSON File Inputs ^^^^^^^^^^^^^^^^ Below are some recommendation for setting the other input parameters required by Flow360: Since we want to replicate the airplane mode, pitch 26 |deg| condition discussed in :ref:`this case study `, we need to have the following run conditions: - Tip Mach Number = 0.54 - RPM= 460 (to get the tip mach values above) which leads to Omega= 0.1417 (:ref:`see below `) - Advance ratio (defined as inflow speed over tip speed)= 0.337 which means the inflow Mach = 0.182 - :code:`axisOfRotation`: In this case it is important to note that the X axis points towards the aft of the wing while we want the thrust to be forwards in X, hence our :code:`axisOfRotation` must be [-1,0,0] to have a thrust axis pointing forward in X. See this :ref:`documentation section `. - :code:`rotationDirectionRule`: can be defined using a right-handed or left-handed coordinate system. For more information on the rotation direction see the following :ref:`entry in our knowledge base `. In the sample JSON code :ref:`below ` you can see we chose :code:`rightHand` .. _omega_bet_calc: - :code:`omega`: The definition of :code:`omega` follows the standard :ref:`nondimensionalisation conventions used in Flow360 `. for more information please see our :ref:`dedicated tutorial `. In our case RPM=460, speed of sound of freestream is 340.2 m/s and grid unit is 1 meter so :math:`\text{omega}=\Omega\times L_\text{gridUnit}/C_\infty=\frac{460\times 2\pi}{60\text{ s}}\times\frac{1 \text{ m}}{340.2\text{ m/s}}=0.1417`. - :code:`chordRef`: this value is only used to post-process the sectional loads in the bet_forces_v2.csv file. It is required as an input but is only needed if you want to redimensionalize the extracted local slice Cl and Cd values into dimensional values. :ref:`In this tutorial ` we chose the mean propeller chord to set :code:`"chordRef": 0.3556`. - :code:`tipGap`: this can be used to introduce the presence of a duct/shroud through a tip loss effect, see more in :ref:`the BET knowledge base `. Here we use the default (no effect) by removing the parameter. More recommendations on how to setup the Flow360.json file's parameters can be found in the :ref:`Knowledge Base `. In our case, the :code:`BETDisks` section of the input Flow360.json file looks like this: .. _samplebetJSON: .. code-block:: "BETDisks": [ { "axisOfRotation": [-1,0,0], "centerOfRotation": [-2.0, 5.0, 0], "rotationDirectionRule": "rightHand", "omega": 0.1417, "numberOfBlades": 3, "radius": 3.81, "thickness": 0.4572, "chordRef": 0.3556, "nLoadingNodes": 20, "sectionalRadiuses": [ 0.3429, 0.6477, 1.9431, 3.048, 3.81], "twists": [ { "radius": 0.0, "twist": 90.0 }, { "radius": 0.3429, "twist": 56.2993654 }, ............. { "radius": 3.81, "twist": 19.97515983 } ], "chords": [ { "radius": 0.0, "chord": 0.0 }, { "radius": 0.3429, "chord": 0.4494840642 }, ......... { "radius": 3.81, "chord": 0.3557147064 } ], "MachNumbers": [0, 0.5773502691896257, 0.816496580927726, 0.9486832980505138], "alphas": [ -180.0, -179.0, -178.0, ........ 178.0, 179.0, 180.0 ], "ReynoldsNumbers": [ 1.0 ], "sectionalPolars": [ { "liftCoeffs": [[[...]],[[...]],[[...]],[...]], "dragCoeffs": [[[...]],[[...]],[[...]],[...]], }, { "liftCoeffs": [[[...]],[[...]],[[...]],[...]], "dragCoeffs": [[[...]],[[...]],[[...]],[...]], }, { "liftCoeffs": [[[...]],[[...]],[[...]],[...]], "dragCoeffs": [[[...]],[[...]],[[...]],[...]], }, { "liftCoeffs": [[[...]],[[...]],[[...]],[...]], "dragCoeffs": [[[...]],[[...]],[[...]],[...]], }, { "liftCoeffs": [[[...]],[[...]],[[...]],[...]], "dragCoeffs": [[[...]],[[...]],[[...]],[...]], }] Please note that we have five, .. code-block:: { "liftCoeffs": [[[...],[...],[...],[...]]], "dragCoeffs": [[[...],[...],[...],[...]]], } sections corresponding to the five defined :code:`sectionalRadiuses` where we define the 2D airfoil polars. Each one of the :code:`liftCoeffs` and :code:`dragCoeffs` lists have dimensions of 4 x 1 x 360, relating to the 4 :code:`MachNumbers` by 1 :code:`ReynoldsNumbers` by 360 :code:`alphas`. You can download and inspect the complete `BET_tutorial_Flow360.json file `_ for this case. Now that you have a valid BET_tutorial_Flow360.json file then, using the :code:`volumeMeshId` we created above we can submit the simulation :ref:`via the WEBUI ` or by simply typing the following single python line of code: .. _launch_bet_api: .. code-block:: python caseId = flow360client.NewCase(meshId = volumeMeshId, config="BET_tutorial_Flow360.json", caseName='BET_tutorial') The caseId will now be used below to retrieve the desired output data for postprocessing. So in conclusion, as we have shown, the surface meshing, volume meshing, and case submission can all be triggered in sequence using three lines of Python code: .. code-block:: python surfaceMeshId = flow360client.NewSurfaceMeshFromGeometry("BET_tutorial_wing.csm", "BET_tutorial_surface.json") volumeMeshId = flow360client.NewMeshFromSurface(surfaceMeshId=surfaceMeshId, config="BET_tutorial_volume.json") caseId = flow360client.NewCase(meshId = volumeMeshId, config="BET_tutorial_Flow360.json", caseName='BET_wing_tutorial') .. _bet_tutorial_postprocess: Output and postprocessing ~~~~~~~~~~~~~~~~~~~~~~~~~~ The first thing to check when postprocessing a simulation is its convergence. Getting the **Nonlinear Residuals** to below 1e-10 is the target for simulation accuracy. Figure :numref:`convergence_fig` below shows the convergence plot for this simulation, which achieves our convergnece target. .. _convergence_fig: .. figure:: Figures/BET_tutorial_Convergence.png :align: center :scale: 60% BET Disk run convergence showing very good 7 orders of magnitude residual reductions. As mentioned in our :ref:`quickstart section `, To download the surface data and the entire flow field, use the following command lines, respectively: .. code-block:: python flow360client.case.DownloadSurfaceResults('case_Id', 'surfaces.tar.gz') flow360client.case.DownloadVolumetricResults('case_Id', 'volume.tar.gz') where :code:`case_Id` is the variable returned from the :ref:`python call to launch the case `. Once downloaded, you can postprocess these output files in either Tecplot or ParaView. You can specify the exported data you want in the Flow360.json file under the :code:`volumeOutput` and :code:`surfaceOutput` sections. If the BET disk configuration is simulated for the first time, it is useful to examine the flow field solution, with a particular emphasis on the BET disk metrics. Flow360 outputs :ref:`BET specific volumeOutput metrics ` to help evaluate the BET solution. This helps to make sure that the BET disk input is correct and that the volumetric mesh refinement regions are aligned with expectations. For example, by looking at the contours of the BET metric :code:`betMetric_AlphaRadians`, which is zero outside the BET disk, we can see in :numref:`Fig2_BETMeshFigure` and :numref:`Fig3_BETMeshFigure2` above that, as expected, the BET disk in the simulation is slightly thinner and slightly smaller in radius than the refinement region. Example visualizations of the BET disk angle of attack are shown in :numref:`bet_x_view` and :numref:`bet_side_view` below. .. _bet_x_view: .. figure:: Figures/BET_region.png :align: center :scale: 70% View from behind of BET disk in front of the wing. Visualized using the calculated local blade angle of attack. Notice that this simulation was done with AoA= 5 |deg|, hence we have the expected asymmetry in the local blade angle of attack. .. _bet_side_view: .. figure:: Figures/BET_regionYslice.png :align: center :scale: 70% Side view BET disk in front of the wing. Visualized using the calculated local blade angle of attack. The :ref:`qcriterion ` output is a very good method for visualizing vorticity and generally better understand where propeller wakes are flowing. As we can see in :numref:`Fig1_Config` the vortices being shed by the BET disk are clearly visible. Please note that as the BET disk generates a smooth shear layer once past the initial sharp wake contraction, it is not very well resolved in this relatively coarse mesh. For BET simulations, the Forces and Moments (F&M) values seen in the WebUI as well as reported in the total_forces_v2.csv and surface_forces_v2.csv files only include forces on no-slip walls present in the simulation, they do NOT include the BET disk F&M. The BET disk F&M are only located in the bet_forces_v2.csv file. As outlined in :ref:`this tutorial `, unlike the no-slip walls F&M values in total_forces_v2.csv which use the reference data in the geometry section of the Flow360.json file, the BET forces are in the inertial frame of reference (regardless of the axis of rotation) and the moments are computed around the BET disk center and use a different non dimensionalization set of reference values. In order to get the forces on the whole vehicle, care must be taken to combine the components from the no-slip walls with the components from the BET Disk. This can be done by dimensionalizing the F&M coefficients or converting the F&M coefficients present in the total_forces_v2.csv and BET_forces_v2.csv files to the same denominator. For more details on how to post process BET forces, please see :ref:`this case study `