Euler-Euler multiphase solvers (twoPhaseEulerFoam, multiphaseEulerFoam) fail in a way that surprises people coming from single-phase cases: the run starts, meshes fine, then stops the moment it builds the momentum equations with a FATAL IO ERROR about a div term that is "not found" in divSchemes. The cause is not a typo in your scheme — it is that these solvers name every field per phase, and your fvSchemes has to match those phase-suffixed names. This guide shows the exact error, why it happens, and the complete divSchemes that fixes it.
Running twoPhaseEulerFoam on OpenFOAM (here v2512, but the message is the same across recent releases) with a missing convection scheme produces:
PIMPLE: iteration 1
MULES: Solving for alpha.air
alpha.air volume fraction = 0.293333 Min(alpha.air) = 0 Max(alpha.air) = 1
Constructing momentum equations
--> FOAM FATAL IO ERROR: (openfoam-2512)
Entry 'div(alphaRhoPhi.air,U.air)' not found in dictionary "system/fvSchemes/divSchemes"
file: system/fvSchemes/divSchemes at line 29 to 43.
From const Foam::entry& Foam::dictionary::lookupEntry(const Foam::word&, Foam::keyType::option) const
in file db/dictionary/dictionary.C at line 363.
FOAM exiting
Two details matter. First, the field is div(alphaRhoPhi.air,U.air) — with a phase suffix, not the plain div(rhoPhi,U) you would write for a single-phase compressible solver. Second, the failure happens at "Constructing momentum equations", after the mesh and the phase fraction step succeed — which is why it looks like the case is fine right up to the crash.
The Euler-Euler (two-fluid) model solves a separate set of equations for each phase. OpenFOAM therefore creates one velocity, temperature, and flux field per phase, named with the phase name from constant/phaseProperties as a suffix:
// single-phase (e.g. rhoPimpleFoam) // Euler multiphase (twoPhaseEulerFoam)
U U.air U.water
alphaRhoPhi (does not exist) alphaRhoPhi.air alphaRhoPhi.water
T T.air T.water
The suffix is part of the field name that the solver looks up in fvSchemes. A scheme written for plain U or plain alphaRhoPhi will not match U.air, so with default none; the term is genuinely missing. This is the root cause behind almost every "div ... not found" error in twoPhaseEulerFoam: a divSchemes block copied from a single-phase case, or one that lists div(alphaRhoPhi.air,U.air) by hand but forgets div(alphaRhoPhi.water,U.water) for the second phase.
Instead of listing a scheme for each phase by hand, the Euler multiphase tutorials use regular expressions (in quotes) that match all phases at once. The .* matches any phase name, and the backslashes escape the literal parentheses. This is a complete, working divSchemes for twoPhaseEulerFoam, taken from the OpenFOAM tutorial and verified to run:
// system/fvSchemes
divSchemes
{
default none;
// phase-fraction transport
div(phi,alpha.air) Gauss vanLeer;
div(phir,alpha.air) Gauss vanLeer;
// momentum convection — matches U.air, U.water, ...
"div\(alphaRhoPhi.*,U.*\)" Gauss limitedLinearV 1;
"div\(phi.*,U.*\)" Gauss limitedLinearV 1;
// energy and kinetic energy
"div\(alphaRhoPhi.*,(h|e).*\)" Gauss limitedLinear 1;
"div\(alphaRhoPhi.*,K.*\)" Gauss limitedLinear 1;
// pressure work
"div\(alphaPhi.*,p\)" Gauss limitedLinear 1;
// turbulence transport
"div\(alphaRhoPhi.*,(k|epsilon).*\)" Gauss limitedLinear 1;
"div\(phim,(k|epsilon)m\)" Gauss limitedLinear 1;
// viscous stress (dev2) term
"div\(\(\(\(alpha.*\*thermo:rho.*\)\*nuEff.*\)\*dev2\(T\(grad\(U.*\)\)\)\)\)" Gauss linear;
}
The single most common missing line is the momentum one: "div\(alphaRhoPhi.*,U.*\)". If your error names div(alphaRhoPhi.air,U.air), that regex is what you are missing.
With default none;, the solver constructs its equations in order and stops at the first term it cannot match. Work through them in the same order the solver does:
div(phi,alpha.<phase>) and div(phir,alpha.<phase>). Missing this stops the run at "MULES: Solving for alpha"."div\(alphaRhoPhi.*,U.*\)" and "div\(phi.*,U.*\)". Missing this stops at "Constructing momentum equations" (the error above)."div\(alphaRhoPhi.*,(h|e).*\)" and "div\(alphaRhoPhi.*,K.*\)". Names depend on whether your thermo uses enthalpy (h) or internal energy (e); the (h|e) alternation covers both."div\(alphaPhi.*,p\)"."div\(alphaRhoPhi.*,(k|epsilon).*\)" for per-phase models, and "div\(phim,(k|epsilon)m\)" for a mixture turbulence model. Which one you need depends on the simulationType in constant/phaseProperties.dev2 regex. Copy it verbatim from a tutorial; it is not worth retyping.The same phase-suffix mismatch shows up in other dictionaries with a nearly identical message:
Entry 'U.air' not found in dictionary "solvers". The linear solver block also needs phase-suffixed or regex keys, e.g. "U.*" { solver smoothSolver; ... }.default, but if you set default none; there too, you must cover the diffusion terms per phase.default Gauss linear; is enough, so gradient terms rarely trigger this.If you set a catch-all like default Gauss upwind; the run will start, but you have then silently applied first-order upwind to every term, which smears the interface and the momentum field. Prefer default none; and fix the specific missing entry — the error is telling you exactly which one.
Across recent OpenFOAM releases the Euler-Euler solvers have been reorganised — multiphaseEulerFoam in the ESI line, and the modular foamRun with the multiphaseEuler solver module in the Foundation (.org) line. The solver name and some field names differ, but the mechanism in this guide is unchanged: phase-suffixed fields, default none;, and regex div schemes. The safest fix is always to copy divSchemes from a tutorial that ships with your exact OpenFOAM version rather than from a single-phase case or a different release.
# find a matching tutorial that ships with your installation
ls $FOAM_TUTORIALS/multiphase/twoPhaseEulerFoam/RAS/
# then diff its fvSchemes against yours to spot the missing entry
foamDictionary -diff $FOAM_TUTORIALS/multiphase/twoPhaseEulerFoam/RAS/bubbleColumn/system/fvSchemes \
system/fvSchemes
Point CFDpilot at your twoPhaseEulerFoam case in your terminal. It reads your real fvSchemes, phaseProperties, and log, tells you exactly which div term is missing, and proposes the fix as a diff you approve. No upload.
twoPhaseEulerFoam sets default none;, so every divergence term must be declared. The momentum convection term is named per phase — div(alphaRhoPhi.air,U.air), div(alphaRhoPhi.water,U.water). If your divSchemes was copied from a single-phase case or lists the term without matching the phase suffix, it is missing and the run stops at the momentum equations. Add the regex "div\(alphaRhoPhi.*,U.*\)" to cover every phase.
They are regular expressions. Euler-Euler solvers create per-phase fields (U.air, U.water, alphaRhoPhi.air, ...), and a quoted regex like "div\(alphaRhoPhi.*,U.*\)" matches the momentum term of all phases at once. The backslashes escape the literal parentheses; .* matches any phase name. This avoids listing a separate line per phase.
Phase fraction (div(phi,alpha.air), div(phir,alpha.air)), momentum ("div\(alphaRhoPhi.*,U.*\)", "div\(phi.*,U.*\)"), energy ("div\(alphaRhoPhi.*,(h|e).*\)", "div\(alphaRhoPhi.*,K.*\)"), pressure work ("div\(alphaPhi.*,p\)"), and turbulence ("div\(alphaRhoPhi.*,(k|epsilon).*\)"). A missing entry stops the run at the equation that uses it.
You can (default Gauss upwind;) and the case will start, but you have then applied that scheme to every unspecified term — usually first-order upwind, which smears the interface and the momentum field. Keep default none; and add the specific missing entry. The error names exactly which term you forgot.
Yes. Phase-suffixed fields, default none;, and regex div schemes apply to multiphaseEulerFoam and to the modular foamRun/multiphaseEuler module as well. Copy divSchemes from a tutorial in your own OpenFOAM version, since field and solver names shifted between releases.
The two-fluid model gives each phase its own velocity, temperature and turbulence fields, so OpenFOAM suffixes them with the phase name from phaseProperties. The suffix is part of the field name used in fvSchemes and fvSolution, which is why a scheme or solver written for plain U does not match.