A CFD Tutorial in Julia: Introduction to Laminar Boundary-Layer Theory

: Numerical simulations of laminar boundary-layer equations are used to investigate the origins of skin-friction drag, ﬂow separation, and aerodynamic heating concepts in advanced undergraduate-and graduate-level ﬂuid dynamics/aerodynamics courses. A boundary-layer is a thin layer of ﬂuid near a solid surface, and viscous effects dominate it. Students must understand the modeling of ﬂow physics and implement numerical methods to conduct successful simulations. Writing computer codes to solve equations numerically is a critical part of the simulation process. Julia is a new programming language that is designed to combine performance and productivity. It is dynamic and fast. However, it is crucial to understand the capabilities of a new programming language before attempting to use it in a new project. In this paper, fundamental ﬂow problems such as Blasius, Hiemenz, Homann, and Falkner-Skan ﬂow equations are derived from scratch and numerically solved using the Julia language. We used the ﬁnite difference scheme to discretize the governing equations, employed the Thomas algorithm to solve the resulting linear system, and compared the results with the published data. In addition, we released the Julia codes in GitHub to shorten the learning curve for new users and discussed the advantages of Julia over other programming languages. We found that the Julia language has signiﬁcant advantages in productivity over other coding languages. Interested readers may access the Julia codes on our GitHub page.


