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 the entire domain 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
)");
- Note
- The NonTensorComputeTags are intended to be used for Variables compute tags like Tags::DerivCompute
- 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.
- 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.