From 6fe04532287c7dc9c5441729927b483f1e841eb4 Mon Sep 17 00:00:00 2001
From: Florian Atteneder <florian.atteneder@uni-jena.de>
Date: Wed, 7 Aug 2024 15:24:31 +0000
Subject: [PATCH] dg1d: add lazy integrator
 (https://git.tpi.uni-jena.de/dg/dg1d.jl/-/merge_requests/198)

I am surprised that I did not need this before.

This is intentionally a hacky implementation as I just need that for the thesis right now.

---

This also implements
- the total rest-mass computation for the GRHD project as a first application,
- adds helper functions for the `Output` struct to read all data at once.
---
 src/GRHD/GRHD.jl                              |  12 ++++++
 src/GRHD/callbacks.jl                         |  25 ++++++++++++
 src/GRHD/initialdata.jl                       |  10 +++++
 src/GRHD/setup.jl                             |   7 ++++
 src/glgl.jl                                   |  14 +++++++
 src/lgl.jl                                    |   8 ++++
 src/mesh.jl                                   |  31 +++++++++++++++
 src/output.jl                                 |  31 +++++++++++++--
 src/spectralelement.jl                        |  11 ++++++
 .../grhd_bondi_accretion.toml                 |  37 +++++++++---------
 .../refs/grhd_bondi_accretion/output0d.h5     | Bin 22082 -> 25300 bytes
 .../refs/grhd_bondi_accretion/output1d.h5     | Bin 180568 -> 182104 bytes
 test/IntegrationTests/refs/testconfig.toml    |   2 +-
 13 files changed, 166 insertions(+), 22 deletions(-)

diff --git a/src/GRHD/GRHD.jl b/src/GRHD/GRHD.jl
index b4c8c6c7..f5c63495 100644
--- a/src/GRHD/GRHD.jl
+++ b/src/GRHD/GRHD.jl
@@ -292,6 +292,18 @@ dg1d.@parameters GRHD begin
   """
   freeze_vars = String[]
 
+  """
+  List of 0d variables to analyze during simulations.
+  Variable names enequeued here become available for `Output.variables0d`.
+
+  Available variables:
+  - `Mtot`: Total restmass density, Mtot = ∫ √(γ) D dΩ.
+  """
+  variables0d_analyze = String[]
+  @check variables0d_analyze isa Vector{String}
+  @check allunique(variables0d_analyze)
+  @check variables0d_analyze ⊂ ["Mtot"]
+
   """
   If `true` then the doublecartoon derivative terms are not accounted for in the source terms.
   This appears to be necessary in order to perform TOV star simulations with the doublecartoon
diff --git a/src/GRHD/callbacks.jl b/src/GRHD/callbacks.jl
index 265baf3e..1b302c14 100644
--- a/src/GRHD/callbacks.jl
+++ b/src/GRHD/callbacks.jl
@@ -21,6 +21,12 @@ function make_callback(env, P)
                                                  CallbackTiming(every_iteration=1,every_dt=0))
     push!(callbackset, cb)
   end
+  if !isempty(P.prmsdb["GRHD"]["variables0d_analyze"])
+    cbfn_analyzed0d(u, t)     = callback_analyze0d(env, P, env.mesh)
+    cb                        = FunctionCallback(cbfn_analyzed0d,
+                                                 CallbackTiming(every_iteration=1,every_dt=0))
+    push!(callbackset, cb)
+  end
   return callbackset
 end
 
@@ -475,3 +481,22 @@ function callback_analyze1d_error(env, P, mesh::Mesh1d)
     @. v_err = v .- v_ref
   end
 end