Introduction
Computational fluid dynamics (CFD) simulation is one of the vital steps of the design of a product that includes fluid motion. Since fluid dynamics are extremely complex and the motion equations have nonlinear terms, usage of numerical approaches is inevitable to simulate or predict fluid motion. Predictions can also be done with experiments. However, it is usually costlier than a regular CFD simulation. On the other hand, fundamental knowledge about the flow, that is planned to simulate, is necessary because of the required numerical approach decision. Learning the canonical flows well is extremely important in this point because most of the complex flow consists of a combination of a couple of canonical flows. An airfoil CFD simulation can consist of boundary-layer flow over the smooth part of the airfoil, mixing layer flow where the tail ends, and blunt body flow in the wake region. One airfoil simulation consists of three different canonical flows. A full understanding of the canonical flows is extremely important to model an accurate airfoil simulation.
Prandtl [1] stated that some of the terms in the Navier-Stokes equations can be neglected for the boundary-layer flows. As a result of this assumption, well-known boundary-layer equations arose. These approaches are still valid after a century and the resultant system of equations inspired lots of researchers in their studies. One of them was Blasius who is the Ph.D. student of Prandtl. Blasius [2] worked on the same problem as Prandtl did. However, he aimed to overcome the enigma of turbulence by considering the phenomenon of boundary-layer flow explained by Hager [3]. He further simplified the boundary-layer equations for a flat plate. He assumed that the flow is parallel. In other words, the velocity component in the parallel direction is not zero and the velocity in the transverse direction is zero. Moreover, he represented the resultant system of equations with a third-order ordinary differential equation, which is known as the Blasius similarity solution.
The Falkner-Skan similarity solution is another laminar similarity solution. Cebeci [4] explains the Falkner-Skan equations named after V. M. Falkner and Sylvia W. Skan. Falkner and Skan generalized the Blasius similarity solution for non-parallel flows, such as wedge flows and corner flows. The resultant equation can be used to predict the boundary-layer thickness for wedge flow. It has to be noted that these assumptions are available in the laminar region. Once the turbulence occurs, both of these similarity solutions will be inaccurate. In the incompressible region, the Falkner-Skan equation can be used without additional equation; however, after the compressibility limit, the temperature effect must be introduced to the system as an additional equation. If the Falkner-Skan equation is solved with the energy equation, the boundary-layer profile can be obtained in the compressible region.
One of the other Ph.D. students of Prandtl is Karl Hiemenz who worked on Hiemenz flow which is a type of stagnation point flow. Hiemenz [5] formulated and calculated the stagnation point problem as explained in the Schlichting [6]. The problem was a special case of the Falkner-Skan similarity solution. Howarth [7] also worked on the same problem and concluded similar results. Another Ph.D. student of Prandtl, Fritz Homann [8] worked on the same problem for axisymmetric bodies as Schlichting [6] explains. Homann's similarity formulation was for a sphere while Hiemenz's similarity formulation was for a cylinder. Both similarity solutions are being widely used for stagnation flows.
The aforementioned papers are the origins of the boundary-layer theory. As it is mentioned, the boundary-layer theory is the origin of many problems, such as the laminar to turbulent boundary-layer transition and flow separation. The main concern of these researches is to increase the performance of the vehicle because the transition increases the heat transfer and the vehicle requires a better thermal protection system at high speeds due to increased heat transfer rate. On the other hand, flow separation may lead to a lift force loss on the wing as a result, the performance of aircraft decreases. Since the focus of the present paper is the fundamentals of laminar boundary-layer theory, the details will not be provided about advanced researches. However, readers who are interested in details may check [9][10][11][12] for subsonic boundary-layer transition, Ref. [13][14][15][16][17][18][19][20][21] for supersonic/hypersonic boundary-layer transition, and Ref. [22][23][24] for flow separation. The other researches where boundary-layer flow is involved are [25][26][27][28][29][30].
Understanding the aforementioned fundamental flows are crucial for a senior undergraduate student or a graduate student in order to simulate more complex flows. However, modeling these equations in a computer environment requires more than knowledge about canonical flows instead it requires knowledge about programming languages as well. There are several learning modules and papers [31][32][33][34][35] for computational fluid dynamics simulation coding; however, there is not enough publication for Julia language [36]. It is a relatively new coding language among the other coding languages such as Fortran, C/C++, Python, and MATLAB but it is getting popular fast because it is trying to fill the gap between the language of the state-of-art CFD codes, Fortran and C/C++, and straightforward/user-friendly languages, Python and MATLAB. Most of the state-of-art CFD codes are written in Fortran and C/C++ because it is so fast and random access memory usage (RAM) can be reduced drastically. On the other hand, MATLAB and Python have user-friendly and easy syntax which makes them favorites of students, with a price, which is the speed of computation. Julia is a language that tries to fill this gap between two different coding styles. It has a user-friendly environment, while also being fast. It provides a working space that helps users to write clear, high-level, generic code that resembles mathematical formulas. Julia's ability to combine high-performance with productivity makes it a great choice for researchers working in different areas.
In this paper, fundamental flow problems such as Hiemenz flow, Homann flow, Blasius flow, and Falkner-Skan flow will be derived from scratch and modeled in the Julia environment. The finite-difference discretization in space with Thomas algorithm as linear system solver is used. Outputs of the code are provided and they are compared with the literature. Additionally, the advantages of the Julia language over other languages will be discussed. The computer codes and the implementation instructions will help students to understand the fundamental flows which will provide insight for student's course work and researches. Using these examples, they can solve more complex flow types and develop their own codes. We make all these codes available on GitHub and they are accessible to everyone. We provide installation instruction for Julia and the required packages in Appendix A. The GitHub link of the codes also can be found in Appendix A.

Laminar Boundary-Layer Theory
Understanding canonical flows is crucial to understanding more complex flows such as flow over a wing or an airfoil. Hosseini et al. [37] studied flow over a wing section with a direct numerical simulation (DNS) study. They created a great video about how flow is formed over the aircraft. The video shows the development of the boundary-layer, how the trailing edge looks like a mixing-layer flow, and how Karman vortex street type of wake structures occurs. If the pre-study work is examined, it can be seen that the mesh structure is built on the flow prediction. Using a finer mesh on the critical regions is a key point of the CFD and it requires predictions about the possible flow behavior. The boundary-layer is the origin of many engineering problems in aerodynamics, including wing stall, the skin friction drag on an object, and the heat transfer that occurs in high-speed flight. In this present paper, boundary-layer theory will be examined under two subsections, which are laminar boundary-layer problems and stagnation point problems. In this present paper, fundamental fluid dynamics problems related to boundary-layer theory will be derived and implemented in a relatively new programming language, Julia. The contribution is employing the Julia language. The governing equations and solution methodologies are already published in the literature. The interested reader should refer to the additional references [6,38] for detailed derivations. The manuscript may enable students to adopt the programming language easily.

