Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ac09141

Browse filesBrowse files
committed
Enhance boundary element handling in importGmshQuadTri function and fix nodal numbering remapping for quadrilateral elements
1 parent d5b8c94 commit ac09141
Copy full SHA for ac09141

File tree

1 file changed

+93
-24
lines changed
Filter options

1 file changed

+93
-24
lines changed

‎src/readers/gmshReaderScript.js

Copy file name to clipboardExpand all lines: src/readers/gmshReaderScript.js
+93-24Lines changed: 93 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -261,34 +261,103 @@ const importGmshQuadTri = async (file) => {
261261
if (!result.boundaryElements[prop.tag]) {
262262
result.boundaryElements[prop.tag] = [];
263263
}
264-
// TODO: Calculate the boundaryElements based on boundaryElementsByTag and nodalNumbering
265-
// NEXT TODO: Remap nodalNumbering according to https://gmsh.info/doc/texinfo/gmsh.html#Node-ordering.
266-
// In the case of quadrilaterals, the order is:
267-
/**
268-
* Gmsh quadrilateral node numbering (linear elements):
269-
*
270-
* 3__ __2
271-
* | |
272-
* |__ __|
273-
* 0 1
274-
*
275-
* FEAScript quadrilateral node numbering:
276-
*
277-
* 1__ __3
278-
* | |
279-
* |__ __|
280-
* 0 2
281-
*
282-
* Remapping:
283-
* - 0 (bottom left): stays as 0
284-
* - 3 (top left): becomes 1
285-
* - 1 (bottom right): becomes 2
286-
* - 2 (top right): becomes 3
287-
*/
264+
265+
// For each boundary line segment (2 nodes)
266+
boundaryNodes.forEach((nodesPair) => {
267+
// Find which quad element contains both nodes of this boundary
268+
let foundElement = false;
269+
for (let elemIdx = 0; elemIdx < result.nodalNumbering.quadElements.length; elemIdx++) {
270+
const elemNodes = result.nodalNumbering.quadElements[elemIdx];
271+
272+
// Check if both boundary nodes are in this element
273+
if (elemNodes.includes(nodesPair[0]) && elemNodes.includes(nodesPair[1])) {
274+
// Find which side of the element these nodes form
275+
let side;
276+
277+
// For linear quadrilateral elements, the Gmsh local numbering is:
278+
// 3 --- 2
279+
// | |
280+
// 0 --- 1
281+
282+
// Check which side these nodes belong to
283+
if (
284+
(elemNodes.indexOf(nodesPair[0]) === 0 && elemNodes.indexOf(nodesPair[1]) === 1) ||
285+
(elemNodes.indexOf(nodesPair[1]) === 0 && elemNodes.indexOf(nodesPair[0]) === 1)
286+
) {
287+
side = 0; // Bottom side
288+
} else if (
289+
(elemNodes.indexOf(nodesPair[0]) === 1 && elemNodes.indexOf(nodesPair[1]) === 2) ||
290+
(elemNodes.indexOf(nodesPair[1]) === 1 && elemNodes.indexOf(nodesPair[0]) === 2)
291+
) {
292+
side = 1; // Right side
293+
} else if (
294+
(elemNodes.indexOf(nodesPair[0]) === 2 && elemNodes.indexOf(nodesPair[1]) === 3) ||
295+
(elemNodes.indexOf(nodesPair[1]) === 2 && elemNodes.indexOf(nodesPair[0]) === 3)
296+
) {
297+
side = 2; // Top side
298+
} else if (
299+
(elemNodes.indexOf(nodesPair[0]) === 3 && elemNodes.indexOf(nodesPair[1]) === 0) ||
300+
(elemNodes.indexOf(nodesPair[1]) === 3 && elemNodes.indexOf(nodesPair[0]) === 0)
301+
) {
302+
side = 3; // Left side
303+
}
304+
305+
// Add to boundary elements
306+
result.boundaryElements[prop.tag].push([elemIdx, side]);
307+
foundElement = true;
308+
break;
309+
}
310+
}
311+
});
288312
}
289313
}
290314
});
291315

316+
// Remap nodal numbering from Gmsh format to FEAScript format for quadrilateral elements
317+
if (result.nodalNumbering.quadElements.length > 0) {
318+
/*
319+
* Gmsh quadrilateral node numbering (linear elements):
320+
*
321+
* 3__ __2
322+
* | |
323+
* |__ __|
324+
* 0 1
325+
*
326+
* FEAScript quadrilateral node numbering (linear elements):
327+
*
328+
* 1__ __3
329+
* | |
330+
* |__ __|
331+
* 0 2
332+
*
333+
*/
334+
// Mapping: Gmsh → FEAScript
335+
// 0 → 0 (bottom left)
336+
// 1 → 2 (bottom right)
337+
// 2 → 3 (top right)
338+
// 3 → 1 (top left)
339+
const gmshToFEAMap = [0, 2, 3, 1];
340+
341+
for (let i = 0; i < result.nodalNumbering.quadElements.length; i++) {
342+
const originalNodes = [...result.nodalNumbering.quadElements[i]];
343+
for (let j = 0; j < 4; j++) {
344+
result.nodalNumbering.quadElements[i][gmshToFEAMap[j]] = originalNodes[j];
345+
}
346+
}
347+
}
348+
349+
// Fix boundary elements array - remove the empty first element
350+
if (result.boundaryElements.length > 0 && result.boundaryElements[0] === undefined) {
351+
// Create a new array without the empty first element
352+
const fixedBoundaryElements = [];
353+
for (let i = 1; i < result.boundaryElements.length; i++) {
354+
if (result.boundaryElements[i]) {
355+
fixedBoundaryElements.push(result.boundaryElements[i]);
356+
}
357+
}
358+
result.boundaryElements = fixedBoundaryElements;
359+
}
360+
292361
return result;
293362
};
294363

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.