Computing Line Integrals

The Ray Tracing Module can be utilized to integrate fields along a line throughout the domain. Example fields include Variables, AuxVariables, Material properties, and Functions.

The discussion that follows will describe how to integrate a variable across a line in a simple diffusion problem. To integrate other fields, the process remains the same except for the definition of the RayKernel.

Problem Definition

We begin with the standard "simple diffusion" problem:

[Mesh<<<{"href": "../../../syntax/Mesh/index.html"}>>>]
  [gmg]
    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"}>>> = 5
    ny<<<{"description": "Number of elements in the Y direction"}>>> = 5
    xmax<<<{"description": "Upper X Coordinate of the generated mesh"}>>> = 5
    ymax<<<{"description": "Upper Y Coordinate of the generated mesh"}>>> = 5
  []
[]

[Variables<<<{"href": "../../../syntax/Variables/index.html"}>>>/u]
[]

[Kernels<<<{"href": "../../../syntax/Kernels/index.html"}>>>/diff]
  type = Diffusion<<<{"description": "The Laplacian operator ($-\\nabla \\cdot \\nabla u$), with the weak form of $(\\nabla \\phi_i, \\nabla u_h)$.", "href": "../../../source/kernels/Diffusion.html"}>>>
  variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = u
[]

[BCs<<<{"href": "../../../syntax/BCs/index.html"}>>>]
  [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"}>>> = u
    boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = left
    value<<<{"description": "Value of the BC"}>>> = 0
  []
  [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"}>>> = u
    boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = right
    value<<<{"description": "Value of the BC"}>>> = 1
  []
[]

[Executioner<<<{"href": "../../../syntax/Executioner/index.html"}>>>]
  type = Steady
  solve_type = 'PJFNK'
  petsc_options_iname = '-pc_type -pc_hypre_type'
  petsc_options_value = 'hypre boomeramg'
[]
(moose/modules/ray_tracing/test/tests/raykernels/variable_integral_ray_kernel/simple_diffusion_line_integral.i)

For this problem, we seek the value of the integrals (where is the finite-element solution)

and

in which we will denote the first line, , as diag and the second, , as right_up for simplicity.

Note that the integral along the second line, , is trivial due to the Dirichlet boundary condition,

which implies

Defining the Study

A RepeatableRayStudy is defined that generates and executes the rays that compute the variable line integral:

[UserObjects<<<{"href": "../../../syntax/UserObjects/index.html"}>>>/study]
  type = RepeatableRayStudy<<<{"description": "A ray tracing study that generates rays from vector of user-input start points and end points/directions.", "href": "../../../source/userobjects/RepeatableRayStudy.html"}>>>
  names<<<{"description": "Unique names for the Rays"}>>> = 'diag
           right_up'
  start_points<<<{"description": "The points to start Rays from"}>>> = '0 0 0
                  5 0 0'
  end_points<<<{"description": "The points where Rays should end. Use either this parameter or the directions parameter, but not both!"}>>> = '5 5 0
                5 5 0'

  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."}>>> = TIMESTEP_END

  # Needed to cache trace information for RayTracingMeshOutput
  # always_cache_traces = true
  # Needed to cache Ray data for RayTracingMeshOutput
  # data_on_cache_traces = true
[]
(moose/modules/ray_tracing/test/tests/raykernels/variable_integral_ray_kernel/simple_diffusion_line_integral.i)

The study object defines two rays to be executed on TIMESTEP_END:

  • diag from to

  • right_up from to

Defining the RayKernel

RayKernels are objects that are executed on the segments of the rays. In this case, we wish to compute the integral of a variable so we will define a VariableIntegralRayKernel:

[RayKernels<<<{"href": "../../../syntax/RayKernels/index.html"}>>>/u_integral]
  type = VariableIntegralRayKernel<<<{"description": "Integrates a Variable or AuxVariable along a Ray.", "href": "../../../source/raykernels/VariableIntegralRayKernel.html"}>>>
  variable<<<{"description": "The name of the variable to integrate"}>>> = u
[]
(moose/modules/ray_tracing/test/tests/raykernels/variable_integral_ray_kernel/simple_diffusion_line_integral.i)

The u_integral VariableIntegralRayKernel will accumulate the variable line integral of the u Variable for our defined rays, diag and right_up.

commentnote

Integral Output

Lastly, we need to obtain the accumulated integrals from the study. We will utilize a RayIntegralValue Postprocessor to achieve this:

[Postprocessors<<<{"href": "../../../syntax/Postprocessors/index.html"}>>>]
  [diag_line_integral]
    type = RayIntegralValue<<<{"description": "Obtains the integrated value accumulated into a Ray from an IntegralRayKernel-derived class.", "href": "../../../source/postprocessors/RayIntegralValue.html"}>>>
    ray_kernel<<<{"description": "The name of the IntegralRayKernel-derived RayKernel to obtain the integral value of"}>>> = u_integral
    ray<<<{"description": "Name of the Ray to get the final integral value from"}>>> = diag
  []
  [right_up_line_integral]
    type = RayIntegralValue<<<{"description": "Obtains the integrated value accumulated into a Ray from an IntegralRayKernel-derived class.", "href": "../../../source/postprocessors/RayIntegralValue.html"}>>>
    ray_kernel<<<{"description": "The name of the IntegralRayKernel-derived RayKernel to obtain the integral value of"}>>> = u_integral
    ray<<<{"description": "Name of the Ray to get the final integral value from"}>>> = right_up
  []
[]
(moose/modules/ray_tracing/test/tests/raykernels/variable_integral_ray_kernel/simple_diffusion_line_integral.i)

The accumulated integrals are seen in output:


Postprocessor Values:
+----------------+--------------------+------------------------+
| time           | diag_line_integral | right_up_line_integral |
+----------------+--------------------+------------------------+
|   0.000000e+00 |       0.000000e+00 |           0.000000e+00 |
|   1.000000e+00 |       3.535534e+00 |           5.000000e+00 |
+----------------+--------------------+------------------------+

Segment-wise Integral Output

The segment-wise accumulated integral can also be outputted in a mesh format using the RayTracingMeshOutput. For more information, see Example.