Laminar Boundary-Layer Flow Problems
Velocity distribution over a flat plate can be represented with a similarity solution. In this subsection, Blasius and Falkner-Skan similarity solutions will be derived from scratch and they will be solved numerically in the Julia environment. The Julia codes will be available to shorten the learning curve.
where u and v are the velocities in the x-direction and y-direction, respectively. p is the pressure, ν is the kinematic viscosity, ρ is the density. If Equations (1)-(3) are nondimensionalized with: where L is the plate length and U ∞ is the free-stream velocity. The two-dimensional, incompressible non-dimensional Navier-Stokes equations can be shown as: Star superscript ([ ] * ) corresponds to non-dimensional variable. In a boundary-layer flow, some variables are smaller than others. For example, u * = O(1) and In the continuity equation, two terms must be in the same order to obtain 0 so ∂v * ∂y * = O(1). It can be seen that from Figure 1, y = O(δ * ) where δ * is the nondimensionalized boundary-layer thickness. From here, it can be concluded that v = O(δ * ). It has to be noted that δ * << 1. If the same approach is applied to momentum equations, the final system of equations will be: For an inviscid flow, where the Reynolds number is so high, the viscous term can be neglected. The pressure is constant as obtained in the Equation (11) and v = 0. Equation (10) will be: where U e and P e are the inviscid velocity and pressure. Finally, the two-dimensional boundary-layer equations in the dimensionless form can be written as: ∂u ∂x It has to be noted that star superscript is suppressed to avoid confusion. In order to solve this problem, similarity transformation can be used. The similarity parameter (η) can be chosen as: After that, velocity components can be shown as: If Equations (13) and (14) are rearranged with the given velocities, the boundary-layer equations will be: In order to make the next procedure easier, it can be assumed that F = f . After that, Equation (18) can be integrated and put into Equation (19). The final ordinary differential equation can be obtained as: 2 The boundary conditions of the system will be: The given assumptions reduced the system of second-order partial differential equations into a third-order ordinary differential equation. The computational approach will be examined in the Julia framework.

