Method of Manufactured Solutions (MMS) Simulator Back
Verification & Validation

Method of Manufactured Solutions (MMS) Simulator

Verify a CFD/FEM code's discretization with the Method of Manufactured Solutions. Pick a smooth analytical solution, back out the source term, refine the grid four times, and read off the L2 error and the observed convergence order. If the observed order matches the design order, the code verification passes.

Parameters
Domain length L
Length of the 1D computational domain x ∈ [0, L]
Coarse-grid cells N
Cell count of the coarsest grid; refined three more times
Refinement ratio r
Each grid divides h by r relative to the previous one
Expected order p_design
Formal scheme order (2 for central difference)
Diffusivity D
Coefficient in −D·u'' = f(x)
Manufactured solution u_mms(x)
This tool fixes u_mms(x) = sin(πx/L) and feeds the back-computed f(x) = D·(π/L)²·sin(πx/L) into the discretized equation.
Results
Coarse-grid error E₁
Fine-grid error E₄
Observed order p_obs (avg)
Design order p_design
MMS verification
Error ratio E₁/E₄
Grid refinement & numerical solution vs manufactured solution

Four grids (coarse → fine) solving u_mms(x) = sin(πx/L) are overlaid; the error bars on the highlighted grid shrink as h is refined.

Convergence plot — log E vs log h
Observed convergence orders p_obs between grids
Theory & Key Formulas

$$f_{mms}(x) = L[u_{mms}(x)],\quad E_k = \|u_h^{(k)} - u_{mms}\|_2,\quad p_{obs} = \frac{\log(E_1/E_2)}{\log r}$$

L is the discrete operator of the governing equation, u_mms is any smooth function, and p_obs ≈ p_design indicates a passing verification.

$$-D\,u''(x) = f(x),\qquad u_{mms}(x) = \sin\!\left(\tfrac{\pi x}{L}\right),\qquad f(x) = D\!\left(\tfrac{\pi}{L}\right)^{2}\sin\!\left(\tfrac{\pi x}{L}\right)$$

The 1D steady diffusion equation solved by the tool and the source term f(x) back-computed from the manufactured solution. Boundary conditions: u(0)=u(L)=0.

$$E_k \;\propto\; h_k^{\,p_{design}},\qquad \frac{E_k}{E_{k+1}} = r^{\,p_{obs}}$$

For 2nd-order central differences, E ∝ h² and the adjacent error ratio is r² = 4. The tool inverts this relation to obtain p_obs.

Method of Manufactured Solutions (MMS) for code verification

🙋
"Manufactured solution" is a strange phrase. We normally solve an equation to find a solution — why are we manufacturing one?
🎓
Good question — the logic is inverted. Normal verification compares against a known analytical solution of a benchmark, and only a small set of problems have one. MMS goes the other way: you simply pick a smooth function u_mms(x) of your own choosing — say, sin(πx/L) — and plug it into the governing equation −D·u''(x) = f(x). The left-hand side is something you can evaluate, so you can back out what f must be to make this u a solution. Here it gives f(x) = D·(π/L)²·sin(πx/L).
🙋
So you decide on the answer first and then build the problem around it. How does that catch bugs?
🎓
You feed f into the code and let it compute its numerical solution u_h. By construction, u_h should match u_mms; in practice it differs slightly because of the discretization's truncation error. Measure that error E = ‖u_h − u_mms‖₂ on a sequence of refined grids. A 2nd-order central scheme should give E ∝ h², so halving h should cut the error by a factor of four. That is why E₁/E₄ in the result panel above sits at 64 = 2⁶ — h has been halved three times, giving 2² · 2² · 2² = 64.
🙋
So if the observed order matches the design order, the code is correct?
🎓
It is a strong stamp of approval. Matching p_obs = log(E_k/E_{k+1})/log(r) with p_design simultaneously requires that the discretization, the boundary conditions and the sign of the source term are all correct. The classic field win for MMS is regression testing: refactor a solver and "it still runs and the benchmark is within tolerance" hides a silent order loss, whereas MMS shows p_obs dropping from 2 to 1 clearly. That sensitivity is why Roy and Oberkampf, and standards like ASME V&V 10/40, treat MMS as the gold standard for code verification.
🙋
And if p_obs is off, what should I suspect first?
🎓
Try setting p_design to 1 here and watch the slope on the convergence plot. There are four classic causes for a low observed order. First, a boundary-condition implementation bug — a single boundary point computed to first order drags the whole solution down to first order. Second, a sign error in the source term — the error becomes nearly grid-independent. Third, an under-converged iterative solver — when the linear residual is larger than the truncation error, p_obs collapses toward zero. Fourth, the grids are not in the asymptotic regime — the coarse-grid error saturates and you need to push N higher.

