Tutorial: 2-D Steady Heat Conduction around a Cylinder (Dirichlet)
This tutorial walks through the Tests/2D_Heat_Conduction_Cylinder_Dirichlet
test case. It demonstrates how to use an embedded-boundary level-set body
with an isothermal (Dirichlet) thermal BC to compute steady-state heat
conduction in a 2-D domain containing a circular cylinder — the canonical
Laplace-equation problem with an analytic solution.
Required build flags: USE_EB=TRUE, USE_TEMP=TRUE, DIM=2.
Physical problem
A unit square domain \([0,1]^2\) contains a circular cylinder of radius \(r = 0.15\) centred at \((0.5,\,0.5)\). The four domain walls are held at \(T = 0\), and the cylinder surface is isothermal at \(T = 1\). There are no volumetric heat sources, and the initial elastic solid velocity is zero throughout.
The governing equation is the steady-state heat equation (Laplace equation):
with boundary conditions:
In the time-dependent MPM formulation, the simulation is advanced until the transient decays and the solution converges to the steady state. The thermal diffusivity is \(\alpha = k / (\rho\,c_p) = 1\), so the characteristic diffusion time across the domain is \(t_\alpha \sim 1\). The simulation is run to \(t = 0.1\), by which point the solution has relaxed to within plotting accuracy of the Laplace steady state.
Analytical solution
The steady-state temperature in polar coordinates centred on the cylinder axis is:
where \(r_0 = 0.15\) is the cylinder radius and \(R_\text{out}\) is an effective outer radius determined by the Dirichlet condition \(T = 0\) on the square boundary. For a circular outer boundary of radius \(R_\text{out}\), this reduces to:
Because the outer boundary is square rather than circular, the exact solution
is a 2-D series; however, at large separation the logarithmic profile provides
an excellent approximation. The post-processing script in
PostProcess/validate.py computes the numerical angular average at each
radial band and compares it against a reference profile obtained by
high-resolution numerical integration of the Laplace equation on the same
geometry.
Material properties
Property |
Value |
Notes |
|---|---|---|
Density \(\rho\) |
1.0 |
uniform |
Specific heat \(c_p\) |
1.0 |
uniform; gives \(\alpha = 1\) |
Thermal conductivity \(k\) |
1.0 |
uniform |
Volumetric heat source \(\dot{q}\) |
0.0 |
no internal source |
Initial temperature \(T_0\) |
0.0 |
uniform; below the cylinder BC |
Domain and discretisation
The computational domain is the unit square \([0,1]^2\) discretised
with a \(128 \times 128\) background grid (mpm.ncells = 128 128 0).
One material point per cell is placed throughout the domain excluding the
cylinder interior, giving approximately 15 000 active particles. The time
step is fixed at \(\Delta t = 10^{-5}\) and the simulation runs to
\(t_\text{final} = 0.1\).
The level-set grid is refined by a factor of 2 (cylinder.ls_refinement = 2),
giving an effective resolution of \(256 \times 256\) for the signed-distance
field, which accurately represents the circular geometry.
Boundary conditions
Domain walls — all four faces use Dirichlet temperature BCs at \(T = 0\) and slip momentum BCs (no momentum exchange with the walls):
mpm.bc_xlo_mom = slip
mpm.bc_xhi_mom = slip
mpm.bc_ylo_mom = slip
mpm.bc_yhi_mom = slip
mpm.bc_xlo_temp = dirichlet
mpm.bc_xlo_temp.T_wall = 0.0
mpm.bc_xhi_temp = dirichlet
mpm.bc_xhi_temp.T_wall = 0.0
mpm.bc_ylo_temp = dirichlet
mpm.bc_ylo_temp.T_wall = 0.0
mpm.bc_yhi_temp = dirichlet
mpm.bc_yhi_temp.T_wall = 0.0
Cylinder surface — isothermal at \(T = 1\) with a slip momentum BC (no drag on the particles from the cylinder):
eb2.body_names = cylinder
cylinder.geom_type = sphere
cylinder.sphere_radius = 0.15
cylinder.sphere_center = 0.5 0.5 0.0
cylinder.sphere_has_fluid_inside = false
cylinder.ls_refinement = 2
cylinder.levelset_mom = slipwall
cylinder.temp_bc_type = isothermal
cylinder.lset_T_wall = 1.0
For a full description of the level-set BC parameters see Embedded Boundaries via Level Sets (USE_EB).
Setting up the test case
The particle file and input file are generated from the JSON configuration
in PreProcess/config.json. The key fields are the grid resolution, the
particles-per-cell count, and the thermal properties:
{
"grid": { "nx": 128, "ny": 128 },
"ppc": [1, 1],
"bodies": [{
"temperature": {
"T": 0.0,
"spheat": 1.0,
"thermcond": 1.0,
"heatsrc": 0.0
}
}]
}
To (re)generate the particle and input files, run from the test directory:
cd Tests/2D_Heat_Conduction_Cylinder_Dirichlet/
bash Generate_MPs_Inputfile_Generic.sh
This writes mpm_particles.dat (particle positions and thermal properties)
and Inputs_2DHeat_Conduction_Cylinder_Dirichlet.inp one level up.
Building
Navigate to the test directory and build with the required flags:
cd Tests/2D_Heat_Conduction_Cylinder_Dirichlet
# create a temporary copy of the GNUmakefile here
make USE_EB=TRUE USE_TEMP=TRUE DIM=2 -j4
The resulting executable is named
ExaGOOP2d.<suffix>.ex (suffix depends on the build environment).
Note
USE_EB=TRUE pulls in the AMReX EB2 library. On some systems this
significantly increases compile time; using -j4 or higher
parallelises the build across compilation units.
Running
From the test directory:
./ExaGOOP2d.<suffix>.ex Inputs_2DHeat_Conduction_Cylinder_Dirichlet.inp
For a parallel run on four MPI ranks:
mpirun -n 4 ./ExaGOOP2d.<suffix>.ex \
Inputs_2DHeat_Conduction_Cylinder_Dirichlet.inp
ASCII particle snapshots are written at intervals of
mpm.write_output_time = 0.01 to the subdirectory
2D_Heat_Conduction_Cylinder_Dirichlet/<solution folder name set in input file>/matpnt*. A checkpoint is written
to 2D_Heat_Conduction_Cylinder_Dirichlet/solution folder name set in input file/chk* at the same frequency.
Post-processing and validation
The validation script reads the final particle snapshot, bins particles by radial distance from the cylinder axis, and compares the angularly-averaged temperature profile against the analytical steady-state:
cd Tests/2D_Heat_Conduction_Cylinder_Dirichlet/
python3 PostProcess/validate.py --time 0.1
A passing run prints the RMS error and PASS. The acceptance criterion
is RMS \(< 5 \times 10^{-2}\) (the finite-time run and square-vs-circle
outer boundary geometry contribute a background error of order
\(10^{-2}\)).
The companion script Plot_Temperature.py generates a colour map of the
particle temperature field together with a contour overlay:
python Plot_Temperature.py
Expected result
At \(t = 0.1\) the temperature field has relaxed to a radially symmetric profile that rises from \(T = 0\) at the domain walls to \(T = 1\) at the cylinder surface. The gradient is steepest in the gap between the cylinder and the nearest wall. Representative radially-averaged values are:
Radial distance from axis \(r\) |
\(T_\text{avg}(r)\) |
|---|---|
0.15 (cylinder surface) |
1.000 |
0.20 |
≈ 0.82 |
0.30 |
≈ 0.57 |
0.40 |
≈ 0.32 |
≥ 0.50 (approaching walls) |
→ 0.0 |
The temperature profile is symmetric about the cylinder axis to within numerical discretisation error.