Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4ConstRK4.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// G4ConstRK4 implementation
27//
28// Created: J.Apostolakis, T.Nikitina - 18.09.2008
29// -------------------------------------------------------------------
30
31#include "G4ConstRK4.hh"
32#include "G4ThreeVector.hh"
33#include "G4LineSection.hh"
34
35//////////////////////////////////////////////////////////////////
36//
37// Constructor sets the number of *State* variables (default = 8)
38// The number of variables integrated is always 6
39//
40G4ConstRK4::G4ConstRK4(G4Mag_EqRhs* EqRhs, G4int numStateVariables)
41 : G4MagErrorStepper(EqRhs, 6, numStateVariables)
42{
43 // const G4int numberOfVariables= 6;
44 if( numStateVariables < 8 )
45 {
46 std::ostringstream message;
47 message << "The number of State variables at least 8 " << G4endl
48 << "Instead it is - numStateVariables= " << numStateVariables;
49 G4Exception("G4ConstRK4::G4ConstRK4()", "GeomField0002",
50 FatalException, message, "Use another Stepper!");
51 }
52
53 fEq = EqRhs;
54 yMiddle = new G4double[8];
55 dydxMid = new G4double[8];
56 yInitial = new G4double[8];
57 yOneStep = new G4double[8];
58
59 dydxm = new G4double[8];
60 dydxt = new G4double[8];
61 yt = new G4double[8];
62 Field[0]=0.; Field[1]=0.; Field[2]=0.;
63}
64
65////////////////////////////////////////////////////////////////
66//
67// Destructor
68
70{
71 delete [] yMiddle;
72 delete [] dydxMid;
73 delete [] yInitial;
74 delete [] yOneStep;
75 delete [] dydxm;
76 delete [] dydxt;
77 delete [] yt;
78}
79
80//////////////////////////////////////////////////////////////////////
81//
82// Given values for the variables y[0,..,n-1] and their derivatives
83// dydx[0,...,n-1] known at x, use the classical 4th Runge-Kutta
84// method to advance the solution over an interval h and return the
85// incremented variables as yout[0,...,n-1], which is not a distinct
86// array from y. The user supplies the routine RightHandSide(x,y,dydx),
87// which returns derivatives dydx at x. The source is routine rk4 from
88// NRC p. 712-713 .
89//
91 const G4double dydx[],
92 G4double h,
93 G4double yOut[])
94{
95 G4double hh = h*0.5 , h6 = h/6.0 ;
96
97 // 1st Step K1=h*dydx
98 yt[5] = yIn[5] + hh*dydx[5] ;
99 yt[4] = yIn[4] + hh*dydx[4] ;
100 yt[3] = yIn[3] + hh*dydx[3] ;
101 yt[2] = yIn[2] + hh*dydx[2] ;
102 yt[1] = yIn[1] + hh*dydx[1] ;
103 yt[0] = yIn[0] + hh*dydx[0] ;
104 RightHandSideConst(yt,dydxt) ;
105
106 // 2nd Step K2=h*dydxt
107 yt[5] = yIn[5] + hh*dydxt[5] ;
108 yt[4] = yIn[4] + hh*dydxt[4] ;
109 yt[3] = yIn[3] + hh*dydxt[3] ;
110 yt[2] = yIn[2] + hh*dydxt[2] ;
111 yt[1] = yIn[1] + hh*dydxt[1] ;
112 yt[0] = yIn[0] + hh*dydxt[0] ;
113 RightHandSideConst(yt,dydxm) ;
114
115 // 3rd Step K3=h*dydxm
116 // now dydxm=(K2+K3)/h
117 yt[5] = yIn[5] + h*dydxm[5] ;
118 dydxm[5] += dydxt[5] ;
119 yt[4] = yIn[4] + h*dydxm[4] ;
120 dydxm[4] += dydxt[4] ;
121 yt[3] = yIn[3] + h*dydxm[3] ;
122 dydxm[3] += dydxt[3] ;
123 yt[2] = yIn[2] + h*dydxm[2] ;
124 dydxm[2] += dydxt[2] ;
125 yt[1] = yIn[1] + h*dydxm[1] ;
126 dydxm[1] += dydxt[1] ;
127 yt[0] = yIn[0] + h*dydxm[0] ;
128 dydxm[0] += dydxt[0] ;
129 RightHandSideConst(yt,dydxt) ;
130
131 // 4th Step K4=h*dydxt
132 yOut[5] = yIn[5]+h6*(dydx[5]+dydxt[5]+2.0*dydxm[5]);
133 yOut[4] = yIn[4]+h6*(dydx[4]+dydxt[4]+2.0*dydxm[4]);
134 yOut[3] = yIn[3]+h6*(dydx[3]+dydxt[3]+2.0*dydxm[3]);
135 yOut[2] = yIn[2]+h6*(dydx[2]+dydxt[2]+2.0*dydxm[2]);
136 yOut[1] = yIn[1]+h6*(dydx[1]+dydxt[1]+2.0*dydxm[1]);
137 yOut[0] = yIn[0]+h6*(dydx[0]+dydxt[0]+2.0*dydxm[0]);
138
139} // end of DumbStepper ....................................................
140
141////////////////////////////////////////////////////////////////
142//
143// Stepper
144
145void
147 const G4double dydx[],
148 G4double hstep,
149 G4double yOutput[],
150 G4double yError [] )
151{
152 const G4int nvar = 6; // number of variables integrated
153 const G4int maxvar = GetNumberOfStateVariables();
154
155 // Correction for Richardson extrapolation
156 G4double correction = 1. / ( (1 << IntegratorOrder()) -1 );
157
158 G4int i;
159
160 // Saving yInput because yInput and yOutput can be aliases for same array
161 for (i=0; i<maxvar; ++i) { yInitial[i]= yInput[i]; }
162
163 // Must copy the part of the state *not* integrated to the output
164 for (i=nvar; i<maxvar; ++i) { yOutput[i]= yInput[i]; }
165
166 // yInitial[7]= yInput[7]; // The time is typically needed
167 yMiddle[7] = yInput[7]; // Copy the time from initial value
168 yOneStep[7] = yInput[7]; // As it contributes to final value of yOutput ?
169 // yOutput[7] = yInput[7]; // -> dumb stepper does it too for RK4
170 yError[7] = 0.0;
171
172 G4double halfStep = hstep * 0.5;
173
174 // Do two half steps
175 //
176 GetConstField(yInitial,Field);
177 DumbStepper (yInitial, dydx, halfStep, yMiddle);
178 RightHandSideConst(yMiddle, dydxMid);
179 DumbStepper (yMiddle, dydxMid, halfStep, yOutput);
180
181 // Store midpoint, chord calculation
182 //
183 fMidPoint = G4ThreeVector( yMiddle[0], yMiddle[1], yMiddle[2]);
184
185 // Do a full Step
186 //
187 DumbStepper(yInitial, dydx, hstep, yOneStep);
188 for(i=0; i<nvar; ++i)
189 {
190 yError [i] = yOutput[i] - yOneStep[i] ;
191 yOutput[i] += yError[i]*correction ;
192 // Provides accuracy increased by 1 order via the
193 // Richardson extrapolation
194 }
195
196 fInitialPoint = G4ThreeVector( yInitial[0], yInitial[1], yInitial[2]);
197 fFinalPoint = G4ThreeVector( yOutput[0], yOutput[1], yOutput[2]);
198
199 return;
200}
201
202////////////////////////////////////////////////////////////////
203//
204// Estimate the maximum distance from the curve to the chord
205//
206// We estimate this using the distance of the midpoint to chord.
207// The method below is good only for angle deviations < 2 pi;
208// this restriction should not be a problem for the Runge Kutta methods,
209// which generally cannot integrate accurately for large angle deviations
210//
212{
213 G4double distLine, distChord;
214
215 if (fInitialPoint != fFinalPoint)
216 {
217 distLine= G4LineSection::Distline( fMidPoint, fInitialPoint, fFinalPoint );
218 // This is a class method that gives distance of Mid
219 // from the Chord between the Initial and Final points
220 distChord = distLine;
221 }
222 else
223 {
224 distChord = (fMidPoint-fInitialPoint).mag();
225 }
226 return distChord;
227}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition G4Types.hh:83
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
void Stepper(const G4double y[], const G4double dydx[], G4double h, G4double yout[], G4double yerr[]) override
G4double DistChord() const override
G4int IntegratorOrder() const override
Definition G4ConstRK4.hh:72
~G4ConstRK4() override
Definition G4ConstRK4.cc:69
void RightHandSideConst(const G4double y[], G4double dydx[]) const
Definition G4ConstRK4.hh:86
G4ConstRK4(G4Mag_EqRhs *EquationMotion, G4int numberOfStateVariables=8)
Definition G4ConstRK4.cc:40
void DumbStepper(const G4double yIn[], const G4double dydx[], G4double h, G4double yOut[]) override
Definition G4ConstRK4.cc:90
void GetConstField(const G4double y[], G4double Field[])
static G4double Distline(const G4ThreeVector &OtherPnt, const G4ThreeVector &LinePntA, const G4ThreeVector &LinePntB)
G4int GetNumberOfStateVariables() const