Overview
Heat Conduction in a 2D Fin Tutorial (Gmsh Mesh)
This page demonstrates solving the 2D heat conduction fin problem using a Gmsh-generated mesh. Gmsh is a powerful mesh generation tool that can create complex geometries and meshes for finite element analysis. For the mathematical formulation and theory, see the basic tutorial.
This example demonstrates how to import a Gmsh-generated mesh (.msh file format)
and solve a heat conduction problem.
<body>
<!-- ...body region... -->
<script type="module">
import {
FEAScriptModel,
importGmshMesh,
plotInterpolatedSolution,
printVersion,
} from "https://core.feascript.com/dist/feascript.esm.js";
window.addEventListener("DOMContentLoaded", async () => {
console.log("FEAScript version:", printVersion);
// 1. Create the model and select the physics
const model = new FEAScriptModel();
model.setModelConfig("heatConductionScript");
// 2. Load the Gmsh mesh (.msh format version 4.1)
const response = await fetch("./rect_quad.msh");
if (!response.ok) {
throw new Error(`Failed to load the mesh file: ${response.status} ${response.statusText}`);
}
const meshFile = new File([await response.text()], "rect_quad.msh");
const mesh = await importGmshMesh(meshFile);
model.setMeshConfig({ parsedMesh: mesh });
// 3. Apply the boundary conditions (key = Gmsh physical group tag - 1)
model.addBoundaryCondition("0", ["constantTemperature", 200]); // Bottom
model.addBoundaryCondition("1", ["symmetry"]); // Left
model.addBoundaryCondition("2", ["convection", 1, 20]); // Top
model.addBoundaryCondition("3", ["constantTemperature", 200]); // Right
// 4. Solve
model.setSolverMethod("lusolve");
const result = model.solve();
// 5. Plot the results
plotInterpolatedSolution(model, result, "contour", "resultsCanvas");
});
</script>
<!-- ...rest of body region... -->
</body>
Important notes about the Gmsh workflow:
-
Physical Groups in Gmsh: In your
.geofile (see Example Gmsh.geoFile), you need to define physical groups for boundaries using commands likePhysical Line("bottom", 1) = {1};. These are mapped to tags in the imported mesh. -
Boundary Condition Mapping and Tag Indexing: When using Gmsh meshes in
FEAScript, you need to subtract 1 from the Gmsh physical group tag numbers. For example, if
your Gmsh file has physical groups with tags
"1","2","3","4", you would reference them in FEAScript as"0","1","2","3", respectively. For example:model.addBoundaryCondition("0", ["constantTemperature", 200]); // Gmsh physical group tag 1. This conversion is necessary because Gmsh uses 1-based indexing while FEAScript uses 0-based indexing.
You can create your own Gmsh files by writing .geo scripts or using Gmsh's GUI. For
this example, we used a simple rectangular domain defined in a .geo file with
specific physical groups for each boundary.
Below is the rect.geo file used in this tutorial. It defines a 4 m × 2 m
rectangular domain with a physical line for each boundary edge:
// 2D rectangle: 4 m (width) x 2 m (height)
// Generate the mesh with: gmsh rect.geo -2 -format msh41 -o rect_quad.msh
// 1. Mesh size
lc = 0.7; // Characteristic length
// 2. Points (x, y, z, mesh size)
Point(1) = {0, 0, 0, lc}; // Bottom left
Point(2) = {4, 0, 0, lc}; // Bottom right
Point(3) = {4, 2, 0, lc}; // Top right
Point(4) = {0, 2, 0, lc}; // Top left
// 3. Lines and surface
Line(1) = {1, 2}; // Bottom
Line(2) = {2, 3}; // Right
Line(3) = {3, 4}; // Top
Line(4) = {4, 1}; // Left
Line Loop(1) = {1, 2, 3, 4}; // Closed boundary
Plane Surface(1) = {1}; // Domain
// 4. Physical groups, tagged bottom, left, top, right (the side order of FEAScript structured meshes)
Physical Line("bottom", 1) = {1}; // FEAScript boundary "0"
Physical Line("left", 2) = {4}; // FEAScript boundary "1"
Physical Line("top", 3) = {3}; // FEAScript boundary "2"
Physical Line("right", 4) = {2}; // FEAScript boundary "3"
Physical Surface("domain", 5) = {1}; // Domain
// 5. Mesh
Recombine Surface{1}; // Quadrilaterals instead of triangles
Mesh.ElementOrder = 2; // Quadratic elements
Mesh 2;
Note how the physical line tags in the .geo file correspond to the boundary
conditions in our FEAScript code. The tags are given in the order bottom, left, top, right, which
is the side order of FEAScript's structured meshes, so the boundary keys are the same as in the
basic fin tutorial:
-
Physical Line("bottom", 1) = {1};→model.addBoundaryCondition("0", ["constantTemperature", 200]); -
Physical Line("left", 2) = {4};→model.addBoundaryCondition("1", ["symmetry"]); -
Physical Line("top", 3) = {3};→model.addBoundaryCondition("2", ["convection", 1, 20]); -
Physical Line("right", 4) = {2};→model.addBoundaryCondition("3", ["constantTemperature", 200]);
To generate a mesh file from this .geo script, you would run:
gmsh rect.geo -2 -format msh41 -o rect_quad.msh in your terminal, which creates the rect_quad.msh file that
can be imported into FEAScript.
FEAScript also supports triangular elements. To use them, remove the
Recombine Surface{1}; line so that Gmsh keeps the triangles. Set
Mesh.ElementOrder to 1 for linear or 2 for quadratic
elements; FEAScript detects the mesh dimension and element order from the imported mesh, so
there is no need to set meshDimension or elementOrder in the mesh
configuration.
Below is a visualization of the quadrilateral mesh generated with Gmsh. The mesh consists of 30 elements.
Quadrilateral mesh (rect_quad.msh) generated using the
rect.geo script with Gmsh
The unstructured mesh approach would be particularly advantageous for complex geometries, where the mapped mesh approach could not be applied effectively.
Below is the 2D contour plot of the computed temperature distribution. This plot is generated in real time using FEAScript. Please note that solutions computed on unstructured meshes like this may exhibit small numerical differences compared to solutions on structured orthogonal meshes. This occurs because derivative calculations in non-orthogonal elements are inherently less precise due to the Jacobian transformation process. These small differences are expected and acceptable for most engineering applications, but may be noticeable in regions with steep temperature gradients.
See also here for a variation with a rhomboid fin.