Skip to content

Commit 00afa80

Browse files
committed
Add a seperate linear system solver function (linearSystemScript.js). Refactor linearSystemScript.js and FEAScript.js to utilize it
1 parent 9c090d9 commit 00afa80

File tree

4 files changed

+86
-49
lines changed

4 files changed

+86
-49
lines changed

src/FEAScript.js

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
// Internal imports
1212
import { jacobiMethod } from "./methods/jacobiMethodScript.js";
1313
import { newtonRaphson } from "./methods/newtonRaphsonScript.js";
14+
import { solveLinearSystem } from "./methods/linearSystemScript.js";
1415
import { assembleFrontPropagationMat } from "./solvers/frontPropagationScript.js";
1516
import { assembleSolidHeatTransferMat } from "./solvers/solidHeatTransferScript.js";
1617
import { basicLog, debugLog, errorLog } from "./utilities/loggingScript.js";
@@ -63,15 +64,19 @@ export class FEAScriptModel {
6364
let solutionVector = [];
6465
let nodesCoordinates = {};
6566

66-
// Assembly matrices
67-
basicLog("Beginning matrix assembly...");
68-
console.time("assemblyMatrices");
67+
// Select and execute the appropriate solver based on solverConfig
68+
basicLog("Beginning solving process...");
69+
console.time("totalSolvingTime");
6970
if (this.solverConfig === "solidHeatTransferScript") {
7071
basicLog(`Using solver: ${this.solverConfig}`);
7172
({ jacobianMatrix, residualVector, nodesCoordinates } = assembleSolidHeatTransferMat(
7273
this.meshConfig,
7374
this.boundaryConditions
7475
));
76+
77+
// Solve the assembled linear system
78+
const linearSystemResult = solveLinearSystem(this.solverMethod, jacobianMatrix, residualVector);
79+
solutionVector = linearSystemResult.solutionVector;
7580
} else if (this.solverConfig === "frontPropagationScript") {
7681
basicLog(`Using solver: ${this.solverConfig}`);
7782
let eikonalActivationFlag = 0; // Parameterization flag (from 0 to 1)
@@ -84,7 +89,7 @@ export class FEAScriptModel {
8489
boundaryConditions: this.boundaryConditions,
8590
eikonalActivationFlag,
8691
eikonalViscousTerm,
87-
solverMethod: this.solverMethod
92+
solverMethod: this.solverMethod,
8893
};
8994

9095
while (eikonalActivationFlag <= 1) {
@@ -102,35 +107,12 @@ export class FEAScriptModel {
102107
nodesCoordinates = newtonRaphsonResult.nodesCoordinates;
103108
solutionVector = newtonRaphsonResult.solution;
104109

105-
// Increment eikonalActivationFlag for next step if needed
110+
// Increment eikonalActivationFlag for next step
106111
eikonalActivationFlag += 0.1;
107112
}
108113
}
109-
console.timeEnd("assemblyMatrices");
110-
basicLog("Matrix assembly completed");
111-
112-
// Solve the linear system based on the specified solver method
113-
basicLog(`Solving system using ${this.solverMethod}...`);
114-
console.time("systemSolving");
115-
if (this.solverMethod === "lusolve") {
116-
// Use LU decomposition method
117-
solutionVector = math.lusolve(jacobianMatrix, residualVector);
118-
} else if (this.solverMethod === "jacobi") {
119-
// Use Jacobi method
120-
const initialGuess = new Array(residualVector.length).fill(0);
121-
const jacobiResult = jacobiMethod(jacobianMatrix, residualVector, initialGuess, 1000, 1e-6);
122-
123-
// Log convergence information
124-
if (jacobiResult.converged) {
125-
debugLog(`Jacobi method converged in ${jacobiResult.iterations} iterations`);
126-
} else {
127-
debugLog(`Jacobi method did not converge after ${jacobiResult.iterations} iterations`);
128-
}
129-
130-
solutionVector = jacobiResult.solution;
131-
}
132-
console.timeEnd("systemSolving");
133-
basicLog("System solved successfully");
114+
console.timeEnd("totalSolvingTime");
115+
basicLog("Solving process completed");
134116

135117
return { solutionVector, nodesCoordinates };
136118
}

src/methods/jacobiMethodScript.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@
1313
* @param {array} A - The coefficient matrix (must be square)
1414
* @param {array} b - The right-hand side vector
1515
* @param {array} x0 - Initial guess for solution vector
16-
* @param {number} [maxIterations=100] - Maximum number of iterations
17-
* @param {number} [tolerance=1e-7] - Convergence tolerance
16+
* @param {object} [options] - Options for the solver
17+
* @param {number} [options.maxIterations=1000] - Maximum number of iterations
18+
* @param {number} [options.tolerance=1e-6] - Convergence tolerance
1819
* @returns {object} An object containing:
1920
* - solution: The solution vector
2021
* - iterations: The number of iterations performed
2122
* - converged: Boolean indicating whether the method converged
2223
*/
23-
export function jacobiMethod(A, b, x0, maxIterations = 100, tolerance = 1e-7) {
24+
export function jacobiMethod(A, b, x0, options = {}) {
25+
const { maxIterations = 1000, tolerance = 1e-6 } = options;
2426
const n = A.length; // Size of the square matrix
2527
let x = [...x0]; // Current solution (starts with initial guess)
2628
let xNew = new Array(n); // Next iteration's solution

src/methods/linearSystemScript.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// ______ ______ _____ _ _ //
2+
// | ____| ____| /\ / ____| (_) | | //
3+
// | |__ | |__ / \ | (___ ___ ____ _ ____ | |_ //
4+
// | __| | __| / /\ \ \___ \ / __| __| | _ \| __| //
5+
// | | | |____ / ____ \ ____) | (__| | | | |_) | | //
6+
// |_| |______/_/ \_\_____/ \___|_| |_| __/| | //
7+
// | | | | //
8+
// |_| | |_ //
9+
// Website: https://feascript.com/ \__| //
10+
11+
// Internal imports
12+
import { jacobiMethod } from "./jacobiMethodScript.js";
13+
import { basicLog, debugLog } from "../utilities/loggingScript.js";
14+
15+
/**
16+
* Function to solve a system of linear equations using different solver methods
17+
* @param {string} solverMethod - The solver method to use ("lusolve" or "jacobi")
18+
* @param {Array} jacobianMatrix - The coefficient matrix
19+
* @param {Array} residualVector - The right-hand side vector
20+
* @param {object} [options] - Additional options for the solver
21+
* @param {number} [options.maxIterations=1000] - Maximum iterations for iterative methods
22+
* @param {number} [options.tolerance=1e-6] - Convergence tolerance for iterative methods
23+
* @returns {object} An object containing:
24+
* - solutionVector: The solution vector
25+
* - converged: Boolean indicating whether the method converged (for iterative methods)
26+
* - iterations: Number of iterations performed (for iterative methods)
27+
*/
28+
export function solveLinearSystem(solverMethod, jacobianMatrix, residualVector, options = {}) {
29+
const { maxIterations = 1000, tolerance = 1e-6 } = options;
30+
31+
let solutionVector = [];
32+
let converged = true;
33+
let iterations = 0;
34+
35+
// Solve the linear system based on the specified solver method
36+
basicLog(`Solving system using ${solverMethod}...`);
37+
console.time("systemSolving");
38+
39+
if (solverMethod === "lusolve") {
40+
// Use LU decomposition method
41+
solutionVector = math.lusolve(jacobianMatrix, residualVector);
42+
} else if (solverMethod === "jacobi") {
43+
// Use Jacobi method
44+
const initialGuess = new Array(residualVector.length).fill(0);
45+
const jacobiResult = jacobiMethod(jacobianMatrix, residualVector, initialGuess, { maxIterations, tolerance });
46+
47+
// Log convergence information
48+
if (jacobiResult.converged) {
49+
debugLog(`Jacobi method converged in ${jacobiResult.iterations} iterations`);
50+
} else {
51+
debugLog(`Jacobi method did not converge after ${jacobiResult.iterations} iterations`);
52+
}
53+
54+
solutionVector = jacobiResult.solution;
55+
converged = jacobiResult.converged;
56+
iterations = jacobiResult.iterations;
57+
} else {
58+
throw new Error(`Unknown solver method: ${solverMethod}`);
59+
}
60+
61+
console.timeEnd("systemSolving");
62+
basicLog("System solved successfully");
63+
64+
return { solutionVector, converged, iterations };
65+
}

src/methods/newtonRaphsonScript.js

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
// Internal imports
1212
import { euclideanNorm } from "../methods/euclideanNormScript.js";
13+
import { solveLinearSystem } from "../methods/linearSystemScript.js";
1314
import { basicLog, debugLog, errorLog } from "./utilities/loggingScript.js";
1415

1516
/**
@@ -46,7 +47,7 @@ export function newtonRaphson(assembleMat, context, maxIterations = 100, toleran
4647

4748
// Compute Jacobian and Residual matrices
4849
if (assembleMat === "assembleFrontPropagationMat") {
49-
// Pass an additional artificial visous parameter for front propagation
50+
// Pass an additional viscous parameter for front propagation
5051
({ jacobianMatrix, residualVector, nodesCoordinates } = assembleMat(
5152
context.meshConfig,
5253
context.boundaryConditions,
@@ -61,21 +62,8 @@ export function newtonRaphson(assembleMat, context, maxIterations = 100, toleran
6162
}
6263

6364
// Solve the linear system based on the specified solver method
64-
basicLog(`Solving system using ${context.solverMethod}...`);
65-
if (context.solverMethod === "jacobi") {
66-
// Use Jacobi method
67-
const initialGuess = new Array(residualVector.length).fill(0);
68-
const jacobiResult = jacobiMethod(jacobianMatrix, residualVector, initialGuess, 1000, 1e-6);
69-
debugLog(
70-
`Used Jacobi solver in Newton-Raphson iteration ${iterations + 1}, converged: ${
71-
jacobiResult.converged
72-
}`
73-
);
74-
} else if (context.solverMethod === "lusolve") {
75-
// Use LU decomposition method
76-
deltaX = math.lusolve(jacobianMatrix, residualVector);
77-
debugLog(`Used LU decomposition solver in Newton-Raphson iteration ${iterations + 1}`);
78-
}
65+
const linearSystemResult = solveLinearSystem(context.solverMethod, jacobianMatrix, residualVector);
66+
deltaX = linearSystemResult.solutionVector;
7967

8068
// Check convergence
8169
errorNorm = euclideanNorm(deltaX);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy