Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4ChordFinderSaf.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26
27
28#include "G4ChordFinderSaf.hh"
29#include <iomanip>
30
31// ..........................................................................
32
34 : G4ChordFinder(pIntegrationDriver)
35{
36 // check the values and set the other parameters
37 // fNoInitialRadBig=0; fNoInitialRadSmall=0;
38 // fNoTrialsRadBig=0; fNoTrialsRadSmall=0;
39
40}
41
42// ..........................................................................
43
45 G4double stepMinimum,
46 G4MagIntegratorStepper* pItsStepper )
47 : G4ChordFinder( theMagField, stepMinimum, pItsStepper )
48{
49 // Let G4ChordFinder create the Driver, the Stepper and EqRhs ...
50 // ...
51}
52
53// ......................................................................
54
55// ......................................................................
56
58{
59 if( SetVerbose(0) ) { PrintStatistics(); }
60 // Set verbosity 0, so that will be called in base class again
61}
62
63void
65{
66 // Print Statistics
67 G4cout << "G4ChordFinderSaf statistics report: " << G4endl;
69
70/*******************
71 G4cout
72 << " No radbig calls " << std::setw(10) << fNoInitialRadBig
73 << " trials " << std::setw(10) << fNoTrialsRadBig
74 << " - over " << std::setw(10) << fNoTrialsRadBig - fNoInitialRadBig
75 << G4endl
76 << " No radsm calls " << std::setw(10) << fNoInitialRadSmall
77 << " trials " << std::setw(10) << fNoTrialsRadSmall
78 << " - over " << std::setw(10) << fNoTrialsRadSmall - fNoInitialRadSmall
79 << G4endl;
80 G4cout
81 << " *** Limiting stepTrial via if Delta_chord < R_curvature "
82 << " for large to angle from Delta_chord / R_curv "
83 << " and for small with multiple " << GetMultipleRadius()
84 << G4endl;
85********************/
86}
87
88
89// G4SafetyDist::
90// inline
93 G4double safetyRadius,
94 G4ThreeVector point)
95{
96 G4double pointSafety= 0.0;
97
98 G4ThreeVector OriginShift = point - safetyOrigin ;
99 G4double MagSqShift = OriginShift.mag2() ;
100 if( MagSqShift < sqr(safetyRadius) ){
101 pointSafety = safetyRadius - std::sqrt(MagSqShift) ;
102 }
103
104 return pointSafety;
105}
106
107// inline
108G4bool
110 G4double safetyRadius,
111 G4ThreeVector point)
112{
113 G4ThreeVector OriginShift = point - safetyOrigin ;
114 return ( OriginShift.mag2() < safetyRadius*safetyRadius );
115}
116
119 G4double stepMax,
120 G4FieldTrack& yEnd, // Endpoint
121 G4double& dyErrPos, // Error of endpoint
122 G4double epsStep,
123 G4double* pStepForAccuracy,
124 const G4ThreeVector latestSafetyOrigin,
125 G4double latestSafetyRadius
126 )
127 // Returns Length of Step taken
128{
129 // G4int stepRKnumber=0;
130 G4FieldTrack yCurrent= yStart;
131 G4double stepTrial, stepForAccuracy;
133
134 // 1.) Try to "leap" to end of interval
135 // 2.) Evaluate if resulting chord gives d_chord that is good enough.
136 // 2a.) If d_chord is not good enough, find one that is.
137
138 G4bool validEndPoint= false;
139 G4double dChordStep, lastStepLength; // stepOfLastGoodChord;
140
141 GetIntegrationDriver()-> GetDerivatives( yCurrent, dydx ) ;
142
143 G4int noTrials=0;
144 const G4double safetyFactor= GetFirstFraction(); // was 0.999
145
146 // Figure out the starting safety
147 G4double startSafety=
148 CalculatePointSafety( latestSafetyOrigin,
149 latestSafetyRadius,
150 yCurrent.GetPosition() );
151
153 likelyGood = std::max( startSafety ,
154 safetyFactor * GetLastStepEstimateUnc() );
155
156 stepTrial = std::min( stepMax, likelyGood );
157
159 G4double newStepEst_Uncons= 0.0;
160 do
161 {
162 G4double stepForChord;
163 yCurrent = yStart; // Always start from initial point
164
165 // ************
166 pIntgrDriver->QuickAdvance( yCurrent, dydx, stepTrial,
167 dChordStep, dyErrPos);
168 // ************
169
170 G4ThreeVector EndPointCand= yCurrent.GetPosition();
171 G4bool endPointInSafetySphere=
172 CalculatePointInside(latestSafetyOrigin, latestSafetyRadius, EndPointCand);
173
174 // We check whether the criterion is met here.
175 validEndPoint = AcceptableMissDist(dChordStep)
176 || endPointInSafetySphere;
177 // && (dyErrPos < eps) ;
178
179 lastStepLength = stepTrial;
180
181 // This method estimates to step size for a good chord.
182 stepForChord = NewStep(stepTrial, dChordStep, newStepEst_Uncons );
183
184 if( ! validEndPoint ) {
185 if( stepTrial<=0.0 )
186 stepTrial = stepForChord;
187 else if (stepForChord <= stepTrial)
188 // Reduce by a fraction, possibly up to 20%
189 stepTrial = std::min( stepForChord,
190 GetFractionLast() * stepTrial);
191 else
192 stepTrial *= 0.1;
193
194 // if(dbg) G4cerr<<"Dchord too big. Try new hstep="<<stepTrial<<G4endl;
195 }
196 // #ifdef TEST_CHORD_PRINT
197 // TestChordPrint( noTrials, lastStepLength, dChordStep, stepTrial );
198 // #endif
199
200 noTrials++;
201 }
202 while( ! validEndPoint ); // End of do-while RKD
203
204 AccumulateStatistics( noTrials );
205
206 // Should we update newStepEst_Uncons for a 'long step' via safety ??
207 if( newStepEst_Uncons > 0.0 ){
208 SetLastStepEstimateUnc( newStepEst_Uncons );
209 }
210
211 // stepOfLastGoodChord = stepTrial;
212
213 if( pStepForAccuracy ){
214 // Calculate the step size required for accuracy, if it is needed
215 G4double dyErr_relative = dyErrPos/(epsStep*lastStepLength);
216 if( dyErr_relative > 1.0 ) {
217 stepForAccuracy =
218 pIntgrDriver->ComputeNewStepSize( dyErr_relative,
219 lastStepLength );
220 }else{
221 stepForAccuracy = 0.0; // Convention to show step was ok
222 }
223 *pStepForAccuracy = stepForAccuracy;
224 }
225
226#ifdef TEST_CHORD_PRINT
227 static int dbg=0;
228 if( dbg )
229 G4cout << "ChordF/FindNextChord: NoTrials= " << noTrials
230 << " StepForGoodChord=" << std::setw(10) << stepTrial << G4endl;
231#endif
232
233 yEnd= yCurrent;
234 return stepTrial;
235}
G4double CalculatePointSafety(G4ThreeVector safetyOrigin, G4double safetyRadius, G4ThreeVector point)
G4bool CalculatePointInside(G4ThreeVector safetyOrigin, G4double safetyRadius, G4ThreeVector point)
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
double mag2() const
G4ChordFinderSaf(G4MagInt_Driver *pIntegrationDriver)
G4double FindNextChord(const G4FieldTrack &yStart, G4double stepMax, G4FieldTrack &yEnd, G4double &dyErrPos, G4double epsStep, G4double *pStepForAccuracy, const G4ThreeVector latestSafetyOrigin, G4double latestSafetyRadius)
void SetLastStepEstimateUnc(G4double stepEst)
G4bool AcceptableMissDist(G4double dChordStep) const
G4double NewStep(G4double stepTrialOld, G4double dChordStep, G4double &stepEstimate_Unconstrained)
G4double GetLastStepEstimateUnc()
G4int SetVerbose(G4int newvalue=1)
void AccumulateStatistics(G4int noTrials)
G4double GetFractionLast()
virtual void PrintStatistics()
G4MagInt_Driver * GetIntegrationDriver()
G4double GetFirstFraction()
G4ThreeVector GetPosition() const
G4double ComputeNewStepSize(G4double errMaxNorm, G4double hstepCurrent)
G4bool QuickAdvance(G4FieldTrack &y_val, const G4double dydx[], G4double hstep, G4double &dchord_step, G4double &dyerr)
T sqr(const T &x)
Definition: templates.hh:145