Numerical Solution of Blasius Flow Problem
In this computational section, the solution of the third-order ordinary differential equation will be transformed into two equations and they will be solved with Thomas algorithm [39] which is one of the best methods for the tridiagonal matrices. It has to be noted that the same equations can be solved with any other methods such as Runge-Kutta, Runge-Kutta-Fehlberg, compact finite difference, high-order finite-difference; however, in this present paper, authors used the finite difference method for spatial discretization with the Thomas algorithm for the linear system solution. If it is assumed that f = h and f = p in Equation (20), the system of equations will be: with the following boundary conditions: If the second-order central finite difference method is applied to h variable: In this paper, details of the finite difference and derivation of it from Taylor's series will not be covered. If the reader is curious about the derivation of them, the book of Moin [40] can be checked. If the finite difference approach for h is substituted into the Equation (24), the final equation will be: where the A n , B n , and C n are: with the boundary conditions for the system the tridiagonal system (Ax = b) can be shown as: It has to be noted that the first and last rows of the matrix are known and they are coming from the boundary conditions. In order to solve this problem, the Thomas algorithm can be applied. If relation between h n and h n−1 is: If Equation (37) is substituted into Equation (31), the final equation will be: If Equations (36) and (38) are compared, G n and H n coefficients can be found as: The problem here is that one has to know G 1 and H 1 in order to start the calculation. H 1 can be assumed as 0 and the G 1 can be calculated as 0 from the boundary conditions. Once G 1 and H 1 are calculated, G n and H n can be calculated from Equations (39) and (40). The given formulations can be implemented as it is shown in Listing 1.
The problem in Listing 1 is the usage of the p and h values which are not defined yet. In order to start to iteration, the initial assumption for h must be given. Most of the time, the linear assumption is the best assumption. Figure 2 shows the schematic of the profile transformation after some iterations. Once the initialization of h is done, p can be calculated from the integration of p = h. The discrete integration of p can be written as: Listing 1. Implementation of Thomas algorithm for Blasius profile. § ¤ If the integration is done numerically with the trapezoidal rule [41], the initial guess for h and p can be calculated in Julia as shown in Listing 2 After the initialization is done, Listing 1 can be run with p calculation of Listing 2, until the change in h is smaller than an arbitrary parameter which can be taken as 1 × 10 −8 .
The final profile will be as shown in Figure 3. The profile is also compared with Schlichting [6] in order to validate the results. It has to be noted that, Schlichting used η = y 2νx U∞ as similarity coordinate so the figure is plotted according to this nondimensionalization. Listing 2. Implementation of initial velocity guess and initial p for Blasius profile. § ¤  (13) and (14), and satisfies the following equation: can be considered as self-similar. If boundary-layer Equations (13) and (14) are considered and similarity a transformation is assumed as: .
If the continuity equation of boundary-layer Equation (13) is modified with the given transformation, the final equation will be: If Equation (44) is integrated over ξ to find the velocity v, the v velocity will be: v(x, ξ) = −(U e g) f + U e ξg f + H(x).
H(x) can be calculated from the boundary conditions on the wall where ξ is zero and correspondingly, velocities and f (0) are zero. H(x) will be 0 if f (0) is chosen as 0. If calculated derivatives and velocities are substituted into Equation (14), after some simplification, the final equation will be: Since f must be the function of ξ only and must not be a function of x, the coefficients of second and third terms must be constant. The final Falkner-Skan equation for the family of self-similar solutions: f where α = g ν (U e g) and β = g 2 U e ν . The α and β can be further solved for the velocity scale and length scale. If the following consideration is applied: If (U e g 2 ) is written in terms of α * and β * , the obtained equation integrated with respect to x, the resultant equation will be: The constant of the integration represents a shift in the origin on x. Hence it doesn't affect the result and it also can be calculated from the stagnation point where x = 0 and U e = 0 as a result, c = 0. If relation of β * = g 2 U e is divided by Equation (50) and integrated with respect to x, U e can be calculated as: where m = β * 2α * −β * and c 1 is a positive or negative constant which depends on the sign of U e . It can be concluded from these calculations that similar solutions exist when the inviscid velocity is proportional to x raised to some power. Next, Equation (50) can be used by taking c = 0 to calculate the g which is: Self-similar boundary-layers occur when the external velocity is the simple power law (U e = U 0 (x/L) m ), where the arbitrary constants U 0 and L have the same sign as U and x. The similarity variable for these kinds of flows can be written as: When U e and x have the same signs, the Falkner-Skan equation can be written as: The two arbitrary constants α and β have been reduced to one constant m by fixing the scale for the function δ(x). The boundary conditions of the equation are: If the Falkner-Skan Equation (54) is carefully examined, it can be seen that when the constant m is 0, the equation will be Blasius flow. Moreover, if the constant m is 1, the equation will be Hiemenz flow (see Section 2.2.1). This important point is stated before and it is emphasized one more time after the derivation. Another great usage of the Falkner-Skan equation is to simulate the boundary-layer over a wedge with half-angle θ = mπ m+1 when the m is between 0 and 1. If the m is in between 1 and 2, the Falkner-Skan equation will solve a corner flow with θ > π 2 . The visual schematic of four different physical flows that can be calculated from the Falkner-Skan equation can be seen in Figure 4. One interesting point of the equation is that when m = −0.0904, the obtained profile will have zero-shear at the wall which corresponds to the verge of the separation point for all x stations.

