Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4INCL::RootFinder Namespace Reference

Classes

class  Solution
 

Functions

Solution solve (RootFunctor const *const f, const G4double x0)
 Numerically solve a one-dimensional equation.
 

Function Documentation

◆ solve()

Solution G4INCL::RootFinder::solve ( RootFunctor const *const  f,
const G4double  x0 
)

Numerically solve a one-dimensional equation.

Numerically solves the equation f(x)==0. This implementation uses the false-position method.

If a root is found, it can be retrieved using the getSolution() method,

Parameters
fpointer to a RootFunctor
x0initial value of the function argument
Returns
a Solution object describing the root, if it was found

Definition at line 118 of file G4INCLRootFinder.cc.

118 {
119 // If we already have the solution, do nothing
120 const G4double y0 = (*f)(x0);
121 if( std::abs(y0) < toleranceY ) {
122 return Solution(x0,y0);
123 }
124
125 // Bracket the root and set the initial values
126 std::pair<G4double,G4double> bracket = bracketRoot(f,x0);
127 G4double x1 = bracket.first;
128 G4double x2 = bracket.second;
129 // If x1>x2, it means that we could not bracket the root. Return false.
130 if(x1>x2) {
131 // Maybe zero is a good solution?
132 G4double y_at_zero = (*f)(0.);
133 if(std::abs(y_at_zero)<=toleranceY) {
134 f->cleanUp(true);
135 return Solution(0.,y_at_zero);
136 } else {
137 INCL_DEBUG("Root-finding algorithm could not bracket the root." << '\n');
138 f->cleanUp(false);
139 return Solution();
140 }
141 }
142
143 G4double y1 = (*f)(x1);
144 G4double y2 = (*f)(x2);
145 G4double x = x1;
146 G4double y = y1;
147
148 /* ********************************
149 * Start of the false-position loop
150 * ********************************/
151
152 // Keep track of the last updated interval end (-1=left, 1=right)
153 G4int lastUpdated = 0;
154
155 for(G4int iterations=0; std::abs(y) > toleranceY; iterations++) {
156
157 if(iterations > maxIterations) {
158 INCL_DEBUG("Root-finding algorithm did not converge." << '\n');
159 f->cleanUp(false);
160 return Solution();
161 }
162
163 // Estimate the root position by linear interpolation
164 x = (y1*x2-y2*x1)/(y1-y2);
165
166 // Update the value of the function
167 y = (*f)(x);
168
169 // Update the bracketing interval
170 if(Math::sign(y) == Math::sign(y1)) {
171 x1=x;
172 y1=y;
173 if(lastUpdated==-1) y2 *= 0.5;
174 lastUpdated = -1;
175 } else {
176 x2=x;
177 y2=y;
178 if(lastUpdated==1) y1 *= 0.5;
179 lastUpdated = 1;
180 }
181 }
182
183 /* ******************************
184 * End of the false-position loop
185 * ******************************/
186
187 f->cleanUp(true);
188 return Solution(x,y);
189 }
#define INCL_DEBUG(x)
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85

Referenced by G4INCL::InteractionAvatar::enforceEnergyConservation().