Conjugate heat transfer over a flat plate
Problem Description
This validation case demonstrates conjugate heat transfer (CHT) between a laminar fluid flow and a conducting solid wall in a 2D configuration Luikov (1974). The case is modeled after the benchmark problem presented in Verstraete and Scholl (2016), which investigates the stability and accuracy of static coupling approaches for CHT problems.
The problem involves forced convection of air over a solid aluminum wall with a finite thickness, where heat conduction within the solid is coupled with convective transport in the fluid. Temperature and heat flux continuity are enforced at the fluid–solid interfaces.
The geometry of the problem is depicted in Figure 5.

Figure 5: The geometry of the problem (dimensions in m).
We note that an entrance region has been added to the domain to allow the boundary layer to buildup before the flow reaches the solid domain. The boundary conditions for the momentum and pressure equations are the following:
Table 1: Momentum and pressure boundary conditions.
| Boundary | Boundary condition |
|---|---|
| Fluid inlet | Fixed velocity, |
| Fluid top | Free stream |
| Fluid outlet | Outlet pressure, |
| Fluid bottom and solid top | No-slip |
The boundary conditions for the fluid and solid energy equations are the following:
Table 2: Solid and fluid energy boundary conditions.
| Boundary | Boundary condition |
|---|---|
| Fluid inlet | Fixed temperature, |
| Fluid top | Insulated |
| Fluid outlet | Outlet enthalpy |
| Fluid bottom before solid | Insulated |
| Solid top | Conjugate heat transfer |
| Solid bottom | Fixed temperature |
| Solid sides | Insulated |
Material properties used are given in Table 3.
Table 3: Material properties used in the CHT benchmark case.
| Region | Density, | Specific Heat, | Conductivity, | Dynamic Viscosity, |
|---|---|---|---|---|
| Fluid (air) | 0.3525 | 1142.6 | 0.06808 | 3.95 |
| Solid (fictional) | Not used | Not used | 0.2876 | Not used |
OpenPronghorn Model
The mesh is generated using the MOOSE mesh generator system and includes both solid and fluid regions. A representative section of the mesh is shown in Figure 1 below. The cell density near the fluid–solid interface is refined to capture strong thermal gradients. The refinement is achieved by the introduction of mesh bias parameters.

