Skip to content

[Hacktoberfest Athens] Fin with two holes: a Gmsh heat-conduction tutorial (Team A) #5

Open

Description

@nikoscham

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:

  1. Outer rectangle: 4 points and 4 lines (bottom, right, top, left), lc = 0.4
  2. Each hole: a centre point plus 4 points on the circle, joined by 4 Circle arcs
    (e.g. Circle(11) = {11, 10, 12}; means start, centre, end); use a finer size lch = 0.2
  3. Surface: one Curve Loop per boundary, then Plane Surface(1) = {outer, hole1, hole2};
  4. Physical groups: exactly as in the table. Both holes (all 8 arcs) in one group. The surface gets the last tag (6)
  5. Elements: FEAScript needs quadrilateral elements:
    Recombine Surface{1};
    Mesh.RecombinationAlgorithm = 1;
    Mesh.SubdivisionAlgorithm = 1; // all-quad mesh
    Mesh 2;
    
  6. Export as MSH 4.1 ASCII:
    gmsh fin-two-holes.geo -2 -format msh41 -o fin_two_holes_quad.msh
  7. Check the size: the second number after $Nodes in the .msh is the node count.
    Aim for about 3,000 nodes or fewer.
  8. 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.geo
  • heat-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 fetch and importGmshMesh
  • 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:
    1. One team member forks FEAScript-website and adds the others as collaborators on the fork
    2. Everyone clones the fork and works on the branch fin-two-holes
    3. Split the work: one person on the .geo/.msh and the Gist, one on the HTML/JS, one on the
      text and screenshots
    4. Commit small steps with clear messages (e.g. "Add two-hole geometry", "Add tutorial page")
    5. Push and open a pull request to FEAScript/FEAScript-website main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions