Skip to content

Added worker #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions src/FEAWorkerScript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import * as Comlink from "https://unpkg.com/comlink/dist/esm/comlink.mjs";
import { basicLog } from "./utilities/utilitiesScript.js";

export class FEAWorkerScript {
constructor() {
this.worker = null;
this.feaWorker = null;
this.isReady = false;

this._initWorker();
}

async _initWorker() {
try {
this.worker = new Worker(
new URL("./FEAWrapperScript.js", import.meta.url),
{
type: "module",
}
);

this.worker.onerror = (event) => {
console.error("FEAWorkerScript: Worker error:", event);
};
const FEAWorkerWrapper = Comlink.wrap(this.worker);

this.feaWorker = await new FEAWorkerWrapper();

this.isReady = true;
} catch (error) {
console.error("Failed to initialize worker", error);
throw error;
}
}

async _ensureReady() {
if (this.isReady) return Promise.resolve();

return new Promise((resolve, reject) => {
let attempts = 0;
const maxAttempts = 50; // 5 seconds max

const checkReady = () => {
attempts++;
if (this.isReady) {
resolve();
} else if (attempts >= maxAttempts) {
reject(new Error("Timeout waiting for worker to be ready"));
} else {
setTimeout(checkReady, 1000);
}
};
checkReady();
});
}

async setSolverConfig(solverConfig) {
await this._ensureReady();
basicLog(`FEAWorkerScript: Setting solver config to: ${solverConfig}`);
return this.feaWorker.setSolverConfig(solverConfig);
}

async setMeshConfig(meshConfig) {
await this._ensureReady();
basicLog(`FEAWorkerScript: Setting mesh config`);
return this.feaWorker.setMeshConfig(meshConfig);
}

async addBoundaryCondition(boundaryKey, condition) {
await this._ensureReady();
basicLog(
`FEAWorkerScript: Adding boundary condition for boundary: ${boundaryKey}`
);
return this.feaWorker.addBoundaryCondition(boundaryKey, condition);
}

async setSolverMethod(solverMethod) {
await this._ensureReady();
basicLog(`FEAWorkerScript: Setting solver method to: ${solverMethod}`);
return this.feaWorker.setSolverMethod(solverMethod);
}

async solve() {
await this._ensureReady();
basicLog("FEAWorkerScript: Requesting solution from worker...");

const startTime = performance.now();
const result = await this.feaWorker.solve();
const endTime = performance.now();

basicLog(
`FEAWorkerScript: Solution completed in ${(
(endTime - startTime) /
1000
).toFixed(2)}s`
);
return result;
}

async getModelInfo() {
await this._ensureReady();
return this.feaWorker.getModelInfo();
}

async ping() {
await this._ensureReady();
return this.feaWorker.ping();
}

terminate() {
if (this.worker) {
this.worker.terminate();
this.worker = null;
this.feaWorker = null;
this.isReady = false;
}
}
}
89 changes: 89 additions & 0 deletions src/FEAWrapperScript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import * as Comlink from "https://unpkg.com/comlink/dist/esm/comlink.mjs";
import { FEAScriptModel } from "./FEAScript.js";
import { create, all } from "https://cdn.jsdelivr.net/npm/mathjs@latest/+esm";

const math = create(all);

globalThis.math = math;

class FEAWorkerWrapper {
constructor() {
try {
this.model = new FEAScriptModel();
} catch (error) {
console.error("FEA Worker: Error initializing FEAScriptModel", error);
throw error;
}
}

setSolverConfig(solverConfig) {
try {
this.model.setSolverConfig(solverConfig);
return true;
} catch (error) {
console.error("FEA Worker: Error in setSolverConfig", error);
throw error;
}
}

setMeshConfig(meshConfig) {
try {
this.model.setMeshConfig(meshConfig);
return true;
} catch (error) {
console.error("FEA Worker: Error in setMeshConfig", error);
throw error;
}
}

addBoundaryCondition(boundaryKey, condition) {
try {
this.model.addBoundaryCondition(boundaryKey, condition);
return true;
} catch (error) {
console.error("FEA Worker: Error in addBoundaryCondition", error);
throw error;
}
}

setSolverMethod(solverMethod) {
try {
this.model.setSolverMethod(solverMethod);
return true;
} catch (error) {
console.error("FEA Worker: Error in setSolverMethod", error);
throw error;
}
}

solve() {
try {
const result = this.model.solve();

return {
solutionVector: result.solutionVector,
nodesCoordinates: result.nodesCoordinates,
solverConfig: this.model.solverConfig,
meshDimension: this.model.meshConfig.meshDimension,
};
} catch (error) {
console.error("FEA Worker: Error in solve", error);
throw error;
}
}
getModelInfo() {
try {
return {
solverConfig: this.model.solverConfig,
meshConfig: this.model.meshConfig,
boundaryConditions: this.model.boundaryConditions,
solverMethod: this.model.solverMethod,
};
} catch (error) {
console.error("FEA Worker: Error in getModelInfo", error);
throw error;
}
}
}

Comlink.expose(FEAWorkerWrapper);
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
export { FEAScriptModel } from "./FEAScript.js";
export { plotSolution } from "./visualization/plotSolutionScript.js";
export { printVersion, logSystem } from "./utilities/utilitiesScript.js";
export { FEAWorkerScript } from "./FEAWorkerScript.js";