Skip to content

Commit d2f75f8

Browse files
committedMay 5, 2025·
Enhance documentation and code clarity across multiple scripts by updating function descriptions, organizing imports, and improving formatting for better readability
1 parent b679f4d commit d2f75f8

13 files changed

+184
-151
lines changed
 

‎CONTRIBUTING.md

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,62 @@ Thank you for your interest in contributing! FEAScript is in early development,
2020
```
2121

2222
FEAScript can be run on a local server. To start a local server, you can use [Python HTTP Server](https://docs.python.org/3/library/http.server.html):
23-
```bash
24-
python -m http.server
25-
```
23+
24+
```bash
25+
python -m http.server
26+
```
27+
2628
where the server will be available at `http://127.0.0.1:8000/`. Static file server npm packages like [serve](https://github.com/vercel/serve#readme) and [Vite](https://vite.dev/) can also be used.
29+
30+
## File Structure Guidelines
31+
32+
All files in the FEAScript-core codebase should follow this structure:
33+
34+
1. **Banner**: All files start with the FEAScript ASCII art banner
35+
2. **Imports**:
36+
- External imports (from npm packages) first, alphabetically ordered
37+
- Internal imports next, grouped by module/folder
38+
3. **Classes/Functions**: Implementation with proper JSDoc comments
39+
40+
Example:
41+
42+
```javascript
43+
// ______ ______ _____ _ _ //
44+
// | ____| ____| /\ / ____| (_) | | //
45+
// | |__ | |__ / \ | (___ ___ ____ _ ____ | |_ //
46+
// | __| | __| / /\ \ \___ \ / __| __| | _ \| __| //
47+
// | | | |____ / ____ \ ____) | (__| | | | |_) | | //
48+
// |_| |______/_/ \_\_____/ \___|_| |_| __/| | //
49+
// | | | | //
50+
// |_| | |_ //
51+
// Website: https://feascript.com/ \__| //
52+
53+
// External imports
54+
import { mathLibrary } from "math-package";
55+
56+
// Internal imports
57+
import { relatedFunction } from "../utilities/helperScript.js";
58+
59+
/**
60+
* Class to handle specific functionality
61+
*/
62+
export class MyClass {
63+
/**
64+
* Constructor to initialize the class
65+
* @param {object} options - Configuration options
66+
*/
67+
constructor(options) {
68+
// Implementation
69+
}
70+
71+
/**
72+
* Function to perform a specific action
73+
* @param {number} input - Input value
74+
* @returns {number} Processed result
75+
*/
76+
doSomething(input) {
77+
// Implementation
78+
return input * DEFAULT_VALUE;
79+
}
80+
}
81+
```

‎src/FEAScript.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88
// |_| | |_ //
99
// Website: https://feascript.com/ \__| //
1010

11-
import { assembleSolidHeatTransferMat } from "./solvers/solidHeatTransferScript.js";
11+
// Internal imports
1212
import { jacobiMethod } from "./methods/jacobiMethodScript.js";
13+
import { assembleSolidHeatTransferMat } from "./solvers/solidHeatTransferScript.js";
1314
import { basicLog, debugLog } from "./utilities/loggingScript.js";
1415

