@meshioplusplus/wasm 9.27.0 → 10.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -236,6 +236,13 @@ export type OpSpec =
236
236
  value?: number;
237
237
  closure?: RefineClosure;
238
238
  recordLevels?: boolean;
239
+ /**
240
+ * Attach `refine:cell_id`/`refine:parent_id` -- the persistent
241
+ * parent/child hierarchy a multigrid caller resolves across the
242
+ * sequence of meshes it keeps. Also forces `refine:entity` to be
243
+ * attached even when the closure leaves no hanging node.
244
+ */
245
+ recordHierarchy?: boolean;
239
246
  }
240
247
  | {
241
248
  /**
@@ -295,6 +302,21 @@ export type OpSpec =
295
302
  output?: string;
296
303
  component?: number;
297
304
  }
305
+ | {
306
+ /**
307
+ * The ZZ recovery-based error indicator of a `point_data` field, plus
308
+ * optional marking. A pure data step: geometry is untouched and the
309
+ * indicator (and, when `marking` is not `"none"`, the marking) array
310
+ * is attached.
311
+ */
312
+ op: 'estimateError';
313
+ array: string;
314
+ method?: ErrorMethod;
315
+ marking?: ErrorMarking;
316
+ markingValue?: number;
317
+ output?: string;
318
+ marked?: string;
319
+ }
298
320
  | {
299
321
  /**
300
322
  * A regular grid around the mesh. One of the two steps that replace their
@@ -363,6 +385,12 @@ export type SdfWatertightCheck = 'off' | 'warn' | 'error';
363
385
  /** `gradient`'s reconstruction method. See doc/gradient.md. */
364
386
  export type GradientMethod = 'green-gauss' | 'least-squares';
365
387
 
388
+ /** `estimateError`'s estimator family. Only `"zz"` exists today. */
389
+ export type ErrorMethod = 'zz';
390
+
391
+ /** `estimateError`'s marking policy. See doc/error.md. */
392
+ export type ErrorMarking = 'none' | 'absolute' | 'fraction' | 'dorfler';
393
+
366
394
  /** One data array's location: `point_data`, `cell_data`, or `field_data`. */
367
395
  export type DataLocation = 'point' | 'cell' | 'field';
368
396
 
@@ -438,6 +466,19 @@ export interface RefineOptions {
438
466
  closure?: RefineClosure;
439
467
  /** Attach the `refine:level` `cell_data` array. */
440
468
  recordLevels?: boolean;
469
+ /**
470
+ * Attach the `refine:cell_id`/`refine:parent_id` `cell_data` arrays -- the
471
+ * persistent parent/child hierarchy a multigrid caller resolves across the
472
+ * sequence of meshes it keeps ("a link between two meshes, not a tree
473
+ * inside one"): an unsplit cell keeps its id and is its own parent; a
474
+ * split cell's children each get a fresh id and carry the parent's id. An
475
+ * input already carrying `refine:cell_id` is updated whatever this says.
476
+ * Also forces `refine:entity` to be attached even when the closure leaves
477
+ * no hanging node, since it already records the coarse corners each new
478
+ * fine node is the mean of -- the multigrid prolongation weights, which
479
+ * `'redgreen'`/`'propagate'` would otherwise never expose.
480
+ */
481
+ recordHierarchy?: boolean;
441
482
  }
442
483
 
443
484
  /** Where `decimate` places the surviving vertex of a collapsed edge. */
@@ -973,6 +1014,25 @@ export interface MeshioPlusPlusModule {
973
1014
  onConflict?: InterpolateOnConflict,
974
1015
  ): Mesh;
975
1016
 
1017
+ /**
1018
+ * Green-element undo: restore `fine`'s transitional (closure-only) cells
1019
+ * back to their original parent, read verbatim from `coarse` — a lookup,
1020
+ * not a reconstruction, since `refine` never renumbers or prunes points.
1021
+ * `fine` must carry `refine:cell_id`/`refine:parent_id`/`refine:level`
1022
+ * (i.e. must come from `refine(coarse, ..., {recordHierarchy: true,
1023
+ * recordLevels: true})`); `coarse` must be the mesh that call was run on.
1024
+ * The six reserved `refine:*` arrays are dropped from the output. Only a
1025
+ * single-pass (`levels=1`) hierarchy is supported.
1026
+ * @throws {Error} when `fine` lacks the required hierarchy arrays, when a
1027
+ * `refine:parent_id` value does not resolve against `coarse`'s id space,
1028
+ * or when a sibling group's level matches neither the red nor the green
1029
+ * relationship to its coarse parent's own level.
1030
+ */
1031
+ undoGreen(
1032
+ coarse: Mesh,
1033
+ fine: Mesh,
1034
+ ): { mesh: Mesh; numGroupsUndone: number; numCellsRemoved: number };
1035
+
976
1036
  /** Subset a mesh to an axis-aligned bounding box. */
977
1037
  cropBbox(mesh: Mesh, lo: number[], hi: number[], mode?: CropMode, recordIds?: boolean): Mesh;
978
1038
 
@@ -1188,6 +1248,41 @@ export interface MeshioPlusPlusModule {
1188
1248
  overwrite?: boolean,
1189
1249
  ): { mesh: Mesh; numSkipped: number; numFallback: number };
1190
1250
 
1251
+ /**
1252
+ * The Zienkiewicz-Zhu (ZZ) recovery-based error indicator of a `point_data`
1253
+ * field, plus optional marking. A composition of `gradient` (Green-Gauss,
1254
+ * cell location) with the measure-weighted point↔cell averaging round
1255
+ * trip: the indicator is `sqrt(|measure| * sum((recovered - raw)^2))` per
1256
+ * cell, attached as `output` (default `"error:zz"`, Float64).
1257
+ *
1258
+ * `marking` is `"none"` (default), `"absolute"`, `"fraction"`, or
1259
+ * `"dorfler"`; when not `"none"` a second Int64 0/1 array `marked`
1260
+ * (default `"error:marked"`) is attached too, so `refine`'s own `where`/
1261
+ * `--where` selector needs no change at all — the intended use is
1262
+ * `refine(mesh, {compare: '>', value: 0.5, array: 'error:marked'})`.
1263
+ * `markingValue`'s meaning depends on `marking`: an absolute indicator
1264
+ * threshold, a fraction in `(0, 1]` of cells, or the Doerfler bulk fraction
1265
+ * theta in `(0, 1]`.
1266
+ *
1267
+ * Cells that cannot be evaluated read NaN in the indicator array and 0
1268
+ * (never NaN) in the marking array, and are counted in `numSkipped`
1269
+ * (excluded from `globalError` and from `numMarked`).
1270
+ * @throws {Error} when `array` names a `cell_data` array (piecewise
1271
+ * constant, so it has no derivative to recover), an unknown array, an
1272
+ * unknown method/marking policy, or an out-of-range `markingValue` for
1273
+ * `"fraction"`/`"dorfler"`.
1274
+ */
1275
+ estimateError(
1276
+ mesh: Mesh,
1277
+ array: string,
1278
+ method?: ErrorMethod,
1279
+ marking?: ErrorMarking,
1280
+ markingValue?: number,
1281
+ output?: string,
1282
+ marked?: string,
1283
+ overwrite?: boolean,
1284
+ ): { mesh: Mesh; globalError: number; numSkipped: number; numMarked: number };
1285
+
1191
1286
  /** Partition a mesh into submeshes by type, connected component, or tag. */
1192
1287
  split(mesh: Mesh, by: SplitBy, tagName?: string): { key: string; mesh: Mesh }[];
1193
1288
 
@@ -1200,6 +1295,33 @@ export interface MeshioPlusPlusModule {
1200
1295
  */
1201
1296
  convertCells(mesh: Mesh, mode?: ConvertCellsMode, recordParentIds?: boolean): Mesh;
1202
1297
 
1298
+ /**
1299
+ * Polyhedrally refine a mesh: one polyhedral child per face of every
1300
+ * eligible 3D cell, connected to a new interior point. Needs no per-type
1301
+ * template table -- tabulated types (reduced to corners for a quadratic
1302
+ * variant) and existing polyhedron blocks are handled uniformly.
1303
+ * Automatically conforming, unlike `refine`. Non-3D blocks and the
1304
+ * full-Lagrange family (no face table) pass through unchanged. Unlike
1305
+ * `convertCells`, there is no point map -- subdivide never prunes or
1306
+ * renumbers an original point.
1307
+ * @throws {Error} when a cell's faces are not a closed orientable surface.
1308
+ */
1309
+ subdivide(mesh: Mesh, recordParentIds?: boolean): Mesh;
1310
+
1311
+ /**
1312
+ * Polyhedrally coarsen a mesh: merge groups of cells into single larger
1313
+ * polyhedral cells via greedy seed-and-grow over the mesh's shared-face
1314
+ * dual, absorbing face-adjacent neighbours into a group until it reaches
1315
+ * `targetGroupSize` (default 8; a short group at a mesh boundary or
1316
+ * pocket is expected, not an error). `targetGroupSize=1` groups every
1317
+ * cell by itself. Non-volume blocks pass through unchanged; points are
1318
+ * never pruned or renumbered (`clean(mesh, ..., true)` is the follow-up
1319
+ * for a minimal point set).
1320
+ * @throws {Error} when targetGroupSize is 0, or the mesh contains a face
1321
+ * shared by three or more cells (non-manifold).
1322
+ */
1323
+ agglomerate(mesh: Mesh, targetGroupSize?: number): Mesh;
1324
+
1203
1325
  /**
1204
1326
  * Refine a mesh, subdividing cells into same-type children (`line` → 2,
1205
1327
  * `triangle` → 4, `quad` → 4, `tetra` → 8, `wedge` → 8, `hexahedron` → 8).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meshioplusplus/wasm",
3
- "version": "9.27.0",
3
+ "version": "10.6.0",
4
4
  "description": "meshio++ mesh I/O compiled to WebAssembly: read/write 41 mesh formats (incl. MED, CGNS, Exodus) in the browser or Node.js",
5
5
  "type": "module",
6
6
  "main": "./src/index.mjs",
package/src/index.mjs CHANGED
@@ -160,8 +160,11 @@ function resolveVariant(variant) {
160
160
  * distanceToSurface: (query: Mesh, surface: Mesh, sign?: string, location?: string, band?: number, recordInside?: boolean, watertightCheck?: string) => {mesh: Mesh, numBanded: number, quality: object},
161
161
  * computeSdf: (surface: Mesh, structure?: string, resolution?: number[], cellSize?: number, bounds?: number[], padding?: number, paddingRelative?: number, rootResolution?: number, maxDepth?: number, bandCells?: number, recordLevels?: boolean, maxCells?: number, sign?: string, location?: string, band?: number, watertightCheck?: string) => {mesh: Mesh, dims: number[], origin: number[], spacing: number[], maxDepth: number, numBanded: number, quality: object},
162
162
  * gradient: (mesh: Mesh, array: string, operator?: string, method?: string, location?: string, output?: string, component?: number, overwrite?: boolean) => {mesh: Mesh, numSkipped: number, numFallback: number},
163
+ * estimateError: (mesh: Mesh, array: string, method?: string, marking?: string, markingValue?: number, output?: string, marked?: string, overwrite?: boolean) => {mesh: Mesh, globalError: number, numSkipped: number, numMarked: number},
163
164
  * split: (mesh: Mesh, by: string, tagName?: string) => {key: string, mesh: Mesh}[],
164
165
  * convertCells: (mesh: Mesh, mode?: string, recordParentIds?: boolean) => Mesh,
166
+ * subdivide: (mesh: Mesh, recordParentIds?: boolean) => Mesh,
167
+ * agglomerate: (mesh: Mesh, targetGroupSize?: number) => Mesh,
165
168
  * refine: (mesh: Mesh, levels?: number, recordParentIds?: boolean,
166
169
  * options?: object) => Mesh,
167
170
  * decimate: (mesh: Mesh, ratio?: number, targetFaces?: number, maxError?: number, placement?: string, preserveBoundary?: boolean, preserveFeatures?: boolean, featureAngle?: number) => {mesh: Mesh, facesRemoved: number, pointsRemoved: number, collapsesRejected: number, maxErrorApplied: number},
@@ -352,6 +355,9 @@ export async function loadMeshioPlusPlus(moduleOverrides = {}, { variant = 'auto
352
355
  defaultValue,
353
356
  onConflict,
354
357
  ),
358
+ // Restore `fine`'s transitional (green) cells to their coarse parent,
359
+ // read verbatim from `coarse` (a lookup, not a reconstruction).
360
+ undoGreen: (coarse, fine) => Module.undoGreen(coarse, fine),
355
361
  cropBbox: (mesh, lo, hi, mode = 'all', recordIds = false) =>
356
362
  Module.cropBbox(mesh, lo, hi, mode, recordIds),
357
363
  cropPlane: (mesh, point, normal, mode = 'all', recordIds = false) =>
@@ -431,9 +437,31 @@ export async function loadMeshioPlusPlus(moduleOverrides = {}, { variant = 'auto
431
437
  overwrite = false,
432
438
  ) =>
433
439
  Module.gradient(mesh, array, operator, method, location, output, component, overwrite),
440
+ estimateError: (
441
+ mesh,
442
+ array,
443
+ method = 'zz',
444
+ marking = 'none',
445
+ markingValue = 0.0,
446
+ output = '',
447
+ marked = '',
448
+ overwrite = false,
449
+ ) =>
450
+ Module.estimateError(
451
+ mesh,
452
+ array,
453
+ method,
454
+ marking,
455
+ markingValue,
456
+ output,
457
+ marked,
458
+ overwrite,
459
+ ),
434
460
  split: (mesh, by, tagName = '') => Module.split(mesh, by, tagName),
435
461
  convertCells: (mesh, mode = 'linearize', recordParentIds = false) =>
436
462
  Module.convertCells(mesh, mode, recordParentIds),
463
+ subdivide: (mesh, recordParentIds = false) => Module.subdivide(mesh, recordParentIds),
464
+ agglomerate: (mesh, targetGroupSize = 8) => Module.agglomerate(mesh, targetGroupSize),
437
465
  refine: (mesh, levels = 1, recordParentIds = false, options = undefined) =>
438
466
  Module.refine(mesh, levels, recordParentIds, options),
439
467
  // Exactly one of ratio / targetFaces / maxError must be non-negative;