Numerical Solution of Falkner-Skan Flow Problem
In this section, the Falkner-Skan equation will be solved with the Thomas algorithm and central finite difference scheme. In order to do that, the third-order ordinary differential equation should be reduced to second-order and first-order differential equations as it is done in Blasius flow. If it is assumed that f = h and f = p in Equation (54), the system of equations will be: where the boundary conditions of the system are: If finite difference scheme is applied to h variable, the final system of equations will be: where the A n , B n , C n , and D n are: The relation between h n and h n−1 is taken as it is done in Blasius flow. When Equation (37) is substituted into Equation (63), the final G n and H n will be: The implementation of these variables in the Julia environment can be seen in Listing 3.

¦ ¥
The final profiles for the varying m values can be seen in the Figure 5. The profiles are also compared with Schlichting [6] in order to validate the results. It has to be noted that,

Stagnation Point Flow Problems
Boundary-layer velocity distribution over a wall that is perpendicular to the flow velocity vector can be represented with a similarity solution. In this subsection, Hiemenz and Homann similarity solutions will be derived from scratch and they will be solved numerically in the Julia environment. The Julia codes will be available to shorten the learning curve.

Hiemenz Flow Problem
This problem is that of a fluid flow that is parallel to the y-axis in the far-field impinging on a wall that coincides with the x-axis. The flow which is perpendicular to a cylinder can be assumed as the Hiemenz flow around the stagnation point. The schematic description of the Hiemenz flow can be seen in Figure 6. In the Hiemenz flow, viscous forces away from the wall become so small in comparison with the inertia forces, particularly when the Reynolds number is large. In this case, inviscid irrotational flow assumption (ξ = ∇ × U = 0) can be done. The velocity can be represented with a scalar function, φ, which is the velocity potential. The velocities in the x-direction and y-direction can be written as: If the dimensional Navier-Stokes equations (Equations (1)-(3)) are considered for this flow as well, and the continuity equation becomes: On the wall, in the absence of viscosity, the flow can slip in the x-direction but in y-direction the velocity must be zero ( ∂φ ∂y | y=0 = 0) because of the no-penetration boundary condition. The inviscid flow solution for the potential function was found to be: where a is a constant that depends on the freestream flow and the body shape. This solution satisfies the governing equations for inviscid, irrotational flow, and the boundary conditions which can be shown as: Since potential the function is obtained, the stream-function can be calculated from the potential function. the velocity components, in terms of stream-function, ψ (x,y) : If Equation (74) is integrated for x and y, the stream function can be found as: In order to find the pressure in the inviscid flow, Bernoulli equation [42] can be used. The pressure from the Bernoulli equation is: where p 0 is the stagnation pressure and ρ is the density. So far, flow is assumed as inviscid flow; however viscous forces will modify the inviscid solution, in particular in the ydirection. Hence, the viscous velocity components can be assumed as: If Equations (77) and (78) are substituted in the Navier-Stokes equations (Equations (1)-(3)), the final system of equations will be: Once Equation (79) is substituted into Equations (80) and (81), two non-linear ordinary differential equations can be obtained as: It has to be noted that these two equations are coupled, which means they have to be solved together. If the x-momentum and y-momentum are solved for pressure, it can be seen that the pressure will be in the form of: where H(y) is a function depends on only y. On the other hand, if the inviscid pressure compared with the viscous pressure as y − → ∞, the pressure gradient in x-direction and y-direction can be found as: If the pressure gradients are substituted into Equations (82) and (83), the resultant system of ordinary differential equations can be found as: Momentum equations are decoupled in this system of equations so once, f (y) is calculated from Equation (87), F(y) in the Equation (88) can be solved. The boundary conditions of the system are: Additionally, F(y − → ∞) = y 2 can be obtained from y-momentum equation as y − → ∞. The final Equations (87) and (88) can be solved with the given boundary conditions; however, it is possible to get rid of the dependence on a. In order to do that, affine transformation [43] can be used. If it is assumed that f (y) = Aϕ(η) and y = Bη where A and B are constant to be determined, the f derivative functions can be calculated as: If Equations (93)-(95) substituted into the Equations (87) and (88) and assume that ν AB = 1 and a 2 B 2 A 2 = 1, the A and B coefficients can be calculated as: The given transformation allows to reduce two ordinary differential equations into one third-order ordinary differential equation as: where the boundary conditions are: and the velocities: the resultant equation along with the boundary conditions can be solved with different numerical approaches such as Runge-Kutta, Runge-Kutta-Fehlberg, compact finite difference, high-order finite difference; however, in this present paper, the Thomas algorithm with finite difference discretization will be used to solve the Hiemenz profile in the Julia framework.

