1+ <!DOCTYPE html>
2+
3+ <!-- ______ ______ _____ _ _ -->
4+ <!-- | ____| ____| /\ / ____| (_) | | -->
5+ <!-- | |__ | |__ / \ | (___ ___ ____ _ ____ | |_ -->
6+ <!-- | __| | __| / /\ \ \___ \ / __| __| | _ \| __| -->
7+ <!-- | | | |____ / ____ \ ____) | (__| | | | |_) | | -->
8+ <!-- |_| |______/_/ \_\_____/ \___|_| |_| __/| | -->
9+ <!-- | | | | -->
10+ <!-- |_| | |_ -->
11+ <!-- Website: https://feascript.com/ \__| -->
12+
13+ < html >
14+ < head >
15+ < title > FEAScript: Heat Conduction in a Two-Dimensional Fin Tutorial</ title >
16+ < link rel ="icon " type ="image/x-icon " href ="../assets/favicon.ico " />
17+ < meta http-equiv ="Content-Type " content ="text/html; charset=UTF-8 " />
18+ < meta
19+ name ="keywords "
20+ content ="finite elements, fem, galerkin, cfd, computational mechanics, javascript "
21+ />
22+ < meta name ="viewport " content ="width=device-width " />
23+ <!-- Link to the CSS files -->
24+ < link href ="../FEAScript-website.css " rel ="stylesheet " type ="text/css " />
25+ < link href ="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap " rel ="stylesheet " />
26+ <!-- Import the Math.js library for mathematical operations -->
27+ < script src ="https://cdnjs.cloudflare.com/ajax/libs/mathjs/5.0.0/math.min.js "> </ script >
28+ <!-- Import the Plotly.js library for plotting -->
29+ < script src ="https://cdnjs.cloudflare.com/ajax/libs/plotly.js/2.27.0/plotly.min.js "> </ script >
30+ <!-- Import MathJax for writing equations -->
31+ < script src ="https://polyfill.io/v3/polyfill.min.js?features=es6 "> </ script >
32+ < script
33+ id ="MathJax-script "
34+ async
35+ src ="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js "
36+ > </ script >
37+ <!-- Import the run_prettify.js library for JavaScript code coloring *** Deprecated library *** -->
38+ < script src ="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js "> </ script >
39+ < style >
40+ # plot {
41+ width : 100% ;
42+ max-width : 700px ;
43+ margin : 0 ;
44+ }
45+ # orientation-message {
46+ display : none;
47+ color : red;
48+ font-weight : bold;
49+ }
50+ </ style >
51+ < script type ="module ">
52+ import {
53+ FEAWorkerScript ,
54+ plotSolution ,
55+ printVersion ,
56+ } from "https://feascript.github.io/FEAScript-core/src/index.js" ;
57+ </ script >
58+ </ head >
59+
60+ <!-- Google tag (gtag.js) -->
61+ < script async src ="https://www.googletagmanager.com/gtag/js?id=G-1JPK0KLEC9 "> </ script >
62+ < script >
63+ window . dataLayer = window . dataLayer || [ ] ;
64+ function gtag ( ) {
65+ dataLayer . push ( arguments ) ;
66+ }
67+ gtag ( "js" , new Date ( ) ) ;
68+
69+ gtag ( "config" , "G-1JPK0KLEC9" ) ;
70+ </ script >
71+
72+ < body >
73+ < h1 class ="top ">
74+ < a href ="../index.html ">
75+ < img
76+ src ="../assets/FEAScriptLogo.png "
77+ alt ="FEAScript Logo "
78+ id ="responsive-logo "
79+ style ="vertical-align: middle "
80+ />
81+ </ a >
82+ </ h1 >
83+ < h1 > Heat Conduction in a Two-Dimensional Fin Tutorial</ h1 >
84+
85+ < ul id ="menu ">
86+ < li > < a href ="#mathematicalformulation "> Mathematical Formulation</ a > </ li >
87+ < li > < a href ="#solvingwithfeascript "> Solving with FEAScript</ a > </ li >
88+ < li > < a href ="#results "> Results</ a > </ li >
89+ </ ul >
90+
91+ < div class ="highlight-container ">
92+ < p >
93+ In this tutorial, we address a stationary heat transfer problem within a two-dimensional rectangular
94+ domain. This is a typical cooling fin problem. Cooling fins are commonly used to increase the area
95+ available for heat transfer between metal walls and poorly conducting fluids such as air.
96+ </ p >
97+ </ div >
98+
99+ < h2 id ="mathematicalformulation "> < a name ="Mathematical formulation "> </ a > Mathematical Formulation</ h2 >
100+ < p >
101+ Steady heat conduction is described by the Laplace equation: \(\nabla^{2}T(x,y) = 0\), where \(T\)
102+ signifies the temperature values.
103+ </ p >
104+ < img src ="../assets/HeatConduction2DFin.png " width ="300 " />
105+ < p >
106+ The above schematic illustrates the problem domain and outlines the associated boundary conditions. The
107+ constant temperature boundary conditions are implemented as Dirichlet types in the finite element code.
108+ The symmetry boundary condition is implemented as a Neumann zero-flux type \( \left(
109+ \frac{dT}{dx}|_{x=0}=0 \right) \), while the convective cooling boundary condition is of the Robin type.
110+ Specifically, the latter is expressed as \(\frac{dT}{dy}|_{y=4}=-{\frac{h}{k}}(T-T_0)\), where \(h\) is
111+ the heat transfer coefficient, \(k\) the thermal conductivity and \(T_0\) is the external temperature.
112+ We assume here that \({\frac{h}{k}}\) = 1 m< sup > -1</ sup > and \(T_0\) = 20 °C.
113+ </ p >
114+
115+ < h2 id ="solvingwithfeascript "> < a name ="Solving with FEAScript "> </ a > Solving with FEAScript</ h2 >
116+ < p >
117+ Below is a demonstration of how to use the FEAScript library to solve this stationary heat transfer
118+ problem in your web browser. You only need a simple HTML page to run this example where the following
119+ code snippets should be included. First, we should load the required external libraries:
120+ </ p >
121+ < pre class ="prettyprint ">
122+ <head>
123+ . . .
124+ <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/5.0.0/math.min.js"> </script>
125+ <script src="https://cdnjs.cloudflare.com/ajax/libs/plotly.js/2.27.0/plotly.min.js"> </script>
126+ . . .
127+ </head></ pre
128+ >
129+ < p >
130+ We should then define the problem parameters, such as the solver type, the geometry configuration, and
131+ the boundary conditions. This is performed using JavaScript objects directly in the HTML file:
132+ </ p >
133+ < pre class ="prettyprint ">
134+ <body>
135+ . . .
136+ <script type="module">
137+ // Import the FEAScript library
138+ import { FEAWorkerScript, plotSolution, printVersion } from "https://feascript.github.io/FEAScript-core/src/index.js";
139+ window.addEventListener("DOMContentLoaded", async (event) => {
140+
141+ // Print FEAScript version
142+ printVersion();
143+
144+ // Create a new FEAWorkerScript instance
145+ const model = new FEAWorkerScript();
146+
147+ // Ensure the worker is ready
148+ await model.ping();
149+
150+ // Set solver configuration
151+ await model.setSolverConfig("solidHeatTransferScript");
152+
153+ // Define mesh configuration
154+ await model.setMeshConfig({
155+ meshDimension: "2D",
156+ elementOrder: "quadratic",
157+ numElementsX: 8,
158+ numElementsY: 4,
159+ maxX: 4,
160+ maxY: 2,
161+ });
162+
163+ // Define boundary conditions
164+ await model.addBoundaryCondition("0", ["constantTemp", 200]);
165+ await model.addBoundaryCondition("1", ["symmetry"]);
166+ await model.addBoundaryCondition("2", ["convection", 1, 20]);
167+ await model.addBoundaryCondition("3", ["constantTemp", 200]);
168+
169+ // Set solver method
170+ await model.setSolverMethod("lusolve");
171+
172+ // Solve the problem and get the solution
173+ const { solutionVector, nodesCoordinates } = await model.solve();
174+
175+ // Plot the solution as a 2D contour plot
176+ plotSolution(
177+ solutionVector,
178+ nodesCoordinates,
179+ "solidHeatTransferScript",
180+ "2D",
181+ "contour",
182+ "solutionPlot"
183+ );
184+
185+ // Terminate the worker
186+ model.terminate();
187+
188+ });
189+ </script>
190+ . . .
191+ </body></ pre
192+ >
193+ < p >
194+ In the boundary condition definition, the numbers at the left side (from 0 to 3) indicate the boundaries
195+ of the geometry (the mesh generator of FEAScript has assigned numbers to the boundaries, starting from
196+ the bottom boundary and proceeding clockwise). The `constantTemp` condition sets a constant temperature
197+ value. The `symmetry` boundary condition represents a zero-flux type. Finally, the `convection`
198+ condition describes a convective heat transfer scenario. In addition, the second argument of the
199+ `constantTemp` boundary condition corresponds to the constant temperature value. For a `convection`
200+ boundary condition, the second argument represents the \({\frac{h}{k}}\) value, and the third argument
201+ indicates the external temperature \(T_0\).
202+ </ p >
203+ < p >
204+ After solving the case, the results are demonstrated in a 2D contour plot. To visualize it, include an
205+ HTML container where the plot will render:
206+ </ p >
207+ < pre class ="prettyprint ">
208+ <body>
209+ . . .
210+ <div id="solutionPlot"> </div>
211+ . . .
212+ </body></ pre
213+ >
214+ < p >
215+ The `solutionPlot` is the id of the div where the plot will be rendered. This id is passed as an
216+ argument to the plotSolution function to specify the target div for the plot.
217+ </ p >
218+
219+ < h2 id ="results "> < a name ="Results "> </ a > Results</ h2 >
220+ < p >
221+ Below is the 2D contour plot of the computed temperature distribution. This plot is generated in real
222+ time using FEAScript. You can find a minimal example of this tutorial in the
223+ < a
224+ href ="https://github.com/FEAScript/FEAScript-core/tree/main/examples/solidHeatTransferScript/HeatConduction2DFin "
225+ target ="_blank "
226+ > example directory</ a
227+ > .
228+ </ p >
229+
230+ <!-- Container element where the solution plot will be rendered -->
231+ < div id ="orientation-message ">
232+ Cannot draw the results. Please turn your phone to horizontal position to see the results.
233+ </ div >
234+ < div id ="solutionPlot "> </ div >
235+
236+ < ul id ="menu ">
237+ < li >
238+ < a href ="https://feascript.com/index.html " target ="_blank "> Return</ a >
239+ </ li >
240+ </ ul >
241+
242+ < script type ="module ">
243+ //Import FEAScript library from GitHub
244+ import {
245+ FEAWorkerScript ,
246+ plotSolution ,
247+ printVersion ,
248+ } from "https://feascript.github.io/FEAScript-core/src/index.js" ;
249+ //Import FEAScript library from a local directory
250+ //import { FEAWorkerScript, plotSolution, printVersion } from "../../FEAScript-core/src/index.js";
251+
252+ window . addEventListener ( "DOMContentLoaded" , async ( ) => {
253+ if ( window . innerHeight > window . innerWidth ) {
254+ document . getElementById ( "orientation-message" ) . style . display = "block" ;
255+ document . getElementById ( "solutionPlot" ) . style . display = "none" ;
256+ } else {
257+ document . getElementById ( "orientation-message" ) . style . display = "none" ;
258+ document . getElementById ( "solutionPlot" ) . style . display = "block" ;
259+
260+ // Print FEAScript version
261+ printVersion ( ) ;
262+
263+ // Create a new FEAWorkerScript instance
264+ const model = new FEAWorkerScript ( ) ;
265+
266+ // Ensure the worker is ready
267+ await model . ping ( ) ;
268+
269+ // Set solver configuration
270+ await model . setSolverConfig ( "solidHeatTransferScript" ) ;
271+
272+ // Define mesh configuration
273+ await model . setMeshConfig ( {
274+ meshDimension : "2D" ,
275+ elementOrder : "quadratic" ,
276+ numElementsX : 8 ,
277+ numElementsY : 4 ,
278+ maxX : 4 ,
279+ maxY : 2 ,
280+ } ) ;
281+
282+ // Define boundary conditions
283+ await model . addBoundaryCondition ( "0" , [ "constantTemp" , 200 ] ) ;
284+ await model . addBoundaryCondition ( "1" , [ "symmetry" ] ) ;
285+ await model . addBoundaryCondition ( "2" , [ "convection" , 1 , 20 ] ) ;
286+ await model . addBoundaryCondition ( "3" , [ "constantTemp" , 200 ] ) ;
287+
288+ // Set solver method
289+ await model . setSolverMethod ( "lusolve" ) ;
290+
291+ // Solve the problem and get the solution
292+ const { solutionVector, nodesCoordinates } = await model . solve ( ) ;
293+
294+ // Plot the solution as a 2D contour plot
295+ plotSolution (
296+ solutionVector ,
297+ nodesCoordinates ,
298+ "solidHeatTransferScript" ,
299+ "2D" ,
300+ "contour" ,
301+ "solutionPlot"
302+ ) ;
303+
304+ // Terminate the worker
305+ model . terminate ( ) ;
306+ }
307+ } ) ;
308+
309+ window . addEventListener ( "resize" , async ( ) => {
310+ if ( window . innerHeight > window . innerWidth ) {
311+ document . getElementById ( "orientation-message" ) . style . display = "block" ;
312+ document . getElementById ( "solutionPlot" ) . style . display = "none" ;
313+ } else {
314+ document . getElementById ( "orientation-message" ) . style . display = "none" ;
315+ document . getElementById ( "solutionPlot" ) . style . display = "block" ;
316+
317+ // Print FEAScript version
318+ printVersion ( ) ;
319+
320+ // Create a new FEAWorkerScript instance
321+ const model = new FEAWorkerScript ( ) ;
322+
323+ // Ensure the worker is ready
324+ await model . ping ( ) ;
325+
326+ // Set solver configuration
327+ await model . setSolverConfig ( "solidHeatTransferScript" ) ;
328+
329+ // Define mesh configuration
330+ await model . setMeshConfig ( {
331+ meshDimension : "2D" ,
332+ elementOrder : "quadratic" ,
333+ numElementsX : 8 ,
334+ numElementsY : 4 ,
335+ maxX : 4 ,
336+ maxY : 2 ,
337+ } ) ;
338+
339+ // Define boundary conditions
340+ await model . addBoundaryCondition ( "0" , [ "constantTemp" , 200 ] ) ;
341+ await model . addBoundaryCondition ( "1" , [ "symmetry" ] ) ;
342+ await model . addBoundaryCondition ( "2" , [ "convection" , 1 , 20 ] ) ;
343+ await model . addBoundaryCondition ( "3" , [ "constantTemp" , 200 ] ) ;
344+
345+ // Set solver method
346+ await model . setSolverMethod ( "lusolve" ) ;
347+
348+ // Solve the problem and get the solution
349+ const { solutionVector, nodesCoordinates } = await model . solve ( ) ;
350+
351+ // Plot the solution as a 2D contour plot
352+ plotSolution (
353+ solutionVector ,
354+ nodesCoordinates ,
355+ "solidHeatTransferScript" ,
356+ "2D" ,
357+ "contour" ,
358+ "solutionPlot"
359+ ) ;
360+
361+ // Terminate the worker
362+ model . terminate ( ) ;
363+ }
364+ } ) ;
365+ </ script >
366+
367+ < p > © 2023-< span id ="currentYear "> </ span > FEAScript</ p >
368+ < script >
369+ document . getElementById ( "currentYear" ) . innerHTML = new Date ( ) . getFullYear ( ) ;
370+ </ script >
371+ </ body >
372+ </ html >
0 commit comments