Overview
multiPhysicsFoam is a library and solver for OpenFOAM (.com, v2512 and v2606) that simulates multi-region, coupled multiphysics problems. Instead of writing a new solver for every combination of physics, a problem is assembled from building blocks:
- Regions – separate meshes, each carrying one or more physics models
(region types), e.g. a fluid solved with
pimpleFluidplus heat transport withtransportTemperature, or a solid solved withconductTemperature. - Interfaces – pairs of patches through which two regions are coupled, each
with an interface type that defines the interface physics, e.g.
heatTransferInterfaceorfsiInterface. - Coupled boundary conditions – the patch fields on the interface patches that exchange values and fluxes between the regions.
All of this is configured in dictionaries at run time. The same executable,
multiPhysicsFoam, runs every case.
The multiPhysicsFoam executable
multiPhysicsFoam itself only contains the time loop. On start-up it creates a
multiRegionSystem, which reads the case configuration and builds all regions
and interfaces. Then, in every time step, it
- adjusts the time step to the smallest stable time step reported by all
regions (adaptive time stepping, limited by
maxDeltaT), - calls
preSolve()andsolve()of the multi-region system, - writes the results.
All physics lives in the libmultiRegionSystem library, so new region,
interface or boundary condition types extend the framework without touching
the solver.
What happens in one time step
multiRegionSystem::solve() advances the coupled problem in the following
order:
Region-local physics – every region solves the equations that are not coupled to other regions (e.g. a VOF phase-fraction equation or the abuse reactions of a battery model).
Pressure–velocity coupling – regions that use the PIMPLE algorithm (fluid regions) run their momentum predictor and pressure corrector, including mesh motion where needed.
Self-coupled fields – fields that each region solves on its own, without exchange with a neighbour.
Partitioned coupling – for every field that is coupled across an interface (e.g.
Tin conjugate heat transfer), the equations of all regions sharing that field are solved repeatedly in a Dirichlet–Neumann (DNA) loop. One side of each interface receives a value (Dirichlet) and the other a flux (Neumann) from its partner. The loop repeats until the jump and flux residuals at the interfaces fall below the specified tolerances ormaxCoupleIteris reached. Convergence can be accelerated with fixed relaxation, Aitken or IQN-ILS.Two coupled fields have their own loops:
pUPimplefor sharp-interface multiphase flows andDfor fluid–structure interaction. They also run the PIMPLE algorithm, mesh-motion correction and the interface update inside each coupling iteration.
Monolithic coupling (all regions in one matrix) is planned; currently, partitioned coupling is the supported mode.
Setting up a case
A multi-region case looks like a standard OpenFOAM case with one sub-directory per region:
case/
├── 0/<region>/ initial and boundary conditions per region
├── constant/
│ ├── multiRegionProperties regions, their types, DNA settings
│ ├── regionInterfaceProperties interfaces and coupled fields
│ └── <region>/ mesh and physical properties per region
└── system/
├── controlDict time control (shared by all regions)
└── <region>/ fvSchemes, fvSolution per region
multiRegionProperties – regions
The regions list names every region and the region types stacked on it. The
DNA dictionary configures the partitioned coupling loop per coupled field:
regions
(
(fluid (pimpleFluid transportTemperature) )
(solid (conductTemperature) )
);
DNA
{
T
{
maxCoupleIter 20;
residualControl
{
maxJumpRes 1e-07;
maxFluxRes 1e-07;
}
}
}
regionInterfaceProperties – interfaces
Each entry of partitionedCoupledPatches defines one interface: its interface
type, the two patches it connects, the fields coupled across it and the
interface-specific coefficients:
partitionedCoupledPatches
(
fluidsolid
{
interfaceType (heatTransferInterface);
coupledPatchPair
(
(fluid interface)
(solid top)
);
coupledFields
(
T
);
heatTransferInterfaceCoeffs
{
jumpCoefficient jumpCoefficient [ 0 0 0 0 0 0 0 ] 1;
}
}
);
Values are transferred between non-conformal interface patches by interpolation (e.g. AMI or direct mapping).
Coupled boundary conditions
On the interface patches, the coupled field uses a matching pair of
coupled boundary conditions: a value (jump) condition on one side and a
flux condition on the other. For the example above, 0/fluid/T and
0/solid/T contain:
// 0/fluid/T
interface
{
type regionCoupledTemperatureJump;
interfaceType (heatTransferInterface);
accType aitken;
relax 0.75;
value $internalField;
}
// 0/solid/T
top
{
type regionCoupledHeatFlux;
interfaceType (heatTransferInterface);
value $internalField;
}
Running the case
Each region is meshed separately, with its mesh dictionaries in
system/<region>/, and the solver is started as usual:
blockMesh -region fluid
blockMesh -region solid
multiPhysicsFoam # serial
decomposePar -region fluid # parallel: decompose every region
decomposePar -region solid
mpirun -np 4 multiPhysicsFoam -parallel
The multi-region tutorials contain an Allrun script that does all of this,
e.g. ./Allrun -p -S for partitioned coupling in serial (-P for parallel).
Single-region mode
A single region type can also be run on a plain OpenFOAM case, without
multiRegionProperties, regionInterfaceProperties or region
sub-directories. Two entries in system/controlDict are enough:
singleRegionMode yes;
regionType pimpleFluid;
The case then behaves like the corresponding stock OpenFOAM solver (here
pimpleFoam), run through the multiPhysicsFoam infrastructure. This is useful
to verify a region type against the stock solver, or as a first step before
setting up a coupled case. The tutorials/singleRegion/<regionType>/ cases
use this mode.
Where to go next
- Region Physics – available region types and their settings
- Interface Physics – available interface types
- Boundary Conditions – coupled and custom boundary conditions
- Utilities – pre- and post-processing tools
- Tutorials – complete example cases