Frequently Asked Questions

Standard verification compares against an analytical solution of a benchmark problem, which limits what you can test. MMS does the opposite: you first "manufacture" an arbitrary smooth solution u_mms(x,t), substitute it into the governing equation, and back out the source term f. Feeding that f to the code gives you an exact-solution test case for any equation and any boundary condition. You can then compare the design order p with the observed order p_obs and prove that the implementation is correct. This is why MMS is considered the gold standard for V&V.
For grid k with representative size h_k, the L2 error is E_k = sqrt(Σ(u_h − u_mms)² · h). For two adjacent grids related by a refinement ratio r, the observed order is p_obs = log(E_k / E_{k+1}) / log(r). This tool refines four times with r = 2, produces three p_obs values and shows the average. If p_obs matches the design order p (e.g. 2.0 for a 2nd-order central difference) within ±0.15, the implementation does not contain bugs that drop the formal discretization order.
Four common causes: (1) a boundary-condition implementation error — order loss at the boundary dominates and drops p_obs to 1; (2) a sign error in the source term — error becomes constant with respect to h; (3) an under-converged iterative solver — residuals exceed the truncation error and p_obs falls toward zero; (4) the grids are not yet in the asymptotic regime — the coarse-grid error saturates. If p_obs is far from the design order in this tool, recheck the boundary conditions and the sign of f first.
No — MMS works for nonlinear, time-dependent, multi-dimensional and coupled problems, which is precisely its strength. Navier-Stokes, advection-diffusion, nonlinear structural mechanics, fluid-structure interaction, radiative heat transfer — pick u_mms, expand L[u_mms] symbolically (e.g. with SymPy), and you get f. The manufactured solution need not be physically meaningful; the trick is to choose a smooth function (combination of polynomials, trigonometric and exponential terms) that activates every term in the code. This tool uses 1D linear diffusion to illustrate the basic MMS workflow, but the same procedure scales to industrial CFD codes.

Real-World Applications

Verification of commercial CFD/FEM solvers: Vendors of major solvers — ANSYS Fluent, OpenFOAM, CFD++, Code_Saturne, ABAQUS, LS-DYNA — run MMS on every release. Whenever a new turbulence model, transport equation or boundary-condition type is added, an automated regression test generates the corresponding u_mms and f and checks the observed convergence order. Safety-critical codes such as NASA's CFL3D and FUN3D, or Sandia's SIERRA suite, depend on an MMS test suite as the backbone of their quality assurance.

Peer review of research codes: Journals such as JCP, CMAME and IJNMF increasingly expect papers proposing new numerical methods to include an MMS-based proof of the convergence order. If the manuscript claims "2nd-order accuracy," reviewers want to see a convergence plot whose observed order clusters around 2.00 ± 0.05. MMS is preferred over simple analytical comparisons because it detects bugs that ad-hoc verification misses.

Nuclear and aerospace safety cases: Domains whose simulation results feed directly into safety regulation — nuclear thermal-hydraulics, rocket combustion chambers, reentry aerothermodynamics — follow the three-step V&V workflow standardized by ASME V&V 10/20/40 and ANS-2.27: code verification, solution verification, then validation. MMS is the centerpiece of the code-verification step, and any implementation that has not earned an MMS PASS is treated as not credible for the validation step that follows.

