Study set-up: element size and the mesh handed to the solver
Prepares a simulation or generative study for solving: the automatic element size, the estimated element count, the design box, and the copy of the body's mesh the solver works on.
How the precision is kept
Sizes, volumes and counts are 64-bit. The automatic element size is deliberately rounded to a tidy value with 3 significant digits. The triangle mesh given to the solvers is a Float32Array copy of the body's mesh, which is itself 32-bit where it is made (brep.js, kernel.js); voxel.js and tetmesh.js read that mesh as the geometry of the study.
Open item. Hand the solvers a 64-bit copy of the body's vertices (or only the exact face records) so that the study's geometry is not limited to 32-bit coordinates.
Calculations under this policy
4 calculations in 1 source file. The code is read from the released app when this page loads. It is the calculation people run, not a copy kept for this page.
sim.jsPartCraft 0.8.1 32-bit in part4 calculationsReviewed
A tidy element size that gives about the target number of elements for a solid of a given volume.
raw = ∛(volume ÷ target); size = next step ≥ raw among 1, 1.25, 1.5, 2, 2.5, 3, 4, 5, 6, 8 × 10ⁿ
The value that is kept is rounded on purpose: up to the next tidy step, then to 3 significant digits with toPrecision. The decade comes from Math.floor(Math.log10(raw)), and the step list runs up to 10, which covers a value at the top of its decade.
sim.js
lines 128 to 134
PartCraft 0.8.1
/** A tidy element size giving about `target` elements for a solid of this volume (1, 1.25, 1.5, 2, 2.5, 3, 4, 5, 6, 8 × 10ⁿ). */
export function autoSize(volume, target) {
const raw = Math.cbrt(volume / target), e = Math.floor(Math.log10(raw)), b = raw / 10 ** e;
const steps = [1, 1.25, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10];
const s = steps.find((x) => x >= b - 1e-9) || 10;
return +(s * 10 ** e).toPrecision(3);
}
Estimated element count
64-bit
The element size a study will use and the number of elements that size is expected to give.
estimate = round(volume ÷ h³) (× 12 for tetrahedra)
One 64-bit division rounded to a whole number for the limit check and the message. The body's volume comes from the build's statistics.
sim.js
lines 172 to 173
PartCraft 0.8.1
const h = st.h || (tet ? tetAutoSize(regen.stats.volume) : autoSize(regen.stats.volume, AUTO_ELEMENTS.simulation));
const est = Math.round((tet ? 12 : 1) * regen.stats.volume / h ** 3); // tets: before grading near curved faces and edges
Mesh copy for the solver
32-bit in part
Copies the body's triangle mesh for the worker that meshes and solves the study.
The positions are copied with Float32Array.from, so every coordinate of the geometry the study is solved on has about 7 significant digits. simJob adds the B-rep edge segments as a Float32Array as well.
sim.js
lines 152 to 153
PartCraft 0.8.1
/** The mesh fields a worker needs (copies, so the transfer leaves the view's mesh alone). */
export const meshForJob = (mesh) => ({ positions: Float32Array.from(mesh.positions), indices: Uint32Array.from(mesh.indices), triFace: mesh.triFace ? Int32Array.from(mesh.triFace) : null });
Design box and size of a generative study
64-bit
The design space of a generative study (the body's box grown by a margin), its volume, element size and estimated element count.
The box is one subtraction or addition per coordinate and the volume one product of three differences, all 64-bit. The default minimum member size is 1.5 × h.
sim.js
lines 211 to 215
PartCraft 0.8.1
const bb = regen.stats.bbox, m = st.margin;
const box = { min: bb.min.map((v) => v - m), max: bb.max.map((v) => v + m) };
const vol = st.designSpace === 'box' ? (box.max[0] - box.min[0]) * (box.max[1] - box.min[1]) * (box.max[2] - box.min[2]) : regen.stats.volume;
const h = st.h || autoSize(vol, AUTO_ELEMENTS.generative);
const est = Math.round(vol / h ** 3);
In detail
Method
Element size = cube root of volume ÷ target count, rounded up to the next of 1, 1.25, 1.5, 2, 2.5, 3, 4, 5, 6, 8 × 10ⁿ.
Number types
64-bit numbers for sizes, volumes and estimates; Float32Array for the mesh positions and edge segments sent to the solver; Uint32Array and Int32Array for indexes.
Tolerances
A step is accepted when it is within 1e-9 below the wanted value. Element size from a file must lie in 0.01 to 1000; a direction must be longer than 1e-9.
Limits
Mesh coordinates handed to the solver carry about 7 significant digits. The tet mesher also receives the exact face records (planes, cylinders and other surfaces) with 64-bit values.
Approach: 32-bit step, flagged
One step stores or exchanges 32-bit values that reach a number a person reads. It is listed here with its open item, and the step is either moved to 64-bit or the app will warn where the number is read.