+
+
+callback_analyze0d(env, P::Project, mesh) = TODO()
+function callback_analyze0d(env, P::Project{:spherical1d}, mesh::Mesh1d)
+  vars = P.prmsdb["GRHD"]["variables0d_analyze"]
+  if "Mtot" in vars
+    @unpack D = get_dynamic_variables(mesh)
+    @unpack γrr, γθθ, γϕϕ, r = get_static_variables(mesh)
+    @unpack Mtot = get_global_variables(mesh)
+    Mtot .= dg1d.integrate(mesh) do i
+      D[i] * sqrt(γrr[i]*γθθ[i]*γϕϕ[i]) * 4*π
+    end
+    if dg1d.is_domain_symmetric(mesh)
+      # in this case we integrated the sphere twice, so halving the result
+      # should correspond to an averaging of the integral from either side
+      Mtot ./= 2
+    end
+  end
+end
diff --git a/src/GRHD/initialdata.jl b/src/GRHD/initialdata.jl
index 5268e247..46a93144 100644
--- a/src/GRHD/initialdata.jl
+++ b/src/GRHD/initialdata.jl
@@ -841,6 +841,16 @@ function initialdata_equation!(::Val{:tov}, env, P::Project{:spherical1d}, prms)
   @. init_ρ     = ρ
   @. init_ϵ     = ϵ
 
+  Mtot = dg1d.integrate(mesh) do i
+    v = D[i] * sqrt(γrr[i]*γθθ[i]*γϕϕ[i]) * 4*π
+    v
+  end
+  if dg1d.is_domain_symmetric(mesh)
+    Mtot /= 2
+  end
+  Madm = data.M
+  @show Mtot, Madm
+
 end
 
 
diff --git a/src/GRHD/setup.jl b/src/GRHD/setup.jl
index f7e18af8..6e85e21a 100644
--- a/src/GRHD/setup.jl
+++ b/src/GRHD/setup.jl
@@ -481,6 +481,9 @@ function register_analysis!(mesh::Mesh1d, P)
       static_variablenames = (:c2p_reset_ϵ, :c2p_reset_atm, :c2p_limit_vr,
                               :c2p_freeze_atm, :c2p_init_admissible, :v)
   )
+  if "Mtot" in P.prmsdb["GRHD"]["variables0d_analyze"]
+    register_variables!(mesh, global_variablenames = (:Mtot,))
+  end
 end
 function register_analysis!(mesh::Mesh2d, P)
   register_variables!(mesh,
@@ -488,6 +491,10 @@ function register_analysis!(mesh::Mesh2d, P)
                               :c2p_freeze_atm, :c2p_init_admissible, :v,
                               :buf_c2p_reset_atm,)
   )
+  if "Mtot" in P.prmsdb["GRHD"]["variables0d_analyze"]
+    TODO()
+    register_variables!(mesh, global_variablenames = (:Mtot,))
+  end
 end
 
 
diff --git a/src/glgl.jl b/src/glgl.jl
index 11198584..980b8e92 100644
--- a/src/glgl.jl
+++ b/src/glgl.jl
@@ -62,6 +62,20 @@ function integrate(w, v, D, f)
 
   return sum
 end
+function integrate(w, v, D, fn::Function, idxs::AbstractVector{<:Integer})
+
+  N = length(w)
+  @toggled_assert (N,N) == size(D)
+  @toggled_assert N == length(idxs)
+
+  sum = 0.0
+  for i in 1:N
+    fi = fn(idxs[i])
+    sum += (w[i] + v * (D[1,i] - D[N,i])) * fi
+  end
+
+  return sum
+end
 
 
 function integrate(w, v, D, f1, f2)
diff --git a/src/lgl.jl b/src/lgl.jl
index 4c009eac..493d7f4b 100644
--- a/src/lgl.jl
+++ b/src/lgl.jl
@@ -30,6 +30,14 @@ function integrate(w, f)
   @toggled_assert length(w) == length(f)
   return dot(w, f)
 end
+function integrate(w, f::Function, idxs::AbstractVector{<:Integer})
+  @toggled_assert length(w) == length(idxs)
+  sum = 0.0
+  for i in 1:length(w)
+    sum += w[i] * f(idxs[i])
+  end
+  return sum
+end
 
 
 function integrate(w, f, g)