Figure 1: Mesh showing the fluid and solid regions in the 2D CHT channel.
Altogether, the mesh has 125 divisions horizontally in the entrance region and 250 in the fluid region above the plate. The solid plate has 80 vertical divisions while the fluid domain 160 vertical divisions. Altogether, the mesh consists of 80,000 quad cells. A mesh sensitivity has been carried out and the included model provides closely converged results with the least amount of cells.
The simulation employs a SIMPLE solver to obtain the steady state solution. Second order geometric average interpolation has been used for the advection discretization, while the stress and conduction operators have been discretized using an arithmetic average discretization. The mesh is orthogonal, so no correction terms were used. The input file for this case is embedded below.
##########################################################
# Conjugate heat transfer over a flat plate test case
# Author: Anshuman Chaube & Peter German
# Last Update: Please Check the commit history
# Flow model: Newtonian fluid, laminar flow
# SIMPLE solve
# benchmark sources:
# https://doi.org/10.1016/j.compfluid.2018.06.016
# https://doi.org/10.1016/0017-9310(74)90087-8
##########################################################
b = 0.01 # plate thickness
l = 0.2 # plate length
nxi = 125 # nx in the inlet/entrance region
nyf = 160 # ny in fluid
nxf = 250 # nx in the main fluid region
nys = 80 # ny in the solid domain
fx1_bias = 1.025 # bdry layer bias - fluid
fx2_bias = '${fparse 1.0/1.025}' # bdry layer bias - solid
fy_bias = 1.04 # bdry layer bias - fluid
sy_bias = '${fparse 1.0/1.05}' # bdry layer bias - solid
k_s = 0.2876
rho = 0.3525
mu = 3.95e-5
k = 0.06808
cp = 1142.6
vin = 12.0
Tin = 1000.0
T_s_bottom = 600.0
P_out = 1.03e5
h_s = 1
h_f = 1
advected_interp_method = 'average'
[Mesh<<<{"href": "../../../../syntax/Mesh/index.html"}>>>]
[fluid_channel]
type = GeneratedMeshGenerator<<<{"description": "Create a line, square, or cube mesh with uniformly spaced or biased elements.", "href": "../../../../source/meshgenerators/GeneratedMeshGenerator.html"}>>>
dim<<<{"description": "The dimension of the mesh to be generated"}>>> = 2
nx<<<{"description": "Number of elements in the X direction"}>>> = ${nxf}
ny<<<{"description": "Number of elements in the Y direction"}>>> = ${nyf}
xmin<<<{"description": "Lower X Coordinate of the generated mesh"}>>> = 0
xmax<<<{"description": "Upper X Coordinate of the generated mesh"}>>> = ${l}
ymin<<<{"description": "Lower Y Coordinate of the generated mesh"}>>> = 0
ymax<<<{"description": "Upper Y Coordinate of the generated mesh"}>>> = '${fparse 10.0*b}'
subdomain_ids<<<{"description": "Subdomain IDs for each element, default to all zero. If a single number is specified, that subdomain id is used for all elements."}>>> = '1'
subdomain_name<<<{"description": "If specified, single subdomain name for all elements"}>>> = 'fluid'
bias_x<<<{"description": "The amount by which to grow (or shrink) the cells in the x-direction."}>>> = '${fx1_bias}'
bias_y<<<{"description": "The amount by which to grow (or shrink) the cells in the y-direction."}>>> = '${fparse fy_bias}'
boundary_name_prefix<<<{"description": "If provided, prefix the built in boundary names with this string"}>>> = 'fluid'
[]
[solid_base]
type = GeneratedMeshGenerator<<<{"description": "Create a line, square, or cube mesh with uniformly spaced or biased elements.", "href": "../../../../source/meshgenerators/GeneratedMeshGenerator.html"}>>>
dim<<<{"description": "The dimension of the mesh to be generated"}>>> = 2
nx<<<{"description": "Number of elements in the X direction"}>>> = ${nxf}
ny<<<{"description": "Number of elements in the Y direction"}>>> = ${nys}
xmin<<<{"description": "Lower X Coordinate of the generated mesh"}>>> = 0
xmax<<<{"description": "Upper X Coordinate of the generated mesh"}>>> = ${l}
ymin<<<{"description": "Lower Y Coordinate of the generated mesh"}>>> = '${fparse -b}'
ymax<<<{"description": "Upper Y Coordinate of the generated mesh"}>>> = 0
subdomain_ids<<<{"description": "Subdomain IDs for each element, default to all zero. If a single number is specified, that subdomain id is used for all elements."}>>> = '2'
subdomain_name<<<{"description": "If specified, single subdomain name for all elements"}>>> = 'solid'
bias_x<<<{"description": "The amount by which to grow (or shrink) the cells in the x-direction."}>>> = ${fx1_bias}
bias_y<<<{"description": "The amount by which to grow (or shrink) the cells in the y-direction."}>>> = '${fparse sy_bias}'
boundary_id_offset<<<{"description": "This offset is added to the generated boundary IDs"}>>> = 10
boundary_name_prefix<<<{"description": "If provided, prefix the built in boundary names with this string"}>>> = 'solid'
[]
[entrance]
type = GeneratedMeshGenerator<<<{"description": "Create a line, square, or cube mesh with uniformly spaced or biased elements.", "href": "../../../../source/meshgenerators/GeneratedMeshGenerator.html"}>>>
dim<<<{"description": "The dimension of the mesh to be generated"}>>> = 2
nx<<<{"description": "Number of elements in the X direction"}>>> = '${fparse nxi}'
ny<<<{"description": "Number of elements in the Y direction"}>>> = ${nyf}
xmin<<<{"description": "Lower X Coordinate of the generated mesh"}>>> = '${fparse -l/2}'
xmax<<<{"description": "Upper X Coordinate of the generated mesh"}>>> = 0
ymin<<<{"description": "Lower Y Coordinate of the generated mesh"}>>> = 0
ymax<<<{"description": "Upper Y Coordinate of the generated mesh"}>>> = '${fparse 10.0*b}'
subdomain_ids<<<{"description": "Subdomain IDs for each element, default to all zero. If a single number is specified, that subdomain id is used for all elements."}>>> = '0'
subdomain_name<<<{"description": "If specified, single subdomain name for all elements"}>>> = 'entrance'
bias_x<<<{"description": "The amount by which to grow (or shrink) the cells in the x-direction."}>>> = ${fx2_bias}
bias_y<<<{"description": "The amount by which to grow (or shrink) the cells in the y-direction."}>>> = '${fparse fy_bias}'
boundary_id_offset<<<{"description": "This offset is added to the generated boundary IDs"}>>> = 20
boundary_name_prefix<<<{"description": "If provided, prefix the built in boundary names with this string"}>>> = 'ent'
[]
[smg]
type = StitchedMeshGenerator<<<{"description": "Allows multiple mesh files to be stitched together to form a single mesh.", "href": "../../../../source/meshgenerators/StitchMeshGenerator.html"}>>>
inputs<<<{"description": "The input MeshGenerators."}>>> = 'entrance fluid_channel solid_base'
stitch_boundaries_pairs<<<{"description": "Pairs of boundaries to be stitched together between the 1st mesh in inputs and each consecutive mesh"}>>> = 'ent_right fluid_left;
fluid_bottom solid_top'
prevent_boundary_ids_overlap<<<{"description": "Whether to re-number boundaries in stitched meshes to prevent merging of unrelated boundaries"}>>> = false
[]
[interface]
type = SideSetsBetweenSubdomainsGenerator<<<{"description": "MeshGenerator that creates a sideset composed of the nodes located between two or more subdomains.", "href": "../../../../source/meshgenerators/SideSetsBetweenSubdomainsGenerator.html"}>>>
input<<<{"description": "The mesh we want to modify"}>>> = 'smg'
primary_block<<<{"description": "The primary set of blocks for which to draw a sideset between"}>>> = 'fluid'
paired_block<<<{"description": "The paired set of blocks for which to draw a sideset between"}>>> = 'solid'
new_boundary<<<{"description": "The list of boundary names to create on the supplied subdomain"}>>> = interface
[]
[symmetry_transform]
type = SymmetryTransformGenerator<<<{"description": "Applies a symmetry transformation to the entire mesh.", "href": "../../../../source/meshgenerators/SymmetryTransformGenerator.html"}>>>
input<<<{"description": "The mesh we want to modify"}>>> = interface
mirror_point<<<{"description": "Any point on the plane/line over which the reflection operation will be done"}>>> = '0 0 0'
mirror_normal_vector<<<{"description": "A vector normal to (perpendicular/orthogonal to) the plane/line over which the reflection operation will be done"}>>> = '0 1 0'
[]
inactive<<<{"description": "If specified blocks matching these identifiers will be skipped."}>>> = 'symmetry_transform'
[]
[Problem<<<{"href": "../../../../syntax/Problem/index.html"}>>>]
linear_sys_names = 'u_system v_system pressure_system energy_system solid_energy_system'
previous_nl_solution_required = true
[]
[UserObjects<<<{"href": "../../../../syntax/UserObjects/index.html"}>>>]
[rc]
type = RhieChowMassFlux<<<{"description": "Computes H/A and 1/A together with face mass fluxes for segregated momentum-pressure equations using linear systems.", "href": "../../../../source/userobjects/RhieChowMassFlux.html"}>>>
u<<<{"description": "The x-component of velocity"}>>> = vel_x
v<<<{"description": "The y-component of velocity"}>>> = vel_y
pressure<<<{"description": "The pressure variable."}>>> = pressure
rho<<<{"description": "Density functor. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = ${rho}
p_diffusion_kernel<<<{"description": "The diffusion kernel acting on the pressure."}>>> = p_diffusion
block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = '0 1'
pressure_projection_method<<<{"description": "The method to use in the pressure projection for Ainv - standard (SIMPLE) or consistent (SIMPLEC)"}>>> = consistent
[]
[]
[Variables<<<{"href": "../../../../syntax/Variables/index.html"}>>>]
[vel_x]
type = MooseLinearVariableFVReal<<<{"description": "Base class for Moose variables. This should never be the terminal object type", "href": "../../../../source/variables/MooseLinearVariableFV.html"}>>>
initial_condition<<<{"description": "Specifies a constant initial condition for this variable"}>>> = ${vin}
solver_sys<<<{"description": "If this variable is a solver variable, this is the solver system to which it should be added."}>>> = u_system
block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = '0 1'
[]
[vel_y]
type = MooseLinearVariableFVReal<<<{"description": "Base class for Moose variables. This should never be the terminal object type", "href": "../../../../source/variables/MooseLinearVariableFV.html"}>>>
solver_sys<<<{"description": "If this variable is a solver variable, this is the solver system to which it should be added."}>>> = v_system
initial_condition<<<{"description": "Specifies a constant initial condition for this variable"}>>> = 0.0
block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = '0 1'
[]
[pressure]
type = MooseLinearVariableFVReal<<<{"description": "Base class for Moose variables. This should never be the terminal object type", "href": "../../../../source/variables/MooseLinearVariableFV.html"}>>>
solver_sys<<<{"description": "If this variable is a solver variable, this is the solver system to which it should be added."}>>> = pressure_system
initial_condition<<<{"description": "Specifies a constant initial condition for this variable"}>>> = ${P_out}
block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = '0 1'
[]
[T_fluid]
type = MooseLinearVariableFVReal<<<{"description": "Base class for Moose variables. This should never be the terminal object type", "href": "../../../../source/variables/MooseLinearVariableFV.html"}>>>
solver_sys<<<{"description": "If this variable is a solver variable, this is the solver system to which it should be added."}>>> = energy_system
initial_condition<<<{"description": "Specifies a constant initial condition for this variable"}>>> = ${Tin}
block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = '0 1'
[]
[T_solid]
type = MooseLinearVariableFVReal<<<{"description": "Base class for Moose variables. This should never be the terminal object type", "href": "../../../../source/variables/MooseLinearVariableFV.html"}>>>
solver_sys<<<{"description": "If this variable is a solver variable, this is the solver system to which it should be added."}>>> = solid_energy_system
initial_condition<<<{"description": "Specifies a constant initial condition for this variable"}>>> = ${T_s_bottom}
block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = 2
[]
[]
[LinearFVKernels<<<{"href": "../../../../syntax/LinearFVKernels/index.html"}>>>]
[u_advection_stress]
type = LinearWCNSFVMomentumFlux<<<{"description": "Represents the matrix and right hand side contributions of the stress and advection terms of the momentum equation.", "href": "../../../../source/linearfvkernels/LinearWCNSFVMomentumFlux.html"}>>>
variable<<<{"description": "The name of the variable whose linear system this object contributes to"}>>> = vel_x
advected_interp_method<<<{"description": "The interpolation to use for the advected quantity. Options are 'upwind', 'average', 'sou' (for second-order upwind), 'min_mod', 'vanLeer', 'quick', 'venkatakrishnan', and 'skewness-corrected' with the default being 'upwind'."}>>> = ${advected_interp_method}
mu<<<{"description": "The diffusion coefficient. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = ${mu}
u<<<{"description": "The velocity in the x direction."}>>> = vel_x
v<<<{"description": "The velocity in the y direction."}>>> = vel_y
momentum_component<<<{"description": "The component of the momentum equation that this kernel applies to."}>>> = 'x'
rhie_chow_user_object<<<{"description": "The rhie-chow user-object which is used to determine the face velocity."}>>> = 'rc'
use_nonorthogonal_correction<<<{"description": "If the nonorthogonal correction should be used when computing the normal gradient."}>>> = false
[]
[v_advection_stress]
type = LinearWCNSFVMomentumFlux<<<{"description": "Represents the matrix and right hand side contributions of the stress and advection terms of the momentum equation.", "href": "../../../../source/linearfvkernels/LinearWCNSFVMomentumFlux.html"}>>>
variable<<<{"description": "The name of the variable whose linear system this object contributes to"}>>> = vel_y
advected_interp_method<<<{"description": "The interpolation to use for the advected quantity. Options are 'upwind', 'average', 'sou' (for second-order upwind), 'min_mod', 'vanLeer', 'quick', 'venkatakrishnan', and 'skewness-corrected' with the default being 'upwind'."}>>> = ${advected_interp_method}
mu<<<{"description": "The diffusion coefficient. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = ${mu}
u<<<{"description": "The velocity in the x direction."}>>> = vel_x
v<<<{"description": "The velocity in the y direction."}>>> = vel_y
momentum_component<<<{"description": "The component of the momentum equation that this kernel applies to."}>>> = 'y'
rhie_chow_user_object<<<{"description": "The rhie-chow user-object which is used to determine the face velocity."}>>> = 'rc'
use_nonorthogonal_correction<<<{"description": "If the nonorthogonal correction should be used when computing the normal gradient."}>>> = false
[]
[u_pressure]
type = LinearFVMomentumPressure<<<{"description": "Represents the pressure gradient term in the Navier Stokes momentum equations, added to the right hand side.", "href": "../../../../source/linearfvkernels/LinearFVMomentumPressure.html"}>>>
variable<<<{"description": "The name of the variable whose linear system this object contributes to"}>>> = vel_x
pressure<<<{"description": "The pressure variable whose gradient should be used."}>>> = pressure
momentum_component<<<{"description": "The component of the momentum equation that this kernel applies to."}>>> = 'x'
[]
[v_pressure]
type = LinearFVMomentumPressure<<<{"description": "Represents the pressure gradient term in the Navier Stokes momentum equations, added to the right hand side.", "href": "../../../../source/linearfvkernels/LinearFVMomentumPressure.html"}>>>
variable<<<{"description": "The name of the variable whose linear system this object contributes to"}>>> = vel_y
pressure<<<{"description": "The pressure variable whose gradient should be used."}>>> = pressure
momentum_component<<<{"description": "The component of the momentum equation that this kernel applies to."}>>> = 'y'
[]
[p_diffusion]
type = LinearFVAnisotropicDiffusion<<<{"description": "Represents the matrix and right hand side contributions of a diffusion term in a partial differential equation.", "href": "../../../../source/linearfvkernels/LinearFVAnisotropicDiffusion.html"}>>>
variable<<<{"description": "The name of the variable whose linear system this object contributes to"}>>> = pressure
diffusion_tensor<<<{"description": "Functor describing a diagonal diffusion tensor. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = Ainv
use_nonorthogonal_correction<<<{"description": "If the nonorthogonal correction should be used when computing the normal gradient."}>>> = false
[]
[HbyA_divergence]
type = LinearFVDivergence<<<{"description": "Represents a divergence term. Note, this term does not contribute to the system matrix, only takes the divergence of a face flux field and adds it to the right hand side of the linear system.", "href": "../../../../source/linearfvkernels/LinearFVDivergence.html"}>>>
variable<<<{"description": "The name of the variable whose linear system this object contributes to"}>>> = pressure
face_flux<<<{"description": "Functor for the face flux. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = HbyA
force_boundary_execution<<<{"description": "Whether to force execution of this object on all external boundaries."}>>> = true
[]
[h_advection]
type = LinearFVEnergyAdvection<<<{"description": "Represents the matrix and right hand side contributions of an advection term for the energy e.g. h=int(cp dT). A user may still override what quantity is advected, but the default is temperature.", "href": "../../../../source/linearfvkernels/LinearFVEnergyAdvection.html"}>>>
variable<<<{"description": "The name of the variable whose linear system this object contributes to"}>>> = T_fluid
advected_quantity<<<{"description": "The advected quantity"}>>> = temperature
cp<<<{"description": "Constant specific heat value"}>>> = ${cp}
advected_interp_method<<<{"description": "The interpolation to use for the advected quantity. Options are 'upwind', 'average', 'sou' (for second-order upwind), 'min_mod', 'vanLeer', 'quick', 'venkatakrishnan', and 'skewness-corrected' with the default being 'upwind'."}>>> = ${advected_interp_method}
rhie_chow_user_object<<<{"description": "The rhie-chow user-object which is used to determine the face velocity."}>>> = 'rc'
[]
[conduction]
type = LinearFVDiffusion<<<{"description": "Represents the matrix and right hand side contributions of a diffusion term in a partial differential equation.", "href": "../../../../source/linearfvkernels/LinearFVDiffusion.html"}>>>
variable<<<{"description": "The name of the variable whose linear system this object contributes to"}>>> = T_fluid
diffusion_coeff<<<{"description": "The diffusion coefficient. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = ${k}
use_nonorthogonal_correction<<<{"description": "If the nonorthogonal correction should be used when computing the normal gradient."}>>> = false
[]
[solid-conduction]
type = LinearFVDiffusion<<<{"description": "Represents the matrix and right hand side contributions of a diffusion term in a partial differential equation.", "href": "../../../../source/linearfvkernels/LinearFVDiffusion.html"}>>>
variable<<<{"description": "The name of the variable whose linear system this object contributes to"}>>> = T_solid
diffusion_coeff<<<{"description": "The diffusion coefficient. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = ${k_s}
use_nonorthogonal_correction<<<{"description": "If the nonorthogonal correction should be used when computing the normal gradient."}>>> = false
[]
[]
[LinearFVBCs<<<{"href": "../../../../syntax/LinearFVBCs/index.html"}>>>]
# velocity BCs
[inlet-u]
type = LinearFVAdvectionDiffusionFunctorDirichletBC<<<{"description": "Adds a dirichlet BC which can be used for the assembly of linear finite volume system and whose face values are determined using a functor. This kernel is only designed to work with advection-diffusion problems.", "href": "../../../../source/linearfvbcs/LinearFVAdvectionDiffusionFunctorDirichletBC.html"}>>>
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'ent_left'
variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = vel_x
functor<<<{"description": "The functor for this boundary condition. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = ${vin}
[]
[inlet-v]
type = LinearFVAdvectionDiffusionFunctorDirichletBC<<<{"description": "Adds a dirichlet BC which can be used for the assembly of linear finite volume system and whose face values are determined using a functor. This kernel is only designed to work with advection-diffusion problems.", "href": "../../../../source/linearfvbcs/LinearFVAdvectionDiffusionFunctorDirichletBC.html"}>>>
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'ent_left'
variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = vel_y
functor<<<{"description": "The functor for this boundary condition. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = '0.000'
[]
[walls-u]
type = LinearFVAdvectionDiffusionFunctorDirichletBC<<<{"description": "Adds a dirichlet BC which can be used for the assembly of linear finite volume system and whose face values are determined using a functor. This kernel is only designed to work with advection-diffusion problems.", "href": "../../../../source/linearfvbcs/LinearFVAdvectionDiffusionFunctorDirichletBC.html"}>>>
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'ent_bottom interface'
variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = vel_x
functor<<<{"description": "The functor for this boundary condition. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 0.0
[]
[walls-v]
type = LinearFVAdvectionDiffusionFunctorDirichletBC<<<{"description": "Adds a dirichlet BC which can be used for the assembly of linear finite volume system and whose face values are determined using a functor. This kernel is only designed to work with advection-diffusion problems.", "href": "../../../../source/linearfvbcs/LinearFVAdvectionDiffusionFunctorDirichletBC.html"}>>>
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'ent_bottom interface'
variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = vel_y
functor<<<{"description": "The functor for this boundary condition. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 0.0
[]
[outlet_p]
type = LinearFVAdvectionDiffusionFunctorDirichletBC<<<{"description": "Adds a dirichlet BC which can be used for the assembly of linear finite volume system and whose face values are determined using a functor. This kernel is only designed to work with advection-diffusion problems.", "href": "../../../../source/linearfvbcs/LinearFVAdvectionDiffusionFunctorDirichletBC.html"}>>>
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'fluid_right'
variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = pressure
functor<<<{"description": "The functor for this boundary condition. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = ${P_out}
[]
[outlet_u]
type = LinearFVAdvectionDiffusionOutflowBC<<<{"description": "Adds a boundary condition which represents a surface with outflowing material with a constant velocity. This kernel is only compatible with advection-diffusion problems.", "href": "../../../../source/linearfvbcs/LinearFVAdvectionDiffusionOutflowBC.html"}>>>
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'fluid_right'
variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = vel_x
use_two_term_expansion<<<{"description": "If an approximate linear expansion should be used to compute the face value."}>>> = false
[]
[outlet_v]
type = LinearFVAdvectionDiffusionOutflowBC<<<{"description": "Adds a boundary condition which represents a surface with outflowing material with a constant velocity. This kernel is only compatible with advection-diffusion problems.", "href": "../../../../source/linearfvbcs/LinearFVAdvectionDiffusionOutflowBC.html"}>>>
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'fluid_right'
variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = vel_y
use_two_term_expansion<<<{"description": "If an approximate linear expansion should be used to compute the face value."}>>> = false
[]
# freestream BCs for top of fluid domain
[freestream_u]
type = LinearFVAdvectionDiffusionOutflowBC<<<{"description": "Adds a boundary condition which represents a surface with outflowing material with a constant velocity. This kernel is only compatible with advection-diffusion problems.", "href": "../../../../source/linearfvbcs/LinearFVAdvectionDiffusionOutflowBC.html"}>>>
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'fluid_top ent_top'
variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = vel_x
use_two_term_expansion<<<{"description": "If an approximate linear expansion should be used to compute the face value."}>>> = false
[]
[freestream_v]
type = LinearFVAdvectionDiffusionOutflowBC<<<{"description": "Adds a boundary condition which represents a surface with outflowing material with a constant velocity. This kernel is only compatible with advection-diffusion problems.", "href": "../../../../source/linearfvbcs/LinearFVAdvectionDiffusionOutflowBC.html"}>>>
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'fluid_top ent_top'
variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = vel_y
use_two_term_expansion<<<{"description": "If an approximate linear expansion should be used to compute the face value."}>>> = false
[]
[freestream_p]
type = LinearFVAdvectionDiffusionFunctorNeumannBC<<<{"description": "Adds a fixed diffusive flux BC which can be used for the assembly of linear finite volume system and whose normal face gradient values are determined using a functor. This kernel is only designed to work with advection-diffusion problems.", "href": "../../../../source/linearfvbcs/LinearFVAdvectionDiffusionFunctorNeumannBC.html"}>>>
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'fluid_top ent_top'
variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = pressure
functor<<<{"description": "The diffusive flux functor for this boundary condition. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 0
[]
# temperature BCs
[inlet_T]
type = LinearFVAdvectionDiffusionFunctorDirichletBC<<<{"description": "Adds a dirichlet BC which can be used for the assembly of linear finite volume system and whose face values are determined using a functor. This kernel is only designed to work with advection-diffusion problems.", "href": "../../../../source/linearfvbcs/LinearFVAdvectionDiffusionFunctorDirichletBC.html"}>>>
variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = T_fluid
functor<<<{"description": "The functor for this boundary condition. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = ${Tin}
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'ent_left'
[]
[heated_wall_solid]
type = LinearFVAdvectionDiffusionFunctorDirichletBC<<<{"description": "Adds a dirichlet BC which can be used for the assembly of linear finite volume system and whose face values are determined using a functor. This kernel is only designed to work with advection-diffusion problems.", "href": "../../../../source/linearfvbcs/LinearFVAdvectionDiffusionFunctorDirichletBC.html"}>>>
variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = T_solid
functor<<<{"description": "The functor for this boundary condition. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = ${T_s_bottom}
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'solid_bottom'
[]
[insulated_fluid]
type = LinearFVAdvectionDiffusionFunctorNeumannBC<<<{"description": "Adds a fixed diffusive flux BC which can be used for the assembly of linear finite volume system and whose normal face gradient values are determined using a functor. This kernel is only designed to work with advection-diffusion problems.", "href": "../../../../source/linearfvbcs/LinearFVAdvectionDiffusionFunctorNeumannBC.html"}>>>
variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = T_fluid
functor<<<{"description": "The diffusive flux functor for this boundary condition. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 0
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'ent_top ent_bottom fluid_top'
[]
[insulated_solid]
type = LinearFVAdvectionDiffusionFunctorNeumannBC<<<{"description": "Adds a fixed diffusive flux BC which can be used for the assembly of linear finite volume system and whose normal face gradient values are determined using a functor. This kernel is only designed to work with advection-diffusion problems.", "href": "../../../../source/linearfvbcs/LinearFVAdvectionDiffusionFunctorNeumannBC.html"}>>>
variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = T_solid
functor<<<{"description": "The diffusive flux functor for this boundary condition. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 0
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'solid_left solid_right'
[]
[outlet_T]
type = LinearFVAdvectionDiffusionOutflowBC<<<{"description": "Adds a boundary condition which represents a surface with outflowing material with a constant velocity. This kernel is only compatible with advection-diffusion problems.", "href": "../../../../source/linearfvbcs/LinearFVAdvectionDiffusionOutflowBC.html"}>>>
variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = T_fluid
use_two_term_expansion<<<{"description": "If an approximate linear expansion should be used to compute the face value."}>>> = false
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'fluid_right'
[]
[fluid_solid]
type = LinearFVRobinCHTBC<<<{"description": "Conjugate heat transfer BC for Robin boundary condition-based coupling.", "href": "../../../../source/linearfvbcs/LinearFVRobinCHTBC.html"}>>>
variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = T_fluid
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = interface
h<<<{"description": "The convective heat transfer coefficient. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = ${h_f}
incoming_flux<<<{"description": "The incoming diffusive flux on the interface. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = heat_flux_to_fluid_interface
surface_temperature<<<{"description": "The prescribed temperature on the interface. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = interface_temperature_solid_interface
thermal_conductivity<<<{"description": "The thermal conductivity of the material. Only used to compute the pure normal gradient of the variable on the boundary. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = ${k}
[]
[solid_fluid]
type = LinearFVRobinCHTBC<<<{"description": "Conjugate heat transfer BC for Robin boundary condition-based coupling.", "href": "../../../../source/linearfvbcs/LinearFVRobinCHTBC.html"}>>>
variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = T_solid
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = interface
h<<<{"description": "The convective heat transfer coefficient. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = ${h_s}
incoming_flux<<<{"description": "The incoming diffusive flux on the interface. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = heat_flux_to_solid_interface
surface_temperature<<<{"description": "The prescribed temperature on the interface. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = interface_temperature_fluid_interface
thermal_conductivity<<<{"description": "The thermal conductivity of the material. Only used to compute the pure normal gradient of the variable on the boundary. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = ${k_s}
[]
[]
[FunctorMaterials<<<{"href": "../../../../syntax/FunctorMaterials/index.html"}>>>]
[rhocpT]
property_name<<<{"description": "Name to give the new functor material property"}>>> = 'rhocpT'
type = ParsedFunctorMaterial<<<{"description": "Computes a functor material from a parsed expression of other functors.", "href": "../../../../source/functormaterials/ParsedFunctorMaterial.html"}>>>
functor_names<<<{"description": "Functors to use in the parsed expression"}>>> = 'T_fluid'
expression<<<{"description": "Expression to parse for the new functor material"}>>> = '${rho}*${cp}*T_fluid'
[]
[]
[Postprocessors<<<{"href": "../../../../syntax/Postprocessors/index.html"}>>>]
[h_in]
type = VolumetricFlowRate<<<{"description": "Computes the volumetric flow rate of an advected quantity through a sideset.", "href": "../../../../source/postprocessors/VolumetricFlowRate.html"}>>>
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'ent_left'
vel_x<<<{"description": "The x-axis velocity"}>>> = vel_x
vel_y<<<{"description": "The y-axis velocity"}>>> = vel_y
rhie_chow_user_object<<<{"description": "The rhie-chow user-object"}>>> = rc
advected_quantity<<<{"description": "The quantity to advect. This is the canonical parameter to set the advected quantity when finite volume is being used. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 'rhocpT'
subtract_mesh_velocity<<<{"description": "To subtract the velocity of the potentially moving mesh. Defaults to true if a displaced problem exists, else false."}>>> = false
[]
[h_out]
type = VolumetricFlowRate<<<{"description": "Computes the volumetric flow rate of an advected quantity through a sideset.", "href": "../../../../source/postprocessors/VolumetricFlowRate.html"}>>>
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'fluid_right fluid_top ent_top interface'
vel_x<<<{"description": "The x-axis velocity"}>>> = vel_x
vel_y<<<{"description": "The y-axis velocity"}>>> = vel_y
rhie_chow_user_object<<<{"description": "The rhie-chow user-object"}>>> = rc
advected_quantity<<<{"description": "The quantity to advect. This is the canonical parameter to set the advected quantity when finite volume is being used. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 'rhocpT'
advected_interp_method<<<{"description": "The interpolation to use for the advected quantity. Options are 'upwind', 'average', 'sou' (for second-order upwind), 'min_mod', 'vanLeer', 'quick', 'venkatakrishnan', and 'skewness-corrected' with the default being 'upwind'."}>>> = upwind
subtract_mesh_velocity<<<{"description": "To subtract the velocity of the potentially moving mesh. Defaults to true if a displaced problem exists, else false."}>>> = false
[]
[]
[VectorPostprocessors<<<{"href": "../../../../syntax/VectorPostprocessors/index.html"}>>>]
[y_vs_ts]
type = LineValueSampler<<<{"description": "Samples variable(s) along a specified line", "href": "../../../../source/vectorpostprocessors/LineValueSampler.html"}>>>
variable<<<{"description": "The names of the variables that this VectorPostprocessor operates on"}>>> = 'T_solid'
start_point<<<{"description": "The beginning of the line"}>>> = '0.100000001 -1e-9 0' # making sure we are always in the domain
end_point<<<{"description": "The ending of the line"}>>> = '0.100000001 ${fparse -b+1e-9} 0'
num_points<<<{"description": "The number of points to sample along the line"}>>> = 300
sort_by<<<{"description": "What to sort the samples by. Options include 'x', 'y', 'z', 'id', and the name of any of the sampled quantities (which each create a vector of the same name)."}>>> = id
warn_discontinuous_face_values<<<{"description": "Whether to return a warning if a discontinuous variable is sampled on a face"}>>> = false
[]
[y_vs_tf]
type = LineValueSampler<<<{"description": "Samples variable(s) along a specified line", "href": "../../../../source/vectorpostprocessors/LineValueSampler.html"}>>>
variable<<<{"description": "The names of the variables that this VectorPostprocessor operates on"}>>> = 'T_fluid'
start_point<<<{"description": "The beginning of the line"}>>> = '0.100000001 1e-9 0' # making sure we are always in the domain
end_point<<<{"description": "The ending of the line"}>>> = '0.100000001 ${fparse b-1e-9} 0'
num_points<<<{"description": "The number of points to sample along the line"}>>> = 300
sort_by<<<{"description": "What to sort the samples by. Options include 'x', 'y', 'z', 'id', and the name of any of the sampled quantities (which each create a vector of the same name)."}>>> = id
warn_discontinuous_face_values<<<{"description": "Whether to return a warning if a discontinuous variable is sampled on a face"}>>> = false
[]
[interface_temp]
type = SideValueSampler<<<{"description": "Sample variable(s) along a sideset, internal or external.", "href": "../../../../source/vectorpostprocessors/SideValueSampler.html"}>>>
variable<<<{"description": "The names of the variables that this VectorPostprocessor operates on"}>>> = 'T_fluid'
boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = interface
sort_by<<<{"description": "What to sort the samples by. Options include 'x', 'y', 'z', 'id', and the name of any of the sampled quantities (which each create a vector of the same name)."}>>> = x
[]
[]
[Executioner<<<{"href": "../../../../syntax/Executioner/index.html"}>>>]
type = SIMPLE
num_iterations = 3500
momentum_systems = 'u_system v_system'
pressure_system = 'pressure_system'
rhie_chow_user_object = 'rc'
momentum_l_abs_tol = 1e-8
pressure_l_abs_tol = 1e-8
momentum_l_tol = 0
pressure_l_tol = 0
momentum_equation_relaxation = 0.9
pressure_variable_relaxation = 1.0
momentum_absolute_tolerance = 1e-6
pressure_absolute_tolerance = 1e-6
momentum_petsc_options_iname = '-pc_type -pc_hypre_type'
momentum_petsc_options_value = 'hypre boomeramg'
pressure_petsc_options_iname = '-pc_type -pc_hypre_type'
pressure_petsc_options_value = 'hypre boomeramg'
energy_system = 'energy_system'
solid_energy_system = 'solid_energy_system'
energy_l_abs_tol = 1e-8
solid_energy_l_abs_tol = 1e-8
energy_l_tol = 0
solid_energy_l_tol = 0
energy_equation_relaxation = 1.0
energy_absolute_tolerance = 1e-7
solid_energy_absolute_tolerance = 1e-7
energy_petsc_options_iname = '-pc_type -pc_hypre_type'
energy_petsc_options_value = 'hypre boomeramg'
solid_energy_petsc_options_iname = '-pc_type -pc_hypre_type'
solid_energy_petsc_options_value = 'hypre boomeramg'
cht_interfaces = 'interface'
cht_solid_flux_relaxation = 1.0
cht_fluid_flux_relaxation = 1.0
cht_solid_temperature_relaxation = 1.0
cht_fluid_temperature_relaxation = 1.0
max_cht_fpi = 2
print_fields = false
continue_on_max_its = true
[]
[Outputs<<<{"href": "../../../../syntax/Outputs/index.html"}>>>]
exodus<<<{"description": "Output the results using the default settings for Exodus output."}>>> = true
csv<<<{"description": "Output the scalar variable and postprocessors to a *.csv file using the default CSV output."}>>> = true
execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'initial timestep_end'
[](validation/free_flow/heat_transfer/flat_plate/cht_rob-rob.i)Results
Two key physical quantities are being considered to build validation metrics:
Vertical temperature profile: temperature variation along the vertical line at .
Wall temperature distribution: temperature along the solid-fluid interface.
To judge the acceptability of the results, we utilize the analytic expressions by Luikov from Luikov (1974). These expressions utilized techniques like the boundary layer integral (BL) and differential heat transfer (DHT). It is important to note, however, that these expressions were derived using approximations such as assuming an averaged velocity in the boundary layer and no stream-wise conduction in the solid and fluid domains.
Figure 2 presents the temperature profile along the vertical line. We see that the numerical solution is between the two analytic expressions. As expected, the numerical results are slightly lower than the DHT approach mainly due to the neglect of the stream-wise conduction in the corresponding derivation in DHT.

Figure 2: Vertical temperature profile at 0.1 m from the leading edge of the flat plate.
Figure 3 presents the temperature profile along the solid-fluid interface. We see considerable differences at the leading edge of the plate where the gradients are the sharpest. Heat conduction in the solid is especially high serving as an explanation for the experienced deviation.

Figure 3: Temperature profile along the fluid-solid interface.
Discussion of errors
Mainly due to the approximations used in the analytic solutions, we see a considerable (up to 7-8%) error in the interface temperatures close to the leading edge of the plate. Closer to the middle and end tail of the plate, this error shrinks to approximately 2%.
Using the automatic testing of OpenPronghorn, we make sure this error does not increase over time. We allow a 1% deviation from previous error levels. We emphasize this is a change in the error levels, not in the solution itself. If software changes lead to a different solution with errors that surpass this level we declare a failed validation test. Furthermore, if we encounter changes in results more than 0.1% we notify the developers with a failed regression test. The validation test might still pass at this point.
Performance Chart
The following figure showcases the measured total runtime of the problem over the commit history. We utilized INL's High-Performance Computational resources to run these simulations so runtimes might vary depending on which physical resource the job got allocated.

Figure 4: Runtime over the latest commtits.
References
- AV Luikov.
Conjugate convective heat transfer problems.
International Journal of Heat and Mass Transfer, 17(2):257–265, 1974.[BibTeX]
- Tom Verstraete and Sebastian Scholl.
Stability analysis of partitioned methods for predicting conjugate heat transfer.
International Journal of Heat and Mass Transfer, 101:852–869, 2016.[BibTeX]