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 1D and 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 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, computed for every element as
is the size of the element per node spacing: the element length in 1D and the square root of the element area in 2D, divided by two for quadratic elements. The term proportional to stabilizes coarse meshes and vanishes under mesh refinement.
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 a step does not converge, FEAScript stops at that step and logs an error: the returned solution is 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 { 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. A non-zero value sets a later start time for that boundary: with
["constantValue", 1] on the left end of a 1D domain, for example, the solution is .
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.