Numerical Solution of Hiemenz Flow Problem
The computational approach for the Hiemenz flow is similar to the Blasius solution since the final ordinary equation of the Hiemenz flow (Equation (98)) is similar to the Blasius similarity solution (Equation (20)). If it is assumed that ϕ = h and ϕ = p in Equation (98), the system of equations will be: where the boundary conditions of the system are: If finite difference scheme is applied to the h variable as in Blasius flow. The final system of equations will be: where the A n , B n , C n , and D n are: The relation between h n and h n−1 is taken as it is done in Blasius flow. When Equation (37) is substituted into the Equation (109), the final G n and H n coefficients can be found as: In order to start the calculation, H 1 can be assumed as 0 and the G 1 can be calculated as 0 from the boundary conditions. Once G 1 and H 1 are calculated, G n and H n can be calculated from Equations (114) and (115). p can be calculated as it is done for Blasius flow: The system of equations can be implemented in the Julia environment as it is shown in Listing 4. The linear profile assumption is taken as the initial condition of h (see Figure 2) as it is done for the Blasius solution. The reason hp and errorPro f ile variables are used in the Listing 4 is that the linear profile converges to the Hiemenz profile in each iteration so in order to check the difference between previous and present profiles, the solution vector from the previous iteration is copied and it is compared with the new solution vector. If the difference between these two solution vectors is less than , which is an arbitrary limit and can be taken as 1 × 10 −8 , then it can be said that the solution has converged. It has to be noted that can be taken as any number; however, if it is small, the solution will be more accurate. The final result of the Hiemenz flow can be seen in Figure 7. The results are also validated with White [44].

Homann Flow Problem
Homann flow is similar to Hiemenz flow. The only difference is that Homann flow is an axisymmetric version of the Hiemenz flow. The same schematic ( Figure 6) can represent this flow as well; however, in this flow, the circle is the projection of a sphere. On the other hand, it was the projection of a cylinder in Hiemenz flow. Derivation of the Homann similarity solution has the almost same procedure as well but it uses cylindrical coordinates instead of Cartesian coordinates. The velocity components of the flow can be shown as: p =p(r, z).
(120) Figure 7. The velocity distribution of Hiemenz similarity solution obtained by Julia code and data digitized from White [44].
As axisymmetric assumptions, derivative with respect to θ ( ∂ ∂θ ) and v θ can be assumed as zero. The Navier-Stokes equations in cylindrical coordinates can be written as: If the same procedures applied to Navier-Stokes in Cartesian coordinates for Hiemenz flow, are applied in cylindrical coordinates, the final potential function and stream function will be: where k is a constant which depends on the freestream flow and the body shape. The corresponding velocities are: Once velocities are calculated, the pressure from the Bernoulli can be calculated as: The viscous velocity components and pressure can be calculated as:

¦ ¥
After the affine transformation, the final ordinary differential equation will be: where the boundary conditions of the equation is: If one compares Hiemenz and Homann similarity solutions (see Equations (98) and (132)) the only difference is the 2 in the second term. In the same manner, the computational process will be the same except for two lines of code.

Numerical Solution of Homann Flow Problem
Since equations of Hiemenz and Homann similarity solutions are the same except one coefficient, procedures for the solution are also the same, except for two lines of code. If it is assumed that ϕ = h and ϕ = p in Equation (132), the system of equations will be: where the boundary conditions of the system are: If the finite difference scheme is applied to the h variable, the final system of equations will be: A n h n+1 + B n h n + C n h n−1 + D n = 0, where the A n , B n , C n , and D n are: The final G n and H n coefficients are the same as Hiemenz flow as well and they are: The final code can be seen in Listing 5. If the Hiemenz code (4) and Homann code (5) are compared, the only difference is in the A and C and it is because of the finite difference approach for the h .

