@@ -261,34 +261,103 @@ const importGmshQuadTri = async (file) => {
261
261
if ( ! result . boundaryElements [ prop . tag ] ) {
262
262
result . boundaryElements [ prop . tag ] = [ ] ;
263
263
}
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
+ } ) ;
288
312
}
289
313
}
290
314
} ) ;
291
315
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
+
292
361
return result ;
293
362
} ;
294
363
0 commit comments