LinearFVGrayLambertBC

LinearFVGrayLambertBC applies a surface-to-surface radiation boundary condition to a linear finite-volume temperature variable. It is the LinearFV counterpart of GrayLambertNeumannBC. Both boundary conditions obtain the radiative exchange quantities from a GrayLambertSurfaceRadiationBase user object; the difference is that LinearFVGrayLambertBC contributes to a linear finite-volume system.

This boundary condition is intended for heat-conduction or energy equations using a MooseVariableLinearFVReal variable and a LinearFVDiffusion kernel. It does not compute view factors or solve the enclosure radiosity equations itself. Those tasks remain the responsibility of a surface-radiation user object such as ConstantViewFactorSurfaceRadiation or ViewFactorObjectSurfaceRadiation.

commentnote

LinearFVGrayLambertBC models surface-to-surface exchange among opaque, gray, diffuse surfaces. It is distinct from a Marshak boundary condition used with a participating- media radiation-diffusion model.

Gray-Lambert surface exchange

For a gray, diffuse surface , the radiosity , irradiation , and net outward radiative heat-flux density satisfy

(1)(2)

and

(3)

where is the surface emissivity, is the Stefan–Boltzmann constant, is the absolute surface temperature, and is the view factor from surface to surface . The surface-radiation user object solves this enclosure problem and provides the irradiation, emissivity, and net heat flux for each participating boundary.

The radiative heat flux is coupled to the finite-volume energy equation through

(4)

where is the diffusion coefficient, is the boundary-face temperature, and is the outward unit normal.

LinearFV formulation

When "reconstruct_emission" is true, the emitted portion of the heat flux is reconstructed using the local boundary-face temperature. Substitution of Eq. (3) into Eq. (4) gives

(5)

The LinearFV system is linear, so the fourth-power temperature dependence is treated with linearization. For outer iteration ,

(6)

Consequently, Eq. (5) is written in the Robin form

(7)

with

(8)

where and are the temperature and diffusion coefficient, respectively, evaluated in the cell adjacent to the boundary using the previous nonlinear solution state. For a constant diffusion coefficient, .

The use of avoids recursively evaluating the temperature at a boundary whose value is itself determined by this boundary condition. Consequently, the emission term is approximated as

(9)

This treatment combines fixed-point lagging of the nonlinear coefficient with a first-order approximation of the previous boundary temperature, . Therefore, even after convergence of the nonlinear iterations, the reconstructed emission is proportional to rather than exactly .

commentnote:First-order boundary approximation

The current implementation evaluates the temperature-dependent emission coefficient using the adjacent-cell temperature. This avoids recursive boundary evaluation but introduces a first-order spatial approximation in the nonlinear radiative coefficient.

warningwarning:Consistent diffusion coefficient

The coeff_diffusion supplied to this boundary condition must represent the same physical coefficient as the diffusion_coeff used by the associated LinearFVDiffusion kernel. For a heat-conduction equation, both parameters represent the thermal conductivity. If the diffusion coefficient depends on temperature, the boundary-condition coefficient is evaluated at the adjacent cell using the previous nonlinear solution state.

When "reconstruct_emission" is false, the surface-averaged heat-flux density obtained directly from the Gray–Lambert user object is imposed as a constant Neumann flux over each participating sideset. The Robin coefficients then reduce to

(10)

Reconstructing the emission is generally preferable when the temperature varies spatially along a radiating sideset because it preserves the local emission term. In this mode, irradiation remains the surface quantity supplied by the enclosure radiation user object.

Iterative coupling

Surface-to-surface radiation introduces two sources of nonlinearity and coupling: the emitted energy depends on , and the irradiation on one surface depends on the radiosities of all surfaces in the enclosure. It is therefore important to use relaxation, either for the multi-system fixed-point iteration or through outer SIMPLE iterations.

Example syntax

The following example applies the boundary condition to an inner empty cube within a 2D domain

[Problem<<<{"href": "../../syntax/Problem/index.html"}>>>]
  kernel_coverage_check = false
  linear_sys_names = 'energy_system'
[]

