A multi-region conjugate-heat-transfer (CHT) solver with a two-phase VOF fluid region for OpenFOAM. It combines, in a single executable, what interFoam/compressibleInterFoam and chtMultiRegionFoam do separately:
- fluid region(s) — two compressible, non-isothermal, immiscible phases (e.g. water + air) captured with an algebraic-MULES volume-of-fluid interface, with surface tension, buoyancy and an energy equation;
- solid region(s) — heat conduction, optionally with volumetric heat sources (
fvOptions); - coupled at every fluid–solid and solid–solid interface by a conjugate (mixed temperature/heat-flux) boundary condition, so a free-surface flow and the heat conduction in the surrounding solids are solved together.
The bundled example is liquid-jet-impingement cooling of a pin-fin heat sink on a hot GPU chip: a water jet falls through air onto an aluminium pin-fin heat sink mounted on a heat-dissipating silicon die.
![]() |
![]() |
⚠️ Provenance & scope. This is not a newly derived solver. It is an extraction ofchtMultiRegionInterFoamfrom C. Schubert's GPL-3OpenFOAM--MHD--VoF-Solver-Collection(developed for OpenFOAM v1912), ported to v2412 with a minimal, documented 4-line API patch (mesh.data::add/remove(...)→mesh.data().setFinalIteration(...), seedocs/porting/). The core fluid/solid discretisation is faithful to upstream; this distribution additionally fixes the VOF interface-Courant time-step limiting and removes dead/duplicated code (see Changes in this distribution). As the upstream author notes, the solver has not been formally verified or validated against experiment — the example here is a demonstration with internal sanity/consistency checks (see V&V). Use accordingly.
Per time step the multi-region PIMPLE driver solves each region in turn and couples them through the interface temperature condition. With nOuterCorrectors 1 (the example default) each step is a single, fully-explicit (segregated) fluid-then-solid update. With nOuterCorrectors > 1, the first outer corrector is followed by an energy-coupling sub-loop (energyCoupling { iterations N; } in the PIMPLE dictionary) that re-solves the fluid temperature and solid conduction with the flow frozen, making the conjugate coupling implicit within the step.
Fluid region (compressibleInterFoam formulation, phase 1 = liquid):
| Equation | Field |
|---|---|
VOF phase fraction (MULES): d(alpha1)/dt + div(alpha1 U) + div(alpha1 alpha2 Ur) = 0 |
alpha.water |
Mixture momentum (PIMPLE) with gravity + surface tension sigma kappa grad(alpha1) |
U, p_rgh, p |
Energy (temperature form), mixture rho = alpha1 rho1 + alpha2 rho2 |
T |
Compressible turbulence (here laminar; RAS/LES selectable) |
— |
Solid region(s):
| Equation | Field |
|---|---|
Heat conduction d(rho h)/dt - laplacian(alpha_h, h) = q_source |
h (→ T) |
Interface coupling: compressible::turbulentTemperatureRadCoupledMixed enforces temperature and heat-flux continuity (T_s = T_f, k_s dT_s/dn = k_f dT_f/dn) on the auto-generated <region>_to_<neighbour> patches.
Relative to the upstream v1912 source (beyond the mechanical v2412 portability patch), this distribution applies the following corrections and clean-ups. The fluid/solid finite-volume discretisation is otherwise unchanged.
- Interface-Courant time-step limiting (bug fix). The adaptive time-step controller (
include/setMultiRegionDeltaT.H) previously limiteddeltaTonly by the bulk-flow Courant number and solid diffusion number; the VOF interface Courant number (maxAlphaCo) was computed and printed but never applied, somaxAlphaCoincontrolDicthad no effect. The controller now limits the fluid step bymin(maxCo/CoNum, maxAlphaCo/alphaCoNum), matchingcompressibleInterFoam. The initial step (setInitialMultiRegionDeltaT.H) is limited the same way. - Adaptive outer-corrector reduction (optional, off by default). The driver can drop a time step to a single outer corrector (no
energyCouplingsub-loop; that corrector is the final iteration, sop_rgh,Tandhall use their Final solver settings - this needed a one-line fix influid/pEqn.H, which now selectsp_rghFinalby the driver'sfinalIterinstead of the configured outer-corrector count) once the relative per-step change of the flow and of the solid thermal field has stayed belowadaptiveOuterTolforadaptiveOuterStepsconsecutive steps (PIMPLE keys in the top-levelsystem/fvSolution; defaults0and5). WithadaptiveOuterTol 0the solver is bit-identical to the plain fixed-corrector driver. It is intended for quasi-steady / long thermal-design runs; the consecutive-steps hysteresis keeps it from firing on an isolated low-change step during a transient. - Dead code removed. Unused single-region leftovers (
VoF/setDeltaT.H,VoF/setRDeltaT.H,VoF/alphaCourantNo.H,VoF/alphaEqnSubCycle.H,VoF/createAlphaFluxes.H,fluid/alphaEqn_bu.H,fluid/setMultiRegionRDeltaT.H), the unusedinitialMassbookkeeping and the deadnEnergyCorrectorscontrol were removed. The dead outer-correctorp_rgh.storePrevIter()loop (and itsfluid/storeOldFluidFields.Hheader) was removed as well (p_rghis never under-relaxed across outer correctors, so results are unchanged). - Source hygiene. The application identity/description was corrected (it self-identified as
chtMultiRegionTwoPhaseEulerFoam), and all non-ASCII / work-in-progress comments were converted to ASCII English.
Pressure reference. Like its parent
compressibleInterFoam, the fluid solver sets the pressure level from the compressible thermodynamics and the boundary conditions; it does not carry a closed-domainpRefCell/pRefValuereference. Each fluid region therefore needs a pressure-referencing boundary (e.g. thetotalPressureoutlet in the example) or compressible pinning.
chtMultiRegionInterFoam/
├── Allwmake / Allwclean build scripts (wmake src/chtMultiRegionInterFoam)
├── src/
│ └── chtMultiRegionInterFoam/ solver source (built by Allwmake)
│ ├── chtMultiRegionInterFoam.C application + shared multi-region setup headers
│ ├── createFields.H createMeshes.H …
│ ├── Make/ files / options
│ ├── fluid/ fluid-region (compressibleInterFoam VOF) headers
│ ├── solid/ solid-region conduction headers
│ ├── include/ multi-region time-control headers
│ └── VoF/ header-only algebraic-MULES VoF (alpha equation)
├── examples/
│ └── pinFinJetCooling/ pin-fin heat sink, liquid jet impingement cooling
└── docs/
├── verification_validation.md sanity / consistency report
├── porting/ upstream provenance + v2412 portability patch
└── figures/ result figures
Note on the layout.
chtMultiRegionInterFoamis built on a shared multi-region framework plus a bundled header-only VoF library. These are collected under a single solver directorysrc/chtMultiRegionInterFoam/, mirroring the layout of the sibling solvers (dacFoam,adsorptionFoam,electrostaticSimpleFoam); the multi-region sources are split intofluid/,solid/andinclude/subdirectories following the OpenFOAMchtMultiRegionFoamidiom.Allwmakebuilds this one application; the bundledVoF/,fluid/,solid/andinclude/headers are pulled in via the relative include paths inMake/options.
- OpenFOAM v2412 (ESI/OpenCFD). The solver targets the bundled
compressibleInterFoamlibraries (twoPhaseMixtureThermo,VoFphaseCompressibleTurbulenceModels,surfaceTensionModels), which ship with v2412. - For the result figures: ParaView (
pvbatch); optionalgnuplotfor the temperature plot.
source /usr/lib/openfoam/openfoam2412/etc/bashrc # adjust to your installation
git clone https://github.com/swtbkim/chtMultiRegionInterFoam.git
cd chtMultiRegionInterFoam
./Allwmake./Allwmake builds chtMultiRegionInterFoam into $FOAM_USER_APPBIN. Verify:
chtMultiRegionInterFoam -helpcd examples/pinFinJetCooling
./Allrun # blockMesh -> topoSet -> createPatch -> splitMeshRegions -> decomposePar -> (parallel) solve -> reconstructThe example is a 3-region case (fluid, heatSink, chip) and runs in parallel (4 ranks by default; see system/decomposeParDict). For a quick single-core run, coarsen the mesh in system/blockMeshDict (e.g. (32 24 32)) and replace the parallel block of Allrun with a plain runApplication $(getApplication). Clean with ./Allclean. See examples/pinFinJetCooling/README.md.
This is a demonstration solver; the checks below are internal sanity/consistency tests, not experimental validation (full report: docs/verification_validation.md):
- Builds on OpenFOAM v2412 with only the documented 4-line portability patch; links against the stock
compressibleInterFoamlibraries. - Bounded VOF: across the full 0.5 s run the phase fraction stays bounded (
min(alpha.water) ≈ -1e-17,max = 1); the interface Courant number is now actively limited bymaxAlphaCothrough the adaptive time step. - Conjugate heat transfer is consistent: with a 150 W chip source, the chip heats from 300 K toward a quasi-steady level while the jet holds the pin tips near the 300 K coolant temperature, giving a physical chip → base → pin-tip gradient.
- Energy bookkeeping: the chip-temperature rise rate is consistent with the lumped
Q / (rho Cp V)estimate minus the (growing) jet heat removal. - Mesh refinement: a 3×-refined mesh (664 k cells) reproduces the coarse-mesh temperature trend and sharpens the resolved jet/interface.
- Verification & validation report
- Step-by-step tutorial (Korean, 예제 19 of
openfoam-tutorial-ko) — physics, file-by-file case setup, meshing, running (serial & parallel) and post-processing, with the jet-interface and temperature-history results.
chtMultiRegionInterFoam is derived from C. Schubert, OpenFOAM--MHD--VoF-Solver-Collection (GPL-3), which itself combines the OpenFOAM standard solvers compressibleInterFoam and chtMultiRegionFoam (Copyright OpenFOAM Foundation / OpenCFD Ltd) with ideas from the DLR VoFLibrary, varRhoTurbVOF (Fan & Anglart) and isoAdvector (Roenby et al.). Please credit those works. The original upstream README is preserved in docs/porting/UPSTREAM_README.md.
This offering is not approved or endorsed by OpenCFD Limited, producer and distributor of the OpenFOAM software via openfoam.com, and owner of the OPENFOAM and OpenCFD trade marks.
Distributed under the GNU General Public License v3, as required for OpenFOAM derivatives.

