Repository navigation
[Hacktoberfest Athens] Fin with two holes: a Gmsh heat-conduction tutorial (Team A) #5
Description
Fin with two holes: a Gmsh heat-conduction tutorial, Team A (no AI)
This issue is a hands-on example prepared for the Hacktoberfest Meetup Athens x FEAScript, 2026.
Add a new browser tutorial to the FEAScript website: 2D steady-state heat conduction in a
rectangular fin with two circular holes, meshed with Gmsh and solved with FEAScript.
This team works without AI assistants: use the existing tutorials, the Gmsh docs and each other.
Start from the existing rhomboid tutorial:
tutorials/heat-conduction-2d-rhom-fin-gmsh.html (+ rhom.geo, rhom_quad.msh)
The geometry
- Rectangle 4 m × 2 m, corners (0, 0) and (4, 2)
- Two circular holes of radius 0.3 m, centred at (1.3, 1) and (2.7, 1)
- The holes act as cooling channels: heat leaves the fin through their surface by convection
The physics
Steady heat conduction, k = 1 (default), no heat source.
| Boundary | Gmsh physical group | Tag | Condition |
|---|---|---|---|
| Bottom | bottom |
1 | ["constantTemperature", 200] |
| Right | right |
2 | ["constantTemperature", 200] |
| Top | top |
3 | ["convection", 1, 20] |
| Left | left |
4 | insulated (no condition required) |
| Both holes | holes |
5 | ["convection", 1, 20] |
| Surface | domain |
6 | – |
FEAScript boundary key = Gmsh physical group tag − 1.
Making the mesh with Gmsh
Write fin-two-holes.geo:
- Outer rectangle: 4 points and 4 lines (bottom, right, top, left),
lc = 0.4 - Each hole: a centre point plus 4 points on the circle, joined by 4
Circlearcs
(e.g.Circle(11) = {11, 10, 12};means start, centre, end); use a finer sizelch = 0.2 - Surface: one
Curve Loopper boundary, thenPlane Surface(1) = {outer, hole1, hole2}; - Physical groups: exactly as in the table. Both holes (all 8 arcs) in one group. The surface gets the last tag (6)
- Elements: FEAScript needs quadrilateral elements:
Recombine Surface{1}; Mesh.RecombinationAlgorithm = 1; Mesh.SubdivisionAlgorithm = 1; // all-quad mesh Mesh 2; - Export as MSH 4.1 ASCII:
gmsh fin-two-holes.geo -2 -format msh41 -o fin_two_holes_quad.msh - Check the size: the second number after
$Nodesin the.mshis the node count.
Aim for about 3,000 nodes or fewer. - Upload the mesh to a Gist: create a Gist at https://gist.github.com with your
fin_two_holes_quad.msh(public or secret), open it, click Raw and copy the URL.
Remove the commit hash so the link keeps working after edits:
https://gist.githubusercontent.com/<user>/<gist-id>/raw/fin_two_holes_quad.msh
Starter skeleton for fin-two-holes.geo (complete the TODOs):
lc = 0.4; // Mesh size at the outer boundary
lch = 0.2; // Finer mesh size around the holes
r = 0.3; // Hole radius
// Outer rectangle
Point(1) = {0, 0, 0, lc};
Point(2) = {4, 0, 0, lc};
Point(3) = {4, 2, 0, lc};
Point(4) = {0, 2, 0, lc};
Line(1) = {1, 2}; // bottom
Line(2) = {2, 3}; // right
Line(3) = {3, 4}; // top
Line(4) = {4, 1}; // left
// Hole 1: centre (1.3, 1), four arcs
Point(10) = {1.3, 1, 0, lch}; // centre
Point(11) = {1.3 + r, 1, 0, lch};
Point(12) = {1.3, 1 + r, 0, lch};
Point(13) = {1.3 - r, 1, 0, lch};
Point(14) = {1.3, 1 - r, 0, lch};
Circle(11) = {11, 10, 12}; // start, centre, end
Circle(12) = {12, 10, 13};
Circle(13) = {13, 10, 14};
Circle(14) = {14, 10, 11};
// TODO: Hole 2, centre (2.7, 1), same pattern (use points 20-24 and circles 21-24)
// TODO: one Curve Loop per boundary (outer, hole 1, hole 2)
// TODO: Plane Surface(1) = {outer loop, hole 1 loop, hole 2 loop};
// TODO: physical groups as in the table (tags 1-5 with no gaps, surface = 6)
// Syntax example: Physical Line("bottom", 1) = {1};
Recombine Surface{1};
Mesh.RecombinationAlgorithm = 1;
Mesh.SubdivisionAlgorithm = 1;
Mesh 2;
The FEAScript part
Start from heat-conduction-2d-rhom-fin-gmsh.html and complete the TODOs:
// Load the mesh from your Gist (raw URL without commit hash)
const response = await fetch("https://gist.githubusercontent.com/<user>/<gist-id>/raw/fin_two_holes_quad.msh");
if (!response.ok) throw new Error(`Failed to load mesh: ${response.status}`);
const meshFile = new File([await response.text()], "fin_two_holes_quad.msh");
model.setModelConfig("heatConductionScript");
model.setMeshConfig({
parsedMesh: await importGmshMesh(meshFile),
meshDimension: "2D",
elementOrder: /* TODO: must match how you generated the mesh */,
});
// TODO: add one boundary condition per row of the physics table.
// Remember: FEAScript key = Gmsh physical group tag − 1.
// Hint: the left edge needs no line at all.
model.setSolverMethod("lusolve"); // frontal currently fails on this mesh
const result = model.solve();
plotInterpolatedSolution(model, result, "contour", "resultsCanvas");Note: the rhomboid tutorial uses quadratic elements, a local mesh file, the deprecated constantTemp
and symmetry. This tutorial uses linear elements, a Gist mesh, constantTemperature, and leaves
insulated edges without a condition.
Hint: Performing sanity check. solve() returns { solutionVector, nodesCoordinates }.
// Find min and max of the temperature
const minT = Math.min(...result.solutionVector);
const maxT = Math.max(...result.solutionVector);Files to add (in tutorials/)
fin-two-holes.geoheat-conduction-2d-fin-two-holes-gmsh.html
The .msh file is not committed: it lives in your Gist and the page fetches it from there.
Required features
- Page loads the mesh from your Gist raw URL with
fetchandimportGmshMesh - Linear elements and
lusolve - Contour with
plotInterpolatedSolution, with both holes masked (empty) - Console prints min/max temperature
Definition of done
- Page works when opened by double-click (as
file://): the mesh loads from the Gist - The Gist raw URL has no commit hash and opens the mesh text in the browser
- All temperatures lie within [20, 200] (sanity check)
- Every team member has at least one commit
- PR includes a screenshot of the mesh (from Gmsh) and of the result
- PR description includes the link to your mesh Gist
- PR description contains
Closes #<this issue number>
Bonus goals
- Compare insulated holes (remove the holes' condition) vs convective holes: how does the max/min T change?
- Investigate mesh refinement: Generate a finer quadrilateral mesh and compare the minimum/maximum temperatures.
Where and how to contribute
- Repository: FEAScript-website
- Workflow:
- One team member forks FEAScript-website and adds the others as collaborators on the fork
- Everyone clones the fork and works on the branch
fin-two-holes - Split the work: one person on the
.geo/.mshand the Gist, one on the HTML/JS, one on the
text and screenshots - Commit small steps with clear messages (e.g. "Add two-hole geometry", "Add tutorial page")
- Push and open a pull request to
FEAScript/FEAScript-websitemain

Activity