[Mesh<<<{"href": "../../syntax/Mesh/index.html"}>>>]
  type = MeshGeneratorMesh

  [cmg]
    type = CartesianMeshGenerator<<<{"description": "This CartesianMeshGenerator creates a non-uniform Cartesian mesh.", "href": "../meshgenerators/CartesianMeshGenerator.html"}>>>
    dim<<<{"description": "The dimension of the mesh to be generated"}>>> = 2
    dx<<<{"description": "Intervals in the X direction"}>>> = '1 1.3 1.9'
    ix<<<{"description": "Number of grids in all intervals in the X direction (default to all one)"}>>> = '5 5 5'
    dy<<<{"description": "Intervals in the Y direction (required when dim>1 otherwise ignored)"}>>> = '2 1.2 0.9'
    iy<<<{"description": "Number of grids in all intervals in the Y direction (default to all one)"}>>> = '5 5 5'
    subdomain_id<<<{"description": "Block IDs (default to all zero)"}>>> = '0 1 0
                    4 5 2
                    0 3 0'
  []

  [inner_bottom]
    type = SideSetsBetweenSubdomainsGenerator<<<{"description": "MeshGenerator that creates a sideset composed of the nodes located between two or more subdomains.", "href": "../meshgenerators/SideSetsBetweenSubdomainsGenerator.html"}>>>
    input<<<{"description": "The mesh we want to modify"}>>> = cmg
    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"}>>> = 5
    new_boundary<<<{"description": "The list of boundary names to create on the supplied subdomain"}>>> = 'inner_bottom'
  []

  [inner_left]
    type = SideSetsBetweenSubdomainsGenerator<<<{"description": "MeshGenerator that creates a sideset composed of the nodes located between two or more subdomains.", "href": "../meshgenerators/SideSetsBetweenSubdomainsGenerator.html"}>>>
    input<<<{"description": "The mesh we want to modify"}>>> = inner_bottom
    primary_block<<<{"description": "The primary set of blocks for which to draw a sideset between"}>>> = 4
    paired_block<<<{"description": "The paired set of blocks for which to draw a sideset between"}>>> = 5
    new_boundary<<<{"description": "The list of boundary names to create on the supplied subdomain"}>>> = 'inner_left'
  []

  [inner_right]
    type = SideSetsBetweenSubdomainsGenerator<<<{"description": "MeshGenerator that creates a sideset composed of the nodes located between two or more subdomains.", "href": "../meshgenerators/SideSetsBetweenSubdomainsGenerator.html"}>>>
    input<<<{"description": "The mesh we want to modify"}>>> = inner_left
    primary_block<<<{"description": "The primary set of blocks for which to draw a sideset between"}>>> = 2
    paired_block<<<{"description": "The paired set of blocks for which to draw a sideset between"}>>> = 5
    new_boundary<<<{"description": "The list of boundary names to create on the supplied subdomain"}>>> = 'inner_right'
  []

  [inner_top]
    type = SideSetsBetweenSubdomainsGenerator<<<{"description": "MeshGenerator that creates a sideset composed of the nodes located between two or more subdomains.", "href": "../meshgenerators/SideSetsBetweenSubdomainsGenerator.html"}>>>
    input<<<{"description": "The mesh we want to modify"}>>> = inner_right
    primary_block<<<{"description": "The primary set of blocks for which to draw a sideset between"}>>> = 3
    paired_block<<<{"description": "The paired set of blocks for which to draw a sideset between"}>>> = 5
    new_boundary<<<{"description": "The list of boundary names to create on the supplied subdomain"}>>> = 'inner_top'
  []

  [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": "../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'"}>>> = '1 2 3 4'
    new_block<<<{"description": "The new block ID(s)/name(s) to be given by the elements defined in 'old_block'."}>>> = '0 0 0 0'
    input<<<{"description": "The mesh we want to modify"}>>> = inner_top
  []

  [split_inner_bottom]
    type = PatchSidesetGenerator<<<{"description": "Divides the given sideset into smaller patches of roughly equal size.", "href": "../meshgenerators/PatchSidesetGenerator.html"}>>>
    boundary<<<{"description": "The boundary that will be divided into patches"}>>> = 4
    n_patches<<<{"description": "Number of patches"}>>> = 2
    partitioner<<<{"description": "Specifies a mesh partitioner to use when splitting the mesh for a parallel computation."}>>> = centroid
    centroid_partitioner_direction<<<{"description": "Specifies the sort direction if using the centroid partitioner. Available options: x, y, z, radial"}>>> = x
    input<<<{"description": "The mesh we want to modify"}>>> = rename
  []

  [split_inner_left]
    type = PatchSidesetGenerator<<<{"description": "Divides the given sideset into smaller patches of roughly equal size.", "href": "../meshgenerators/PatchSidesetGenerator.html"}>>>
    boundary<<<{"description": "The boundary that will be divided into patches"}>>> = 5
    n_patches<<<{"description": "Number of patches"}>>> = 2
    partitioner<<<{"description": "Specifies a mesh partitioner to use when splitting the mesh for a parallel computation."}>>> = centroid
    centroid_partitioner_direction<<<{"description": "Specifies the sort direction if using the centroid partitioner. Available options: x, y, z, radial"}>>> = y
    input<<<{"description": "The mesh we want to modify"}>>> = split_inner_bottom
  []

  [split_inner_right]
    type = PatchSidesetGenerator<<<{"description": "Divides the given sideset into smaller patches of roughly equal size.", "href": "../meshgenerators/PatchSidesetGenerator.html"}>>>
    boundary<<<{"description": "The boundary that will be divided into patches"}>>> = 6
    n_patches<<<{"description": "Number of patches"}>>> = 2
    partitioner<<<{"description": "Specifies a mesh partitioner to use when splitting the mesh for a parallel computation."}>>> = centroid
    centroid_partitioner_direction<<<{"description": "Specifies the sort direction if using the centroid partitioner. Available options: x, y, z, radial"}>>> = y
    input<<<{"description": "The mesh we want to modify"}>>> = split_inner_left
  []

  [split_inner_top]
    type = PatchSidesetGenerator<<<{"description": "Divides the given sideset into smaller patches of roughly equal size.", "href": "../meshgenerators/PatchSidesetGenerator.html"}>>>
    boundary<<<{"description": "The boundary that will be divided into patches"}>>> = 7
    n_patches<<<{"description": "Number of patches"}>>> = 3
    partitioner<<<{"description": "Specifies a mesh partitioner to use when splitting the mesh for a parallel computation."}>>> = centroid
    centroid_partitioner_direction<<<{"description": "Specifies the sort direction if using the centroid partitioner. Available options: x, y, z, radial"}>>> = x
    input<<<{"description": "The mesh we want to modify"}>>> = split_inner_right
  []

  [delete_others]
    type = BoundaryDeletionGenerator<<<{"description": "Mesh generator which removes side sets", "href": "../meshgenerators/BoundaryDeletionGenerator.html"}>>>
    input<<<{"description": "The mesh we want to modify"}>>> = 'split_inner_top'
    boundary_names<<<{"description": "The boundaries to be deleted / kept"}>>> = 'inner_bottom inner_top inner_left inner_right'
  []

  [delete_block5]
    type = BlockDeletionGenerator<<<{"description": "Mesh generator which removes elements from the specified subdomains", "href": "../meshgenerators/BlockDeletionGenerator.html"}>>>
    input<<<{"description": "The mesh we want to modify"}>>> = 'delete_others'
    block<<<{"description": "The list of blocks to be processed (deleted or kept)"}>>> = '5'
  []
[]

[Variables<<<{"href": "../../syntax/Variables/index.html"}>>>]
  [temperature]
    type = MooseLinearVariableFVReal<<<{"description": "Base class for Moose variables. This should never be the terminal object type", "href": "../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"}>>> = 400
  []
[]

[LinearFVKernels<<<{"href": "../../syntax/LinearFVKernels/index.html"}>>>]
  [temp_conduction]
    type = LinearFVDiffusion<<<{"description": "Represents the matrix and right hand side contributions of a diffusion term in a partial differential equation.", "href": "../linearfvkernels/LinearFVDiffusion.html"}>>>
    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."}>>> = 5.
    variable<<<{"description": "The name of the variable whose linear system this object contributes to"}>>> = temperature
  []
[]

[UserObjects<<<{"href": "../../syntax/UserObjects/index.html"}>>>]
  [gray_lambert]
    type = ViewFactorObjectSurfaceRadiation<<<{"description": "ViewFactorObjectSurfaceRadiation computes radiative heat transfer between side sets and the view factors are computed by a ViewFactor object", "href": "../userobjects/ViewFactorObjectSurfaceRadiation.html"}>>>
    boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'inner_bottom_0 inner_bottom_1
                inner_left_0 inner_left_1
                inner_right_0 inner_right_1
                inner_top_0 inner_top_1 inner_top_2'
    fixed_temperature_boundary<<<{"description": "The list of boundary IDs from the mesh with fixed temperatures."}>>> = 'inner_bottom_0 inner_bottom_1'
    fixed_boundary_temperatures<<<{"description": "The temperatures of the fixed boundary."}>>> = '1200 1200'
    adiabatic_boundary<<<{"description": "The list of boundary IDs from the mesh that are adiabatic."}>>> = 'inner_top_0 inner_top_1 inner_top_2'
    emissivity<<<{"description": "Emissivities for each boundary."}>>> = '0.9 0.9
                  0.8 0.8
                  0.4 0.4
                  1 1 1'
    temperature<<<{"description": "The coupled temperature variable."}>>> = temperature
    view_factor_object_name<<<{"description": "Name of the ViewFactor userobjects."}>>> = view_factor
    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."}>>> = 'NONLINEAR'
  []

  [view_factor]
    type = UnobstructedPlanarViewFactor<<<{"description": "Computes the view factors for planar faces in unubstructed radiative heat transfer.", "href": "../userobjects/UnobstructedPlanarViewFactor.html"}>>>
    boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'inner_bottom_0 inner_bottom_1
                inner_left_0 inner_left_1
                inner_right_0 inner_right_1
                inner_top_0 inner_top_1 inner_top_2'
    normalize_view_factor<<<{"description": "Determines if view factors are normalized to sum to one (consistent with their definition)."}>>> = 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'
  []
[]

[LinearFVBCs<<<{"href": "../../syntax/LinearFVBCs/index.html"}>>>]
  [left]
    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": "LinearFVAdvectionDiffusionFunctorDirichletBC.html"}>>>
    variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = temperature
    boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'left'
    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."}>>> = 600.
  []
  [right]
    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": "LinearFVAdvectionDiffusionFunctorDirichletBC.html"}>>>
    variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = temperature
    boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'right'
    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."}>>> = 300.
  []

  [radiation]
    type = LinearFVGrayLambertBC<<<{"description": "Applies a surface-to-surface Gray-Lambert radiation heat flux boundary condition to a linear finite-volume energy equation.", "href": "LinearFVGrayLambertBC.html"}>>>
    variable<<<{"description": "The name of the variable that this boundary condition applies to"}>>> = temperature
    temperature_radiation<<<{"description": "Temperature functor used to reconstruct the local surface emission. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = temperature
    coeff_diffusion<<<{"description": "Diffusion coefficient used by the corresponding LinearFVDiffusion kernel. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 5.
    surface_radiation_object_name<<<{"description": "Name of the GrayLambertSurfaceRadiationBase UO"}>>> = gray_lambert
    boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = 'inner_left_0 inner_left_1
                inner_right_0 inner_right_1'
  []
[]

[Executioner<<<{"href": "../../syntax/Executioner/index.html"}>>>]
  type = Steady
  petsc_options_iname = '-energy_system_pc_type -energy_system_pc_factor_shift_type -snes_linesearch_damping'
  petsc_options_value = 'hypre boomeramg 0.8'
  l_abs_tol = 1e-10
  l_tol = 1e-10
  multi_system_fixed_point=true
  multi_system_fixed_point_convergence=linear
  multi_system_fixed_point_relaxation_factor = 0.5

  [Quadrature<<<{"href": "../../syntax/Executioner/Quadrature/index.html"}>>>]
    side_order<<<{"description": "Order of the quadrature for sides"}>>> = SECOND
  []

[]

[Convergence<<<{"href": "../../syntax/Convergence/index.html"}>>>]
  [linear]
    type = IterationCountConvergence<<<{"description": "Checks the iteration count.", "href": "../convergence/IterationCountConvergence.html"}>>>
    max_iterations<<<{"description": "Maximum number of iterations"}>>> = 100
    converge_at_max_iterations<<<{"description": "Converge at 'max_iterations' instead of diverging"}>>> = true
  []
[]

[Outputs<<<{"href": "../../syntax/Outputs/index.html"}>>>]
  exodus<<<{"description": "Output the results using the default settings for Exodus output."}>>> = true
[]
(moose/modules/heat_transfer/test/tests/radiation_transfer_action/radiative_transfer_no_action_linearfv_steady.i)

The boundary names supplied to LinearFVGrayLambertBC must also participate in the referenced Gray-Lambert surface-radiation user object. A boundary face may match only one boundary listed for a given LinearFVGrayLambertBC object; overlapping boundary restrictions are not currently supported.

Input Parameters

  • boundaryThe list of boundary IDs from the mesh where this object applies

    C++ Type:std::vector<BoundaryName>

    Controllable:No

    Description:The list of boundary IDs from the mesh where this object applies

  • coeff_diffusionDiffusion coefficient used by the corresponding LinearFVDiffusion kernel. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number.

    C++ Type:MooseFunctorName

    Unit:(no unit assumed)

    Controllable:No

    Description:Diffusion coefficient used by the corresponding LinearFVDiffusion kernel. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number.

  • surface_radiation_object_nameName of the GrayLambertSurfaceRadiationBase UO

    C++ Type:UserObjectName

    Controllable:No

    Description:Name of the GrayLambertSurfaceRadiationBase UO

  • temperature_radiationTemperature functor used to reconstruct the local surface emission. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number.

    C++ Type:MooseFunctorName

    Unit:(no unit assumed)

    Controllable:No

    Description:Temperature functor used to reconstruct the local surface emission. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number.

  • variableThe name of the variable that this boundary condition applies to

    C++ Type:LinearVariableName

    Unit:(no unit assumed)

    Controllable:No

    Description:The name of the variable that this boundary condition applies to

Required Parameters

  • reconstruct_emissionTrueFlag to apply constant heat flux on sideset or reconstruct emission by T^4 law.

    Default:True

    C++ Type:bool

    Controllable:No

    Description:Flag to apply constant heat flux on sideset or reconstruct emission by T^4 law.

Optional Parameters

  • absolute_value_vector_tagsThe tags for the vectors this residual object should fill with the absolute value of the residual contribution

    C++ Type:std::vector<TagName>

    Controllable:No

    Description:The tags for the vectors this residual object should fill with the absolute value of the residual contribution

  • extra_matrix_tagsThe extra tags for the matrices this Kernel should fill

    C++ Type:std::vector<TagName>

    Controllable:No

    Description:The extra tags for the matrices this Kernel should fill

  • extra_vector_tagsThe extra tags for the vectors this Kernel should fill

    C++ Type:std::vector<TagName>

    Controllable:No

    Description:The extra tags for the vectors this Kernel should fill

  • matrix_onlyFalseWhether this object is only doing assembly to matrices (no vectors)

    Default:False

    C++ Type:bool

    Controllable:No

    Description:Whether this object is only doing assembly to matrices (no vectors)

  • matrix_tagssystemThe tag for the matrices this Kernel should fill

    Default:system

    C++ Type:MultiMooseEnum

    Options:nontime, system

    Controllable:No

    Description:The tag for the matrices this Kernel should fill

  • vector_tagsrhsThe tag for the vectors this Kernel should fill

    Default:rhs

    C++ Type:MultiMooseEnum

    Options:rhs, time

    Controllable:No

    Description:The tag for the vectors this Kernel should fill

Contribution To Tagged Field Data Parameters

  • control_tagsAdds user-defined labels for accessing object parameters via control logic.

    C++ Type:std::vector<std::string>

    Controllable:No

    Description:Adds user-defined labels for accessing object parameters via control logic.

  • enableTrueSet the enabled status of the MooseObject.

    Default:True

    C++ Type:bool

    Controllable:Yes

    Description:Set the enabled status of the MooseObject.

  • implicitTrueDetermines whether this object is calculated using an implicit or explicit form

    Default:True

    C++ Type:bool

    Controllable:No

    Description:Determines whether this object is calculated using an implicit or explicit form

  • search_methodnearest_node_connected_sidesChoice of search algorithm. All options begin by finding the nearest node in the primary boundary to a query point in the secondary boundary. In the default nearest_node_connected_sides algorithm, primary boundary elements are searched iff that nearest node is one of their nodes. This is fast to determine via a pregenerated node-to-elem map and is robust on conforming meshes. In the optional all_proximate_sides algorithm, primary boundary elements are searched iff they touch that nearest node, even if they are not topologically connected to it. This is more CPU-intensive but is necessary for robustness on any boundary surfaces which has disconnections (such as Flex IGA meshes) or non-conformity (such as hanging nodes in adaptively h-refined meshes).

    Default:nearest_node_connected_sides

    C++ Type:MooseEnum

    Options:nearest_node_connected_sides, all_proximate_sides

    Controllable:No

    Description:Choice of search algorithm. All options begin by finding the nearest node in the primary boundary to a query point in the secondary boundary. In the default nearest_node_connected_sides algorithm, primary boundary elements are searched iff that nearest node is one of their nodes. This is fast to determine via a pregenerated node-to-elem map and is robust on conforming meshes. In the optional all_proximate_sides algorithm, primary boundary elements are searched iff they touch that nearest node, even if they are not topologically connected to it. This is more CPU-intensive but is necessary for robustness on any boundary surfaces which has disconnections (such as Flex IGA meshes) or non-conformity (such as hanging nodes in adaptively h-refined meshes).

Advanced Parameters