Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/magneticfield/include/G4QSS2.hh

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /geometry/magneticfield/include/G4QSS2.hh (Version 11.3.0) and /geometry/magneticfield/include/G4QSS2.hh (Version 11.2.2)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // G4QSS2                                          26 // G4QSS2
 27 //                                                 27 //
 28 // G4QSS2 simulator                                28 // G4QSS2 simulator
 29                                                    29 
 30 // Authors: Lucio Santi, Rodrigo Castro (Univ. <<  30 // Authors: Lucio Santi, Rodrigo Castro - 2018-2021
 31 // -------------------------------------------     31 // --------------------------------------------------------------------
 32 #ifndef _G4QSS2_H_                                 32 #ifndef _G4QSS2_H_
 33 #define _G4QSS2_H_ 1                           <<  33 #define _G4QSS2_H_
 34                                                    34 
 35 #include "G4Types.hh"                          <<  35 #include "G4Types.hh"  //  For G4int, G4double
 36 #include "G4qss_misc.hh"                           36 #include "G4qss_misc.hh"
 37                                                    37 
 38 #include <cmath>                                   38 #include <cmath>
 39 #include <cassert>                                 39 #include <cassert>
 40                                                    40 
 41 #define  REPORT_CRITICAL_PROBLEM  1                41 #define  REPORT_CRITICAL_PROBLEM  1
 42                                                    42 
 43 #ifdef   REPORT_CRITICAL_PROBLEM                   43 #ifdef   REPORT_CRITICAL_PROBLEM
 44 #include <cassert>                                 44 #include <cassert>
 45 #include "G4Log.hh"                                45 #include "G4Log.hh"
 46 #endif                                             46 #endif
 47                                                    47 
 48 class G4QSS2                                       48 class G4QSS2
 49 {                                                  49 {
 50   public:                                          50   public:
 51                                                    51 
 52     G4QSS2(QSS_simulator sim) : simulator(sim)     52     G4QSS2(QSS_simulator sim) : simulator(sim) {}
 53                                                    53 
 54     inline QSS_simulator getSimulator() const      54     inline QSS_simulator getSimulator() const { return this->simulator; }
 55                                                    55 
 56     inline G4int order() const { return 2; }       56     inline G4int order() const { return 2; }
 57                                                    57 
 58     inline void full_definition(G4double coeff     58     inline void full_definition(G4double coeff)
 59     {                                              59     {
 60       G4double* const x = simulator->q;            60       G4double* const x = simulator->q;
 61       G4double* const dx = simulator->x;           61       G4double* const dx = simulator->x;
 62       G4double* const alg = simulator->alg;        62       G4double* const alg = simulator->alg;
 63                                                    63 
 64       dx[1] = x[9];                                64       dx[1] = x[9];
 65       dx[2] = 0;                                   65       dx[2] = 0;
 66                                                    66 
 67       dx[4] = x[12];                               67       dx[4] = x[12];
 68       dx[5] = 0;                                   68       dx[5] = 0;
 69                                                    69 
 70       dx[7] = x[15];                               70       dx[7] = x[15];
 71       dx[8] = 0;                                   71       dx[8] = 0;
 72                                                    72 
 73       dx[10] = coeff * (alg[2] * x[12] - alg[1     73       dx[10] = coeff * (alg[2] * x[12] - alg[1] * x[15]);
 74       dx[11] = 0;                                  74       dx[11] = 0;
 75                                                    75 
 76       dx[13] = coeff * (alg[0] * x[15] - alg[2     76       dx[13] = coeff * (alg[0] * x[15] - alg[2] * x[9]);
 77       dx[14] = 0;                                  77       dx[14] = 0;
 78                                                    78 
 79       dx[16] = coeff * (alg[1] * x[9] - alg[0]     79       dx[16] = coeff * (alg[1] * x[9] - alg[0] * x[12]);
 80       dx[17] = 0;                                  80       dx[17] = 0;
 81     }                                              81     }
 82                                                    82 
 83     inline void dependencies(G4int i, G4double     83     inline void dependencies(G4int i, G4double coeff)
 84     {                                              84     {
 85       G4double* const x = simulator->q;            85       G4double* const x = simulator->q;
 86       G4double* const der = simulator->x;          86       G4double* const der = simulator->x;
 87       G4double* const alg = simulator->alg;        87       G4double* const alg = simulator->alg;
 88                                                    88 
 89       switch (i)                                   89       switch (i)
 90       {                                            90       {
 91         case 0:                                    91         case 0:
 92           der[10] = coeff * (alg[2] * x[12] -      92           der[10] = coeff * (alg[2] * x[12] - alg[1] * x[15]);
 93           der[11] = ((alg[2] * x[13] - x[16] *     93           der[11] = ((alg[2] * x[13] - x[16] * alg[1]) * coeff) / 2;
 94                                                    94 
 95           der[13] = coeff * (alg[0] * x[15] -      95           der[13] = coeff * (alg[0] * x[15] - alg[2] * x[9]);
 96           der[14] = ((alg[0] * x[16] - alg[2]      96           der[14] = ((alg[0] * x[16] - alg[2] * x[10]) * coeff) / 2;
 97                                                    97 
 98           der[16] = coeff * (alg[1] * x[9] - a     98           der[16] = coeff * (alg[1] * x[9] - alg[0] * x[12]);
 99           der[17] = (-coeff * (alg[0] * x[13]      99           der[17] = (-coeff * (alg[0] * x[13] - x[10] * alg[1])) / 2;
100           return;                                 100           return;
101         case 1:                                   101         case 1:
102           der[10] = coeff * (alg[2] * x[12] -     102           der[10] = coeff * (alg[2] * x[12] - alg[1] * x[15]);
103           der[11] = ((alg[2] * x[13] - x[16] *    103           der[11] = ((alg[2] * x[13] - x[16] * alg[1]) * coeff) / 2;
104                                                   104 
105           der[13] = coeff * (alg[0] * x[15] -     105           der[13] = coeff * (alg[0] * x[15] - alg[2] * x[9]);
106           der[14] = ((alg[0] * x[16] - alg[2]     106           der[14] = ((alg[0] * x[16] - alg[2] * x[10]) * coeff) / 2;
107                                                   107 
108           der[16] = coeff * (alg[1] * x[9] - a    108           der[16] = coeff * (alg[1] * x[9] - alg[0] * x[12]);
109           der[17] = (-coeff * (alg[0] * x[13]     109           der[17] = (-coeff * (alg[0] * x[13] - x[10] * alg[1])) / 2;
110           return;                                 110           return;
111         case 2:                                   111         case 2:
112           der[10] = coeff * (alg[2] * x[12] -     112           der[10] = coeff * (alg[2] * x[12] - alg[1] * x[15]);
113           der[11] = ((alg[2] * x[13] - x[16] *    113           der[11] = ((alg[2] * x[13] - x[16] * alg[1]) * coeff) / 2;
114                                                   114 
115           der[13] = coeff * (alg[0] * x[15] -     115           der[13] = coeff * (alg[0] * x[15] - alg[2] * x[9]);
116           der[14] = ((alg[0] * x[16] - alg[2]     116           der[14] = ((alg[0] * x[16] - alg[2] * x[10]) * coeff) / 2;
117                                                   117 
118           der[16] = coeff * (alg[1] * x[9] - a    118           der[16] = coeff * (alg[1] * x[9] - alg[0] * x[12]);
119           der[17] = (-coeff * (alg[0] * x[13]     119           der[17] = (-coeff * (alg[0] * x[13] - x[10] * alg[1])) / 2;
120           return;                                 120           return;
121         case 3:                                   121         case 3:
122           der[1] = x[9];                          122           der[1] = x[9];
123           der[2] = (x[10]) / 2;                   123           der[2] = (x[10]) / 2;
124                                                   124 
125           der[13] = coeff * (alg[0] * x[15] -     125           der[13] = coeff * (alg[0] * x[15] - alg[2] * x[9]);
126           der[14] = ((alg[0] * x[16] - alg[2]     126           der[14] = ((alg[0] * x[16] - alg[2] * x[10]) * coeff) / 2;
127                                                   127 
128           der[16] = coeff * (alg[1] * x[9] - a    128           der[16] = coeff * (alg[1] * x[9] - alg[0] * x[12]);
129           der[17] = (-coeff * (alg[0] * x[13]     129           der[17] = (-coeff * (alg[0] * x[13] - x[10] * alg[1])) / 2;
130           return;                                 130           return;
131         case 4:                                   131         case 4:
132           der[4] = x[12];                         132           der[4] = x[12];
133           der[5] = (x[13]) / 2;                   133           der[5] = (x[13]) / 2;
134                                                   134 
135           der[10] = coeff * (alg[2] * x[12] -     135           der[10] = coeff * (alg[2] * x[12] - alg[1] * x[15]);
136           der[11] = ((alg[2] * x[13] - x[16] *    136           der[11] = ((alg[2] * x[13] - x[16] * alg[1]) * coeff) / 2;
137                                                   137 
138           der[16] = coeff * (alg[1] * x[9] - a    138           der[16] = coeff * (alg[1] * x[9] - alg[0] * x[12]);
139           der[17] = (-coeff * (alg[0] * x[13]     139           der[17] = (-coeff * (alg[0] * x[13] - x[10] * alg[1])) / 2;
140           return;                                 140           return;
141         case 5:                                   141         case 5:
142           der[7] = x[15];                         142           der[7] = x[15];
143           der[8] = (x[16]) / 2;                   143           der[8] = (x[16]) / 2;
144                                                   144 
145           der[10] = coeff * (alg[2] * x[12] -     145           der[10] = coeff * (alg[2] * x[12] - alg[1] * x[15]);
146           der[11] = ((alg[2] * x[13] - x[16] *    146           der[11] = ((alg[2] * x[13] - x[16] * alg[1]) * coeff) / 2;
147                                                   147 
148           der[13] = coeff * (alg[0] * x[15] -     148           der[13] = coeff * (alg[0] * x[15] - alg[2] * x[9]);
149           der[14] = ((alg[0] * x[16] - alg[2]     149           der[14] = ((alg[0] * x[16] - alg[2] * x[10]) * coeff) / 2;
150           return;                                 150           return;
151       }                                           151       }
152     }                                             152     }
153                                                   153 
154     inline void recompute_next_times(G4int* in    154     inline void recompute_next_times(G4int* inf, G4double t)
155     {                                             155     {
156       G4int i;                                    156       G4int i;
157       G4double* x = simulator->x;                 157       G4double* x = simulator->x;
158       G4double* q = simulator->q;                 158       G4double* q = simulator->q;
159       G4double* lqu = simulator->lqu;             159       G4double* lqu = simulator->lqu;
160       G4double* time = simulator->nextStateTim    160       G4double* time = simulator->nextStateTime;
161                                                   161 
162       for (i = 0; i < 3; i++)                     162       for (i = 0; i < 3; i++)
163       {                                           163       {
164         const G4int var = inf[i];                 164         const G4int var = inf[i];
165         const G4int icf0 = 3 * var;               165         const G4int icf0 = 3 * var;
166         const G4int icf1 = icf0 + 1;              166         const G4int icf1 = icf0 + 1;
167         const G4int icf2 = icf1 + 1;              167         const G4int icf2 = icf1 + 1;
168                                                   168 
169         time[var] = t;                            169         time[var] = t;
170                                                   170 
171         if (std::fabs(q[icf0] - x[icf0]) < lqu    171         if (std::fabs(q[icf0] - x[icf0]) < lqu[var])
172         {                                         172         {
173           G4double mpr = -1, mpr2;                173           G4double mpr = -1, mpr2;
174           G4double cf0 = q[icf0] + lqu[var] -     174           G4double cf0 = q[icf0] + lqu[var] - x[icf0];
175           G4double cf1 = q[icf1] - x[icf1];       175           G4double cf1 = q[icf1] - x[icf1];
176           G4double cf2 = -x[icf2];                176           G4double cf2 = -x[icf2];
177           G4double cf0Alt = q[icf0] - lqu[var]    177           G4double cf0Alt = q[icf0] - lqu[var] - x[icf0];
178                                                   178 
179           if (unlikely(cf2 == 0 || (1000 * std    179           if (unlikely(cf2 == 0 || (1000 * std::fabs(cf2)) < std::fabs(cf1)))
180           {                                       180           {
181             if (cf1 == 0) {                       181             if (cf1 == 0) {
182               mpr = Qss_misc::INF;                182               mpr = Qss_misc::INF;
183             } else                                183             } else
184             {                                     184             {
185               mpr = -cf0 / cf1;                   185               mpr = -cf0 / cf1;
186               mpr2 = -cf0Alt / cf1;               186               mpr2 = -cf0Alt / cf1;
187               if (mpr < 0 || (mpr2 > 0 && mpr2    187               if (mpr < 0 || (mpr2 > 0 && mpr2 < mpr)) { mpr = mpr2; }
188             }                                     188             }
189                                                   189 
190             if (mpr < 0) { mpr = Qss_misc::INF    190             if (mpr < 0) { mpr = Qss_misc::INF; }
191           }                                       191           }
192           else                                    192           else
193           {                                       193           {
194             static G4ThreadLocal unsigned long    194             static G4ThreadLocal unsigned long long okCalls=0LL, badCalls= 0LL;
195             constexpr G4double dangerZone = 1.    195             constexpr G4double dangerZone = 1.0e+30;
196             static G4ThreadLocal G4double bigC    196             static G4ThreadLocal G4double bigCf1_pr = dangerZone,
197                                           bigC    197                                           bigCf2_pr = dangerZone;
198             static G4ThreadLocal G4double bigC    198             static G4ThreadLocal G4double bigCf1 = 0.0, bigCf2 = 0.0;
199             if( std::abs(cf1) > dangerZone ||     199             if( std::abs(cf1) > dangerZone || std::fabs(cf2) > dangerZone )
200             {                                     200             {
201               badCalls++;                         201               badCalls++;
202               if( badCalls == 1                   202               if( badCalls == 1 
203                  || ( badCalls < 1000 && badCa    203                  || ( badCalls < 1000 && badCalls % 20 == 0 )
204                  || (   1000 < badCalls && bad    204                  || (   1000 < badCalls && badCalls <   10000 && badCalls %  100 == 0 )
205                  || (  10000 < badCalls && bad    205                  || (  10000 < badCalls && badCalls <  100000 && badCalls % 1000 == 0 )
206                  || ( 100000 < badCalls &&        206                  || ( 100000 < badCalls &&                       badCalls % 10000 == 0 )
207                  || ( std::fabs(cf1) > 1.5 * b    207                  || ( std::fabs(cf1) > 1.5 * bigCf1_pr || std::fabs(cf2) > 1.5 * bigCf2_pr )
208                 )                                 208                 )
209               {                                   209               {
210                 std::cout << " cf1 = " << std:    210                 std::cout << " cf1 = " << std::setw(15) << cf1 << " cf2= " << std::setw(15) << cf2
211                           << "  badCall # " <<    211                           << "  badCall # " << badCalls << " of " << badCalls + okCalls
212                           << "  fraction = " <    212                           << "  fraction = " << double(badCalls) / double(badCalls+okCalls);
213                                                   213 
214                 if( std::fabs(cf1) > 1.5 * big    214                 if( std::fabs(cf1) > 1.5 * bigCf1_pr ) { bigCf1_pr = std::fabs(cf1); std::cout << " Bigger cf1 "; }
215                 if( std::fabs(cf2) > 1.5 * big    215                 if( std::fabs(cf2) > 1.5 * bigCf2_pr ) { bigCf2_pr = std::fabs(cf2); std::cout << " Bigger cf2 "; }
216                 std::cout << std::endl;           216                 std::cout << std::endl;
217               }                                   217               }
218               if( std::fabs(cf1) > 1.5 * bigCf    218               if( std::fabs(cf1) > 1.5 * bigCf1 ) { bigCf1 = std::fabs(cf1); }
219               if( std::fabs(cf2) > 1.5 * bigCf    219               if( std::fabs(cf2) > 1.5 * bigCf2 ) { bigCf2 = std::fabs(cf2); }
220             }                                     220             }
221             else                                  221             else
222             {                                     222             {
223               okCalls++;                          223               okCalls++;
224             }                                     224             }
225                                                   225 
226 #ifdef REPORT_CRITICAL_PROBLEM                    226 #ifdef REPORT_CRITICAL_PROBLEM
227             constexpr unsigned int exp_limit=     227             constexpr unsigned int exp_limit= 140;
228             constexpr G4double limit= 1.0e+140    228             constexpr G4double limit= 1.0e+140; // std::pow(10,exp_limit));
229             assert( std::fabs( std::pow(10, ex    229             assert( std::fabs( std::pow(10, exp_limit) - limit ) < 1.0e-14*limit );
230             G4bool bad_cf2fac= G4Log(std::fabs    230             G4bool bad_cf2fac= G4Log(std::fabs(cf2))
231                              + G4Log(std::max(    231                              + G4Log(std::max( std::fabs(cf0), std::fabs(cf0Alt))) > 2*limit;
232             if( std::fabs(cf1) > limit            232             if( std::fabs(cf1) > limit
233                || G4Log(std::fabs(cf2))           233                || G4Log(std::fabs(cf2))
234                 + G4Log(std::max( std::fabs(cf    234                 + G4Log(std::max( std::fabs(cf0), std::fabs(cf0Alt))) > 2*exp_limit )
235             {                                     235             {
236               G4ExceptionDescription ermsg;       236               G4ExceptionDescription ermsg;
237               ermsg << "QSS2: Coefficients exc    237               ermsg << "QSS2: Coefficients exceed tolerable values -- beyond " << limit << G4endl;
238               if( std::fabs(cf1) > limit )        238               if( std::fabs(cf1) > limit )
239               {                                   239               {
240                 ermsg << " |cf1| = " << cf1 <<    240                 ermsg << " |cf1| = " << cf1 << " is > " << limit << " (limit)";
241               }                                   241               }
242               if( bad_cf2fac)                     242               if( bad_cf2fac)
243               {                                   243               {
244                 ermsg << " bad cf2-factor:  cf    244                 ermsg << " bad cf2-factor:  cf2 = " << cf2
245                       << " product is > " << 2    245                       << " product is > " << 2*limit << " (limit)";
246               }                                   246               }
247               G4Exception("QSS2::recompute_nex    247               G4Exception("QSS2::recompute_next_times",
248                           "Field/Qss2-", Fatal    248                           "Field/Qss2-", FatalException, ermsg ); 
249             }                                     249             }
250 #endif                                            250 #endif
251             G4double cf1_2 = cf1 * cf1;           251             G4double cf1_2 = cf1 * cf1;
252             G4double cf2_4 = 4 * cf2;             252             G4double cf2_4 = 4 * cf2;
253             G4double disc1 = cf1_2 - cf2_4 * c    253             G4double disc1 = cf1_2 - cf2_4 * cf0;
254             G4double disc2 = cf1_2 - cf2_4 * c    254             G4double disc2 = cf1_2 - cf2_4 * cf0Alt;
255             G4double cf2_d2 = 2 * cf2;            255             G4double cf2_d2 = 2 * cf2;
256                                                   256 
257             if (unlikely(disc1 < 0 && disc2 <     257             if (unlikely(disc1 < 0 && disc2 < 0))  // no real roots
258             {                                     258             {
259               mpr = Qss_misc::INF;                259               mpr = Qss_misc::INF;
260             }                                     260             }
261             else if (disc2 < 0)                   261             else if (disc2 < 0)
262             {                                     262             {
263               G4double sd, r1;                    263               G4double sd, r1;
264               sd = std::sqrt(disc1);              264               sd = std::sqrt(disc1);
265               r1 = (-cf1 + sd) / cf2_d2;          265               r1 = (-cf1 + sd) / cf2_d2;
266               if (r1 > 0) {                       266               if (r1 > 0) {
267                 mpr = r1;                         267                 mpr = r1;
268               } else {                            268               } else {
269                 mpr = Qss_misc::INF;              269                 mpr = Qss_misc::INF;
270               }                                   270               }
271               r1 = (-cf1 - sd) / cf2_d2;          271               r1 = (-cf1 - sd) / cf2_d2;
272               if ((r1 > 0) && (r1 < mpr)) { mp    272               if ((r1 > 0) && (r1 < mpr)) { mpr = r1; }
273             }                                     273             }
274             else if (disc1 < 0)                   274             else if (disc1 < 0)
275             {                                     275             {
276               G4double sd, r1;                    276               G4double sd, r1;
277               sd = std::sqrt(disc2);              277               sd = std::sqrt(disc2);
278               r1 = (-cf1 + sd) / cf2_d2;          278               r1 = (-cf1 + sd) / cf2_d2;
279               if (r1 > 0) {                       279               if (r1 > 0) {
280                 mpr = r1;                         280                 mpr = r1;
281               } else {                            281               } else {
282                 mpr = Qss_misc::INF;              282                 mpr = Qss_misc::INF;
283               }                                   283               }
284               r1 = (-cf1 - sd) / cf2_d2;          284               r1 = (-cf1 - sd) / cf2_d2;
285               if ((r1 > 0) && (r1 < mpr)) { mp    285               if ((r1 > 0) && (r1 < mpr)) { mpr = r1; }
286             }                                     286             }
287             else                                  287             else
288             {                                     288             {
289               G4double sd1, r1, sd2, r2;          289               G4double sd1, r1, sd2, r2;
290               sd1 = std::sqrt(disc1);             290               sd1 = std::sqrt(disc1);
291               sd2 = std::sqrt(disc2);             291               sd2 = std::sqrt(disc2);
292               r1 = (-cf1 + sd1) / cf2_d2;         292               r1 = (-cf1 + sd1) / cf2_d2;
293               r2 = (-cf1 + sd2) / cf2_d2;         293               r2 = (-cf1 + sd2) / cf2_d2;
294               if (r1 > 0) { mpr = r1; }           294               if (r1 > 0) { mpr = r1; }
295               else { mpr = Qss_misc::INF; }       295               else { mpr = Qss_misc::INF; }
296               r1 = (-cf1 - sd1) / cf2_d2;         296               r1 = (-cf1 - sd1) / cf2_d2;
297               if ((r1 > 0) && (r1 < mpr)) { mp    297               if ((r1 > 0) && (r1 < mpr)) { mpr = r1; }
298               if (r2 > 0 && r2 < mpr) { mpr =     298               if (r2 > 0 && r2 < mpr) { mpr = r2; }
299               r2 = (-cf1 - sd2) / cf2_d2;         299               r2 = (-cf1 - sd2) / cf2_d2;
300               if ((r2 > 0) && (r2 < mpr)) { mp    300               if ((r2 > 0) && (r2 < mpr)) { mpr = r2; }
301             }                                     301             }
302           }                                       302           }
303           time[var] += mpr;                       303           time[var] += mpr;
304         }                                         304         }
305       }                                           305       }
306     }                                             306     }
307                                                   307 
308     inline void recompute_all_state_times(G4do    308     inline void recompute_all_state_times(G4double t)
309     {                                             309     {
310       G4double mpr;                               310       G4double mpr;
311       G4double* const x = simulator->x;           311       G4double* const x = simulator->x;
312       G4double* const lqu = simulator->lqu;       312       G4double* const lqu = simulator->lqu;
313       G4double* const time = simulator->nextSt    313       G4double* const time = simulator->nextStateTime;
314                                                   314 
315       for (G4int var = 0, icf0 = 0; var < 6; v    315       for (G4int var = 0, icf0 = 0; var < 6; var++, icf0 += 3)
316       {                                           316       {
317         const G4int icf1 = icf0 + 1;              317         const G4int icf1 = icf0 + 1;
318                                                   318 
319         if (x[icf1] == 0)                         319         if (x[icf1] == 0)
320         {                                         320         {
321           time[var] = Qss_misc::INF;              321           time[var] = Qss_misc::INF;
322         }                                         322         }
323         else                                      323         else
324         {                                         324         {
325           mpr = lqu[var] / x[icf1];               325           mpr = lqu[var] / x[icf1];
326           if (mpr < 0) { mpr *= -1; }             326           if (mpr < 0) { mpr *= -1; }
327           time[var] = t + mpr;                    327           time[var] = t + mpr;
328         }                                         328         }
329       }                                           329       }
330     }                                             330     }
331                                                   331 
332     inline void next_time(G4int var, G4double     332     inline void next_time(G4int var, G4double t)
333     {                                             333     {
334       const G4int cf2 = var * 3 + 2;              334       const G4int cf2 = var * 3 + 2;
335       G4double* const x = simulator->x;           335       G4double* const x = simulator->x;
336       G4double* const lqu = simulator->lqu;       336       G4double* const lqu = simulator->lqu;
337       G4double* const time = simulator->nextSt    337       G4double* const time = simulator->nextStateTime;
338                                                   338 
339       if (x[cf2] != 0.0) {                        339       if (x[cf2] != 0.0) {
340         time[var] = t + std::sqrt(lqu[var] / s    340         time[var] = t + std::sqrt(lqu[var] / std::fabs(x[cf2]));
341       } else {                                    341       } else {
342         time[var] = Qss_misc::INF;                342         time[var] = Qss_misc::INF;
343       }                                           343       }
344     }                                             344     }
345                                                   345 
346     inline void update_quantized_state(G4int i    346     inline void update_quantized_state(G4int i)
347     {                                             347     {
348       const G4int cf0 = i * 3, cf1 = cf0 + 1;     348       const G4int cf0 = i * 3, cf1 = cf0 + 1;
349       G4double* const q = simulator->q;           349       G4double* const q = simulator->q;
350       G4double* const x = simulator->x;           350       G4double* const x = simulator->x;
351                                                   351 
352       q[cf0] = x[cf0];                            352       q[cf0] = x[cf0];
353       q[cf1] = x[cf1];                            353       q[cf1] = x[cf1];
354     }                                             354     }
355                                                   355 
356     inline void reset_state(G4int i, G4double     356     inline void reset_state(G4int i, G4double value)
357     {                                             357     {
358       G4double* const x = simulator->x;           358       G4double* const x = simulator->x;
359       G4double* const q = simulator->q;           359       G4double* const q = simulator->q;
360       G4double* const tq = simulator->tq;         360       G4double* const tq = simulator->tq;
361       G4double* const tx = simulator->tx;         361       G4double* const tx = simulator->tx;
362       const G4int idx = 3 * i;                    362       const G4int idx = 3 * i;
363                                                   363 
364       x[idx] = value;                             364       x[idx] = value;
365                                                   365 
366       simulator->lqu[i] = simulator->dQRel[i]     366       simulator->lqu[i] = simulator->dQRel[i] * std::fabs(value);
367       if (simulator->lqu[i] < simulator->dQMin    367       if (simulator->lqu[i] < simulator->dQMin[i])
368       {                                           368       {
369         simulator->lqu[i] = simulator->dQMin[i    369         simulator->lqu[i] = simulator->dQMin[i];
370       }                                           370       }
371                                                   371 
372       q[idx] = value;                             372       q[idx] = value;
373       q[idx + 1] = tq[i] = tx[i] = 0;             373       q[idx + 1] = tq[i] = tx[i] = 0;
374     }                                             374     }
375                                                   375 
376     inline G4double evaluate_x_poly(G4int i, G    376     inline G4double evaluate_x_poly(G4int i, G4double dt, G4double* p)
377     {                                             377     {
378       return (p[i + 2] * dt + p[i + 1]) * dt +    378       return (p[i + 2] * dt + p[i + 1]) * dt + p[i];
379     }                                             379     }
380                                                   380 
381     inline void advance_time_q(G4int i, G4doub    381     inline void advance_time_q(G4int i, G4double dt)  // __attribute__((hot))
382     {                                             382     {
383       G4double* const p = simulator->q;           383       G4double* const p = simulator->q;
384       p[i] = p[i] + dt * p[i + 1];                384       p[i] = p[i] + dt * p[i + 1];
385     }                                             385     }
386                                                   386 
387     inline void advance_time_x(G4int i, G4doub    387     inline void advance_time_x(G4int i, G4double dt)  // __attribute__((hot))
388     {                                             388     {
389       G4double* const p = simulator->x;           389       G4double* const p = simulator->x;
390       const G4int i0 = i, i1 = i0 + 1, i2 = i1    390       const G4int i0 = i, i1 = i0 + 1, i2 = i1 + 1;
391       p[i0] = (p[i2] * dt + p[i1]) * dt + p[i0    391       p[i0] = (p[i2] * dt + p[i1]) * dt + p[i0];
392       p[i1] = p[i1] + 2 * dt * p[i2];             392       p[i1] = p[i1] + 2 * dt * p[i2];
393     }                                             393     }
394                                                   394 
395   private:                                        395   private:
396                                                   396 
397     QSS_simulator simulator;                      397     QSS_simulator simulator;
398 };                                                398 };
399                                                   399 
400 #endif                                            400 #endif
401                                                   401