Quality gate for in-house scripts: Many engineering departments now use MMS as a quality gate before deploying internal Python or MATLAB analysis scripts on real projects. The test runs on only a handful of grids, so it is cheap enough to drop into a CI/CD pipeline. The interactive UI of this tool is a minimal version of that test runner.

Common Misconceptions and Pitfalls

The biggest pitfall is to assume that an MMS PASS means the simulation results are physically trustworthy. MMS only proves "code verification" — that the program is correctly solving the mathematical model you wrote down. Agreement with the actual physical system (validation) is a separate question that requires experimental data. A RANS turbulence simulation may pass MMS yet still disagree wildly with real flow if the model itself is wrong. Always distinguish "the equations are solved correctly" from "the equations are correct," and never let a PASS lull you into skipping validation.

A second mistake is trying to choose a physically realistic manufactured solution. u_mms can be anything smooth and easy to differentiate; it does not have to make physical sense. In fact, simple polynomials or pure sines may fail to activate certain code paths (advection terms, nonlinear coefficients, special boundary branches), leaving bugs hidden. Practitioners deliberately pick artificial blends of polynomials, trig and exponential functions to ensure every term of the governing equation has a non-zero contribution. This tool uses sin(πx/L), the simplest manufactured solution that already satisfies the boundary conditions u(0)=u(L)=0.

The third pitfall is to compute the observed order before the grids are in the asymptotic regime. p_obs is only meaningful when the error is dominated by the leading truncation term. On too-coarse grids, higher-order terms and non-asymptotic effects pollute the measurement and the observed order drifts from the design order. A simple sanity check: if the three p_obs values across four grids are roughly constant, you are asymptotic; if they scatter, you are not. Drop N to 4 in this tool and you can see a small scatter appear. In real code testing, always require at least three comparisons (four grids) and check that p_obs itself is converging.

How to Use

  1. Define your grid sequence: set lNum (number of grids) and lRange (refinement ratio, typically 2–4) to establish coarse-to-fine mesh spacing.
  2. Configure numerical discretization: choose nNum (spatial dimensions: 1D, 2D, 3D) and nRange (polynomial order: linear to quintic) matching your FEM/CFD scheme.
  3. Set convergence parameters: specify rNum (residual iterations, 100–10000) and pRange (expected design order, e.g., p=2 for second-order centered differences).
  4. Run verification: simulator computes L₂ and L∞ norms on each grid, calculates observed order p_obs via log-log regression, and flags success when |p_obs – p_design| < 0.1.

Worked Example

For a 2D Navier–Stokes solver using second-order finite differences on a square domain [0,1]×[0,1]: lNum=4 grids with lRange=2.0 (mesh halving), nNum=2D, nRange=2 (quadratic elements), rNum=5000 iterations. Coarse grid (h=0.1) yields E₁=0.0487. After refinement to h=0.0125, fine grid yields E₄=0.00298. Observed order p_obs=(log(0.0487/0.00298))/(log(2))≈4.03, exceeding design order 2.0, indicating superconvergence at element nodes or verification success if p_obs≈2.0 within tolerance.

Practical Notes

  1. Use lRange=2 (dyadic refinement) for standard FEM/FDM codes; higher ratios (3–4) reduce computational cost but worsen convergence statistics for p_obs detection.
  2. Manufactured solutions must satisfy all boundary conditions identically; polynomial forcing functions (up to degree nRange+2) ensure smooth source terms without truncation artifacts.
  3. If p_obs < p_design, check solver residuals (target <1e-10), time-step courant numbers, and asymptotic-range mesh sizes; grid-spacing ratios below 1.5 or above 4.0 distort order measurement.
  4. For multi-physics (e.g., conjugate heat transfer), verify each field independently; coupled systems may mask convergence in secondary variables.