Front propagation
frontPropagationScript computes how a front (for example a solidification interface) advances from a part of
the boundary into the domain, by solving the eikonal equation in 2D. The solution is the arrival time
of the front at every point, which for a unit speed equals the distance from the initial front.
The front propagation model of version 0.2.0 supports 2D meshes only. 1D front propagation was added in version 0.3.0.
The eikonal equation post on the FEAScript blog gives the background of the method.
Governing equation
The eikonal equation with unit speed is
It is a nonlinear, first-order equation whose solutions can have kinks (points where is discontinuous). FEAScript uses the vanishing viscosity method: it adds a diffusion term that keeps the solution smooth, and solves
where is the activation parameter of the eikonal term and the viscous term,
Weak form
After integration by parts of the viscous term, the Galerkin residuals are
where the boundary term vanishes on zero-gradient boundaries. The Jacobian matrix uses the derivative , regularized so that it stays finite where .
Solution procedure
The eikonal term is activated gradually, in six steps:
- At , the eikonal term is off and the equation is a linear diffusion problem.
- Each step is solved with the Newton–Raphson method, starting from the solution of the previous step (the first step starts from ).
- At , the remaining viscous term is .
If the Newton–Raphson iterations of a step diverge, FEAScript logs an error and continues with the next step; the
returned solution is then not valid, and a finer mesh may be required. The maxIterations and tolerance options
(see Solvers) apply to the Newton–Raphson iterations of each
step.
Usage
The solidification front in a domain, starting from the bottom, left and right sides:
import * as math from "mathjs";
global.math = math;
import { FEAScriptModel } from "feascript";
// 1. Create the model and select the physics
const model = new FEAScriptModel();
model.setModelConfig("frontPropagationScript");
// 2. Define the mesh
model.setMeshConfig({
meshDimension: "2D",
elementOrder: "quadratic",
numElementsX: 12,
numElementsY: 8,
maxX: 4,
maxY: 2,
});
// 3. Apply the boundary conditions
model.addBoundaryCondition("0", ["constantValue", 0]); // Bottom: initial front
model.addBoundaryCondition("1", ["constantValue", 0]); // Left: initial front
model.addBoundaryCondition("2", ["zeroGradient"]); // Top
model.addBoundaryCondition("3", ["constantValue", 0]); // Right: initial front
// 4. Solve
model.setSolverMethod("lusolve");
const { solutionVector, nodesCoordinates } = model.solve();
The model takes no coefficient functions: the speed of the front is one everywhere.
Boundary conditions
| Condition | Parameters | Kind | Meaning |
|---|---|---|---|
["constantValue", value] | Arrival time | Dirichlet | The front is on this boundary at time |
["zeroGradient"] | – | Neumann (natural) |
Use ["constantValue", 0] for the initial front.
Solvers
"lusolve" (default), "jacobi" and "frontal" are supported; the selected method solves the linear system of
each Newton–Raphson iteration.
Results
solutionVector holds the nodal values of , the arrival time of the front (equal to the distance from the
initial front for a unit speed). The position of the front at time is the contour line , so a contour
plot of the solution shows successive positions of the front.
Examples
- Node.js script in
examples/frontPropagationScriptof FEAScript-core 0.2.0