Thermal Contact Condition Verification Case

This document describes the two block 1-D verification test for the ThermalContactCondition object. Below is a summary of the test, along with a derivation of the analytic solution used for comparison and the relevant test input file for review.

Summary

A visual summary of the two block verification test domain, as well as relevant boundary and interface conditions is shown below (click to zoom):

Figure 1: Visual summary of the two block verification test with boundary and interface conditions.

It is important to note that in Figure 1:

  • is the thermal conductivity of material ,

  • is the electrical contact conductance at the interface,

  • is the thermal contact conductance at the interface,

  • is the electrostatic potential of material , and

  • is the temperature of material .

See the ThermalContactCondition documentation for more information about the particular definition of and . In order to simplify for the analytic solution derivation, the scenario was assumed to be steady state in order to remove the time derivative term of the heat conduction equation. The heating source term is electrothermal (or Joule) heating. This leads to

(1)

where is the electrical conductivity of material . Material properties being used in this case are constants within each block, and they are summarized below in Table 1. All material properties were evaluated at a temperature of ~300 K.

Table 1: Material properties for the two block thermal contact verification case.

Property (unit)ValueSource
Stainless Steel (304) Electrical Conductivity (S / m)(Cincotti et al., 2007)
Stainless Steel (304) Thermal Conductivity (W / (m K))(Cincotti et al., 2007)
Stainless Steel (304) Hardness (Pa)(Cincotti et al., 2007)
Graphite (AT 101) Electrical Conductivity (S / m)(Cincotti et al., 2007)
Graphite (AT 101) Thermal Conductivity (W / (m K))(Cincotti et al., 2007)
Graphite (AT 101) Hardness (Pa)(Cincotti et al., 2007)

The hardness values shown in Table 1 are used in the ThermalContactCondition object as a harmonic mean of the two values. For reference, the harmonic mean calculation for two values, and , is given by

The harmonic mean of hardness for stainless steel and graphite was calculated and set to be Pa. Harmonic mean values for the conductivities of stainless steel and graphite were also calculated in this way. Applied mechanical pressure was set to be . The mean hardness, mean conductivities, and applied mechanical pressure are all used to determine and (see the ThermalContactCondition documentation, (Cincotti et al., 2007), and (Madhusudana, 1996) for more information). The resulting calculated contact conductances were hard-coded in the input file shown near the bottom of this page, and are summarized below in Table 2.

Table 2: Thermal and electrical conductance values used in the thermal contact verification input file.

Conductance (units)Value
()75524.0
()0.242

Potential Function

The electrostatic potential function used in this test was determined based on the following scenario

Figure 2: Visual summary of the two block electrostatic verification test with boundary and interface conditions.

where the interface condition above is the ElectrostaticContactCondition. Solving for in each domain (using the same material properties and parameters outlined for this verification test) results in

This result was implemented in source code in both ThermalContactTemperatureTestFunc (for use in the final analytic result presented below) and in ThermalContactPotentialTestFunc (for use in the input file as the value of an auxiliary coupled variable). Both of these can be found in malamute/test/src.

Analytic Solution Derivation

In 1-D, Eq. (1) becomes

(2)

since is constant in both domains. Given that the gradient of the potential function used in this example is a linear one (so the right-hand-side is constant), this equation suggests a reasonable guess for a generic solution function for would be

(3)

where , , and are to-be-determined constant coefficients.

Apply differential equation

Using Eq. (2) and Eq. (3), we can determine for both the stainless steel and graphite domains:

Stainless Steel

Graphite

Apply boundary conditions

Applying the boundary conditions, we can determine for both the stainless steel and graphite domains (with the caveat that we still need to do a bit more work for ):

Stainless Steel

Graphite

Apply interface conditions

Now, the interface conditions can be applied from Figure 1. To begin, let's focus on the heat flux condition on the stainless steel side of the interface at .

Given that and has the form in Eq. (3), we have

If we let , then we have

(4)

Next, we can apply the heat flux condition on the graphite side of the interface at .

Again, given and Eq. (3), we have

If we let , then we have

(5)

Find the remaining coefficients

Using the Elimination Method, we can combine Eq. (4) and Eq. (5) in order to solve for each remaining unknown coefficient. If Eq. (4) is multiplied through on both sides by and Eq. (5) is multiplied through on both sides by , we have

(6)

and

(7)

Combining Eq. (6) and Eq. (7) together via addition yields

which can then be solved for

Using Eq. (5) and , we can now solve for :

Summarize

