Skip to content

Postprocessing Capabilities

Tim Wildey edited this page Jan 11, 2025 · 10 revisions

Extracting meaningful data from a simulation to provide insights to a user is critical if the computational model is to be used for anything meaningful. MrHyDE provides a variety of mechanisms for extracting data from the simulation as it is running, i.e., without requiring the state solution to be stored throughout the simulation. These capabilities are described in the following sections

Visualization

As previously mentioned, MrHyDE uses the Exodus data format for both mesh import and for data export. The Panzer STK interface is the primary mechanism for writing data to an Exodus file. By default, this output is stored in output.exo, but this file name can be changed by modifying the appropriate option in the “Postprocess” sublist in the input file:

Postprocess:
  write solution: true # default is false
  output file: output # .exo gets added automatically

The exodus file can contain arbitrary data on the nodes of the mesh, which get linearly interpolated in the volume of the element, or at the cell-centers, which are represented as piecewise constants over the mesh. While nodal interpolations are well-suited for the solutions that use the lowest order HGRAD basis functions, they are less appropriate for most of the other discretizations. For now, MrHyDE only plots the cell average for the solutions that use HDIV, HCURL, HVOL and HFACE basis functions. Exodus and STK have recently added the ability to visualize both edge and face data, but this is not enabled in MrHyDE yet. If visualization is enabled, then several cell and nodal fields are added automatically, e.g., the state variables, the cell number, the processor number, etc. The one type of variable that is not automatically added is HFACE. These are more expensive to compute, so the user needs to explicitly request this feature using:

Postprocess:
  write solution: true # default is false
  write HFACE variables: true

While the data that can be visualized at the nodes is quite limited, there is virtually no limit on the data that can be visualized at the cell centers. This is because MrHyDE can evaluate arbitrary functions at the volumetric integration points, through the function manager, and taking the cell-average of these quantities is trivial. To visualize arbitrary functions, one simply needs to add these functions in the “Extra cell fields” sublist within the “Postprocess” sublist:

Postprocess:
  write solution: true # default is false
  Extra cell fields:
    ex: sin(pi*x)+2.0*grad(e)[x]

In principle, anything that is composed of leafs, or basic building blocks that the function manager is aware of, can be visualized at the cell centers.

The default behavior is to output to the Exodus file after every time step. For some problems, this is too much data, so there is an option to only output every 𝑃 time steps:

Postprocess:
  write solution: true # default is false
  write frequency: 10

where here we have set $P=10$.

Verification

Solution verification is a critical component of V&V and MrHyDE provides the ability to perform solution verification using arbitrary analytical functions. Performing solution verification is enabled by setting:

Postprocess:
  compute errors: true # default is false

However, this won’t actually compute anything since the user also needs to provide true solutions to compare against. MrHyDE automatically selects the solutions and norms based on the user-provided true solutions within the Postprocess sublist. For vector variables, we use rectangular brackets to denote specific components. For example, if B is a vector variable, one can compute the vector $L^2$ norm by defining true solutions for B[x], B[y], B[z]. Similarly, the error for the divergence of B or the curl of B can be enabled by defining true solutions for div(B), or any of curl(B)[x], curl(B)[y] or curl(B)[z]. For example, providing:

Postprocess: 
    compute errors: true
    True solutions:
      e: sin(2*pi*x)*sin(2*pi*y)
      e face: sin(2*pi*x)*sin(2*pi*y)
      'grad(e)[x]': 2*pi*cos(2*pi*x)*sin(2*pi*y)
      'grad(e)[y]': 2*pi*sin(2*pi*x)*cos(2*pi*y)

will tell MrHyDE to compute the L2 norm of the error:

$$ \lVert e-e_{\text{true}} \rVert_{L^2} = \left( \int_{\Omega} \left( e - \sin(2\pi x) \sin(2\pi y) \right)^2\ dx \right)^{1/2}$$

the L2 norm of the error in the gradient:

$$ \lVert \nabla e - \nabla e_{\text{true}} \rVert_{L^2} = \left( \int_{\Omega} \left( \frac{\partial e}{\partial x} - 2\pi \cos(2\pi x) \sin(2\pi y) \right)^2 + \left( \frac{\partial e}{\partial y} - 2\pi \sin(2\pi x) \cos(2\pi y) \right)^2\ dx \right)^{1/2} $$

and the L2-face norm of the error in the solution:

$$ \lVert e-e_{\text{true}} \rVert_{L^2(E_h)} = \left( \sum_{T\in T_h} \sum_{\gamma \in \partial T}\frac{1}{2|\gamma|}\int_{\gamma} \left( e - \sin(2\pi x) \sin(2\pi y) \right)^2\ dx \right)^{1/2} $$

where $T_h$ is a mesh, $E_h$ is the skeleton of the mesh, and $|\gamma|$ is the measure of the face denoted by $\gamma$. The factor of $1/2$ is to account for the fact that each face/edge on the interior of the mesh is counted twice.

Computing the norm of the error in the gradient is enabled by defining true solutions for each of the components of the gradient. MrHyDE will throw an error if only a subset of the components are given true solutions. MrHyDE will also throw an error if an improper request is made, e.g., providing expressions for the true curl of a solution that does not use an HCURL basis.

Generating Responses and Other Data

In general, the postprocess manager is responsible for taking a state solution at the end of each time step and extracting the necessary information from it before it is removed from memory (MrHyDE does not store the state over time unless necessary). This includes visualization and verification as described above, but one often wants to extract a small number of QoI from the state vector for various purposes. MrHyDE has two types of responses: integrated and pointwise (sensors).

Integrated Responses

In MrHyDE, there are actually several ways to compute an integrated response. This simplest way is to reuse the optimization objective function and store the response function it utilizes. This approach makes it easy to then perform optimization on the same quantities. To enable this, one needs to define an objective function and ask it to save the response values:

Postprocess:
    compute objective: true
    compute sensitivities: false
    Objective functions:
      obj0:
        type: integrated response
        response: 'e'
        save response data: true
        weight: 0.0625

Note that in this case, the objective

Sensor Responses

Sensors are simply pointwise evaluations of user-defined functions, objective functions or solution fields. It is up to the user to use caution in the proper use of pointwise quantities, as the solution may not possess sufficient regularity for such quantities to be well-defined and converge properly as the mesh is refined. There are three ways to generate the physical locations for sensors:

  • Exodus Import: If the Exodus file contains sensors, then these can be imported automatically. This is rarely used and may not be tested very well.
  • Grid: If the sensors can be defined on a uniform grid, then the grid bounds and spacings are sufficient to specify the sensor locations.
  • Text File: For arbitrary point clouds, use the text input file format. The file should contain only the physical locations of each sensor. Format is $N\times d$, where $N$ is the number of points and $d$ is the spatial dimension.

Similar to integrated responses, the easiest way to generate sensor response data is to go through the optimization objective functions. In this case we would define:

Postprocess: 
    response type: pointwise
    verification: compute errors
    write solution: false
    compute objective: false
    compute responses: true
    Objective functions:
      objgrad:
        type: sensors
        sensor points file: sensor_points.dat
        save sensor data: true
        response: '(grad(e)[x])^2 + (grad(e)[y])^2'
        weight: 1.0
      objval:
        type: sensors
        sensor points file: sensor_points.dat
        save sensor data: true
        response: 'e'
        weight: 1.0
Clone this wiki locally