1516
/**
16-
* FEAScript: An open-source finite element simulation library developed in JavaScript
17+
* Class to implement finite element analysis in JavaScript
1718
* @param {string} solverConfig - Parameter specifying the type of solver
1819
* @param {object} meshConfig - Object containing computational mesh details
1920
* @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis
@@ -35,7 +36,11 @@ export class FEAScriptModel {
3536

3637
setMeshConfig(meshConfig) {
3738
this.meshConfig = meshConfig;
38-
debugLog(`Mesh config set with dimensions: ${meshConfig.meshDimension}, elements: ${meshConfig.numElementsX}x${meshConfig.numElementsY || 1}`);
39+
debugLog(
40+
`Mesh config set with dimensions: ${meshConfig.meshDimension}, elements: ${meshConfig.numElementsX}x${
41+
meshConfig.numElementsY || 1
42+
}`
43+
);
3944
}
4045

4146
addBoundaryCondition(boundaryKey, condition) {
@@ -83,14 +88,14 @@ export class FEAScriptModel {
8388
const initialGuess = new Array(residualVector.length).fill(0);
8489
// Call Jacobi method with desired max iterations and tolerance
8590
const jacobiResult = jacobiMethod(jacobianMatrix, residualVector, initialGuess, 1000, 1e-6);
86-
91+
8792
// Log convergence information
8893
if (jacobiResult.converged) {
8994
debugLog(`Jacobi method converged in ${jacobiResult.iterations} iterations`);
9095
} else {
9196
debugLog(`Jacobi method did not converge after ${jacobiResult.iterations} iterations`);
9297
}
93-
98+
9499
solutionVector = jacobiResult.solution;
95100
}
96101
console.timeEnd("systemSolving");

‎src/mesh/basisFunctionsScript.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export class basisFunctions {
2323
}
2424

2525
/**
26-
* Return the basis functions and their derivatives based on the dimension and order
26+
* Function to calculate basis functions and their derivatives based on the dimension and order
2727
* @param {number} ksi - Natural coordinate (for both 1D and 2D)
2828
* @param {number} [eta] - Second natural coordinate (only for 2D elements)
2929
* @returns {object} An object containing:

‎src/mesh/meshGenerationScript.js

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

11-
/**
12-
* Class to handle the generation of structured finite element meshes
13-
*/
14-
11+
// Internal imports
1512
import { importGmshQuadTri } from "../readers/gmshReaderScript.js";
1613
import { errorLog } from "../utilities/loggingScript.js";
1714

