Engee documentation
Notebook

Loading STL files and calculation of the turbine blade load state

In this script we will show an example of how the Engee environment can:

  1. load a 3D model of a part from STL format
  2. visualise the mesh of this model
  3. calculate the loaded state of the part using MATLAB commands.

To open a CAD file (in STL format), we will use the library Meshes.jl. It allows to work with many different CAD formats and calculation meshes and can prepare a saved 3D model of the object for further manipulations.

For visualisation we first use the standard Plots library built into Engee, then we use the higher-level library Makie. You can evaluate its capabilities by visiting Makie's Plots Gallery.

In the third part, we will demonstrate how Engee can be used to perform an example calculation of the mechanical load experienced by a turbine blade, and we'll zoom in on the graphs.

Loading a 3D model

Let's first connect the necessary libraries for this step

In [ ]:
Pkg.add(["CairoMakie", "Makie", "Animations", "Meshes", "MeshIO"])
In [ ]:
import Pkg; Pkg.add(["Meshes", "MeshIO"], io=devnull);
using Meshes, MeshIO, FileIO, Plots
#plotly();
gr();

Let's specify a working folder for all future operations with files.

In [ ]:
cd( @__DIR__ )

Now let's load the model and display the calculation grid on the graph using separate triangles, each of which can be styled separately in any way.

In [ ]:
obj = load( "Blade.stl" );

p = plot()
for i in obj
    m = Matrix([i[1] i[2] i[3] i[1]])'
    plot!( p, m[:,1], m[:,2], m[:,3], lc=:black, label=:none, lw=.1 )
end
plot!( camera=(120, 30), axis=nothing, border=:none, aspect_ratio=:equal, projection_type=:persp )
display(p)

Why don't we draw a 3D animation of the rotation of this part?

In [ ]:
Pkg.add( "Animations", io=devnull );
using Animations
In [ ]:
obj = load( "Blade.stl" );

@gif for az in 0:10:359
    p = plot()
    for i in obj
        m = Matrix([i[1] i[2] i[3] i[1]])'
        plot!( p, m[:,1], m[:,2], m[:,3], lc=:black, label=:none, lw=.1 )
    end
    plot!( camera = (az, 30), axis=nothing, border=:none, aspect_ratio=:equal )
end
[ Info: Saved animation to /user/start/examples/math_and_optimization/turbine_blade/tmp.gif
Out[0]:
No description has been provided for this image

To demonstrate a high-level method of working with the model, let's connect the library for visualisation Makie, and choose a suitable toolkit for fast graph drawing (CairoMakie). Another option supported by the browser is the package WGLMakie, which requires more complex settings. The other packages (GLMakie and RPRMakie) require additional windows and are not yet supported by Engee.

In [ ]:
import Pkg; Pkg.add(["Makie", "CairoMakie"], io=devnull);
using Makie, CairoMakie
WARNING: using Makie.plot in module Main conflicts with an existing identifier.
WARNING: using Makie.plot! in module Main conflicts with an existing identifier.

Visualise the model with a single line.

The first execution of this cell, immediately after loading the Makie library, may take more than a minute.

In [ ]:
Makie.wireframe( obj, linewidth=.2 )
Out[0]:
No description has been provided for this image

Let's perform the calculations using the MATLAB kernel

For finite element calculations, you generally need to use well-established external tools. There are many excellent research packages in this area. For example, the packages for partitioning a mesh into polygons (tetgen, gmsh) have shells in Julia that can be plugged into Engee to perform calculations.

If you already have an existing project in MATLAB, or if you have found a demo code that is very similar to what you need, Engee will allow you to run it and save the result in the cloud.

In [ ]:
using MATLAB

Let's set up a computational problem and load a 3D model of the part.

The first execution of this cell, immediately after connecting the MATLAB library, may take more than a minute.

In [ ]:
mat"cd $(@__DIR__)"

outp = mat"""
smodel = createpde('structural','static-solid');
g = importGeometry(smodel, 'Blade.stl');

figure;
p = pdegplot( smodel, 'FaceLabels', 'on', 'FaceAlpha',0.5);
axis off;
view( [133.027 16.056] );

saveas( gcf, 'Blade.png' );
""";
>> >> >> >> >> >> >> >> [Warning: MATLAB has disabled some advanced graphics rendering features by
switching to software OpenGL. For more information, click <a
href="matlab:opengl('problems')">here</a>.] 
Fontconfig warning: "/usr/share/fontconfig/conf.avail/05-reset-dirs-sample.conf", line 6: unknown element "reset-dirs"
Fontconfig warning: "/usr/share/fontconfig/conf.avail/05-reset-dirs-sample.conf", line 6: unknown element "reset-dirs"

Let's display the saved image in the Engee environment using the load command built into the Engee library Images.

In [ ]:
using Images
img = Images.load( "Blade.png" )
Out[0]:
No description has been provided for this image

The downloaded file contained only a description of the surface. Now let's create a three-dimensional computational mesh inside this surface.

In [ ]:
outp = mat"""
msh = generateMesh(smodel,'Hmax',0.01);

figure
p1 = pdemesh(msh, 'FaceAlpha', 1)
view([133.027 16.056])

saveas( gcf, "Blade_mesh.png" )
""";
>> >> >> >> >> >> [Warning: Cannot set Renderer to OpenGL on this figure.] 
[> In pdeplot3D (line 276)
In pdemesh (line 129)] 

p1 = 

  Patch with properties:

    FaceColor: [0 1 1]
    FaceAlpha: 1
    EdgeColor: [0 0 0]
    LineStyle: '-'
        Faces: [5488x3 double]
     Vertices: [2744x3 double]

  Use GET to show all properties

In [ ]:
img = Images.load( "Blade_mesh.png" )
Out[0]:
No description has been provided for this image

And thirdly, we need to set the parameters of the problem (computational and physical), in particular the boundary conditions.

Let's calculate the deformation of the blade using the function solve and output a three-dimensional graph, where the mechanical deformation of the part will be amplified hundreds of times and the colour information will show the degree of mechanical stress in the circumference of the given point of the part.

In [ ]:
outp = mat"""
E = 227E9; % in Pa
CTE = 12.7E-6; % in 1/K
nu = 0.27;

s1 = structuralProperties(smodel,'YoungsModulus',E, ...
                            'PoissonsRatio',nu, ...
                            'CTE',CTE);

s2 = structuralBC(smodel,'Face',3,'Constraint','fixed');

p1 = 5e5; %in Pa
p2 = 4.5e5; %in Pa

s3 = structuralBoundaryLoad(smodel,'Face',11,'Pressure',p1); % Pressure side
s4 = structuralBoundaryLoad(smodel,'Face',10,'Pressure',p2);  % Suction side

Rs = solve(smodel);

figure
p2 = pdeplot3D(smodel,'ColorMapData',Rs.VonMisesStress, ...
                 'Deformation',Rs.Displacement, ...
                 'DeformationScaleFactor',100);
%view([116,25]);
view( [133.027 16.056] );

saveas(gcf, "Blade_solved.png");
""";

Let's display two graphs in the same projection: the first one shows the distribution of the blade zones for which we set the boundary conditions. The second one shows the deformed model with marked areas of high mechanical stress.

In [ ]:
img_topo = Images.load( "Blade.png" );
img_mesh = Images.load( "Blade_mesh.png" );
img_solved = Images.load( "Blade_solved.png" );
mosaic(img_topo, img_mesh, img_solved; nrow=1)
Out[0]:
No description has been provided for this image