¦ ¥
The final solution profile can be seen in Figure 8. The results are also validated with White [44]. One can use these results to validate their own codes. Reference data will be shared on GitHub as well.

Discussion
Fast computational fluid dynamics solvers are crucial for engineers because the design process requires a lot of simulations to reach the final and optimized design. One of the most important factors that make a solver fast is the language itself. Writing almost the same script in different languages may give different solution central processing unit (CPU) times. For instance, a script that uses long and complex for loops in both Julia and Python environments will result in different solution times because Python is slower with for loops in general. The reasons that cause this slow behavior will not be covered in this paper since it is out of the scope of this paper. However, it is important to state these differences in order to decide which coding language is proper for the simulation that is planned.
Sometimes, some other criteria, such as a user-friendly environment, might be the critical condition. The easy matrix-matrix multiplication and backslash linear system solver can be some of the user-friendly examples. In CFD, the usage of vectors and matrices is so common. Most of the time, it is required to multiply or add vectors or matrices with one another. Fortran, which is one of the fastest languages and also one of the fundamental languages in the CFD industry, does not have a built-in element-wise vector or matrix multiplication feature. This requires the use of for loops for each element-wise matrix and vector operation. As a result of this, every time, one needs to use a for loop to do these operations. This ends up with hard-to-read codes and also excessive usage of indices is another source of possible mistakes that will cause trouble during the debugging. However, in the Julia environment, it can be done in one line without any trouble. Listing 6 is showing the two for loop usage. Both of them use Julia syntax in order to prevent confusion; however, it is required to state that Fortran has a different syntax than this but, logically, the for loops are the same with Fortran logic.
Another user-friendly feature of Julia over Fortran is to plot a vector in the code with built-in functions. However, in Fortran, it is not possible to do it with built-in functions so one needs to extract the solution vector or matrix to an external file to visualize it. As it is stated before, coding language selection can be an important topic. In this section, the strong sides of the Julia environment will be stated. One of the user-friendly features of Julia is compact for loop syntax. Listing 7 shows the traditional way and compact way to use a for loop in the Julia environment. of the complex flow consists of a combination of a couple of canonical flows. For example, an airfoil CFD simulation can consist of boundary-layer flow over the smooth part of it, mixing layer flow where the tail ends, and blunt body flow in the wake region. In other words, one airfoil simulation consists of three different canonical flows. A full understanding on canonical flows is extremely important in order to simulate similar flows accurately and cheaply. In this paper, boundary-layer theory is introduced and boundary-layer flows are derived from scratch. The Blasius flow, Hiemenz flow, Homann flow, Falkner-Skan flow are the focus of this paper. Once the derivations of them are completed, derived forms are implemented in the Julia environment. In order to model the equations, a finite difference scheme for space discretization is used and the Thomas algorithm is used for the linear system solution. It has to be noted that other methods such as Runge-Kutta, Runge-Kutta-Fehlberg, compact finite difference, high-order finite difference can also be used to solve the given ODEs; however, in this present paper, authors preferred the finite difference method and Thomas algorithm. The authors further discussed the advantages of the Julia language over some other coding languages available in the literature. It is shown that Julia syntax is so straightforward, easy, and user-friendly. Strong sides of the Julia environment are stated with the given comparisons as well. The popularity of Julia may drastically increase in the near future because of its potential. Data Availability Statement: All the data used and generated in this study is available in the GitHub link provided in Appendix A.

Conflicts of Interest:
The authors declare no conflict of interest. This software contains a set of packages for plotting, optimization, machine learning, database, and much more. Pluto is appropriate for small scripts while JuliaPro is better for more complex codes. The GitHub link of the codes used in this paper is: • https://github.com/frkanz/A-CFD-Tutorial-in-Julia (accessed on 1 June 2021)