SpECTRE  v2026.09.05
Loading...
Searching...
No Matches
Events::ObserveNorms< ObservableTensorTagsList, NonTensorComputeTagsList, ArraySectionIdTag, OptionName > Class Template Reference

Compute norms of tensors in the DataBox and write them to disk. More...

Detailed Description

template<typename ObservableTensorTagsList, typename NonTensorComputeTagsList = tmpl::list<>, typename ArraySectionIdTag = void, typename OptionName = void>
class Events::ObserveNorms< ObservableTensorTagsList, NonTensorComputeTagsList, ArraySectionIdTag, OptionName >

Compute norms of tensors in the DataBox and write them to disk.

The L1 norm is computed as the mean absolute value, so

\begin{align*}L_1(u)=\frac{1}{N}\sum_{i=0}^{N-1} |u_i| \end{align*}

where \(N\) is the number of grid points.

The L2 norm is computed as the RMS, so

\begin{align*}L_2(u)=\sqrt{\frac{1}{N}\sum_{i=0}^{N-1} u_i^2} \end{align*}

The norm can be taken for each individual component, or summed over components. For the max/min it is then the max/min over all components, while for the L1 norm we have (for a 3d vector, 2d and 1d are similar)

\begin{align*}L_1(v^k)=\frac{1}{N}\sum_{i=0}^{N-1} \left[|v^x_i| + |v^y_i| + |v^z_i|\right] \end{align*}

and for the L2 norm

\begin{align*}L_2(v^k)=\sqrt{\frac{1}{N}\sum_{i=0}^{N-1} \left[(v^x_i)^2 + (v^y_i)^2 + (v^z_i)^2\right]} \end{align*}

The L1 integral norm is:

\begin{equation}L_{1,\mathrm{int}}(v^k) = \frac{1}{V}\int_\Omega \left[ |v^x_i| + |v^y_i| + |v^z_i|\right] \mathrm{d}V \end{equation}

The L2 integral norm is:

\begin{equation}L_{2,\mathrm{int}}(v^k) = \sqrt{\frac{1}{V}\int_\Omega \left[ (v^x_i)^2 + (v^y_i)^2 + (v^z_i)^2\right] \mathrm{d}V} \end{equation}

where \(V=\int_\Omega\) is the volume of all observed elements in inertial coordinates.

VolumeIntegral only computes the volume integral without any normalization.

Here is an example of an input file:

R"(
ObserveNorms:
SubfileName: reduction0
TensorsToObserve:
- Name: Var0
NormType: Max
Components: Individual
- Name: Var1
NormType: Min
Components: Individual
- Name: Var0
NormType: Max
Components: Sum
- Name: Var0TimesTwo
NormType: Max
Components: Individual
- Name: Var0TimesThree
NormType: Max
Components: Individual
- Name: Var1
NormType: L1Norm
Components: Sum
- Name: Var1
NormType: L1IntegralNorm
Components: Sum
- Name: Var1
NormType: L2Norm
Components: Sum
- Name: Var1
NormType: L2IntegralNorm
Components: Sum
- Name: Var1
NormType: VolumeIntegral
Components: Sum
- Name: Var1
NormType: L1Norm
Components: Individual
- Name: Var1
NormType: L1IntegralNorm
Components: Individual
- Name: Var1
NormType: L2Norm
Components: Individual
- Name: Var1
NormType: L2IntegralNorm
Components: Individual
- Name: Var1
NormType: VolumeIntegral
Components: Individual
- Name: Var1
NormType: Min
Components: Sum
BlocksToObserve: All
ReductionScope: WholeDomain
)");
Note
The NonTensorComputeTags are intended to be used for Variables compute tags like Tags::DerivCompute
Observing a subset of blocks
The BlocksToObserve option restricts the observation to the listed blocks and block groups. Set it to All to observe the whole domain. The number of points, volume, and all norms are then computed over the observed elements only.
Reduction scope
The ReductionScope option (see Events::ReductionScope) controls whether the observed elements are reduced together or split up by block:
  • WholeDomain: a single reduction over all observed elements, written to the subfile <SubfileName>.dat.
  • ByBlock: a separate reduction for each observed block, written to <SubfileName>/<BlockName>.dat. Block groups listed in BlocksToObserve are expanded to their blocks.
  • ByBlockOrGroup: a separate reduction for each entry of BlocksToObserve, written to <SubfileName>/<BlockOrGroupName>.dat. A block group is reduced as a whole. Since each element contributes to only one reduction, the entries must not overlap (e.g. a group and one of its blocks). When BlocksToObserve is All this is the same as ByBlock.

To observe norms both over the whole domain and per block, add two ObserveNorms events with different SubfileNames, one with ReductionScope: WholeDomain and one with ReductionScope: ByBlock.

Array sections
This event supports sections (see Parallel::Section). Set the ArraySectionIdTag template parameter to split up observations into subsets of elements. The observers::Tags::ObservationKey<ArraySectionIdTag> must be available in the DataBox. It identifies the section and is used as a suffix for the path in the output file. When combined with a ReductionScope other than WholeDomain, the per-block subfiles are placed in the group <SubfileName><SectionSuffix>/.
Option name
The OptionName template parameter is used to give the event a name in the input file. If it is not specified, the name defaults to "ObserveNorms". If you have multiple ObserveNorms events in the input file, you must specify a unique name for each one. This can happen, for example, if you want to observe norms the full domain and also over a section of the domain.

The documentation for this class was generated from the following file:
  • src/ParallelAlgorithms/Events/ObserveNorms.hpp