Electrostatic Contact Verification (Three Block Test)

This document describes the three block 1-D verification test for the ElectrostaticContactCondition 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 three block verification test domain, as well as relevant boundary and interface conditions is shown below (click to zoom):

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

It is important to note that in Figure 1:

  • is the electrical conductivity of material ,

  • is the electrical contact conductance at the interface, and

  • is the electrostatic potential of material .

See the ElectrostaticContactCondition documentation for more information about the particular definition of . As the ElectrostaticContactCondition object is intended for electrostatic field solves, the PDE being solved within each domain is Poisson's Equation for electrostatic potential. In this case, we are assuming a zero total charge density, which leads to

(1)

Material properties being used in this case are constants in 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 three block electrostatic contact verification case.

Property (unit)ValueSource
Stainless Steel (304) Electrical Conductivity (S / m)(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) Hardness (Pa)(Cincotti et al., 2007)

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

In the input file, the harmonic mean of hardness for stainless steel and graphite was calculated and set to be Pa.

Analytic Solution Derivation

In 1-D, Eq. (1) becomes

since is constant in all domains. This equation means a reasonable guess for a generic solution function for would be

where and are to-be-determined constant coefficients.

Apply boundary conditions

Using the boundary conditions in Figure 1, we can determine for both of the outer stainless steel regions:

Stainless Steel (left)

Stainless Steel (right)

Apply interface conditions

Now, the interface conditions can be applied from Figure 1. To begin, let's focus on the current density () equivalence condition on the left interface (at ):

Taking into account our initial guess for the solution function, this becomes

(2)

Next, we can apply the conductance condition from Figure 1, which is

Taking into account our initial guess for the solution function and the constant coefficient solved for above, this becomes

Grouping terms, we have

(3)

Next, let's focus on the current density () equivalence condition on the right interface (at ):

Taking into account our initial guess for the solution function, this becomes

(4)

Next, we can apply the conductance condition from Figure 1, which is

Taking into account our initial guess for the solution function and the constant coefficient solved for above, this becomes

Grouping terms, we have

(5)

Find the remaining coefficients

Using the Elimination Method and some algebra, we can combine Eq. (2), Eq. (3), Eq. (4), and Eq. (5) in order to solve for each remaining unknown coefficient. To begin, let's focus on Eq. (2) and Eq. (3). Multiplying Eq. (2) through by and Eq. (3) through by yields

(6)

and

(7)

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

which can then be solved for :

(8)

Next, we focus on Eq. (4) and Eq. (5). Multiplying Eq. (4) through by and Eq. (5) through by yields

(9)

and

(10)

Combining Eq. (9) and Eq. (10) together via addition yields

which can then be solved for :

(11)

Note that Eq. (8) and Eq. (11) still depend on finding the coefficient . We can now solve for by using Eq. (2), which yields

and finally

(12)

Returning to Eq. (11), we can now fully solve for :

Simplifying yields:

(13)

Returning to Eq. (8), we can now fully solve for :

Simplifying yields:

(14)

Returning to Eq. (4), we can now fully solve for :

(15)

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:

  • For stainless steel from to :

  • For graphite from to :

  • For stainless steel from to :

This is implemented in source code as ElectricalContactTestFunc.C and is located within the test source code directory located at modules/electromagnetics/test/src.

Input File

# Regression test for ElectrostaticContactCondition with analytic solution with
# three blocks
#
# dim = 1D
# X = [0,3]
# Interfaces at X = 1 and X = 2
#
#   stainless_steel        graphite        stainless_steel
# +------------------+------------------+------------------+
#
# Left BC: Potential = 1
# Right BC: Potential = 0
# Left Interface: ElectrostaticContactCondition (primary = stainless_steel)
# Right Interface: ElectrostaticContactCondition (primary = graphite)
#

