Skip to content

Commit db743cf

Browse files
committed
Add heat conduction 2D fin tutorial with VTK.js plotting
1 parent d1eca10 commit db743cf

File tree

1 file changed

+290
-0
lines changed

1 file changed

+290
-0
lines changed
Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
<!doctype html>
2+
3+
<!--
4+
════════════════════════════════════════════════════════════════
5+
FEAScript Website
6+
Lightweight Finite Element Simulation in JavaScript
7+
Version: 0.3.0 (RC) | https://feascript.com
8+
CC BY 4.0 License © 2023–2026 FEAScript
9+
════════════════════════════════════════════════════════════════
10+
-->
11+
12+
<html>
13+
<head>
14+
<title>FEAScript: Heat Conduction in a 2D Fin (VTK.js) Tutorial</title>
15+
<link rel="icon" type="image/x-icon" href="../assets/favicon.ico" />
16+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
17+
<meta
18+
name="description"
19+
content="This example demonstrates solving a steady-state heat transfer problem in a 2D domain using the FEAScript library with VTK.js visualization. The problem represents a typical cooling fin scenario."
20+
/>
21+
<meta
22+
name="keywords"
23+
content="finite elements, fem, galerkin, computational mechanics, javascript, 2D heat transfer, vtk.js"
24+
/>
25+
<meta name="robots" content="noindex, nofollow" />
26+
<meta name="viewport" content="width=device-width" />
27+
<!-- Link to the CSS files -->
28+
<link href="../feascript-website.css" rel="stylesheet" type="text/css" />
29+
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet" />
30+
<!-- Import the Math.js library for mathematical operations -->
31+
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/11.12.0/math.min.js"></script>
32+
<!-- Import the run_prettify.js library for JavaScript code coloring *** Deprecated library *** -->
33+
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
34+
35+
<!-- VTK.js import map -->
36+
<script type="importmap">
37+
{
38+
"imports": {
39+
"@kitware/vtk.js/": "https://cdn.jsdelivr.net/npm/@kitware/vtk.js@32.12.0/",
40+
"gl-matrix": "https://esm.sh/v135/gl-matrix@3.4.3",
41+
"d3-scale": "https://esm.sh/v135/d3-scale@4.0.2",
42+
"fast-deep-equal": "https://esm.sh/v135/fast-deep-equal@3.1.3",
43+
"seedrandom": "https://esm.sh/v135/seedrandom@3.0.5",
44+
"spark-md5": "https://esm.sh/v135/spark-md5",
45+
"fflate": "https://esm.sh/v135/fflate",
46+
"utif": "https://esm.sh/v135/utif",
47+
"webworker-promise": "https://esm.sh/v135/webworker-promise",
48+
"xmlbuilder2": "https://esm.sh/v135/xmlbuilder2",
49+
"globalthis": "data:text/javascript,export default function(){return globalThis}"
50+
}
51+
}
52+
</script>
53+
</head>
54+
55+
<!-- Google tag (gtag.js) -->
56+
<script async src="https://www.googletagmanager.com/gtag/js?id=G-1JPK0KLEC9"></script>
57+
<script>
58+
window.dataLayer = window.dataLayer || [];
59+
function gtag() {
60+
dataLayer.push(arguments);
61+
}
62+
gtag("js", new Date());
63+
64+
gtag("config", "G-1JPK0KLEC9");
65+
</script>
66+
67+
<body>
68+
<h1 class="top">
69+
<a href="../index.html">
70+
<img
71+
src="../assets/feascript-logo.png"
72+
alt="FEAScript Logo"
73+
id="responsive-logo"
74+
style="vertical-align: middle"
75+
/>
76+
</a>
77+
<div class="social-icons-top-right">
78+
<ul>
79+
<li>
80+
<a href="https://blog.feascript.com/" title="FEAScript blog">
81+
<img
82+
src="../assets/blog-icon-feascript.png"
83+
alt="Blog icon"
84+
style="height: 18px; vertical-align: middle"
85+
/>
86+
</a>
87+
</li>
88+
<li>
89+
<a href="https://www.youtube.com/@FEAScript" title="FEAScript YouTube">
90+
<img
91+
src="../assets/youtube-icon-feascript.svg"
92+
alt="YouTube icon"
93+
style="height: 18px; vertical-align: middle"
94+
/>
95+
</a>
96+
</li>
97+
<li>
98+
<a href="https://www.linkedin.com/company/feascript/" title="FEAScript LinkedIn">
99+
<img
100+
src="../assets/linkedin-icon-feascript.png"
101+
alt="LinkedIn icon"
102+
style="height: 18px; vertical-align: middle"
103+
/>
104+
</a>
105+
</li>
106+
<li>
107+
<a href="https://discord.gg/3DVjNcuW4f" title="FEAScript Discord">
108+
<img
109+
src="../assets/discord-icon-feascript.png"
110+
alt="Discord icon"
111+
style="height: 18px; vertical-align: middle"
112+
/>
113+
</a>
114+
</li>
115+
<li>
116+
<a href="https://github.com/FEAScript/FEAScript-core" title="FEAScript GitHub">
117+
<img
118+
src="../assets/github-icon-feascript.png"
119+
alt="GitHub icon"
120+
style="height: 20px; vertical-align: middle"
121+
/>
122+
<span
123+
id="github-stars"
124+
style="
125+
font-size: 0.9em;
126+
margin-left: 5px;
127+
vertical-align: middle;
128+
border: 1px solid #ddd;
129+
border-radius: 4px;
130+
padding: 1px 5px;
131+
background-color: #f8f8f8;
132+
"
133+
></span>
134+
</a>
135+
</li>
136+
</ul>
137+
</div>
138+
</h1>
139+
<h1>Heat Conduction in a 2D Fin — VTK.js Visualization</h1>
140+
141+
<div class="highlight-container">
142+
<p>
143+
This page demonstrates the VTK.js rendering backend for the
144+
<a href="https://feascript.com/tutorials/heat-conduction-2d-fin.html">Heat Conduction in a 2D Fin</a>
145+
tutorial. For the full mathematical formulation, boundary condition details, and step-by-step code
146+
walkthrough, please refer to the
147+
<a href="https://feascript.com/tutorials/heat-conduction-2d-fin.html">main tutorial</a>.
148+
</p>
149+
</div>
150+
151+
<h2>Using VTK.js Instead of Plotly</h2>
152+
<p>
153+
To use VTK.js for visualization, two changes are needed compared to the
154+
<a href="https://feascript.com/tutorials/heat-conduction-2d-fin.html">Plotly-based tutorial</a>. First,
155+
add a VTK.js import map in the <code>&lt;head&gt;</code> section (instead of loading Plotly):
156+
</p>
157+
<pre class="prettyprint">
158+
&lt;script type="importmap"&gt;
159+
{
160+
"imports": {
161+
"@kitware/vtk.js/": "https://cdn.jsdelivr.net/npm/@kitware/vtk.js@32.12.0/",
162+
"gl-matrix": "https://esm.sh/v135/gl-matrix@3.4.3",
163+
"d3-scale": "https://esm.sh/v135/d3-scale@4.0.2",
164+
"fast-deep-equal": "https://esm.sh/v135/fast-deep-equal@3.1.3",
165+
"seedrandom": "https://esm.sh/v135/seedrandom@3.0.5",
166+
"spark-md5": "https://esm.sh/v135/spark-md5",
167+
"fflate": "https://esm.sh/v135/fflate",
168+
"utif": "https://esm.sh/v135/utif",
169+
"webworker-promise": "https://esm.sh/v135/webworker-promise",
170+
"xmlbuilder2": "https://esm.sh/v135/xmlbuilder2",
171+
"globalthis": "data:text/javascript,export default function(){return globalThis}"
172+
}
173+
}
174+
&lt;/script&gt;</pre
175+
>
176+
<p>
177+
Second, import <code>plotInterpolatedSolutionVtk</code>, <code>createColorScale</code>, and
178+
<code>createContourLineOptions</code> from FEAScript instead of <code>plotSolution</code>, and use them
179+
to render the results:
180+
</p>
181+
<pre class="prettyprint">
182+
import { FEAScriptModel, plotInterpolatedSolutionVtk, createColorScale,
183+
createContourLineOptions, printVersion } from "https://core.feascript.com/dist/feascript.esm.js";
184+
185+
// ...model setup and solve (same as the Plotly tutorial)...
186+
const result = model.solve();
187+
188+
// Plot results using VTK.js
189+
await plotInterpolatedSolutionVtk(model, result, "contour", "resultsCanvas", {
190+
colorScale: createColorScale({
191+
presetName: "Cool to Warm",
192+
scalarBarTitle: "Temperature",
193+
}),
194+
contourLines: createContourLineOptions({
195+
enabled: true,
196+
numberOfContours: 14,
197+
lineWidth: 1.25,
198+
}),
199+
});</pre
200+
>
201+
202+
<h2>Results</h2>
203+
<p>
204+
The 2D contour plot below shows the computed temperature distribution rendered in real time using
205+
FEAScript with VTK.js. The interactive canvas supports pan, zoom, and rotate.
206+
</p>
207+
208+
<div id="resultsCanvas"></div>
209+
210+
<br />
211+
212+
<ul id="menu">
213+
<li><a href="https://feascript.com/index.html">Home</a></li>
214+
<li><a href="https://feascript.com/#tutorials">All Tutorials</a></li>
215+
</ul>
216+
217+
<script type="module">
218+
// Import FEAScript library from GitHub
219+
// import {
220+
// FEAScriptModel,
221+
// plotInterpolatedSolutionVtk,
222+
// createColorScale,
223+
// createContourLineOptions,
224+
// printVersion,
225+
// } from "https://core.feascript.com/dist/feascript.esm.js";
226+
// Import FEAScript library from a local directory
227+
import {
228+
FEAScriptModel,
229+
plotInterpolatedSolutionVtk,
230+
createColorScale,
231+
createContourLineOptions,
232+
printVersion,
233+
} from "../../FEAScript-core/src/index.js";
234+
235+
window.addEventListener("DOMContentLoaded", async () => {
236+
console.log("FEAScript version:", printVersion);
237+
238+
const model = new FEAScriptModel();
239+
model.setModelConfig("heatConductionScript");
240+
model.setMeshConfig({
241+
meshDimension: "2D",
242+
elementOrder: "quadratic",
243+
numElementsX: 8,
244+
numElementsY: 4,
245+
maxX: 4,
246+
maxY: 2,
247+
});
248+
249+
model.addBoundaryCondition("0", ["constantTemp", 200]);
250+
model.addBoundaryCondition("1", ["symmetry"]);
251+
model.addBoundaryCondition("2", ["convection", 1, 20]);
252+
model.addBoundaryCondition("3", ["constantTemp", 200]);
253+
254+
model.setSolverMethod("lusolve");
255+
const result = model.solve();
256+
257+
await plotInterpolatedSolutionVtk(model, result, "contour", "resultsCanvas", {
258+
colorScale: createColorScale({
259+
presetName: "Cool to Warm",
260+
scalarBarTitle: "Temperature",
261+
}),
262+
contourLines: createContourLineOptions({
263+
enabled: true,
264+
numberOfContours: 14,
265+
lineWidth: 1.25,
266+
}),
267+
});
268+
});
269+
</script>
270+
271+
<footer>
272+
<p>&#169; 2023-<span id="currentYear"></span> FEAScript</p>
273+
</footer>
274+
<script>
275+
document.getElementById("currentYear").innerHTML = new Date().getFullYear();
276+
277+
// Fetch GitHub stars
278+
fetch("https://api.github.com/repos/FEAScript/FEAScript-core")
279+
.then((response) => response.json())
280+
.then((data) => {
281+
const starCount = data.stargazers_count;
282+
const starsElement = document.getElementById("github-stars");
283+
if (starsElement && starCount) {
284+
starsElement.innerHTML = `★ ${starCount}`;
285+
}
286+
})
287+
.catch((error) => console.error("Error fetching GitHub stars:", error));
288+
</script>
289+
</body>
290+
</html>

0 commit comments

Comments
 (0)