15+
/**
16+
* Class to handle the generation of structured finite element meshes
17+
*/
1818
export class meshGeneration {
1919
/**
2020
* Constructor to initialize the meshGeneration class
@@ -46,7 +46,7 @@ export class meshGeneration {
4646
}
4747

4848
/**
49-
* Generate the mesh based on the dimension or custom mesh file
49+
* Function to generate the mesh based on the dimension or custom mesh file
5050
* @returns {object} The generated mesh containing node coordinates and total nodes
5151
*/
5252
generateMesh() {
@@ -64,7 +64,12 @@ export class meshGeneration {
6464
throw new Error(errorMessage);
6565
}
6666
} else if (this.meshDimension === "2D") {
67-
if (this.numElementsX === null || this.maxX === null || this.numElementsY === null || this.maxY === null) {
67+
if (
68+
this.numElementsX === null ||
69+
this.maxX === null ||
70+
this.numElementsY === null ||
71+
this.maxY === null
72+
) {
6873
const errorMessage =
6974
"numElementsX, maxX, numElementsY, and maxY are required parameters when generating a 2D mesh from geometry";
7075
errorLog(errorMessage);
@@ -78,7 +83,7 @@ export class meshGeneration {
7883
}
7984

8085
/**
81-
* Parse a custom mesh JSON file and generate the mesh
86+
* Function to parse a custom mesh JSON file and generate the mesh
8287
* @param {string} meshFilePath - Path to the custom mesh file (JSON format)
8388
* @returns {object} Mesh data containing coordinates and connectivity
8489
*/
@@ -106,7 +111,7 @@ export class meshGeneration {
106111
}
107112

108113
/**
109-
* Generate a structured mesh based on the msh file
114+
* Function to generate a structured mesh based on the msh file
110115
* @returns {object} An object containing the coordinates of nodes,
111116
* total number of nodes, nodal numbering (NOP) array, and boundary elements
112117
*/
@@ -118,7 +123,7 @@ export class meshGeneration {
118123
}
119124

120125
/**
121-
* Generate a structured mesh based on the geometry configuration
126+
* Function to generate a structured mesh based on the geometry configuration
122127
* @returns {object} An object containing the coordinates of nodes,
123128
* total number of nodes, nodal numbering (NOP) array, and boundary elements
124129
*/
@@ -233,21 +238,13 @@ export class meshGeneration {
233238
}
234239

235240
/**
236-
* Find the elements that belong to each boundary for a simple rectangular domain
241+
* Function to find the elements that belong to each boundary for a simple rectangular domain
237242
* @returns {array} An array containing arrays of elements and their adjacent boundary side for each boundary
238243
* Each element in the array is of the form [elementIndex, side], where side for a rectangular element is:
239244
* 0 - Bottom side
240245
* 1 - Left side
241246
* 2 - Top side
242247
* 3 - Right side
243-
*
244-
* Example representation of boundaryElements array in case of a rectangular element:
245-
* boundaryElements = [
246-
* [[element1, 0], [element2, 0], [element3, 0], ...], // Bottom boundary
247-
* [[element*, 1], [element*, 1], [element*, 1], ...], // Left boundary
248-
* [[element*, 2], [element*, 2], [element*, 2], ...], // Top boundary
249-
* [[element*, 3], [element*, 3], [element*, 3], ...] // Right boundary
250-
* ];
251248
*/
252249
findBoundaryElements() {
253250
const boundaryElements = [];
@@ -294,7 +291,7 @@ export class meshGeneration {
294291
}
295292

296293
/**
297-
* Generate the nodal numbering (NOP) array for a structured mesh
294+
* Function to generate the nodal numbering (NOP) array for a structured mesh
298295
* This array represents the connectivity between elements and their corresponding nodes
299296
* @param {number} numElementsX - Number of elements along the x-axis
300297
* @param {number} [numElementsY] - Number of elements along the y-axis (optional for 1D)

‎src/methods/jacobiMethodScript.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// Website: https://feascript.com/ \__| //
1010

1111
/**
12-
* Solves a system of linear equations using the Jacobi iterative method
12+
* Function to solve a system of linear equations using the Jacobi iterative method
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
@@ -22,9 +22,9 @@
2222
*/
2323
export function jacobiMethod(A, b, x0, maxIterations = 100, tolerance = 1e-7) {
2424
const n = A.length; // Size of the square matrix
25-
let x = [...x0]; // Current solution (starts with initial guess)
25+
let x = [...x0]; // Current solution (starts with initial guess)
2626
let xNew = new Array(n); // Next iteration's solution
27-
27+
2828
for (let iteration = 0; iteration < maxIterations; iteration++) {
2929
// Perform one iteration
3030
for (let i = 0; i < n; i++) {
@@ -38,30 +38,30 @@ export function jacobiMethod(A, b, x0, maxIterations = 100, tolerance = 1e-7) {
3838
// Update xNew[i] using the Jacobi formula
3939
xNew[i] = (b[i] - sum) / A[i][i];
4040
}
41-
41+
4242
// Check convergence
4343
let maxDiff = 0;
4444
for (let i = 0; i < n; i++) {
4545
maxDiff = Math.max(maxDiff, Math.abs(xNew[i] - x[i]));
4646
}
47-
47+
4848
// Update x for next iteration
4949
x = [...xNew];
50-
50+
5151
// Successfully converged if maxDiff is less than tolerance
5252
if (maxDiff < tolerance) {
5353
return {
5454
solution: x,
5555
iterations: iteration + 1,
56-
converged: true
56+
converged: true,
5757
};
5858
}
5959
}
60-
60+
6161
// maxIterations were reached without convergence
6262
return {
6363
solution: x,
6464
iterations: maxIterations,
65-
converged: false
65+
converged: false,
6666
};
67-
}
67+
}

‎src/methods/numericalIntegrationScript.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@
1313
*/
1414
export class numericalIntegration {
1515
/**
16-
* Constructor to initialize the numIntegration class
16+
* Constructor to initialize the numericalIntegration class
1717
* @param {string} meshDimension - The dimension of the mesh
18-
* @param {number} elementOrder - The order of elements
18+
* @param {string} elementOrder - The order of elements
1919
*/
2020
constructor({ meshDimension, elementOrder }) {
2121
this.meshDimension = meshDimension;
2222
this.elementOrder = elementOrder;
2323
}
2424

2525
/**
26-
* Return Gauss points and weights based on element configuration
26+
* Function to return Gauss points and weights based on element configuration
2727
* @returns {object} An object containing:
2828
* - gaussPoints: Array of Gauss points
2929
* - gaussWeights: Array of Gauss weights

‎src/readers/gmshReaderScript.js

Lines changed: 29 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
// |_| | |_ //
99
// Website: https://feascript.com/ \__| //
1010

11+
/**
12+
* Function to import mesh data from Gmsh format containing quadrilateral and triangular elements
13+
* @param {File} file - The Gmsh file to be parsed
14+
* @returns {object} The parsed mesh data including node coordinates, element connectivity, and boundary conditions
15+
*/
1116
const importGmshQuadTri = async (file) => {
1217
let result = {
1318
nodesXCoordinates: [],
@@ -17,7 +22,7 @@ const importGmshQuadTri = async (file) => {
1722
triangleElements: [],
1823
},
1924
boundaryElements: [],
20-
boundaryConditions: [],
25+
boundaryConditions: [],
2126
gmshV: 0,
2227
ascii: false,
2328
fltBytes: "8",
@@ -54,9 +59,9 @@ const importGmshQuadTri = async (file) => {
5459
numElements: 0,
5560
};
5661
let elementsProcessedInBlock = 0;
57-
62+
5863
let boundaryElementsByTag = {};
59-
64+
6065
while (lineIndex < lines.length) {
6166
const line = lines[lineIndex];
6267

@@ -136,10 +141,7 @@ const importGmshQuadTri = async (file) => {
136141
continue;
137142
}
138143

139-
if (
140-
nodeBlocksProcessed < nodeEntityBlocks &&
141-
currentNodeBlock.numNodes === 0
142-
) {
144+
if (nodeBlocksProcessed < nodeEntityBlocks && currentNodeBlock.numNodes === 0) {
143145
currentNodeBlock = {
144146
dim: parseInt(parts[0], 10),
145147
tag: parseInt(parts[1], 10),
@@ -156,11 +158,7 @@ const importGmshQuadTri = async (file) => {
156158
}
157159

158160
if (nodeTagsCollected < currentNodeBlock.numNodes) {
159-
for (
160-
let i = 0;
161-
i < parts.length && nodeTagsCollected < currentNodeBlock.numNodes;
162-
i++
163-
) {
161+
for (let i = 0; i < parts.length && nodeTagsCollected < currentNodeBlock.numNodes; i++) {
164162
nodeTags.push(parseInt(parts[i], 10));
165163
nodeTagsCollected++;
166164
}
@@ -199,10 +197,7 @@ const importGmshQuadTri = async (file) => {
199197
continue;
200198
}
201199

202-
if (
203-
elementBlocksProcessed < elementEntityBlocks &&
204-
currentElementBlock.numElements === 0
205-
) {
200+
if (elementBlocksProcessed < elementEntityBlocks && currentElementBlock.numElements === 0) {
206201
currentElementBlock = {
207202
dim: parseInt(parts[0], 10),
208203
tag: parseInt(parts[1], 10),
@@ -211,8 +206,7 @@ const importGmshQuadTri = async (file) => {
211206
};
212207

213208
result.elementTypes[currentElementBlock.elementType] =
214-
(result.elementTypes[currentElementBlock.elementType] || 0) +
215-
currentElementBlock.numElements;
209+
(result.elementTypes[currentElementBlock.elementType] || 0) + currentElementBlock.numElements;
216210

217211
elementsProcessedInBlock = 0;
218212
lineIndex++;
@@ -225,16 +219,15 @@ const importGmshQuadTri = async (file) => {
225219

226220
if (currentElementBlock.elementType === 1) {
227221
const physicalTag = currentElementBlock.tag;
228-
222+
229223
if (!boundaryElementsByTag[physicalTag]) {
230224
boundaryElementsByTag[physicalTag] = [];
231225
}
232-
226+
233227
boundaryElementsByTag[physicalTag].push(nodeIndices);
234228
} else if (currentElementBlock.elementType === 2) {
235229
result.nodalNumbering.triangleElements.push(nodeIndices);
236230
} else if (currentElementBlock.elementType === 3) {
237-
238231
result.nodalNumbering.quadElements.push(nodeIndices);
239232
}
240233

@@ -250,42 +243,34 @@ const importGmshQuadTri = async (file) => {
250243
lineIndex++;
251244
}
252245

253-
result.physicalPropMap.forEach(prop => {
254-
if (prop.dimension === 1) {
246+
result.physicalPropMap.forEach((prop) => {
247+
if (prop.dimension === 1) {
255248
const boundaryNodes = boundaryElementsByTag[prop.tag] || [];
256-
249+
257250
if (boundaryNodes.length > 0) {
258251
result.boundaryConditions.push({
259252
name: prop.name,
260253
tag: prop.tag,
261-
nodes: boundaryNodes
254+
nodes: boundaryNodes,
262255
});
263256
}
264257
}
265258
});
266259

267-
processBoundaryElements(
268-
result.nodalNumbering.triangleElements,
269-
result.boundaryElements,
270-
3,
271-
"triangle"
272-
);
273-
processBoundaryElements(
274-
result.nodalNumbering.quadElements,
275-
result.boundaryElements,
276-
4,
277-
"quad"
278-
);
260+
processBoundaryElements(result.nodalNumbering.triangleElements, result.boundaryElements, 3, "triangle");
261+
processBoundaryElements(result.nodalNumbering.quadElements, result.boundaryElements, 4, "quad");
279262

280263
return result;
281264
};
282265

283-
function processBoundaryElements(
284-
elements,
285-
boundaryElements,
286-
numNodes,
287-
elementType
288-
) {
266+
/**
267+
* Function to process boundary elements from a mesh
268+
* @param {array} elements - Array of elements to process
269+
* @param {array} boundaryElements - Array to store the boundary elements
270+
* @param {number} numNodes - Number of nodes per element
271+
* @param {string} elementType - Type of element (triangle, quad)
272+
*/
273+
function processBoundaryElements(elements, boundaryElements, numNodes, elementType) {
289274
const edgeCount = {};
290275

291276
for (let i = 0; i < elements.length; i++) {
@@ -321,4 +306,4 @@ function processBoundaryElements(
321306
}
322307
}
323308

324-
export { importGmshQuadTri };
309+
export { importGmshQuadTri };

‎src/solvers/solidHeatTransferScript.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@
88
// |_| | |_ //
99
// Website: https://feascript.com/ \__| //
1010

11-
import { basisFunctions } from "../mesh/basisFunctionsScript.js";
11+
// Internal imports
1212
import { numericalIntegration } from "../methods/numericalIntegrationScript.js";
13+
import { basisFunctions } from "../mesh/basisFunctionsScript.js";
1314
import { meshGeneration } from "../mesh/meshGenerationScript.js";
1415
import { ThermalBoundaryConditions } from "./thermalBoundaryConditionsScript.js";
1516
import { basicLog, debugLog } from "../utilities/loggingScript.js";
1617

1718
/**
18-
* Assemble the solid heat transfer matrix
19+
* Function to assemble the solid heat transfer matrix
1920
* @param {object} meshConfig - Object containing computational mesh details
2021
* @param {object} boundaryConditions - Object containing boundary conditions for the finite element analysis
2122
* @returns {object} An object containing:

‎src/solvers/thermalBoundaryConditionsScript.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export class ThermalBoundaryConditions {
2929
}
3030

3131
/**
32-
* Impose constant temperature boundary conditions (Dirichlet type)
32+
* Function to impose constant temperature boundary conditions (Dirichlet type)
3333
* @param {array} residualVector - The residual vector to be modified
3434
* @param {array} jacobianMatrix - The Jacobian matrix to be modified
3535
*/
@@ -124,7 +124,7 @@ export class ThermalBoundaryConditions {
124124
}
125125

126126
/**
127-
* Impose convection boundary conditions (Robin type)
127+
* Function to impose convection boundary conditions (Robin type)
128128
* @param {array} residualVector - The residual vector to be modified
129129
* @param {array} jacobianMatrix - The Jacobian matrix to be modified
130130
* @param {array} gaussPoints - Array of Gauss points for numerical integration
@@ -177,7 +177,7 @@ export class ThermalBoundaryConditions {
177177
nodeIndex = 2;
178178
}
179179
}
180-
180+
181181
const globalNodeIndex = this.nop[elementIndex][nodeIndex] - 1;
182182
residualVector[globalNodeIndex] += -convectionCoeff * extTemp;
183183
jacobianMatrix[globalNodeIndex][globalNodeIndex] += convectionCoeff;

‎src/utilities/loggingScript.js

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,46 +9,49 @@
99
// Website: https://feascript.com/ \__| //
1010

1111
// Global logging level
12-
let currentLogLevel = 'basic';
12+
let currentLogLevel = "basic";
1313

1414
/**
1515
* Function to set the logging system level
1616
* @param {string} level - Logging level (basic, debug)
1717
*/
1818
export function logSystem(level) {
19-
if (level !== 'basic' && level !== 'debug') {
20-
console.log('%c[WARN] Invalid log level: ' + level + '. Using basic instead.', 'color: #FFC107; font-weight: bold;'); // Yellow for warnings
21-
currentLogLevel = 'basic';
19+
if (level !== "basic" && level !== "debug") {
20+
console.log(
21+
"%c[WARN] Invalid log level: " + level + ". Using basic instead.",
22+
"color: #FFC107; font-weight: bold;"
23+
); // Yellow for warnings
24+
currentLogLevel = "basic";
2225
} else {
2326
currentLogLevel = level;
2427
basicLog(`Log level set to: ${level}`);
2528
}
2629
}
2730

2831
/**
29-
* Debug logging function - only logs if level is 'debug'
32+
* Function to log debug messages - only logs if level is 'debug'
3033
* @param {string} message - Message to log
3134
*/
3235
export function debugLog(message) {
33-
if (currentLogLevel === 'debug') {
34-
console.log('%c[DEBUG] ' + message, 'color: #2196F3; font-weight: bold;'); // Blue color for debug
36+
if (currentLogLevel === "debug") {
37+
console.log("%c[DEBUG] " + message, "color: #2196F3; font-weight: bold;"); // Blue color for debug
3538
}
3639
}
3740

3841
/**
39-
* Basic logging function - always logs
42+
* Function to log basic information - always logs
4043
* @param {string} message - Message to log
4144
*/
4245
export function basicLog(message) {
43-
console.log('%c[INFO] ' + message, 'color: #4CAF50; font-weight: bold;'); // Green color for basic info
46+
console.log("%c[INFO] " + message, "color: #4CAF50; font-weight: bold;"); // Green color for basic info
4447
}
4548

4649
/**
47-
* Error logging function
50+
* Function to log error messages
4851
* @param {string} message - Message to log
4952
*/
5053
export function errorLog(message) {
51-
console.log('%c[ERROR] ' + message, 'color: #F44336; font-weight: bold;'); // Red color for errors
54+
console.log("%c[ERROR] " + message, "color: #F44336; font-weight: bold;"); // Red color for errors
5255
}
5356

5457
/**

‎src/visualization/plotSolutionScript.js

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// Website: https://feascript.com/ \__| //
1010

1111
/**
12-
* Create plots of the solution vector
12+
* Function to create plots of the solution vector
1313
* @param {*} solutionVector - The computed solution vector
1414
* @param {*} nodesCoordinates - Object containing x and y coordinates for the nodes
1515
* @param {string} solverConfig - Parameter specifying the type of solver
@@ -33,7 +33,7 @@ export function plotSolution(
3333
// Check if solutionVector is a nested array
3434
let yData;
3535
if (solutionVector.length > 0 && Array.isArray(solutionVector[0])) {
36-
yData = solutionVector.map(arr => arr[0]);
36+
yData = solutionVector.map((arr) => arr[0]);
3737
} else {
3838
yData = solutionVector;
3939
}
@@ -45,7 +45,7 @@ export function plotSolution(
4545
mode: "lines",
4646
type: "scatter",
4747
line: { color: "rgb(219, 64, 82)", width: 2 },
48-
name: "Solution"
48+
name: "Solution",
4949
};
5050

5151
let maxWindowWidth = Math.min(window.innerWidth, 700);
@@ -60,7 +60,7 @@ export function plotSolution(
6060
height: plotHeight,
6161
xaxis: { title: "x" },
6262
yaxis: { title: "Solution" },
63-
margin: { l: 70, r: 40, t: 50, b: 50 }
63+
margin: { l: 70, r: 40, t: 50, b: 50 },
6464
};
6565

6666
Plotly.newPlot(plotDivId, [lineData], layout, { responsive: true });
@@ -70,20 +70,11 @@ export function plotSolution(
7070
const numNodesY = new Set(nodesYCoordinates).size;
7171

7272
// Reshape the nodesXCoordinates and nodesYCoordinates arrays to match the grid dimensions
73-
let reshapedXCoordinates = math.reshape(Array.from(nodesXCoordinates), [
74-
numNodesX,
75-
numNodesY,
76-
]);
77-
let reshapedYCoordinates = math.reshape(Array.from(nodesYCoordinates), [
78-
numNodesX,
79-
numNodesY,
80-
]);
73+
let reshapedXCoordinates = math.reshape(Array.from(nodesXCoordinates), [numNodesX, numNodesY]);
74+
let reshapedYCoordinates = math.reshape(Array.from(nodesYCoordinates), [numNodesX, numNodesY]);
8175

8276
// Reshape the solution array to match the grid dimensions
83-
let reshapedSolution = math.reshape(Array.from(solutionVector), [
84-
numNodesX,
85-
numNodesY,
86-
]);
77+
let reshapedSolution = math.reshape(Array.from(solutionVector), [numNodesX, numNodesY]);
8778

8879
// Transpose the reshapedSolution array to get column-wise data
8980
let transposedSolution = math.transpose(reshapedSolution);
@@ -148,9 +139,7 @@ export function plotSolution(
148139

149140
// Set the layout for the contour plot
150141
let layout = {
151-
title: `${plotType} plot${
152-
showMesh ? " with mesh" : ""
153-
} - ${solverConfig}`,
142+
title: `${plotType} plot${showMesh ? " with mesh" : ""} - ${solverConfig}`,
154143
width: plotWidth,
155144
height: plotHeight,
156145
xaxis: { title: "x" },

‎src/workers/workerScript.js

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

11-
// import * as Comlink from "https://unpkg.com/comlink/dist/esm/comlink.mjs";
12-
// The Web Worker functionality now uses the local Comlink library to avoid CORS issues
11+
// External imports
1312
import * as Comlink from "../vendor/comlink.mjs";
13+
14+
// Internal imports
1415
import { basicLog } from "../utilities/loggingScript.js";
1516

17+
/**
18+
* Class to facilitate communication with web workers for FEAScript operations
19+
*/
1620
export class FEAScriptWorker {
1721
/**
1822
* Constructor to initialize the FEAScriptWorker class
@@ -27,18 +31,15 @@ export class FEAScriptWorker {
2731
}
2832

2933
/**
30-
* Initializes the web worker and wraps it using Comlink.
34+
* Function to initialize the web worker and wrap it using Comlink.
3135
* @private
3236
* @throws Will throw an error if the worker fails to initialize.
3337
*/
3438
async _initWorker() {
3539
try {
36-
this.worker = new Worker(
37-
new URL("./wrapperScript.js", import.meta.url),
38-
{
39-
type: "module",
40-
}
41-
);
40+
this.worker = new Worker(new URL("./wrapperScript.js", import.meta.url), {
41+
type: "module",
42+
});
4243

4344
this.worker.onerror = (event) => {
4445
console.error("FEAScriptWorker: Worker error:", event);
@@ -55,7 +56,7 @@ export class FEAScriptWorker {
5556
}
5657

5758
/**
58-
* Ensures that the worker is ready before performing any operations.
59+
* Function to ensure that the worker is ready before performing any operations.
5960
* @private
6061
* @returns {Promise<void>} Resolves when the worker is ready.
6162
* @throws Will throw an error if the worker is not ready within the timeout period.
@@ -82,7 +83,7 @@ export class FEAScriptWorker {
8283
}
8384

8485
/**
85-
* Sets the solver configuration in the worker.
86+
* Function to set the solver configuration in the worker.
8687
* @param {string} solverConfig - The solver configuration to set.
8788
* @returns {Promise<boolean>} Resolves when the configuration is set.
8889
*/
@@ -111,9 +112,7 @@ export class FEAScriptWorker {
111112
*/
112113
async addBoundaryCondition(boundaryKey, condition) {
113114
await this._ensureReady();
114-
basicLog(
115-
`FEAScriptWorker: Adding boundary condition for boundary: ${boundaryKey}`
116-
);
115+
basicLog(`FEAScriptWorker: Adding boundary condition for boundary: ${boundaryKey}`);
117116
return this.feaWorker.addBoundaryCondition(boundaryKey, condition);
118117
}
119118

@@ -140,12 +139,7 @@ export class FEAScriptWorker {
140139
const result = await this.feaWorker.solve();
141140
const endTime = performance.now();
142141

143-
basicLog(
144-
`FEAScriptWorker: Solution completed in ${(
145-
(endTime - startTime) /
146-
1000
147-
).toFixed(2)}s`
148-
);
142+
basicLog(`FEAScriptWorker: Solution completed in ${((endTime - startTime) / 1000).toFixed(2)}s`);
149143
return result;
150144
}
151145

‎src/workers/wrapperScript.js

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

11-
// import * as Comlink from "https://unpkg.com/comlink/dist/esm/comlink.mjs";
12-
// The Web Worker functionality now uses the local Comlink library to avoid CORS issues
11+
// External imports
12+
import { create, all } from "https://cdn.jsdelivr.net/npm/mathjs@latest/+esm";
1313
import * as Comlink from "../vendor/comlink.mjs";
14+
15+
// Internal imports
1416
import { FEAScriptModel } from "../FEAScript.js";
15-
import { create, all } from "https://cdn.jsdelivr.net/npm/mathjs@latest/+esm";
1617

1718
const math = create(all);
1819

1920
globalThis.math = math;
2021

22+
/**
23+
* Class to wrap the FEAScriptModel for use in a web worker context
24+
*/
2125
class workerWrapper {
2226
/**
2327
* Constructor to initialize the workerWrapper class.
@@ -34,7 +38,7 @@ class workerWrapper {
3438
}
3539

3640
/**
37-
* Sets the solver configuration in the FEAScriptModel.
41+
* Function to set the solver configuration in the FEAScriptModel.
3842
* @param {string} solverConfig - The solver configuration to set.
3943
* @returns {boolean} Returns true if the configuration is set successfully.
4044
* @throws Will throw an error if the configuration fails to set.
@@ -50,7 +54,7 @@ class workerWrapper {
5054
}
5155

5256
/**
53-
* Sets the mesh configuration in the FEAScriptModel.
57+
* Function to set the mesh configuration in the FEAScriptModel.
5458
* @param {object} meshConfig - The mesh configuration to set.
5559
* @returns {boolean} Returns true if the configuration is set successfully.
5660
* @throws Will throw an error if the configuration fails to set.
@@ -66,7 +70,7 @@ class workerWrapper {
6670
}
6771

6872
/**
69-
* Adds a boundary condition to the FEAScriptModel.
73+
* Function to add a boundary condition to the FEAScriptModel.
7074
* @param {string} boundaryKey - The key identifying the boundary.
7175
* @param {array} condition - The boundary condition to add.
7276
* @returns {boolean} Returns true if the boundary condition is added successfully.
@@ -83,7 +87,7 @@ class workerWrapper {
8387
}
8488

8589
/**
86-
* Sets the solver method in the FEAScriptModel.
90+
* Function to set the solver method in the FEAScriptModel.
8791
* @param {string} solverMethod - The solver method to set.
8892
* @returns {boolean} Returns true if the solver method is set successfully.
8993
* @throws Will throw an error if the solver method fails to set.
@@ -99,7 +103,7 @@ class workerWrapper {
99103
}
100104

101105
/**
102-
* Solves the problem using the FEAScriptModel.
106+
* Function to solve the problem using the FEAScriptModel.
103107
* @returns {object} Returns the solution result, including the solution vector, node coordinates, solver configuration, and mesh dimension.
104108
* @throws Will throw an error if the solve operation fails.
105109
*/
@@ -120,7 +124,7 @@ class workerWrapper {
120124
}
121125

122126
/**
123-
* Retrieves model information from the FEAScriptModel.
127+
* Function to retrieve model information from the FEAScriptModel.
124128
* @returns {object} Returns the model information, including solver configuration, mesh configuration, boundary conditions, and solver method.
125129
* @throws Will throw an error if the model information fails to retrieve.
126130
*/
@@ -139,7 +143,7 @@ class workerWrapper {
139143
}
140144

141145
/**
142-
* Simple ping method to check if the worker is responsive.
146+
* Function to perform a simple ping to check if the worker is responsive.
143147
* @returns {boolean} Returns true to indicate the worker is available.
144148
*/
145149
ping() {
@@ -152,4 +156,4 @@ class workerWrapper {
152156
}
153157
}
154158

155-
Comlink.expose(workerWrapper);
159+
Comlink.expose(workerWrapper);

0 commit comments

Comments
 (0)
Please sign in to comment.