[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"}>>>
    dim<<<{"description": "The dimension of the mesh to be generated"}>>> = 1
    nx<<<{"description": "Number of elements in the X direction"}>>> = 6
    xmax<<<{"description": "Upper X Coordinate of the generated mesh"}>>> = 3
  []
  [break_center]
    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"}>>>
    input<<<{"description": "The mesh we want to modify"}>>> = line
    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)"}>>> = 'graphite'
    bottom_left<<<{"description": "The bottom left point (in x,y,z with spaces in-between)."}>>> = '1 0 0'
    top_right<<<{"description": "The bottom left point (in x,y,z with spaces in-between)."}>>> = '2 0 0'
  []
  [break_right]
    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"}>>>
    input<<<{"description": "The mesh we want to modify"}>>> = break_center
    block_id<<<{"description": "Subdomain id to set for inside/outside the bounding box"}>>> = 2
    bottom_left<<<{"description": "The bottom left point (in x,y,z with spaces in-between)."}>>> = '2 0 0'
    top_right<<<{"description": "The bottom left point (in x,y,z with spaces in-between)."}>>> = '3 0 0'
  []
  [ssg_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"}>>> = break_right
    primary_block<<<{"description": "The primary set of blocks for which to draw a sideset between"}>>> = 0
    paired_block<<<{"description": "The paired set of blocks for which to draw a sideset between"}>>> = 1
    new_boundary<<<{"description": "The list of boundary names to create on the supplied subdomain"}>>> = 'ssg_interface'
  []
  [gss_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"}>>> = ssg_interface
    primary_block<<<{"description": "The primary set of blocks for which to draw a sideset between"}>>> = 1
    paired_block<<<{"description": "The paired set of blocks for which to draw a sideset between"}>>> = 2
    new_boundary<<<{"description": "The list of boundary names to create on the supplied subdomain"}>>> = 'gss_interface'
  []
  [block_rename]
    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"}>>>
    input<<<{"description": "The mesh we want to modify"}>>> = gss_interface
    old_block<<<{"description": "Elements with these block ID(s)/name(s) will be given the new block information specified in 'new_block'"}>>> = '0 2'
    new_block<<<{"description": "The new block ID(s)/name(s) to be given by the elements defined in 'old_block'."}>>> = 'stainless_steel_left stainless_steel_right'
  []
[]

[Variables<<<{"href": "../../../syntax/Variables/index.html"}>>>]
  [potential_graphite]
    block = graphite
  []
  [potential_stainless_steel_left]
    block = stainless_steel_left
  []
  [potential_stainless_steel_right]
    block = stainless_steel_right
  []
[]

[AuxVariables<<<{"href": "../../../syntax/AuxVariables/index.html"}>>>]
  [analytic_potential_stainless_steel_left]
    block = stainless_steel_left
  []
  [analytic_potential_stainless_steel_right]
    block = stainless_steel_right
  []
  [analytic_potential_graphite]
    block = graphite
  []
[]

[Kernels<<<{"href": "../../../syntax/Kernels/index.html"}>>>]
  [electric_graphite]
    type = ADMatDiffusion<<<{"description": "Diffusion equation kernel that takes an isotropic diffusivity from a material property", "href": "../../../source/kernels/ADMatDiffusion.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = potential_graphite
    diffusivity<<<{"description": "The diffusivity value or material property"}>>> = electrical_conductivity
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = graphite
  []
  [electric_stainless_steel_left]
    type = ADMatDiffusion<<<{"description": "Diffusion equation kernel that takes an isotropic diffusivity from a material property", "href": "../../../source/kernels/ADMatDiffusion.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = potential_stainless_steel_left
    diffusivity<<<{"description": "The diffusivity value or material property"}>>> = electrical_conductivity
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = stainless_steel_left
  []
  [electric_stainless_steel_right]
    type = ADMatDiffusion<<<{"description": "Diffusion equation kernel that takes an isotropic diffusivity from a material property", "href": "../../../source/kernels/ADMatDiffusion.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = potential_stainless_steel_right
    diffusivity<<<{"description": "The diffusivity value or material property"}>>> = electrical_conductivity
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = stainless_steel_right
  []
[]

[AuxKernels<<<{"href": "../../../syntax/AuxKernels/index.html"}>>>]
  [analytic_function_aux_stainless_steel_left]
    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_left
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = analytic_potential_stainless_steel_left
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = stainless_steel_left
  []
  [analytic_function_aux_stainless_steel_right]
    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_right
    variable<<<{"description": "The name of the variable that this object applies to"}>>> = analytic_potential_stainless_steel_right
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = stainless_steel_right
  []
  [analytic_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
  []
[]

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

[InterfaceKernels<<<{"href": "../../../syntax/InterfaceKernels/index.html"}>>>]
  [electric_contact_conductance_ssg]
    type = ElectrostaticContactCondition<<<{"description": "Interface condition that describes the current continuity and contact conductance across a boundary formed between two dissimilar materials (resulting in a potential discontinuity). Conductivity on each side of the boundary is defined via the material properties system.", "href": "../../../source/interfacekernels/ElectrostaticContactCondition.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = potential_stainless_steel_left
    neighbor_var<<<{"description": "The variable on the other side of the interface."}>>> = potential_graphite
    boundary<<<{"description": "The list of boundaries (ids or names) from the mesh where this object applies"}>>> = ssg_interface
    mean_hardness<<<{"description": "Geometric mean of the hardness of each contacting material."}>>> = mean_hardness
    mechanical_pressure<<<{"description": "Mechanical pressure uniformly applied at the contact surface area (Pressure = Force / Surface Area)."}>>> = 3000
  []
  [electric_contact_conductance_gss]
    type = ElectrostaticContactCondition<<<{"description": "Interface condition that describes the current continuity and contact conductance across a boundary formed between two dissimilar materials (resulting in a potential discontinuity). Conductivity on each side of the boundary is defined via the material properties system.", "href": "../../../source/interfacekernels/ElectrostaticContactCondition.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = potential_graphite
    neighbor_var<<<{"description": "The variable on the other side of the interface."}>>> = potential_stainless_steel_right
    boundary<<<{"description": "The list of boundaries (ids or names) from the mesh where this object applies"}>>> = gss_interface
    mean_hardness<<<{"description": "Geometric mean of the hardness of each contacting material."}>>> = mean_hardness
    mechanical_pressure<<<{"description": "Mechanical pressure uniformly applied at the contact surface area (Pressure = Force / Surface Area)."}>>> = 3000
  []
[]

[Materials<<<{"href": "../../../syntax/Materials/index.html"}>>>]
  #graphite (at 300 K)
  [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 (at 300 K)
  [sigma_stainless_steel_left]
    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_left
  []
  [sigma_stainless_steel_right]
    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_right
  []

  # harmonic mean of graphite and stainless steel hardness
  [mean_hardness]
    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"}>>> = mean_hardness
    prop_values<<<{"description": "The values associated with the named properties"}>>> = 2.4797e9
  []
[]

[Functions<<<{"href": "../../../syntax/Functions/index.html"}>>>]
  [potential_fxn_stainless_steel_left]
    type = ElectricalContactTestFunc
    domain = stainless_steel
    three_block = true
    three_block_side = left
  []
  [potential_fxn_stainless_steel_right]
    type = ElectricalContactTestFunc
    domain = stainless_steel
    three_block = true
    three_block_side = right
  []
  [potential_fxn_graphite]
    type = ElectricalContactTestFunc
    domain = graphite
    three_block = true
  []
[]

[Postprocessors<<<{"href": "../../../syntax/Postprocessors/index.html"}>>>]
  [error_stainless_steel_left]
    type = ElementL2Error<<<{"description": "Computes L2 error between a field variable and an analytical function", "href": "../../../source/postprocessors/ElementL2Error.html"}>>>
    variable<<<{"description": "The name of the variable that this object operates on"}>>> = potential_stainless_steel_left
    function<<<{"description": "The analytic solution to compare against"}>>> = potential_fxn_stainless_steel_left
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = stainless_steel_left
  []
  [error_graphite]
    type = ElementL2Error<<<{"description": "Computes L2 error between a field variable and an analytical function", "href": "../../../source/postprocessors/ElementL2Error.html"}>>>
    variable<<<{"description": "The name of the variable that this object operates on"}>>> = potential_graphite
    function<<<{"description": "The analytic solution to compare against"}>>> = potential_fxn_graphite
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = graphite
  []
  [error_stainless_steel_right]
    type = ElementL2Error<<<{"description": "Computes L2 error between a field variable and an analytical function", "href": "../../../source/postprocessors/ElementL2Error.html"}>>>
    variable<<<{"description": "The name of the variable that this object operates on"}>>> = potential_stainless_steel_right
    function<<<{"description": "The analytic solution to compare against"}>>> = potential_fxn_stainless_steel_right
    block<<<{"description": "The list of blocks (ids or names) that this object will be applied"}>>> = stainless_steel_right
  []
[]

[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
  automatic_scaling = true
[]

[Outputs<<<{"href": "../../../syntax/Outputs/index.html"}>>>]
  csv<<<{"description": "Output the scalar variable and postprocessors to a *.csv file using the default CSV output."}>>> = true
  perf_graph<<<{"description": "Enable printing of the performance graph to the screen (Console)"}>>> = true
[]
(modules/electromagnetics/test/tests/interfacekernels/electrostatic_contact/analytic_solution_test_three_block.i)

Results

Results from the input file shown above (with Mesh/line/nx=60 and Outputs/exodus=true) compared to the analytic function are shown below in Figure 2. Note that the number of points shown in the plot has been down-sampled compared to the solved number of elements for readability.

Figure 2: Results of electrostatic contact three 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]