Skip to content

Commit d8e9e3b

Browse files
committed
Refactor heat conduction example and improve Jacobi solver
- Updated mesh configuration in HeatConduction2DFinCG.html to reduce the number of elements for better performance. - Enhanced FEAScript.js to prepare the mesh and extract node coordinates before matrix assembly. - Modified jacobiMethodScript.js documentation to clarify return object structure. - Rewrote jacobiSolverScript.js to implement a CPU synchronous version of the Jacobi method, removing the WebGPU dependency. - Adjusted convergence check in webgpuJacobiWorker.js to use absolute differences. - Removed testWebGPU.html as it is no longer needed.
1 parent 5832886 commit d8e9e3b

File tree

7 files changed

+50
-678
lines changed

7 files changed

+50
-678
lines changed

dist/feascript.esm.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/heatConductionScript/heatConduction2DFin/HeatConduction2DFinCG.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ <h1>Heat Conduction in 2D Fin - Conjugate Gradient Solver</h1>
3535
model.setMeshConfig({
3636
meshDimension: "2D",
3737
elementOrder: "quadratic",
38-
numElementsX: 40,
39-
numElementsY: 20,
38+
numElementsX: 20,
39+
numElementsY: 10,
4040
maxX: 4000,
4141
maxY: 2000,
4242
});

src/FEAScript.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,24 @@ export class FEAScriptModel {
8282
let solutionVector = [];
8383
let nodesCoordinates = {};
8484

85+
// Prepare the mesh
86+
basicLog("Preparing mesh...");
87+
const meshData = prepareMesh(this.meshConfig);
88+
basicLog("Mesh preparation completed");
89+
90+
// Extract node coordinates from meshData
91+
nodesCoordinates = {
92+
nodesXCoordinates: meshData.nodesXCoordinates,
93+
nodesYCoordinates: meshData.nodesYCoordinates,
94+
};
95+
8596
// Assembly matrices
8697
basicLog("Beginning matrix assembly...");
8798
console.time("assemblyMatrices");
8899
if (this.solverConfig === "solidHeatTransferScript") {
89100
basicLog(`Using solver: ${this.solverConfig}`);
90-
({ jacobianMatrix, residualVector, nodesCoordinates } = assembleSolidHeatTransferMat(
91-
this.meshConfig,
101+
({ jacobianMatrix, residualVector } = assembleHeatConductionMat(
102+
meshData,
92103
this.boundaryConditions
93104
));
94105
}

src/methods/jacobiMethodScript.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { WebGPUComputeEngine } from "../utilities/webgpuComputeEngine.js";
2121
* @param {number} [tolerance=1e-7] - Convergence tolerance
2222
* @param {boolean} [useFloat64=true] - Whether to use Float64Array for higher precision
2323
* @returns {object} An object containing:
24-
* - solution: The solution vector
24+
* - solutionVector: The solution vector
2525
* - iterations: The number of iterations performed
2626
* - converged: Boolean indicating whether the method converged
2727
*/

src/methods/jacobiSolverScript.js

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,47 @@
88
// |_| | |_ //
99
// Website: https://feascript.com/ \__| //
1010

11-
import * as Comlink from "../vendor/comlink.mjs";
12-
import { WebGPUComputeEngine } from "../utilities/webgpuComputeEngine.js";
13-
1411
/**
15-
* Function to solve a system of linear equations using the Jacobi iterative method
16-
* This version uses the WebGPU compute engine for maximum performance and reusability
12+
* Function to solve a system of linear equations using the Jacobi iterative method (CPU synchronous version)
1713
* @param {array} A - The coefficient matrix (must be square)
1814
* @param {array} b - The right-hand side vector
1915
* @param {array} x0 - Initial guess for solution vector
20-
* @param {number} [maxIterations=100] - Maximum number of iterations
21-
* @param {number} [tolerance=1e-7] - Convergence tolerance
22-
* @param {boolean} [useFloat64=true] - Whether to use Float64Array for higher precision
16+
* @param {object} [options] - Additional options for the solver
17+
* @param {number} [options.maxIterations=1000] - Maximum number of iterations
18+
* @param {number} [options.tolerance=1e-6] - Convergence tolerance
2319
* @returns {object} An object containing:
2420
* - solutionVector: The solution vector
2521
* - iterations: The number of iterations performed
2622
* - converged: Boolean indicating whether the method converged
2723
*/
28-
export async function jacobiMethod(A, b, x0, maxIterations = 100, tolerance = 1e-7, useFloat64 = true) {
29-
// Use the dedicated worker file
30-
const worker = new Worker('./workers/webgpuJacobiWorker.js', { type: 'module' });
31-
const jacobiWorker = Comlink.wrap(worker);
24+
export function jacobiSolver(A, b, x0, options = {}) {
25+
const { maxIterations = 1000, tolerance = 1e-6 } = options;
26+
const n = A.length;
27+
let x = [...x0];
28+
let xNew = new Array(n);
29+
30+
for (let iter = 0; iter < maxIterations; iter++) {
31+
for (let i = 0; i < n; i++) {
32+
let sum = 0;
33+
for (let j = 0; j < n; j++) {
34+
if (i !== j) {
35+
sum += A[i][j] * x[j];
36+
}
37+
}
38+
xNew[i] = (b[i] - sum) / A[i][i];
39+
}
40+
41+
let maxDiff = 0;
42+
for (let i = 0; i < n; i++) {
43+
maxDiff = Math.max(maxDiff, Math.abs(xNew[i] - x[i]));
44+
}
3245

33-
try {
34-
const result = await jacobiWorker.jacobiMethod(A, b, x0, maxIterations, tolerance, useFloat64);
35-
return result;
36-
} catch (error) {
37-
console.error("Error in WebGPU Jacobi method:", error);
38-
throw error;
39-
} finally {
40-
worker.terminate();
46+
x = [...xNew];
47+
48+
if (maxDiff < tolerance) {
49+
return { solutionVector: x, iterations: iter + 1, converged: true };
50+
}
4151
}
52+
53+
return { solutionVector: x, iterations: maxIterations, converged: false };
4254
}

src/workers/webgpuJacobiWorker.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class WebGPUJacobiWorker {
6565
xNew = await xNewField.toArray();
6666

6767
// Check convergence by computing max difference
68-
const diffField = ti.field(ti.f32, [n]);
68+
const absDiffField = ti.field(ti.f32, [n]);
6969
diffField.fromArray(xNew.map((val, i) => val - x[i]));
7070

7171
ti.addToKernelScope({diffField, absDiffField});

0 commit comments

Comments
 (0)