diff --git a/src/mesh.jl b/src/mesh.jl
index c86989cf..75ed9541 100644
--- a/src/mesh.jl
+++ b/src/mesh.jl
@@ -9,6 +9,7 @@ abstract type AbstractMesh end
 struct Mesh{Element,N_Dim,N_Sides} <: AbstractMesh
   tree::Tree{N_Dim,N_Sides} # abstract representation of mesh
   boxes::Vector{Box{N_Dim}} # physical extends of each cell
+  # TODO Fix spelling extends -> extents
   extends::NTuple{N_Dim,Tuple{Float64,Float64}} # total extend of mesh
   element::Element
   cache::Cache
@@ -286,6 +287,11 @@ function isperiodic(m::Mesh)
   return all(m.tree.periodic)
 end
 
+is_domain_symmetric(m::Mesh) = TODO()
+function is_domain_symmetric(m::Mesh1d)
+  (Lmin, Lmax), = m.extends
+  return Lmin ≈ -Lmax
+end
 
 Base.broadcastable(mesh::Mesh) = Ref(mesh)
 
@@ -389,6 +395,31 @@ function integrate_cell(u, k, mesh::Mesh2d)
 end
 
 
+function integrate(fn::Function, mesh::Mesh1d{SpectralElement})
+  @unpack invdetJ = get_static_variables(mesh)
+  Npts, K = layout(mesh)
+  mat_invdetJ = vreshape(invdetJ, (Npts,K))
+  integral = 0.0
+  for k in 1:K
+    idxs = cellindices(mesh, k)
+    integral += integrate(fn, idxs, mesh.element) / mat_invdetJ[first(idxs)]
+  end
+  return integral
+end
+function integrate(fn::Function, mesh::Mesh1d{FVElement})
+  L, = widths(mesh)
+  K, = mesh.tree.dims
+  @assert K >= 2
+  dL = L/K
+  integral = 0.0
+  fk, fkp1 = fn(1), fn(2)
+  for k in 1:K-1
+    integral += (fk+fkp1)*dL/2
+    fk, fkp1 = fkp1, fn(k+1)
+  end
+  return integral
+end
+
 function integrate_fv_central(integrand::Function, δu, uavg, mesh::Mesh{<:FVElement})
   # assume vanilla FV method so that solution in jth cell [x_(j-1/2),x_(j+1/2)] can
   # be approximated by
diff --git a/src/output.jl b/src/output.jl
index ee47f383..79150b42 100644
--- a/src/output.jl
+++ b/src/output.jl
@@ -61,7 +61,7 @@ Base.length(o::Output) = length(o.times)
 has_variable(o::Output, variable) = variable in o.variables
 
 
-function _smart_read_variable!(storage, h5_data)
+function _smart_read_variable!(storage::AbstractArray{<:Number}, h5_data)
   # figure out compatibility between storage and data
   size_data      = size(h5_data)
   ndims_data     = ndims(h5_data)
@@ -131,7 +131,7 @@ Similar to `read_variable`, but instead read data into `storage`.
 This read is smart in the sense that it recognizes the shape of the `storage` and reads
 the data accordingly.
 """
-function read_variable!(storage, o::Output, variable::AbstractString, t::Real)
+function read_variable!(storage::AbstractArray{<:Number}, o::Output, variable::AbstractString, t::Real)
   if !has_variable(o, variable)
     error("Output does not contain data for 'variable = $variable'")
   end
@@ -153,7 +153,7 @@ Similar to `read_variable`, but instead read data into `storage`.
 This read is smart in the sense that it recognizes the shape of the `storage` and reads
 the data accordingly.
 """
-function read_variable!(storage, o::Output, variable::AbstractString, index_t::Int)
+function read_variable!(storage::AbstractArray{<:Number}, o::Output, variable::AbstractString, index_t::Int)
   if !has_variable(o, variable)
     error("Output does not contain data for 'variable = $variable'")
   end
