This page demonstrates solving the 2D lid-driven cavity problem using FEAScript in a web worker for improved browser responsiveness. For the mathematical formulation and theory, see the basic tutorial.
The code below shows how to use FEAScript with a web worker. The velocity field is decomposed and plotted as contour plots.
<body>
<!-- ...body region... -->
<script type="module">
// Import FEAScript library
import { FEAScriptWorker, plotSolution, printVersion } from "https://core.feascript.com/src/index.js";
window.addEventListener("DOMContentLoaded", async () => {
// Print FEAScript version in the console
printVersion();
// Create a new FEAScriptWorker instance
const model = new FEAScriptWorker();
// Ensure the worker is ready
await model.ping();
// Configure model
await model.setModelConfig("creepingFlowScript");
// Mesh parameters
const numElementsX = 12;
const numElementsY = 6;
await model.setMeshConfig({
meshDimension: "2D",
elementOrder: "quadratic",
numElementsX: numElementsX,
numElementsY: numElementsY,
maxX: 4,
maxY: 2,
});
// Apply boundary conditions
await model.addBoundaryCondition("0", ["constantVelocity", 0, 0]); // Bottom boundary
await model.addBoundaryCondition("1", ["constantVelocity", 0, 0]); // Left boundary
await model.addBoundaryCondition("2", ["constantVelocity", 1, 0]); // Top boundary
await model.addBoundaryCondition("3", ["constantVelocity", 0, 0]); // Right boundary
// Solve
await model.setSolverMethod("lusolve");
const result = await model.solve();
// Calculate total velocity nodes for quadratic elements
const nodesX = 2 * numElementsX + 1;
const nodesY = 2 * numElementsY + 1;
const totalNodesVelocity = nodesX * nodesY;
// Extract solution components
const solutionVector = result.solutionVector;
const uVelocity = solutionVector.slice(0, totalNodesVelocity);
const vVelocity = solutionVector.slice(totalNodesVelocity, 2 * totalNodesVelocity);
const velocityMagnitude = uVelocity.map((u, i) => Math.sqrt(u * u + vVelocity[i] * vVelocity[i]));
// Get model info for plotting
const modelInfo = await model.getModelInfo();
// Plot results
plotSolution(modelInfo, { solutionVector: velocityMagnitude, nodesCoordinates: result.nodesCoordinates },
"contour", "velocityMagnitudeCanvas");
plotSolution(modelInfo, { solutionVector: uVelocity, nodesCoordinates: result.nodesCoordinates },
"contour", "uVelocityCanvas");
plotSolution(modelInfo, { solutionVector: vVelocity, nodesCoordinates: result.nodesCoordinates },
"contour", "vVelocityCanvas");
// Terminate the worker
model.terminate();
});
</script>
<!-- ...rest of body region... -->
</body>
Below are the 2D contour plots of the computed velocity magnitude \(|\mathbf{u}| = \sqrt{u^2+v^2}\), horizontal velocity component \(u\), and vertical velocity component \(v\). These plots are generated in real time using FEAScript.