Repository navigation
Commit ae9f329
TPC SC: faster and more robust space-charge distortion calculation
Major improvements:
- Poisson solver: anisotropy aware multigrid with phi line relaxation. Fine
phi grids converge now (1800 phi bins did not converge before), relative
stopping criterion independent of units and grid size, parallelised
- tricubic interpolation without Vc, the three components of the fields and
of the distortions/corrections are interpolated together
- fix of the global distortions (standard method) at the readout and several
other bug fixes in SpaceCharge, no crash or endless loop for invalid
interpolation positions
- faster filling of the density from histograms and faster reading of dumped
files (ZSTD)
- SpaceCharge objects read from a file are directly usable (the grid is set up
by a read rule, initAfterReadingFromFile() is not needed anymore)
- the slow space-charge correction is removed from TPCFastTransform
- closure test of the global distortions and corrections
Time per TPC side for calculateDistortionsCorrections() (default: fast
global distortions), realistic space-charge density, 32 threads (AMD EPYC
7702P):
grid (z x r x phi) old new speed-up
129 x 129 x 180 4.4 s 0.49 s 9x
257 x 257 x 180 50 s 1.6 s 32x
129 x 129 x 1800 68 s (*) 4.7 s 15x
(*) Poisson solver not converged after 200 V-cycles
Poisson solver only old new
129 x 129 x 180 3.4 s 0.11 s
257 x 257 x 180 47 s 0.33 s
129 x 129 x 1800 62 s (*) 1.55 s
other old new
density from TH3 (3600x257x257 -> 129x129x180) 11.7 s 0.3 s
read all dumped containers of one side (1800 phi) 2.7 s 1.0 s
The global distortions and corrections agree with the old code to a few um
rms (max. ~30 um for r < 248 cm). Larger differences are only at the outer
radial edge (extrapolation) and from the fixes listed below.
Poisson solver
- phi is only coarsened if its coupling (h_rz / (r_min * h_phi))^2 is not
weak compared to r/z (MGParameters::phiCoarseningThreshold, default 0.5).
On levels where the phi coupling dominates, each phi ring is solved exactly
(periodic tridiagonal system, Thomas algorithm + Sherman-Morrison) instead
of the point-wise relaxation, which does not smooth the error there
(MGParameters::phiLineRelaxThreshold, default 4, 0 disables). The levels
are described by a list of MGLevel. All levels converge in 3-15 V-cycles.
- relative stopping criterion (MGParameters::relativeConvergence, default
true): relative change of the potential between two V-cycles < 1e-8
(1e-6 for float, which stays at ~1e-7 because of the rounding). The
previous absolute criterion (sum of dV^2 < 1e-6) depended on the units of
the potential and on the grid size. The error w.r.t. the converged solution
is now ~3e-9 of max|V|. relativeConvergence = false with
setConvergenceError(1e-6) reproduces the previous criterion.
- parallelised: red-black relaxation over phi, line relaxation (factorisation
and blocks of lines), restriction, interpolation, convergence error,
allocation of the level buffers and the copies between the V-cycles
- removed unused options (available in the git history): 2D solver, 3D solver
with constant number of phi slices, W cycle (not functional), Jacobi
relaxation, half weighting, the symmetry argument (diverged; also removed
from SpaceCharge::poissonSolver() and calcEField()) and the MGParameters
isFull3D, cycleType, gtType, relaxType, maxLoop, gamma with their enums
- merged duplicated code (interpolate3D<Add>(), restrictBoundary2D())
- fixes: minimum radius of the grid instead of the hard coded IFC radius for
the coefficients, Vector3D constructor (list initialisation gave a single
element) and size()
Tricubic interpolation
- separable Catmull-Rom interpolation (z, then r, then phi) with the values
taken directly from the grid. The cell (position, index, weights) is
calculated once for the three components (new
TriCubicInterpolator::interpolate(z, r, phi, other1, other2, ...), used by
NumericalFields::evalFields() and DistCorrInterpolator::evalDistCorr()) and
the three sums are done in one pass. The results change at the rounding
level (< 2.3e-14 of max|V| for double).
- the cells at the boundary use a generic extrapolation of the stencil points
outside of the grid instead of 26 hand-written cases. This fixes the
extrapolation at the (first z, last r) and (last z, first r) edges, which
was done along the wrong diagonal.
- no Vc: Vector.h is removed (std::array in RegularGrid3D), the public
headers and the dictionary do not include Vc anymore and TPCSpaceCharge
does not link Vc
- fixes: without extrapolation, queries at or beyond the last vertex in r or z
returned the value one grid spacing inwards; the move constructor did not
take over the extrapolation setting
- non-finite query positions return NaN instead of reading outside of the
grid, and positions far outside of the grid in phi are wrapped with fmod
instead of loops which did not terminate for huge values
SpaceCharge
- calcGlobalDistortions(): in the last step before the readout the local
distortions were scaled to the remaining drift length, but the correction
for the missing distance assumed a full z bin, and std::abs turned the
correction for electrons which passed the readout into an addition. The z
bias of the standard method w.r.t. a direct integration of the fields
changes from -83 um to -12 um, the closure with the global corrections in z
from 110 um to 2.7 um rms. Standard and fast method agree in z to ~2 um.
- correctElectron(): the z coordinate of the corrected point was set to
y + corrY
- calcGlobalDistCorrIterativeLinearCartesian(): the scaled contribution was
lost for corrections with a scaling object; float precision of the angles
- calcGlobalDistCorrIterative*(): reference to a member of scSCale also for
scSCale == nullptr (undefined behaviour)
- calcGlobalCorrections() with type 1: dR was copied to dRPhi and dZ for the
vertices out of the volume
- scaleChargeDensityStack(): phi of the vertex taken from the radial index
- fillChargeDensityFromHisto(file, ...): nullptr dereference if a histogram
is missing
- getStepWidth(): integer division
- DataContainer3D: the element-wise operators did not check the grid of the
other container (out-of-bounds read)
- reading from a file: the grid properties are transient and were only set up
for the default number of vertices. Without calling
initAfterReadingFromFile() an object with a different grid gave wrong
values or read outside of the data. A read rule in the LinkDef now calls it
for every SpaceCharge object read from a file (calling it explicitly, e.g.
in the Digitizer, is still possible).
- warning if the global distortions/corrections contain non-finite values
(e.g. for unphysically large fields)
- the functions processing both sides used only two threads (nested OpenMP
regions are not active); the sides are processed one after the other with
all threads, and the number of threads is passed to the Poisson solver
- the density is rebinned from the histograms of both sides directly, without
a merged copy (1.9 GB for 3600x257x257 bins)
- iterative Simpson integration: the fields at the start point are evaluated
once per step instead of once per iteration
- calculateDistortionsCorrections() and initAllBuffers() allocate the
containers concurrently: the first access to the memory of a large
container by the single thread zeroing it took ~1.2 s per side at 1800 phi
- the dumped containers use ZSTD instead of ZLIB compression: same file size
(the data are hardly compressible), ~2.7 times faster reading. Old files are
read as before.
GPU TPCFastTransform
- TPCSlowSpaceChargeCorrection held a SpaceCharge<float> object with the
global corrections (setSlowTPCSCCorrection()), which replaced the spline
correction in TransformLocal() on the CPU. It is not used anymore (the
reconstruction uses the POD correction object) and is removed together with
setSlowTPCSCCorrection(), getCorrectionSlow() and the dependency of
TPCFastTransformation on O2::TPCSpaceCharge (O2::DataFormatsTPC is linked
directly instead).
- the persistent member mCorrectionSlow is removed: ClassDefNV of
TPCFastTransform is increased to 6 (schema evolution). An empty
dictionary-only stub of TPCSlowSpaceChargeCorrection is kept, so that
reading existing objects (ClassDef <= 5, e.g. the CCDB maps) does not print
a missing-dictionary warning. It can be removed once old maps are no longer
read.
Tests
- Poisson solver: phi coarsening, phi line relaxation (720 phi bins)
- tricubic interpolation: interpolation at all vertices, combined vs.
separate interpolation of three components, phi spacing of the query points
- new SpaceCharge test: closure of the global distortions (standard and fast
method) with the global corrections from analytical fields on both sides,
large fields and queries at invalid positions, reading of a stored object
with a non-default grid (float and double)
- createResidualDistortionObject.C is tested compiled only (COMPILE_ONLY, as the
other space-charge macros and as documented in the macro): loading it in
the interpreter crashed while auto-loading the CommonUtils dictionary
(DebugStreamer's map of unique_ptr<TreeStreamRedirector> with an incomplete
type), independent of this change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>1 parent ab59052 commit ae9f329
23 files changed
Lines changed: 1546 additions & 2982 deletions
File tree
- Detectors/TPC/spacecharge
- include/TPCSpaceCharge
- src
- test
- GPU/TPCFastTransformation
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | | - | |
21 | 20 | | |
22 | 21 | | |
23 | 22 | | |
| |||
35 | 34 | | |
36 | 35 | | |
37 | 36 | | |
38 | | - | |
39 | 37 | | |
40 | 38 | | |
41 | 39 | | |
| |||
49 | 47 | | |
50 | 48 | | |
51 | 49 | | |
52 | | - | |
| 50 | + | |
53 | 51 | | |
54 | 52 | | |
55 | 53 | | |
| |||
81 | 79 | | |
82 | 80 | | |
83 | 81 | | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
84 | 90 | | |
85 | 91 | | |
86 | 92 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
| 24 | + | |
23 | 25 | | |
24 | 26 | | |
25 | 27 | | |
| |||
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
42 | | - | |
43 | | - | |
44 | | - | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
58 | | - | |
59 | | - | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
60 | 37 | | |
61 | 38 | | |
62 | 39 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | | - | |
21 | 20 | | |
22 | 21 | | |
| 22 | + | |
| 23 | + | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
| |||
90 | 91 | | |
91 | 92 | | |
92 | 93 | | |
93 | | - | |
94 | | - | |
95 | | - | |
96 | | - | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
97 | 98 | | |
98 | 99 | | |
99 | 100 | | |
100 | 101 | | |
101 | 102 | | |
102 | 103 | | |
103 | | - | |
| 104 | + | |
104 | 105 | | |
105 | 106 | | |
106 | 107 | | |
| |||
141 | 142 | | |
142 | 143 | | |
143 | 144 | | |
144 | | - | |
| 145 | + | |
145 | 146 | | |
146 | 147 | | |
147 | 148 | | |
| |||
159 | 160 | | |
160 | 161 | | |
161 | 162 | | |
162 | | - | |
163 | | - | |
164 | | - | |
165 | | - | |
166 | | - | |
167 | | - | |
168 | | - | |
169 | | - | |
170 | | - | |
171 | | - | |
172 | | - | |
173 | | - | |
174 | | - | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
175 | 176 | | |
176 | 177 | | |
177 | 178 | | |
| |||
217 | 218 | | |
218 | 219 | | |
219 | 220 | | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
220 | 226 | | |
221 | 227 | | |
222 | 228 | | |
| |||
229 | 235 | | |
230 | 236 | | |
231 | 237 | | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
232 | 243 | | |
233 | 244 | | |
234 | 245 | | |
| |||
0 commit comments