Skip to content

Commit d51e418

Browse files
committed
Add logging functionality using
loglevel (https://github.com/pimterry/loglevel?tab=MIT-1-ov-file#readme)
1 parent ac43574 commit d51e418

File tree

8 files changed

+118
-28
lines changed

8 files changed

+118
-28
lines changed

NOTICE.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,8 @@ FEAScript makes use of the following third-party software:
99
- License: MIT License
1010
- Source: https://github.com/plotly/plotly.js/tree/master
1111
- License: https://github.com/plotly/plotly.js/blob/master/LICENSE
12+
13+
2. **loglevel**
14+
- License: MIT License
15+
- Source: https://github.com/pimterry/loglevel
16+
- License: https://github.com/pimterry/loglevel/blob/main/LICENSE-MIT

src/FEAScript.js

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

1111
import { assembleSolidHeatTransferMat } from "./solvers/solidHeatTransferScript.js";
12+
import loggers from "./utilities/loggerScript.js";
13+
14+
const log = loggers.main;
1215

1316
/**
1417
* FEAScript: An open-source finite element simulation library developed in JavaScript
@@ -23,27 +26,34 @@ export class FEAScriptModel {
2326
this.meshConfig = {};
2427
this.boundaryConditions = {};
2528
this.solverMethod = "lusolve"; // Default solver method
29+
log.info("FEAScriptModel instance created");
2630
}
2731

2832
setSolverConfig(solverConfig) {
2933
this.solverConfig = solverConfig;
34+
log.debug(`Solver config set to: ${solverConfig}`);
3035
}
3136

3237
setMeshConfig(meshConfig) {
3338
this.meshConfig = meshConfig;
39+
log.debug(`Mesh config set with dimensions: ${meshConfig.meshDimension}, elements: ${meshConfig.numElementsX}x${meshConfig.numElementsY || 1}`);
3440
}
3541

3642
addBoundaryCondition(boundaryKey, condition) {
3743
this.boundaryConditions[boundaryKey] = condition;
44+
log.debug(`Boundary condition added for key: ${boundaryKey}, type: ${condition[0]}`);
3845
}
3946

4047
setSolverMethod(solverMethod) {
4148
this.solverMethod = solverMethod;
49+
log.debug(`Solver method set to: ${solverMethod}`);
4250
}
4351

4452
solve() {
4553
if (!this.solverConfig || !this.meshConfig || !this.boundaryConditions) {
46-
throw new Error("Solver config, mesh config, and boundary conditions must be set before solving.");
54+
const error = "Solver config, mesh config, and boundary conditions must be set before solving.";
55+
log.error(error);
56+
throw new Error(error);
4757
}
4858

4959
let jacobianMatrix = []; // Jacobian matrix
@@ -52,22 +62,26 @@ export class FEAScriptModel {
5262
let nodesCoordinates = {}; // Object to store x and y coordinates of nodes
5363

5464
// Assembly matrices
65+
log.info("Beginning matrix assembly...");
5566
console.time("assemblyMatrices");
5667
if (this.solverConfig === "solidHeatTransferScript") {
57-
console.log("FEAScript solver:", this.solverConfig);
68+
log.info(`Using solver: ${this.solverConfig}`);
5869
({ jacobianMatrix, residualVector, nodesCoordinates } = assembleSolidHeatTransferMat(
5970
this.meshConfig,
6071
this.boundaryConditions
6172
));
6273
}
6374
console.timeEnd("assemblyMatrices");
75+
log.info("Matrix assembly completed");
6476

6577
// System solving
78+
log.info(`Solving system using ${this.solverMethod}...`);
6679
console.time("systemSolving");
6780
if (this.solverMethod === "lusolve") {
6881
solutionVector = math.lusolve(jacobianMatrix, residualVector); // Solve the system of linear equations using LU decomposition
6982
}
7083
console.timeEnd("systemSolving");
84+
log.info("System solved successfully");
7185

7286
// Return the solution matrix and nodes coordinates
7387
return {

src/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@
1010

1111
export { FEAScriptModel } from "./FEAScript.js";
1212
export { plotSolution } from "./visualization/plotSolutionScript.js";
13-
export { printVersion } from "./utilities/helperFunctionsScript.js";
13+
export { printVersion, setLogLevel } from "./utilities/utilitiesScript.js";
14+
export { default as loggers } from "./utilities/loggerScript.js";

src/solvers/solidHeatTransferScript.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ import { basisFunctions } from "../mesh/basisFunctionsScript.js";
1212
import { numericalIntegration } from "../methods/numericalIntegrationScript.js";
1313
import { meshGeneration } from "../mesh/meshGenerationScript.js";
1414
import { ThermalBoundaryConditions } from "../methods/thermalBoundaryConditionsScript.js";
15+
import loggers from "../utilities/loggerScript.js";
16+
17+
const log = loggers.solver;
1518

1619
/**
1720
* Assemble the solid heat transfer matrix
@@ -23,6 +26,8 @@ import { ThermalBoundaryConditions } from "../methods/thermalBoundaryConditionsS
2326
* - nodesCoordinates: Object containing x and y coordinates of nodes
2427
*/
2528
export function assembleSolidHeatTransferMat(meshConfig, boundaryConditions) {
29+
log.info("Starting solid heat transfer matrix assembly");
30+
2631
// Extract mesh details from the configuration object
2732
const {
2833
meshDimension, // The dimension of the mesh
@@ -33,6 +38,8 @@ export function assembleSolidHeatTransferMat(meshConfig, boundaryConditions) {
3338
elementOrder, // The order of elements
3439
} = meshConfig;
3540

41+
log.debug(`Mesh configuration: ${meshDimension}, Elements: ${numElementsX}x${numElementsY || 1}, Size: ${maxX}x${maxY || 0}, Order: ${elementOrder}`);
42+
3643
// Extract boundary conditions from the configuration object
3744
let convectionHeatTranfCoeff = [];
3845
let convectionExtTemp = [];
@@ -41,10 +48,12 @@ export function assembleSolidHeatTransferMat(meshConfig, boundaryConditions) {
4148
if (boundaryCondition[0] === "convection") {
4249
convectionHeatTranfCoeff[key] = boundaryCondition[1];
4350
convectionExtTemp[key] = boundaryCondition[2];
51+
log.debug(`Convection boundary condition on boundary ${key}: h=${boundaryCondition[1]}, T=${boundaryCondition[2]}`);
4452
}
4553
});
4654

4755
// Create a new instance of the meshGeneration class
56+
log.debug("Generating mesh...");
4857
const meshGenerationData = new meshGeneration({
4958
numElementsX,
5059
numElementsY,
@@ -56,6 +65,7 @@ export function assembleSolidHeatTransferMat(meshConfig, boundaryConditions) {
5665

5766
// Generate the mesh
5867
const nodesCoordinatesAndNumbering = meshGenerationData.generateMesh();
68+
log.debug("Mesh generated successfully");
5969

6070
// Extract nodes coordinates and nodal numbering (NOP) from the mesh data
6171
let nodesXCoordinates = nodesCoordinatesAndNumbering.nodesXCoordinates;
@@ -68,6 +78,9 @@ export function assembleSolidHeatTransferMat(meshConfig, boundaryConditions) {
6878
// Initialize variables for matrix assembly
6979
const totalElements = numElementsX * (meshDimension === "2D" ? numElementsY : 1); // Total number of elements
7080
const totalNodes = totalNodesX * (meshDimension === "2D" ? totalNodesY : 1); // Total number of nodes
81+
log.debug(`Total elements: ${totalElements}, Total nodes: ${totalNodes}`);
82+
83+
// Initialize variables for matrix assembly
7184
let localNodalNumbers = []; // Local nodal numbering
7285
let gaussPoints = []; // Gauss points
7386
let gaussWeights = []; // Gauss weights
@@ -96,12 +109,14 @@ export function assembleSolidHeatTransferMat(meshConfig, boundaryConditions) {
96109
}
97110

98111
// Initialize the basisFunctions class
112+
log.debug("Initializing basis functions...");
99113
const basisFunctionsData = new basisFunctions({
100114
meshDimension,
101115
elementOrder,
102116
});
103117

104118
// Initialize the numericalIntegration class
119+
log.debug("Setting up numerical integration...");
105120
const numIntegrationData = new numericalIntegration({
106121
meshDimension,
107122
elementOrder,
@@ -114,6 +129,8 @@ export function assembleSolidHeatTransferMat(meshConfig, boundaryConditions) {
114129

115130
// Determine the number of nodes in the reference element based on the first element in the nop array
116131
const numNodes = nop[0].length;
132+
133+
log.info(`Beginning matrix assembly for ${totalElements} elements...`);
117134

118135
// Matrix assembly
119136
for (let elementIndex = 0; elementIndex < totalElements; elementIndex++) {
@@ -236,6 +253,7 @@ export function assembleSolidHeatTransferMat(meshConfig, boundaryConditions) {
236253
}
237254

238255
// Create an instance of ThermalBoundaryConditions
256+
log.debug("Applying thermal boundary conditions...");
239257
const thermalBoundaryConditions = new ThermalBoundaryConditions(
240258
boundaryConditions,
241259
boundaryElements,
@@ -256,9 +274,13 @@ export function assembleSolidHeatTransferMat(meshConfig, boundaryConditions) {
256274
convectionHeatTranfCoeff,
257275
convectionExtTemp
258276
);
277+
log.debug("Convection boundary conditions applied");
259278

260279
// Impose ConstantTemp boundary conditions
261280
thermalBoundaryConditions.imposeConstantTempBoundaryConditions(residualVector, jacobianMatrix);
281+
log.debug("Constant temperature boundary conditions applied");
282+
283+
log.info("Solid heat transfer matrix assembly completed");
262284

263285
return {
264286
jacobianMatrix,

src/utilities/helperFunctionsScript.js

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/utilities/loggerScript.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// ______ ______ _____ _ _ //
2+
// | ____| ____| /\ / ____| (_) | | //
3+
// | |__ | |__ / \ | (___ ___ ____ _ ____ | |_ //
4+
// | __| | __| / /\ \ \___ \ / __| __| | _ \| __| //
5+
// | | | |____ / ____ \ ____) | (__| | | | |_) | | //
6+
// |_| |______/_/ \_\_____/ \___|_| |_| __/| | //
7+
// | | | | //
8+
// |_| | |_ //
9+
// Website: https://feascript.com/ \__| //
10+
11+
import log from '../third-party/loglevel.min.js';
12+
13+
// Configure default log level (can be overridden)
14+
log.setDefaultLevel(log.levels.INFO);
15+
16+
// Create namespace-specific loggers for different parts of the app
17+
const loggers = {
18+
main: log.getLogger('FEAScript'),
19+
solver: log.getLogger('Solver'),
20+
mesh: log.getLogger('Mesh'),
21+
visualization: log.getLogger('Viz')
22+
};
23+
24+
// Helper method to set all loggers to a specific level
25+
export function setAllLogLevels(level) {
26+
Object.values(loggers).forEach(logger => logger.setLevel(level));
27+
}
28+
29+
// Export the configured loggers
30+
export default loggers;

src/utilities/utilitiesScript.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// ______ ______ _____ _ _ //
2+
// | ____| ____| /\ / ____| (_) | | //
3+
// | |__ | |__ / \ | (___ ___ ____ _ ____ | |_ //
4+
// | __| | __| / /\ \ \___ \ / __| __| | _ \| __| //
5+
// | | | |____ / ____ \ ____) | (__| | | | |_) | | //
6+
// |_| |______/_/ \_\_____/ \___|_| |_| __/| | //
7+
// | | | | //
8+
// |_| | |_ //
9+
// Website: https://feascript.com/ \__| //
10+
11+
import loggers from './loggerScript.js';
12+
13+
const log = loggers.main;
14+
15+
/**
16+
* Function to handle version information and fetch the latest update date and release from GitHub
17+
*/
18+
export async function printVersion() {
19+
log.info("Fetching latest FEAScript version information...");
20+
try {
21+
// Fetch the latest commit date
22+
const commitResponse = await fetch("https://api.github.com/repos/FEAScript/FEAScript/commits/main");
23+
const commitData = await commitResponse.json();
24+
const latestCommitDate = new Date(commitData.commit.committer.date).toLocaleString();
25+
log.info(`Latest FEAScript update: ${latestCommitDate}`);
26+
return latestCommitDate;
27+
} catch (error) {
28+
log.error("Failed to fetch version information:", error);
29+
return "Version information unavailable";
30+
}
31+
}
32+
33+
/**
34+
* Set the logging level for all loggers
35+
* @param {string} level - The log level to set (trace, debug, info, warn, error)
36+
*/
37+
export function setLogLevel(level) {
38+
loggers.setAllLogLevels(level);
39+
log.info(`Log level set to: ${level}`);
40+
}

third-party/loglevel.min.js

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)