Now our determined coefficients can be combined to form the complete solutions for both stainless steel and graphite. To summarize, the derived analytical solutions for each domain given the boundary and interface conditions described in Figure 1 is

where

This is implemented in source code as ThermalContactTemperatureTestFunc. It can be found in the test source code directory located at malamute/test/src.

Input File

[Mesh<<<{"href": "../syntax/Mesh/index.html"}>>>]
  [line]
    type = GeneratedMeshGenerator<<<{"description": "Create a line, square, or cube mesh with uniformly spaced or biased elements.", "href": "../source/meshgenerators/GeneratedMeshGenerator.html"}>>>
    xmax<<<{"description": "Upper X Coordinate of the generated mesh"}>>> = 2
    dim<<<{"description": "The dimension of the mesh to be generated"}>>> = 1
    nx<<<{"description": "Number of elements in the X direction"}>>> = 400
  []
  [split]
    type = SubdomainBoundingBoxGenerator<<<{"description": "Changes the subdomain ID of elements either (XOR) inside or outside the specified box to the specified ID.", "href": "../source/meshgenerators/SubdomainBoundingBoxGenerator.html"}>>>
    bottom_left<<<{"description": "The bottom left point (in x,y,z with spaces in-between)."}>>> = '0 0 0'
    top_right<<<{"description": "The bottom left point (in x,y,z with spaces in-between)."}>>> = '1 0 0'
    block_id<<<{"description": "Subdomain id to set for inside/outside the bounding box"}>>> = 1
    block_name<<<{"description": "Subdomain name to set for inside/outside the bounding box (optional)"}>>> = 'stainless_steel'
    input<<<{"description": "The mesh we want to modify"}>>> = line
  []
  [rename_right]
    type = RenameBlockGenerator<<<{"description": "Changes the block IDs and/or block names for a given set of blocks defined by either block ID or block name. The changes are independent of ordering. The merging of blocks is supported.", "href": "../source/meshgenerators/RenameBlockGenerator.html"}>>>
    old_block<<<{"description": "Elements with these block ID(s)/name(s) will be given the new block information specified in 'new_block'"}>>> = 0
    new_block<<<{"description": "The new block ID(s)/name(s) to be given by the elements defined in 'old_block'."}>>> = 'graphite'
    input<<<{"description": "The mesh we want to modify"}>>> = split
  []
  [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"}>>> = rename_right
    primary_block<<<{"description": "The primary set of blocks for which to draw a sideset between"}>>> = 'stainless_steel'
    paired_block<<<{"description": "The paired set of blocks for which to draw a sideset between"}>>> = 'graphite'
    new_boundary<<<{"description": "The list of boundary names to create on the supplied subdomain"}>>> = 'ssg_interface'
  []
[]

[Variables<<<{"href": "../syntax/Variables/index.html"}>>>]
  [temperature_graphite]
    initial_condition<<<{"description": "Specifies a constant initial condition for this variable"}>>> = 300.0
    block = graphite
  []
  [temperature_stainless_steel]
    initial_condition<<<{"description": "Specifies a constant initial condition for this variable"}>>> = 300.0
    block = stainless_steel
  []
[]

[AuxVariables<<<{"href": "../syntax/AuxVariables/index.html"}>>>]
  [analytic_potential_graphite]
    block = graphite
  []
  [analytic_potential_stainless_steel]
    block = stainless_steel
  []
  [analytic_temperature_graphite]
    block = graphite
  []
  [analytic_temperature_stainless_steel]
    block = stainless_steel
  []
[]

[Kernels<<<{"href": "../syntax/Kernels/index.html"}>>>]
  [HeatDiff_graphite]
    type = ADHeatConduction<<<{"description": "Same as `Diffusion` in terms of physics/residual, but the Jacobian is computed using forward automatic differentiation", "href": "../source/kernels/ADHeatConduction.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = temperature_graphite
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = graphite
  []
  [HeatSource_graphite]
    type = ADJouleHeatingSource<<<{"description": "Calculates the heat source term corresponding to electrostatic or electromagnetic Joule heating, with Jacobian contributions calculated using the automatic differentiation system.", "href": "../source/kernels/ADJouleHeatingSource.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = temperature_graphite
    elec<<<{"description": "Electrostatic potential for joule heating."}>>> = analytic_potential_graphite
    electrical_conductivity<<<{"description": "Material property providing electrical conductivity of the material."}>>> = electrical_conductivity
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = graphite
  []

  [HeatDiff_stainless_steel]
    type = ADHeatConduction<<<{"description": "Same as `Diffusion` in terms of physics/residual, but the Jacobian is computed using forward automatic differentiation", "href": "../source/kernels/ADHeatConduction.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = temperature_stainless_steel
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = stainless_steel
  []
  [HeatSource_stainless_steel]
    type = ADJouleHeatingSource<<<{"description": "Calculates the heat source term corresponding to electrostatic or electromagnetic Joule heating, with Jacobian contributions calculated using the automatic differentiation system.", "href": "../source/kernels/ADJouleHeatingSource.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = temperature_stainless_steel
    elec<<<{"description": "Electrostatic potential for joule heating."}>>> = analytic_potential_stainless_steel
    electrical_conductivity<<<{"description": "Material property providing electrical conductivity of the material."}>>> = electrical_conductivity
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = stainless_steel
  []
[]

[AuxKernels<<<{"href": "../syntax/AuxKernels/index.html"}>>>]
  [analytic_potential_function_aux_stainless_steel]
    type = FunctionAux<<<{"description": "Auxiliary Kernel that creates and updates a field variable by sampling a function through space and time.", "href": "../source/auxkernels/FunctionAux.html"}>>>
    function<<<{"description": "The function to use as the value"}>>> = potential_fxn_stainless_steel
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = analytic_potential_stainless_steel
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = stainless_steel
  []
  [analytic_potential_function_aux_graphite]
    type = FunctionAux<<<{"description": "Auxiliary Kernel that creates and updates a field variable by sampling a function through space and time.", "href": "../source/auxkernels/FunctionAux.html"}>>>
    function<<<{"description": "The function to use as the value"}>>> = potential_fxn_graphite
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = analytic_potential_graphite
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = graphite
  []
  [analytic_temperature_function_aux_stainless_steel]
    type = FunctionAux<<<{"description": "Auxiliary Kernel that creates and updates a field variable by sampling a function through space and time.", "href": "../source/auxkernels/FunctionAux.html"}>>>
    function<<<{"description": "The function to use as the value"}>>> = temperature_fxn_stainless_steel
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = analytic_temperature_stainless_steel
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = stainless_steel
  []
  [analytic_temperature_function_aux_graphite]
    type = FunctionAux<<<{"description": "Auxiliary Kernel that creates and updates a field variable by sampling a function through space and time.", "href": "../source/auxkernels/FunctionAux.html"}>>>
    function<<<{"description": "The function to use as the value"}>>> = temperature_fxn_graphite
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = analytic_temperature_graphite
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = graphite
  []
[]

[BCs<<<{"href": "../syntax/BCs/index.html"}>>>]
  [thermal_left]
    type = DirichletBC<<<{"description": "Imposes the essential boundary condition $u=g$, where $g$ is a constant, controllable value.", "href": "../source/bcs/DirichletBC.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = temperature_stainless_steel
    boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = left
    value<<<{"description": "Value of the BC"}>>> = 300
  []
  [thermal_right]
    type = DirichletBC<<<{"description": "Imposes the essential boundary condition $u=g$, where $g$ is a constant, controllable value.", "href": "../source/bcs/DirichletBC.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = temperature_graphite
    boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = right
    value<<<{"description": "Value of the BC"}>>> = 300
  []
[]

[InterfaceKernels<<<{"href": "../syntax/InterfaceKernels/index.html"}>>>]
  [thermal_contact_conductance]
    type = ThermalContactCondition<<<{"description": "Interface condition that describes the thermal contact resistance across a boundary formed between two dissimilar materials (resulting in a temperature discontinuity) under the influence of an electrostatic potential, as described in Cincotti, et al (DOI: 10.1002/aic.11102). Thermal conductivity on each side of the boundary is defined via the material properties system.", "href": "../source/interfacekernels/ThermalContactCondition.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = temperature_stainless_steel
    neighbor_var<<<{"description": "The variable on the other side of the interface."}>>> = temperature_graphite
    primary_potential<<<{"description": "Electrostatic potential on the primary block."}>>> = analytic_potential_stainless_steel
    secondary_potential<<<{"description": "Electrostatic potential on the secondary block."}>>> = analytic_potential_graphite
    primary_thermal_conductivity<<<{"description": "Thermal conductivity on the primary block."}>>> = thermal_conductivity
    secondary_thermal_conductivity<<<{"description": "Thermal conductivity on the secondary block."}>>> = thermal_conductivity
    primary_electrical_conductivity<<<{"description": "Electrical conductivity on the primary block."}>>> = electrical_conductivity
    secondary_electrical_conductivity<<<{"description": "Electrical conductivity on the secondary block."}>>> = electrical_conductivity
    user_electrical_contact_conductance<<<{"description": "User-provided electrical contact conductance coefficient."}>>> = 75524 # at 300K with 3 kN/m^2 applied pressure
    user_thermal_contact_conductance<<<{"description": "User-provided thermal contact conductance coefficient."}>>> = 0.242 # also from Cincotti et al
    boundary<<<{"description": "The list of boundaries (ids or names) from the mesh where this object applies"}>>> = ssg_interface
  []
[]

[Materials<<<{"href": "../syntax/Materials/index.html"}>>>]
  #graphite
  [heat_conductor_graphite]
    type = ADGenericConstantMaterial<<<{"description": "Declares material properties based on names and values prescribed by input parameters.", "href": "../source/materials/GenericConstantMaterial.html"}>>>
    prop_names<<<{"description": "The names of the properties this material will have"}>>> = thermal_conductivity
    prop_values<<<{"description": "The values associated with the named properties"}>>> = 100
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = graphite
  []
  [sigma_graphite]
    type = ADGenericConstantMaterial<<<{"description": "Declares material properties based on names and values prescribed by input parameters.", "href": "../source/materials/GenericConstantMaterial.html"}>>>
    prop_names<<<{"description": "The names of the properties this material will have"}>>> = electrical_conductivity
    prop_values<<<{"description": "The values associated with the named properties"}>>> = 73069.2
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = graphite
  []

  #stainless_steel
  [heat_conductor_stainless_steel]
    type = ADGenericConstantMaterial<<<{"description": "Declares material properties based on names and values prescribed by input parameters.", "href": "../source/materials/GenericConstantMaterial.html"}>>>
    prop_names<<<{"description": "The names of the properties this material will have"}>>> = thermal_conductivity
    prop_values<<<{"description": "The values associated with the named properties"}>>> = 15
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = stainless_steel
  []
  [sigma_stainless_steel]
    type = ADGenericConstantMaterial<<<{"description": "Declares material properties based on names and values prescribed by input parameters.", "href": "../source/materials/GenericConstantMaterial.html"}>>>
    prop_names<<<{"description": "The names of the properties this material will have"}>>> = electrical_conductivity
    prop_values<<<{"description": "The values associated with the named properties"}>>> = 1.41867e6
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = stainless_steel
  []
[]

[Functions<<<{"href": "../syntax/Functions/index.html"}>>>]
  [potential_fxn_stainless_steel]
    type = ThermalContactPotentialTestFunc
    domain = stainless_steel
  []
  [potential_fxn_graphite]
    type = ThermalContactPotentialTestFunc
    domain = graphite
  []
  [temperature_fxn_stainless_steel]
    type = ThermalContactTemperatureTestFunc
    domain = stainless_steel
  []
  [temperature_fxn_graphite]
    type = ThermalContactTemperatureTestFunc
    domain = graphite
  []
[]

[Preconditioning<<<{"href": "../syntax/Preconditioning/index.html"}>>>]
  [SMP]
    type = SMP<<<{"description": "Single matrix preconditioner (SMP) builds a preconditioner using user defined off-diagonal parts of the Jacobian.", "href": "../source/preconditioners/SingleMatrixPreconditioner.html"}>>>
    full<<<{"description": "Set to true if you want the full set of couplings between variables simply for convenience so you don't have to set every off_diag_row and off_diag_column combination."}>>> = true
  []
[]

[Executioner<<<{"href": "../syntax/Executioner/index.html"}>>>]
  type = Steady
  solve_type = NEWTON
  petsc_options_iname = '-pc_type'
  petsc_options_value = 'lu'
[]

[Outputs<<<{"href": "../syntax/Outputs/index.html"}>>>]
  exodus<<<{"description": "Output the results using the default settings for Exodus output."}>>> = true
  perf_graph<<<{"description": "Enable printing of the performance graph to the screen (Console)"}>>> = true
[]
(test/tests/interfacekernels/thermal_conductance/thermal_interface_analytic_solution_two_block.i)

Results

Results from the input file shown above compared to the analytic function are shown below in Figure 3. Note that the number of points shown in the plot has been down-sampled compared to the solved number of elements for readability.

Figure 3: Results of electrothermal contact two block validation case.

References

  1. A. Cincotti, A. M. Locci, R. OrrĂ¹, and G. Cao. Modeling of SPS apparatus: temperature, current and strain distribution with no powders. AIChE Journal, 53(3):703–719, 2007. doi:10.1002/aic.11102.[BibTeX]
  2. Chakravarti V. Madhusudana. Thermal Contact Conductance. Springer-Verlag, 1996.[BibTeX]