@@ -165,3 +165,28 @@ function read_variable!(storage, o::Output, variable::AbstractString, index_t::I
   _smart_read_variable!(storage, h5_variable)
   return
 end
+
+
+function read_variable(o::Output, variable::AbstractString)
+  var1 = read_variable(o, variable, 1)
+  N = length(o.times)
+  allvars = Vector{typeof(var1)}(undef, N)
+  allvars[1] = var1
+  for i in 2:N
+    allvars[i] = read_variable(o, variable, i)
+  end
+  return allvars
+end
+
+
+function read_variable!(storage::AbstractVector{<:AbstractArray{<:Number}}, o::Output,
+                        variable::AbstractString)
+  N = length(o.times)
+  if length(storage) != N
+    resize!(storage, N)
+  end
+  for i in 1:N
+    read_variable!(storage[i], o, variable, i)
+  end
+  return
+end
diff --git a/src/spectralelement.jl b/src/spectralelement.jl
index 76649a75..1fbbf23f 100644
--- a/src/spectralelement.jl
+++ b/src/spectralelement.jl
@@ -111,6 +111,17 @@ end
 end
 
 
+@inline function integrate(fn::Function, idxs::AbstractVector{<:Integer}, el::SpectralElement)
+  @unpack quadr = el
+  @toggled_assert quadr in (:LGL, :LGL_lumped, :GLGL)
+  if quadr === :LGL || quadr === :LGL_lumped
+    return LGL.integrate(el.w, fn, idxs)
+  else # quadr === :GLGL
+    return GLGL.integrate(el.w, el.v, el.D, fn, idxs)
+  end
+end
+
+
 @inline function differentiate(u, el::SpectralElement)
   return el.D * u
 end
diff --git a/test/IntegrationTests/refs/grhd_bondi_accretion/grhd_bondi_accretion.toml b/test/IntegrationTests/refs/grhd_bondi_accretion/grhd_bondi_accretion.toml
index 27ba7b96..91c070ec 100644
--- a/test/IntegrationTests/refs/grhd_bondi_accretion/grhd_bondi_accretion.toml
+++ b/test/IntegrationTests/refs/grhd_bondi_accretion/grhd_bondi_accretion.toml
@@ -1,29 +1,30 @@
 [EquationOfState]
-eos = "polytrope"
-polytrope_k = 0.02143872868864732
 polytrope_gamma = "$(4/3)"
+polytrope_k = 0.02143872868864732
+eos = "polytrope"
+
+[Evolution]
+cfl = 0.2
+tend = 5.0
+
+[Output]
+variables0d = ["D_err_norm", "Mtot"]
+aligned_ts = "$(collect(range(0.5,5.0,step=0.5)))"
+variables1d = ["D_err", "D", "Sr", "τ", "p", "ρ", "ϵ", "vr"]
 
 [GRHD]
-bc = "from_id"
-id = "bondi_accretion"
-id_filename = "$(joinpath(ROOTDIR,\"initialdata\",\"bondi_accretion.h5\"))"
-c2p_enforce_causal_atm = false
 analyze_error_reference_solution = "bondi_accretion"
+id_filename = "$(joinpath(ROOTDIR,\"initialdata\",\"bondi_accretion.h5\"))"
+variables0d_analyze = ["Mtot"]
+id = "bondi_accretion"
 variables0d_analyze_error = ["D"]
 variables1d_analyze_error = ["D"]
+c2p_enforce_causal_atm = false
+bc = "from_id"
 
 [Mesh]
-range = [ 1.8, 10.0 ]
-n = 4
+periodic = false
+range = [1.8, 10.0]
 k = 35
 basis = "lgl"
-periodic = false
-
-[Output]
-variables0d = [ "D_err_norm" ]
-variables1d = [ "D_err", "D", "Sr", "τ", "p", "ρ", "ϵ", "vr" ]
-aligned_ts  = "$(collect(range(0.5,5.0,step=0.5)))"
-
-[Evolution]
-cfl = 0.2
-tend = 5.0
+n = 4
diff --git a/test/IntegrationTests/refs/grhd_bondi_accretion/output0d.h5 b/test/IntegrationTests/refs/grhd_bondi_accretion/output0d.h5
index 9931e08123ca1eec7aeddf3d3b8406eaa683877c..2c258cd6e73e717289c01b4a4a953373f070538d 100644
GIT binary patch
delta 2138
zcmaKte{54#6vywo+q&}T;#(QrQ)XH^7@fe@m94gOd+%+n<*gJQQe%NJI)Vv5R+(fb
zbuk(KWy2rM=JgLlNca(mlaN5uDE-4|X=391*_kDvCT9HQFfrK-F~ooH-Fx45?})Vj
zH0OKIJ?C@JIrqNO4PpLkVXDC)0QP%q{^pP7UMSW)Bk!h5*XcjHFE%2{a<wWK$)o$B
z_ffLRi!O<_nzY9P0P2vP>&8U7<81zN?L~;Z&2`WnMbmp4YOD8-pB|rxp`NJU*b}f@
zfJ9scNgzuFJ38-oijC%e0P-8w3l@?pH!zI`H`&pJXad>o?$z`w+OHc|wfy-=079z+
z*<Kl@*<WMXOL4SgAc=g9)IB$F#~`VLQx5cY*crOzqNxFR60NwIt_Z*iaJ6L9Q8JH^
zZlQvX<~FPA`eW1zOkZ|R{!wbZy{wLFR9a9=uV2%Y<<rWKheMpcq<-+zr$^olj4E@}
z-JJeN^~AwNr$421{}$tPpgp)U7yO|&r8M77aC)^ic=yWf?;ejTwws5sK4~VlYS$h<
z_^`PtrD(IqxD7V#$QShiOIu3m6;E=yq{XY=X=?VQl=)vqIo+<sw!i$<9d}B3_3yVh
zy+K=kcf%pamXz}SpJSY!f1_2bUFjVx$mq+E>&f=P;u@KDP}*vAumHbdOSyqrSl))-
zi>6_jsm2u6ue3pKrB(K#ocKH}wxCP(XW%{FHw%w%#pAGzOq|t2{h!uWd1r1S0^zOg
z1Z9B*!YE^H1Z9z_JW8RRL#ayc1ZZE^8G-lBLhBBOGSgNWWpNil8T1(_N$3Ahp>IEp
zp`*S{C*UKN4C88D1Q$HZcVM-089#>$y`7|TR^B%Y@A(*Rx~np7p&R20E+hm`RgIra
zuq!AY!dDPVEH<W-dI+7&RKA#rUY-uTMCe?+Zx+r38J*r!nJ&{uin*j#DCWcg8iN+o
z!;)d#g?@tTWh#&B3G=w+K7t$IeX}sFF<d!R8CRDHZZTru4x=Td1(tUsSsm&;x0h}N
z;KXc9>W}MTPy-+U>kavs$F0*<8?c#fBiDbAq8Zf>pBq98s-rriyXy1*ss|y|7#;W4
zLY>L{0X6fDr}xaaha7Nljqk>Y9_|M#pAVehHusMe-3+@Ym(1P9yD#i=nNKM;I(75@
zVxw!(yg}IT7tHy@#)}zq9Iz2cn8n6MaK=YZY8bG?t81Lq(K$q|+$T|iJ~7|!BlkMN
zz;SQS#Yu0IOy!TBbkHdD=o9<N(T}h3rNQk95`2s;;ov_XB*D{6<%6e#eDKl%68!8M
zU!;jO?Pc?;EJOwHIo{I#*{Q#t_J~y{$@E+pCOjDy4f70*5S}Tf@;q0M@;tF5;rW>N
S&BBMnc#!MJd-~A`_5Tl8-z1y>

delta 1483
zcmY*ZOH5Ni6rDE}9z3dfR49m*K8r~GrWL3~v3-_bt%?=U5H$k+QWc{c6LcfEP-0ww
zvoUP2MEoQsQk!T^OhBRu#;9OSXx!*hjSEOz5M1bdJNh;=_uRSXo-?2K>9sQXNEs-w
zgMYq1{0kjSte?oz=K?HuHONL(+G$66_FYTqd;-1P-G}ZJ)o$u>XJ;4`kOdSR6>~%f
zI-On67!XUw)nT}<v9+}UJm92CL;+7pdhWvPPqy68>pjS;)}cq*Moj@KCH4cXp+qM=
z2DoxRo}*|-LDI<kl|_}sBfpW&<|6at{sYe;Tqr=+_EV@|)$>CU(h7hu8-NFOm3JZ6
za=IGDTN0YkoGwCv&K~r`&Qip#sV#-Qh3K*7gj06ZqZ+xL4#pEkmsDr|<$XNLkYhAA
zy_%zg@pA2JaPq*Y8JIsGNKU)_SXv2|mVzk*TQHdVmNzi9iu8sP5*6*ED{*@RIzXZ?
z2%*Oi#&VyuWx5n<bHVE$9(J7ccL&gb{ScgT|HtkrqwLcX73@<6HD|bpIT))*HXmt(
zaJn3KIf~s|EnCtW>QD<U)v+?v)qWhNB}W|VPJ1ZxSBYZg!Lemm7J}|JFzoc5<2MSJ
z-$!O@-t7?a5;HnG^6c%OZl2FEM}K|4Rpt<RtJ(1)-=Do%#JbsLx#%c!i`ZuF+0Zcl
z(k0>obN<ru!}c{iPTpIgse@ze1l!l5FGYq@K|Si#%wtbw#-q1ar5=5{mwNoh+&J-_
zCmv%y>Tyn@V)sB5*}Wz0)%ZgG(45H`UlW8mH5uYcy_gbjz2l?A3zC8mFKnm8U>!Xy
z(oPT$)X-!3wv9^G>X_u)0m@w5v=%-HBD3j8)lfaZc;NI++xt*kxE{Yp2tXc&Pq-KP
zgR=rFUlzz497fYkK8MNQX9-V;@!EK*I_U}@!ZxHTqV-rk)v8NWXkFY%v^rbrgp|f`
zeF%s@2?3kWzVe~ry{;>1-c`{R1@8?jAVF2^p8#JqnZaiw1H6wi@Ox@yP!lc81kmdd
z{}ap&z21I<<r4QJ3VVc~!+0lCuvoew9*1^QkA_5r$1S^vN6U=}dxf@UTJDw$N%_Yp
pE%!)Nl%Hv)<&*nZd8Cz=`{hDXt{tT1rbI>gNGmDV7Wsn*;4dd>fmi?l

diff --git a/test/IntegrationTests/refs/grhd_bondi_accretion/output1d.h5 b/test/IntegrationTests/refs/grhd_bondi_accretion/output1d.h5
index 7219b39bc289421afdd21452654ec09cca851686..740e709f24c311ee88cb745632d6f3fb0f3db056 100644
GIT binary patch
delta 1220
zcmYk6T}V_x6vvy%5?yz1Ty@<@+1%(wswLk<La`LJT1|=UQz-J|X+sDih!r0)4PEt?
zQ)p_U^b%}xs|!-}5RsMn6@d?tf%E~c2|naQ#ck%?Gws}m%kMvD&Y5%0J#!b^T#MbV
zo(wP9lz41>>RwOeb#6_XC^H+3k<?b>%a&BLBzYlaGhZ?6&~HQ60}dCg7=iQz=Vt)3
z;2RP*4rb<xO|0lG7qwmx#@gU@<FD5OZ+~@%S?qfT2GcHZ6R~P)g{$cRb|}YL@mH4u
zfb;4xE0Nf?S3a}2Hd}}N^%pThxB(&3h!AZ;7;fIZ3(mGfy`n7ReAgs6`@2g?BCaTS
zJv!+EQ*7XXlgHX1LU0HnJd6+<k$di6%LA|QbdKW{eJ{_RL5R&FyqH6nokv(&xSZ%_
z$uEbs!Uv{j<42O3xOwZ(oEsJ*jd51%BDo-<O>uT14MlLMoq62kDOh;3S+$2e2Eo6A
z)uoZFY*4X*yR3K*83Qrg+{>=)B@aRHldYM3B(z;9%U@2MnyjJ<;v{TURgx!Zu-7hF
zVe2Qz|MVF>sR;d)A_Ausk$(oo(t^c2XUQEW8vi~c-9D@49La-_R-~02*T5ETh_jbH
zSfnWbL$6Z)avusv$WTtAw-urHqu>QwQ~l)7eyCBKk~Q)f#v1tm%WB_As-GtJvcSV$
zmTTHqN&at=g5SyWov?2$nPT^}6zYb%WchW9k%Q@yiZUcsWlE~|N(yI5iumZqAoPRZ
zNLEupozBnB^9iV=&Nzq`v>Zl@5N$^k(RWl4qahTcA9YpqQzAm31x;ccezwpuxS!%j
z!1CLb5G6MhQPbfF#%G0R)QK61$#dVN8(t@KF*Boz7adcCK8`}1`+1yR-SM=Glv8+3
IJi0{w0oH^6od5s;

delta 1206
zcmYk5Ur19?9LGCHOLT5G?sP8FZZ3L}YUG<pD3*~{n{7n)S19t&(?AF!h=~uGhEBcZ
zDKs@vdI^Ty>Vg;%5m=d1Bk&<Ikp6%((T9AfxSezE@3^z4&-eE`zrXjlg)YZJtD`%|
zvqkz@@T+|_UevKIeb?G}y*`}PqJQ0*WmII$XQok$ZUz46s_L`3WLfvQQ(T<GnfTwL
zq<%QJkUb)0@2CiSxX@PzZt4F#CXd!?+KqDWBzG8Ai4!rap_Hz;Iaq-L+oIJ}a^S%$
zr_5Ai+uwMN@^HS&-`8D*43T<(Xahj35n!lk?;c*;3iPnC^vj(SJXq_hM5(-N;Pu#q
zgS+DWhwMI92LSwo0Ffbp_^^2M=w=a*icA;SQLzuA_6$Hg0q}AbATbB9IDaj*&5GYP
zE2WPO*T&CuxpCv}-&rR&L>rPM>_CNF#2S<2N;U}pU>k8c(R1#h%O*80^pp$w70gZr
z<>hk~?|(qb_n}cPhMIcF_5J7x7qqfDa{vW)q-ks8rgjX`nHZH-A=)sbU^RM{%}BRO
zmdW}V<l7YZtR&QPlJK3EMDYa>i}NONT}1co1oZn1cX`dwB~-*yn$Z??TH(G(eUiNH
zrbDu_Z2XTsAlUdzy&!l)x>O0@lZ4s_f(~p>^`RpNSvpgh5;M{ph8gJri)r5rs+&d+
z^LT`{By7qzLE3jg{vYVYZvJjH1H<-|Ozh0$HciEl+3yxqmLn*bE2z#RD3T{A>cyY@
zEDQTbl28@4H=mfJ7f_Au<**er9|sQ;ttTYWdr}f30T65-wL$zjmBH5xE_M#Tn(<Nh
yX4&F4DMiI?Nrc*MLFlc}jyj+tc6rV_c*A3-U^g=&Md49NsAC{l-7jPK#?Jo@-~)vK

diff --git a/test/IntegrationTests/refs/testconfig.toml b/test/IntegrationTests/refs/testconfig.toml
index 8ae07561..5b254ec5 100644
--- a/test/IntegrationTests/refs/testconfig.toml
+++ b/test/IntegrationTests/refs/testconfig.toml
@@ -123,7 +123,7 @@ variables1d = [ "D", "S", "tau" ]
 reltol1d = 1e-6
 
 [grhd_bondi_accretion]
-variables0d  = [ "D_err_norm" ]
+variables0d  = [ "D_err_norm", "Mtot" ]
 variables1d  = [ "D_err", "D", "Sr", "τ", "p", "ρ", "ϵ", "vr" ]
 
 [grhd_bondi_infall_avmda]
-- 
GitLab