Import Geant4 11.4.0 source tree
This commit is contained in:
@@ -6,6 +6,65 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 2025-11-03 Vladimir Ivanchenko (field-V11-03-09)
|
||||
- G4TClassicalRK4 - fixed typo identified by CMS
|
||||
|
||||
## 2025-10-21 Gabriele Cosmo (field-V11-03-08)
|
||||
- Reorganised and enriched comments in headers to follow Doxygen style.
|
||||
- Moved inline implementations to .icc file for G4ChargeState and for
|
||||
G4FieldParameters.
|
||||
- Removed not implemented methods in G4ChordFinder, G4DoLoMcPriRK34 and
|
||||
G4FieldSetup.
|
||||
|
||||
## 2025-09-09 Gabriele Cosmo (field-V11-03-07)
|
||||
- Applied clang-tidy fixes: basic, modernize-use-default-member-init,
|
||||
readability-redundant-member-init, modernize-use-emplace,
|
||||
readability-container-size-empty, readability-implicit-bool-conversion,
|
||||
performance-unnecessary-value-param, readability-else-after-return,
|
||||
modernize-return-braced-init-list.
|
||||
- Minor code cleanup and formatting.
|
||||
|
||||
## 2025-09-08 Gabriele Cosmo (field-V11-03-06)
|
||||
- Disabled use of QSS as default stepper in G4ChordFinder.
|
||||
|
||||
## 2025-08-19 John Apostolakis (field-V11-03-05)
|
||||
- Fixed big bug in method compare_time_and_update, from conversion of macro
|
||||
- Enabled use of QSS3 (now a choice in G4ChordFinder).
|
||||
- Addressed Coverity issues (memory leak, initialisation) in G4QSStepper
|
||||
and G4QSSubstepStruct.
|
||||
- G4QSSMessenger: added QSS3 as option, made data private, added access methods
|
||||
- G4QSStepper: cleanup of constructors, made qssOrder const data member.
|
||||
- testQssDriver.cc : corrected and improved this unit test, a critical check.
|
||||
|
||||
## 2025-08-11 Ivana Hrivnacova (field-V11-03-04)
|
||||
- Added default implementation to pure virtual functions introduced in the
|
||||
previous tag for backward compatibility:
|
||||
G4MagIntegratorStepper.hh:
|
||||
virtual G4StepperType StepperType() const { return kUserStepper; }
|
||||
G4Field.hh
|
||||
virtual G4FieldType GetFieldType() const { return kUserFieldType; }
|
||||
|
||||
## 2025-06-23 Ivana Hrivnacova (field-V11-03-03)
|
||||
- Consistent use of the parameters introduced in G4FieldParameters
|
||||
in field classes:
|
||||
- Extracted default parameters values as constexpr in new namespace 'G4FieldDefaults',
|
||||
so that they can be used in other classes as default parameters in functions
|
||||
declarations
|
||||
- Replaced defalut values in 'G4FieldManager' and 'G4ChordFinder' with
|
||||
'G4FieldDefaults' constants
|
||||
- Added functions for accessing the field, stepper and equation types
|
||||
using the enum types defined in 'G4FieldParameters':
|
||||
G4MagIntegratorStepper.hh:
|
||||
virtual G4StepperType StepperType() const = 0;
|
||||
G4Field.hh
|
||||
virtual G4FieldType GetFieldType() const = 0;
|
||||
G4EquationOfMotion.hh:
|
||||
virtual G4EquationType GetEquationType() const { return kUserEquation; }
|
||||
and their implementation in all derived classes defined in the magneticfield category
|
||||
- Updated enums 'G4EquationType' and 'G4StepperType' with missing constants
|
||||
with a comment that these equations/templated steppers are not built by G4FieldBuilder
|
||||
- Renamed 'const G4String& G4DormandPrince745::StepperType() const;' in 'StepperTypeName'
|
||||
|
||||
## 2025-06-13 Gabriele Cosmo (field-V11-03-02)
|
||||
- Fixed compilation warning in G4QSStepper and minor code formatting.
|
||||
|
||||
@@ -123,7 +182,6 @@ It must **not** be used as a substitute for writing good git commit messages!
|
||||
- Fixed compilation warnings for implicit type conversions on macOS/XCode 14.1.
|
||||
|
||||
## 2022-11-05 Divyansh Tiwari, John Apostolakis (field-V11-00-02)
|
||||
|
||||
- Introduced G4BorisScheme and G4BorisDriver, a 2nd order symplectic
|
||||
integration method, created as part of GSoC 2022.
|
||||
|
||||
@@ -243,7 +301,6 @@ March 13, 2020 J.Apostolakis - field-V10-06-03
|
||||
( Done to enable comparisons with new G4IntegrationDriver<> implementation.)
|
||||
- G4OldMagIntDriver maintains all old behaviour of G4MagInt_Driver.
|
||||
|
||||
|
||||
January 22, 2020 G.Cosmo - field-V10-06-02
|
||||
------------------------
|
||||
- Fixed compilation errors and configuration for field07 unit test.
|
||||
|
||||
@@ -27,9 +27,10 @@
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// Specialized integration driver for pure magnetic field
|
||||
// Specialised integration driver for pure magnetic field.
|
||||
|
||||
// Author: D.Sorokin
|
||||
// Author: Dmitry Sorokin (CERN, Google Summer of Code 2017), 12.09.2018
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4BFIELD_INTEGRATION_DRIVER_HH
|
||||
#define G4BFIELD_INTEGRATION_DRIVER_HH
|
||||
@@ -39,115 +40,143 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
/**
|
||||
* @brief G4BFieldIntegrationDriver is specialised integration driver
|
||||
* for pure magnetic field.
|
||||
*/
|
||||
|
||||
class G4BFieldIntegrationDriver : public G4VIntegrationDriver
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for the integrator driver.
|
||||
* @param[in] smallStepDriver Pointer to driver for small steps.
|
||||
* @param[in] largeStepDriver Pointer to driver for large steps.
|
||||
*/
|
||||
G4BFieldIntegrationDriver(
|
||||
std::unique_ptr<G4VIntegrationDriver> smallStepDriver,
|
||||
std::unique_ptr<G4VIntegrationDriver> largeStepDriver);
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4BFieldIntegrationDriver() override = default;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4BFieldIntegrationDriver(const G4BFieldIntegrationDriver &) = delete;
|
||||
const G4BFieldIntegrationDriver& operator =(const G4BFieldIntegrationDriver &) = delete;
|
||||
|
||||
/**
|
||||
* Computes the step to take, based on chord limits.
|
||||
* @param[in,out] track The current track in field.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[in] eps Requested accuracy, y_err/hstep.
|
||||
* @param[in] chordDistance Maximum sagitta distance.
|
||||
* @returns The length of step taken.
|
||||
*/
|
||||
G4double AdvanceChordLimited(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps,
|
||||
G4double chordDistance) override;
|
||||
|
||||
G4bool AccurateAdvance(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps,
|
||||
G4double hinitial = 0) override
|
||||
{
|
||||
return fCurrDriver->AccurateAdvance(track, hstep, eps, hinitial);
|
||||
}
|
||||
/**
|
||||
* Integrates ODE from current s (s=s0) to s=s0+h with accuracy eps.
|
||||
* @param[in,out] track The current track in field.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[in] eps Requested accuracy, y_err/hstep.
|
||||
* @param[in] hinitial Initial minimum integration step.
|
||||
* @returns true if integration succeeds.
|
||||
*/
|
||||
inline G4bool AccurateAdvance(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps,
|
||||
G4double hinitial = 0) override;
|
||||
|
||||
G4bool DoesReIntegrate() const override
|
||||
{
|
||||
return fCurrDriver->DoesReIntegrate();
|
||||
}
|
||||
/**
|
||||
* Checks whether the driver implements re-integration.
|
||||
* @returns true if driver *Recalculates* when AccurateAdvance() is called.
|
||||
*/
|
||||
inline G4bool DoesReIntegrate() const override;
|
||||
|
||||
//[[deprecated("will be removed")]]
|
||||
void GetDerivatives(const G4FieldTrack& track,
|
||||
G4double dydx[]) const override
|
||||
{
|
||||
fCurrDriver->GetDerivatives(track, dydx);
|
||||
}
|
||||
|
||||
//[[deprecated("will be removed")]]
|
||||
void GetDerivatives(const G4FieldTrack& track,
|
||||
G4double dydx[],
|
||||
G4double field[]) const override
|
||||
{
|
||||
fCurrDriver->GetDerivatives(track, dydx, field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter and getter for the equation of motion.
|
||||
*/
|
||||
void SetEquationOfMotion(G4EquationOfMotion* equation) override;
|
||||
inline G4EquationOfMotion* GetEquationOfMotion() override;
|
||||
|
||||
G4EquationOfMotion* GetEquationOfMotion() override
|
||||
{
|
||||
return fCurrDriver->GetEquationOfMotion();
|
||||
}
|
||||
/**
|
||||
* Returns a pointer to the integrator stepper.
|
||||
*/
|
||||
inline G4MagIntegratorStepper* GetStepper() override;
|
||||
|
||||
//[[deprecated("use GetEquationOfMotion() instead of GetStepper()->GetEquationOfMotion()")]]
|
||||
const G4MagIntegratorStepper* GetStepper() const override
|
||||
{
|
||||
return fCurrDriver->GetStepper();
|
||||
}
|
||||
/**
|
||||
* Computes a step size for the next step, taking the last step's
|
||||
* normalised error 'errMaxNorm'.
|
||||
* @param[in] errMaxNorm The normalised error on last step.
|
||||
* @param[in] hstepCurrent The current proposed step.
|
||||
* @returns The step size for the next step.
|
||||
*/
|
||||
inline G4double ComputeNewStepSize(G4double errMaxNorm,
|
||||
G4double hstepCurrent) override;
|
||||
|
||||
G4MagIntegratorStepper* GetStepper() override
|
||||
{
|
||||
return fCurrDriver->GetStepper();
|
||||
}
|
||||
/**
|
||||
* Setter and getter for verbosity.
|
||||
*/
|
||||
inline void SetVerboseLevel(G4int level) override;
|
||||
inline G4int GetVerboseLevel() const override;
|
||||
|
||||
G4double ComputeNewStepSize(G4double errMaxNorm,
|
||||
G4double hstepCurrent) override
|
||||
{
|
||||
return fCurrDriver->ComputeNewStepSize(errMaxNorm, hstepCurrent);
|
||||
}
|
||||
/**
|
||||
* Dispatch interface method for computing step.
|
||||
*/
|
||||
inline void OnComputeStep(const G4FieldTrack* track) override;
|
||||
|
||||
void SetVerboseLevel(G4int level) override
|
||||
{
|
||||
fSmallStepDriver->SetVerboseLevel(level);
|
||||
fLargeStepDriver->SetVerboseLevel(level);
|
||||
}
|
||||
/**
|
||||
* Dispatch interface method for initialisation/reset of driver.
|
||||
*/
|
||||
inline void OnStartTracking() override;
|
||||
|
||||
G4int GetVerboseLevel() const override
|
||||
{
|
||||
return fCurrDriver->GetVerboseLevel();
|
||||
}
|
||||
|
||||
void OnComputeStep(const G4FieldTrack* track) override
|
||||
{
|
||||
fSmallStepDriver->OnComputeStep(track);
|
||||
fLargeStepDriver->OnComputeStep(track);
|
||||
}
|
||||
|
||||
void OnStartTracking() override
|
||||
{
|
||||
fSmallStepDriver->OnStartTracking();
|
||||
fLargeStepDriver->OnStartTracking();
|
||||
}
|
||||
|
||||
void StreamInfo( std::ostream& os ) const override
|
||||
{
|
||||
os << "Small Step Driver Info: " << std::endl;
|
||||
fSmallStepDriver->StreamInfo(os);
|
||||
os << "Large Step Driver Info: " << std::endl;
|
||||
fLargeStepDriver->StreamInfo(os);
|
||||
}
|
||||
// Write out the parameters / state of the driver
|
||||
/**
|
||||
* Writes out to stream the parameters/state of the driver.
|
||||
*/
|
||||
inline void StreamInfo( std::ostream& os ) const override;
|
||||
|
||||
/**
|
||||
* Prints out statistics of the integrator driver.
|
||||
*/
|
||||
void PrintStatistics() const;
|
||||
|
||||
/** [[deprecated("will be removed")]] */
|
||||
inline void GetDerivatives(const G4FieldTrack& track,
|
||||
G4double dydx[]) const override;
|
||||
|
||||
/** [[deprecated("will be removed")]] */
|
||||
inline void GetDerivatives(const G4FieldTrack& track,
|
||||
G4double dydx[],
|
||||
G4double field[]) const override;
|
||||
|
||||
/** [[deprecated("use GetEquationOfMotion() instead of GetStepper()->GetEquationOfMotion()")]] */
|
||||
inline const G4MagIntegratorStepper* GetStepper() const override;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Given the field track, computes the radius of the curvature in field.
|
||||
*/
|
||||
G4double CurvatureRadius(const G4FieldTrack& track) const;
|
||||
|
||||
/**
|
||||
* Returns the value of the field in the 'Field' array, give the track.
|
||||
* @param[in] track The current field track.
|
||||
* @param[in,out] Field The array with field values.
|
||||
*/
|
||||
void GetFieldValue(const G4FieldTrack& track,
|
||||
G4double Field[] ) const;
|
||||
G4double Field[] ) const;
|
||||
|
||||
private:
|
||||
|
||||
std::unique_ptr<G4VIntegrationDriver> fSmallStepDriver;
|
||||
std::unique_ptr<G4VIntegrationDriver> fLargeStepDriver;
|
||||
G4VIntegrationDriver* fCurrDriver = nullptr;
|
||||
@@ -157,4 +186,6 @@ class G4BFieldIntegrationDriver : public G4VIntegrationDriver
|
||||
G4int fLargeDriverSteps = 0;
|
||||
};
|
||||
|
||||
#include "G4BFieldIntegrationDriver.icc"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,99 +23,103 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// class G4BFieldIntegrationDriver
|
||||
// G4BFieldIntegrationDriver inline methods
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// Specialized integration driver for pure magnetic field
|
||||
|
||||
// Author: D.Sorokin, CERN
|
||||
// Author: Dmitry Sorokin (CERN, Google Summer of Code), 12.09.2018
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "globals.hh"
|
||||
#include "G4GeometryTolerance.hh"
|
||||
#include "G4FieldTrack.hh"
|
||||
#include "G4FieldUtils.hh"
|
||||
|
||||
namespace internal
|
||||
{
|
||||
G4Mag_EqRhs* toMagneticEquation(G4EquationOfMotion* equation)
|
||||
{
|
||||
auto e = dynamic_cast<G4Mag_EqRhs*>(equation);
|
||||
if (!e)
|
||||
{
|
||||
G4Exception("G4BFieldIntegrationDriver::G4BFieldIntegrationDriver",
|
||||
"GeomField0003", FatalErrorInArgument,
|
||||
"Works only with G4Mag_EqRhs");
|
||||
}
|
||||
return e;
|
||||
}
|
||||
} // internal
|
||||
|
||||
|
||||
template <class T>
|
||||
G4BFieldIntegrationDriver<T>::G4BFieldIntegrationDriver(G4double hminimum,
|
||||
T* pStepper,
|
||||
G4int numComponents,
|
||||
G4int statisticsVerbose)
|
||||
: G4IntegrationDriver<T>(hminimum, pStepper, numComponents, statisticsVerbose),
|
||||
fallbackThreshold(pi / 3.),
|
||||
fequation(internal::toMagneticEquation(pStepper->GetEquationOfMotion())),
|
||||
fallbackStepper(fequation)
|
||||
inline
|
||||
G4bool G4BFieldIntegrationDriver::AccurateAdvance(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps,
|
||||
G4double hinitial)
|
||||
{
|
||||
return fCurrDriver->AccurateAdvance(track, hstep, eps, hinitial);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool G4BFieldIntegrationDriver<T>::QuickAdvance(G4FieldTrack& fieldTrack,
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double inverseCurvatureRadius,
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr)
|
||||
inline
|
||||
G4bool G4BFieldIntegrationDriver::DoesReIntegrate() const
|
||||
{
|
||||
if (hstep * inverseCurvatureRadius < fallbackThreshold)
|
||||
{
|
||||
return G4IntegrationDriver<T>::QuickAdvance(
|
||||
fieldTrack, dydx, hstep, inverseCurvatureRadius, dchord_step, dyerr);
|
||||
}
|
||||
|
||||
G4IntegrationDriver<T>::IncrementQuickAdvanceCalls();
|
||||
|
||||
G4double yError[G4FieldTrack::ncompSVEC],
|
||||
yIn[G4FieldTrack::ncompSVEC],
|
||||
yOut[G4FieldTrack::ncompSVEC];
|
||||
|
||||
fieldTrack.DumpToArray(yIn);
|
||||
|
||||
fallbackStepper.Stepper(yIn, dydx, hstep, yOut, yError);
|
||||
dchord_step = fallbackStepper.DistChord();
|
||||
dyerr = field_utils::absoluteError(yOut, yError, hstep);
|
||||
|
||||
fieldTrack.LoadFromArray(yOut, fallbackStepper.GetNumberOfVariables());
|
||||
fieldTrack.SetCurveLength(fieldTrack.GetCurveLength() + hstep);
|
||||
|
||||
return true;
|
||||
return fCurrDriver->DoesReIntegrate();
|
||||
}
|
||||
|
||||
inline
|
||||
G4EquationOfMotion* G4BFieldIntegrationDriver::GetEquationOfMotion()
|
||||
{
|
||||
return fCurrDriver->GetEquationOfMotion();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4BFieldIntegrationDriver<T>::
|
||||
SetEquationOfMotion(G4EquationOfMotion* equation)
|
||||
inline
|
||||
G4MagIntegratorStepper* G4BFieldIntegrationDriver::GetStepper()
|
||||
{
|
||||
G4IntegrationDriver<T>::SetEquationOfMotion(equation);
|
||||
fequation = internal::toMagneticEquation(equation);
|
||||
return fCurrDriver->GetStepper();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4double G4BFieldIntegrationDriver<T>::
|
||||
GetInverseCurvatureRadius(const G4FieldTrack& track,
|
||||
G4double field[]) const
|
||||
inline
|
||||
G4double G4BFieldIntegrationDriver::ComputeNewStepSize(G4double errMaxNorm,
|
||||
G4double hstepCurrent)
|
||||
{
|
||||
const G4double Bmag = std::sqrt(field[0] * field[0]
|
||||
+ field[1] * field[1] + field[2] * field[2]);
|
||||
const G4double momentum = track.GetMomentum().mag();
|
||||
const G4double particleCharge = fequation->FCof()
|
||||
/ (CLHEP::eplus * CLHEP::c_light);
|
||||
|
||||
return std::abs(field_utils::inverseCurvatureRadius(particleCharge,
|
||||
momentum, Bmag));
|
||||
return fCurrDriver->ComputeNewStepSize(errMaxNorm, hstepCurrent);
|
||||
}
|
||||
|
||||
inline
|
||||
void G4BFieldIntegrationDriver::SetVerboseLevel(G4int level)
|
||||
{
|
||||
fSmallStepDriver->SetVerboseLevel(level);
|
||||
fLargeStepDriver->SetVerboseLevel(level);
|
||||
}
|
||||
|
||||
inline
|
||||
G4int G4BFieldIntegrationDriver::GetVerboseLevel() const
|
||||
{
|
||||
return fCurrDriver->GetVerboseLevel();
|
||||
}
|
||||
|
||||
inline
|
||||
void G4BFieldIntegrationDriver::OnComputeStep(const G4FieldTrack* track)
|
||||
{
|
||||
fSmallStepDriver->OnComputeStep(track);
|
||||
fLargeStepDriver->OnComputeStep(track);
|
||||
}
|
||||
|
||||
inline
|
||||
void G4BFieldIntegrationDriver::OnStartTracking()
|
||||
{
|
||||
fSmallStepDriver->OnStartTracking();
|
||||
fLargeStepDriver->OnStartTracking();
|
||||
}
|
||||
|
||||
inline
|
||||
void G4BFieldIntegrationDriver::StreamInfo( std::ostream& os ) const
|
||||
{
|
||||
os << "Small Step Driver Info: " << std::endl;
|
||||
fSmallStepDriver->StreamInfo(os);
|
||||
os << "Large Step Driver Info: " << std::endl;
|
||||
fLargeStepDriver->StreamInfo(os);
|
||||
}
|
||||
|
||||
/** ----------------- Deprecated methods ----------------------------------- **/
|
||||
|
||||
inline
|
||||
void G4BFieldIntegrationDriver::GetDerivatives(const G4FieldTrack& track,
|
||||
G4double dydx[]) const
|
||||
{
|
||||
fCurrDriver->GetDerivatives(track, dydx);
|
||||
}
|
||||
|
||||
inline
|
||||
void G4BFieldIntegrationDriver::GetDerivatives(const G4FieldTrack& track,
|
||||
G4double dydx[],
|
||||
G4double field[]) const
|
||||
{
|
||||
fCurrDriver->GetDerivatives(track, dydx, field);
|
||||
}
|
||||
|
||||
inline
|
||||
const G4MagIntegratorStepper* G4BFieldIntegrationDriver::GetStepper() const
|
||||
{
|
||||
return fCurrDriver->GetStepper();
|
||||
}
|
||||
|
||||
/** ------------------------------------------------------------------------ **/
|
||||
|
||||
@@ -27,19 +27,19 @@
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// Bogacki-Shampine - 4 - 3(2) non-FSAL implementation
|
||||
// Bogacki-Shampine - 4 - 3(2) non-FSAL implementation
|
||||
//
|
||||
// An implementation of the embedded RK method from the paper
|
||||
// An implementation of the embedded RK method from the paper
|
||||
// [1] P. Bogacki and L. F. Shampine,
|
||||
// "A 3(2) pair of Runge - Kutta formulas"
|
||||
// Appl. Math. Lett., vol. 2, no. 4, pp. 321-325, Jan. 1989.
|
||||
//
|
||||
// This version does not utilise the FSAL property of the method,
|
||||
// which would allow the reuse of the last derivative in the next step.
|
||||
// (Alternative FSAL implementation created with revised interface)
|
||||
// This version does not utilise the FSAL property of the method,
|
||||
// which would allow the reuse of the last derivative in the next step.
|
||||
// (Alternative FSAL implementation created with revised interface)
|
||||
|
||||
// Created: Somnath Banerjee, Google Summer of Code 2015, 20 May 2015
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// Author: Somnath Banerjee (CERN, Google Summer of Code 2015), 20.05.2015
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4BOGACKI_SHAMPINE23_HH
|
||||
#define G4BOGACKI_SHAMPINE23_HH
|
||||
@@ -47,19 +47,60 @@
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
#include "G4FieldTrack.hh"
|
||||
|
||||
/**
|
||||
* @brief G4BogackiShampine23 is an integrator of particle's equation of
|
||||
* motion based on the Bogacki-Shampine non-FSAL implementation.
|
||||
*/
|
||||
|
||||
class G4BogackiShampine23 : public G4MagIntegratorStepper
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4BogackiShampine23.
|
||||
* @param[in] EqRhs Pointer to the provided equation of motion.
|
||||
* @param[in] numberOfVariables The number of integration variables.
|
||||
*/
|
||||
G4BogackiShampine23(G4EquationOfMotion* EqRhs,
|
||||
G4int numberOfVariables = 6);
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4BogackiShampine23() override = default;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4BogackiShampine23(const G4BogackiShampine23&) = delete;
|
||||
G4BogackiShampine23& operator = (const G4BogackiShampine23&) = delete;
|
||||
|
||||
/**
|
||||
* The stepper for the Runge Kutta integration.
|
||||
* The stepsize is fixed, with the step size given by 'hstep'.
|
||||
* Integrates ODE starting values yInput[0 to 6].
|
||||
* Outputs yOutput[] and its estimated error yError[].
|
||||
* @param[in] yInput Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] hstep The given step size.
|
||||
* @param[out] yOutput Integration output.
|
||||
* @param[out] yError The estimated error.
|
||||
*/
|
||||
void Stepper(const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[]) override;
|
||||
|
||||
/**
|
||||
* Same as the Stepper() function above, with dydx also in ouput.
|
||||
* @param[in] yInput Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] hstep The given step size.
|
||||
* @param[out] yOutput Integration output.
|
||||
* @param[out] yError The estimated error.
|
||||
* @param[out] dydxOutput dydx in output.
|
||||
*/
|
||||
void Stepper(const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
@@ -67,14 +108,26 @@ class G4BogackiShampine23 : public G4MagIntegratorStepper
|
||||
G4double yError[],
|
||||
G4double dydxOutput[]);
|
||||
|
||||
G4BogackiShampine23(const G4BogackiShampine23&) = delete;
|
||||
G4BogackiShampine23& operator = (const G4BogackiShampine23&) = delete;
|
||||
|
||||
/**
|
||||
* Returns the distance from chord line.
|
||||
*/
|
||||
G4double DistChord() const override;
|
||||
G4int IntegratorOrder() const override { return 3; }
|
||||
|
||||
/**
|
||||
* Returns the order, 3, of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override { return 3; }
|
||||
|
||||
/**
|
||||
* Returns the stepper type-ID, "kBogackiShampine23".
|
||||
*/
|
||||
inline G4StepperType StepperType() const override { return kBogackiShampine23; }
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Utility method used in Stepper() for computing the actual step.
|
||||
*/
|
||||
void makeStep(const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double hstep,
|
||||
@@ -82,6 +135,8 @@ class G4BogackiShampine23 : public G4MagIntegratorStepper
|
||||
G4double* dydxOutput = nullptr,
|
||||
G4double* yError = nullptr) const;
|
||||
|
||||
private:
|
||||
|
||||
G4double fyIn[G4FieldTrack::ncompSVEC],
|
||||
fdydx[G4FieldTrack::ncompSVEC],
|
||||
fyOut[G4FieldTrack::ncompSVEC],
|
||||
|
||||
@@ -27,78 +27,118 @@
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// An implementation of the embedded RK method from the following paper
|
||||
// by P. Bogacki and L. F. Shampine:
|
||||
// "An efficient Runge-Kutta (4,5) pair"
|
||||
// Comput. Math. with Appl., vol. 32, no. 6, pp. 15-28, Sep. 1996.
|
||||
// An implementation of the embedded RK method from the following paper
|
||||
// by P. Bogacki and L. F. Shampine:
|
||||
// "An efficient Runge-Kutta (4,5) pair"
|
||||
// Comput. Math. with Appl., vol. 32, no. 6, pp. 15-28, Sep. 1996.
|
||||
//
|
||||
// An interpolation method provides the value of an intermediate
|
||||
// point in a step -- if a step was sucessful.
|
||||
// An interpolation method provides the value of an intermediate
|
||||
// point in a step -- if a step was sucessful.
|
||||
//
|
||||
// This version can provide the FSAL property of the method,
|
||||
// which allows the reuse of the last derivative in the next step,
|
||||
// but only by using the additional method GetLastDyDx() (an alternative
|
||||
// interface for simpler use of FSAL is under development).
|
||||
// This version can provide the FSAL property of the method,
|
||||
// which allows the reuse of the last derivative in the next step,
|
||||
// but only by using the additional method GetLastDyDx() (an alternative
|
||||
// interface for simpler use of FSAL is under development).
|
||||
|
||||
// Created: Somnath Banerjee, Google Summer of Code 2015, 25 May 2015
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// Author: Somnath Banerjee (CERN, Google Summer of Code 2015), 25.05.2015
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef BOGACKI_SHAMPINE_45_HH
|
||||
#define BOGACKI_SHAMPINE_45_HH
|
||||
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
|
||||
/**
|
||||
* @brief G4BogackiShampine45 is an integrator of particle's equation of
|
||||
* motion based on the Bogacki-Shampine method with FSAL property, allowing
|
||||
* the reuse of the last derivative in the next step.
|
||||
* This Stepper provides 'dense output'. After a successful step, it is
|
||||
* possible to obtain an estimate of the value of the function at an
|
||||
* intermediate point of the interval. This requires only two additional
|
||||
* evaluations of the derivative (and thus the field).
|
||||
*/
|
||||
|
||||
class G4BogackiShampine45 : public G4MagIntegratorStepper
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4BogackiShampine45.
|
||||
* @param[in] EqRhs Pointer to the provided equation of motion.
|
||||
* @param[in] numberOfVariables The number of integration variables.
|
||||
* @param[in] primary Flag for initialisation of the auxiliary stepper.
|
||||
*/
|
||||
G4BogackiShampine45(G4EquationOfMotion* EqRhs,
|
||||
G4int numberOfVariables = 6,
|
||||
G4bool primary = true);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~G4BogackiShampine45() override;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4BogackiShampine45(const G4BogackiShampine45&) = delete;
|
||||
G4BogackiShampine45& operator=(const G4BogackiShampine45&) = delete;
|
||||
|
||||
/**
|
||||
* The stepper for the Runge Kutta integration.
|
||||
* The stepsize is fixed, with the step size given by 'h'.
|
||||
* Integrates ODE starting values y[0 to 6].
|
||||
* Outputs yout[] and its estimated error yerr[].
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
* @param[out] yerr The estimated error.
|
||||
*/
|
||||
void Stepper( const G4double y[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yout[],
|
||||
G4double yerr[] ) override ;
|
||||
G4double yerr[] ) override;
|
||||
|
||||
// This Stepper provides 'dense output'. After a successful
|
||||
// step, it is possible to obtain an estimate of the value
|
||||
// of the function at an intermediate point of the interval.
|
||||
// This requires only two additional evaluations of the
|
||||
// derivative (and thus the field).
|
||||
|
||||
inline void SetupInterpolation()
|
||||
{
|
||||
SetupInterpolationHigh(); // ( yInput, dydx, Step);
|
||||
}
|
||||
/**
|
||||
* Setup all coefficients for interpolation.
|
||||
*/
|
||||
void SetupInterpolationHigh(); // ( yInput, dydx, Step);
|
||||
inline void SetupInterpolation() { SetupInterpolationHigh(); }
|
||||
|
||||
// For calculating the output at the tau fraction of Step
|
||||
//
|
||||
/**
|
||||
* Calculates the output at the tau fraction of step.
|
||||
* @param[in] tau The tau fraction of the step.
|
||||
* @param[out] yOut Interpolation output.
|
||||
*/
|
||||
void InterpolateHigh( G4double tau, G4double yOut[] ) const;
|
||||
inline void Interpolate( G4double tau,
|
||||
G4double yOut[] ) // Output value
|
||||
{
|
||||
InterpolateHigh( tau, yOut);
|
||||
// InterpolateHigh( yInput, dydx, Step, yOut, tau);
|
||||
}
|
||||
|
||||
void SetupInterpolationHigh();
|
||||
|
||||
// For calculating the output at the tau fraction of Step
|
||||
//
|
||||
void InterpolateHigh( G4double tau,
|
||||
G4double yOut[] ) const;
|
||||
|
||||
G4double DistChord() const override;
|
||||
G4int IntegratorOrder() const override { return 4; }
|
||||
G4double yOut[] ) { InterpolateHigh( tau, yOut); }
|
||||
|
||||
/**
|
||||
* Returns the distance from chord line.
|
||||
*/
|
||||
G4double DistChord() const override;
|
||||
|
||||
/**
|
||||
* Returns the order, 4, of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override { return 4; }
|
||||
|
||||
/**
|
||||
* Returns the stepper type-ID, "kBogackiShampine45".
|
||||
*/
|
||||
inline G4StepperType StepperType() const override { return kBogackiShampine45; }
|
||||
|
||||
/**
|
||||
* Acccessor for dydx array.
|
||||
*/
|
||||
void GetLastDydx( G4double dyDxLast[] );
|
||||
|
||||
void PrepareConstants(); // Initialise the values of the bi[][] array
|
||||
/**
|
||||
* Initialises the values of the bi[][] array.
|
||||
*/
|
||||
void PrepareConstants();
|
||||
|
||||
private:
|
||||
|
||||
@@ -108,15 +148,17 @@ class G4BogackiShampine45 : public G4MagIntegratorStepper
|
||||
G4double *p[6];
|
||||
|
||||
G4double fLastStepLength = -1.0;
|
||||
|
||||
/** For DistChord() calculations. */
|
||||
G4double *fLastInitialVector, *fLastFinalVector, *fLastDyDx,
|
||||
*fMidVector, *fMidError;
|
||||
// For DistChord calculations
|
||||
|
||||
G4BogackiShampine45* fAuxStepper = nullptr;
|
||||
// For chord - until interpolation is proven
|
||||
|
||||
/** For chord - until interpolation is proven. */
|
||||
G4bool fPreparedInterpolation = false;
|
||||
|
||||
// Class constants
|
||||
/** Class constants. */
|
||||
static G4bool fPreparedConstants;
|
||||
static G4double bi[12][7];
|
||||
};
|
||||
|
||||
@@ -26,12 +26,11 @@
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// G4BorisDriver is a driver class using the second order Boris
|
||||
// G4BorisDriver is a driver class using the second order Boris
|
||||
// method to integrate the equation of motion.
|
||||
//
|
||||
//
|
||||
// Author: Divyansh Tiwari, Google Summer of Code 2022
|
||||
// Supervision: John Apostolakis,Renee Fatemi, Soon Yung Jun
|
||||
|
||||
// Author: Divyansh Tiwari (CERN, Google Summer of Code 2022), 05.11.2022
|
||||
// Supervision: John Apostolakis (CERN), Renee Fatemi, Soon Yung Jun (FNAL)
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4BORIS_DRIVER_HH
|
||||
#define G4BORIS_DRIVER_HH
|
||||
@@ -40,102 +39,180 @@
|
||||
#include "G4BorisScheme.hh"
|
||||
#include "G4ChordFinderDelegate.hh"
|
||||
|
||||
/**
|
||||
* @brief G4BorisDriver is a driver class using the second order Boris
|
||||
* method to integrate the equation of motion.
|
||||
*/
|
||||
|
||||
class G4BorisDriver : public G4VIntegrationDriver,
|
||||
public G4ChordFinderDelegate<G4BorisDriver>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4BorisDriver.
|
||||
* @param[in] hminimum The minumum allowed step.
|
||||
* @param[in] Boris Pointer to the Boris motion algorithm.
|
||||
* @param[in] numberOfComponents The number of integration variables.
|
||||
* @param[in] verbosity Flag for verbosity.
|
||||
*/
|
||||
G4BorisDriver( G4double hminimum,
|
||||
G4BorisScheme* Boris,
|
||||
G4int numberOfComponents = 6,
|
||||
G4bool verbosity = false);
|
||||
|
||||
inline ~G4BorisDriver() override = default;
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4BorisDriver() override = default;
|
||||
|
||||
inline G4BorisDriver(const G4BorisDriver&) = delete;
|
||||
inline G4BorisDriver& operator=(const G4BorisDriver&) = delete;
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4BorisDriver(const G4BorisDriver&) = delete;
|
||||
G4BorisDriver& operator=(const G4BorisDriver&) = delete;
|
||||
|
||||
// 1. Core methods that advance the integration
|
||||
|
||||
G4bool AccurateAdvance( G4FieldTrack& track,
|
||||
G4double stepLen,
|
||||
G4double epsilon,
|
||||
G4double beginStep = 0) override;
|
||||
// Advance integration accurately
|
||||
// - by relative accuracy better than 'epsilon'
|
||||
/**
|
||||
* Advances integration accurately by relative accuracy better than 'eps'.
|
||||
* @param[in,out] track The current track in field.
|
||||
* @param[in] stepLen Proposed step length.
|
||||
* @param[in] epsilon Requested accuracy, y_err/hstep.
|
||||
* @param[in] beginStep Initial minimum integration step.
|
||||
* @returns true if integration succeeds.
|
||||
*/
|
||||
G4bool AccurateAdvance(G4FieldTrack& track,
|
||||
G4double stepLen,
|
||||
G4double eps,
|
||||
G4double beginStep = 0) override;
|
||||
|
||||
G4bool QuickAdvance( G4FieldTrack& y_val, // In/Out
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double& missDist, // Out: estimated sagitta
|
||||
G4double& dyerr ) override;
|
||||
// Attempt one integration step, and return estimated error 'dyerr'
|
||||
|
||||
void OneGoodStep(G4double yCurrentState[], // In/Out: state ('y')
|
||||
G4double& curveLength, // In/Out: 'x'
|
||||
G4double htry, // step to attempt
|
||||
G4double epsilon_rel, // relative accuracy
|
||||
G4double restMass,
|
||||
G4double charge,
|
||||
G4double& hdid, // Out: step achieved
|
||||
G4double& hnext); // Out: proposed next step
|
||||
// Method to implement Accurate Advance
|
||||
/**
|
||||
* Attempts one integration step, and returns estimated error 'dyerr'.
|
||||
* It does not ensure accuracy.
|
||||
* @param[in,out] y_val The current track in field.
|
||||
* @param[in] dydx dydx array.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[out] missDist Estimated sagitta distance.
|
||||
* @param[out] dyerr Estimated error.
|
||||
* @returns true if integration succeeds.
|
||||
*/
|
||||
G4bool QuickAdvance(G4FieldTrack& y_val, // In/Out
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double& missDist, // Out: estimated sagitta
|
||||
G4double& dyerr) override;
|
||||
/**
|
||||
* Takes one Step that is as large as possible while satisfying the
|
||||
* accuracy criterion.
|
||||
* @param[in,out] yCurrentState The current track state, y.
|
||||
* @param[in,out] curveLength Step start, x.
|
||||
* @param[in] htry Step to attempt.
|
||||
* @param[in] epsilon_rel The relative accuracy.
|
||||
* @param[in] restMass Mass value for computing velocity.
|
||||
* @param[in] charge Charge value for computing momentum.
|
||||
* @param[out] hdid Step achieved.
|
||||
* @param[out] hnext Proposed next step.
|
||||
* @returns true if integration succeeds.
|
||||
*/
|
||||
void OneGoodStep(G4double yCurrentState[], // In/Out: state ('y')
|
||||
G4double& curveLength, // In/Out: 'x'
|
||||
G4double htry, // step to attempt
|
||||
G4double epsilon_rel, // relative accuracy
|
||||
G4double restMass,
|
||||
G4double charge,
|
||||
G4double& hdid, // Out: step achieved
|
||||
G4double& hnext); // Out: proposed next step
|
||||
|
||||
// 2. Methods needed to co-work with G4ChordFinder
|
||||
|
||||
G4double AdvanceChordLimited(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps,
|
||||
G4double chordDistance) override
|
||||
{
|
||||
return ChordFinderDelegate::
|
||||
AdvanceChordLimitedImpl(track, hstep, eps, chordDistance);
|
||||
}
|
||||
/**
|
||||
* Computes the step to take, based on chord limits.
|
||||
* @param[in,out] track The current track in field.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[in] eps Requested accuracy, y_err/hstep.
|
||||
* @param[in] chordDistance Maximum sagitta distance.
|
||||
* @returns The length of step taken.
|
||||
*/
|
||||
inline G4double AdvanceChordLimited(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps,
|
||||
G4double chordDistance) override;
|
||||
/**
|
||||
* Dispatch interface method for initialisation/reset of driver.
|
||||
*/
|
||||
inline void OnStartTracking() override;
|
||||
|
||||
void OnStartTracking() override
|
||||
{
|
||||
ChordFinderDelegate::ResetStepEstimate();
|
||||
}
|
||||
|
||||
void OnComputeStep(const G4FieldTrack*) override {}
|
||||
/**
|
||||
* Dispatch interface method for computing step. Does nothing here.
|
||||
*/
|
||||
inline void OnComputeStep(const G4FieldTrack*) override;
|
||||
|
||||
// 3. Does the method redo integrations when called to obtain values for
|
||||
// internal, smaller intervals? (when needed to identify an intersection)
|
||||
|
||||
G4bool DoesReIntegrate() const override { return true; }
|
||||
// It would be no if it just used interpolation to provide a result.
|
||||
/**
|
||||
* The driver implements re-integration. Returns true.
|
||||
* It would be false if it just used interpolation to provide a result.
|
||||
*/
|
||||
inline G4bool DoesReIntegrate() const override;
|
||||
|
||||
// 4. Relevant for calculating a new step size to achieve required accuracy
|
||||
|
||||
inline G4double ComputeNewStepSize(G4double errMaxNorm, // normalised error
|
||||
G4double hstepCurrent) override; // current step size
|
||||
/**
|
||||
* Computes a step size for the next step, taking the last step's
|
||||
* normalised error 'errMaxNorm'.
|
||||
* @param[in] errMaxNorm The normalised error on last step.
|
||||
* @param[in] hstepCurrent The current proposed step.
|
||||
* @returns The step size for the next step.
|
||||
*/
|
||||
inline G4double ComputeNewStepSize(G4double errMaxNorm,
|
||||
G4double hstepCurrent) override;
|
||||
|
||||
/**
|
||||
* Methods to calculate the next step size given the square of the
|
||||
* relative error.
|
||||
*/
|
||||
G4double ShrinkStepSize2(G4double h, G4double error2) const;
|
||||
G4double GrowStepSize2(G4double h, G4double error2) const;
|
||||
// Calculate the next step size given the square of the relative error
|
||||
|
||||
// 5. Auxiliary Methods ...
|
||||
|
||||
/**
|
||||
* Getters for derivatives.
|
||||
*/
|
||||
void GetDerivatives( const G4FieldTrack& track,
|
||||
G4double dydx[] ) const override;
|
||||
|
||||
void GetDerivatives( const G4FieldTrack& track,
|
||||
G4double dydx[],
|
||||
G4double field[] ) const override;
|
||||
|
||||
/**
|
||||
* Setter and getter for verbosity.
|
||||
*/
|
||||
inline void SetVerboseLevel(G4int level) override;
|
||||
inline G4int GetVerboseLevel() const override;
|
||||
|
||||
/**
|
||||
* Getters for the equation of motion.
|
||||
*/
|
||||
inline G4EquationOfMotion* GetEquationOfMotion() override;
|
||||
inline const G4EquationOfMotion* GetEquationOfMotion() const;
|
||||
|
||||
/**
|
||||
* Setter for the equation of motion. Issues an exception, as not
|
||||
* foreseen to change equation of motion for the Boris stepper.
|
||||
*/
|
||||
void SetEquationOfMotion(G4EquationOfMotion* equation) override;
|
||||
|
||||
void StreamInfo( std::ostream& os ) const override;
|
||||
// Write out the parameters / state of the driver
|
||||
/**
|
||||
* Writes out to stream the parameters/state of the driver.
|
||||
*/
|
||||
void StreamInfo( std::ostream& os ) const override;
|
||||
|
||||
// 6. Not relevant for Boris and other non-RK methods
|
||||
|
||||
/**
|
||||
* Accessors for stepper. Not relevant for Boris and other non-RK methods.
|
||||
*/
|
||||
inline const G4MagIntegratorStepper* GetStepper() const override;
|
||||
inline G4MagIntegratorStepper* GetStepper() override;
|
||||
|
||||
|
||||
@@ -24,94 +24,118 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4BorisDriver inline methods implementation
|
||||
|
||||
// Author: Divyansh Tiwari, Google Summer of Code 2022
|
||||
// Supervision: John Apostolakis,Renee Fatemi, Soon Yung Jun
|
||||
//
|
||||
// Author: Divyansh Tiwari (CERN, Google Summer of Code 2022), 05.11.2022
|
||||
// Supervision: John Apostolakis (CERN), Renee Fatemi, Soon Yung Jun (FNAL)
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
inline
|
||||
G4double G4BorisDriver::AdvanceChordLimited(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps,
|
||||
G4double chordDistance)
|
||||
{
|
||||
return ChordFinderDelegate::
|
||||
AdvanceChordLimitedImpl(track, hstep, eps, chordDistance);
|
||||
}
|
||||
|
||||
inline
|
||||
void G4BorisDriver::OnStartTracking()
|
||||
{
|
||||
ChordFinderDelegate::ResetStepEstimate();
|
||||
}
|
||||
|
||||
inline
|
||||
void G4BorisDriver::OnComputeStep(const G4FieldTrack*)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
G4bool G4BorisDriver::DoesReIntegrate() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline
|
||||
G4double G4BorisDriver::ComputeNewStepSize( G4double /* errMaxNorm*/,
|
||||
G4double hstepCurrent)
|
||||
{
|
||||
return hstepCurrent;
|
||||
}
|
||||
|
||||
inline
|
||||
void G4BorisDriver::SetVerboseLevel(G4int level)
|
||||
{
|
||||
fVerbosity = (level != 0);
|
||||
fVerbosity = (level != 0);
|
||||
}
|
||||
|
||||
inline
|
||||
G4int G4BorisDriver::GetVerboseLevel() const
|
||||
{
|
||||
return static_cast<G4int>(fVerbosity);
|
||||
}
|
||||
|
||||
G4double G4BorisDriver::ComputeNewStepSize( G4double /* errMaxNorm*/, G4double hstepCurrent)
|
||||
{
|
||||
return hstepCurrent;
|
||||
return static_cast<G4int>(fVerbosity);
|
||||
}
|
||||
|
||||
inline
|
||||
const G4EquationOfMotion* G4BorisDriver::GetEquationOfMotion() const
|
||||
{
|
||||
auto eq = boris->GetEquationOfMotion();
|
||||
return eq;
|
||||
auto eq = boris->GetEquationOfMotion();
|
||||
return eq;
|
||||
}
|
||||
|
||||
inline
|
||||
G4EquationOfMotion* G4BorisDriver::GetEquationOfMotion()
|
||||
{
|
||||
auto eq = boris->GetEquationOfMotion();
|
||||
return eq;
|
||||
auto eq = boris->GetEquationOfMotion();
|
||||
return eq;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// #ifdef G4USE_SET_EQUATION_OF_MOTION
|
||||
void G4BorisDriver::
|
||||
SetEquationOfMotion( G4EquationOfMotion* equation )
|
||||
{
|
||||
boris->SetEquationOfMotion(equation);
|
||||
}
|
||||
#endif
|
||||
|
||||
inline
|
||||
G4int G4BorisDriver::GetNumberOfVariables() const
|
||||
{
|
||||
return boris->GetNumberOfVariables();
|
||||
return boris->GetNumberOfVariables();
|
||||
}
|
||||
|
||||
const G4MagIntegratorStepper*
|
||||
G4BorisDriver::GetStepper() const
|
||||
inline
|
||||
const G4MagIntegratorStepper* G4BorisDriver::GetStepper() const
|
||||
{
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
G4MagIntegratorStepper*
|
||||
G4BorisDriver::GetStepper()
|
||||
inline
|
||||
G4MagIntegratorStepper* G4BorisDriver::GetStepper()
|
||||
{
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline
|
||||
void G4BorisDriver::CheckStep(const G4ThreeVector& posIn,
|
||||
const G4ThreeVector& posOut,
|
||||
G4double hdid) const
|
||||
{
|
||||
const G4double endPointDist = (posOut - posIn).mag();
|
||||
if (endPointDist >= hdid * (1. + CLHEP::perMillion))
|
||||
{
|
||||
// ++fNoAccurateAdvanceBadSteps;
|
||||
const G4double endPointDist = (posOut - posIn).mag();
|
||||
if (endPointDist >= hdid * (1. + CLHEP::perMillion))
|
||||
{
|
||||
// ++fNoAccurateAdvanceBadSteps;
|
||||
// #ifdef G4DEBUG_FIELD
|
||||
// Issue a warning only for gross differences -
|
||||
// we understand how small difference occur.
|
||||
if (endPointDist >= hdid * (1. + CLHEP::perThousand))
|
||||
{
|
||||
G4Exception("G4BorisDriver::CheckStep()",
|
||||
"GeomField1002", JustWarning,
|
||||
"endPointDist >= hdid!");
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cerr << "G4BorisDriver::CheckStep: moved further than curve distance! "
|
||||
<< " curve hdid= " << hdid << " endpoint dist= " << endPointDist
|
||||
<< " ratio - 1 = " << (endPointDist - hdid) / hdid
|
||||
<< " ( > 1.0e-6 threshold to report ) "
|
||||
<< G4endl;
|
||||
}
|
||||
// Issue a warning only for gross differences -
|
||||
// we understand how small difference occur.
|
||||
if (endPointDist >= hdid * (1. + CLHEP::perThousand))
|
||||
{
|
||||
G4Exception("G4BorisDriver::CheckStep()", "GeomField1002", JustWarning,
|
||||
"endPointDist >= hdid!");
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cerr << "G4BorisDriver::CheckStep: moved further than curve distance! "
|
||||
<< " curve hdid= " << hdid << " endpoint dist= " << endPointDist
|
||||
<< " ratio - 1 = " << (endPointDist - hdid) / hdid
|
||||
<< " ( > 1.0e-6 threshold to report ) "
|
||||
<< G4endl;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// ++fNoAccurateAdvanceGoodSteps;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ++fNoAccurateAdvanceGoodSteps;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,62 +29,106 @@
|
||||
// Implementation of the Boris algorithm for advancing
|
||||
// charged particles in an electromagnetic field.
|
||||
|
||||
// Author: Divyansh Tiwari, Google Summer of Code 2022
|
||||
// Supervision: John Apostolakis,Renee Fatemi, Soon Yung Jun
|
||||
// Author: Divyansh Tiwari (CERN, Google Summer of Code 2022), 05.11.2022
|
||||
// Supervision: John Apostolakis (CERN), Renee Fatemi, Soon Yung Jun (FNAL)
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4BORIS_SCHEME_HH
|
||||
#define G4BORIS_SCHEME_HH
|
||||
|
||||
class G4EquationOfMotion;
|
||||
|
||||
#include "G4Types.hh"
|
||||
|
||||
|
||||
// class G4EqMagElectricField;
|
||||
|
||||
// #include "G4FieldTrack.hh"
|
||||
|
||||
#include <CLHEP/Units/PhysicalConstants.h>
|
||||
|
||||
class G4EquationOfMotion;
|
||||
|
||||
/**
|
||||
* @brief The G4BorisScheme class implements of the Boris algorithm for
|
||||
* advancing charged particles in an electromagnetic field.
|
||||
*/
|
||||
|
||||
class G4BorisScheme
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*/
|
||||
G4BorisScheme() = default;
|
||||
G4BorisScheme( // G4EqMagElectricField
|
||||
G4EquationOfMotion* equation,
|
||||
G4int nvar = 6);
|
||||
~G4BorisScheme() = default;
|
||||
|
||||
void DoStep( G4double restMass, G4double charge, const G4double yIn[],
|
||||
G4double yOut[], G4double hstep) const;
|
||||
/**
|
||||
* Constructor for the equation of motion.
|
||||
* @param[in] equation Pointer to the equation of motion algorithm.
|
||||
* @param[in] nvar The number of integration variables.
|
||||
*/
|
||||
G4BorisScheme( G4EquationOfMotion* equation, G4int nvar = 6 );
|
||||
|
||||
protected:
|
||||
// Used to implement the 'DoStep' method above
|
||||
void UpdatePosition(const G4double restMass, const G4double charge, const G4double yIn[],
|
||||
G4double yOut[], G4double hstep) const;
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4BorisScheme() = default;
|
||||
|
||||
void UpdateVelocity(const G4double restMass, const G4double charge, const G4double yIn[],
|
||||
G4double yOut[], G4double hstep) const;
|
||||
/**
|
||||
* Does one step, updating velocity and position.
|
||||
* @param[in] restMass Particle mass.
|
||||
* @param[in] charge Particle charge.
|
||||
* @param[in] yIn Initial position.
|
||||
* @param[out] yOut Updated position.
|
||||
* @param[in] hstep Proposed step.
|
||||
*/
|
||||
void DoStep(G4double restMass, G4double charge, const G4double yIn[],
|
||||
G4double yOut[], G4double hstep) const;
|
||||
|
||||
public:
|
||||
// - Methods using the Boris Scheme Stepping to estimate integration error
|
||||
void StepWithErrorEstimate(const G4double yIn[], G4double restMass, G4double charge, G4double hstep,
|
||||
/**
|
||||
* Adopts the Boris Scheme Stepping to estimate the integration error.
|
||||
* Uses two half-steps (comparing to a full step) to obtain output and
|
||||
* error estimate.
|
||||
* @param[in] yIn Initial position.
|
||||
* @param[in] restMass Particle mass.
|
||||
* @param[in] charge Particle charge.
|
||||
* @param[in] hstep Proposed step.
|
||||
* @param[out] yOut Updated position.
|
||||
* @param[out] yErr The estimated error.
|
||||
*/
|
||||
void StepWithErrorEstimate(const G4double yIn[], G4double restMass,
|
||||
G4double charge, G4double hstep,
|
||||
G4double yOut[], G4double yErr[]) const;
|
||||
// Use two half-steps (comparing to a full step) to obtain output and error estimate
|
||||
|
||||
void StepWithMidAndErrorEstimate(const G4double yIn[], G4double restMass, G4double charge, G4double hstep,
|
||||
G4double yMid[], G4double yOut[], G4double yErr[]) const;
|
||||
// Same, and also return mid-point evaluation
|
||||
|
||||
// Auxiliary method
|
||||
inline G4EquationOfMotion* GetEquationOfMotion();
|
||||
// inline void SetEquationOfMotion(G4EquationOfMotion* equation); // Un-needed, dangerous
|
||||
/**
|
||||
* Adopts the Boris Scheme Stepping to estimate the integration error.
|
||||
* Uses two half-steps (comparing to a full step) to obtain output and
|
||||
* error estimate. Same as above, but also returns the mid-point evaluation.
|
||||
* @param[in] yIn Initial position.
|
||||
* @param[in] restMass Particle mass.
|
||||
* @param[in] charge Particle charge.
|
||||
* @param[in] hstep Proposed step.
|
||||
* @param[out] yMid tThe mid-point evaluation.
|
||||
* @param[out] yOut Updated position.
|
||||
* @param[out] yErr The estimated error.
|
||||
*/
|
||||
void StepWithMidAndErrorEstimate(const G4double yIn[], G4double restMass,
|
||||
G4double charge, G4double hstep,
|
||||
G4double yMid[], G4double yOut[], G4double yErr[]) const;
|
||||
|
||||
/**
|
||||
* Auxiliary methods returning a pointer to the equation of motion
|
||||
* and the number of integration variables.
|
||||
*/
|
||||
inline G4EquationOfMotion* GetEquationOfMotion() const;
|
||||
inline G4int GetNumberOfVariables() const;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Internal methods for updating position and velocity, used in DoStep().
|
||||
*/
|
||||
void UpdatePosition(const G4double restMass, const G4double charge,
|
||||
const G4double yIn[], G4double yOut[], G4double hstep) const;
|
||||
void UpdateVelocity(const G4double restMass, const G4double charge,
|
||||
const G4double yIn[], G4double yOut[], G4double hstep) const;
|
||||
|
||||
/**
|
||||
* Utility to mem-copy 'src' array data to 'dst'.
|
||||
*/
|
||||
void copy(G4double dst[], const G4double src[]) const;
|
||||
|
||||
private:
|
||||
@@ -95,4 +139,5 @@ class G4BorisScheme
|
||||
};
|
||||
|
||||
#include "G4BorisScheme.icc"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -29,19 +29,12 @@
|
||||
// Supervision: John Apostolakis,Renee Fatemi, Soon Yung Jun
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#if 0
|
||||
inline void G4BorisScheme::SetEquationOfMotion(G4EquationOfMotion* eq)
|
||||
inline G4EquationOfMotion* G4BorisScheme::GetEquationOfMotion() const
|
||||
{
|
||||
fEquation = eq;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline G4EquationOfMotion* G4BorisScheme::GetEquationOfMotion()
|
||||
{
|
||||
return fEquation;
|
||||
return fEquation;
|
||||
}
|
||||
|
||||
inline G4int G4BorisScheme::GetNumberOfVariables() const
|
||||
{
|
||||
return fnvar;
|
||||
return fnvar;
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
// and order of the method. The algorithm uses the modified midpoint and
|
||||
// a polynomial extrapolation computes the solution.
|
||||
|
||||
// Author: Dmitry Sorokin, Google Summer of Code 2016
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// Author: Dmitry Sorokin (CERN, Google Summer of Code 2016), 13.02.2018
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4BULIRSCH_STOER_HH
|
||||
#define G4BULIRSCH_STOER_HH
|
||||
@@ -40,87 +40,136 @@
|
||||
|
||||
#include "G4FieldTrack.hh"
|
||||
|
||||
/**
|
||||
* @brief G4BulirschStoer is a controlled driver that adjusts both step size
|
||||
* and order of the method. The algorithm uses the modified midpoint and
|
||||
* a polynomial extrapolation computes the solution.
|
||||
*/
|
||||
|
||||
class G4BulirschStoer
|
||||
{
|
||||
public:
|
||||
|
||||
enum class step_result
|
||||
{
|
||||
success,
|
||||
fail
|
||||
};
|
||||
enum class step_result { success, fail };
|
||||
|
||||
G4BulirschStoer( G4EquationOfMotion* equation, G4int nvar,
|
||||
G4double eps_rel, G4double max_dt = DBL_MAX);
|
||||
/**
|
||||
* Constructor for G4BulirschStoer.
|
||||
* @param[in] equation Pointer to the provided equation of motion.
|
||||
* @param[in] nvar The number of integration variables.
|
||||
* @param[in] eps_rel Relative tolerance.
|
||||
* @param[in] max_dt Maximum allowed time step.
|
||||
*/
|
||||
G4BulirschStoer(G4EquationOfMotion* equation, G4int nvar,
|
||||
G4double eps_rel, G4double max_dt = DBL_MAX);
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4BulirschStoer() = default;
|
||||
|
||||
/**
|
||||
* Modifiers.
|
||||
*/
|
||||
inline void set_max_dt(G4double max_dt);
|
||||
inline void set_max_relative_error(G4double eps_rel);
|
||||
|
||||
// Stepper method
|
||||
//
|
||||
/**
|
||||
* Stepper method.
|
||||
* @param[in] in Initial position.
|
||||
* @param[in] dxdt dxdt for mid-point calculation.
|
||||
* @param[out] t The updated step.
|
||||
* @param[out] out Updated position.
|
||||
* @param[in,out] dt Step size.
|
||||
* @returns success if step is not rejected.
|
||||
*/
|
||||
step_result try_step(const G4double in[], const G4double dxdt[],
|
||||
G4double& t, G4double out[], G4double& dt);
|
||||
|
||||
// Reset the internal state of the stepper
|
||||
//
|
||||
/**
|
||||
* Resets the internal state of the stepper.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* Setter and getter for the equation of motion.
|
||||
*/
|
||||
inline void SetEquationOfMotion(G4EquationOfMotion* equation);
|
||||
inline G4EquationOfMotion* GetEquationOfMotion();
|
||||
inline G4EquationOfMotion* GetEquationOfMotion() const;
|
||||
|
||||
/**
|
||||
* Returns the number of integration variables.
|
||||
*/
|
||||
inline G4int GetNumberOfVariables() const;
|
||||
|
||||
private:
|
||||
|
||||
const static G4int m_k_max = 8;
|
||||
|
||||
/**
|
||||
* Polynomial extrapolation.
|
||||
*/
|
||||
void extrapolate(std::size_t k, G4double xest[]);
|
||||
|
||||
/**
|
||||
* Calculates the optimal step size for a given error and stage number.
|
||||
*/
|
||||
G4double calc_h_opt(G4double h, G4double error, std::size_t k) const;
|
||||
|
||||
/**
|
||||
* Calculates the optimal stage number.
|
||||
*/
|
||||
G4bool set_k_opt(std::size_t k, G4double& dt);
|
||||
|
||||
/**
|
||||
* Utilities.
|
||||
*/
|
||||
G4bool in_convergence_window(G4int k) const;
|
||||
G4bool should_reject(G4double error, G4int k) const;
|
||||
|
||||
// Number of vars to be integrated
|
||||
private:
|
||||
|
||||
/** Maximum number of stages. */
|
||||
const static G4int m_k_max = 8;
|
||||
|
||||
/** Number of vars to be integrated. */
|
||||
G4int fnvar;
|
||||
|
||||
// Relative tolerance
|
||||
/** Relative tolerance. */
|
||||
G4double m_eps_rel;
|
||||
|
||||
// Modified midpoint algorithm
|
||||
/** Modified midpoint algorithm. */
|
||||
G4ModifiedMidpoint m_midpoint;
|
||||
|
||||
/** Flags for step. */
|
||||
G4bool m_last_step_rejected{false};
|
||||
G4bool m_first{true};
|
||||
|
||||
/** Last step size. */
|
||||
G4double m_dt_last{0.0};
|
||||
// G4double m_t_last;
|
||||
|
||||
// Max allowed time step
|
||||
/** Max allowed time step. */
|
||||
G4double m_max_dt;
|
||||
|
||||
/** Crude estimate of optimal order. */
|
||||
G4int m_current_k_opt;
|
||||
|
||||
// G4double m_xnew[G4FieldTrack::ncompSVEC];
|
||||
/** Error estimate. */
|
||||
G4double m_err[G4FieldTrack::ncompSVEC];
|
||||
// G4double m_dxdt[G4FieldTrack::ncompSVEC];
|
||||
|
||||
// Stores the successive interval counts
|
||||
/** Stores the successive interval counts. */
|
||||
G4int m_interval_sequence[m_k_max+1];
|
||||
|
||||
// Extrapolation coeffs (Neville’s algorithm)
|
||||
/** Extrapolation coeffs (Neville's algorithm). */
|
||||
G4double m_coeff[m_k_max+1][m_k_max];
|
||||
|
||||
// Costs for interval count
|
||||
/** Costs for interval count. */
|
||||
G4int m_cost[m_k_max+1];
|
||||
|
||||
// Sequence of states for extrapolation
|
||||
/** Sequence of states for extrapolation. */
|
||||
G4double m_table[m_k_max][G4FieldTrack::ncompSVEC];
|
||||
|
||||
// Optimal step size
|
||||
/** Optimal step size. */
|
||||
G4double h_opt[m_k_max+1];
|
||||
|
||||
// Work per unit step
|
||||
/** Work per unit step. */
|
||||
G4double work[m_k_max+1];
|
||||
};
|
||||
|
||||
|
||||
@@ -25,30 +25,31 @@
|
||||
//
|
||||
// G4BulirschStoer inline methods implementation
|
||||
//
|
||||
// Author: Dmitry Sorokin, Google Summer of Code 2016
|
||||
// Author: Dmitry Sorokin (CERN, Google Summer of Code 2016), 13.02.2018
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
inline void G4BulirschStoer::set_max_dt(G4double max_dt)
|
||||
{
|
||||
m_max_dt = max_dt;
|
||||
m_max_dt = max_dt;
|
||||
}
|
||||
|
||||
inline void G4BulirschStoer::set_max_relative_error(G4double eps_rel)
|
||||
{
|
||||
m_eps_rel = eps_rel;
|
||||
m_eps_rel = eps_rel;
|
||||
}
|
||||
|
||||
inline void G4BulirschStoer::SetEquationOfMotion(G4EquationOfMotion* equation)
|
||||
{
|
||||
m_midpoint.SetEquationOfMotion(equation);
|
||||
m_midpoint.SetEquationOfMotion(equation);
|
||||
}
|
||||
|
||||
inline G4EquationOfMotion* G4BulirschStoer::GetEquationOfMotion()
|
||||
inline G4EquationOfMotion* G4BulirschStoer::GetEquationOfMotion() const
|
||||
{
|
||||
return m_midpoint.GetEquationOfMotion();
|
||||
return m_midpoint.GetEquationOfMotion();
|
||||
}
|
||||
|
||||
inline G4int G4BulirschStoer::GetNumberOfVariables() const
|
||||
{
|
||||
return fnvar;
|
||||
return fnvar;
|
||||
}
|
||||
|
||||
@@ -26,11 +26,11 @@
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// G4IntegrationDriver<G4BulirschStoer> is a driver class using
|
||||
// G4IntegrationDriver<G4BulirschStoer> is a concrete driver class using
|
||||
// Bulirsch-Stoer method to integrate the equation of motion.
|
||||
|
||||
// Author: Dmitry Sorokin, Google Summer of Code 2016
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// Author: Dmitry Sorokin (CERN, Google Summer of Code 2016), 13.02.2018
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4BULIRSCH_STOER_DRIVER_HH
|
||||
#define G4BULIRSCH_STOER_DRIVER_HH
|
||||
@@ -39,6 +39,11 @@
|
||||
#include "G4BulirschStoer.hh"
|
||||
#include "G4ChordFinderDelegate.hh"
|
||||
|
||||
/**
|
||||
* @brief G4IntegrationDriver<G4BulirschStoer> is a concrete driver class
|
||||
* using the Bulirsch-Stoer method to integrate the equation of motion.
|
||||
*/
|
||||
|
||||
template <>
|
||||
class G4IntegrationDriver<G4BulirschStoer>:
|
||||
public G4VIntegrationDriver,
|
||||
@@ -46,45 +51,97 @@ class G4IntegrationDriver<G4BulirschStoer>:
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for the concrete G4IntegrationDriver.
|
||||
* @param[in] hminimum The minumum allowed step..
|
||||
* @param[in] Boris Pointer to the Bulirsch-Stoer motion algorithm.
|
||||
* @param[in] numberOfComponents The number of integration variables.
|
||||
* @param[in] verbosity Flag for verbosity.
|
||||
*/
|
||||
G4IntegrationDriver( G4double hminimum,
|
||||
G4BulirschStoer* stepper,
|
||||
G4int numberOfComponents = 6,
|
||||
G4int statisticsVerbosity = 1);
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4IntegrationDriver() = default;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4IntegrationDriver(const G4IntegrationDriver&) = delete;
|
||||
G4IntegrationDriver& operator=(const G4IntegrationDriver&) = delete;
|
||||
|
||||
virtual G4double AdvanceChordLimited(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps,
|
||||
G4double chordDistance) override
|
||||
{
|
||||
return ChordFinderDelegate::
|
||||
AdvanceChordLimitedImpl(track, hstep, eps, chordDistance);
|
||||
}
|
||||
|
||||
virtual void OnStartTracking() override
|
||||
{
|
||||
ChordFinderDelegate::ResetStepEstimate();
|
||||
}
|
||||
|
||||
virtual void OnComputeStep(const G4FieldTrack* /*track*/ = nullptr) override {};
|
||||
|
||||
virtual G4bool DoesReIntegrate() const override { return false; } /// ????
|
||||
|
||||
virtual G4bool AccurateAdvance( G4FieldTrack& track,
|
||||
G4double stepLen,
|
||||
G4double eps,
|
||||
G4double beginStep = 0) override;
|
||||
|
||||
virtual G4bool QuickAdvance( G4FieldTrack& y_val,
|
||||
const G4double dydx[],
|
||||
/**
|
||||
* Computes the step to take, based on chord limits.
|
||||
* @param[in,out] track The current track in field.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[in] eps Requested accuracy, y_err/hstep.
|
||||
* @param[in] chordDistance Maximum sagitta distance.
|
||||
* @returns The length of step taken.
|
||||
*/
|
||||
G4double AdvanceChordLimited(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double& missDist,
|
||||
G4double& dyerr) override;
|
||||
G4double eps,
|
||||
G4double chordDistance) override;
|
||||
|
||||
/**
|
||||
* Dispatch interface method for initialisation/reset of driver.
|
||||
*/
|
||||
void OnStartTracking() override;
|
||||
|
||||
/**
|
||||
* Dispatch interface method for computing step. Does nothing here.
|
||||
*/
|
||||
void OnComputeStep(const G4FieldTrack* track = nullptr) override;
|
||||
|
||||
/**
|
||||
* The driver does not implement re-integration. Returns false.
|
||||
*/
|
||||
G4bool DoesReIntegrate() const override;
|
||||
|
||||
/**
|
||||
* Advances integration accurately by relative accuracy better than 'eps'.
|
||||
* @param[in,out] track The current track in field.
|
||||
* @param[in] stepLen Proposed step length.
|
||||
* @param[in] eps Requested accuracy, y_err/hstep.
|
||||
* @param[in] beginStep Initial minimum integration step.
|
||||
* @returns true if integration succeeds.
|
||||
*/
|
||||
G4bool AccurateAdvance( G4FieldTrack& track,
|
||||
G4double stepLen,
|
||||
G4double eps,
|
||||
G4double beginStep = 0) override;
|
||||
|
||||
/**
|
||||
* Attempts one integration step, and returns estimated error 'dyerr'.
|
||||
* It does not ensure accuracy.
|
||||
* @param[in,out] y_val The current track in field.
|
||||
* @param[in] dydx dydx array.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[out] missDist Estimated sagitta distance.
|
||||
* @param[out] dyerr Estimated error.
|
||||
* @returns true if integration succeeds.
|
||||
*/
|
||||
G4bool QuickAdvance( G4FieldTrack& y_val,
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double& missDist,
|
||||
G4double& dyerr) override;
|
||||
|
||||
/**
|
||||
* Takes one Step that is as large as possible while satisfying the
|
||||
* accuracy criterion.
|
||||
* @param[in,out] y The current track state, y.
|
||||
* @param[in] dydx dydx array.
|
||||
* @param[in,out] curveLength Step start, x.
|
||||
* @param[in] htry Step to attempt.
|
||||
* @param[in] eps The relative accuracy.
|
||||
* @param[out] hdid Step achieved.
|
||||
* @param[out] hnext Proposed next step.
|
||||
*/
|
||||
void OneGoodStep( G4double y[],
|
||||
const G4double dydx[],
|
||||
G4double& curveLength,
|
||||
@@ -93,29 +150,47 @@ class G4IntegrationDriver<G4BulirschStoer>:
|
||||
G4double& hdid,
|
||||
G4double& hnext);
|
||||
|
||||
virtual void GetDerivatives( const G4FieldTrack& track,
|
||||
G4double dydx[]) const override;
|
||||
/**
|
||||
* Getters for derivatives.
|
||||
*/
|
||||
void GetDerivatives( const G4FieldTrack& track,
|
||||
G4double dydx[]) const override;
|
||||
void GetDerivatives( const G4FieldTrack& track,
|
||||
G4double dydx[],
|
||||
G4double field[]) const override;
|
||||
|
||||
virtual void GetDerivatives( const G4FieldTrack& track,
|
||||
G4double dydx[],
|
||||
G4double field[]) const override;
|
||||
/**
|
||||
* Setter and getter for verbosity.
|
||||
*/
|
||||
void SetVerboseLevel(G4int level) override;
|
||||
G4int GetVerboseLevel() const override;
|
||||
|
||||
virtual void SetVerboseLevel(G4int level) override;
|
||||
virtual G4int GetVerboseLevel() const override;
|
||||
/**
|
||||
* Computes the new step size .
|
||||
* @param[in] errMaxNorm The normalised error.
|
||||
* @param[in] hstepCurrent The current step size.
|
||||
* @returns The new step size.
|
||||
*/
|
||||
G4double ComputeNewStepSize(G4double errMaxNorm,
|
||||
G4double hstepCurrent) override;
|
||||
|
||||
virtual G4double ComputeNewStepSize(
|
||||
G4double errMaxNorm, // normalised error
|
||||
G4double hstepCurrent) override; // current step size
|
||||
|
||||
virtual G4EquationOfMotion* GetEquationOfMotion() override;
|
||||
/**
|
||||
* Getters and setter for the equation of motion.
|
||||
*/
|
||||
G4EquationOfMotion* GetEquationOfMotion() override;
|
||||
const G4EquationOfMotion* GetEquationOfMotion() const;
|
||||
virtual void SetEquationOfMotion(G4EquationOfMotion* equation) override;
|
||||
void SetEquationOfMotion(G4EquationOfMotion* equation) override;
|
||||
|
||||
virtual const G4MagIntegratorStepper* GetStepper() const override;
|
||||
virtual G4MagIntegratorStepper* GetStepper() override;
|
||||
/**
|
||||
* Getters for the stepper.
|
||||
*/
|
||||
const G4MagIntegratorStepper* GetStepper() const override;
|
||||
G4MagIntegratorStepper* GetStepper() override;
|
||||
|
||||
virtual void StreamInfo( std::ostream& os ) const override;
|
||||
// Write out the parameters / state of the driver
|
||||
/**
|
||||
* Writes out to stream the parameters/state of the driver.
|
||||
*/
|
||||
void StreamInfo( std::ostream& os ) const override;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
//
|
||||
// G4BulirschStoer driver inline methods implementation
|
||||
|
||||
// Author: Dmitry Sorokin, Google Summer of Code 2016
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// Author: Dmitry Sorokin (CERN, Google Summer of Code 2016), 13.02.2018
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include <cassert>
|
||||
@@ -61,9 +61,9 @@ G4bool G4IntegrationDriver<G4BulirschStoer>::
|
||||
AccurateAdvance( G4FieldTrack& track, G4double hstep,
|
||||
G4double eps, G4double hinitial)
|
||||
{
|
||||
G4int fNoTotalSteps = 0;
|
||||
// G4int fNoTotalSteps = 0;
|
||||
G4int fMaxNoSteps = 10000;
|
||||
G4double fNoBadSteps = 0.0;
|
||||
// G4double fNoBadSteps = 0.0;
|
||||
G4double fSmallestFraction = 1.0e-12;
|
||||
|
||||
// Driver with adaptive stepsize control. Integrate starting
|
||||
@@ -124,13 +124,13 @@ AccurateAdvance( G4FieldTrack& track, G4double hstep,
|
||||
|
||||
// loop variables
|
||||
//
|
||||
G4int nstp = 1, no_warnings = 0;
|
||||
G4int nstp = 1; //, no_warnings = 0;
|
||||
G4double hnext, hdid;
|
||||
|
||||
G4bool succeeded = true, lastStepSucceeded;
|
||||
|
||||
G4int noFullIntegr = 0, noSmallIntegr = 0 ;
|
||||
static G4ThreadLocal G4int noGoodSteps = 0 ; // Bad = chord > curve-len
|
||||
// static G4ThreadLocal G4int noGoodSteps = 0 ; // Bad = chord > curve-len
|
||||
|
||||
G4bool lastStep = false;
|
||||
|
||||
@@ -142,7 +142,7 @@ AccurateAdvance( G4FieldTrack& track, G4double hstep,
|
||||
{
|
||||
G4ThreeVector StartPos(yCurrent[0], yCurrent[1], yCurrent[2]);
|
||||
GetEquationOfMotion()->RightHandSide(yCurrent, dydxCurrent);
|
||||
fNoTotalSteps++;
|
||||
// fNoTotalSteps++;
|
||||
|
||||
// Perform the Integration
|
||||
//
|
||||
@@ -185,7 +185,7 @@ AccurateAdvance( G4FieldTrack& track, G4double hstep,
|
||||
lastStepSucceeded ? ++noFullIntegr : ++noSmallIntegr;
|
||||
|
||||
G4ThreeVector EndPos(yCurrent[0], yCurrent[1], yCurrent[2]);
|
||||
|
||||
/*
|
||||
// Check the endpoint
|
||||
//
|
||||
G4double endPointDist = (EndPos - StartPos).mag();
|
||||
@@ -205,7 +205,7 @@ AccurateAdvance( G4FieldTrack& track, G4double hstep,
|
||||
{
|
||||
++noGoodSteps;
|
||||
}
|
||||
|
||||
*/
|
||||
// Avoid numerous small last steps
|
||||
//
|
||||
if((h < eps * hstep) || (h < fSmallestFraction * startCurveLength))
|
||||
@@ -262,7 +262,7 @@ AccurateAdvance( G4FieldTrack& track, G4double hstep,
|
||||
|
||||
if(nstp > fMaxNoSteps)
|
||||
{
|
||||
++no_warnings;
|
||||
// ++no_warnings;
|
||||
succeeded = false;
|
||||
}
|
||||
|
||||
@@ -329,6 +329,14 @@ QuickAdvance( G4FieldTrack& track, const G4double dydx[],
|
||||
return true;
|
||||
}
|
||||
|
||||
G4double G4IntegrationDriver<G4BulirschStoer>::
|
||||
AdvanceChordLimited(G4FieldTrack& track, G4double hstep, G4double eps,
|
||||
G4double chordDistance)
|
||||
{
|
||||
return ChordFinderDelegate::
|
||||
AdvanceChordLimitedImpl(track, hstep, eps, chordDistance);
|
||||
}
|
||||
|
||||
void G4IntegrationDriver<G4BulirschStoer>::
|
||||
OneGoodStep( G4double y[], const G4double dydx[], G4double& curveLength,
|
||||
G4double htry, G4double eps, G4double& hdid, G4double& hnext)
|
||||
@@ -353,6 +361,23 @@ OneGoodStep( G4double y[], const G4double dydx[], G4double& curveLength,
|
||||
hdid = curveLength - curveLengthBegin;
|
||||
}
|
||||
|
||||
void G4IntegrationDriver<G4BulirschStoer>::
|
||||
OnStartTracking()
|
||||
{
|
||||
ChordFinderDelegate::ResetStepEstimate();
|
||||
}
|
||||
|
||||
void G4IntegrationDriver<G4BulirschStoer>::
|
||||
OnComputeStep(const G4FieldTrack* /*track*/)
|
||||
{
|
||||
}
|
||||
|
||||
G4bool G4IntegrationDriver<G4BulirschStoer>::
|
||||
DoesReIntegrate() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void G4IntegrationDriver<G4BulirschStoer>::
|
||||
GetDerivatives( const G4FieldTrack& track, G4double dydx[]) const
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
//
|
||||
// Caches Magnetic Field value, for field whose evaluation is expensive.
|
||||
|
||||
// Author: J.Apostolakis, 20 July 2009.
|
||||
// Author: John Apostolakis (CERN), 20.07.2009.
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4CACHED_MAGNETIC_FIELD_HH
|
||||
#define G4CACHED_MAGNETIC_FIELD_HH
|
||||
@@ -38,29 +38,68 @@
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4MagneticField.hh"
|
||||
|
||||
/**
|
||||
* @brief G4CachedMagneticField is a specialisation of G4MagneticField and
|
||||
* is used to cache the Magnetic Field value, for fields whose evaluation is
|
||||
* expensive.
|
||||
*/
|
||||
|
||||
class G4CachedMagneticField : public G4MagneticField
|
||||
{
|
||||
public:
|
||||
|
||||
G4CachedMagneticField(G4MagneticField*, G4double distanceConst);
|
||||
~G4CachedMagneticField() override;
|
||||
// Constructor and destructor. No actions.
|
||||
/**
|
||||
* Constructor for G4CachedMagneticField.
|
||||
* @param[in] pMagField Pointer to the original magnetic field.
|
||||
* @param[in] distance Distance for field evaluation, within
|
||||
* which the field does not change.
|
||||
*/
|
||||
G4CachedMagneticField(G4MagneticField* pMagField, G4double distance);
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4CachedMagneticField() override = default;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator.
|
||||
*/
|
||||
G4CachedMagneticField(const G4CachedMagneticField& r);
|
||||
G4CachedMagneticField& operator = (const G4CachedMagneticField& p);
|
||||
// Copy constructor & assignment operator.
|
||||
|
||||
/**
|
||||
* Returns the value of the field at the give 'Point'.
|
||||
* @param[in] Point The given position time vector (x,y,z,t).
|
||||
* @param[out] Bfield The returned field array.
|
||||
*/
|
||||
void GetFieldValue( const G4double Point[4],
|
||||
G4double* Bfield ) const override;
|
||||
|
||||
G4double GetConstDistance() const { return fDistanceConst; }
|
||||
void SetConstDistance( G4double dist ) { fDistanceConst= dist;}
|
||||
/**
|
||||
* Getter and setter for the distance within which field is constant.
|
||||
*/
|
||||
inline G4double GetConstDistance() const { return fDistanceConst; }
|
||||
inline void SetConstDistance( G4double dist ) { fDistanceConst = dist;}
|
||||
|
||||
G4int GetCountCalls() const { return fCountCalls; }
|
||||
G4int GetCountEvaluations() const { return fCountEvaluations; }
|
||||
void ClearCounts() { fCountCalls = 0; fCountEvaluations=0; }
|
||||
/**
|
||||
* Accessors.
|
||||
*/
|
||||
inline G4int GetCountCalls() const { return fCountCalls; }
|
||||
inline G4int GetCountEvaluations() const { return fCountEvaluations; }
|
||||
|
||||
/**
|
||||
* Resets counters.
|
||||
*/
|
||||
inline void ClearCounts() { fCountCalls = 0; fCountEvaluations=0; }
|
||||
|
||||
/**
|
||||
* Streams on standard output the values of counters.
|
||||
*/
|
||||
void ReportStatistics();
|
||||
|
||||
/**
|
||||
* Returns a pointer of an allocated clone of the field.
|
||||
*/
|
||||
G4Field* Clone() const override;
|
||||
|
||||
protected:
|
||||
@@ -70,13 +109,13 @@ class G4CachedMagneticField : public G4MagneticField
|
||||
private:
|
||||
|
||||
G4MagneticField* fpMagneticField = nullptr;
|
||||
G4double fDistanceConst;
|
||||
// When the field is evaluated within this distance it will not change
|
||||
|
||||
// Caching state
|
||||
//
|
||||
/** When the field is evaluated within this distance it will not change. */
|
||||
G4double fDistanceConst;
|
||||
|
||||
/** Caching state. */
|
||||
mutable G4ThreeVector fLastLocation;
|
||||
mutable G4ThreeVector fLastValue;
|
||||
};
|
||||
|
||||
#endif /* G4CACHED_MAGNETIC_FIELD_DEF */
|
||||
#endif
|
||||
|
||||
@@ -34,56 +34,89 @@
|
||||
// It is used to integrate the equations of the motion of a particle
|
||||
// in a magnetic field.
|
||||
|
||||
// Authors: J.Apostolakis, V.Grichine - 30.01.1997
|
||||
// Authors: J.Apostolakis, V.Grichine (CERN), 30.01.1997
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4CASHKARP_RKF45_HH
|
||||
#define G4CASHKARP_RKF45_HH
|
||||
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
|
||||
/**
|
||||
* @brief G4CashKarpRKF45 implements the Cash-Karp Runge-Kutta-Fehlberg
|
||||
* 4/5 method, an embedded fourth order method (giving fifth-order accuracy)
|
||||
* for the solution of an ODE. Two different fourth order estimates are
|
||||
* calculated; their difference gives an error estimate.
|
||||
* It is used to integrate the equations of the motion of a particle
|
||||
* in a magnetic field.
|
||||
*/
|
||||
|
||||
class G4CashKarpRKF45 : public G4MagIntegratorStepper
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4CashKarpRKF45.
|
||||
* @param[in] EqRhs Pointer to the provided equation of motion.
|
||||
* @param[in] numberOfVariables The number of integration variables.
|
||||
* @param[in] primary Flag for initialisation of the auxiliary stepper.
|
||||
*/
|
||||
G4CashKarpRKF45( G4EquationOfMotion* EqRhs,
|
||||
G4int numberOfVariables = 6,
|
||||
G4bool primary = true ) ;
|
||||
~G4CashKarpRKF45() override ;
|
||||
G4bool primary = true );
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~G4CashKarpRKF45() override;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4CashKarpRKF45(const G4CashKarpRKF45&) = delete;
|
||||
G4CashKarpRKF45& operator=(const G4CashKarpRKF45&) = delete;
|
||||
// Deleted copy constructor and assignment operator.
|
||||
|
||||
|
||||
/**
|
||||
* The stepper for the Runge Kutta integration.
|
||||
* The stepsize is fixed, with the step size given by 'h'.
|
||||
* Integrates ODE starting values y[0 to 6].
|
||||
* Outputs yout[] and its estimated error yerr[].
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
* @param[out] yerr The estimated error.
|
||||
*/
|
||||
void Stepper( const G4double y[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yout[],
|
||||
G4double yerr[] ) override ;
|
||||
G4double yerr[] ) override;
|
||||
|
||||
G4double DistChord() const override;
|
||||
G4int IntegratorOrder() const override { return 4; }
|
||||
/**
|
||||
* Returns the distance from chord line.
|
||||
*/
|
||||
G4double DistChord() const override;
|
||||
|
||||
/**
|
||||
* Returns the order, 4, of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override { return 4; }
|
||||
|
||||
/**
|
||||
* Returns the stepper type-ID, "kCashKarpRKF45".
|
||||
*/
|
||||
inline G4StepperType StepperType() const override { return kCashKarpRKF45; }
|
||||
|
||||
private:
|
||||
|
||||
void StepWithEst( const G4double yIn[],
|
||||
const G4double dydx[],
|
||||
G4double Step,
|
||||
G4double yOut[],
|
||||
G4double& alpha2,
|
||||
G4double& beta2,
|
||||
const G4double B1[],
|
||||
G4double B2[] );
|
||||
// No longer used. Obsolete.
|
||||
|
||||
private:
|
||||
|
||||
G4double *ak2, *ak3, *ak4, *ak5, *ak6, *yTemp, *yIn; // *ak7
|
||||
// scratch space
|
||||
/** Scratch space. */
|
||||
G4double *ak2, *ak3, *ak4, *ak5, *ak6, *yTemp, *yIn;
|
||||
|
||||
G4double fLastStepLength = 0.0;
|
||||
|
||||
/** For DistChord calculations. */
|
||||
G4double *fLastInitialVector, *fLastFinalVector,
|
||||
*fLastDyDx, *fMidVector, *fMidError;
|
||||
// for DistChord calculations
|
||||
|
||||
G4CashKarpRKF45* fAuxStepper = nullptr;
|
||||
};
|
||||
|
||||
@@ -29,80 +29,92 @@
|
||||
//
|
||||
// Container for magnetic charge and moments.
|
||||
|
||||
// Authors: J.Apostolakis, P.Gumplinger - 10 April 2013
|
||||
// Authors: J.Apostolakis (CERN), P.Gumplinger (TRIUMF), 10.04.2013
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4CHARGESTATE_HH
|
||||
#define G4CHARGESTATE_HH
|
||||
|
||||
#include "globals.hh"
|
||||
|
||||
/**
|
||||
* @brief G4ChargeState is a container for magnetic charge and moments.
|
||||
*/
|
||||
|
||||
class G4ChargeState
|
||||
{
|
||||
public:
|
||||
public:
|
||||
|
||||
inline G4ChargeState(G4double charge,
|
||||
G4double magnetic_dipole_moment,
|
||||
G4double pdgSpin,
|
||||
G4double electric_dipole_moment = 0.0,
|
||||
G4double magnetic_charge = 0.0);
|
||||
/**
|
||||
* Constructor for G4ChargeState.
|
||||
* @param[in] charge Particle charge.
|
||||
* @param[in] magnetic_dipole_moment Magnetic dipole moment.
|
||||
* @param[in] pdgSpin Spin.
|
||||
* @param[in] electric_dipole_moment Electric dipole moment.
|
||||
* @param[in] magnetic_charge Magnetic charge for monopoles.
|
||||
*/
|
||||
inline G4ChargeState(G4double charge,
|
||||
G4double magnetic_dipole_moment,
|
||||
G4double pdgSpin,
|
||||
G4double electric_dipole_moment = 0.0,
|
||||
G4double magnetic_charge = 0.0);
|
||||
|
||||
inline G4ChargeState( const G4ChargeState& right );
|
||||
inline G4ChargeState& operator = ( const G4ChargeState& right );
|
||||
/**
|
||||
* Copy constructor and assignment operator.
|
||||
*/
|
||||
inline G4ChargeState( const G4ChargeState& right );
|
||||
inline G4ChargeState& operator = ( const G4ChargeState& right );
|
||||
|
||||
void SetChargeSpinMoments(G4double charge,
|
||||
G4double pdgSpin,
|
||||
G4double magnetic_dipole_moment= DBL_MAX,
|
||||
G4double electric_dipole_moment= DBL_MAX,
|
||||
G4double magnetic_charge= DBL_MAX );
|
||||
// Revise the charge, pdgSpin, and optionally both moments
|
||||
// and magnetic charge
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4ChargeState() = default;
|
||||
|
||||
void SetCharge(G4double charge){ fCharge = charge; }
|
||||
G4double GetCharge() const { return fCharge; }
|
||||
// Revise the charge (in units of the positron charge)
|
||||
/**
|
||||
* Revises the charge, pdgSpin, and optionally both moments and
|
||||
* magnetic charge.
|
||||
*/
|
||||
void SetChargeSpinMoments(G4double charge,
|
||||
G4double pdgSpin,
|
||||
G4double magnetic_dipole_moment= DBL_MAX,
|
||||
G4double electric_dipole_moment= DBL_MAX,
|
||||
G4double magnetic_charge= DBL_MAX );
|
||||
|
||||
/**
|
||||
* Revises the charge (in units of the positron charge).
|
||||
*/
|
||||
inline void SetCharge(G4double charge);
|
||||
inline G4double GetCharge() const;
|
||||
|
||||
// Basic Get / Set methods
|
||||
/**
|
||||
* Modifiers and accessors.
|
||||
*/
|
||||
inline void SetPDGSpin(G4double spin);
|
||||
inline G4double GetPDGSpin() const;
|
||||
inline void SetSpin(G4double spin);
|
||||
inline G4double GetSpin() const;
|
||||
inline void SetMagneticDipoleMoment(G4double moment);
|
||||
inline G4double GetMagneticDipoleMoment() const;
|
||||
inline void SetElectricDipoleMoment(G4double moment);
|
||||
inline G4double ElectricDipoleMoment() const;
|
||||
inline void SetMagneticCharge(G4double charge);
|
||||
inline G4double MagneticCharge() const;
|
||||
|
||||
void SetPDGSpin(G4double spin){ fSpin = spin; }
|
||||
G4double GetPDGSpin() const { return fSpin; }
|
||||
|
||||
void SetMagneticDipoleMoment(G4double moment){ fMagn_dipole = moment; }
|
||||
G4double GetMagneticDipoleMoment() const { return fMagn_dipole; }
|
||||
|
||||
void SetElectricDipoleMoment(G4double moment){ fElec_dipole = moment; }
|
||||
G4double ElectricDipoleMoment() const { return fElec_dipole; }
|
||||
|
||||
void SetMagneticCharge(G4double charge){ fMagneticCharge=charge; }
|
||||
G4double MagneticCharge() const { return fMagneticCharge; }
|
||||
|
||||
// Auxiliary methods to set several properties at once
|
||||
|
||||
inline void SetChargeMdm(G4double charge, G4double mag_dipole_moment);
|
||||
// SetCharge and Magnetic Dipole Moment
|
||||
|
||||
inline void SetChargeMdmSpin(G4double charge,
|
||||
G4double magnetic_dipole_moment,
|
||||
G4double pdgSpin);
|
||||
|
||||
inline void SetChargeSpin(G4double charge,
|
||||
G4double pdgSpin);
|
||||
|
||||
// Revise the charge, spin and all both moments
|
||||
|
||||
inline void SetChargeDipoleMoments(G4double charge,
|
||||
/**
|
||||
* Auxiliary methods to set several properties at once.
|
||||
*/
|
||||
inline void SetChargeMdm(G4double charge, G4double mag_dipole_moment);
|
||||
inline void SetChargeMdmSpin(G4double charge,
|
||||
G4double magnetic_dipole_moment,
|
||||
G4double electric_dipole_moment);
|
||||
|
||||
inline void SetChargesAndMoments(G4double charge,
|
||||
G4double magnetic_dipole_moment,
|
||||
G4double electric_dipole_moment,
|
||||
G4double magnetic_charge );
|
||||
|
||||
// Obsolete
|
||||
//
|
||||
inline void SetSpin(G4double spin){ SetPDGSpin( spin); }
|
||||
inline G4double GetSpin() const { return GetPDGSpin(); }
|
||||
G4double pdgSpin);
|
||||
inline void SetChargeSpin(G4double charge,
|
||||
G4double pdgSpin);
|
||||
inline void SetChargeDipoleMoments(G4double charge,
|
||||
G4double magnetic_dipole_moment,
|
||||
G4double electric_dipole_moment);
|
||||
inline void SetChargesAndMoments(G4double charge,
|
||||
G4double magnetic_dipole_moment,
|
||||
G4double electric_dipole_moment,
|
||||
G4double magnetic_charge );
|
||||
|
||||
private:
|
||||
|
||||
@@ -115,78 +127,6 @@ class G4ChargeState
|
||||
|
||||
// Inline methods implementation
|
||||
|
||||
inline G4ChargeState::G4ChargeState(G4double charge,
|
||||
G4double magnetic_dipole_moment,
|
||||
G4double spin,
|
||||
G4double electric_dipole_moment,
|
||||
G4double magnetic_charge)
|
||||
{
|
||||
fCharge = charge;
|
||||
fSpin = spin;
|
||||
fMagn_dipole = magnetic_dipole_moment;
|
||||
fElec_dipole = electric_dipole_moment;
|
||||
fMagneticCharge = magnetic_charge;
|
||||
}
|
||||
#include "G4ChargeState.icc"
|
||||
|
||||
inline G4ChargeState::G4ChargeState( const G4ChargeState& right )
|
||||
{
|
||||
fCharge = right.fCharge;
|
||||
fSpin = right.fSpin;
|
||||
fMagn_dipole = right.fMagn_dipole;
|
||||
fElec_dipole = right.fElec_dipole;
|
||||
fMagneticCharge = right.fMagneticCharge;
|
||||
}
|
||||
|
||||
inline G4ChargeState& G4ChargeState::operator = ( const G4ChargeState& right )
|
||||
{
|
||||
if (&right == this) { return *this; }
|
||||
|
||||
fCharge = right.fCharge;
|
||||
fSpin = right.fSpin;
|
||||
fMagn_dipole = right.fMagn_dipole;
|
||||
fElec_dipole = right.fElec_dipole;
|
||||
fMagneticCharge = right.fMagneticCharge;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void G4ChargeState::SetChargeMdm(G4double charge, G4double mdipole_mom)
|
||||
{
|
||||
SetCharge( charge );
|
||||
SetMagneticDipoleMoment( mdipole_mom );
|
||||
}
|
||||
|
||||
inline void G4ChargeState::SetChargeMdmSpin(G4double charge,
|
||||
G4double magDipoleMoment,
|
||||
G4double pdgSpin)
|
||||
{
|
||||
SetChargeMdm( charge, magDipoleMoment );
|
||||
SetPDGSpin( pdgSpin );
|
||||
}
|
||||
|
||||
inline void G4ChargeState::SetChargeSpin(G4double charge,
|
||||
G4double pdgSpin)
|
||||
{
|
||||
SetCharge( charge );
|
||||
SetPDGSpin( pdgSpin );
|
||||
}
|
||||
|
||||
inline void
|
||||
G4ChargeState::SetChargeDipoleMoments(G4double charge,
|
||||
G4double magneticDM,
|
||||
G4double electricDM)
|
||||
{
|
||||
SetChargeMdm( charge, magneticDM );
|
||||
SetElectricDipoleMoment( electricDM );
|
||||
}
|
||||
|
||||
inline void
|
||||
G4ChargeState::SetChargesAndMoments(G4double charge,
|
||||
G4double magneticDM,
|
||||
G4double electricDM,
|
||||
G4double magnetic_charge )
|
||||
{
|
||||
SetChargeDipoleMoments( charge, magneticDM, electricDM);
|
||||
SetMagneticCharge( magnetic_charge );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4ChargeState inline methods implementation
|
||||
|
||||
// Authors: J.Apostolakis (CERN), P.Gumplinger (TRIUMF), 10.04.2013
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
inline G4ChargeState::G4ChargeState(G4double charge,
|
||||
G4double magnetic_dipole_moment,
|
||||
G4double spin,
|
||||
G4double electric_dipole_moment,
|
||||
G4double magnetic_charge)
|
||||
{
|
||||
fCharge = charge;
|
||||
fSpin = spin;
|
||||
fMagn_dipole = magnetic_dipole_moment;
|
||||
fElec_dipole = electric_dipole_moment;
|
||||
fMagneticCharge = magnetic_charge;
|
||||
}
|
||||
|
||||
inline G4ChargeState::G4ChargeState( const G4ChargeState& right )
|
||||
{
|
||||
fCharge = right.fCharge;
|
||||
fSpin = right.fSpin;
|
||||
fMagn_dipole = right.fMagn_dipole;
|
||||
fElec_dipole = right.fElec_dipole;
|
||||
fMagneticCharge = right.fMagneticCharge;
|
||||
}
|
||||
|
||||
inline G4ChargeState& G4ChargeState::operator = ( const G4ChargeState& right )
|
||||
{
|
||||
if (&right == this) { return *this; }
|
||||
|
||||
fCharge = right.fCharge;
|
||||
fSpin = right.fSpin;
|
||||
fMagn_dipole = right.fMagn_dipole;
|
||||
fElec_dipole = right.fElec_dipole;
|
||||
fMagneticCharge = right.fMagneticCharge;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void G4ChargeState::SetCharge(G4double charge)
|
||||
{
|
||||
fCharge = charge;
|
||||
}
|
||||
|
||||
inline G4double G4ChargeState::GetCharge() const
|
||||
{
|
||||
return fCharge;
|
||||
}
|
||||
|
||||
inline void G4ChargeState::SetPDGSpin(G4double spin)
|
||||
{
|
||||
fSpin = spin;
|
||||
}
|
||||
|
||||
inline G4double G4ChargeState::GetPDGSpin() const
|
||||
{
|
||||
return fSpin;
|
||||
}
|
||||
|
||||
inline void G4ChargeState::SetSpin(G4double spin)
|
||||
{
|
||||
SetPDGSpin( spin);
|
||||
}
|
||||
|
||||
inline G4double G4ChargeState::GetSpin() const
|
||||
{
|
||||
return GetPDGSpin();
|
||||
}
|
||||
|
||||
inline void G4ChargeState::SetMagneticDipoleMoment(G4double moment)
|
||||
{
|
||||
fMagn_dipole = moment;
|
||||
}
|
||||
|
||||
inline G4double G4ChargeState::GetMagneticDipoleMoment() const
|
||||
{
|
||||
return fMagn_dipole;
|
||||
}
|
||||
|
||||
inline void G4ChargeState::SetElectricDipoleMoment(G4double moment)
|
||||
{
|
||||
fElec_dipole = moment;
|
||||
}
|
||||
|
||||
inline G4double G4ChargeState::ElectricDipoleMoment() const
|
||||
{
|
||||
return fElec_dipole;
|
||||
}
|
||||
|
||||
inline void G4ChargeState::SetMagneticCharge(G4double charge)
|
||||
{
|
||||
fMagneticCharge=charge;
|
||||
}
|
||||
|
||||
inline G4double G4ChargeState::MagneticCharge() const
|
||||
{
|
||||
return fMagneticCharge;
|
||||
}
|
||||
|
||||
inline void G4ChargeState::SetChargeMdm(G4double charge, G4double mdipole_mom)
|
||||
{
|
||||
SetCharge( charge );
|
||||
SetMagneticDipoleMoment( mdipole_mom );
|
||||
}
|
||||
|
||||
inline void G4ChargeState::SetChargeMdmSpin(G4double charge,
|
||||
G4double magDipoleMoment,
|
||||
G4double pdgSpin)
|
||||
{
|
||||
SetChargeMdm( charge, magDipoleMoment );
|
||||
SetPDGSpin( pdgSpin );
|
||||
}
|
||||
|
||||
inline void G4ChargeState::SetChargeSpin(G4double charge,
|
||||
G4double pdgSpin)
|
||||
{
|
||||
SetCharge( charge );
|
||||
SetPDGSpin( pdgSpin );
|
||||
}
|
||||
|
||||
inline void
|
||||
G4ChargeState::SetChargeDipoleMoments(G4double charge,
|
||||
G4double magneticDM,
|
||||
G4double electricDM)
|
||||
{
|
||||
SetChargeMdm( charge, magneticDM );
|
||||
SetElectricDipoleMoment( electricDM );
|
||||
}
|
||||
|
||||
inline void
|
||||
G4ChargeState::SetChargesAndMoments(G4double charge,
|
||||
G4double magneticDM,
|
||||
G4double electricDM,
|
||||
G4double magnetic_charge )
|
||||
{
|
||||
SetChargeDipoleMoments( charge, magneticDM, electricDM);
|
||||
SetMagneticCharge( magnetic_charge );
|
||||
}
|
||||
@@ -31,12 +31,13 @@
|
||||
// and also has a method that returns an Approximate point on the curve
|
||||
// near to a (chord) point.
|
||||
|
||||
// Author: J.Apostolakis - Design and implementation - 25.02.1997
|
||||
// Author: John Apostolakis (CERN), 25.02.1997 - Design and implementation
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4CHORDFINDER_HH
|
||||
#define G4CHORDFINDER_HH
|
||||
|
||||
#include "G4VIntegrationDriver.hh"
|
||||
#include "G4FieldParameters.hh"
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
|
||||
#include <memory>
|
||||
@@ -48,116 +49,166 @@ class G4CachedMagneticField;
|
||||
class G4HelixHeum;
|
||||
class G4QSStepper;
|
||||
|
||||
/**
|
||||
* @brief G4ChordFinder is a class that provides Runge-Kutta integration of
|
||||
* motion ODE and also has a method that returns an approximate point on the
|
||||
* curve near to a (chord) point.
|
||||
*/
|
||||
|
||||
class G4ChordFinder
|
||||
{
|
||||
public: // with description
|
||||
public:
|
||||
|
||||
explicit G4ChordFinder( G4VIntegrationDriver* pIntegrationDriver );
|
||||
// The most flexible constructor, which allows the user to specify
|
||||
// any type of field, equation, stepper and integration driver.
|
||||
enum kIntegrationType {kDefaultDriverType=0, kFSALStepperType=1,
|
||||
kTemplatedStepperType, kRegularStepperType,
|
||||
kBfieldDriverType, kQss2DriverType, kQss3DriverType};
|
||||
|
||||
enum kIntegrationType { kDefaultDriverType=0, kFSALStepperType=1,
|
||||
kTemplatedStepperType, kRegularStepperType, kBfieldDriverType, kQss2DriverType, kQss3DriverType };
|
||||
/**
|
||||
* The most flexible constructor, which allows the user to specify
|
||||
* any type of field, equation, stepper and integration driver.
|
||||
* @param[in] pIntegrationDriver Pointer to the integrator driver to use.
|
||||
*/
|
||||
explicit G4ChordFinder( G4VIntegrationDriver* pIntegrationDriver );
|
||||
|
||||
G4ChordFinder( G4MagneticField* itsMagField,
|
||||
G4double stepMinimum = 1.0e-2, // * mm
|
||||
G4MagIntegratorStepper* pItsStepper = nullptr,
|
||||
// G4bool useHigherEfficiencyStepper = true,
|
||||
G4int stepperDriverChoice = kTemplatedStepperType );
|
||||
// A constructor that creates defaults for all "children" classes.
|
||||
//
|
||||
// The type of equation of motion is fixed.
|
||||
// A default type of stepper (Dormand Prince since release 10.4) is used,
|
||||
// and the corresponding integration driver.
|
||||
// Except if 'useFSAL' is set (true), which provides a FSAL stepper
|
||||
// and its corresponding specialised (templated) driver.
|
||||
/**
|
||||
* Constructor that creates defaults for all "children" classes.
|
||||
* The type of equation of motion is fixed.
|
||||
* A default type of stepper (Dormand Prince since release 10.4) is used,
|
||||
* and the corresponding integration driver.
|
||||
* @param[in] itsMagField Pointer to the magnetic field.
|
||||
* @param[in] stepMinimum Pointer to the magnetic field.
|
||||
* @param[in] pItsStepper Optional pointer to the stepper algorithm.
|
||||
* @param[in] stepperDriverChoice Type of stepper driver.
|
||||
*/
|
||||
G4ChordFinder( G4MagneticField* itsMagField,
|
||||
G4double stepMinimum = G4FieldDefaults::kMinimumStep,
|
||||
G4MagIntegratorStepper* pItsStepper = nullptr,
|
||||
G4int stepperDriverChoice = kTemplatedStepperType );
|
||||
|
||||
virtual ~G4ChordFinder();
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~G4ChordFinder();
|
||||
|
||||
G4ChordFinder(const G4ChordFinder&) = delete;
|
||||
G4ChordFinder& operator=(const G4ChordFinder&) = delete;
|
||||
// Copy constructor and assignment operator not allowed.
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4ChordFinder(const G4ChordFinder&) = delete;
|
||||
G4ChordFinder& operator=(const G4ChordFinder&) = delete;
|
||||
|
||||
inline G4double AdvanceChordLimited( G4FieldTrack& yCurrent,
|
||||
G4double stepInitial,
|
||||
G4double epsStep_Relative,
|
||||
const G4ThreeVector& latestSafetyOrigin,
|
||||
G4double lasestSafetyRadius);
|
||||
// Uses ODE solver's driver to find the endpoint that satisfies
|
||||
// the chord criterion: that d_chord < delta_chord
|
||||
// -> Returns Length of Step taken.
|
||||
/**
|
||||
* Computes the step to take, based on chord limits.
|
||||
* Uses ODE solver's driver to find the endpoint that satisfies
|
||||
* the chord criterion that: d_chord < delta_chord.
|
||||
* @param[in,out] yCurrent The current track in field.
|
||||
* @param[in] stepInitial Proposed initial step length.
|
||||
* @param[in] epsStep_Relative Requested accuracy.
|
||||
* @param[in] latestSafetyOrigin Last safety origin point. Unused.
|
||||
* @param[in] lasestSafetyRadius Last safety distance. Unused.
|
||||
* @returns The length of step taken.
|
||||
*/
|
||||
inline G4double AdvanceChordLimited( G4FieldTrack& yCurrent,
|
||||
G4double stepInitial,
|
||||
G4double epsStep_Relative,
|
||||
const G4ThreeVector& latestSafetyOrigin,
|
||||
G4double lasestSafetyRadius );
|
||||
|
||||
G4FieldTrack ApproxCurvePointS( const G4FieldTrack& curveAPointVelocity,
|
||||
const G4FieldTrack& curveBPointVelocity,
|
||||
const G4FieldTrack& ApproxCurveV,
|
||||
const G4ThreeVector& currentEPoint,
|
||||
const G4ThreeVector& currentFPoint,
|
||||
const G4ThreeVector& PointG,
|
||||
G4bool first, G4double epsStep);
|
||||
/**
|
||||
* Uses the Brent algorithm when possible, to determine the closest point
|
||||
* on the curve. Given a starting curve point A (CurveA_PointVelocity),
|
||||
* curve point B (CurveB_PointVelocity), a point E which is (generally)
|
||||
* not on the curve and a point F which is on the curve (first
|
||||
* approximation), find new point S on the curve closer to point E.
|
||||
* While advancing towards S utilise 'eps_step' as a measure of the
|
||||
* relative accuracy of each Step.
|
||||
* @returns The end point on the curve closer to the given point E.
|
||||
*/
|
||||
G4FieldTrack ApproxCurvePointS( const G4FieldTrack& curveAPointVelocity,
|
||||
const G4FieldTrack& curveBPointVelocity,
|
||||
const G4FieldTrack& ApproxCurveV,
|
||||
const G4ThreeVector& currentEPoint,
|
||||
const G4ThreeVector& currentFPoint,
|
||||
const G4ThreeVector& PointG,
|
||||
G4bool first, G4double epsStep );
|
||||
|
||||
G4FieldTrack ApproxCurvePointV( const G4FieldTrack& curveAPointVelocity,
|
||||
const G4FieldTrack& curveBPointVelocity,
|
||||
const G4ThreeVector& currentEPoint,
|
||||
G4double epsStep);
|
||||
/**
|
||||
* If r=|AE|/|AB|, and s=true path lenght (AB)
|
||||
* returns the point that is r*s along the curve.
|
||||
*/
|
||||
G4FieldTrack ApproxCurvePointV( const G4FieldTrack& curveAPointVelocity,
|
||||
const G4FieldTrack& curveBPointVelocity,
|
||||
const G4ThreeVector& currentEPoint,
|
||||
G4double epsStep);
|
||||
|
||||
inline G4double InvParabolic( const G4double xa, const G4double ya,
|
||||
const G4double xb, const G4double yb,
|
||||
const G4double xc, const G4double yc );
|
||||
/**
|
||||
* Calculates the inverse parabolic through the three points (x,y) and
|
||||
* returns the value x that, for the inverse parabolic, corresponds to y=0.
|
||||
*/
|
||||
inline G4double InvParabolic( const G4double xa, const G4double ya,
|
||||
const G4double xb, const G4double yb,
|
||||
const G4double xc, const G4double yc );
|
||||
|
||||
inline G4double GetDeltaChord() const;
|
||||
inline void SetDeltaChord(G4double newval);
|
||||
/**
|
||||
* Accessors and modifiers.
|
||||
*/
|
||||
inline G4double GetDeltaChord() const;
|
||||
inline void SetDeltaChord(G4double newval);
|
||||
inline void SetIntegrationDriver(G4VIntegrationDriver* IntegrationDriver);
|
||||
inline G4VIntegrationDriver* GetIntegrationDriver();
|
||||
|
||||
inline void SetIntegrationDriver(G4VIntegrationDriver* IntegrationDriver);
|
||||
inline G4VIntegrationDriver* GetIntegrationDriver();
|
||||
// Access and set Driver.
|
||||
/**
|
||||
* Clears the internal state (last step estimate).
|
||||
*/
|
||||
inline void ResetStepEstimate();
|
||||
|
||||
inline void ResetStepEstimate();
|
||||
// Clear internal state (last step estimate)
|
||||
/**
|
||||
* Sets the verbosity.
|
||||
* @returns The old verbosity value.
|
||||
*/
|
||||
inline G4int SetVerbose( G4int newvalue=1 );
|
||||
|
||||
inline G4int SetVerbose( G4int newvalue=1);
|
||||
// Set verbosity and return old value
|
||||
/**
|
||||
* Dispatch interface method for computing step.
|
||||
*/
|
||||
inline void OnComputeStep(const G4FieldTrack* track);
|
||||
|
||||
void OnComputeStep(const G4FieldTrack* track);
|
||||
/**
|
||||
* Writes out to stream the parameters/state of the driver.
|
||||
*/
|
||||
friend std::ostream& operator<<( std::ostream& os, const G4ChordFinder& cf);
|
||||
|
||||
friend std::ostream&
|
||||
operator<<( std::ostream& os, const G4ChordFinder& cf);
|
||||
/**
|
||||
* Sets verbosity for constructor.
|
||||
*/
|
||||
static void SetVerboseConstruction(G4bool v = true);
|
||||
|
||||
static void SetVerboseConstruction(G4bool v=true) { gVerboseCtor=v;}
|
||||
// Verbosity for contructor
|
||||
protected: // .........................................................
|
||||
private: // ............................................................
|
||||
|
||||
void PrintDchordTrial(G4int noTrials,
|
||||
G4double stepTrial,
|
||||
G4double oldStepTrial,
|
||||
G4double dChordStep);
|
||||
static G4bool gVerboseCtor; // Verbosity for contructor
|
||||
|
||||
static G4bool gVerboseCtor; // Verbosity for contructor
|
||||
// Constants
|
||||
// ---------------------
|
||||
const G4double fDefaultDeltaChord = G4FieldDefaults::kDeltaChord;
|
||||
|
||||
private: // ............................................................
|
||||
// PARAMETERS
|
||||
// ---------------------
|
||||
G4double fDeltaChord; // Maximum miss distance
|
||||
|
||||
// Constants
|
||||
// ---------------------
|
||||
const G4double fDefaultDeltaChord; // SET in G4ChordFinder.cc = 0.25 mm
|
||||
G4int fStatsVerbose = 0; // if > 0, print Statistics in destructor
|
||||
|
||||
// PARAMETERS
|
||||
// ---------------------
|
||||
G4double fDeltaChord; // Maximum miss distance
|
||||
|
||||
G4int fStatsVerbose = 0; // if > 0, print Statistics in destructor
|
||||
|
||||
// DEPENDENT Objects
|
||||
// ---------------------
|
||||
G4VIntegrationDriver* fIntgrDriver = nullptr;
|
||||
G4MagIntegratorStepper* fRegularStepperOwned = nullptr;
|
||||
G4MagIntegratorStepper* fNewFSALStepperOwned = nullptr;
|
||||
std::unique_ptr<G4HelixHeum> fLongStepper;
|
||||
G4CachedMagneticField* fCachedField = nullptr;
|
||||
G4QSStepper* fQssStepperOwned = nullptr;
|
||||
G4EquationOfMotion* fEquation = nullptr;
|
||||
// DEPENDENT Objects
|
||||
// ---------------------
|
||||
G4VIntegrationDriver* fIntgrDriver = nullptr;
|
||||
G4MagIntegratorStepper* fRegularStepperOwned = nullptr;
|
||||
G4MagIntegratorStepper* fNewFSALStepperOwned = nullptr;
|
||||
std::unique_ptr<G4HelixHeum> fLongStepper;
|
||||
G4CachedMagneticField* fCachedField = nullptr;
|
||||
G4QSStepper* fQssStepperOwned = nullptr;
|
||||
G4EquationOfMotion* fEquation = nullptr;
|
||||
};
|
||||
|
||||
// Inline function implementation:
|
||||
|
||||
#include "G4ChordFinder.icc"
|
||||
|
||||
#endif // G4CHORDFINDER_HH
|
||||
#endif
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
//
|
||||
// G4ChordFinder inline implementations
|
||||
//
|
||||
// Author: J.Apostolakis - Design and implementation - 25.02.1997
|
||||
// Author: John Apostolakis (CERN), 25.02.1997 - Design and implementation
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
inline
|
||||
|
||||
@@ -28,55 +28,89 @@
|
||||
// Class description:
|
||||
//
|
||||
// Implementation of common algorithm of finding step size
|
||||
// with distance to chord less then provided value.
|
||||
// with distance to chord less than provided value.
|
||||
|
||||
// Created: D.Sorokin
|
||||
// Author: Dmitry Sorokin (CERN, Google Summer of Code 2017), 12.09.2018
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4CHORD_FINDER_DELEGATE_HH
|
||||
#define G4CHORD_FINDER_DELEGATE_HH
|
||||
|
||||
#include <iomanip>
|
||||
#include "G4VIntegrationDriver.hh"
|
||||
|
||||
/**
|
||||
* @brief G4ChordFinderDelegate is a templated class for a common algorithm
|
||||
* of finding step size with distance to the chord less than the provided value.
|
||||
*/
|
||||
|
||||
template <class Driver>
|
||||
class G4ChordFinderDelegate
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Virtual Destructor.
|
||||
*/
|
||||
virtual ~G4ChordFinderDelegate();
|
||||
|
||||
/**
|
||||
* Computes the step to take, based on chord limits.
|
||||
* @param[in,out] track The current track in field.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[in] eps Requested accuracy, y_err/hstep.
|
||||
* @param[in] chordDistance Maximum sagitta distance.
|
||||
* @returns The length of step taken.
|
||||
*/
|
||||
G4double AdvanceChordLimitedImpl(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps,
|
||||
G4double chordDistance);
|
||||
|
||||
/**
|
||||
* Resets last step estimate to DBL_MAX.
|
||||
*/
|
||||
void ResetStepEstimate();
|
||||
|
||||
/**
|
||||
* Getter and setter for step estimate.
|
||||
*/
|
||||
G4double GetLastStepEstimateUnc();
|
||||
void SetLastStepEstimateUnc(G4double stepEst);
|
||||
|
||||
/**
|
||||
* Gets statistics about number of calls & trials in FindNextChord().
|
||||
*/
|
||||
G4int GetNoCalls();
|
||||
G4int GetNoTrials(); // Total number of trials
|
||||
G4int GetNoMaxTrials(); // Maximum # of trials for one call
|
||||
|
||||
/**
|
||||
* Setters of performance parameters... change with great care!
|
||||
*/
|
||||
void SetFractions_Last_Next(G4double fractLast = 0.90,
|
||||
G4double fractNext = 0.95);
|
||||
void SetFirstFraction(G4double fractFirst);
|
||||
|
||||
/**
|
||||
* Printing for monitoring ...
|
||||
*/
|
||||
G4double GetFirstFraction(); // Originally 0.999
|
||||
G4double GetFractionLast(); // Originally 1.000
|
||||
G4double GetFractionNextEstimate(); // Originally 0.980
|
||||
|
||||
/**
|
||||
* Writes out to stream the parameters/state of the driver.
|
||||
*/
|
||||
void StreamDelegateInfo( std::ostream& os ) const;
|
||||
|
||||
/**
|
||||
* statistics printout for testing.
|
||||
*/
|
||||
void TestChordPrint(G4int noTrials,
|
||||
G4int lastStepTrial,
|
||||
G4double dChordStep,
|
||||
G4double fDeltaChord,
|
||||
G4double nextStepTrial);
|
||||
|
||||
// Get statistics about number of calls & trials in FindNextChord
|
||||
G4int GetNoCalls();
|
||||
G4int GetNoTrials(); // Total number of trials
|
||||
G4int GetNoMaxTrials(); // Maximum # of trials for one call
|
||||
|
||||
// Parameters for performance ... change with great care
|
||||
void SetFractions_Last_Next(G4double fractLast = 0.90,
|
||||
G4double fractNext = 0.95);
|
||||
void SetFirstFraction(G4double fractFirst);
|
||||
|
||||
// Printing for monitoring ...
|
||||
G4double GetFirstFraction(); // Originally 0.999
|
||||
G4double GetFractionLast(); // Originally 1.000
|
||||
G4double GetFractionNextEstimate(); // Originally 0.980
|
||||
|
||||
G4double GetLastStepEstimateUnc();
|
||||
void SetLastStepEstimateUnc(G4double stepEst);
|
||||
|
||||
void StreamDelegateInfo( std::ostream& os ) const;
|
||||
// Write out the parameters / state of the driver
|
||||
|
||||
private:
|
||||
|
||||
Driver& GetDriver();
|
||||
@@ -98,6 +132,8 @@ class G4ChordFinderDelegate
|
||||
|
||||
void PrintStatistics();
|
||||
|
||||
private:
|
||||
|
||||
G4double fFirstFraction = 0.999;
|
||||
G4double fFractionLast = 1.0;
|
||||
G4double fFractionNextEstimate = 0.98;
|
||||
|
||||
@@ -25,11 +25,9 @@
|
||||
//
|
||||
// G4ChordFinderDelegate inline methods implementation
|
||||
//
|
||||
// Created: D.Sorokin
|
||||
// Author: Dmitry Sorokin (CERN, Google Summer of Code 2017), 12.09.2018
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
template <class Driver>
|
||||
G4ChordFinderDelegate<Driver>::~G4ChordFinderDelegate()
|
||||
{
|
||||
|
||||
@@ -30,54 +30,70 @@
|
||||
// Integrate the equations of the motion of a particle in a magnetic field
|
||||
// using the classical 4th Runge-Kutta method.
|
||||
|
||||
// Created: J.Apostolakis, V.Grichine - 30.01.1997
|
||||
// Authors: J.Apostolakis, V.Grichine (CERN), 30.01.1997
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4CLASSICALRK4_HH
|
||||
#define G4CLASSICALRK4_HH
|
||||
|
||||
#include "G4MagErrorStepper.hh"
|
||||
|
||||
/**
|
||||
* @brief G4ClassicalRK4 integrates the equations of the motion of a particle
|
||||
* in a magnetic field using the classical 4th Runge-Kutta method.
|
||||
*/
|
||||
|
||||
class G4ClassicalRK4 : public G4MagErrorStepper
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4ClassicalRK4.
|
||||
* @param[in] EquationMotion Pointer to the provided equation of motion.
|
||||
* @param[in] numberOfVariables The number of integration variables.
|
||||
*/
|
||||
G4ClassicalRK4(G4EquationOfMotion* EquationMotion,
|
||||
G4int numberOfVariables = 6) ;
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~G4ClassicalRK4() override ;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4ClassicalRK4(const G4ClassicalRK4&) = delete;
|
||||
G4ClassicalRK4& operator=(const G4ClassicalRK4&) = delete;
|
||||
// Copy constructor and assignment operator not allowed.
|
||||
|
||||
// A stepper that does not know about errors.
|
||||
// It is used by the MagErrorStepper stepper.
|
||||
|
||||
/**
|
||||
* Given values for the variables y[0,..,n-1] and their derivatives
|
||||
* dydx[0,...,n-1] known at x, uses the classical 4th Runge-Kutta
|
||||
* method to advance the solution over an interval h and returns the
|
||||
* incremented variables as yout[0,...,n-1]. The user supplies the
|
||||
* function RightHandSide(x,y,dydx), which returns derivatives dydx at x.
|
||||
* The source is routine rk4 from NRC p.712-713.
|
||||
* @param[in] yIn Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yOut Integration output.
|
||||
*/
|
||||
void DumbStepper( const G4double yIn[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yOut[] ) override ;
|
||||
// Given values for the variables y[0,..,n-1] and their derivatives
|
||||
// dydx[0,...,n-1] known at x, use the classical 4th Runge-Kutta
|
||||
// method to advance the solution over an interval h and return the
|
||||
// incremented variables as yout[0,...,n-1], which not be a distinct
|
||||
// array from y. The user supplies the routine RightHandSide(x,y,dydx),
|
||||
// which returns derivatives dydx at x. The source is routine rk4 from
|
||||
// NRC p. 712-713 .
|
||||
|
||||
/**
|
||||
* Returns the order, 4, of integration.
|
||||
*/
|
||||
G4int IntegratorOrder() const override { return 4; }
|
||||
|
||||
private:
|
||||
|
||||
void StepWithEst( const G4double yIn[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yOut[],
|
||||
G4double& alpha2,
|
||||
G4double& beta2,
|
||||
const G4double B1[],
|
||||
G4double B2[] );
|
||||
// No longer used. Obsolete.
|
||||
/**
|
||||
* Returns the stepper type-ID, "kClassicalRK4".
|
||||
*/
|
||||
G4StepperType StepperType() const override { return kClassicalRK4; }
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
//
|
||||
// G4ConstRK4
|
||||
//
|
||||
// class description:
|
||||
// Class description:
|
||||
//
|
||||
// G4ConstRK4 performs the integration of one step with error calculation
|
||||
// in constant magnetic field. The integration method is the same as in
|
||||
@@ -33,7 +33,7 @@
|
||||
// This field evaluation is called only once per step.
|
||||
// G4ConstRK4 can be used only for magnetic fields.
|
||||
|
||||
// Created: J.Apostolakis, T.Nikitina - 18.09.2008
|
||||
// Authors: J.Apostolakis, T.Nikitina (CERN), 18.09.2008
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4CONSTRK4_HH
|
||||
#define G4CONSTRK4_HH
|
||||
@@ -42,34 +42,99 @@
|
||||
#include "G4EquationOfMotion.hh"
|
||||
#include "G4Mag_EqRhs.hh"
|
||||
|
||||
/**
|
||||
* @brief G4ConstRK4 performs the integration of one step with error
|
||||
* calculation in constant magnetic field. The integration method is the
|
||||
* same as in ClassicalRK4. The field value is assumed constant for the step.
|
||||
* This field evaluation is called only once per step.
|
||||
* G4ConstRK4 can be used only for magnetic fields.
|
||||
*/
|
||||
|
||||
class G4ConstRK4 : public G4MagErrorStepper
|
||||
{
|
||||
public:
|
||||
|
||||
G4ConstRK4(G4Mag_EqRhs* EquationMotion, G4int numberOfStateVariables=8);
|
||||
~G4ConstRK4() override;
|
||||
/**
|
||||
* Constructor for G4ConstRK4.
|
||||
* @param[in] EqRhs Pointer to the provided equation of motion.
|
||||
* @param[in] numberOfVariables The number of integration variables.
|
||||
*/
|
||||
G4ConstRK4(G4Mag_EqRhs* EquationMotion,
|
||||
G4int numberOfStateVariables=8);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~G4ConstRK4() override;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4ConstRK4(const G4ConstRK4&) = delete;
|
||||
G4ConstRK4& operator=(const G4ConstRK4&) = delete;
|
||||
// Copy constructor and assignment operator not allowed
|
||||
|
||||
/**
|
||||
* The stepper for the Runge Kutta integration.
|
||||
* The stepsize is fixed, with the step size given by 'h'.
|
||||
* Integrates ODE starting values y[0 to 6].
|
||||
* Outputs yout[] and its estimated error yerr[].
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
* @param[out] yerr The estimated error.
|
||||
*/
|
||||
void Stepper( const G4double y[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yout[],
|
||||
G4double yerr[] ) override;
|
||||
|
||||
/**
|
||||
* Given values for the variables y[0,..,n-1] and their derivatives
|
||||
* dydx[0,...,n-1] known at x, uses the classical 4th Runge-Kutta
|
||||
* method to advance the solution over an interval h and returns the
|
||||
* incremented variables as yout[0,...,n-1]. The user supplies the
|
||||
* function RightHandSide(x,y,dydx), which returns derivatives dydx at x.
|
||||
* The source is routine rk4 from NRC p.712-713.
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
*/
|
||||
void DumbStepper( const G4double yIn[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yOut[] ) override ;
|
||||
|
||||
/**
|
||||
* Returns the distance from chord line.
|
||||
*/
|
||||
G4double DistChord() const override;
|
||||
|
||||
inline void RightHandSideConst(const G4double y[],
|
||||
G4double dydx[] ) const;
|
||||
/**
|
||||
* Returns the derivatives value, at position and time 'y'.
|
||||
* @param[in] y The position vector plus time (x,y,z,t).
|
||||
* @param[out] dydx The derivatives array.
|
||||
*/
|
||||
inline void RightHandSideConst(const G4double y[], G4double dydx[] ) const;
|
||||
|
||||
inline void GetConstField(const G4double y[], G4double Field[]);
|
||||
/**
|
||||
* Returns the field values, at position and time 'y'.
|
||||
* @param[in] y The position vector plus time (x,y,z,t).
|
||||
* @param[out] Field The field value in output.
|
||||
*/
|
||||
inline void GetConstField(const G4double y[], G4double Field[]);
|
||||
|
||||
G4int IntegratorOrder() const override { return 4; }
|
||||
/**
|
||||
* Returns the order, 4, of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override { return 4; }
|
||||
|
||||
/**
|
||||
* Returns the stepper type-ID, "kConstRK4".
|
||||
*/
|
||||
inline G4StepperType StepperType() const override { return kConstRK4; }
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -27,29 +27,47 @@
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// Class describing the DELPHI magnetic field. This axial symmetry
|
||||
// field mainly directed along Z axis. The function MagneticField(yTrack,B)
|
||||
// Class describing the DELPHI magnetic field. The axial symmetry
|
||||
// field is mainly directed along Z axis. The function MagneticField(yTrack,B)
|
||||
// calculates the magnetic induction vector B in point corresponding to
|
||||
// yTrack according to parametrization given in:
|
||||
// P.Billoir, Precise tracking in a quasi-honogeneous magnetic field,
|
||||
// P.Billoir, Precise tracking in a quasi-homogeneous magnetic field,
|
||||
// DELPHI 87-6 PROG 65, 1987.
|
||||
|
||||
// Created: V.Grichine - 03.02.1997
|
||||
// Author: Vladimir Grichine (CERN), 03.02.1997
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4DELPHIMAGFIELD_HH
|
||||
#define G4DELPHIMAGFIELD_HH
|
||||
|
||||
#include "G4MagneticField.hh"
|
||||
|
||||
/**
|
||||
* @brief describes the DELPHI magnetic field. The axial symmetry field is
|
||||
* mainly directed along Z axis. The function MagneticField(yTrack,B)
|
||||
* calculates the magnetic induction vector B in given point corresponding
|
||||
* according to parameterisation given in: P.Billoir, DELPHI 87-6 PROG 65, 1987.
|
||||
*/
|
||||
|
||||
class G4DELPHIMagField : public G4MagneticField
|
||||
{
|
||||
public:
|
||||
|
||||
G4DELPHIMagField();
|
||||
~G4DELPHIMagField() override;
|
||||
/**
|
||||
* Default Constructor and Destructor.
|
||||
*/
|
||||
G4DELPHIMagField() = default;
|
||||
~G4DELPHIMagField() override = default;
|
||||
|
||||
void GetFieldValue(const G4double yTrack[],
|
||||
G4double B[] ) const override;
|
||||
/**
|
||||
* Returns the field value on the given position 'yTrack'.
|
||||
* @param[in] yTrack Time position array.
|
||||
* @param[out] B The returned field array.
|
||||
*/
|
||||
void GetFieldValue(const G4double yTrack[], G4double B[]) const override;
|
||||
|
||||
/**
|
||||
* Returns a pointer to a new allocated clone of this object.
|
||||
*/
|
||||
G4Field* Clone() const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -27,71 +27,110 @@
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// Dormand-Lockyer-McGorrigan-Prince-6-3-4 non-FSAL method
|
||||
// ( 6 stage, 3rd & 4th order embedded RK method )
|
||||
// Dormand-Lockyer-McGorrigan-Prince-6-3-4 non-FSAL method
|
||||
// ( 6 stage, 3rd & 4th order embedded RK method )
|
||||
|
||||
// Created: Somnath Banerjee, Google Summer of Code 2015, 7 July 2015
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// Author: Somnath Banerjee (CERN, Google Summer of Code 2015), 07.07.2015
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef DOLO_MCPRI_RK34_HH
|
||||
#define DOLO_MCPRI_RK34_HH
|
||||
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
|
||||
/**
|
||||
* @brief G4DoLoMcPriRK34 implements the Dormand-Lockyer-McGorrigan-Prince-6-3-4
|
||||
* non-FSAL method ( 6 stage, 3rd & 4th order embedded Runge-Kutta method ).
|
||||
*/
|
||||
|
||||
class G4DoLoMcPriRK34 : public G4MagIntegratorStepper
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4DoLoMcPriRK34.
|
||||
* @param[in] EqRhs Pointer to the provided equation of motion.
|
||||
* @param[in] numberOfVariables The number of integration variables.
|
||||
* @param[in] primary Flag for initialisation of the auxiliary stepper.
|
||||
*/
|
||||
G4DoLoMcPriRK34( G4EquationOfMotion* EqRhs,
|
||||
G4int numberOfVariables = 6,
|
||||
G4bool primary = true );
|
||||
// Constructor using Equation
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~G4DoLoMcPriRK34() override;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4DoLoMcPriRK34(const G4DoLoMcPriRK34&) = delete;
|
||||
G4DoLoMcPriRK34& operator=(const G4DoLoMcPriRK34&) = delete;
|
||||
// Copy constructor and assignment operator not allowed
|
||||
|
||||
/**
|
||||
* The stepper for the Runge Kutta integration.
|
||||
* The stepsize is fixed, with the step size given by 'h'.
|
||||
* Integrates ODE starting values y[0 to 6].
|
||||
* Outputs yout[] and its estimated error yerr[].
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
* @param[out] yerr The estimated error.
|
||||
*/
|
||||
void Stepper( const G4double y[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yout[],
|
||||
G4double yerr[] ) override ;
|
||||
|
||||
void SetupInterpolation();
|
||||
void SetupInterpolate( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double Step );
|
||||
// For Preparing the interpolation and calculating the extra stages
|
||||
|
||||
/**
|
||||
* Interface method for interpolation setup. Does nothing here.
|
||||
*/
|
||||
inline void SetupInterpolation() {}
|
||||
|
||||
/**
|
||||
* Calculates the output at the tau fraction of Step.
|
||||
* @param[in] yInput Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] Step The given step size.
|
||||
* @param[out] yOut Interpolation output.
|
||||
* @param[out] tau Fraction of step.
|
||||
*/
|
||||
void Interpolate( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double Step,
|
||||
G4double yOut[],
|
||||
G4double tau );
|
||||
// For calculating the output at the tau fraction of Step
|
||||
|
||||
void Interpolate( G4double tau,
|
||||
G4double yOut[]);
|
||||
|
||||
void interpolate(const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double yOut[],
|
||||
G4double Step,
|
||||
G4double tau ) ;
|
||||
|
||||
/**
|
||||
* Returns the distance from chord line.
|
||||
*/
|
||||
G4double DistChord() const override;
|
||||
G4int IntegratorOrder() const override { return 3; }
|
||||
|
||||
/**
|
||||
* Returns the order, 3, of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override { return 3; }
|
||||
|
||||
|
||||
/**
|
||||
* Returns the stepper type-ID, "kDoLoMcPriRK34".
|
||||
*/
|
||||
inline G4StepperType StepperType() const override { return kDoLoMcPriRK34; }
|
||||
|
||||
private :
|
||||
|
||||
G4double *ak2, *ak3, *ak4, *ak5, *ak6, *yTemp, *yIn;
|
||||
|
||||
G4double fLastStepLength = -1.0;
|
||||
|
||||
/** For DistChord calculations. */
|
||||
G4double *fLastInitialVector, *fLastFinalVector,
|
||||
*fLastDyDx, *fMidVector, *fMidError;
|
||||
// for DistChord calculations
|
||||
|
||||
G4DoLoMcPriRK34* fAuxStepper = nullptr;
|
||||
};
|
||||
|
||||
@@ -27,15 +27,14 @@
|
||||
//
|
||||
// Class desription:
|
||||
//
|
||||
// An implementation of the 5th order embedded RK method from the paper:
|
||||
// J. R. Dormand and P. J. Prince, "A family of embedded Runge-Kutta formulae"
|
||||
// Journal of computational and applied Math., vol.6, no.1, pp.19-26, 1980.
|
||||
//
|
||||
// DormandPrince7 - 5(4) embedded RK method
|
||||
// An implementation of the 5th order embedded RK method from the paper:
|
||||
// J. R. Dormand and P. J. Prince, "A family of embedded Runge-Kutta formulae"
|
||||
// Journal of computational and applied Math., vol.6, no.1, pp.19-26, 1980.
|
||||
//
|
||||
// DormandPrince7 - 5(4) embedded RK method
|
||||
|
||||
// Created: Somnath Banerjee, Google Summer of Code 2015, 25 May 2015
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// Author: Somnath Banerjee (CERN, Google Summer of Code 2015), 25.05.2015
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4DORMAND_PRINCE_745_HH
|
||||
#define G4DORMAND_PRINCE_745_HH
|
||||
@@ -43,19 +42,61 @@
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
#include "G4FieldUtils.hh"
|
||||
|
||||
/**
|
||||
* @brief G4DormandPrince745 implements the 5th order embedded Runge-Kutta
|
||||
* method, non-FSAL definition of the stepper() method that evaluates one step
|
||||
* in field propagation.
|
||||
*/
|
||||
|
||||
class G4DormandPrince745 : public G4MagIntegratorStepper
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4DormandPrince745.
|
||||
* @param[in] equation Pointer to the provided equation of motion.
|
||||
* @param[in] numberOfVariables The number of integration variables.
|
||||
*/
|
||||
G4DormandPrince745(G4EquationOfMotion* equation,
|
||||
G4int numberOfVariables = 6);
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4DormandPrince745() override = default;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4DormandPrince745(const G4DormandPrince745&) = delete;
|
||||
G4DormandPrince745& operator=(const G4DormandPrince745&) = delete;
|
||||
|
||||
/**
|
||||
* The stepper for the Runge Kutta integration.
|
||||
* The stepsize is fixed, with the step size given by 'hstep'.
|
||||
* Integrates ODE starting values yInput[0 to 6].
|
||||
* Outputs yOutput[] and its estimated error yError[].
|
||||
* @param[in] yInput Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] hstep The given step size.
|
||||
* @param[out] yOutput Integration output.
|
||||
* @param[out] yError The estimated error.
|
||||
*/
|
||||
void Stepper(const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[]) override;
|
||||
|
||||
/**
|
||||
* Same as the Stepper() function above, with dydx also in ouput.
|
||||
* @param[in] yInput Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] hstep The given step size.
|
||||
* @param[out] yOutput Integration output.
|
||||
* @param[out] yError The estimated error.
|
||||
* @param[out] dydxOutput dysx in output.
|
||||
*/
|
||||
void Stepper(const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
@@ -63,29 +104,67 @@ class G4DormandPrince745 : public G4MagIntegratorStepper
|
||||
G4double yError[],
|
||||
G4double dydxOutput[]);
|
||||
|
||||
|
||||
/**
|
||||
* Interface method for interpolation setup. Does nothing here.
|
||||
*/
|
||||
inline void SetupInterpolation() {}
|
||||
|
||||
/**
|
||||
* Calculates the output at the tau fraction of Step.
|
||||
* Lower (4th) order interpolant given by Dormand and Prince.
|
||||
*/
|
||||
void Interpolate4thOrder(G4double yOut[], G4double tau) const;
|
||||
|
||||
/**
|
||||
* Wrapper for Interpolate4thOrder() function above.
|
||||
*/
|
||||
inline void Interpolate(G4double tau, G4double yOut[]) const
|
||||
{
|
||||
Interpolate4thOrder(yOut, tau);
|
||||
}
|
||||
// For calculating the output at the tau fraction of Step
|
||||
|
||||
G4double DistChord() const override;
|
||||
|
||||
G4int IntegratorOrder() const override { return 4; }
|
||||
|
||||
const G4String& StepperType() const;
|
||||
const G4String& StepperDescription() const;
|
||||
|
||||
const field_utils::State& GetYOut() const { return fyOut; }
|
||||
|
||||
void Interpolate4thOrder(G4double yOut[], G4double tau) const;
|
||||
|
||||
/**
|
||||
* Sets up the extra stages for the 5th order interpolant.
|
||||
*/
|
||||
void SetupInterpolation5thOrder();
|
||||
|
||||
/**
|
||||
* Calculates the interpolated result 'yOut' with the coefficients.
|
||||
* Interpolant of 5th order given by Baker, Dormand, Gilmore and Prince.
|
||||
*/
|
||||
void Interpolate5thOrder(G4double yOut[], G4double tau) const;
|
||||
|
||||
G4EquationOfMotion* GetSpecificEquation() { return GetEquationOfMotion(); }
|
||||
/**
|
||||
* Returns the distance from chord line.
|
||||
*/
|
||||
G4double DistChord() const override;
|
||||
|
||||
/**
|
||||
* Returns the order, 4, of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override { return 4; }
|
||||
|
||||
/**
|
||||
* Returns the stepper type-ID, "kDormandPrince745".
|
||||
*/
|
||||
inline G4StepperType StepperType() const override { return kDormandPrince745; }
|
||||
|
||||
/**
|
||||
* Methods to return the stepper name and description.
|
||||
*/
|
||||
const G4String& StepperTypeName() const;
|
||||
const G4String& StepperDescription() const;
|
||||
|
||||
/**
|
||||
* Returns the field state in output.
|
||||
*/
|
||||
inline const field_utils::State& GetYOut() const { return fyOut; }
|
||||
|
||||
/**
|
||||
* Returns a pointer to the equation of motion.
|
||||
*/
|
||||
inline G4EquationOfMotion* GetSpecificEquation() { return GetEquationOfMotion(); }
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -29,60 +29,110 @@
|
||||
//
|
||||
// Dormand-Prince RK 6(5) non-FSAL method
|
||||
|
||||
// Created: Somnath Banerjee, Google Summer of Code 2015, 26 June 2015
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// Author: Somnath Banerjee (CERN, Google Summer of Code 2015), 26.06.2015
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4DORMAND_PRINCE_RK56_HH
|
||||
#define G4DORMAND_PRINCE_RK56_HH
|
||||
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
|
||||
/**
|
||||
* @brief G4DormandPrinceRK56 implements the 6(5) embedded Runge-Kutta
|
||||
* non-FSAL method.
|
||||
*/
|
||||
|
||||
class G4DormandPrinceRK56 : public G4MagIntegratorStepper
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4DormandPrinceRK56.
|
||||
* @param[in] EqRhs Pointer to the provided equation of motion.
|
||||
* @param[in] numberOfVariables The number of integration variables.
|
||||
* @param[in] primary Flag for initialisation of the auxiliary stepper.
|
||||
*/
|
||||
G4DormandPrinceRK56( G4EquationOfMotion* EqRhs,
|
||||
G4int numberOfVariables = 6,
|
||||
G4bool primary = true ) ;
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~G4DormandPrinceRK56() override ;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4DormandPrinceRK56(const G4DormandPrinceRK56&) = delete;
|
||||
G4DormandPrinceRK56& operator=(const G4DormandPrinceRK56&) = delete;
|
||||
|
||||
/**
|
||||
* The stepper for the Runge Kutta integration.
|
||||
* The stepsize is fixed, with the step size given by 'h'.
|
||||
* Integrates ODE starting values y[0 to 6].
|
||||
* Outputs yout[] and its estimated error yerr[].
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
* @param[out] yerr The estimated error.
|
||||
*/
|
||||
void Stepper( const G4double y[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yout[],
|
||||
G4double yerr[] ) override ;
|
||||
|
||||
G4double DistChord() const override;
|
||||
G4int IntegratorOrder() const override { return 5; }
|
||||
/**
|
||||
* Returns the distance from chord line.
|
||||
*/
|
||||
G4double DistChord() const override;
|
||||
|
||||
/**
|
||||
* Returns the order, 5, of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override { return 5; }
|
||||
|
||||
/**
|
||||
* Returns the stepper type-ID, "kDormandPrinceRK56".
|
||||
*/
|
||||
inline G4StepperType StepperType() const override { return kDormandPrinceRK56; }
|
||||
|
||||
/**
|
||||
* Prepares the interpolant and calculates the extra stages.
|
||||
* Fifth order interpolant with one extra function evaluation per step.
|
||||
*/
|
||||
void SetupInterpolate_low( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double Step );
|
||||
// For preparing the Interpolant and calculating the extra stages
|
||||
|
||||
void Interpolate_low( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double Step,
|
||||
G4double yOut[],
|
||||
G4double tau );
|
||||
// For calculating the output at the tau fraction of Step
|
||||
|
||||
inline void SetupInterpolation()
|
||||
{
|
||||
SetupInterpolate( fLastInitialVector, fLastDyDx, fLastStepLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrappers for SetupInterpolate_low() above.
|
||||
*/
|
||||
inline void SetupInterpolate( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double Step )
|
||||
{
|
||||
SetupInterpolate_low( yInput, dydx, Step);
|
||||
}
|
||||
|
||||
inline void SetupInterpolation()
|
||||
{
|
||||
SetupInterpolate( fLastInitialVector, fLastDyDx, fLastStepLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the output at the tau fraction of Step.
|
||||
*/
|
||||
void Interpolate_low( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double Step,
|
||||
G4double yOut[],
|
||||
G4double tau );
|
||||
|
||||
/**
|
||||
* Wrappers for Interpolate_low() above.
|
||||
*/
|
||||
inline void Interpolate( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double Step,
|
||||
@@ -91,38 +141,46 @@ class G4DormandPrinceRK56 : public G4MagIntegratorStepper
|
||||
{
|
||||
Interpolate_low( yInput, dydx, Step, yOut, tau);
|
||||
}
|
||||
// For calculating the output at the tau fraction of Step
|
||||
|
||||
inline void Interpolate( G4double tau, G4double yOut[])
|
||||
{
|
||||
Interpolate( fLastInitialVector, fLastDyDx, fLastStepLength, yOut, tau );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the interpolant and calculates the extra stages.
|
||||
* Sixth order interpolant with 3 additional stages per step.
|
||||
*/
|
||||
void SetupInterpolate_high( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double Step );
|
||||
|
||||
/**
|
||||
* Calculates the output at the tau fraction of Step, using
|
||||
* the polynomial coefficients and the respective stages.
|
||||
*/
|
||||
void Interpolate_high( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double Step,
|
||||
G4double yOut[],
|
||||
G4double tau );
|
||||
// For calculating the output at the tau fraction of Step
|
||||
|
||||
private:
|
||||
|
||||
/** For storing intermediate 'k' values in stepper. */
|
||||
G4double *ak2, *ak3, *ak4, *ak5, *ak6, *ak7, *ak8, *ak9;
|
||||
// For storing intermediate 'k' values in stepper
|
||||
|
||||
/** For the additional stages of Interpolant. */
|
||||
G4double *ak10_low, *ak10, *ak11, * ak12;
|
||||
// For the additional stages of Interpolant
|
||||
|
||||
G4double *yTemp, *yIn;
|
||||
|
||||
G4double fLastStepLength = -1.0;
|
||||
|
||||
/** For DistChord() calculations. */
|
||||
G4double *fLastInitialVector, *fLastFinalVector,
|
||||
*fLastDyDx, *fMidVector, *fMidError;
|
||||
// For DistChord calculations
|
||||
|
||||
G4DormandPrinceRK56* fAuxStepper = nullptr;
|
||||
};
|
||||
|
||||
#endif /* G4DormandPrinceRK56 */
|
||||
#endif
|
||||
|
||||
@@ -35,45 +35,88 @@
|
||||
// Journal of Computational and Applied Mathematics, Volume 7, Issue 1, 1981,
|
||||
// Pages 67-75, ISSN 0377-0427, DOI: 10.1016/0771-050X(81)90010-3
|
||||
|
||||
// Created: Somnath Banerjee, Google Summer of Code 2015, 28 June 2015
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// Author: Somnath Banerjee (CERN, Google Summer of Code 2015), 28.06.2015
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4DORMAND_PRINCE_RK78_HH
|
||||
#define G4DORMAND_PRINCE_RK78_HH
|
||||
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
|
||||
/**
|
||||
* @brief G4DormandPrinceRK78 implements the Dormand-Prince 8(7)13M non-FSAL
|
||||
* Runge-Kutta method, a 13 stage embedded explicit Runge-Kutta method, using
|
||||
* a pair of 7th and 8th order formulae.
|
||||
*/
|
||||
|
||||
class G4DormandPrinceRK78 : public G4MagIntegratorStepper
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4DormandPrince745.
|
||||
* @param[in] EqRhs Pointer to the provided equation of motion.
|
||||
* @param[in] numberOfVariables The number of integration variables.
|
||||
* @param[in] primary Flag for initialisation of the auxiliary stepper.
|
||||
*/
|
||||
G4DormandPrinceRK78(G4EquationOfMotion* EqRhs,
|
||||
G4int numberOfVariables = 6,
|
||||
G4bool primary = true);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~G4DormandPrinceRK78() override;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4DormandPrinceRK78(const G4DormandPrinceRK78&) = delete;
|
||||
G4DormandPrinceRK78& operator=(const G4DormandPrinceRK78&) = delete;
|
||||
|
||||
/**
|
||||
* The stepper for the Runge Kutta integration.
|
||||
* The stepsize is fixed, with the step size given by 'h'.
|
||||
* Integrates ODE starting values y[0 to 6].
|
||||
* Outputs yout[] and its estimated error yerr[].
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
* @param[out] yerr The estimated error.
|
||||
*/
|
||||
void Stepper( const G4double y[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yout[],
|
||||
G4double yerr[]) override ;
|
||||
|
||||
/**
|
||||
* Returns the distance from chord line.
|
||||
*/
|
||||
G4double DistChord() const override;
|
||||
|
||||
/**
|
||||
* Returns the order, 7, of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override { return 7; }
|
||||
|
||||
/**
|
||||
* Returns the stepper type-ID, "kDormandPrinceRK78".
|
||||
*/
|
||||
inline G4StepperType StepperType() const override { return kDormandPrinceRK78; }
|
||||
|
||||
private :
|
||||
private :
|
||||
|
||||
G4double *ak2, *ak3, *ak4, *ak5, *ak6, *ak7, *ak8,
|
||||
*ak9, *ak10, *ak11, *ak12, *ak13,
|
||||
*yTemp, *yIn;
|
||||
|
||||
G4double fLastStepLength = -1.0;
|
||||
|
||||
/** For DistChord() calculations. */
|
||||
G4double *fLastInitialVector, *fLastFinalVector,
|
||||
*fLastDyDx, *fMidVector, *fMidError;
|
||||
// For DistChord calculations
|
||||
|
||||
G4DormandPrinceRK78* fAuxStepper = nullptr;
|
||||
};
|
||||
|
||||
@@ -27,32 +27,37 @@
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// Auxiliary class to print information from integration drivers
|
||||
// Can be used by different types of drivers.
|
||||
// Auxiliary class to print information from integration drivers.
|
||||
// Can be used by different types of drivers.
|
||||
|
||||
// Authors: J.Apostolakis - January/March 2020
|
||||
// Author: John Apostolakis (CERN), January/March 2020
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#ifndef G4DRIVERREPORTER_HH
|
||||
#define G4DRIVERREPORTER_HH
|
||||
|
||||
#include "G4FieldTrack.hh"
|
||||
|
||||
/**
|
||||
* @brief G4DriverReporter is an auxiliary utility class to print information
|
||||
* from integration drivers. It can be used by different types of drivers.
|
||||
*/
|
||||
|
||||
class G4DriverReporter
|
||||
{
|
||||
public:
|
||||
|
||||
static void PrintStatus(const G4double* StartArr,
|
||||
G4double xstart,
|
||||
G4double xstart,
|
||||
const G4double* CurrentArr,
|
||||
G4double xcurrent,
|
||||
G4double requestStep,
|
||||
unsigned int subStepNo,
|
||||
unsigned int noIntegrationVariables);
|
||||
G4double xcurrent,
|
||||
G4double requestStep,
|
||||
unsigned int subStepNo,
|
||||
unsigned int noIntegrationVariables);
|
||||
|
||||
static void PrintStatus(const G4FieldTrack& StartFT,
|
||||
const G4FieldTrack& CurrentFT,
|
||||
G4double requestStep,
|
||||
unsigned int subStepNo);
|
||||
G4double requestStep,
|
||||
unsigned int subStepNo);
|
||||
|
||||
static void PrintStat_Aux(const G4FieldTrack& aFieldTrack,
|
||||
G4double requestStep,
|
||||
@@ -60,9 +65,5 @@ class G4DriverReporter
|
||||
G4int subStepNo,
|
||||
G4double subStepSize,
|
||||
G4double dotVelocities);
|
||||
|
||||
private:
|
||||
// G4int fVerboseLevel; // Verbose output for debugging
|
||||
// unsigned int fNoIntegrationVariables);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
//
|
||||
// Electric field abstract class, implements inquiry function interface.
|
||||
|
||||
// Created: J.Apostolakis - 04.11.2003
|
||||
// Author: John Apostolakis (CERN), 04.11.2003
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4ELECTRIC_FIELD_HH
|
||||
#define G4ELECTRIC_FIELD_HH
|
||||
@@ -37,23 +37,37 @@
|
||||
#include "G4Types.hh"
|
||||
#include "G4ElectroMagneticField.hh"
|
||||
|
||||
/**
|
||||
* @brief G4ElectricField is an abstract class for electric field.
|
||||
* It implements inquiry function interface.
|
||||
*/
|
||||
|
||||
class G4ElectricField : public G4ElectroMagneticField
|
||||
{
|
||||
public:
|
||||
|
||||
G4ElectricField();
|
||||
~G4ElectricField() override;
|
||||
// Constructor and destructor. No actions.
|
||||
/**
|
||||
* Default Constructor and Destructor.
|
||||
*/
|
||||
G4ElectricField() = default;
|
||||
~G4ElectricField() override = default;
|
||||
|
||||
G4ElectricField(const G4ElectricField& r);
|
||||
/**
|
||||
* Copy constructor and assignment operator.
|
||||
*/
|
||||
G4ElectricField(const G4ElectricField& r) = default;
|
||||
G4ElectricField& operator = (const G4ElectricField& p);
|
||||
// Copy constructor & assignment operator.
|
||||
|
||||
G4bool DoesFieldChangeEnergy() const override { return true; }
|
||||
// Since an electric field can change track energy
|
||||
/**
|
||||
* Returns true, since an electric field can change track energy.
|
||||
*/
|
||||
inline G4bool DoesFieldChangeEnergy() const override { return true; }
|
||||
|
||||
void GetFieldValue( const G4double Point[4],
|
||||
G4double* Bfield ) const override = 0;
|
||||
/**
|
||||
* Interface for returning the field value 'Bfield' on given time 'Point'.
|
||||
*/
|
||||
void GetFieldValue( const G4double Point[4],
|
||||
G4double* Bfield ) const override = 0;
|
||||
};
|
||||
|
||||
#endif /* G4ELECTRIC_FIELD_DEF */
|
||||
#endif
|
||||
|
||||
@@ -41,8 +41,8 @@
|
||||
// Note 2: such a convention is required between any field and its
|
||||
// corresponding equation of motion.
|
||||
|
||||
// Created: J.Apostolakis, 12.11.1998
|
||||
// Modified: V.Grichine, 08.11.2001: Extended "Point" to add time
|
||||
// Author: John Apostolakis (CERN), 12.11.1998 - Created
|
||||
// Vladimir Grichine(CERN), 08.11.2001 - Extended "Point" to add time
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4ELECTROMAGNETIC_FIELD_HH
|
||||
#define G4ELECTROMAGNETIC_FIELD_HH
|
||||
@@ -53,22 +53,37 @@ class G4ElectroMagneticField : public G4Field
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor and default Destructor.
|
||||
*/
|
||||
G4ElectroMagneticField();
|
||||
~G4ElectroMagneticField() override;
|
||||
~G4ElectroMagneticField() override = default;
|
||||
|
||||
G4ElectroMagneticField(const G4ElectroMagneticField& r);
|
||||
/**
|
||||
* Copy constructor and assignment operator.
|
||||
*/
|
||||
G4ElectroMagneticField(const G4ElectroMagneticField& r) = default;
|
||||
G4ElectroMagneticField& operator = (const G4ElectroMagneticField& p);
|
||||
// Copy constructor & assignment operators.
|
||||
|
||||
void GetFieldValue(const G4double Point[4],
|
||||
G4double *Bfield ) const override = 0;
|
||||
// Return as Bfield[0], [1], [2] the magnetic field x, y & z components
|
||||
// and as Bfield[3], [4], [5] the electric field x, y & z components
|
||||
/**
|
||||
* Interface for returning the field value 'Bfield' on given time 'Point'.
|
||||
* Returns as Bfield[0], [1], [2] the magnetic field x, y & z components
|
||||
* and as Bfield[3], [4], [5] the electric field x, y & z components.
|
||||
*/
|
||||
void GetFieldValue(const G4double Point[4],
|
||||
G4double* Bfield ) const override = 0;
|
||||
|
||||
/**
|
||||
* For field with an electric component it should return true.
|
||||
* For pure magnetic field it should return false.
|
||||
* Alternative: default safe implementation is to return true.
|
||||
*/
|
||||
G4bool DoesFieldChangeEnergy() const override = 0;
|
||||
// For field with an electric component this should be true
|
||||
// For pure magnetic field this should be false
|
||||
// Alternative: default safe implementation { return true; }
|
||||
|
||||
/**
|
||||
* Returns the field type-ID, "kElectroMagnetic".
|
||||
*/
|
||||
inline G4FieldType GetFieldType() const override { return kElectroMagnetic; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
// electric and magnetic field, with spin tracking for both MDM and
|
||||
// EDM terms.
|
||||
|
||||
// Created: Kevin Lynch, 19.02.2009 - Based on G4EqEMFieldWithSpin
|
||||
// Author: Kevin Lynch (Boston Univ.), 19.02.2009 - Based on G4EqEMFieldWithSpin
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4EQEMFIELDWITHEDM_HH
|
||||
#define G4EQEMFIELDWITHEDM_HH
|
||||
@@ -41,31 +41,65 @@
|
||||
|
||||
class G4ElectroMagneticField;
|
||||
|
||||
/**
|
||||
* @brief G4EqEMFieldWithEDM implements the right-hand side of equation of
|
||||
* motion in a combined electric and magnetic field, with spin tracking for
|
||||
* both MDM and EDM terms.
|
||||
*/
|
||||
|
||||
class G4EqEMFieldWithEDM : public G4EquationOfMotion
|
||||
{
|
||||
public:
|
||||
|
||||
G4EqEMFieldWithEDM(G4ElectroMagneticField* emField );
|
||||
/**
|
||||
* Constructor for G4EqEMFieldWithEDM.
|
||||
* @param[in] emField Pointer to the electromagnetic field.
|
||||
*/
|
||||
G4EqEMFieldWithEDM(G4ElectroMagneticField* emField);
|
||||
|
||||
~G4EqEMFieldWithEDM() override;
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4EqEMFieldWithEDM() override = default;
|
||||
|
||||
void SetChargeMomentumMass(G4ChargeState particleCharge, // in e+ units
|
||||
G4double MomentumXc,
|
||||
G4double mass) override;
|
||||
/**
|
||||
* Sets the charge, momentum and mass of the current particle.
|
||||
* Used to set the equation's coefficients.
|
||||
* @param[in] particleCharge Magnetic charge and moments in e+ units.
|
||||
* @param[in] MomentumXc Particle momentum.
|
||||
* @param[in] mass Particle mass.
|
||||
*/
|
||||
void SetChargeMomentumMass(G4ChargeState particleCharge, // in e+ units
|
||||
G4double MomentumXc,
|
||||
G4double mass) override;
|
||||
|
||||
/**
|
||||
* Calculates the value of the derivative, given the value of the
|
||||
* electromagnetic field.
|
||||
* @param[in] y Coefficients array.
|
||||
* @param[in] Field Field value.
|
||||
* @param[out] dydx Derivatives array.
|
||||
*/
|
||||
void EvaluateRhsGivenB(const G4double y[],
|
||||
const G4double Field[],
|
||||
G4double dydx[] ) const override;
|
||||
// Given the value of the electromagnetic field, this function
|
||||
// calculates the value of the derivative dydx.
|
||||
|
||||
/**
|
||||
* Setter and getter for magnetic anomaly.
|
||||
*/
|
||||
inline void SetAnomaly(G4double a) { anomaly = a; }
|
||||
inline G4double GetAnomaly() const { return anomaly; }
|
||||
// set/get magnetic anomaly
|
||||
|
||||
/**
|
||||
* Setter and getter for EDM eta parameter.
|
||||
*/
|
||||
inline void SetEta(G4double n) { eta = n; }
|
||||
inline G4double GetEta() const { return eta; }
|
||||
// set/get EDM eta parameter
|
||||
|
||||
/**
|
||||
* Returns the equation type-ID, "kEqEMfieldWithEDM".
|
||||
*/
|
||||
inline G4EquationType GetEquationType() const override { return kEqEMfieldWithEDM; }
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
// This is the right-hand side of equation of motion in a combined
|
||||
// electric and magnetic field.
|
||||
|
||||
// Created: Chris Gong & Peter Gumplinger, 30.08.2007
|
||||
// Authors: Chris Gong & Peter Gumplinger (TRIUMF), 30.08.2007
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4EQEMFIELDWITHSPIN_HH
|
||||
#define G4EQEMFIELDWITHSPIN_HH
|
||||
@@ -40,26 +40,58 @@
|
||||
|
||||
class G4ElectroMagneticField;
|
||||
|
||||
/**
|
||||
* @brief G4EqEMFieldWithSpin implements the right-hand side of equation
|
||||
* of motion in a combined electric and magnetic field.
|
||||
*/
|
||||
|
||||
class G4EqEMFieldWithSpin : public G4EquationOfMotion
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4EqEMFieldWithSpin.
|
||||
* @param[in] emField Pointer to the electromagnetic field.
|
||||
*/
|
||||
G4EqEMFieldWithSpin(G4ElectroMagneticField* emField );
|
||||
~G4EqEMFieldWithSpin() override;
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4EqEMFieldWithSpin() override = default;
|
||||
|
||||
/**
|
||||
* Sets the charge, momentum and mass of the current particle.
|
||||
* Used to set the equation's coefficients.
|
||||
* @param[in] particleCharge Magnetic charge and moments in e+ units.
|
||||
* @param[in] MomentumXc Particle momentum.
|
||||
* @param[in] mass Particle mass.
|
||||
*/
|
||||
void SetChargeMomentumMass(G4ChargeState particleCharge, // in e+ units
|
||||
G4double MomentumXc,
|
||||
G4double mass) override;
|
||||
|
||||
/**
|
||||
* Calculates the value of the derivative, given the value of the
|
||||
* electromagnetic field.
|
||||
* @param[in] y Coefficients array.
|
||||
* @param[in] Field Field value.
|
||||
* @param[out] dydx Derivatives array.
|
||||
*/
|
||||
void EvaluateRhsGivenB(const G4double y[],
|
||||
const G4double Field[],
|
||||
G4double dydx[] ) const override;
|
||||
// Given the value of the electromagnetic field, this function
|
||||
// calculates the value of the derivative dydx.
|
||||
|
||||
/**
|
||||
* Setter and getter for magnetic anomaly.
|
||||
*/
|
||||
inline void SetAnomaly(G4double a) { anomaly = a; }
|
||||
inline G4double GetAnomaly() const { return anomaly; }
|
||||
// set/get magnetic anomaly
|
||||
|
||||
/**
|
||||
* Returns the equation type-ID, "kEqEMfieldWithSpin".
|
||||
*/
|
||||
inline G4EquationType GetEquationType() const override { return kEqEMfieldWithSpin; }
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
//
|
||||
// This is the right-hand side of equation of motion in a gravity field.
|
||||
|
||||
// Created: P.Gumplinger, 14.06.11 - Adopted from G4EqMagElectricField
|
||||
// Thanks to P.Fierlinger (PSI) and A.Capra and A.Fontana (INFN Pavia)
|
||||
// Author: Peter Gumplinger (TRIUMF), 14.06.11 - Adopted from G4EqMagElectricField
|
||||
// Thanks to P.Fierlinger (PSI) and A.Capra and A.Fontana (INFN Pavia)
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4EQGRAVITYFIELD_HH
|
||||
#define G4EQGRAVITYFIELD_HH
|
||||
@@ -39,22 +39,52 @@
|
||||
#include "G4EquationOfMotion.hh"
|
||||
#include "G4UniformGravityField.hh"
|
||||
|
||||
/**
|
||||
* @brief G4EqGravityField implements the right-hand side of equation
|
||||
* of motion in a gravity field.
|
||||
*/
|
||||
|
||||
class G4EqGravityField : public G4EquationOfMotion
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4EqGravityField.
|
||||
* @param[in] gField Pointer to the uniform gravity field.
|
||||
*/
|
||||
G4EqGravityField(G4UniformGravityField* gField);
|
||||
~G4EqGravityField() override;
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4EqGravityField() override = default;
|
||||
|
||||
/**
|
||||
* Sets the charge, momentum and mass of the current particle.
|
||||
* Used to set the equation's coefficients.
|
||||
* @param[in] particleCharge Magnetic charge and moments in e+ units.
|
||||
* @param[in] MomentumXc Particle momentum.
|
||||
* @param[in] mass Particle mass.
|
||||
*/
|
||||
void SetChargeMomentumMass(G4ChargeState particleCharge, // in e+ units
|
||||
G4double MomentumXc,
|
||||
G4double mass) override;
|
||||
|
||||
/**
|
||||
* Calculates the value of the derivative, given the value of the
|
||||
* electromagnetic field.
|
||||
* @param[in] y Coefficients array.
|
||||
* @param[in] Field Field value.
|
||||
* @param[out] dydx Derivatives array.
|
||||
*/
|
||||
void EvaluateRhsGivenB( const G4double y[],
|
||||
const G4double Field[],
|
||||
G4double dydx[] ) const override;
|
||||
// Given the value of the gravitational field, this function
|
||||
// calculates the value of the derivative dydx.
|
||||
|
||||
/**
|
||||
* Returns the equation type-ID, "kEqGravity".
|
||||
*/
|
||||
inline G4EquationType GetEquationType() const override { return kEqGravity; }
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
// This is the right-hand side of equation of motion in a combined
|
||||
// electric and magnetic field.
|
||||
|
||||
// Created: V.Grichine, 10.11.1998
|
||||
// Author: Vladimir Grichine (CERN), 10.11.1998
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4EQMAGELECTRICFIELD_HH
|
||||
#define G4EQMAGELECTRICFIELD_HH
|
||||
@@ -39,22 +39,52 @@
|
||||
#include "G4EquationOfMotion.hh"
|
||||
#include "G4ElectroMagneticField.hh"
|
||||
|
||||
/**
|
||||
* @brief G4EqMagElectricField implements the right-hand side of equation of
|
||||
* motion in a combined electric and magnetic field.
|
||||
*/
|
||||
|
||||
class G4EqMagElectricField : public G4EquationOfMotion
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4EqMagElectricField.
|
||||
* @param[in] emField Pointer to the electromagnetic field.
|
||||
*/
|
||||
G4EqMagElectricField(G4ElectroMagneticField* emField );
|
||||
~G4EqMagElectricField() override;
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4EqMagElectricField() override = default;
|
||||
|
||||
/**
|
||||
* Sets the charge, momentum and mass of the current particle.
|
||||
* Used to set the equation's coefficients.
|
||||
* @param[in] particleCharge Magnetic charge and moments in e+ units.
|
||||
* @param[in] MomentumXc Particle momentum.
|
||||
* @param[in] mass Particle mass.
|
||||
*/
|
||||
void SetChargeMomentumMass(G4ChargeState particleCharge, // in e+ units
|
||||
G4double MomentumXc,
|
||||
G4double mass) override;
|
||||
|
||||
/**
|
||||
* Calculates the value of the derivative, given the value of the
|
||||
* electromagnetic field.
|
||||
* @param[in] y Coefficients array.
|
||||
* @param[in] Field Field value.
|
||||
* @param[out] dydx Derivatives array.
|
||||
*/
|
||||
void EvaluateRhsGivenB(const G4double y[],
|
||||
const G4double Field[],
|
||||
G4double dydx[] ) const override;
|
||||
// Given the value of the electromagnetic field, this function
|
||||
// calculates the value of the derivative dydx.
|
||||
|
||||
/**
|
||||
* Returns the equation type-ID, "kEqElectroMagnetic".
|
||||
*/
|
||||
inline G4EquationType GetEquationType() const override { return kEqElectroMagnetic; }
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -30,64 +30,101 @@
|
||||
// Abstract Base Class for the right hand size of the equation of
|
||||
// motion of a particle in a field.
|
||||
|
||||
// Created: J.Apostolakis, 1998
|
||||
// Author: John Apostolakis (CERN), 1998
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4EQUATIONOFMOTION_HH
|
||||
#define G4EQUATIONOFMOTION_HH
|
||||
|
||||
#include "G4Types.hh"
|
||||
#include "G4Field.hh" // required in inline method implementations
|
||||
#include "G4FieldParameters.hh"
|
||||
|
||||
#include "G4ChargeState.hh"
|
||||
|
||||
/**
|
||||
* @brief G4EquationOfMotion is the abstract base class for the right
|
||||
* hand size of the equation of motion of a particle in a field.
|
||||
*/
|
||||
|
||||
class G4EquationOfMotion
|
||||
{
|
||||
public: // with description
|
||||
public:
|
||||
|
||||
G4EquationOfMotion( G4Field* Field );
|
||||
virtual ~G4EquationOfMotion();
|
||||
// Constructor and virtual destructor. No operations.
|
||||
/**
|
||||
* Constructor for G4EquationOfMotion.
|
||||
* @param[in] Field Pointer to the field.
|
||||
*/
|
||||
G4EquationOfMotion( G4Field* Field );
|
||||
|
||||
virtual void EvaluateRhsGivenB( const G4double y[],
|
||||
const G4double B[3],
|
||||
G4double dydx[] ) const = 0;
|
||||
// Given the value of the field "B", this function
|
||||
// calculates the value of the derivative dydx.
|
||||
// --------------------------------------------------------
|
||||
// This is the _only_ function a subclass must define.
|
||||
// The other two functions use Rhs_givenB.
|
||||
/**
|
||||
* Default virtual Destructor.
|
||||
*/
|
||||
virtual ~G4EquationOfMotion() = default;
|
||||
|
||||
virtual void SetChargeMomentumMass(G4ChargeState particleCharge,
|
||||
G4double MomentumXc,
|
||||
G4double MassXc2) = 0;
|
||||
// Set the charge, momentum and mass of the current particle
|
||||
// --> used to set the equation's coefficients ...
|
||||
/**
|
||||
* Calculates the value of the derivative, given the value of the field.
|
||||
* @param[in] y Coefficients array.
|
||||
* @param[in] Field Field value.
|
||||
* @param[out] dydx Derivatives array.
|
||||
*/
|
||||
virtual void EvaluateRhsGivenB( const G4double y[],
|
||||
const G4double B[3],
|
||||
G4double dydx[] ) const = 0;
|
||||
|
||||
inline void RightHandSide( const G4double y[],
|
||||
G4double dydx[] ) const;
|
||||
// This calculates the value of the derivative dydx at y.
|
||||
// It is the usual enquiry function.
|
||||
// ---------------------------
|
||||
// (It is not virtual, but calls the virtual function above.)
|
||||
/**
|
||||
* Sets the charge, momentum and mass of the current particle.
|
||||
* Used to set the equation's coefficients.
|
||||
* @param[in] particleCharge Magnetic charge and moments in e+ units.
|
||||
* @param[in] MomentumXc Particle momentum.
|
||||
* @param[in] mass Particle mass.
|
||||
*/
|
||||
virtual void SetChargeMomentumMass(G4ChargeState particleCharge,
|
||||
G4double MomentumXc,
|
||||
G4double MassXc2) = 0;
|
||||
|
||||
inline void EvaluateRhsReturnB( const G4double y[],
|
||||
G4double dydx[],
|
||||
G4double Field[] ) const;
|
||||
// Same as RHS above, but also returns the value of B.
|
||||
// Should be made the new default ? after putting dydx & B in a class.
|
||||
/**
|
||||
* Returns the equation type-ID, "kUserEquation".
|
||||
*/
|
||||
virtual G4EquationType GetEquationType() const { return kUserEquation; }
|
||||
|
||||
inline void GetFieldValue( const G4double Point[4],
|
||||
G4double Field[] ) const;
|
||||
// Obtain only the field - the stepper assumes it is pure Magnetic.
|
||||
// Not protected, because G4RKG3_Stepper uses it directly.
|
||||
/**
|
||||
* Calculates the value of the derivative 'dydx' at 'y'.
|
||||
* Calls the virtual function above.
|
||||
* @param[in] y Coefficients array.
|
||||
* @param[out] dydx Derivatives array.
|
||||
*/
|
||||
inline void RightHandSide( const G4double y[],
|
||||
G4double dydx[] ) const;
|
||||
|
||||
inline const G4Field* GetFieldObj() const;
|
||||
inline G4Field* GetFieldObj();
|
||||
inline void SetFieldObj(G4Field* pField);
|
||||
/**
|
||||
* Calculates the value of the derivative 'dydx' at 'y' as above,
|
||||
* but also returns the value of B.
|
||||
* @param[in] y Coefficients array.
|
||||
* @param[out] dydx Derivatives array.
|
||||
* @param[out] Field Field value.
|
||||
*/
|
||||
inline void EvaluateRhsReturnB( const G4double y[],
|
||||
G4double dydx[],
|
||||
G4double Field[] ) const;
|
||||
|
||||
/**
|
||||
* Returns the 'Field' value at the given time 'Point'.
|
||||
* @param[in] Point The time point (x,y,z,t).
|
||||
* @param[out] Field The returned field value.
|
||||
*/
|
||||
inline void GetFieldValue( const G4double Point[4],
|
||||
G4double Field[] ) const;
|
||||
|
||||
/**
|
||||
* Accessors and modifier for the field.
|
||||
*/
|
||||
inline const G4Field* GetFieldObj() const;
|
||||
inline G4Field* GetFieldObj();
|
||||
inline void SetFieldObj(G4Field* pField);
|
||||
|
||||
private:
|
||||
|
||||
G4Field* itsField = nullptr;
|
||||
G4Field* itsField = nullptr;
|
||||
};
|
||||
|
||||
#include "G4EquationOfMotion.icc"
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
//
|
||||
// G4EquationOfMotion inline methods implementation
|
||||
//
|
||||
// Created: J.Apostolakis, 1998
|
||||
// Author: John Apostolakis (CERN), 1998
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
inline
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
// Serves to reverse the magnetic field when propagation is backwards
|
||||
// for error propagation.
|
||||
|
||||
// Created: P.Arce, September 2004.
|
||||
// Author: Pedro Arce (CIEMAT), September 2004.
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4ERRORMAG_USUALEQRHS_HH
|
||||
#define G4ERRORMAG_USUALEQRHS_HH
|
||||
@@ -38,17 +38,36 @@
|
||||
#include "G4Mag_UsualEqRhs.hh"
|
||||
#include "G4MagneticField.hh"
|
||||
|
||||
/**
|
||||
* @brief G4ErrorMag_UsualEqRhs serves to reverse the magnetic field when
|
||||
* propagation is backwards. It is used for error propagation.
|
||||
*/
|
||||
|
||||
class G4ErrorMag_UsualEqRhs : public G4Mag_UsualEqRhs
|
||||
{
|
||||
public:
|
||||
public:
|
||||
|
||||
G4ErrorMag_UsualEqRhs( G4MagneticField* MagField );
|
||||
~G4ErrorMag_UsualEqRhs() override;
|
||||
/**
|
||||
* Constructor for G4ErrorMag_UsualEqRhs.
|
||||
* @param[in] MagField Pointer to the magnetic field.
|
||||
*/
|
||||
G4ErrorMag_UsualEqRhs( G4MagneticField* MagField );
|
||||
|
||||
void EvaluateRhsGivenB( const G4double y[],
|
||||
const G4double B[3],
|
||||
G4double dydx[] ) const override;
|
||||
// Reverses dedx if propagation is backwards
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4ErrorMag_UsualEqRhs() override = default;
|
||||
|
||||
/**
|
||||
* Calculates the value of the derivative, given the value of the
|
||||
* magnetic field. Reverses dedx if propagation is backwards.
|
||||
* @param[in] y Coefficients array.
|
||||
* @param[in] B Field value.
|
||||
* @param[out] dydx Derivatives array.
|
||||
*/
|
||||
void EvaluateRhsGivenB( const G4double y[],
|
||||
const G4double B[3],
|
||||
G4double dydx[] ) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
//
|
||||
// As the field is assumed constant, an error is not calculated.
|
||||
|
||||
// Author: J.Apostolakis, 28.01.2005.
|
||||
// Author: John Apostolakis (CERN), 28.01.2005.
|
||||
// Implementation adapted from ExplicitEuler by W.Wander
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4EXACTHELIXSTEPPER_HH
|
||||
@@ -48,40 +48,81 @@
|
||||
#include "G4MagHelicalStepper.hh"
|
||||
#include "G4Mag_EqRhs.hh"
|
||||
|
||||
/**
|
||||
* @brief G4ExactHelixStepper is a concrete class for particle motion in
|
||||
* constant magnetic field. Helix a-la-Explicity Euler: x_1 = x_0 + helix(h)
|
||||
* with helix(h) being a helix piece of length h.
|
||||
* As the field is assumed constant, an error is not calculated.
|
||||
*/
|
||||
|
||||
class G4ExactHelixStepper : public G4MagHelicalStepper
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4ExactHelixStepper.
|
||||
* @param[in] EqRhs Pointer to the standard equation of motion.
|
||||
*/
|
||||
G4ExactHelixStepper(G4Mag_EqRhs* EqRhs);
|
||||
~G4ExactHelixStepper() override;
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4ExactHelixStepper() override = default;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4ExactHelixStepper(const G4ExactHelixStepper&) = delete;
|
||||
G4ExactHelixStepper& operator=(const G4ExactHelixStepper&) = delete;
|
||||
|
||||
/**
|
||||
* The stepper for the Runge Kutta integration.
|
||||
* The stepsize is fixed, with the step size given by 'h'.
|
||||
* Provides helix starting values y[0 to 6].
|
||||
* Outputs yout[] and ZERO estimated error yerr[]=0.
|
||||
* @param[in] yInput Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
* @param[out] yerr The estimated error.
|
||||
*/
|
||||
void Stepper( const G4double y[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yout[],
|
||||
G4double yerr[] ) override;
|
||||
// Step 'integration' for step size 'h'
|
||||
// Provides helix starting at y[0 to 6]
|
||||
// Outputs yout[] and ZERO estimated error yerr[]=0.
|
||||
G4double yerr[] ) override;
|
||||
|
||||
/**
|
||||
* Same as Stepper() function above, but should perform a 'dump' step
|
||||
* without error calculation. Assuming a constant field, the solution is
|
||||
* a helix. Should NOT be called; issues a fatal exception as the Stepper
|
||||
* must do all the work.
|
||||
*/
|
||||
void DumbStepper( const G4double y[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yout[] ) override;
|
||||
// Performs a 'dump' Step without error calculation.
|
||||
|
||||
/**
|
||||
* Estimates the maximum distance of curved solution and chord.
|
||||
*/
|
||||
G4double DistChord() const override;
|
||||
// Estimate maximum distance of curved solution and chord ...
|
||||
|
||||
G4int IntegratorOrder() const override;
|
||||
/**
|
||||
* Returns the order, 1, of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override { return 1; }
|
||||
|
||||
/**
|
||||
* Returns the stepper type-ID, "kExactHelixStepper".
|
||||
*/
|
||||
inline G4StepperType StepperType() const override { return kExactHelixStepper; }
|
||||
|
||||
private:
|
||||
|
||||
/** Initial value of field at last step. */
|
||||
G4ThreeVector fBfieldValue;
|
||||
// Initial value of field at last step
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,26 +31,58 @@
|
||||
// The most simple approach for solving linear differential equations.
|
||||
// Take the current derivative and add it to the current position.
|
||||
|
||||
// Created: W.Wander <wwc@mit.edu>, 12.09.1997
|
||||
// Author: W.Wander (MIT), 12.09.1997
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4EXPLICITEULER_HH
|
||||
#define G4EXPLICITEULER_HH
|
||||
|
||||
#include "G4MagErrorStepper.hh"
|
||||
|
||||
/**
|
||||
* @brief G4ExplicitEuler implements an Explicit Euler stepper for magnetic
|
||||
* field: x_1 = x_0 + h * dx_0. The most simple approach for solving linear
|
||||
* differential equations. Takes the current derivative and adds it to the
|
||||
* current position.
|
||||
*/
|
||||
|
||||
class G4ExplicitEuler : public G4MagErrorStepper
|
||||
{
|
||||
public:
|
||||
|
||||
G4ExplicitEuler(G4EquationOfMotion* EqRhs, G4int numberOfVariables = 6) ;
|
||||
~G4ExplicitEuler() override;
|
||||
/**
|
||||
* Constructor for G4ExplicitEuler.
|
||||
* @param[in] EqRhs Pointer to the provided equation of motion.
|
||||
* @param[in] numberOfVariables The number of integration variables.
|
||||
*/
|
||||
G4ExplicitEuler(G4EquationOfMotion* EqRhs,
|
||||
G4int numberOfVariables = 6) ;
|
||||
|
||||
void DumbStepper( const G4double y[],
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4ExplicitEuler() override = default;
|
||||
|
||||
/**
|
||||
* The stepper function for the integration.
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
*/
|
||||
void DumbStepper( const G4double y[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yout[] ) override;
|
||||
|
||||
G4int IntegratorOrder() const override { return 1; }
|
||||
/**
|
||||
* Returns the order, 1, of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override { return 1; }
|
||||
|
||||
/**
|
||||
* Returns the stepper type-ID, "kExplicitEuler".
|
||||
*/
|
||||
inline G4StepperType StepperType() const override { return kExplicitEuler; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -29,26 +29,56 @@
|
||||
//
|
||||
// Bogacki-Shampine - 8 - 5(4) FSAL stepper
|
||||
|
||||
// Created: Somnath Banerjee, Google Summer of Code 2015, 26 May 2015
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// Author: Somnath Banerjee (CERN, Google Summer of Code 2015), 26.05.2015
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4FSAL_BOGACKI_SHAMPINE_45_HH
|
||||
#define G4FSAL_BOGACKI_SHAMPINE_45_HH
|
||||
|
||||
#include "G4VFSALIntegrationStepper.hh"
|
||||
|
||||
/**
|
||||
* @brief G4FSALBogackiShampine45 is an integrator of particle's equation of
|
||||
* motion based on the Bogacki-Shampine - 8 - 5(4) FSAL implementation.
|
||||
*/
|
||||
|
||||
class G4FSALBogackiShampine45 : public G4VFSALIntegrationStepper
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4FSALBogackiShampine45.
|
||||
* @param[in] EqRhs Pointer to the provided equation of motion.
|
||||
* @param[in] numberOfVariables The number of integration variables.
|
||||
* @param[in] primary Flag for initialisation of the auxiliary stepper.
|
||||
*/
|
||||
G4FSALBogackiShampine45(G4EquationOfMotion* EqRhs,
|
||||
G4int numberOfVariables = 6,
|
||||
G4bool primary = true);
|
||||
~G4FSALBogackiShampine45() override;
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~G4FSALBogackiShampine45() override;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4FSALBogackiShampine45(const G4FSALBogackiShampine45&) = delete;
|
||||
G4FSALBogackiShampine45& operator=(const G4FSALBogackiShampine45&) = delete;
|
||||
|
||||
/**
|
||||
* The stepper for the Runge Kutta integration.
|
||||
* The stepsize is fixed, with the step size given by 'h'.
|
||||
* Integrates ODE starting values y[0 to 6].
|
||||
* Outputs yout[] and its estimated error yerr[].
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
* @param[out] yerr The estimated error.
|
||||
* @param[out] nextDydx Last derivatives array for the next step.
|
||||
*/
|
||||
void Stepper( const G4double y[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
@@ -56,31 +86,48 @@ class G4FSALBogackiShampine45 : public G4VFSALIntegrationStepper
|
||||
G4double yerr[],
|
||||
G4double nextDydx[]) override ;
|
||||
|
||||
/**
|
||||
* Calculates the output at the tau fraction of step.
|
||||
* @param[in] yInput Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[out] yOut Interpolation output.
|
||||
* @param[in] Step The given step size.
|
||||
* @param[in] tau The tau fraction of the step.
|
||||
*/
|
||||
void interpolate( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double yOut[],
|
||||
G4double Step,
|
||||
G4double tau ) ;
|
||||
|
||||
/**
|
||||
* Returns the distance from chord line.
|
||||
*/
|
||||
G4double DistChord() const override;
|
||||
|
||||
/**
|
||||
* Returns the order, 4, of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override { return 4; }
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Init method used in constructor.
|
||||
*/
|
||||
void PrepareConstants();
|
||||
|
||||
// Working arrays -- used during stepping
|
||||
//
|
||||
/** Working arrays -- used during stepping. */
|
||||
G4double *ak2, *ak3, *ak4, *ak5, *ak6, *ak7, *ak8, *ak9, *ak10, *ak11,
|
||||
*DyDx, *yTemp, *yIn;
|
||||
G4double *pseudoDydx_for_DistChord;
|
||||
|
||||
G4double fLastStepLength = -1.0;
|
||||
G4double *fLastInitialVector, *fLastFinalVector,
|
||||
*fLastDyDx, *fMidVector, *fMidError;
|
||||
// for DistChord calculations
|
||||
*fLastDyDx, *fMidVector, *fMidError; // for DistChord calculations
|
||||
|
||||
G4double b[12]; // Working array for interpolation
|
||||
/** Working array for interpolation. */
|
||||
G4double b[12];
|
||||
|
||||
G4FSALBogackiShampine45* fAuxStepper = nullptr;
|
||||
|
||||
|
||||
@@ -29,68 +29,126 @@
|
||||
//
|
||||
// DormandPrince7 - 5(4) FSAL stepper
|
||||
|
||||
// Created: Somnath Banerjee, Google Summer of Code 2015, 25 May 2015
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// Author: Somnath Banerjee (CERN, Google Summer of Code 2015), 25.05.2015
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4FSALDORMANDPRINCE745_HH
|
||||
#define G4FSALDORMANDPRINCE745_HH
|
||||
|
||||
#include "G4VFSALIntegrationStepper.hh"
|
||||
|
||||
/**
|
||||
* @brief G4FSALDormandPrince745 is an integrator of particle's equation of
|
||||
* motion based on the DormandPrince7 - 5(4) FSAL implementation.
|
||||
*/
|
||||
|
||||
class G4FSALDormandPrince745 : public G4VFSALIntegrationStepper
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4FSALDormandPrince745.
|
||||
* @param[in] EqRhs Pointer to the provided equation of motion.
|
||||
* @param[in] numberOfVariables The number of integration variables.
|
||||
* @param[in] primary Flag for initialisation of the auxiliary stepper.
|
||||
*/
|
||||
G4FSALDormandPrince745(G4EquationOfMotion* EqRhs,
|
||||
G4int numberOfVariables = 6,
|
||||
G4bool primary = true);
|
||||
~G4FSALDormandPrince745() override;
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~G4FSALDormandPrince745() override;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4FSALDormandPrince745(const G4FSALDormandPrince745&) = delete;
|
||||
G4FSALDormandPrince745& operator=(const G4FSALDormandPrince745&) = delete;
|
||||
|
||||
/**
|
||||
* The stepper for the Runge Kutta integration.
|
||||
* The stepsize is fixed, with the step size given by 'h'.
|
||||
* Integrates ODE starting values y[0 to 6].
|
||||
* Outputs yout[] and its estimated error yerr[].
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
* @param[out] yerr The estimated error.
|
||||
* @param[out] nextDydx Last derivatives array for the next step.
|
||||
*/
|
||||
void Stepper( const G4double y[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yout[],
|
||||
G4double yerr[],
|
||||
G4double nextDydx[]) override ;
|
||||
|
||||
/**
|
||||
* Calculates the output at the tau fraction of step.
|
||||
* @param[in] yInput Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[out] yOut Interpolation output.
|
||||
* @param[in] Step The given step size.
|
||||
* @param[in] tau The tau fraction of the step.
|
||||
*/
|
||||
void interpolate( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double yOut[],
|
||||
G4double Step,
|
||||
G4double tau ) ;
|
||||
|
||||
void SetupInterpolate( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double Step );
|
||||
// For higher order Interpolant
|
||||
|
||||
/**
|
||||
* Calculates the output at the tau fraction of step. Same as above
|
||||
* for higher order interpolant.
|
||||
*/
|
||||
void Interpolate( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double Step,
|
||||
G4double yOut[],
|
||||
G4double tau );
|
||||
// For calculating the output at the tau fraction of Step
|
||||
|
||||
/**
|
||||
* Setup method for higher order interpolant.
|
||||
* @param[in] yInput Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] Step The given step size.
|
||||
*/
|
||||
void SetupInterpolate( const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
const G4double Step );
|
||||
|
||||
G4double DistChord() const override;
|
||||
/**
|
||||
* Returns the distance from chord line.
|
||||
*/
|
||||
G4double DistChord() const override;
|
||||
|
||||
/**
|
||||
* Returns the order, 4, of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override { return 4; }
|
||||
|
||||
/**
|
||||
* Returns true as this is a FSAL integrator.
|
||||
*/
|
||||
inline G4bool isFSAL() const { return true; }
|
||||
|
||||
private:
|
||||
|
||||
/** Working arrays -- used during stepping. */
|
||||
G4double *ak2, *ak3, *ak4, *ak5, *ak6, *ak7,
|
||||
*ak8, *ak9, // For additional stages in the interpolant
|
||||
*yTemp, *yIn;
|
||||
|
||||
/** Only for use with DistChord(). */
|
||||
G4double* pseudoDydx_for_DistChord;
|
||||
// Only for use with DistChord()
|
||||
|
||||
G4double fLastStepLength = -1.0;
|
||||
G4double *fLastInitialVector, *fLastFinalVector,
|
||||
*fInitialDyDx, *fLastDyDx, *fMidVector, *fMidError;
|
||||
// For DistChord() calculations
|
||||
*fInitialDyDx, *fLastDyDx,
|
||||
*fMidVector, *fMidError; // For DistChord() calculations
|
||||
|
||||
G4FSALDormandPrince745* fAuxStepper = nullptr;
|
||||
};
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
//
|
||||
// Driver class which controls the integration error of a Runge-Kutta stepper
|
||||
|
||||
// Created: D.Sorokin, 2017
|
||||
// Author: Dmitry Sorokin (CERN, Google Summer of Code 2017), 20.10.2017
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4FSALINTEGRATIONDRIVER_HH
|
||||
#define G4FSALINTEGRATIONDRIVER_HH
|
||||
@@ -37,98 +37,170 @@
|
||||
#include "G4RKIntegrationDriver.hh"
|
||||
#include "G4ChordFinderDelegate.hh"
|
||||
|
||||
/**
|
||||
* @brief G4FSALIntegrationDriver is a templated driver class which controls
|
||||
* the integration error of a Runge-Kutta stepper.
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
class G4FSALIntegrationDriver : public G4RKIntegrationDriver<T>,
|
||||
public G4ChordFinderDelegate<G4FSALIntegrationDriver<T>>
|
||||
public G4ChordFinderDelegate<G4FSALIntegrationDriver<T>>
|
||||
{
|
||||
public:
|
||||
|
||||
G4FSALIntegrationDriver(G4double hminimum,
|
||||
T* stepper,
|
||||
G4int numberOfComponents = 6,
|
||||
G4int statisticsVerbosity = 1);
|
||||
/**
|
||||
* Constructor for G4FSALIntegrationDriver.
|
||||
* @param[in] hminimum Minimum allowed step.
|
||||
* @param[in] stepper Pointer to the stepper algorithm.
|
||||
* @param[in] numberOfComponents The number of integration variables,
|
||||
* if not matching stepper's number of variables, issue exception.
|
||||
* @param[in] statisticsVerbosity Verbosity level.
|
||||
*/
|
||||
inline G4FSALIntegrationDriver(G4double hminimum,
|
||||
T* stepper,
|
||||
G4int numberOfComponents = 6,
|
||||
G4int statisticsVerbosity = 1);
|
||||
|
||||
~G4FSALIntegrationDriver() override;
|
||||
/**
|
||||
* Destructor. Provides statistics if verbosity level is greater than zero.
|
||||
*/
|
||||
inline ~G4FSALIntegrationDriver() override;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4FSALIntegrationDriver(const G4FSALIntegrationDriver&) = delete;
|
||||
G4FSALIntegrationDriver& operator=(const G4FSALIntegrationDriver&) = delete;
|
||||
|
||||
G4double AdvanceChordLimited(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps,
|
||||
G4double chordDistance) override;
|
||||
/**
|
||||
* Computes the step to take, based on chord limits.
|
||||
* @param[in,out] track The current track in field.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[in] eps Requested accuracy, y_err/hstep.
|
||||
* @param[in] chordDistance Maximum sagitta distance.
|
||||
* @returns The length of step taken.
|
||||
*/
|
||||
inline G4double AdvanceChordLimited(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps,
|
||||
G4double chordDistance) override;
|
||||
|
||||
void OnStartTracking() override
|
||||
{
|
||||
ChordFinderDelegate::ResetStepEstimate();
|
||||
}
|
||||
/**
|
||||
* Dispatch interface method for initialisation/reset of driver.
|
||||
*/
|
||||
inline void OnStartTracking() override;
|
||||
|
||||
void OnComputeStep(const G4FieldTrack* /*track*/ = nullptr) override {}
|
||||
/**
|
||||
* Dispatch interface method for computing step. Does nothing here.
|
||||
*/
|
||||
inline void OnComputeStep(const G4FieldTrack* /*track*/ = nullptr) override;
|
||||
|
||||
G4bool DoesReIntegrate() const override { return true; }
|
||||
/**
|
||||
* The driver does implement re-integration. Returns true.
|
||||
*/
|
||||
inline G4bool DoesReIntegrate() const override;
|
||||
|
||||
G4bool AccurateAdvance( G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps, // Requested y_err/hstep
|
||||
G4double hinitial = 0.0) override;
|
||||
// Integrates ODE from current s (s=s0) to s=s0+h with accuracy eps.
|
||||
// On output track is replaced by value at end of interval.
|
||||
// The concept is similar to the odeint routine from NRC p.721-722.
|
||||
/**
|
||||
* Advances integration accurately by relative accuracy better than 'eps'.
|
||||
* On output the track is replaced by the value at the end of interval.
|
||||
* @param[in,out] track The current track in field.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[in] eps Requested accuracy, y_err/hstep.
|
||||
* @param[in] hinitial Initial minimum integration step.
|
||||
* @returns true if integration succeeds.
|
||||
*/
|
||||
inline G4bool AccurateAdvance(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps, // Requested y_err/hstep
|
||||
G4double hinitial = 0.0) override;
|
||||
|
||||
G4bool QuickAdvance( G4FieldTrack& fieldTrack,
|
||||
const G4double dydx[],
|
||||
/**
|
||||
* Attempts one integration step, and returns estimated error 'dyerr'.
|
||||
* It does not ensure accuracy.
|
||||
* @param[in,out] fieldTrack The current track in field.
|
||||
* @param[in] dydx dydx array.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[out] dchord_step Estimated sagitta distance.
|
||||
* @param[out] dyerr Estimated error.
|
||||
* @returns true if integration succeeds.
|
||||
*/
|
||||
inline G4bool QuickAdvance(G4FieldTrack& fieldTrack,
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr ) override;
|
||||
// QuickAdvance just tries one Step - it does not ensure accuracy.
|
||||
G4double& dyerr) override;
|
||||
|
||||
void SetVerboseLevel(G4int newLevel) override;
|
||||
G4int GetVerboseLevel() const override;
|
||||
/**
|
||||
* Takes one Step that is as large as possible while satisfying the
|
||||
* accuracy criterion.
|
||||
* @param[in,out] y The current track state, y.
|
||||
* @param[in] dydx dydx array.
|
||||
* @param[in,out] curveLength Step start, x.
|
||||
* @param[in] htry Step to attempt.
|
||||
* @param[in] eps The relative accuracy.
|
||||
* @param[out] hdid Step achieved.
|
||||
* @param[out] hnext Proposed next step.
|
||||
*/
|
||||
inline void OneGoodStep(G4double y[], // InOut
|
||||
G4double dydx[],
|
||||
G4double& curveLength,
|
||||
G4double htry,
|
||||
G4double eps,
|
||||
G4double& hdid,
|
||||
G4double& hnext);
|
||||
|
||||
void StreamInfo( std::ostream& os ) const override;
|
||||
// Write out the parameters / state of the driver
|
||||
/**
|
||||
* Setter and getter for verbosity.
|
||||
*/
|
||||
inline void SetVerboseLevel(G4int newLevel) override;
|
||||
inline G4int GetVerboseLevel() const override;
|
||||
|
||||
/**
|
||||
* Writes out to stream the parameters/state of the driver.
|
||||
*/
|
||||
inline void StreamInfo( std::ostream& os ) const override;
|
||||
|
||||
// Accessors
|
||||
/**
|
||||
* Getter and Setter for minimum allowed step.
|
||||
*/
|
||||
inline G4double GetMinimumStep() const;
|
||||
inline void SetMinimumStep(G4double newval);
|
||||
|
||||
G4double GetMinimumStep() const;
|
||||
void SetMinimumStep(G4double newval);
|
||||
|
||||
void OneGoodStep(G4double y[], // InOut
|
||||
G4double dydx[],
|
||||
G4double& curveLength,
|
||||
G4double htry,
|
||||
G4double eps,
|
||||
G4double& hdid,
|
||||
G4double& hnext);
|
||||
// This takes one Step that is of size htry, or as large
|
||||
// as possible while satisfying the accuracy criterion of:
|
||||
// yerr < eps * |y_end-y_start|
|
||||
|
||||
G4double GetSmallestFraction() const;
|
||||
void SetSmallestFraction(G4double val);
|
||||
/**
|
||||
* Getter and Setter for smallest fraction.
|
||||
*/
|
||||
inline G4double GetSmallestFraction() const;
|
||||
inline void SetSmallestFraction(G4double val);
|
||||
|
||||
protected:
|
||||
|
||||
void IncrementQuickAdvanceCalls();
|
||||
/**
|
||||
* Increments the counter for the number of calls to QuickAdvance().
|
||||
*/
|
||||
inline void IncrementQuickAdvanceCalls();
|
||||
|
||||
private:
|
||||
|
||||
void CheckStep(const G4ThreeVector& posIn,
|
||||
const G4ThreeVector& posOut,
|
||||
G4double hdid);
|
||||
/**
|
||||
* Checks accuracy of step distance on the end point.
|
||||
*/
|
||||
inline void CheckStep(const G4ThreeVector& posIn,
|
||||
const G4ThreeVector& posOut, G4double hdid);
|
||||
|
||||
private:
|
||||
|
||||
/** Minimum Step allowed in a Step (in absolute units). */
|
||||
G4double fMinimumStep;
|
||||
// Minimum Step allowed in a Step (in absolute units)
|
||||
|
||||
/** Smallest fraction of (existing) curve length in relative units.
|
||||
* Below this fraction the current step will be the last.
|
||||
* The expected range: smaller than 0.1 * epsilon and bigger than 5e-13
|
||||
* (range not enforced). */
|
||||
G4double fSmallestFraction{1e-12};
|
||||
// Smallest fraction of (existing) curve length - in relative units
|
||||
// below this fraction the current step will be the last
|
||||
// Expected range: smaller than 0.1 * epsilon and bigger than 5e-13
|
||||
// ( Note: this range is not enforced. )
|
||||
|
||||
/** Verbosity level for printing (debug, etc..)
|
||||
* Could be varied during tracking to help identifying issues. */
|
||||
G4int fVerboseLevel;
|
||||
// Verbosity level for printing (debug, ..)
|
||||
// Could be varied during tracking - to help identify issues
|
||||
|
||||
G4int fNoQuickAvanceCalls{0};
|
||||
G4int fNoAccurateAdvanceCalls{0};
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
//
|
||||
// G4FSALIntegrationDriver inline implementation
|
||||
//
|
||||
// Created: D.Sorokin, 2017
|
||||
// Author: Dmitry Sorokin (CERN, Google Summer of Code 2017), 20.10.2017
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4FieldUtils.hh"
|
||||
@@ -34,34 +34,34 @@ template <class T>
|
||||
G4FSALIntegrationDriver<T>::
|
||||
G4FSALIntegrationDriver ( G4double hminimum, T* pStepper,
|
||||
G4int numComponents, G4int statisticsVerbose )
|
||||
: Base(pStepper),
|
||||
fMinimumStep(hminimum),
|
||||
fVerboseLevel(statisticsVerbose)
|
||||
: Base(pStepper),
|
||||
fMinimumStep(hminimum),
|
||||
fVerboseLevel(statisticsVerbose)
|
||||
{
|
||||
if (numComponents != Base::GetStepper()->GetNumberOfVariables())
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Driver's number of integrated components "
|
||||
<< numComponents
|
||||
<< " != Stepper's number of components "
|
||||
<< pStepper->GetNumberOfVariables();
|
||||
G4Exception("G4FSALIntegrationDriver","GeomField0002",
|
||||
FatalException, message);
|
||||
}
|
||||
if (numComponents != Base::GetStepper()->GetNumberOfVariables())
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Driver's number of integrated components "
|
||||
<< numComponents
|
||||
<< " != Stepper's number of components "
|
||||
<< pStepper->GetNumberOfVariables();
|
||||
G4Exception("G4FSALIntegrationDriver","GeomField0002",
|
||||
FatalException, message);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4FSALIntegrationDriver<T>::~G4FSALIntegrationDriver()
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
if( fVerboseLevel > 0 )
|
||||
{
|
||||
G4cout << "G4FSALIntegration Driver Stats: "
|
||||
<< "#QuickAdvance " << fNoQuickAvanceCalls
|
||||
<< " - #AccurateAdvance " << fNoAccurateAdvanceCalls << G4endl
|
||||
<< "#good steps " << fNoAccurateAdvanceGoodSteps << " "
|
||||
<< "#bad steps " << fNoAccurateAdvanceBadSteps << G4endl;
|
||||
}
|
||||
if( fVerboseLevel > 0 )
|
||||
{
|
||||
G4cout << "G4FSALIntegration Driver Stats: "
|
||||
<< "#QuickAdvance " << fNoQuickAvanceCalls
|
||||
<< " - #AccurateAdvance " << fNoAccurateAdvanceCalls << G4endl
|
||||
<< "#good steps " << fNoAccurateAdvanceGoodSteps << " "
|
||||
<< "#bad steps " << fNoAccurateAdvanceBadSteps << G4endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -76,66 +76,65 @@ G4bool G4FSALIntegrationDriver<T>::
|
||||
AccurateAdvance( G4FieldTrack& track, G4double hstep,
|
||||
G4double eps, G4double hinitial )
|
||||
{
|
||||
++fNoAccurateAdvanceCalls;
|
||||
++fNoAccurateAdvanceCalls;
|
||||
|
||||
if (hstep < GetMinimumStep())
|
||||
if (hstep < GetMinimumStep())
|
||||
{
|
||||
G4double dchord_step = 0.0, dyerr = 0.0;
|
||||
G4double dydx[G4FieldTrack::ncompSVEC];
|
||||
Base::GetDerivatives(track, dydx);
|
||||
return QuickAdvance(track, dydx, hstep, dchord_step, dyerr);
|
||||
}
|
||||
|
||||
G4bool succeeded = false;
|
||||
|
||||
G4double hnext, hdid;
|
||||
|
||||
G4double y[G4FieldTrack::ncompSVEC], dydx[G4FieldTrack::ncompSVEC];
|
||||
|
||||
track.DumpToArray(y);
|
||||
|
||||
// hstep somtimes is too small. No need to add large curveLength.
|
||||
G4double curveLength = 0.0;
|
||||
G4double endCurveLength = hstep;
|
||||
|
||||
G4double h = hstep;
|
||||
if (hinitial > CLHEP::perMillion * hstep && hinitial < hstep)
|
||||
{
|
||||
h = hinitial;
|
||||
}
|
||||
|
||||
Base::GetStepper()->RightHandSide(y, dydx);
|
||||
|
||||
for (G4int iter = 0; iter < Base::GetMaxNoSteps(); ++iter)
|
||||
{
|
||||
const G4ThreeVector StartPos =
|
||||
field_utils::makeVector(y, field_utils::Value3D::Position);
|
||||
|
||||
OneGoodStep(y, dydx, curveLength, h, eps, hdid, hnext);
|
||||
|
||||
const G4ThreeVector EndPos =
|
||||
field_utils::makeVector(y, field_utils::Value3D::Position);
|
||||
|
||||
CheckStep(EndPos, StartPos, hdid);
|
||||
|
||||
G4double restCurveLength = endCurveLength - curveLength;
|
||||
if (restCurveLength < GetSmallestFraction() * hstep)
|
||||
{
|
||||
G4double dchord_step = 0.0, dyerr = 0.0;
|
||||
G4double dydx[G4FieldTrack::ncompSVEC];
|
||||
Base::GetDerivatives(track, dydx);
|
||||
return QuickAdvance(track, dydx, hstep, dchord_step, dyerr);
|
||||
succeeded = true;
|
||||
break;
|
||||
}
|
||||
|
||||
G4bool succeeded = false;
|
||||
|
||||
G4double hnext, hdid;
|
||||
|
||||
G4double y[G4FieldTrack::ncompSVEC], dydx[G4FieldTrack::ncompSVEC];
|
||||
|
||||
track.DumpToArray(y);
|
||||
|
||||
// hstep somtimes is too small. No need to add large curveLength.
|
||||
G4double curveLength = 0.0;
|
||||
G4double endCurveLength = hstep;
|
||||
h = std::min(hnext, restCurveLength);
|
||||
}
|
||||
|
||||
|
||||
G4double h = hstep;
|
||||
if (hinitial > CLHEP::perMillion * hstep && hinitial < hstep)
|
||||
{
|
||||
h = hinitial;
|
||||
}
|
||||
if (succeeded)
|
||||
{
|
||||
track.LoadFromArray(y, Base::GetStepper()->GetNumberOfVariables());
|
||||
track.SetCurveLength(track.GetCurveLength() + curveLength);
|
||||
}
|
||||
|
||||
Base::GetStepper()->RightHandSide(y, dydx);
|
||||
|
||||
for (G4int iter = 0; iter < Base::GetMaxNoSteps(); ++iter)
|
||||
{
|
||||
const G4ThreeVector StartPos =
|
||||
field_utils::makeVector(y, field_utils::Value3D::Position);
|
||||
|
||||
OneGoodStep(y, dydx, curveLength, h, eps, hdid, hnext);
|
||||
|
||||
const G4ThreeVector EndPos =
|
||||
field_utils::makeVector(y, field_utils::Value3D::Position);
|
||||
|
||||
CheckStep(EndPos, StartPos, hdid);
|
||||
|
||||
G4double restCurveLength = endCurveLength - curveLength;
|
||||
if (restCurveLength < GetSmallestFraction() * hstep)
|
||||
{
|
||||
succeeded = true;
|
||||
break;
|
||||
}
|
||||
h = std::min(hnext, restCurveLength);
|
||||
}
|
||||
|
||||
|
||||
if (succeeded)
|
||||
{
|
||||
track.LoadFromArray(y, Base::GetStepper()->GetNumberOfVariables());
|
||||
track.SetCurveLength(track.GetCurveLength() + curveLength);
|
||||
}
|
||||
|
||||
return succeeded;
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
// Driver for one Runge-Kutta Step with monitoring of local truncation error
|
||||
@@ -161,36 +160,36 @@ OneGoodStep(G4double y[],
|
||||
G4double& hdid, // Out
|
||||
G4double& hnext) // Out
|
||||
{
|
||||
G4double error2 = DBL_MAX;
|
||||
G4double error2 = DBL_MAX;
|
||||
|
||||
G4double yError[G4FieldTrack::ncompSVEC],
|
||||
yOut[G4FieldTrack::ncompSVEC],
|
||||
dydxOut[G4FieldTrack::ncompSVEC];
|
||||
G4double yError[G4FieldTrack::ncompSVEC],
|
||||
yOut[G4FieldTrack::ncompSVEC],
|
||||
dydxOut[G4FieldTrack::ncompSVEC];
|
||||
|
||||
// Set stepsize to the initial trial value
|
||||
G4double hstep = htry;
|
||||
// Set stepsize to the initial trial value
|
||||
G4double hstep = htry;
|
||||
|
||||
const G4int max_trials = 100;
|
||||
const G4int max_trials = 100;
|
||||
|
||||
for (G4int iter = 0; iter < max_trials; ++iter)
|
||||
{
|
||||
Base::GetStepper()->Stepper(y, dydx, hstep, yOut, yError, dydxOut);
|
||||
error2 = field_utils::relativeError2(y, yError, hstep, eps_rel_max);
|
||||
for (G4int iter = 0; iter < max_trials; ++iter)
|
||||
{
|
||||
Base::GetStepper()->Stepper(y, dydx, hstep, yOut, yError, dydxOut);
|
||||
error2 = field_utils::relativeError2(y, yError, hstep, eps_rel_max);
|
||||
|
||||
// Step succeeded.
|
||||
if (error2 <= 1) { break; }
|
||||
// Step succeeded.
|
||||
if (error2 <= 1) { break; }
|
||||
|
||||
hstep = Base::ShrinkStepSize2(hstep, error2);
|
||||
}
|
||||
hstep = Base::ShrinkStepSize2(hstep, error2);
|
||||
}
|
||||
|
||||
hnext = Base::GrowStepSize2(hstep, error2);
|
||||
curveLength += (hdid = hstep);
|
||||
hnext = Base::GrowStepSize2(hstep, error2);
|
||||
curveLength += (hdid = hstep);
|
||||
|
||||
for(G4int k = 0; k < Base::GetStepper()->GetNumberOfVariables(); ++k)
|
||||
{
|
||||
y[k] = yOut[k];
|
||||
dydx[k] = dydxOut[k];
|
||||
}
|
||||
for(G4int k = 0; k < Base::GetStepper()->GetNumberOfVariables(); ++k)
|
||||
{
|
||||
y[k] = yOut[k];
|
||||
dydx[k] = dydxOut[k];
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@@ -199,123 +198,122 @@ QuickAdvance( G4FieldTrack& fieldTrack, const G4double dydxIn[],
|
||||
G4double hstep,
|
||||
G4double& dchord_step, G4double& dyerr )
|
||||
{
|
||||
++fNoQuickAvanceCalls;
|
||||
|
||||
if (hstep == 0)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Proposed step is zero; hstep = " << hstep << " !";
|
||||
G4Exception("G4FSALIntegrationDriver ::QuickAdvance()",
|
||||
"GeomField1001", JustWarning, message);
|
||||
return true;
|
||||
}
|
||||
if (hstep < 0)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Invalid run condition." << G4endl
|
||||
<< "Proposed step is negative; hstep = "
|
||||
<< hstep << "." << G4endl
|
||||
<< "Requested step cannot be negative! Aborting event.";
|
||||
G4Exception("G4FSALIntegrationDriver ::QuickAdvance()",
|
||||
"GeomField0003", EventMustBeAborted, message);
|
||||
return false;
|
||||
}
|
||||
|
||||
G4double yError[G4FieldTrack::ncompSVEC],
|
||||
yIn[G4FieldTrack::ncompSVEC],
|
||||
yOut[G4FieldTrack::ncompSVEC],
|
||||
dydxOut[G4FieldTrack::ncompSVEC];
|
||||
|
||||
fieldTrack.DumpToArray(yIn);
|
||||
|
||||
Base::GetStepper()->Stepper(yIn, dydxIn, hstep, yOut, yError, dydxOut);
|
||||
dchord_step = Base::GetStepper()->DistChord();
|
||||
|
||||
fieldTrack.LoadFromArray(yOut, Base::GetStepper()->GetNumberOfVariables());
|
||||
fieldTrack.SetCurveLength(fieldTrack.GetCurveLength() + hstep);
|
||||
|
||||
dyerr = field_utils::absoluteError(yOut, yError, hstep);
|
||||
++fNoQuickAvanceCalls;
|
||||
|
||||
if (hstep == 0)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Proposed step is zero; hstep = " << hstep << " !";
|
||||
G4Exception("G4FSALIntegrationDriver ::QuickAdvance()",
|
||||
"GeomField1001", JustWarning, message);
|
||||
return true;
|
||||
}
|
||||
if (hstep < 0)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Invalid run condition." << G4endl
|
||||
<< "Proposed step is negative; hstep = "
|
||||
<< hstep << "." << G4endl
|
||||
<< "Requested step cannot be negative! Aborting event.";
|
||||
G4Exception("G4FSALIntegrationDriver ::QuickAdvance()",
|
||||
"GeomField0003", EventMustBeAborted, message);
|
||||
return false;
|
||||
}
|
||||
|
||||
G4double yError[G4FieldTrack::ncompSVEC],
|
||||
yIn[G4FieldTrack::ncompSVEC],
|
||||
yOut[G4FieldTrack::ncompSVEC],
|
||||
dydxOut[G4FieldTrack::ncompSVEC];
|
||||
|
||||
fieldTrack.DumpToArray(yIn);
|
||||
|
||||
Base::GetStepper()->Stepper(yIn, dydxIn, hstep, yOut, yError, dydxOut);
|
||||
dchord_step = Base::GetStepper()->DistChord();
|
||||
|
||||
fieldTrack.LoadFromArray(yOut, Base::GetStepper()->GetNumberOfVariables());
|
||||
fieldTrack.SetCurveLength(fieldTrack.GetCurveLength() + hstep);
|
||||
|
||||
dyerr = field_utils::absoluteError(yOut, yError, hstep);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::SetSmallestFraction(G4double newFraction)
|
||||
{
|
||||
if( newFraction > 1.e-16 && newFraction < 1e-8 )
|
||||
{
|
||||
fSmallestFraction = newFraction;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Smallest Fraction not changed. " << G4endl
|
||||
<< " Proposed value was " << newFraction << G4endl
|
||||
<< " Value must be between 1.e-8 and 1.e-16";
|
||||
G4Exception("G4FSALIntegrationDriver::SetSmallestFraction()",
|
||||
"GeomField1001", JustWarning, message);
|
||||
}
|
||||
if( newFraction > 1.e-16 && newFraction < 1e-8 )
|
||||
{
|
||||
fSmallestFraction = newFraction;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Smallest Fraction not changed. " << G4endl
|
||||
<< " Proposed value was " << newFraction << G4endl
|
||||
<< " Value must be between 1.e-8 and 1.e-16";
|
||||
G4Exception("G4FSALIntegrationDriver::SetSmallestFraction()",
|
||||
"GeomField1001", JustWarning, message);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::CheckStep(
|
||||
const G4ThreeVector& posIn, const G4ThreeVector& posOut, G4double hdid)
|
||||
{
|
||||
const G4double endPointDist = (posOut - posIn).mag();
|
||||
if (endPointDist >= hdid * (1. + CLHEP::perMillion))
|
||||
{
|
||||
++fNoAccurateAdvanceBadSteps;
|
||||
const G4double endPointDist = (posOut - posIn).mag();
|
||||
if (endPointDist >= hdid * (1. + CLHEP::perMillion))
|
||||
{
|
||||
++fNoAccurateAdvanceBadSteps;
|
||||
#ifdef G4DEBUG_FIELD
|
||||
// Issue a warning only for gross differences -
|
||||
// we understand how small difference occur.
|
||||
if (endPointDist >= hdid * (1. + perThousand))
|
||||
{
|
||||
G4Exception("G4FSALIntegrationDriver::CheckStep()",
|
||||
"GeomField1002", JustWarning,
|
||||
"endPointDist >= hdid!");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
// Issue a warning only for gross differences -
|
||||
// we understand how small difference occur.
|
||||
if (endPointDist >= hdid * (1. + perThousand))
|
||||
{
|
||||
++fNoAccurateAdvanceGoodSteps;
|
||||
G4Exception("G4FSALIntegrationDriver::CheckStep()",
|
||||
"GeomField1002", JustWarning, "endPointDist >= hdid!");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
++fNoAccurateAdvanceGoodSteps;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline G4double G4FSALIntegrationDriver<T>::GetMinimumStep() const
|
||||
{
|
||||
return fMinimumStep;
|
||||
return fMinimumStep;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::SetMinimumStep(G4double minimumStepLength)
|
||||
{
|
||||
fMinimumStep = minimumStepLength;
|
||||
fMinimumStep = minimumStepLength;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4int G4FSALIntegrationDriver<T>::GetVerboseLevel() const
|
||||
{
|
||||
return fVerboseLevel;
|
||||
return fVerboseLevel;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::SetVerboseLevel(G4int newLevel)
|
||||
{
|
||||
fVerboseLevel = newLevel;
|
||||
fVerboseLevel = newLevel;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4double G4FSALIntegrationDriver<T>::GetSmallestFraction() const
|
||||
{
|
||||
return fSmallestFraction;
|
||||
return fSmallestFraction;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::IncrementQuickAdvanceCalls()
|
||||
{
|
||||
++fNoQuickAvanceCalls;
|
||||
++fNoQuickAvanceCalls;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@@ -325,14 +323,32 @@ G4FSALIntegrationDriver<T>::AdvanceChordLimited(G4FieldTrack& track,
|
||||
G4double eps,
|
||||
G4double chordDistance)
|
||||
{
|
||||
return ChordFinderDelegate::AdvanceChordLimitedImpl(track, hstep,
|
||||
eps, chordDistance);
|
||||
return ChordFinderDelegate::AdvanceChordLimitedImpl(track, hstep,
|
||||
eps, chordDistance);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::OnStartTracking()
|
||||
{
|
||||
ChordFinderDelegate::ResetStepEstimate();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::OnComputeStep(const G4FieldTrack*)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4bool G4FSALIntegrationDriver<T>::DoesReIntegrate() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4FSALIntegrationDriver<T>::StreamInfo( std::ostream& os ) const
|
||||
{
|
||||
// Write out the parameters / state of the driver
|
||||
// Write out the parameters / state of the driver
|
||||
|
||||
os << "State of G4IntegrationDriver: " << std::endl;
|
||||
os << "--Base state (G4RKIntegrationDriver): " << std::endl;
|
||||
Base::StreamInfo( os );
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
// It allows any kind of field (vector, scalar, tensor and any set of them)
|
||||
// to be defined by implementing the inquiry function interface.
|
||||
//
|
||||
// The key method is GetFieldValue( const double Point[4],
|
||||
// ************* double *fieldArr )
|
||||
// The key method is GetFieldValue( const G4double Point[4],
|
||||
// ************* G4double* fieldArr )
|
||||
// Given an input position/time vector 'Point',
|
||||
// this method must return the value of the field in "fieldArr".
|
||||
//
|
||||
@@ -44,68 +44,102 @@
|
||||
// spin. For this a field and its equation of motion must follow the
|
||||
// same convention for the order of field components in the array "fieldArr"
|
||||
|
||||
// Created: John Apostolakis, 10.03.1997
|
||||
// Author: John Apostolakis (CERN), 10.03.1997
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4FIELD_HH
|
||||
#define G4FIELD_HH
|
||||
|
||||
#include "G4Types.hh"
|
||||
#include "G4FieldParameters.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
/**
|
||||
* @brief G4Field is the abstract class for any kind of field.
|
||||
* It allows any kind of field (vector, scalar, tensor and any set of them)
|
||||
* to be defined by implementing the inquiry function interface.
|
||||
* A field must co-work with a corresponding Equation of Motion, to
|
||||
* enable the integration of a particle's position, momentum and, optionally,
|
||||
* spin. For this a field and its equation of motion must follow the same
|
||||
* convention for the order of field components.
|
||||
*/
|
||||
|
||||
class G4Field
|
||||
{
|
||||
public: // with description
|
||||
public:
|
||||
|
||||
G4Field( G4bool gravityOn = false);
|
||||
G4Field( const G4Field& );
|
||||
virtual ~G4Field();
|
||||
G4Field& operator = (const G4Field& p);
|
||||
/**
|
||||
* Constructor for G4Field.
|
||||
* @param[in] gravityOn Flag to indicate if gravity is enabled or not.
|
||||
*/
|
||||
G4Field(G4bool gravityOn = false);
|
||||
|
||||
virtual void GetFieldValue( const G4double Point[4],
|
||||
G4double* fieldArr ) const = 0;
|
||||
// Given the position time vector 'Point',
|
||||
// return the value of the field in the array fieldArr.
|
||||
// Notes:
|
||||
// 1) The 'Point' vector has the following structure:
|
||||
// Point[0] is x ( position, in Geant4 units )
|
||||
// Point[1] is y
|
||||
// Point[2] is z
|
||||
// Point[3] is t ( time, in Geant4 units )
|
||||
// 2) The convention for the components of the field
|
||||
// array 'fieldArr' are determined by the type of field.
|
||||
// See for example the class G4ElectroMagneticField.
|
||||
/**
|
||||
* Default virtual Destructor.
|
||||
*/
|
||||
virtual ~G4Field() = default;
|
||||
|
||||
virtual G4bool DoesFieldChangeEnergy() const = 0;
|
||||
// Each type/class of field should respond this accordingly
|
||||
// For example:
|
||||
// - an electric field should return "true"
|
||||
// - a pure magnetic field should return "false"
|
||||
/**
|
||||
* Copy constructor and assignment operator.
|
||||
*/
|
||||
G4Field( const G4Field& p) = default;
|
||||
G4Field& operator = (const G4Field& p);
|
||||
|
||||
inline G4bool IsGravityActive() const;
|
||||
/**
|
||||
* Given the position time vector 'Point', returns the value of the
|
||||
* field in the array 'fieldArr'. Notes:
|
||||
* 1) The 'Point' vector has the following structure:
|
||||
* Point[0] is x ( position, in Geant4 units )
|
||||
* Point[1] is y
|
||||
* Point[2] is z
|
||||
* Point[3] is t ( time, in Geant4 units )
|
||||
* 2) The convention for the components of the field array 'fieldArr'
|
||||
* are determined by the type of field.
|
||||
* @param[in] Point The position time vector.
|
||||
* @param[out] fieldArr The field array in output.
|
||||
*/
|
||||
virtual void GetFieldValue( const G4double Point[4],
|
||||
G4double* fieldArr ) const = 0;
|
||||
|
||||
/**
|
||||
* Each type/class of field should respond the field does change energy.
|
||||
* For example:
|
||||
* - an electric field should return "true"
|
||||
* - a pure magnetic field should return "false"
|
||||
*/
|
||||
virtual G4bool DoesFieldChangeEnergy() const = 0;
|
||||
|
||||
/**
|
||||
* Returns the field type-ID, "kUserFieldType".
|
||||
* This should be overriden in derived classes.
|
||||
*/
|
||||
virtual G4FieldType GetFieldType() const { return kUserFieldType; }
|
||||
|
||||
/**
|
||||
* Replies if the field includes gravity.
|
||||
* @returns true if the field does include gravity.
|
||||
*/
|
||||
inline G4bool IsGravityActive() const { return fGravityActive; }
|
||||
// Does this field include gravity?
|
||||
|
||||
inline void SetGravityActive( G4bool OnOffFlag );
|
||||
/**
|
||||
* Sets the gravity flag.
|
||||
*/
|
||||
inline void SetGravityActive(G4bool OnOffFlag) { fGravityActive = OnOffFlag; }
|
||||
|
||||
virtual G4Field* Clone() const;
|
||||
// Implements cloning, needed by multi-threading
|
||||
/**
|
||||
* Interface method to implement cloning, needed by multi-threading.
|
||||
* Here issuing a fatal exception, as expecting this to be implemented
|
||||
* concretely in derived classes.
|
||||
*/
|
||||
virtual G4Field* Clone() const;
|
||||
|
||||
static constexpr G4int MAX_NUMBER_OF_COMPONENTS = 24;
|
||||
public:
|
||||
|
||||
static constexpr G4int MAX_NUMBER_OF_COMPONENTS = 24;
|
||||
|
||||
private:
|
||||
|
||||
G4bool fGravityActive = false;
|
||||
G4bool fGravityActive = false;
|
||||
};
|
||||
|
||||
// Inline methods ...
|
||||
|
||||
inline G4bool G4Field::IsGravityActive() const
|
||||
{
|
||||
return fGravityActive;
|
||||
}
|
||||
|
||||
inline void G4Field::SetGravityActive( G4bool OnOffFlag )
|
||||
{
|
||||
fGravityActive = OnOffFlag;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,21 +22,35 @@
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
|
||||
//------------------------------------------------
|
||||
// The Geant4 Virtual Monte Carlo package
|
||||
// Copyright (C) 2007 - 2015 Ivana Hrivnacova
|
||||
// All rights reserved.
|
||||
//
|
||||
// For the licensing terms see geant4_vmc/LICENSE.
|
||||
// Contact: root-vmc@cern.ch
|
||||
//-------------------------------------------------
|
||||
|
||||
/// \file G4FieldBuilder.h
|
||||
/// \brief Definition of the G4FieldBuilder class
|
||||
///
|
||||
/// \author I. Hrivnacova; IJCLab, Orsay
|
||||
// G4FieldBuilder
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// The manager class for building magnetic or other fields
|
||||
// using the configuration in field parameters.
|
||||
//
|
||||
// Purpose: Provide a single 'place' to configure field & integration
|
||||
//
|
||||
// - It can configure a global field, and field(s) local to a (logical) volume
|
||||
// - The parameter values can be configured by the user (else use a default)
|
||||
// - They can be set/changed via a messenger provided or in the code
|
||||
// of the user detector construciton
|
||||
// - It retains ownership of the following object(s):
|
||||
// field parameters and field setups, field
|
||||
//
|
||||
// Note MT: an object of the builder class should be created on master only
|
||||
// (in DetectorConstruction constructor)
|
||||
// The functions SetGlobal/LocalField and ConstructFieldSetup should
|
||||
// be called on workers (in DetectorConstruction::ConstructSDandField )
|
||||
//
|
||||
// This design/implementation covers the most common use cases.
|
||||
// It cannot be used to create some complex setups such as
|
||||
// - equations templated on the field type,
|
||||
// - steppers/drivers templated on the equation and field types.
|
||||
|
||||
// Author: Ivana Hrivnacova (IJCLab, Orsay), 2024.
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4FIELDBUILDER_HH
|
||||
#define G4FIELDBUILDER_HH
|
||||
|
||||
@@ -46,187 +60,212 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
class G4Field;
|
||||
class G4FieldBuilderMessenger;
|
||||
class G4FieldSetup;
|
||||
class G4LogicalVolume;
|
||||
class G4EquationOfMotion;
|
||||
class G4MagIntegratorStepper;
|
||||
|
||||
/// \brief The manger class for building magnetic or other field
|
||||
/// using the configuration in field parameters.
|
||||
///
|
||||
/// Purpose: Provide a single 'place' to configure field & integration
|
||||
///
|
||||
/// - It can configure a global field, and field(s) local to a (logical) volume
|
||||
/// - The parameter values can be configured by the user (else use a default)
|
||||
/// - They can be set/changed via a messenger provided or in the code
|
||||
/// of the user detector construciton
|
||||
/// - It retains ownership of the following object(s):
|
||||
/// field parameters and field setups, field
|
||||
///
|
||||
/// Note MT: an object of the builder class should be created on master only
|
||||
/// (in DetectorConstruction constructor)
|
||||
/// The functions SetGlobal/LocalField and ConstructFieldSetup should
|
||||
/// be called on workers (in DetectorConstruction::ConstructSDandField )
|
||||
///
|
||||
/// This design/implementation covers the most common use cases.
|
||||
/// It cannot be used to create some complex setups such as
|
||||
/// - equations templated on the field type,
|
||||
/// - steppers/drivers templated on the equation and field types.
|
||||
///
|
||||
/// \author I. Hrivnacova; IJCLab, Orsay
|
||||
/**
|
||||
* @brief G4FieldBuilder is a singleton manager class for building magnetic
|
||||
* or other fields, using the configuration in G4FieldParameters.
|
||||
*/
|
||||
|
||||
class G4FieldBuilder
|
||||
{
|
||||
public:
|
||||
/// Destructor
|
||||
~G4FieldBuilder();
|
||||
public:
|
||||
|
||||
// Static access method
|
||||
//
|
||||
/**
|
||||
* Destructor. Deletes associated messenger.
|
||||
*/
|
||||
~G4FieldBuilder();
|
||||
|
||||
/// Create the class instance, if it does not exist,
|
||||
/// and return it on the next calls.
|
||||
static G4FieldBuilder* Instance();
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4FieldBuilder(const G4FieldBuilder& right) = delete;
|
||||
G4FieldBuilder& operator=(const G4FieldBuilder& right) = delete;
|
||||
|
||||
/// Return the information if an instance exists
|
||||
static G4bool IsInstance();
|
||||
// Static access methods
|
||||
|
||||
// Functions for constructing field setup
|
||||
//
|
||||
/**
|
||||
* Creates the class instance, if it does not exist; simply returns it
|
||||
* on the next calls.
|
||||
* @returns A pointer to the singleton instance.
|
||||
*/
|
||||
static G4FieldBuilder* Instance();
|
||||
|
||||
/// Create local magnetic field parameters (configuration) which can be then
|
||||
/// configured by the user via UI commands.
|
||||
/// The parameters are used in geometry only if a local magnetic field is
|
||||
/// associated with the volumes with the given name
|
||||
G4FieldParameters* CreateFieldParameters(const G4String& fieldVolName);
|
||||
/**
|
||||
* Tells if the singleton instance exists.
|
||||
* @returns true if the singleton instance exists.
|
||||
*/
|
||||
static G4bool IsInstance();
|
||||
|
||||
/// Construct setups for all registered fields.
|
||||
void ConstructFieldSetup();
|
||||
// Functions for constructing field setup
|
||||
|
||||
/// Update magnetic field.
|
||||
/// This function must be called if the field parameters were changed
|
||||
/// in other than PreInit> phase.
|
||||
void UpdateField();
|
||||
/**
|
||||
* Creates the local magnetic field parameters (configuration) which can
|
||||
* be then configured by the user via UI commands.
|
||||
* The parameters are used in geometry only if a local magnetic field is
|
||||
* associated with the volumes with the given name.
|
||||
* @param[in] fieldVolName Volume name.
|
||||
* @returns A pointer to the field parameters.
|
||||
*/
|
||||
G4FieldParameters* CreateFieldParameters(const G4String& fieldVolName);
|
||||
|
||||
/// Reinitialize if geometry has been modified.
|
||||
/// This function is called by G4RunManager during ReinitializeGeometry()
|
||||
void Reinitialize();
|
||||
/**
|
||||
* Constructs the setup for all registered fields.
|
||||
*/
|
||||
void ConstructFieldSetup();
|
||||
|
||||
// Set methods
|
||||
//
|
||||
/**
|
||||
* Updates the magnetic field. It must be called if the field parameters
|
||||
* were changed in other than PreInit> phase.
|
||||
*/
|
||||
void UpdateField();
|
||||
|
||||
/// Default field type is set to kMagnetic;
|
||||
/// this function should be called for other than magnetic field
|
||||
/// in order to update the default equation and stepper types.
|
||||
void SetFieldType(G4FieldType fieldType);
|
||||
/**
|
||||
* Reinitialises if geometry has been modified. This method is called
|
||||
* by G4RunManager during ReinitializeGeometry().
|
||||
*/
|
||||
void Reinitialize();
|
||||
|
||||
// Set or reset the global field.
|
||||
// Update field objects, if the field was already constructed.
|
||||
// If warn, issue a warning if the previous field is deleted.
|
||||
void SetGlobalField(G4Field* field, G4bool warn = false);
|
||||
// Set methods
|
||||
|
||||
/// Register the local field in the map.
|
||||
/// Update field objects, if the field was already constructed.
|
||||
/// If warn, issue a warning if the previous field is deleted.
|
||||
/// The field is propagated to all volume daughters regardless
|
||||
/// if they have already assigned a field manager or not.
|
||||
/// When multiple local fields are defined (by calling this function
|
||||
/// multiple times), they will be applied in the order they were set.
|
||||
void SetLocalField(G4Field* field, G4LogicalVolume* lv, G4bool warn = false);
|
||||
/**
|
||||
* The default field type is set to "kMagnetic". This method should be
|
||||
* called for other than magnetic field, in order to update the default
|
||||
* equation and stepper types.
|
||||
* @param[in] fieldType The field type-ID.
|
||||
*/
|
||||
void SetFieldType(G4FieldType fieldType);
|
||||
|
||||
/// Set user equation of motion
|
||||
void SetUserEquationOfMotion(
|
||||
G4EquationOfMotion* equation, G4String volumeName = "");
|
||||
/**
|
||||
* Sets or resets the global field. It updates the field objects,
|
||||
* if the field was already constructed.
|
||||
* @param[in] field Pointer to the global field.
|
||||
* @param[in] warn If flag is true, issues a warning if the previous
|
||||
* field is deleted.
|
||||
*/
|
||||
void SetGlobalField(G4Field* field, G4bool warn=false);
|
||||
|
||||
/// Set user stepper
|
||||
void SetUserStepper(
|
||||
G4MagIntegratorStepper* stepper, G4String volumeName = "");
|
||||
/**
|
||||
* Registers the local field in the map. It updates the field objects,
|
||||
* if the field was already constructed.
|
||||
* The field is propagated to all volume daughters regardless if they
|
||||
* have already assigned a field manager or not.
|
||||
* When multiple local fields are defined (by calling this method multiple
|
||||
* times), they will be applied in the order they were set.
|
||||
* @param[in] field Pointer to the global field.
|
||||
* @param[in] lv Pointer to the logical volume.
|
||||
* @param[in] warn If flag is true, issues a warning if the previous
|
||||
* field is deleted.
|
||||
*/
|
||||
void SetLocalField(G4Field* field, G4LogicalVolume* lv, G4bool warn=false);
|
||||
|
||||
/// Set verbose level
|
||||
void SetVerboseLevel(G4int value);
|
||||
/**
|
||||
* Sets the user equation of motion.
|
||||
* @param[in] equation Pointer to the equation of motion algorithm.
|
||||
* @param[in] volumeName Optional volume name.
|
||||
*/
|
||||
void SetUserEquationOfMotion(G4EquationOfMotion* equation,
|
||||
const G4String& volumeName = "");
|
||||
|
||||
// Get methods
|
||||
//
|
||||
/**
|
||||
* Sets the user stepper.
|
||||
* @param[in] stepper Pointer to the stepper algorithm.
|
||||
* @param[in] volumeName Optional volume name.
|
||||
*/
|
||||
void SetUserStepper(G4MagIntegratorStepper* stepper,
|
||||
const G4String& volumeName = "");
|
||||
|
||||
/// Get field parameters with the given volumeName.
|
||||
/// Return global field parameters, if volume name is empty.
|
||||
G4FieldParameters* GetFieldParameters(const G4String& volumeName = "") const;
|
||||
/**
|
||||
* Sets the verbosity level.
|
||||
*/
|
||||
void SetVerboseLevel(G4int value);
|
||||
|
||||
private:
|
||||
/// Default constructor
|
||||
G4FieldBuilder();
|
||||
/// Not implemented
|
||||
G4FieldBuilder(const G4FieldBuilder& right) = delete;
|
||||
/// Not implemented
|
||||
G4FieldBuilder& operator=(const G4FieldBuilder& right) = delete;
|
||||
// Get methods
|
||||
|
||||
// Methods
|
||||
/**
|
||||
* Gets a pointer to the field parameters with the given 'volumeName'.
|
||||
* Return global field parameters, if volume name is empty.
|
||||
*/
|
||||
G4FieldParameters* GetFieldParameters(const G4String& volumeName = "") const;
|
||||
|
||||
/// Get field parameters with the given volumeName or create them if they
|
||||
/// do not exist yet
|
||||
G4FieldParameters* GetOrCreateFieldParameters(const G4String& volumeName);
|
||||
private:
|
||||
|
||||
/// Get field setup with the given logical volume
|
||||
G4FieldSetup* GetFieldSetup(G4LogicalVolume* lv);
|
||||
/**
|
||||
* Private constructor.
|
||||
*/
|
||||
G4FieldBuilder();
|
||||
|
||||
/// Create magnetic, electromagnetic or gravity field setup
|
||||
void CreateFieldSetup(G4Field* field,
|
||||
G4FieldParameters* fieldParameters, G4LogicalVolume* lv);
|
||||
/**
|
||||
* Gets the pointer to field parameters with the given 'volumeName'
|
||||
* or creates them if they do not exist yet.
|
||||
*/
|
||||
G4FieldParameters* GetOrCreateFieldParameters(const G4String& volumeName);
|
||||
|
||||
/// Construct Geant4 global magnetic field setup
|
||||
void ConstructGlobalField();
|
||||
/**
|
||||
* Gets the pointer to the field setup with the given logical volume.
|
||||
*/
|
||||
G4FieldSetup* GetFieldSetup(G4LogicalVolume* lv);
|
||||
|
||||
/// Construct Geant4 local magnetic field setups from the local fields map
|
||||
void ConstructLocalFields();
|
||||
/**
|
||||
* Creates magnetic, electromagnetic or gravity field setup.
|
||||
*/
|
||||
void CreateFieldSetup(G4Field* field, G4FieldParameters* fieldParameters,
|
||||
G4LogicalVolume* lv);
|
||||
|
||||
/// Update all field setups
|
||||
void UpdateFieldSetups();
|
||||
/**
|
||||
* Constructs global magnetic field setup.
|
||||
*/
|
||||
void ConstructGlobalField();
|
||||
|
||||
// helper methods
|
||||
std::vector<G4FieldSetup*>& GetFieldSetups();
|
||||
std::vector<std::pair<G4LogicalVolume*, G4Field*>>& GetLocalFields();
|
||||
/**
|
||||
* Constructs local magnetic field setups from the local fields map.
|
||||
*/
|
||||
void ConstructLocalFields();
|
||||
|
||||
// Data members
|
||||
/**
|
||||
* Updates all field setups.
|
||||
*/
|
||||
void UpdateFieldSetups();
|
||||
|
||||
/// Information if an instance exists
|
||||
inline static G4ThreadLocal G4bool fgIsInstance { false };
|
||||
/**
|
||||
* Helper methods.
|
||||
*/
|
||||
inline std::vector<G4FieldSetup*>& GetFieldSetups();
|
||||
inline std::vector<std::pair<G4LogicalVolume*, G4Field*>>& GetLocalFields();
|
||||
|
||||
/// Messenger for this class
|
||||
G4FieldBuilderMessenger* fMessenger = nullptr;
|
||||
private: // Data members
|
||||
|
||||
/// Field parameters
|
||||
std::vector<G4FieldParameters*> fFieldParameters;
|
||||
/** Information if an instance exists. */
|
||||
inline static G4ThreadLocal G4bool fgIsInstance { false };
|
||||
|
||||
/// Field setups
|
||||
G4Cache<std::vector<G4FieldSetup*>*> fFieldSetups;
|
||||
/** Messenger for this class. */
|
||||
G4FieldBuilderMessenger* fMessenger = nullptr;
|
||||
|
||||
/// Registered global field
|
||||
static G4ThreadLocal G4Field* fGlobalField;
|
||||
/** Field parameters. */
|
||||
std::vector<G4FieldParameters*> fFieldParameters;
|
||||
|
||||
/// Registered local fields
|
||||
G4Cache<std::vector<std::pair<G4LogicalVolume*, G4Field*>>*> fLocalFields;
|
||||
/** Field setups. */
|
||||
G4Cache<std::vector<G4FieldSetup*>*> fFieldSetups;
|
||||
|
||||
/// info if field objects were constructed
|
||||
static G4ThreadLocal G4bool fIsConstructed;
|
||||
/** Registered global field. */
|
||||
static G4ThreadLocal G4Field* fGlobalField;
|
||||
|
||||
/// verbose level
|
||||
G4int fVerboseLevel = 1;
|
||||
/** Registered local fields. */
|
||||
G4Cache<std::vector<std::pair<G4LogicalVolume*, G4Field*>>*> fLocalFields;
|
||||
|
||||
/** Info if field objects were constructed. */
|
||||
static G4ThreadLocal G4bool fIsConstructed;
|
||||
|
||||
/** Verbose level. */
|
||||
G4int fVerboseLevel = 1;
|
||||
};
|
||||
|
||||
// inline methods
|
||||
|
||||
inline G4bool G4FieldBuilder::IsInstance()
|
||||
{
|
||||
// Return the information if an instance exists
|
||||
return fgIsInstance;
|
||||
}
|
||||
|
||||
inline void G4FieldBuilder::SetVerboseLevel(G4int value)
|
||||
{
|
||||
// Set verbose level
|
||||
fVerboseLevel = value;
|
||||
}
|
||||
// Inline methods -------------------------------------------------------------
|
||||
|
||||
inline std::vector<G4FieldSetup*>& G4FieldBuilder::GetFieldSetups()
|
||||
{
|
||||
@@ -240,4 +279,4 @@ inline std::vector<std::pair<G4LogicalVolume*, G4Field*>>& G4FieldBuilder::GetLo
|
||||
return *fLocalFields.Get();
|
||||
}
|
||||
|
||||
#endif // G4FIELDBUILDER_HH
|
||||
#endif
|
||||
|
||||
@@ -22,12 +22,15 @@
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4FieldBuilderMessenger
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// Messenger class that defines commands for G4FieldBuilder.
|
||||
|
||||
/// \file G4FieldBuilderMessenger.h
|
||||
/// \brief Definition of the G4FieldBuilderMessenger class
|
||||
///
|
||||
/// \author I. Hrivnacova; IJCLab, Orsay
|
||||
|
||||
// Author: Ivana Hrivnacova (IJCLab, Orsay), 2024
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4FIELDBUILDERMESSENGER_HH
|
||||
#define G4FIELDBUILDERMESSENGER_HH
|
||||
|
||||
@@ -41,44 +44,45 @@ class G4UIdirectory;
|
||||
class G4UIcmdWithoutParameter;
|
||||
class G4UIcmdWithAnInteger;
|
||||
|
||||
/// \ingroup geometry
|
||||
/// \brief Messenger class that defines commands for G4FieldBuilder
|
||||
///
|
||||
/// Implements commands:
|
||||
/// - /field/verboseLevel level
|
||||
///
|
||||
/// \author I. Hrivnacova; IJCLab, Orsay
|
||||
/**
|
||||
* @brief G4FieldBuilderMessenger is messenger class that defines
|
||||
* commands for G4FieldBuilder.
|
||||
*/
|
||||
|
||||
class G4FieldBuilderMessenger : public G4UImessenger
|
||||
{
|
||||
public:
|
||||
/// Standard constructor
|
||||
G4FieldBuilderMessenger(G4FieldBuilder* fieldBuilder);
|
||||
/// Destructor
|
||||
~G4FieldBuilderMessenger() override;
|
||||
public:
|
||||
|
||||
// methods
|
||||
/// Apply command to the associated object.
|
||||
void SetNewValue(G4UIcommand* command, G4String newValues) override;
|
||||
/**
|
||||
* Standard Constructor and Destructor.
|
||||
*/
|
||||
G4FieldBuilderMessenger(G4FieldBuilder* fieldBuilder);
|
||||
~G4FieldBuilderMessenger() override;
|
||||
|
||||
private:
|
||||
/// Not implemented
|
||||
G4FieldBuilderMessenger() = delete;
|
||||
/// Not implemented
|
||||
G4FieldBuilderMessenger(const G4FieldBuilderMessenger& right) = delete;
|
||||
/// Not implemented
|
||||
G4FieldBuilderMessenger& operator=(
|
||||
const G4FieldBuilderMessenger& right) = delete;
|
||||
/**
|
||||
* Default constructor, copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4FieldBuilderMessenger() = delete;
|
||||
G4FieldBuilderMessenger(const G4FieldBuilderMessenger&) = delete;
|
||||
G4FieldBuilderMessenger& operator=(const G4FieldBuilderMessenger&) = delete;
|
||||
|
||||
// \data members
|
||||
G4FieldBuilder* fFieldBuilder = nullptr; ///< associated class
|
||||
G4UIdirectory* fDirectory = nullptr; ///< command directory
|
||||
/**
|
||||
* Applies command to the associated object.
|
||||
*/
|
||||
void SetNewValue(G4UIcommand* command, G4String newValues) override;
|
||||
|
||||
//
|
||||
// commands data members
|
||||
private:
|
||||
|
||||
/// command: fieldType
|
||||
G4UIcmdWithAnInteger* fVerboseLevelCmd = nullptr;
|
||||
/** Associated class object. */
|
||||
G4FieldBuilder* fFieldBuilder = nullptr;
|
||||
|
||||
/** Associated commands directory. */
|
||||
G4UIdirectory* fDirectory = nullptr;
|
||||
|
||||
// Commands data members
|
||||
|
||||
/** Command: fieldType. */
|
||||
G4UIcmdWithAnInteger* fVerboseLevelCmd = nullptr;
|
||||
};
|
||||
|
||||
#endif // G4FIELDBUILDERMESSENGER_HH
|
||||
#endif
|
||||
|
||||
@@ -50,8 +50,8 @@
|
||||
// exists and what that object is.
|
||||
//
|
||||
// The Chord Finder must be created either by calling CreateChordFinder
|
||||
// for a Magnetic Field or by the user creating a a Chord Finder object
|
||||
// "manually" and setting this pointer.
|
||||
// for a Magnetic Field or by the user creating a Chord Finder object
|
||||
// "manually" and setting the pointer.
|
||||
//
|
||||
// A default FieldManager is created by the singleton class
|
||||
// G4NavigatorForTracking and exists before main is called.
|
||||
@@ -69,11 +69,12 @@
|
||||
// Similarly it could be extended to treat other fields as additional
|
||||
// components of a single field type.
|
||||
|
||||
// Author: John Apostolakis, 10.03.97 - design and implementation
|
||||
// Author: John Apostolakis (CERN), 10.03.1997 - Design and implementation
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4FIELDMANAGER_HH
|
||||
#define G4FIELDMANAGER_HH 1
|
||||
#define G4FIELDMANAGER_HH
|
||||
|
||||
#include "G4FieldParameters.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
class G4Field;
|
||||
@@ -81,165 +82,243 @@ class G4MagneticField;
|
||||
class G4ChordFinder;
|
||||
class G4Track; // Forward reference for parameter configuration
|
||||
|
||||
/**
|
||||
* @brief G4FieldManager is a manager (store) for a pointer to the Field
|
||||
* subclass that describes the field of a detector (magnetic, electric or
|
||||
* other). It also stores a reference to the chord finder.
|
||||
* A field manager can be set to a logical volume (or to more than one),
|
||||
* in order to vary its field from that of the world volume. In this manner
|
||||
* a zero or constant field can override a global field, a more or less exact
|
||||
* version can override the external approximation, lower or higher precision
|
||||
* for tracking can be specified, a different stepper can be chosen for
|
||||
* different volumes, etc...
|
||||
* The Chord Finder must be created either by calling CreateChordFinder()
|
||||
* for a Magnetic Field or by the user creating a Chord Finder object
|
||||
* "manually" and setting the pointer.
|
||||
* The current design envisions that one Field manager is valid for each
|
||||
* detector region. It is expected that a particular geometrical region has
|
||||
* a Field manager. By default a Field Manager is created for the world volume,
|
||||
* and will be utilised for all volumes unless it is overridden by a 'local'
|
||||
* field manager.
|
||||
* Note also that a region with both electric E and magnetic B field will
|
||||
* have these treated as one field. Similarly it could be extended to treat
|
||||
* other fields as additional components of a single field type.
|
||||
*/
|
||||
|
||||
class G4FieldManager
|
||||
{
|
||||
public: // with description
|
||||
public:
|
||||
|
||||
/**
|
||||
* General Constructor for any field. Must be set with field and chord finder
|
||||
* for use.
|
||||
* @param[in] detectorField Pointer to the field.
|
||||
* @param[in] pChordFinder Pointer to the chord finder object.
|
||||
* @param[in] b Flag to indicate if the field changes the energy; it is
|
||||
* taken from the provided field, if specified.
|
||||
*/
|
||||
G4FieldManager(G4Field* detectorField = nullptr,
|
||||
G4ChordFinder* pChordFinder = nullptr,
|
||||
G4bool b = true ); // fieldChangesEnergy is taken from field
|
||||
// General constructor for any field.
|
||||
// -> Must be set with field and chordfinder for use.
|
||||
G4FieldManager(G4MagneticField* detectorMagneticField);
|
||||
// Creates ChordFinder
|
||||
// -> Assumes pure magnetic field (so energy constant)
|
||||
|
||||
/**
|
||||
* Constructor creating the chord finder. It assumes pure magnetic field,
|
||||
* so energy constant.
|
||||
* @param[in] detectorMagneticField Pointer to the magnetic field.
|
||||
*/
|
||||
G4FieldManager(G4MagneticField* detectorMagneticField);
|
||||
|
||||
/**
|
||||
* Virtual Destructor.
|
||||
*/
|
||||
virtual ~G4FieldManager();
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4FieldManager(const G4FieldManager&) = delete;
|
||||
G4FieldManager& operator=(const G4FieldManager&) = delete;
|
||||
|
||||
/**
|
||||
* Pushes the field to the equation. Failure to push the field (due to
|
||||
* absence of a chord finder, driver, stepper or equation) is
|
||||
* - '0' = quiet : Do not complain if chordFinder == 0
|
||||
* (It will still warn for other error);
|
||||
* - '1' = warn : a warning if anything is missing;
|
||||
* - '2'/else = FATAL : a fatal error for all other values.
|
||||
* @param[in] detectorField Pointer to the field.
|
||||
* @param[in] failMode Flag (0/1/2) for selected failure mode.
|
||||
* @returns Success (true) or failure (false).
|
||||
*/
|
||||
G4bool SetDetectorField(G4Field* detectorField, G4int failMode = 0);
|
||||
// Pushes the field to the equation.
|
||||
// Failure to push the field (due to absence of a chord finder, driver,
|
||||
// stepper or equation) is
|
||||
// - '0' = quiet : Do not complain if chordFinder == 0
|
||||
// (It will still warn for other error.)
|
||||
// - '1' = warn : a warning if anything is missing
|
||||
// - '2'/else = FATAL : a fatal error for all other values.
|
||||
// Returns success (true) or failure (false)
|
||||
|
||||
/**
|
||||
* Pushes the field to this class only -- no further.
|
||||
* Should be used to initialise this field, only *before* creating
|
||||
* the chord finder and its dependent classes.
|
||||
* User is then responsible to ensure that:
|
||||
* i) an equation, stepper, driver and chord finder are created;
|
||||
* ii) this field is used by the equation.
|
||||
* @param[in] detectorField Pointer to the field.
|
||||
*/
|
||||
inline void ProposeDetectorField(G4Field* detectorField);
|
||||
// Pushes the field to this class only -- no further.
|
||||
// Should be used to initialise this field, only *before* creating
|
||||
// the chord finder and its dependent classes.
|
||||
// User is then responsible to ensure that:
|
||||
// i) an equation, stepper, driver and chord finder are created
|
||||
// ii) this field is used by the equation.
|
||||
|
||||
inline void ChangeDetectorField(G4Field* detectorField);
|
||||
// Pushes the field to the equation ( & keeps its address )
|
||||
// Can be used only once the equation, stepper, driver and chord finder
|
||||
// have all been created. Else it is an error.
|
||||
/**
|
||||
* Pushes the field to the equation and keeps its address.
|
||||
* Can be used only once the equation, stepper, driver and chord finder
|
||||
* have all been created; else it is an error.
|
||||
* @param[in] detectorField Pointer to the field.
|
||||
*/
|
||||
inline void ChangeDetectorField(G4Field* detectorField);
|
||||
|
||||
inline const G4Field* GetDetectorField() const;
|
||||
inline G4bool DoesFieldExist() const;
|
||||
// Set, get and check the field object
|
||||
/**
|
||||
* Methods to get and check (existance of) the field object.
|
||||
*/
|
||||
inline const G4Field* GetDetectorField() const;
|
||||
inline G4bool DoesFieldExist() const;
|
||||
|
||||
/**
|
||||
* Methods to create, set or get the associated Chord Finder.
|
||||
*/
|
||||
void CreateChordFinder(G4MagneticField* detectorMagField);
|
||||
inline void SetChordFinder(G4ChordFinder* aChordFinder);
|
||||
inline G4ChordFinder* GetChordFinder();
|
||||
inline const G4ChordFinder* GetChordFinder() const;
|
||||
// Create, set or get the associated Chord Finder
|
||||
|
||||
virtual void ConfigureForTrack( const G4Track * );
|
||||
// Setup the choice of the configurable parameters
|
||||
// relying on the current track's energy, particle identity, ..
|
||||
// Note: in addition to the values of member variables,
|
||||
// a user can use this to change the ChordFinder, the field, ...
|
||||
/**
|
||||
* Setups the choice of the configurable parameters, relying on the
|
||||
* current track's energy, particle identity...
|
||||
* Note: in addition to the values of member variables, a user can use
|
||||
* this to change the ChordFinder, the field, etc.
|
||||
* @param[in] pTrack Pointer to a track.
|
||||
*/
|
||||
virtual void ConfigureForTrack( const G4Track* pTrack );
|
||||
|
||||
// static functions to handle global field
|
||||
/**
|
||||
* Static methods to set/get the global field.
|
||||
*/
|
||||
static void SetGlobalFieldManager(G4FieldManager* fieldManager);
|
||||
static G4FieldManager* GetGlobalFieldManager();
|
||||
|
||||
public: // with description
|
||||
|
||||
/**
|
||||
* Returns the accuracy for boundary intersection.
|
||||
*/
|
||||
inline G4double GetDeltaIntersection() const;
|
||||
// Accuracy for boundary intersection.
|
||||
|
||||
/**
|
||||
* Returns the accuracy for one tracking/physics step.
|
||||
*/
|
||||
inline G4double GetDeltaOneStep() const;
|
||||
// Accuracy for one tracking/physics step.
|
||||
|
||||
/**
|
||||
* Sets both accuracies, maintaining a fixed ratio for accuracies
|
||||
* of volume Intersection and Integration (in One Step).
|
||||
*/
|
||||
inline void SetAccuraciesWithDeltaOneStep(G4double valDeltaOneStep);
|
||||
// Sets both accuracies, maintaining a fixed ratio for accuracies
|
||||
// of volume Intersection and Integration (in One Step)
|
||||
|
||||
inline void SetDeltaOneStep(G4double valueD1step);
|
||||
// Set accuracy for integration of one step. (only)
|
||||
/**
|
||||
* Sets the accuracy for integration of one step (only).
|
||||
*/
|
||||
inline void SetDeltaOneStep(G4double valueD1step);
|
||||
|
||||
/**
|
||||
* Sets the accuracy of intersection of a volume (only).
|
||||
*/
|
||||
inline void SetDeltaIntersection(G4double valueDintersection);
|
||||
// Set accuracy of intersection of a volume. (only)
|
||||
|
||||
inline G4double GetMinimumEpsilonStep() const;
|
||||
G4bool SetMinimumEpsilonStep( G4double newEpsMin );
|
||||
// Minimum for Relative accuracy of a Step
|
||||
/**
|
||||
* Methods to set/get the minimum for Relative accuracy of a Step.
|
||||
*/
|
||||
inline G4double GetMinimumEpsilonStep() const;
|
||||
G4bool SetMinimumEpsilonStep( G4double newEpsMin );
|
||||
|
||||
inline G4double GetMaximumEpsilonStep() const;
|
||||
G4bool SetMaximumEpsilonStep( G4double newEpsMax );
|
||||
// Maximum for Relative accuracy of a Step
|
||||
/**
|
||||
* Methods to set/get the maximum for Relative accuracy of a Step.
|
||||
*/
|
||||
inline G4double GetMaximumEpsilonStep() const;
|
||||
G4bool SetMaximumEpsilonStep( G4double newEpsMax );
|
||||
|
||||
inline G4bool DoesFieldChangeEnergy() const;
|
||||
inline void SetFieldChangesEnergy(G4bool value);
|
||||
// For electric field this should be true
|
||||
// For magnetic field this should be false
|
||||
/**
|
||||
* Methods to set/get flag for field changing energy.
|
||||
* For electric field this should be true; for magnetic field this
|
||||
* should be false.
|
||||
*/
|
||||
inline G4bool DoesFieldChangeEnergy() const;
|
||||
inline void SetFieldChangesEnergy(G4bool value);
|
||||
|
||||
/**
|
||||
* Needed for multi-threading, create and returns an allocated clone
|
||||
* of this object.
|
||||
*/
|
||||
virtual G4FieldManager* Clone() const;
|
||||
// Needed for multi-threading, create a clone of this object
|
||||
|
||||
public:
|
||||
/**
|
||||
* Static methods to set/get the maximum accepted epsilon.
|
||||
* If setting fails, with softFail=true it gives Warning, else
|
||||
* a FatalException.
|
||||
*/
|
||||
static G4double GetMaxAcceptedEpsilon();
|
||||
static G4bool SetMaxAcceptedEpsilon(G4double maxEps, G4bool softFail= false);
|
||||
// Set value -- within limits.
|
||||
// If it fails, with softFail=true it gives Warning, else FatalException
|
||||
static G4bool SetMaxAcceptedEpsilon(G4double maxEps, G4bool softFail= false);
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Logger for reporting on correctness of the proposed epsilon value.
|
||||
*/
|
||||
void ReportBadEpsilonValue(G4ExceptionDescription& erm, G4double value,
|
||||
const G4String& name) const;
|
||||
|
||||
/** Epsilon_min/max values must be smaller than this for robust integration. */
|
||||
static G4double fMaxAcceptedEpsilon;
|
||||
static constexpr G4double fMinAcceptedEpsilon= 1000.0 * std::numeric_limits<G4double>::epsilon();
|
||||
// Epsilon_min/max values must be smaller than this - for robust integration
|
||||
static constexpr G4double fMinAcceptedEpsilon = 1000.0 * std::numeric_limits<G4double>::epsilon();
|
||||
|
||||
static constexpr G4double fMaxWarningEpsilon= 0.001; // Setting larger value will give warning.
|
||||
static constexpr G4double fMaxFinalEpsilon= 0.02; // Will not accept larger values
|
||||
/** Setting larger value will give warning. */
|
||||
static constexpr G4double fMaxWarningEpsilon = 0.001;
|
||||
|
||||
/** Will not accept larger values. */
|
||||
static constexpr G4double fMaxFinalEpsilon = 0.02;
|
||||
|
||||
static G4bool fVerboseConstruction;
|
||||
// Control verbosity of constructors
|
||||
|
||||
/** Controls verbosity of constructors. */
|
||||
static G4bool fVerboseConstruction;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Checks whether the field/equation changes the energy and sets the data
|
||||
* member accordingly. Does not handle special cases - this must be done
|
||||
* separately (e.g. magnetic monopole in B field).
|
||||
*/
|
||||
void InitialiseFieldChangesEnergy();
|
||||
// Check whether field/equation change the energy,
|
||||
// and sets the data member accordingly
|
||||
// Note: does not handle special cases - this must be done
|
||||
// separately (e.g. magnetic monopole in B field )
|
||||
|
||||
protected:
|
||||
void ReportBadEpsilonValue(G4ExceptionDescription& erm, G4double value,
|
||||
G4String& name) const;
|
||||
|
||||
private:
|
||||
|
||||
/** Dependent objects -- with state that depends on tracking. */
|
||||
G4Field* fDetectorField = nullptr;
|
||||
G4ChordFinder* fChordFinder = nullptr;
|
||||
// Dependent objects -- with state that depends on tracking
|
||||
|
||||
G4bool fAllocatedChordFinder = false; // Did we used "new" to
|
||||
// create fChordFinder ?
|
||||
// INVARIANTS of tracking ---------------------------------------
|
||||
//
|
||||
// 1. 'CONSTANTS' - default values for accuracy parameters
|
||||
//
|
||||
const G4double fEpsilonMinDefault= 5.0e-5; // Expected: 5.0e-5 to 1.0e-10 ...
|
||||
const G4double fEpsilonMaxDefault= 1.0e-3; // Expected: 1.0e-3 to 1.0e-8 ...
|
||||
/** Flag to indicate if "new" was used to create the Chord Finder. */
|
||||
G4bool fAllocatedChordFinder = false; //
|
||||
|
||||
static G4double fDefault_Delta_One_Step_Value; // = 0.01 * millimeter;
|
||||
static G4double fDefault_Delta_Intersection_Val; // = 0.001 * millimeter;
|
||||
// Default values for accuracy parameters
|
||||
// 1. CHARACTERISTIC of field
|
||||
|
||||
// 2. CHARACTERISTIC of field
|
||||
//
|
||||
G4bool fFieldChangesEnergy = false;
|
||||
|
||||
// 3. PARAMETERS that determine the accuracy of integration or intersection
|
||||
//
|
||||
G4double fDelta_One_Step_Value; // for one tracking/physics step
|
||||
G4double fDelta_Intersection_Val; // for boundary intersection
|
||||
// Values for the required accuracies
|
||||
// 2. PARAMETERS that determine the accuracy of integration or intersection
|
||||
|
||||
G4double fEpsilonMin;
|
||||
G4double fEpsilonMax;
|
||||
// Values for the small possible relative accuracy of a step
|
||||
// (corresponding to the greatest possible integration accuracy)
|
||||
/** Value for the required accuracies for one tracking/physics step. */
|
||||
G4double fDelta_One_Step_Value = G4FieldDefaults::kDeltaOneStep;
|
||||
|
||||
/** Value for the required accuracies for boundary intersection. */
|
||||
G4double fDelta_Intersection_Val = G4FieldDefaults::kDeltaIntersection;
|
||||
|
||||
/** Values for the small possible relative accuracy of a step
|
||||
(corresponding to the greatest possible integration accuracy). */
|
||||
G4double fEpsilonMin = G4FieldDefaults::kMinimumEpsilonStep;
|
||||
G4double fEpsilonMax = G4FieldDefaults::kMaximumEpsilonStep;
|
||||
|
||||
/** Global field manager set by G4TransportationManager to allow accessing
|
||||
the global field without dependency on navigation. */
|
||||
static G4ThreadLocal G4FieldManager* fGlobalFieldManager;
|
||||
// Global field manager set by G4TransportationManager
|
||||
// to allow accessing the global field without dependency
|
||||
// on navigation
|
||||
};
|
||||
|
||||
// Implementation of inline functions
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
//
|
||||
// G4FieldManager inline implementation
|
||||
//
|
||||
// Author: John Apostolakis, 10.03.97 - design and implementation
|
||||
// Author: John Apostolakis (CERN), 10.03.1997 - Design and implementation
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
inline
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
// Intended principally to enable resetting of 'state' at start of event.
|
||||
// The underlying container initially has a capacity of 100.
|
||||
|
||||
// Author: J.Apostolakis, 07.12.2007 - Initial version
|
||||
// Author: John Apostolakis (CERN), 07.12.2007 - Initial version
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4FIELDMANAGERSTORE_HH
|
||||
#define G4FIELDMANAGERSTORE_HH
|
||||
@@ -46,29 +46,55 @@
|
||||
|
||||
#include "G4FieldManager.hh"
|
||||
|
||||
/**
|
||||
* @brief G4FieldManagerStore is a container for all field managers, with
|
||||
* functionality derived from std::vector<T>. The class is a singleton.
|
||||
* All field managers should be registered with G4FieldManagerStore,
|
||||
* and removed on their destruction. Intended principally to enable resetting
|
||||
* of 'state' at start of an event.
|
||||
*/
|
||||
|
||||
class G4FieldManagerStore : public std::vector<G4FieldManager*>
|
||||
{
|
||||
public: // with description
|
||||
public:
|
||||
|
||||
static void Register(G4FieldManager* pVolume);
|
||||
// Add the logical volume to the collection.
|
||||
static void DeRegister(G4FieldManager* pVolume);
|
||||
// Remove the logical volume from the collection.
|
||||
/**
|
||||
* Gets a pointer to the unique G4FieldManagerStore, creating it if
|
||||
* necessary.
|
||||
*/
|
||||
static G4FieldManagerStore* GetInstance();
|
||||
// Get a ptr to the unique G4FieldManagerStore, creating it if necessary.
|
||||
static G4FieldManagerStore* GetInstanceIfExist();
|
||||
// Get a ptr to the unique G4FieldManagerStore.
|
||||
|
||||
/**
|
||||
* Adds the field manager to the collection.
|
||||
*/
|
||||
static void Register(G4FieldManager* pFieldMan);
|
||||
|
||||
/**
|
||||
* Removes the field manager from the collection.
|
||||
*/
|
||||
static void DeRegister(G4FieldManager* pFieldMan);
|
||||
|
||||
/**
|
||||
* Deletes all managers from the store.
|
||||
*/
|
||||
static void Clean();
|
||||
// Delete all volumes from the store.
|
||||
|
||||
/**
|
||||
* Loops over all field managers and calls each one to reset step estimate.
|
||||
*/
|
||||
void ClearAllChordFindersState();
|
||||
// Looping over all field managers, call each one to reset step estimate
|
||||
|
||||
/**
|
||||
* Destructor: takes care to delete the allocated field managers.
|
||||
*/
|
||||
~G4FieldManagerStore();
|
||||
// Destructor: takes care to delete allocated field managers.
|
||||
|
||||
protected:
|
||||
private:
|
||||
|
||||
/**
|
||||
* Private constructor.
|
||||
*/
|
||||
G4FieldManagerStore();
|
||||
|
||||
private:
|
||||
|
||||
@@ -22,39 +22,47 @@
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4FieldParameters
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// The class defines the type of equation of motion of a particle
|
||||
// in a field and the integration method, as well as other accuracy
|
||||
// parameters.
|
||||
//
|
||||
// The default values correspond to the defaults set in Geant4.
|
||||
|
||||
/// \file G4FieldParameters.hh
|
||||
/// \brief Definition of the G4FieldParameters class
|
||||
///
|
||||
/// This code was initially developed in Geant4 VMC package
|
||||
/// (https://github.com/vmc-project)
|
||||
/// and adapted to Geant4.
|
||||
///
|
||||
/// \author I. Hrivnacova; IJCLab, Orsay
|
||||
|
||||
// Author: Ivana Hrivnacova (IJCLab, Orsay), 2024.
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4FIELDPARAMETERS_HH
|
||||
#define G4FIELDPARAMETERS_HH
|
||||
|
||||
#include "G4MagneticField.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
#include <CLHEP/Units/SystemOfUnits.h>
|
||||
|
||||
class G4FieldParametersMessenger;
|
||||
|
||||
class G4EquationOfMotion;
|
||||
class G4MagIntegratorStepper;
|
||||
|
||||
/// The available fields in Geant4
|
||||
/**
|
||||
* @brief G4FieldType defines the available fields in Geant4.
|
||||
*/
|
||||
|
||||
enum G4FieldType
|
||||
{
|
||||
kMagnetic, ///< magnetic field
|
||||
kElectroMagnetic, ///< electromagnetic field
|
||||
kGravity ///< gravity field
|
||||
kMagnetic, ///< magnetic field
|
||||
kElectroMagnetic, ///< electromagnetic field
|
||||
kGravity, ///< gravity field
|
||||
kUserFieldType ///< User defined field type
|
||||
};
|
||||
|
||||
/// The available equations of motion of a particle in a field
|
||||
/// in Geant4
|
||||
/**
|
||||
* @brief G4EquationType defines the types of equations of motion of a
|
||||
* particle in a field in Geant4.
|
||||
*/
|
||||
|
||||
enum G4EquationType
|
||||
{
|
||||
kEqMagnetic, ///< G4Mag_UsualEqRhs: the standard right-hand side for
|
||||
@@ -70,11 +78,22 @@ enum G4EquationType
|
||||
kEqEMfieldWithEDM, ///< G4EqEMFieldWithEDM: Equation of motion in a combined
|
||||
///< electric and magnetic field, with spin tracking for
|
||||
///< both MDM and EDM terms
|
||||
kEqGravity, ///< G4EqGravityField: equation of motion in a gravity field
|
||||
/// (not build by G4FieldBuilder)
|
||||
kEqMonopole, ///< G4MonopoleEq: the right-hand side of equation of motion for monopole
|
||||
/// in a combined electric and magnetic field
|
||||
/// (not build by G4FieldBuilder)
|
||||
kEqReplate, ///< G4RepleteEofM: equation of motion in a combined field, including:
|
||||
/// magnetic, electric, gravity, and gradient B field, as well as spin tracking
|
||||
/// (not build by G4FieldBuilder)
|
||||
kUserEquation ///< User defined equation of motion
|
||||
};
|
||||
|
||||
/// The available integrator of particle's equation of motion
|
||||
/// in Geant4
|
||||
/**
|
||||
* @brief G4StepperType defines the available integrator of particle's
|
||||
* equation of motion in Geant4.
|
||||
*/
|
||||
|
||||
enum G4StepperType
|
||||
{
|
||||
// steppers with equation of motion of generic type (G4EquationOfMotion)
|
||||
@@ -82,6 +101,7 @@ enum G4StepperType
|
||||
kClassicalRK4, ///< G4ClassicalRK4
|
||||
kBogackiShampine23, ///< G4BogackiShampine23
|
||||
kBogackiShampine45, ///< G4BogackiShampine45
|
||||
kDoLoMcPriRK34, ///< G4DoLoMcPriRK34
|
||||
kDormandPrince745, ///< G4DormandPrince745
|
||||
kDormandPrinceRK56, ///< G4DormandPrinceRK56
|
||||
kDormandPrinceRK78, ///< G4DormandPrinceRK78
|
||||
@@ -104,310 +124,281 @@ enum G4StepperType
|
||||
kUserStepper, ///< User defined stepper
|
||||
|
||||
// FSAL steppers
|
||||
kRK547FEq1, ///< G4RK547FEq1
|
||||
kRK547FEq2, ///< G4RK547FEq2
|
||||
kRK547FEq3 ///< G4RK547FEq3
|
||||
kRK547FEq1, ///< G4RK547FEq1
|
||||
kRK547FEq2, ///< G4RK547FEq2
|
||||
kRK547FEq3, ///< G4RK547FEq3
|
||||
|
||||
// Templated steppers (not build by G4FieldBuilder)
|
||||
kTCashKarpRKF45, ///< G4TCashKarpRKF45
|
||||
kTDormandPrince45, ///< G4TDormandPrince45
|
||||
kTMagErrorStepper, ///< G4TMagErrorStepper
|
||||
kQSStepper ///< G4QSStepper
|
||||
};
|
||||
|
||||
/// \brief The magnetic field parameters
|
||||
///
|
||||
/// The class defines the type of equation of motion of a particle
|
||||
/// in a field and the integration method, as well as other accuracy
|
||||
/// parameters.
|
||||
///
|
||||
/// The default values correspond to the defaults set in Geant4
|
||||
/// (taken from Geant4 9.3 release.)
|
||||
/// As Geant4 classes to not provide access methods for these defaults,
|
||||
/// the defaults have to be checked with each new Geant4 release.
|
||||
///
|
||||
/// \author I. Hrivnacova; IJCLab, Orsay
|
||||
/**
|
||||
* @brief G4FieldDefaults defines the magnetic field parameters defaults.
|
||||
* The namespace defines the default values of the field paraments as constexpr
|
||||
* so that they can be used also as the default values in the magnetic field
|
||||
* classes constructors and other member functions.
|
||||
*/
|
||||
|
||||
namespace G4FieldDefaults
|
||||
{
|
||||
/// Default minimum step in G4ChordFinder
|
||||
constexpr G4double kMinimumStep = 0.01 * CLHEP::mm;
|
||||
/// Default delta chord in G4ChordFinder
|
||||
constexpr G4double kDeltaChord = 0.25 * CLHEP::mm;
|
||||
/// Default delta one step in global field manager
|
||||
constexpr G4double kDeltaOneStep = 0.01 * CLHEP::mm;
|
||||
/// Delta intersection in global field manager
|
||||
constexpr G4double kDeltaIntersection = 0.001 * CLHEP::mm;
|
||||
/// Default minimum epsilon step in global field manager
|
||||
constexpr G4double kMinimumEpsilonStep = 5.0e-5; // Expected: 5.0e-5 to 1.0e-10 ...
|
||||
/// Default maximum epsilon step in global field manager
|
||||
constexpr G4double kMaximumEpsilonStep = 0.001; // Expected: 1.0e-3 to 1.0e-8 ...
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief G4FieldParameters defines the type of equation of motion of a
|
||||
* particle in a field and the integration method, as well as other accuracy
|
||||
* parameters. The default values correspond to the defaults set in Geant4.
|
||||
*/
|
||||
|
||||
class G4FieldParameters
|
||||
{
|
||||
public:
|
||||
/// Standard and default constructor
|
||||
G4FieldParameters(const G4String& volumeName = "");
|
||||
/// Destructor
|
||||
~G4FieldParameters();
|
||||
public:
|
||||
|
||||
// Methods
|
||||
//
|
||||
/**
|
||||
* Constructor for G4FieldParameters.
|
||||
* @param[in] volumeName The volume name where field is applied.
|
||||
*/
|
||||
G4FieldParameters(const G4String& volumeName = "");
|
||||
|
||||
/// Return the field type as a string
|
||||
static G4String FieldTypeName(G4FieldType field);
|
||||
/// Return the equation type as a string
|
||||
static G4String EquationTypeName(G4EquationType equation);
|
||||
/// Return the stepper type as a string
|
||||
static G4String StepperTypeName(G4StepperType stepper);
|
||||
/// Return the field type for given field type name
|
||||
static G4FieldType GetFieldType(const G4String& name);
|
||||
/// Return the equation type for given equation type name
|
||||
static G4EquationType GetEquationType(const G4String& name);
|
||||
/// Return the stepper type for given stepper type name
|
||||
static G4StepperType GetStepperType(const G4String& name);
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~G4FieldParameters();
|
||||
|
||||
/// Prints all customizable accuracy parameters
|
||||
void PrintParameters() const;
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4FieldParameters(const G4FieldParameters& right) = delete;
|
||||
G4FieldParameters& operator=(const G4FieldParameters& right) = delete;
|
||||
|
||||
// Set methods
|
||||
//
|
||||
/**
|
||||
* Returns the field type as a string.
|
||||
*/
|
||||
static G4String FieldTypeName(G4FieldType field);
|
||||
|
||||
/// Set type of field
|
||||
void SetFieldType(G4FieldType field);
|
||||
/// Set Type of equation of motion of a particle in a field
|
||||
void SetEquationType(G4EquationType equation);
|
||||
/// Type of integrator of particle's equation of motion
|
||||
void SetStepperType(G4StepperType stepper);
|
||||
/// Set user defined equation of motion
|
||||
void SetUserEquationOfMotion(G4EquationOfMotion* equation);
|
||||
/// Set user defined integrator of particle's equation of motion
|
||||
void SetUserStepper(G4MagIntegratorStepper* stepper);
|
||||
/**
|
||||
* Returns the equation type as a string.
|
||||
*/
|
||||
static G4String EquationTypeName(G4EquationType equation);
|
||||
|
||||
/// Set minimum step in G4ChordFinder
|
||||
void SetMinimumStep(G4double value);
|
||||
/// Set delta chord in G4ChordFinder
|
||||
void SetDeltaChord(G4double value);
|
||||
/// Set delta one step in global field manager
|
||||
void SetDeltaOneStep(G4double value);
|
||||
/// Set delta intersection in global field manager
|
||||
void SetDeltaIntersection(G4double value);
|
||||
/// Set minimum epsilon step in global field manager
|
||||
void SetMinimumEpsilonStep(G4double value);
|
||||
/// Set maximum epsilon step in global field manager
|
||||
void SetMaximumEpsilonStep(G4double value);
|
||||
/// Set the distance within which the field is considered constant
|
||||
void SetConstDistance(G4double value);
|
||||
/**
|
||||
* Returns the stepper type as a string.
|
||||
*/
|
||||
static G4String StepperTypeName(G4StepperType stepper);
|
||||
|
||||
// Get methods
|
||||
//
|
||||
/**
|
||||
* Returns the field type for given field type name.
|
||||
*/
|
||||
static G4FieldType GetFieldType(const G4String& name);
|
||||
|
||||
// Get the name of associated volume, if local field
|
||||
G4String GetVolumeName() const;
|
||||
/**
|
||||
* Returns the equation type for given equation type name.
|
||||
*/
|
||||
static G4EquationType GetEquationType(const G4String& name);
|
||||
|
||||
/// Get type of field
|
||||
G4FieldType GetFieldType() const;
|
||||
/// Get type of equation of motion of a particle in a field
|
||||
G4EquationType GetEquationType() const;
|
||||
/// Get rype of integrator of particle's equation of motion
|
||||
G4StepperType GetStepperType() const;
|
||||
/// Get user defined equation of motion
|
||||
G4EquationOfMotion* GetUserEquationOfMotion() const;
|
||||
/// Get user defined integrator of particle's equation of motion
|
||||
G4MagIntegratorStepper* GetUserStepper() const;
|
||||
/**
|
||||
* Returns the stepper type for given stepper type name.
|
||||
*/
|
||||
static G4StepperType GetStepperType(const G4String& name);
|
||||
|
||||
/// Get minimum step in G4ChordFinder
|
||||
G4double GetMinimumStep() const;
|
||||
/// Get delta chord in G4ChordFinder
|
||||
G4double GetDeltaChord() const;
|
||||
/// Get delta one step in global field manager
|
||||
G4double GetDeltaOneStep() const;
|
||||
/// Get delta intersection in global field manager
|
||||
G4double GetDeltaIntersection() const;
|
||||
/// Get minimum epsilon step in global field manager
|
||||
G4double GetMinimumEpsilonStep() const;
|
||||
/// Get maximum epsilon step in global field manager
|
||||
G4double GetMaximumEpsilonStep() const;
|
||||
/// Get the distance within which the field is considered constant
|
||||
G4double GetConstDistance() const;
|
||||
/**
|
||||
* Prints all customisable accuracy parameters.
|
||||
*/
|
||||
void PrintParameters() const;
|
||||
|
||||
private:
|
||||
/// Not implemented
|
||||
G4FieldParameters(const G4FieldParameters& right) = delete;
|
||||
/// Not implemented
|
||||
G4FieldParameters& operator=(const G4FieldParameters& right) = delete;
|
||||
// Set methods ------------------------------------------------------------
|
||||
|
||||
// static data members
|
||||
//
|
||||
/// Default minimum step in G4ChordFinder
|
||||
inline static const G4double fgkDefaultMinimumStep = 0.01 * CLHEP::mm;
|
||||
/// Default delta chord in G4ChordFinder
|
||||
inline static const G4double fgkDefaultDeltaChord = 0.25 * CLHEP::mm;
|
||||
/// Default delta one step in global field manager
|
||||
inline static const G4double fgkDefaultDeltaOneStep = 0.01 * CLHEP::mm;
|
||||
/// Delta intersection in global field manager
|
||||
inline static const G4double fgkDefaultDeltaIntersection = 0.001 * CLHEP::mm;
|
||||
/// Default minimum epsilon step in global field manager
|
||||
inline static const G4double fgkDefaultMinimumEpsilonStep = 5.0e-5;
|
||||
/// Default maximum epsilon step in global field manager
|
||||
inline static const G4double fgkDefaultMaximumEpsilonStep = 0.001;
|
||||
/// Default constant distance
|
||||
inline static const G4double fgkDefaultConstDistance = 0.;
|
||||
/**
|
||||
* Sets the type of field.
|
||||
*/
|
||||
void SetFieldType(G4FieldType field);
|
||||
|
||||
// data members
|
||||
//
|
||||
/// Messenger for this class
|
||||
G4FieldParametersMessenger* fMessenger = nullptr;
|
||||
/**
|
||||
* Sets the type of equation of motion of a particle in a field.
|
||||
*/
|
||||
void SetEquationType(G4EquationType equation);
|
||||
|
||||
/// The name of associated volume, if local field
|
||||
G4String fVolumeName;
|
||||
/**
|
||||
* Sets the type of integrator of particle's equation of motion.
|
||||
*/
|
||||
void SetStepperType(G4StepperType stepper);
|
||||
|
||||
/// Minimum step in G4ChordFinder
|
||||
G4double fMinimumStep = fgkDefaultMinimumStep;
|
||||
/// Delta chord in G4ChordFinder
|
||||
G4double fDeltaChord = fgkDefaultDeltaChord;
|
||||
/// Delta one step in global field manager
|
||||
G4double fDeltaOneStep = fgkDefaultDeltaOneStep;
|
||||
/// Delta intersection in global field manager
|
||||
G4double fDeltaIntersection = fgkDefaultDeltaIntersection;
|
||||
/// Minimum epsilon step in global field manager
|
||||
G4double fMinimumEpsilonStep = fgkDefaultMinimumEpsilonStep;
|
||||
/// Maximum epsilon step in global field manager
|
||||
G4double fMaximumEpsilonStep = fgkDefaultMaximumEpsilonStep;
|
||||
/**
|
||||
* Sets the user defined equation of motion.
|
||||
*/
|
||||
void SetUserEquationOfMotion(G4EquationOfMotion* equation);
|
||||
|
||||
/// Type of field
|
||||
G4FieldType fField = kMagnetic;
|
||||
/**
|
||||
* Sets the user defined integrator of particle's equation of motion.
|
||||
*/
|
||||
void SetUserStepper(G4MagIntegratorStepper* stepper);
|
||||
|
||||
/// Type of equation of motion of a particle in a field
|
||||
G4EquationType fEquation = kEqMagnetic;
|
||||
/**
|
||||
* Sets the minimum step in G4ChordFinder.
|
||||
*/
|
||||
void SetMinimumStep(G4double value);
|
||||
|
||||
/// Type of integrator of particle's equation of motion
|
||||
G4StepperType fStepper = kDormandPrince745;
|
||||
/**
|
||||
* Sets the delta chord in G4ChordFinder.
|
||||
*/
|
||||
void SetDeltaChord(G4double value);
|
||||
|
||||
/// User defined equation of motion
|
||||
G4EquationOfMotion* fUserEquation = nullptr;
|
||||
/**
|
||||
* Sets the delta one step in global field manager.
|
||||
*/
|
||||
void SetDeltaOneStep(G4double value);
|
||||
|
||||
/// User defined integrator of particle's equation of motion
|
||||
G4MagIntegratorStepper* fUserStepper = nullptr;
|
||||
/**
|
||||
* Sets the delta intersection in global field manager.
|
||||
*/
|
||||
void SetDeltaIntersection(G4double value);
|
||||
|
||||
/// The distance within which the field is considered constant
|
||||
G4double fConstDistance = fgkDefaultConstDistance;
|
||||
/**
|
||||
* Sets the minimum epsilon step in global field manager.
|
||||
*/
|
||||
void SetMinimumEpsilonStep(G4double value);
|
||||
|
||||
/**
|
||||
* Sets the maximum epsilon step in global field manager.
|
||||
*/
|
||||
void SetMaximumEpsilonStep(G4double value);
|
||||
|
||||
/**
|
||||
* Sets the distance within which the field is considered constant.
|
||||
*/
|
||||
void SetConstDistance(G4double value);
|
||||
|
||||
// Get methods ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets the name of associated volume, if local field.
|
||||
*/
|
||||
const G4String& GetVolumeName() const;
|
||||
|
||||
/**
|
||||
* Gets the type of field.
|
||||
*/
|
||||
const G4FieldType& GetFieldType() const;
|
||||
|
||||
/**
|
||||
* Gets the type of equation of motion of a particle in a field.
|
||||
*/
|
||||
const G4EquationType& GetEquationType() const;
|
||||
|
||||
/**
|
||||
* Gets the type of integrator of particle's equation of motion.
|
||||
*/
|
||||
const G4StepperType& GetStepperType() const;
|
||||
|
||||
/**
|
||||
* Gets the user defined equation of motion.
|
||||
*/
|
||||
G4EquationOfMotion* GetUserEquationOfMotion() const;
|
||||
|
||||
/**
|
||||
* Gets the user defined integrator of particle's equation of motion.
|
||||
*/
|
||||
G4MagIntegratorStepper* GetUserStepper() const;
|
||||
|
||||
/**
|
||||
* Gets the minimum step in G4ChordFinder.
|
||||
*/
|
||||
G4double GetMinimumStep() const;
|
||||
|
||||
/**
|
||||
* Gets the delta chord in G4ChordFinder.
|
||||
*/
|
||||
G4double GetDeltaChord() const;
|
||||
|
||||
/**
|
||||
* Gets the delta one step in global field manager.
|
||||
*/
|
||||
G4double GetDeltaOneStep() const;
|
||||
|
||||
/**
|
||||
* Gets the delta intersection in global field manager.
|
||||
*/
|
||||
G4double GetDeltaIntersection() const;
|
||||
|
||||
/**
|
||||
* Gets the minimum epsilon step in global field manager.
|
||||
*/
|
||||
G4double GetMinimumEpsilonStep() const;
|
||||
|
||||
/**
|
||||
* Gets the maximum epsilon step in global field manager.
|
||||
*/
|
||||
G4double GetMaximumEpsilonStep() const;
|
||||
|
||||
/**
|
||||
* Gets the distance within which the field is considered constant.
|
||||
*/
|
||||
G4double GetConstDistance() const;
|
||||
|
||||
private:
|
||||
|
||||
/** Default constant distance. */
|
||||
inline static const G4double fgkDefaultConstDistance = 0.;
|
||||
|
||||
/** Messenger for this class. */
|
||||
G4FieldParametersMessenger* fMessenger = nullptr;
|
||||
|
||||
/** The name of the associated volume, if local field. */
|
||||
G4String fVolumeName;
|
||||
|
||||
/** The minimum step in G4ChordFinder. */
|
||||
G4double fMinimumStep = G4FieldDefaults::kMinimumStep;
|
||||
|
||||
/** The delta chord in G4ChordFinder. */
|
||||
G4double fDeltaChord = G4FieldDefaults::kDeltaChord;
|
||||
|
||||
/** The delta one step in global field manager. */
|
||||
G4double fDeltaOneStep = G4FieldDefaults::kDeltaOneStep;
|
||||
|
||||
/** The delta intersection in global field manager. */
|
||||
G4double fDeltaIntersection = G4FieldDefaults::kDeltaIntersection;
|
||||
|
||||
/** The minimum epsilon step in global field manager. */
|
||||
G4double fMinimumEpsilonStep = G4FieldDefaults::kMinimumEpsilonStep;
|
||||
|
||||
/** The maximum epsilon step in global field manager. */
|
||||
G4double fMaximumEpsilonStep = G4FieldDefaults::kMaximumEpsilonStep;
|
||||
|
||||
/** The type of field. */
|
||||
G4FieldType fField = kMagnetic;
|
||||
|
||||
/** Type of equation of motion of a particle in a field. */
|
||||
G4EquationType fEquation = kEqMagnetic;
|
||||
|
||||
/** Type of integrator of particle's equation of motion. */
|
||||
G4StepperType fStepper = kDormandPrince745;
|
||||
|
||||
/** User defined equation of motion. */
|
||||
G4EquationOfMotion* fUserEquation = nullptr;
|
||||
|
||||
/// User defined integrator of particle's equation of motion. */
|
||||
G4MagIntegratorStepper* fUserStepper = nullptr;
|
||||
|
||||
/** The distance within which the field is considered constant. */
|
||||
G4double fConstDistance = fgkDefaultConstDistance;
|
||||
};
|
||||
|
||||
// inline functions
|
||||
// Inline functions
|
||||
|
||||
// Set type of field
|
||||
inline void G4FieldParameters::SetFieldType(G4FieldType field)
|
||||
{
|
||||
fField = field;
|
||||
}
|
||||
#include "G4FieldParameters.icc"
|
||||
|
||||
// Set the type of equation of motion of a particle in a field
|
||||
inline void G4FieldParameters::SetEquationType(G4EquationType equation)
|
||||
{
|
||||
fEquation = equation;
|
||||
}
|
||||
|
||||
// Set the type of integrator of particle's equation of motion
|
||||
inline void G4FieldParameters::SetStepperType(G4StepperType stepper)
|
||||
{
|
||||
fStepper = stepper;
|
||||
}
|
||||
|
||||
// Set minimum step in G4ChordFinder
|
||||
inline void G4FieldParameters::SetMinimumStep(G4double value)
|
||||
{
|
||||
fMinimumStep = value;
|
||||
}
|
||||
|
||||
// Set delta chord in G4ChordFinder
|
||||
inline void G4FieldParameters::SetDeltaChord(G4double value)
|
||||
{
|
||||
fDeltaChord = value;
|
||||
}
|
||||
|
||||
// Set delta one step in global field manager
|
||||
inline void G4FieldParameters::SetDeltaOneStep(G4double value)
|
||||
{
|
||||
fDeltaOneStep = value;
|
||||
}
|
||||
|
||||
// Set delta intersection in global field manager
|
||||
inline void G4FieldParameters::SetDeltaIntersection(G4double value)
|
||||
{
|
||||
fDeltaIntersection = value;
|
||||
}
|
||||
|
||||
// Set minimum epsilon step in global field manager
|
||||
inline void G4FieldParameters::SetMinimumEpsilonStep(G4double value)
|
||||
{
|
||||
fMinimumEpsilonStep = value;
|
||||
}
|
||||
|
||||
// Set maximum epsilon step in global field manager
|
||||
inline void G4FieldParameters::SetMaximumEpsilonStep(G4double value)
|
||||
{
|
||||
fMaximumEpsilonStep = value;
|
||||
}
|
||||
|
||||
// Set the distance within which the field is considered constant
|
||||
inline void G4FieldParameters::SetConstDistance(G4double value)
|
||||
{
|
||||
fConstDistance = value;
|
||||
}
|
||||
|
||||
// Return the name of associated volume, if local field
|
||||
inline G4String G4FieldParameters::GetVolumeName() const
|
||||
{
|
||||
return fVolumeName;
|
||||
}
|
||||
|
||||
// Return the type of field
|
||||
inline G4FieldType G4FieldParameters::GetFieldType() const { return fField; }
|
||||
|
||||
// Return the type of equation of motion of a particle in a field
|
||||
inline G4EquationType G4FieldParameters::GetEquationType() const
|
||||
{
|
||||
return fEquation;
|
||||
}
|
||||
|
||||
// Return the type of integrator of particle's equation of motion
|
||||
inline G4StepperType G4FieldParameters::GetStepperType() const
|
||||
{
|
||||
return fStepper;
|
||||
}
|
||||
|
||||
// Return the user defined equation of motion
|
||||
inline G4EquationOfMotion* G4FieldParameters::GetUserEquationOfMotion() const
|
||||
{
|
||||
return fUserEquation;
|
||||
}
|
||||
|
||||
// Return the user defined integrator of particle's equation of motion
|
||||
inline G4MagIntegratorStepper* G4FieldParameters::GetUserStepper() const
|
||||
{
|
||||
return fUserStepper;
|
||||
}
|
||||
|
||||
// Return minimum step in G4ChordFinder
|
||||
inline G4double G4FieldParameters::GetMinimumStep() const
|
||||
{
|
||||
return fMinimumStep;
|
||||
}
|
||||
|
||||
// Return delta chord in G4ChordFinder
|
||||
inline G4double G4FieldParameters::GetDeltaChord() const
|
||||
{
|
||||
return fDeltaChord;
|
||||
}
|
||||
|
||||
// Return delta one step in global field manager
|
||||
inline G4double G4FieldParameters::GetDeltaOneStep() const
|
||||
{
|
||||
return fDeltaOneStep;
|
||||
}
|
||||
|
||||
// Return delta intersection in global field manager
|
||||
inline G4double G4FieldParameters::GetDeltaIntersection() const
|
||||
{
|
||||
return fDeltaIntersection;
|
||||
}
|
||||
|
||||
// Return minimum epsilon step in global field manager
|
||||
inline G4double G4FieldParameters::GetMinimumEpsilonStep() const
|
||||
{
|
||||
return fMinimumEpsilonStep;
|
||||
}
|
||||
|
||||
// Return maximum epsilon step in global field manager
|
||||
inline G4double G4FieldParameters::GetMaximumEpsilonStep() const
|
||||
{
|
||||
return fMaximumEpsilonStep;
|
||||
}
|
||||
|
||||
// Return the distance within which the field is considered constant
|
||||
inline G4double G4FieldParameters::GetConstDistance() const
|
||||
{
|
||||
return fConstDistance;
|
||||
}
|
||||
|
||||
#endif // G4FIELDPARAMETERS_HH
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4FieldParameters inline methods implementation
|
||||
//
|
||||
// Author: Ivana Hrivnacova (IJCLab, Orsay), 2024.
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// Set type of field
|
||||
inline void G4FieldParameters::SetFieldType(G4FieldType field)
|
||||
{
|
||||
fField = field;
|
||||
}
|
||||
|
||||
// Set the type of equation of motion of a particle in a field
|
||||
inline void G4FieldParameters::SetEquationType(G4EquationType equation)
|
||||
{
|
||||
fEquation = equation;
|
||||
}
|
||||
|
||||
// Set the type of integrator of particle's equation of motion
|
||||
inline void G4FieldParameters::SetStepperType(G4StepperType stepper)
|
||||
{
|
||||
fStepper = stepper;
|
||||
}
|
||||
|
||||
// Set minimum step in G4ChordFinder
|
||||
inline void G4FieldParameters::SetMinimumStep(G4double value)
|
||||
{
|
||||
fMinimumStep = value;
|
||||
}
|
||||
|
||||
// Set delta chord in G4ChordFinder
|
||||
inline void G4FieldParameters::SetDeltaChord(G4double value)
|
||||
{
|
||||
fDeltaChord = value;
|
||||
}
|
||||
|
||||
// Set delta one step in global field manager
|
||||
inline void G4FieldParameters::SetDeltaOneStep(G4double value)
|
||||
{
|
||||
fDeltaOneStep = value;
|
||||
}
|
||||
|
||||
// Set delta intersection in global field manager
|
||||
inline void G4FieldParameters::SetDeltaIntersection(G4double value)
|
||||
{
|
||||
fDeltaIntersection = value;
|
||||
}
|
||||
|
||||
// Set minimum epsilon step in global field manager
|
||||
inline void G4FieldParameters::SetMinimumEpsilonStep(G4double value)
|
||||
{
|
||||
fMinimumEpsilonStep = value;
|
||||
}
|
||||
|
||||
// Set maximum epsilon step in global field manager
|
||||
inline void G4FieldParameters::SetMaximumEpsilonStep(G4double value)
|
||||
{
|
||||
fMaximumEpsilonStep = value;
|
||||
}
|
||||
|
||||
// Set the distance within which the field is considered constant
|
||||
inline void G4FieldParameters::SetConstDistance(G4double value)
|
||||
{
|
||||
fConstDistance = value;
|
||||
}
|
||||
|
||||
// Return the name of associated volume, if local field
|
||||
inline const G4String& G4FieldParameters::GetVolumeName() const
|
||||
{
|
||||
return fVolumeName;
|
||||
}
|
||||
|
||||
// Return the type of field
|
||||
inline const G4FieldType& G4FieldParameters::GetFieldType() const
|
||||
{
|
||||
return fField;
|
||||
}
|
||||
|
||||
// Return the type of equation of motion of a particle in a field
|
||||
inline const G4EquationType& G4FieldParameters::GetEquationType() const
|
||||
{
|
||||
return fEquation;
|
||||
}
|
||||
|
||||
// Return the type of integrator of particle's equation of motion
|
||||
inline const G4StepperType& G4FieldParameters::GetStepperType() const
|
||||
{
|
||||
return fStepper;
|
||||
}
|
||||
|
||||
// Return the user defined equation of motion
|
||||
inline G4EquationOfMotion* G4FieldParameters::GetUserEquationOfMotion() const
|
||||
{
|
||||
return fUserEquation;
|
||||
}
|
||||
|
||||
// Return the user defined integrator of particle's equation of motion
|
||||
inline G4MagIntegratorStepper* G4FieldParameters::GetUserStepper() const
|
||||
{
|
||||
return fUserStepper;
|
||||
}
|
||||
|
||||
// Return minimum step in G4ChordFinder
|
||||
inline G4double G4FieldParameters::GetMinimumStep() const
|
||||
{
|
||||
return fMinimumStep;
|
||||
}
|
||||
|
||||
// Return delta chord in G4ChordFinder
|
||||
inline G4double G4FieldParameters::GetDeltaChord() const
|
||||
{
|
||||
return fDeltaChord;
|
||||
}
|
||||
|
||||
// Return delta one step in global field manager
|
||||
inline G4double G4FieldParameters::GetDeltaOneStep() const
|
||||
{
|
||||
return fDeltaOneStep;
|
||||
}
|
||||
|
||||
// Return delta intersection in global field manager
|
||||
inline G4double G4FieldParameters::GetDeltaIntersection() const
|
||||
{
|
||||
return fDeltaIntersection;
|
||||
}
|
||||
|
||||
// Return minimum epsilon step in global field manager
|
||||
inline G4double G4FieldParameters::GetMinimumEpsilonStep() const
|
||||
{
|
||||
return fMinimumEpsilonStep;
|
||||
}
|
||||
|
||||
// Return maximum epsilon step in global field manager
|
||||
inline G4double G4FieldParameters::GetMaximumEpsilonStep() const
|
||||
{
|
||||
return fMaximumEpsilonStep;
|
||||
}
|
||||
|
||||
// Return the distance within which the field is considered constant
|
||||
inline G4double G4FieldParameters::GetConstDistance() const
|
||||
{
|
||||
return fConstDistance;
|
||||
}
|
||||
@@ -22,16 +22,39 @@
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4FieldParametersMessenger
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// Messenger class that defines commands for field configuration.
|
||||
//
|
||||
// Implements commands:
|
||||
// - /field/fieldType fieldType
|
||||
// fieldType = Magnetic | ElectroMagnetic | Gravity
|
||||
// - /field/equationType eqType
|
||||
// eqType = EqMagnetic | EqMagneticWithSpin | EqElectroMagnetic |
|
||||
// EqEMfieldWithSpin | EqEMfieldWithEDM
|
||||
// - /field/stepperType stepperType
|
||||
// stepperType = CashKarpRKF45 | ClassicalRK4 | ExplicitEuler | ImplicitEuler |
|
||||
// SimpleHeum | SimpleRunge | ConstRK4 | ExactHelixStepper
|
||||
// | HelixExplicitEuler | HelixHeum | HelixImplicitEuler |
|
||||
// HelixMixedStepper | HelixSimpleRunge | NystromRK4 |
|
||||
// RKG3Stepper
|
||||
// - /field/setMinimumStep value
|
||||
// - /field/setDeltaChord value
|
||||
// - /field/setDeltaOneStep value
|
||||
// - /field/setDeltaIntersection value
|
||||
// - /field/setMinimumEpsilonStep value
|
||||
// - /field/setMaximumEpsilonStep value
|
||||
// - /field/setConstDistance value
|
||||
// - /field/printParameters
|
||||
//
|
||||
// Only equation type and stepper type values that are handled by G4FieldBuilder
|
||||
// are accepted by the commands.
|
||||
|
||||
/// \file G4FieldParametersMessenger.h
|
||||
/// \brief Definition of the G4FieldParametersMessenger class
|
||||
///
|
||||
/// This code was initially developed in Geant4 VMC package
|
||||
/// (https://github.com/vmc-project)
|
||||
/// and adapted to Geant4.
|
||||
///
|
||||
/// \author I. Hrivnacova; IJCLab, Orsay
|
||||
|
||||
// Author: Ivana Hrivnacova (IJClab, Orsay), 2024.
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4FIELDPARAMETERSMESSENGER_HH
|
||||
#define G4FIELDPARAMETERSMESSENGER_HH
|
||||
|
||||
@@ -48,92 +71,81 @@ class G4UIcmdWithADouble;
|
||||
class G4UIcmdWithADoubleAndUnit;
|
||||
class G4UIcmdWithABool;
|
||||
|
||||
/// \ingroup geometry
|
||||
/// \brief Messenger class that defines commands for TG4DetConstruction.
|
||||
///
|
||||
/// Implements commands:
|
||||
/// - /field/fieldType fieldType \n
|
||||
/// fieldType = Magnetic | ElectroMagnetic | Gravity
|
||||
/// - /field/equationType eqType \n
|
||||
/// eqType = EqMagnetic | EqMagneticWithSpin | EqElectroMagnetic |
|
||||
/// EqEMfieldWithSpin | EqEMfieldWithEDM
|
||||
/// - /field/stepperType stepperType \n
|
||||
/// stepperType = CashKarpRKF45 | ClassicalRK4 | ExplicitEuler | ImplicitEuler |
|
||||
/// SimpleHeum | SimpleRunge | ConstRK4 | ExactHelixStepper
|
||||
/// | HelixExplicitEuler | HelixHeum | HelixImplicitEuler |
|
||||
/// HelixMixedStepper | HelixSimpleRunge | NystromRK4 |
|
||||
/// RKG3Stepper
|
||||
/// - /field/setMinimumStep value
|
||||
/// - /field/setDeltaChord value
|
||||
/// - /field/setDeltaOneStep value
|
||||
/// - /field/setDeltaIntersection value
|
||||
/// - /field/setMinimumEpsilonStep value
|
||||
/// - /field/setMaximumEpsilonStep value
|
||||
/// - /field/setConstDistance value
|
||||
/// - /field/printParameters
|
||||
///
|
||||
/// \author I. Hrivnacova; IJClab, Orsay
|
||||
/**
|
||||
* @brief G4FieldParametersMessenger is a messenger class that defines
|
||||
* commands for field configuration. Only equation type and stepper type
|
||||
* values that are handled by G4FieldBuilder are accepted by the commands.
|
||||
*/
|
||||
|
||||
class G4FieldParametersMessenger : public G4UImessenger
|
||||
{
|
||||
public:
|
||||
/// Standard constructor
|
||||
G4FieldParametersMessenger(G4FieldParameters* fieldParameters);
|
||||
/// Destructor
|
||||
~G4FieldParametersMessenger() override;
|
||||
public:
|
||||
|
||||
// methods
|
||||
/// Apply command to the associated object.
|
||||
void SetNewValue(G4UIcommand* command, G4String newValues) override;
|
||||
/**
|
||||
* Standard constructor for G4FieldParametersMessenger.
|
||||
* @param[in] fieldParameters Pointer to the field parameters object.
|
||||
*/
|
||||
G4FieldParametersMessenger(G4FieldParameters* fieldParameters);
|
||||
|
||||
private:
|
||||
/// Not implemented
|
||||
G4FieldParametersMessenger() = delete;
|
||||
/// Not implemented
|
||||
G4FieldParametersMessenger(const G4FieldParametersMessenger& right) = delete;
|
||||
/// Not implemented
|
||||
G4FieldParametersMessenger& operator=(
|
||||
const G4FieldParametersMessenger& right) = delete;
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~G4FieldParametersMessenger() override;
|
||||
|
||||
// Data members
|
||||
/**
|
||||
* Default constructor, copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4FieldParametersMessenger() = delete;
|
||||
G4FieldParametersMessenger(const G4FieldParametersMessenger&) = delete;
|
||||
G4FieldParametersMessenger& operator=(const G4FieldParametersMessenger&) = delete;
|
||||
|
||||
G4FieldParameters* fFieldParameters = nullptr; ///< associated class
|
||||
G4UIdirectory* fDirectory = nullptr; ///< command directory
|
||||
/**
|
||||
* Applies command to the associated object.
|
||||
*/
|
||||
void SetNewValue(G4UIcommand* command, G4String newValues) override;
|
||||
|
||||
// Commands data members
|
||||
private:
|
||||
|
||||
/// Command: fieldType
|
||||
G4UIcmdWithAString* fFieldTypeCmd = nullptr;
|
||||
/** Associated class object. */
|
||||
G4FieldParameters* fFieldParameters = nullptr;
|
||||
|
||||
/// Command: equationType
|
||||
G4UIcmdWithAString* fEquationTypeCmd = nullptr;
|
||||
/** Commands directory. */
|
||||
G4UIdirectory* fDirectory = nullptr;
|
||||
|
||||
/// Command: stepperType
|
||||
G4UIcmdWithAString* fStepperTypeCmd = nullptr;
|
||||
// Commands data members
|
||||
|
||||
/// Command: setMinimumStep
|
||||
G4UIcmdWithADoubleAndUnit* fSetMinimumStepCmd = nullptr;
|
||||
/** Command: fieldType. */
|
||||
G4UIcmdWithAString* fFieldTypeCmd = nullptr;
|
||||
|
||||
/// Command: setDeltaChord
|
||||
G4UIcmdWithADoubleAndUnit* fSetDeltaChordCmd = nullptr;
|
||||
/** Command: equationType. */
|
||||
G4UIcmdWithAString* fEquationTypeCmd = nullptr;
|
||||
|
||||
/// Command: setDeltaOneStep
|
||||
G4UIcmdWithADoubleAndUnit* fSetDeltaOneStepCmd = nullptr;
|
||||
/** Command: stepperType. */
|
||||
G4UIcmdWithAString* fStepperTypeCmd = nullptr;
|
||||
|
||||
/// Command: setDeltaIntersection
|
||||
G4UIcmdWithADoubleAndUnit* fSetDeltaIntersectionCmd = nullptr;
|
||||
/** Command: setMinimumStep. */
|
||||
G4UIcmdWithADoubleAndUnit* fSetMinimumStepCmd = nullptr;
|
||||
|
||||
/// Command: setMinimumEpsilon
|
||||
G4UIcmdWithADouble* fSetMinimumEpsilonStepCmd = nullptr;
|
||||
/** Command: setDeltaChord. */
|
||||
G4UIcmdWithADoubleAndUnit* fSetDeltaChordCmd = nullptr;
|
||||
|
||||
/// Command: setMaximumEpsilon
|
||||
G4UIcmdWithADouble* fSetMaximumEpsilonStepCmd = nullptr;
|
||||
/** Command: setDeltaOneStep. */
|
||||
G4UIcmdWithADoubleAndUnit* fSetDeltaOneStepCmd = nullptr;
|
||||
|
||||
/// Command: setConstDistance
|
||||
G4UIcmdWithADoubleAndUnit* fSetConstDistanceCmd = nullptr;
|
||||
/** Command: setDeltaIntersection. */
|
||||
G4UIcmdWithADoubleAndUnit* fSetDeltaIntersectionCmd = nullptr;
|
||||
|
||||
/// Command: printParameters
|
||||
G4UIcmdWithoutParameter* fPrintParametersCmd = nullptr;
|
||||
/** Command: setMinimumEpsilon. */
|
||||
G4UIcmdWithADouble* fSetMinimumEpsilonStepCmd = nullptr;
|
||||
|
||||
/** Command: setMaximumEpsilon. */
|
||||
G4UIcmdWithADouble* fSetMaximumEpsilonStepCmd = nullptr;
|
||||
|
||||
/** Command: setConstDistance. */
|
||||
G4UIcmdWithADoubleAndUnit* fSetConstDistanceCmd = nullptr;
|
||||
|
||||
/** Command: printParameters. */
|
||||
G4UIcmdWithoutParameter* fPrintParametersCmd = nullptr;
|
||||
};
|
||||
|
||||
#endif // G4FIELDPARAMETERSMESSENGER_HH
|
||||
#endif
|
||||
|
||||
@@ -22,16 +22,22 @@
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4FieldSetup
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// The class for constructing magnetic, electromagnetic and gravity
|
||||
// fields which strength is defined via G4Field.
|
||||
//
|
||||
// The equation of motion of a particle in a field and the
|
||||
// integration method are set according to the selection in
|
||||
// G4FieldParameters, as well as other accuracy parameters.
|
||||
// The default values in G4FieldParameters correspond to defaults
|
||||
// set in Geant4.
|
||||
|
||||
/// \file G4FieldSetup.h
|
||||
/// \brief Definition of the G4FieldSetup class
|
||||
///
|
||||
/// This code was initially developed in Geant4 VMC package
|
||||
/// (https://github.com/vmc-project)
|
||||
/// and adapted to Geant4.
|
||||
///
|
||||
/// \author I. Hrivnacova; IJCLab, Orsay
|
||||
|
||||
// Author: Ivana Hrivnacova (IJClab, Orsay), 2024.
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4FIELDSETUP_HH
|
||||
#define G4FIELDSETUP_HH
|
||||
|
||||
@@ -49,148 +55,160 @@ class G4MagIntegratorStepper;
|
||||
class G4LogicalVolume;
|
||||
class G4VIntegrationDriver;
|
||||
|
||||
class TVirtualMagField;
|
||||
|
||||
/// \ingroup geometry
|
||||
/// \brief The class for constructing magnetic, electromagnetic and gravity
|
||||
/// fields which strength is defined via G4Field.
|
||||
///
|
||||
/// The equation of motion of a particle in a field and the
|
||||
/// integration method is set according to the selection in
|
||||
/// G4FieldParameters, as well as other accuracy parameters.
|
||||
/// The default values in G4FieldParameters correspond to defaults
|
||||
/// set in Geant4 (taken from Geant4 9.3 release.)
|
||||
/// As Geant4 classes to not provide access methods for these defaults,
|
||||
/// the defaults have to be checked with each new Geant4 release.
|
||||
/// TO DO: unify defaults in G4 classes and G4 parameters
|
||||
///
|
||||
/// \author I. Hrivnacova; IJClab, Orsay
|
||||
/**
|
||||
* @brief G4FieldSetup is a class for constructing magnetic, electromagnetic
|
||||
* and gravity fields which strength is defined via G4Field.
|
||||
* The equation of motion of a particle in a field and the integration method
|
||||
* are set according to the selection in G4FieldParameters, as well as other
|
||||
* accuracy parameters.
|
||||
*/
|
||||
|
||||
class G4FieldSetup
|
||||
{
|
||||
public:
|
||||
/// Standard constructor
|
||||
G4FieldSetup(const G4FieldParameters& parameters, G4Field* field,
|
||||
G4LogicalVolume* lv = nullptr);
|
||||
/// Destructor
|
||||
~G4FieldSetup();
|
||||
public:
|
||||
|
||||
// Methods
|
||||
/**
|
||||
* Standard constructor for G4FieldSetup.
|
||||
* @param[in] parameters The field parameters.
|
||||
* @param[in] field Pointer to the field object.
|
||||
* @param[in] lv Optional logical volume where field applies; if
|
||||
* null, global field applies.
|
||||
*/
|
||||
G4FieldSetup(const G4FieldParameters& parameters,
|
||||
G4Field* field,
|
||||
G4LogicalVolume* lv = nullptr);
|
||||
|
||||
/// Clear previously created setup
|
||||
void Clear();
|
||||
/// Update field setup with new field parameters
|
||||
void Update();
|
||||
/// Print information
|
||||
void PrintInfo(G4int verboseLevel, const G4String about = "created");
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4FieldSetup();
|
||||
|
||||
// Set methods
|
||||
/**
|
||||
* Default constructor, copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4FieldSetup() = delete;
|
||||
G4FieldSetup(const G4FieldSetup& right) = delete;
|
||||
G4FieldSetup& operator=(const G4FieldSetup& right) = delete;
|
||||
|
||||
/// Set G4 field
|
||||
void SetG4Field(G4Field* field);
|
||||
/**
|
||||
* Clears previously created setup.
|
||||
*/
|
||||
void Clear();
|
||||
|
||||
// Access to field setting
|
||||
/**
|
||||
* Updates the field setup with new field parameters.
|
||||
*/
|
||||
void Update();
|
||||
|
||||
/// Return the instantiated field
|
||||
G4Field* GetG4Field() const;
|
||||
/// Return the logical vol;ume
|
||||
G4LogicalVolume* GetLogicalVolume() const;
|
||||
/// Return the equation of motion
|
||||
G4EquationOfMotion* GetEquation() const;
|
||||
/// Return the magnetic integrator stepper
|
||||
G4MagIntegratorStepper* GetStepper() const;
|
||||
/// Return the magnetic integrator driver
|
||||
G4VIntegrationDriver* GetIntegrationDriver() const;
|
||||
/**
|
||||
* Prints information.
|
||||
* @param[in] verboseLevel Verbosity level; if greater than 1, parameters
|
||||
* are also printed out to standard output.
|
||||
* @param[in] about Optional string.
|
||||
*/
|
||||
void PrintInfo(G4int verboseLevel, const G4String& about = "created");
|
||||
|
||||
private:
|
||||
/// Not implemented
|
||||
G4FieldSetup() = delete;
|
||||
/// Not implemented
|
||||
G4FieldSetup(const G4FieldSetup& right) = delete;
|
||||
/// Not implemented
|
||||
G4FieldSetup& operator=(const G4FieldSetup& right) = delete;
|
||||
/**
|
||||
* Setter for the field object.
|
||||
*/
|
||||
inline void SetG4Field(G4Field* field) { fG4Field = field; }
|
||||
|
||||
// Methods
|
||||
/**
|
||||
* Accessors.
|
||||
*/
|
||||
inline G4Field* GetG4Field() const { return fG4Field; }
|
||||
inline G4LogicalVolume* GetLogicalVolume() const { return fLogicalVolume; }
|
||||
inline G4EquationOfMotion* GetEquation() const { return fEquation; }
|
||||
inline G4MagIntegratorStepper* GetStepper() const { return fStepper; }
|
||||
|
||||
// Create cached magnetic field if const distance is set > 0.
|
||||
// and field is of G4MagneticField.
|
||||
// Return the input field otherwise.
|
||||
G4Field* CreateCachedField(
|
||||
const G4FieldParameters& parameters, G4Field* field);
|
||||
private:
|
||||
|
||||
/// Set the equation of motion of a particle in a field
|
||||
G4EquationOfMotion* CreateEquation(G4EquationType equation);
|
||||
/**
|
||||
* Creates cached magnetic field if const distance is set greater than zero.
|
||||
* @param[in] parameters The field parameters.
|
||||
* @param[in] field Pointer to the field in input.
|
||||
* @returns The pointer to the cached field or the input field otherwise.
|
||||
*/
|
||||
G4Field* CreateCachedField( const G4FieldParameters& parameters,
|
||||
G4Field* field);
|
||||
|
||||
/// Set the integrator of particle's equation of motion
|
||||
G4MagIntegratorStepper* CreateStepper(
|
||||
G4EquationOfMotion* equation, G4StepperType stepper);
|
||||
/**
|
||||
* Creates and sets the equation of motion of a particle in a field.
|
||||
* @param[in] equation The equation type.
|
||||
* @returns The pointer to the created equation of motion.
|
||||
*/
|
||||
G4EquationOfMotion* CreateEquation(G4EquationType equation);
|
||||
|
||||
/// Set the FSAL integrator of particle's equation of motion
|
||||
G4VIntegrationDriver* CreateFSALStepperAndDriver(
|
||||
G4EquationOfMotion* equation, G4StepperType stepper, G4double minStep);
|
||||
/**
|
||||
* Creates and sets the field integration stepper.
|
||||
* @param[in] equation Pointer to the equation of motion.
|
||||
* @param[in] stepper The stepper type.
|
||||
* @returns The pointer to the created integration stepper.
|
||||
*/
|
||||
G4MagIntegratorStepper* CreateStepper(G4EquationOfMotion* equation,
|
||||
G4StepperType stepper);
|
||||
|
||||
// methods to update field setup step by step
|
||||
/// Create cached field (if ConstDistance is set)
|
||||
void CreateCachedField();
|
||||
/// Create cached field (if ConstDistance is set)
|
||||
void CreateStepper();
|
||||
/// Create chord finder
|
||||
void CreateChordFinder();
|
||||
/// Update field manager
|
||||
void UpdateFieldManager();
|
||||
/**
|
||||
* Creates and sets the FSAL field integration driver.
|
||||
* @param[in] equation Pointer to the equation of motion.
|
||||
* @param[in] stepper The stepper type.
|
||||
* @param[in] minStep The minimum allowed step.
|
||||
* @returns The pointer to the created FSAL integration driver.
|
||||
*/
|
||||
G4VIntegrationDriver*
|
||||
CreateFSALStepperAndDriver(G4EquationOfMotion* equation,
|
||||
G4StepperType stepper, G4double minStep);
|
||||
|
||||
// Data members
|
||||
// Methods to update field setup step by step
|
||||
|
||||
/// Messenger for this class
|
||||
G4FieldSetupMessenger* fMessenger = nullptr;
|
||||
/// Parameters
|
||||
const G4FieldParameters& fParameters;
|
||||
/// Geant4 field manager
|
||||
G4FieldManager* fFieldManager = nullptr;
|
||||
/// Geant4 field
|
||||
G4Field* fG4Field = nullptr;
|
||||
/// The associated ROOT volume (if local field)
|
||||
G4LogicalVolume* fLogicalVolume = nullptr;
|
||||
/// The equation of motion
|
||||
G4EquationOfMotion* fEquation = nullptr;
|
||||
/// The magnetic integrator stepper
|
||||
G4MagIntegratorStepper* fStepper = nullptr;
|
||||
/// The magnetic integrator driver
|
||||
G4VIntegrationDriver* fDriver = nullptr;
|
||||
/// Chord finder
|
||||
G4ChordFinder* fChordFinder = nullptr;
|
||||
/**
|
||||
* Creates cached field (if ConstDistance is set).
|
||||
*/
|
||||
void CreateCachedField();
|
||||
|
||||
/**
|
||||
* Creates the stepper.
|
||||
*/
|
||||
void CreateStepper();
|
||||
|
||||
/**
|
||||
* Creates the chord finder.
|
||||
*/
|
||||
void CreateChordFinder();
|
||||
|
||||
/**
|
||||
* Updates the field manager.
|
||||
*/
|
||||
void UpdateFieldManager();
|
||||
|
||||
private: // data members
|
||||
|
||||
/** Messenger for this class. */
|
||||
G4FieldSetupMessenger* fMessenger = nullptr;
|
||||
|
||||
/** Field parameters. */
|
||||
const G4FieldParameters& fParameters;
|
||||
|
||||
/** The field manager. */
|
||||
G4FieldManager* fFieldManager = nullptr;
|
||||
|
||||
/** The field class object. */
|
||||
G4Field* fG4Field = nullptr;
|
||||
|
||||
/** The associated volume (if local field). */
|
||||
G4LogicalVolume* fLogicalVolume = nullptr;
|
||||
|
||||
/** The equation of motion. */
|
||||
G4EquationOfMotion* fEquation = nullptr;
|
||||
|
||||
/** The magnetic integrator stepper. */
|
||||
G4MagIntegratorStepper* fStepper = nullptr;
|
||||
|
||||
/** The magnetic integrator driver. */
|
||||
G4VIntegrationDriver* fDriver = nullptr;
|
||||
|
||||
/** Chord finder. */
|
||||
G4ChordFinder* fChordFinder = nullptr;
|
||||
};
|
||||
|
||||
// inline functions
|
||||
|
||||
inline void G4FieldSetup::SetG4Field(G4Field* field)
|
||||
{
|
||||
// Set G4 field
|
||||
fG4Field = field;
|
||||
}
|
||||
|
||||
inline G4Field* G4FieldSetup::GetG4Field() const
|
||||
{
|
||||
// Return the instantiated field
|
||||
return fG4Field;
|
||||
}
|
||||
|
||||
inline G4LogicalVolume* G4FieldSetup::GetLogicalVolume() const
|
||||
{
|
||||
// Return the logical vol;ume
|
||||
return fLogicalVolume;
|
||||
}
|
||||
|
||||
inline G4EquationOfMotion* G4FieldSetup::GetEquation() const
|
||||
{
|
||||
// Return the equation of motion
|
||||
return fEquation;
|
||||
}
|
||||
|
||||
inline G4MagIntegratorStepper* G4FieldSetup::GetStepper() const
|
||||
{
|
||||
// Return the magnetic integrator stepper
|
||||
return fStepper;
|
||||
}
|
||||
|
||||
#endif // G4FIELDSETUP_HH
|
||||
#endif
|
||||
|
||||
@@ -22,12 +22,18 @@
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4FieldSetupMessenger
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// Messenger class that defines commands for G4FieldSetup.
|
||||
//
|
||||
// Implements commands:
|
||||
// - /field/update
|
||||
|
||||
/// \file G4FieldSetupMessenger.h
|
||||
/// \brief Definition of the G4FieldSetupMessenger class
|
||||
///
|
||||
/// \author I. Hrivnacova; IJCLab, Orsay
|
||||
|
||||
// Author: Ivana Hrivnacova (IJCLab, Orsay), 2024
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4FIELDSETUPMESSENGER_HH
|
||||
#define G4FIELDSETUPMESSENGER_HH
|
||||
|
||||
@@ -41,42 +47,42 @@ class G4UIdirectory;
|
||||
class G4UIcmdWithoutParameter;
|
||||
class G4UIcmdWithAnInteger;
|
||||
|
||||
/// \ingroup geometry
|
||||
/// \brief Messenger class that defines commands for G4FieldSetup
|
||||
///
|
||||
/// Implements commands:
|
||||
/// - /field/update
|
||||
///
|
||||
/// \author I. Hrivnacova; IJCLab, Orsay
|
||||
/**
|
||||
* @brief G4FieldSetupMessenger is a messenger class that defines
|
||||
* commands for G4FieldSetup.
|
||||
*/
|
||||
|
||||
class G4FieldSetupMessenger : public G4UImessenger
|
||||
{
|
||||
public:
|
||||
/// Standard constructor
|
||||
G4FieldSetupMessenger(G4FieldSetup* fieldSetup);
|
||||
/// Destructor
|
||||
~G4FieldSetupMessenger() override;
|
||||
public:
|
||||
|
||||
// methods
|
||||
/// Apply command to the associated object.
|
||||
void SetNewValue(G4UIcommand* command, G4String newValues) override;
|
||||
/**
|
||||
* Standard Constructor and Destructor.
|
||||
*/
|
||||
G4FieldSetupMessenger(G4FieldSetup* fieldSetup);
|
||||
~G4FieldSetupMessenger() override;
|
||||
|
||||
private:
|
||||
/// Not implemented
|
||||
G4FieldSetupMessenger() = delete;
|
||||
/// Not implemented
|
||||
G4FieldSetupMessenger(const G4FieldSetupMessenger& right) = delete;
|
||||
/// Not implemented
|
||||
G4FieldSetupMessenger& operator=(const G4FieldSetupMessenger& right) = delete;
|
||||
/**
|
||||
* Default constructor, copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4FieldSetupMessenger() = delete;
|
||||
G4FieldSetupMessenger(const G4FieldSetupMessenger&) = delete;
|
||||
G4FieldSetupMessenger& operator=(const G4FieldSetupMessenger&) = delete;
|
||||
|
||||
// data members
|
||||
G4FieldSetup* fFieldSetup = nullptr; ///< associated class
|
||||
/**
|
||||
* Applies command to the associated object.
|
||||
*/
|
||||
void SetNewValue(G4UIcommand* command, G4String newValues) override;
|
||||
|
||||
//
|
||||
// commands data members
|
||||
private:
|
||||
|
||||
/// Command: update
|
||||
G4UIcmdWithoutParameter* fUpdateCmd = nullptr;
|
||||
/** Associated class object. */
|
||||
G4FieldSetup* fFieldSetup = nullptr;
|
||||
|
||||
// Commands data members
|
||||
|
||||
/** Command: update. */
|
||||
G4UIcmdWithoutParameter* fUpdateCmd = nullptr;
|
||||
};
|
||||
|
||||
#endif // G4FIELDBUILDERMESSENGER_HH
|
||||
#endif
|
||||
|
||||
@@ -27,13 +27,13 @@
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// Data structure bringing together a magnetic track's state.
|
||||
// (position, momentum direction & modulus, energy, spin, ... )
|
||||
// Data structure bringing together a magnetic track's state
|
||||
// (position, momentum direction & modulus, energy, spin, ... ).
|
||||
// Uses/abilities:
|
||||
// - does not maintain any relationship between its data (eg energy/momentum).
|
||||
// - for use in Runge-Kutta solver (in passing it the values right now).
|
||||
|
||||
// Author: John Apostolakis, CERN - First version, 14.10.1996
|
||||
// Author: John Apostolakis (CERN), 14.10.1996 - First version
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4FIELDTRACK_HH
|
||||
#define G4FIELDTRACK_HH
|
||||
@@ -41,140 +41,202 @@
|
||||
#include "G4ThreeVector.hh"
|
||||
#include "G4ChargeState.hh"
|
||||
|
||||
/**
|
||||
* @brief G4FieldTrack defines a data structure bringing together a magnetic
|
||||
* track's state (position, momentum direction & modulus, energy, spin, etc. ).
|
||||
*/
|
||||
|
||||
class G4FieldTrack
|
||||
{
|
||||
public: // with description
|
||||
public:
|
||||
|
||||
G4FieldTrack( const G4ThreeVector& pPosition,
|
||||
G4double LaboratoryTimeOfFlight,
|
||||
const G4ThreeVector& pMomentumDirection,
|
||||
G4double kineticEnergy,
|
||||
G4double restMass_c2,
|
||||
G4double charge,
|
||||
const G4ThreeVector& polarization,
|
||||
G4double magnetic_dipole_moment = 0.0,
|
||||
G4double curve_length = 0.0,
|
||||
G4double PDGspin = -1.0 );
|
||||
/**
|
||||
* Constructor for G4FieldTrack.
|
||||
* @param[in] pPosition Position in Cartesian coordinates.
|
||||
* @param[in] LaboratoryTimeOfFlight Laboratory time of flight value.
|
||||
* @param[in] pMomentumDirection Direction vector.
|
||||
* @param[in] kineticEnergy Kinetic energy value.
|
||||
* @param[in] restMass_c2 Mass at rest.
|
||||
* @param[in] charge Charge.
|
||||
* @param[in] polarization Polarisation vector.
|
||||
* @param[in] magnetic_dipole_moment Magnetic dipole moment.
|
||||
* @param[in] curve_length Length of curve.
|
||||
* @param[in] PDGspin Spin.
|
||||
*/
|
||||
G4FieldTrack( const G4ThreeVector& pPosition,
|
||||
G4double LaboratoryTimeOfFlight,
|
||||
const G4ThreeVector& pMomentumDirection,
|
||||
G4double kineticEnergy,
|
||||
G4double restMass_c2,
|
||||
G4double charge,
|
||||
const G4ThreeVector& polarization,
|
||||
G4double magnetic_dipole_moment = 0.0,
|
||||
G4double curve_length = 0.0,
|
||||
G4double PDGspin = -1.0 );
|
||||
|
||||
G4FieldTrack( char );
|
||||
// Almost default constructor
|
||||
/**
|
||||
* Older constructor for G4FieldTrack, similar to above but missing charge.
|
||||
* @param[in] pPosition Position in Cartesian coordinates.
|
||||
* @param[in] pMomentumDirection Direction vector.
|
||||
* @param[in] curve_length Length of curve.
|
||||
* @param[in] kineticEnergy Kinetic energy value.
|
||||
* @param[in] restMass_c2 Mass at rest.
|
||||
* @param[in] velocity Velocity value - Not used.
|
||||
* @param[in] LaboratoryTimeOfFlight Laboratory time of flight value.
|
||||
* @param[in] ProperTimeOfFlight Proper time of flight value.
|
||||
* @param[in] polarization Polarisation vector.
|
||||
* @param[in] PDGspin Spin.
|
||||
*/
|
||||
G4FieldTrack( const G4ThreeVector& pPosition,
|
||||
const G4ThreeVector& pMomentumDirection,
|
||||
G4double curve_length,
|
||||
G4double kineticEnergy,
|
||||
const G4double restMass_c2,
|
||||
G4double velocity,
|
||||
G4double LaboratoryTimeOfFlight = 0.0,
|
||||
G4double ProperTimeOfFlight = 0.0,
|
||||
const G4ThreeVector* pPolarization = nullptr,
|
||||
G4double PDGspin = -1.0 );
|
||||
|
||||
G4FieldTrack( const G4ThreeVector& pPosition,
|
||||
const G4ThreeVector& pMomentumDirection,
|
||||
G4double curve_length,
|
||||
G4double kineticEnergy,
|
||||
const G4double restMass_c2,
|
||||
G4double velocity,
|
||||
G4double LaboratoryTimeOfFlight = 0.0,
|
||||
G4double ProperTimeOfFlight = 0.0,
|
||||
const G4ThreeVector* pPolarization = nullptr,
|
||||
G4double PDGspin = -1.0 );
|
||||
// Older constructor
|
||||
// ---> Misses charge !!!
|
||||
/**
|
||||
* Empty init constructor.
|
||||
*/
|
||||
G4FieldTrack( char );
|
||||
|
||||
~G4FieldTrack() = default;
|
||||
// Destructor
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4FieldTrack() = default;
|
||||
|
||||
inline G4FieldTrack( const G4FieldTrack& pFieldTrack );
|
||||
inline G4FieldTrack& operator= ( const G4FieldTrack& rStVec );
|
||||
// Copy constructor & Assignment operator
|
||||
/**
|
||||
* Copy constructor and assignment operator.
|
||||
*/
|
||||
inline G4FieldTrack( const G4FieldTrack& pFieldTrack );
|
||||
inline G4FieldTrack& operator= ( const G4FieldTrack& rStVec );
|
||||
|
||||
inline G4FieldTrack(G4FieldTrack&& from) noexcept ;
|
||||
inline G4FieldTrack& operator=(G4FieldTrack&& from) noexcept ;
|
||||
// Move constructor & operator
|
||||
/**
|
||||
* Move constructor and move assignment operator.
|
||||
*/
|
||||
inline G4FieldTrack(G4FieldTrack&& from) noexcept ;
|
||||
inline G4FieldTrack& operator=(G4FieldTrack&& from) noexcept ;
|
||||
|
||||
inline void UpdateState( const G4ThreeVector& pPosition,
|
||||
G4double LaboratoryTimeOfFlight,
|
||||
const G4ThreeVector& pMomentumDirection,
|
||||
G4double kineticEnergy);
|
||||
// Update four-vectors for space/time and momentum/energy
|
||||
// Also resets curve length.
|
||||
/**
|
||||
* Streaming operator.
|
||||
*/
|
||||
friend std::ostream& operator<<(std::ostream& os, const G4FieldTrack& SixVec);
|
||||
|
||||
inline void UpdateFourMomentum( G4double kineticEnergy,
|
||||
const G4ThreeVector& momentumDirection );
|
||||
// Update momentum (and direction), and kinetic energy
|
||||
/**
|
||||
* Updates four-vectors for space/time and momentum/energy, also
|
||||
* resets the curve length.
|
||||
* @param[in] pPosition Position in Cartesian coordinates.
|
||||
* @param[in] LaboratoryTimeOfFlight Laboratory time of flight value.
|
||||
* @param[in] pMomentumDirection Direction vector.
|
||||
* @param[in] kineticEnergy Kinetic energy value.
|
||||
*/
|
||||
inline void UpdateState( const G4ThreeVector& pPosition,
|
||||
G4double LaboratoryTimeOfFlight,
|
||||
const G4ThreeVector& pMomentumDirection,
|
||||
G4double kineticEnergy);
|
||||
|
||||
void SetChargeAndMoments(G4double charge,
|
||||
G4double magnetic_dipole_moment = DBL_MAX,
|
||||
G4double electric_dipole_moment = DBL_MAX,
|
||||
G4double magnetic_charge = DBL_MAX );
|
||||
// Set the charges and moments that are not given as DBL_MAX
|
||||
/**
|
||||
* Updates momentum, direction and kinetic energy.
|
||||
* @param[in] kineticEnergy Kinetic energy value.
|
||||
* @param[in] pMomentumDirection Direction vector.
|
||||
*/
|
||||
inline void UpdateFourMomentum( G4double kineticEnergy,
|
||||
const G4ThreeVector& momentumDirection );
|
||||
|
||||
inline void SetPDGSpin(G4double pdgSpin);
|
||||
inline G4double GetPDGSpin();
|
||||
/**
|
||||
* Sets the charges and moments that are not given as DBL_MAX.
|
||||
* @param[in] charge Charge value.
|
||||
* @param[in] magnetic_dipole_moment M agnetic dipole moment.
|
||||
* @param[in] electric_dipole_moment Electric dipole moment.
|
||||
* @param[in] magnetic_charge Magnetic charge.
|
||||
*/
|
||||
void SetChargeAndMoments(G4double charge,
|
||||
G4double magnetic_dipole_moment = DBL_MAX,
|
||||
G4double electric_dipole_moment = DBL_MAX,
|
||||
G4double magnetic_charge = DBL_MAX );
|
||||
|
||||
inline G4ThreeVector GetMomentum() const;
|
||||
inline G4ThreeVector GetPosition() const;
|
||||
inline const G4ThreeVector& GetMomentumDir() const;
|
||||
inline G4ThreeVector GetMomentumDirection() const;
|
||||
inline G4double GetCurveLength() const;
|
||||
// Distance along curve of point.
|
||||
/**
|
||||
* Setter and getter for PDG spin.
|
||||
*/
|
||||
inline void SetPDGSpin(G4double pdgSpin);
|
||||
inline G4double GetPDGSpin();
|
||||
|
||||
inline G4ThreeVector GetPolarization() const;
|
||||
inline void SetPolarization( const G4ThreeVector& vecPol );
|
||||
/**
|
||||
* Accessors.
|
||||
*/
|
||||
inline G4ThreeVector GetMomentum() const;
|
||||
inline G4ThreeVector GetPosition() const;
|
||||
inline const G4ThreeVector& GetMomentumDir() const;
|
||||
inline G4ThreeVector GetMomentumDirection() const;
|
||||
inline G4double GetCurveLength() const;
|
||||
inline const G4ChargeState* GetChargeState() const;
|
||||
inline G4double GetLabTimeOfFlight() const;
|
||||
inline G4double GetProperTimeOfFlight() const;
|
||||
inline G4double GetKineticEnergy() const;
|
||||
inline G4double GetCharge() const;
|
||||
inline G4double GetRestMass() const;
|
||||
|
||||
inline const G4ChargeState* GetChargeState() const;
|
||||
inline G4double GetLabTimeOfFlight() const;
|
||||
inline G4double GetProperTimeOfFlight() const;
|
||||
inline G4double GetKineticEnergy() const;
|
||||
inline G4double GetCharge() const;
|
||||
inline G4double GetRestMass() const;
|
||||
// Accessors.
|
||||
/**
|
||||
* Getter and setter for polarisation.
|
||||
*/
|
||||
inline G4ThreeVector GetPolarization() const;
|
||||
inline void SetPolarization( const G4ThreeVector& vecPol );
|
||||
|
||||
inline void SetPosition(const G4ThreeVector& nPos);
|
||||
inline void SetMomentum(const G4ThreeVector& nMomDir);
|
||||
// Does change mom-dir too.
|
||||
/**
|
||||
* Setters for momentum. SetMomentumDir() does not change momentum
|
||||
* or Velocity Vector.
|
||||
*/
|
||||
inline void SetMomentum(const G4ThreeVector& nMomDir);
|
||||
inline void SetMomentumDir(const G4ThreeVector& nMomDir);
|
||||
|
||||
inline void SetMomentumDir(const G4ThreeVector& nMomDir);
|
||||
// Does NOT change Momentum or Velocity Vector.
|
||||
/**
|
||||
* Modifiers.
|
||||
*/
|
||||
inline void SetPosition(const G4ThreeVector& nPos);
|
||||
inline void SetRestMass(G4double Mass_c2);
|
||||
inline void SetCurveLength(G4double nCurve_s); // Distance along curve.
|
||||
inline void SetKineticEnergy(G4double nEnergy); // Does not modify momentum.
|
||||
inline void SetLabTimeOfFlight(G4double tofLab);
|
||||
inline void SetProperTimeOfFlight(G4double tofProper);
|
||||
|
||||
inline void SetRestMass(G4double Mass_c2);
|
||||
|
||||
inline void SetCurveLength(G4double nCurve_s);
|
||||
// Distance along curve.
|
||||
inline void SetKineticEnergy(G4double nEnergy);
|
||||
// Does not modify momentum.
|
||||
enum { ncompSVEC = 12 }; // Needed; should be used only for RK integration driver
|
||||
|
||||
inline void SetLabTimeOfFlight(G4double tofLab);
|
||||
inline void SetProperTimeOfFlight(G4double tofProper);
|
||||
// Modifiers
|
||||
/**
|
||||
* Dumps/loads values to/from a provided array 'valArray'.
|
||||
*/
|
||||
inline void DumpToArray(G4double valArr[ncompSVEC]) const;
|
||||
void LoadFromArray(const G4double valArr[ncompSVEC],
|
||||
G4int noVarsIntegrated);
|
||||
|
||||
public: // without description
|
||||
/**
|
||||
* More setters/getter foe spin, now obsolete.
|
||||
*/
|
||||
inline void InitialiseSpin( const G4ThreeVector& vecPolarization );
|
||||
inline G4ThreeVector GetSpin() const;
|
||||
inline void SetSpin(const G4ThreeVector& vSpin);
|
||||
|
||||
enum { ncompSVEC = 12 };
|
||||
// Needed and should be used only for RK integration driver
|
||||
private:
|
||||
|
||||
inline void DumpToArray(G4double valArr[ncompSVEC]) const;
|
||||
void LoadFromArray(const G4double valArr[ncompSVEC],
|
||||
G4int noVarsIntegrated);
|
||||
friend std::ostream&
|
||||
operator<<( std::ostream& os, const G4FieldTrack& SixVec);
|
||||
/**
|
||||
* Implementation method. Obsolete.
|
||||
*/
|
||||
inline G4FieldTrack& SetCurvePnt(const G4ThreeVector& pPosition,
|
||||
const G4ThreeVector& pMomentum,
|
||||
G4double s_curve );
|
||||
private:
|
||||
|
||||
public: // Obsolete methods -- due to potential confusion with PDG spin
|
||||
|
||||
inline void InitialiseSpin( const G4ThreeVector& vecPolarization );
|
||||
inline G4ThreeVector GetSpin() const;
|
||||
inline void SetSpin(const G4ThreeVector& vSpin);
|
||||
|
||||
private: // Implementation method -- Obsolete
|
||||
|
||||
inline G4FieldTrack& SetCurvePnt(const G4ThreeVector& pPosition,
|
||||
const G4ThreeVector& pMomentum,
|
||||
G4double s_curve );
|
||||
private:
|
||||
|
||||
G4double SixVector[6];
|
||||
G4double fDistanceAlongCurve; // distance along curve of point
|
||||
G4double fKineticEnergy;
|
||||
G4double fRestMass_c2;
|
||||
G4double fLabTimeOfFlight;
|
||||
G4double fProperTimeOfFlight;
|
||||
G4ThreeVector fPolarization;
|
||||
G4ThreeVector fMomentumDir;
|
||||
// G4double fInitialMomentumMag; // At 'track' creation.
|
||||
// G4double fLastMomentumMag; // From last Update (for checking.)
|
||||
|
||||
G4ChargeState fChargeState;
|
||||
G4double SixVector[6];
|
||||
G4double fDistanceAlongCurve; // distance along curve of point
|
||||
G4double fKineticEnergy;
|
||||
G4double fRestMass_c2;
|
||||
G4double fLabTimeOfFlight;
|
||||
G4double fProperTimeOfFlight;
|
||||
G4ThreeVector fPolarization;
|
||||
G4ThreeVector fMomentumDir;
|
||||
G4ChargeState fChargeState;
|
||||
};
|
||||
|
||||
#include "G4FieldTrack.icc"
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
//
|
||||
// G4FieldTrack inline methods implementation
|
||||
//
|
||||
// Author: John Apostolakis, CERN - First version, 14.10.1996
|
||||
// Author: John Apostolakis (CERN), 14.10.1996 - First version
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
inline
|
||||
@@ -35,7 +35,6 @@ G4FieldTrack::G4FieldTrack( const G4FieldTrack& rStVec )
|
||||
fRestMass_c2( rStVec.fRestMass_c2),
|
||||
fLabTimeOfFlight( rStVec.fLabTimeOfFlight ),
|
||||
fProperTimeOfFlight( rStVec.fProperTimeOfFlight ),
|
||||
// fMomentumModulus( rStVec.fMomentumModulus ),
|
||||
fPolarization( rStVec.fPolarization ),
|
||||
fMomentumDir( rStVec.fMomentumDir ),
|
||||
fChargeState( rStVec.fChargeState )
|
||||
@@ -101,8 +100,7 @@ G4FieldTrack::G4FieldTrack(G4FieldTrack&& from) noexcept
|
||||
inline
|
||||
G4FieldTrack& G4FieldTrack::operator=(G4FieldTrack&& from) noexcept
|
||||
{
|
||||
if (&from == this) { return *this;
|
||||
}
|
||||
if (&from == this) { return *this; }
|
||||
|
||||
SixVector[0]= from.SixVector[0];
|
||||
SixVector[1]= from.SixVector[1];
|
||||
@@ -175,8 +173,6 @@ void G4FieldTrack::SetPosition( const G4ThreeVector& pPosition)
|
||||
inline
|
||||
const G4ThreeVector& G4FieldTrack::GetMomentumDir() const
|
||||
{
|
||||
// G4ThreeVector myMomentum( SixVector[3], SixVector[4], SixVector[5] );
|
||||
// return myVelocity;
|
||||
return fMomentumDir;
|
||||
}
|
||||
|
||||
@@ -337,8 +333,6 @@ void G4FieldTrack::UpdateFourMomentum( G4double kineticEnergy,
|
||||
+2.0*fRestMass_c2*kineticEnergy);
|
||||
G4ThreeVector momentumVector = momentum_mag * momentumDirection;
|
||||
|
||||
// SetMomentum( momentumVector );
|
||||
// Set direction (from unit): used sqrt, div
|
||||
SixVector[3] = momentumVector.x();
|
||||
SixVector[4] = momentumVector.y();
|
||||
SixVector[5] = momentumVector.z();
|
||||
@@ -353,11 +347,9 @@ void G4FieldTrack::UpdateState( const G4ThreeVector& position,
|
||||
const G4ThreeVector& momentumDirection,
|
||||
G4double kineticEnergy )
|
||||
{
|
||||
// SetCurvePnt( position, momentumVector, s_curve=0.0);
|
||||
SetPosition( position);
|
||||
fLabTimeOfFlight = laboratoryTimeOfFlight;
|
||||
fDistanceAlongCurve = 0.0;
|
||||
|
||||
UpdateFourMomentum( kineticEnergy, momentumDirection);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,11 +26,11 @@
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
// Simple methods to extract vectors from arrays in conventions of
|
||||
// the magnetic field integration.
|
||||
// Simple methods to extract vectors from arrays in conventions of
|
||||
// the magnetic field integration.
|
||||
|
||||
// Author: Dmitry Sorokin, Google Summer of Code 2017
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// Author: Dmitry Sorokin (CERN, Google Summer of Code 2017), 13.10.2017
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4FIELD_UTILS_HH
|
||||
#define G4FIELD_UTILS_HH
|
||||
@@ -39,9 +39,13 @@
|
||||
#include "G4Types.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
|
||||
/**
|
||||
* @brief field_utils is a helper namespace, including simple methods to extract
|
||||
* vectors from arrays in conventions of the magnetic field integration.
|
||||
*/
|
||||
|
||||
namespace field_utils
|
||||
{
|
||||
|
||||
using State = G4double[G4FieldTrack::ncompSVEC];
|
||||
|
||||
template <unsigned int N>
|
||||
@@ -108,8 +112,7 @@ namespace field_utils
|
||||
|
||||
template <typename T>
|
||||
T clamp(T value, T lo, T hi);
|
||||
|
||||
} // field_utils
|
||||
}
|
||||
|
||||
#include "G4FieldUtils.icc"
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
//
|
||||
// Helper namespace field_utils inline implementation
|
||||
|
||||
// Author: Dmitry Sorokin, Google Summer of Code 2017
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// Author: Dmitry Sorokin (CERN, Google Summer of Code 2017), 13.10.2017
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
namespace field_utils {
|
||||
@@ -42,27 +42,27 @@ namespace internal
|
||||
template <typename ArrayType>
|
||||
inline G4double getValue(const ArrayType& array, Value1D value)
|
||||
{
|
||||
const auto begin = internal::getFirstIndex(value);
|
||||
return array[begin];
|
||||
const auto begin = internal::getFirstIndex(value);
|
||||
return array[begin];
|
||||
}
|
||||
|
||||
template <typename ArrayType>
|
||||
G4double getValue2(const ArrayType& array, Value1D value)
|
||||
{
|
||||
return sqr(getValue(array, value));
|
||||
return sqr(getValue(array, value));
|
||||
}
|
||||
|
||||
template <typename ArrayType>
|
||||
G4double getValue(const ArrayType& array, Value3D value)
|
||||
{
|
||||
return std::sqrt(getValue2(array, value));
|
||||
return std::sqrt(getValue2(array, value));
|
||||
}
|
||||
|
||||
template <typename ArrayType>
|
||||
G4double getValue2(const ArrayType& array, const Value3D value)
|
||||
{
|
||||
const auto begin = internal::getFirstIndex(value);
|
||||
return sqr(array[begin]) + sqr(array[begin+1]) + sqr(array[begin+2]);
|
||||
const auto begin = internal::getFirstIndex(value);
|
||||
return sqr(array[begin]) + sqr(array[begin+1]) + sqr(array[begin+2]);
|
||||
}
|
||||
|
||||
template <typename ArrayType>
|
||||
@@ -75,23 +75,23 @@ G4ThreeVector makeVector(const ArrayType& array, Value3D value)
|
||||
template <typename SourceArray, typename TargetArray>
|
||||
void setValue(const SourceArray& src, Value1D value, TargetArray& trg)
|
||||
{
|
||||
const auto begin = internal::getFirstIndex(value);
|
||||
trg[begin] = src[begin];
|
||||
const auto begin = internal::getFirstIndex(value);
|
||||
trg[begin] = src[begin];
|
||||
}
|
||||
|
||||
template <typename SourceArray, typename TargetArray, typename ...TargetArrays>
|
||||
void setValue(const SourceArray& src, Value1D value,
|
||||
TargetArray& trg, TargetArrays&... trgs)
|
||||
{
|
||||
const auto begin = internal::getFirstIndex(value);
|
||||
trg[begin] = src[begin];
|
||||
setValue(src, value, trgs...);
|
||||
const auto begin = internal::getFirstIndex(value);
|
||||
trg[begin] = src[begin];
|
||||
setValue(src, value, trgs...);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T clamp(T value, T lo, T hi)
|
||||
{
|
||||
return std::min(std::max(lo, value), hi);
|
||||
return std::min(std::max(lo, value), hi);
|
||||
}
|
||||
|
||||
} // field_utils
|
||||
|
||||
@@ -34,22 +34,38 @@
|
||||
// M.Metcalf, Analysis of the SFM Field
|
||||
// OM Development Note AP-10 (revised), 1974
|
||||
|
||||
// Author: V.Grichine, 03.02.1997
|
||||
// Author: Vladimir Grichine (CERN), 03.02.1997
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4HARMONICPOLMAGFIELD_HH
|
||||
#define G4HARMONICPOLMAGFIELD_HH
|
||||
|
||||
#include "G4MagneticField.hh"
|
||||
|
||||
/**
|
||||
* @brief G4HarmonicPolMagField describes a magnetic field parametrised
|
||||
* by harmonic polynom up to 3rd order.
|
||||
*/
|
||||
|
||||
class G4HarmonicPolMagField : public G4MagneticField
|
||||
{
|
||||
public:
|
||||
|
||||
G4HarmonicPolMagField();
|
||||
~G4HarmonicPolMagField() override;
|
||||
/**
|
||||
* Default Constructor and Destructor.
|
||||
*/
|
||||
G4HarmonicPolMagField() = default;
|
||||
~G4HarmonicPolMagField() override = default;
|
||||
|
||||
void GetFieldValue(const G4double yTrack[] ,
|
||||
G4double B[] ) const override ;
|
||||
/**
|
||||
* Returns the field value on the given position 'yTrack'.
|
||||
* @param[in] yTrack Time position array.
|
||||
* @param[out] B The returned field array.
|
||||
*/
|
||||
void GetFieldValue(const G4double yTrack[], G4double B[]) const override;
|
||||
|
||||
/**
|
||||
* Returns a pointer to a new allocated clone of this object.
|
||||
*/
|
||||
G4HarmonicPolMagField* Clone() const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -32,34 +32,75 @@
|
||||
// A simple approach for solving linear differential equations.
|
||||
// Take the current derivative and add it to the current position.
|
||||
|
||||
// Author: W.Wander <wwc@mit.edu>, 12.09.1997
|
||||
// Author: W.Wander (MIT), 12.09.1997
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4HELIXEXPLICITEULER_HH
|
||||
#define G4HELIXEXPLICITEULER_HH
|
||||
|
||||
#include "G4MagHelicalStepper.hh"
|
||||
|
||||
/**
|
||||
* @brief G4HelixExplicitEuler implements an Explicit Euler stepper for
|
||||
* magnetic field: x_1 = x_0 + helix(h), with helix(h) being a helix piece
|
||||
* of length h. A simple approach for solving linear differential equations.
|
||||
* Takes the current derivative and adds it to the current position.
|
||||
*/
|
||||
|
||||
class G4HelixExplicitEuler : public G4MagHelicalStepper
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4HelixExplicitEuler.
|
||||
* @param[in] EqRhs Pointer to the provided equation of motion.
|
||||
*/
|
||||
G4HelixExplicitEuler(G4Mag_EqRhs* EqRhs);
|
||||
~G4HelixExplicitEuler() override;
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4HelixExplicitEuler() override = default;
|
||||
|
||||
/**
|
||||
* The stepper function for the integration.
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] na Not used.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
* @param[out] yerr Integration error.
|
||||
*/
|
||||
void Stepper( const G4double y[],
|
||||
const G4double*,
|
||||
const G4double* na,
|
||||
G4double h,
|
||||
G4double yout[],
|
||||
G4double yerr[] ) override;
|
||||
|
||||
/**
|
||||
* The stepper function for the integration.
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] Bfld Derivatives array.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
*/
|
||||
void DumbStepper( const G4double y[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yout[]) override;
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yout[]) override;
|
||||
|
||||
/**
|
||||
* Returns the distance from chord line.
|
||||
*/
|
||||
G4double DistChord() const override;
|
||||
|
||||
/**
|
||||
* Returns the order, 1, of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override { return 1; }
|
||||
|
||||
/**
|
||||
* Returns the stepper type-ID, "kHelixExplicitEuler".
|
||||
*/
|
||||
inline G4StepperType StepperType() const override { return kHelixExplicitEuler; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -33,26 +33,54 @@
|
||||
// 3/4 * dx(t0+2/3*h, x0+2/3*h*(dx(t0+h/3,x0+h/3*dx(t0,x0))))
|
||||
// Third order solver.
|
||||
|
||||
// Author: W.Wander <wwc@mit.edu>, 03/11/1998
|
||||
// Author: W.Wander (MIT), 03.11.1998
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4HELIXHEUM_HH
|
||||
#define G4HELIXHEUM_HH
|
||||
|
||||
#include "G4MagHelicalStepper.hh"
|
||||
|
||||
/**
|
||||
* @brief G4HelixHeum implements a simple Heum stepper for magnetic field
|
||||
* with 3rd order solver.
|
||||
*/
|
||||
|
||||
class G4HelixHeum : public G4MagHelicalStepper
|
||||
{
|
||||
public:
|
||||
|
||||
G4HelixHeum(G4Mag_EqRhs *EqRhs);
|
||||
~G4HelixHeum() override;
|
||||
/**
|
||||
* Constructor for G4HelixHeum.
|
||||
* @param[in] EqRhs Pointer to the provided equation of motion.
|
||||
*/
|
||||
G4HelixHeum(G4Mag_EqRhs* EqRhs);
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4HelixHeum() override = default;
|
||||
|
||||
/**
|
||||
* The stepper function for the integration.
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] Bfld The field vector.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
*/
|
||||
void DumbStepper( const G4double y[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yout[] ) override;
|
||||
G4double h,
|
||||
G4double yout[] ) override;
|
||||
|
||||
/**
|
||||
* Returns the order, 2, of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override { return 2; }
|
||||
|
||||
/**
|
||||
* Returns the stepper type-ID, "kHelixHeum".
|
||||
*/
|
||||
inline G4StepperType StepperType() const override { return kHelixHeum; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,26 +35,54 @@
|
||||
// Take the output and its derivative. Add the mean of both derivatives
|
||||
// to form the final output.
|
||||
|
||||
// Author: W.Wander <wwc@mit.edu>, 03/11/1998
|
||||
// Author: W.Wander (MIT), 03.11.1998
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4HELIXIMPLICITEULER_HH
|
||||
#define G4HELIXIMPLICITEULER_HH
|
||||
|
||||
#include "G4MagHelicalStepper.hh"
|
||||
|
||||
/**
|
||||
* @brief G4HelixImplicitEuler implements a helix implicit Euler
|
||||
* stepper for magnetic field with 2nd order solver.
|
||||
*/
|
||||
|
||||
class G4HelixImplicitEuler : public G4MagHelicalStepper
|
||||
{
|
||||
public:
|
||||
|
||||
G4HelixImplicitEuler(G4Mag_EqRhs *EqRhs);
|
||||
~G4HelixImplicitEuler() override;
|
||||
/**
|
||||
* Constructor for G4HelixImplicitEuler.
|
||||
* @param[in] EqRhs Pointer to the provided equation of motion.
|
||||
*/
|
||||
G4HelixImplicitEuler(G4Mag_EqRhs* EqRhs);
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4HelixImplicitEuler() override = default;
|
||||
|
||||
/**
|
||||
* The stepper function for the integration.
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] Bfld Derivatives array.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
*/
|
||||
void DumbStepper( const G4double y[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yout[] ) override;
|
||||
G4double h,
|
||||
G4double yout[] ) override;
|
||||
|
||||
/**
|
||||
* Returns the order, 2, of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override { return 2; }
|
||||
|
||||
/**
|
||||
* Returns the stepper type-ID, "kHelixImplicitEuler".
|
||||
*/
|
||||
inline G4StepperType StepperType() const override { return kHelixImplicitEuler; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
// Else use HelixExplicitEuler Stepper
|
||||
//
|
||||
// Stepper for the small step is G4ClassicalRK4 by default, but
|
||||
// it possible to choose other stepper,like G4CashKarpRK45 or G4RKG3_Stepper,
|
||||
// by setting StepperNumber : new HelixMixedStepper(EqRhs,N)
|
||||
// it possible to choose other stepper,like G4CashKarpRK45 or G4RKG3_Stepper,
|
||||
// by setting StepperNumber : new HelixMixedStepper(EqRhs,N)
|
||||
//
|
||||
// N=2 G4SimpleRunge; N=3 G4SimpleHeum;
|
||||
// N=4 G4ClassicalRK4;
|
||||
@@ -45,71 +45,134 @@
|
||||
// N=23 BogackiShampine23 N=145 TsitourasRK45
|
||||
// N=45 BogackiShampine45 N=745 DormandPrince745 (ie DoPri5)
|
||||
//
|
||||
// For completeness also available are:
|
||||
// For completeness also available are:
|
||||
// N=11 G4ExplicitEuler N=12 G4ImplicitEuler; -- Likely poor
|
||||
// N=5 G4HelixExplicitEuler (testing only)
|
||||
// For recommendations see comments in 'SetupStepper' method.
|
||||
//
|
||||
// Note: Like other helix steppers, only applicable in pure magnetic field
|
||||
// Note: Like other helix steppers, only applicable in pure magnetic field.
|
||||
|
||||
// Created: T.Nikitina, CERN - 18.05.2007, derived from G4ExactHelicalStepper
|
||||
// Author: Tatiana Nikitina (CERN), 18.05.2007
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4HELIXMIXEDSTEPPER_HH
|
||||
#define G4HELIXMIXEDSTEPPER_HH
|
||||
|
||||
#include "G4MagHelicalStepper.hh"
|
||||
|
||||
/**
|
||||
* @brief G4HelixMixedStepper is a concrete class for particle motion in
|
||||
* magnetic field which splits the method used for Integration in two:
|
||||
* if the stepping angle ( h / R_curve) is less than pi/3, use a RK stepper
|
||||
* for small step, else use G4HelixExplicitEuler stepper.
|
||||
* Like other helix steppers, it is only applicable in pure magnetic field.
|
||||
*/
|
||||
|
||||
class G4HelixMixedStepper : public G4MagHelicalStepper
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4ExactHelixStepper.
|
||||
* @param[in] EqRhs Pointer to the standard equation of motion.
|
||||
* @param[in] StepperNumber Identified for selecting the stepper type;
|
||||
* default (-1) is DormandPrince745.
|
||||
* @param[in] Angle_threshold The stepping angle threshold; default (-1)
|
||||
* is (1/3)*pi.
|
||||
*/
|
||||
G4HelixMixedStepper(G4Mag_EqRhs* EqRhs,
|
||||
G4int StepperNumber = -1,
|
||||
G4double Angle_threshold = -1.0);
|
||||
~G4HelixMixedStepper() override;
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4HelixMixedStepper() override;
|
||||
|
||||
/**
|
||||
* The integration stepper. The stepsize is fixed, with the step size
|
||||
* given by 'hstep'. Integrates ODE starting values yInput[0 to 6].
|
||||
* Outputs yout[] and its estimated error yerr[].
|
||||
* If SteppingAngle = h/R_curve < pi/3, uses default RK stepper else
|
||||
* use Helix fast method.
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
* @param[out] yerr The estimated error.
|
||||
*/
|
||||
void Stepper( const G4double y[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yout[],
|
||||
G4double yerr[] ) override;
|
||||
// Step 'integration' for step size 'h'
|
||||
// If SteppingAngle= h/R_curve < pi/3 uses default RK stepper
|
||||
// else use Helix Fast Method
|
||||
|
||||
/**
|
||||
* Same as Stepper() function above, but should perform a 'dump' step
|
||||
* without error calculation. Assuming a constant field, the solution is
|
||||
* a helix.
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] Bfld The field vector.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
*/
|
||||
void DumbStepper( const G4double y[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yout[]) override;
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yout[] ) override;
|
||||
|
||||
/**
|
||||
* Estimates the maximum distance of curved solution and chord.
|
||||
*/
|
||||
G4double DistChord() const override;
|
||||
// Estimate maximum distance of curved solution and chord ...
|
||||
|
||||
/**
|
||||
* Sets the verbosity level.
|
||||
*/
|
||||
inline void SetVerbose (G4int newvalue) { fVerbose = newvalue; }
|
||||
|
||||
void PrintCalls();
|
||||
G4MagIntegratorStepper* SetupStepper(G4Mag_EqRhs* EqRhs, G4int StepperName);
|
||||
|
||||
/**
|
||||
* Setter and getter for the stepping angle threshold.
|
||||
*/
|
||||
inline void SetAngleThreshold( G4double val ) { fAngle_threshold = val; }
|
||||
inline G4double GetAngleThreshold() { return fAngle_threshold; }
|
||||
|
||||
/**
|
||||
* Returns the order, 4, of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override { return 4; }
|
||||
|
||||
/**
|
||||
* Returns the stepper type-ID, "kHelixMixedStepper".
|
||||
*/
|
||||
inline G4StepperType StepperType() const override { return kHelixMixedStepper; }
|
||||
|
||||
/**
|
||||
* Logger function for the number of calls.
|
||||
*/
|
||||
void PrintCalls();
|
||||
|
||||
/**
|
||||
* Sets the chosen stepper and equation of motion.
|
||||
*/
|
||||
G4MagIntegratorStepper* SetupStepper(G4Mag_EqRhs* EqRhs, G4int StepperName);
|
||||
|
||||
private:
|
||||
|
||||
/** Mixed Integration RK4 for 'small' steps. */
|
||||
G4MagIntegratorStepper* fRK4Stepper = nullptr;
|
||||
// Mixed Integration RK4 for 'small' steps
|
||||
|
||||
/** Int ID of Runge-Kutta stepper. */
|
||||
G4int fStepperNumber = -1;
|
||||
// Int ID of RK stepper
|
||||
|
||||
/** Threshold angle (in radians ); above it, the Helical stepper is used. */
|
||||
G4double fAngle_threshold = -1.0;
|
||||
// Threshold angle (in radians ) - above it Helical stepper is used
|
||||
|
||||
private:
|
||||
|
||||
/** Verbosity level. */
|
||||
G4int fVerbose = 0;
|
||||
|
||||
/** Used for statistic, i.e. how many calls to different steppers. */
|
||||
G4int fNumCallsRK4 = 0;
|
||||
G4int fNumCallsHelix = 0;
|
||||
// Used for statistic = how many calls to different steppers
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,33 +27,61 @@
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// Helix Simple Runge-Kutta stepper for magnetic field:
|
||||
// x_1 = x_0 + h * ( dx( t_0+h/2, x_0 + h/2 * dx( t_0, x_0) ) )
|
||||
// Helix Simple Runge-Kutta stepper for magnetic field:
|
||||
// x_1 = x_0 + h * ( dx( t_0+h/2, x_0 + h/2 * dx( t_0, x_0) ) )
|
||||
//
|
||||
// Second order solver.
|
||||
// Take the derivative at a position to be assumed at the middle of the
|
||||
// Step and add it to the current position.
|
||||
// Second order solver.
|
||||
// Take the derivative at a position to be assumed at the middle of the
|
||||
// Step and add it to the current position.
|
||||
|
||||
// Author: W. Wander <wwc@mit.edu>, 03.12.1998
|
||||
// Author: W.Wander (MIT), 03.12.1998
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4HELIXSIMPLERUNGE_HH
|
||||
#define G4HELIXSIMPLERUNGE_HH
|
||||
|
||||
#include "G4MagHelicalStepper.hh"
|
||||
|
||||
/**
|
||||
* @brief G4HelixSimpleRunge implements a simple Helix stepper for magnetic
|
||||
* field with 2nd order solver.
|
||||
*/
|
||||
|
||||
class G4HelixSimpleRunge : public G4MagHelicalStepper
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4HelixSimpleRunge.
|
||||
* @param[in] EqRhs Pointer to the provided equation of motion.
|
||||
*/
|
||||
G4HelixSimpleRunge(G4Mag_EqRhs* EqRhs);
|
||||
~G4HelixSimpleRunge() override;
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4HelixSimpleRunge() override = default;
|
||||
|
||||
/**
|
||||
* The stepper function for the integration.
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] Bfld The field vector.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
*/
|
||||
void DumbStepper( const G4double y[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yout[] ) override;
|
||||
G4double h,
|
||||
G4double yout[] ) override;
|
||||
|
||||
/**
|
||||
* Returns the order, 2, of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override { return 2; }
|
||||
|
||||
/**
|
||||
* Returns the stepper type-ID, "kHelixSimpleRunge".
|
||||
*/
|
||||
inline G4StepperType StepperType() const override { return kHelixSimpleRunge; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,32 +35,61 @@
|
||||
// Takes the output and its derivative. Adds the mean of both
|
||||
// derivatives to form the final output.
|
||||
|
||||
// Author: W. Wander <wwc@mit.edu>, 12.09.1997
|
||||
// Author: W.Wander (MIT), 12.09.1997
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4IMPLICITEULER_HH
|
||||
#define G4IMPLICITEULER_HH
|
||||
|
||||
#include "G4MagErrorStepper.hh"
|
||||
|
||||
/**
|
||||
* @brief G4ImplicitEuler implements a Euler stepper for magnetic field
|
||||
* with 2nd order solver.
|
||||
*/
|
||||
|
||||
class G4ImplicitEuler : public G4MagErrorStepper
|
||||
{
|
||||
public:
|
||||
|
||||
G4ImplicitEuler(G4EquationOfMotion* EqRhs, G4int numberOfVariables = 6);
|
||||
~G4ImplicitEuler() override;
|
||||
/**
|
||||
* Constructor for G4HelixSimpleRunge.
|
||||
* @param[in] EqRhs Pointer to the provided equation of motion.
|
||||
* @param[in] numberOfVariables The number of integration variables.
|
||||
*/
|
||||
G4ImplicitEuler(G4EquationOfMotion* EqRhs,
|
||||
G4int numberOfVariables = 6);
|
||||
|
||||
void DumbStepper( const G4double y[] ,
|
||||
const G4double dydx[] ,
|
||||
G4double h ,
|
||||
G4double yout[] ) override;
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~G4ImplicitEuler() override;
|
||||
|
||||
/**
|
||||
* The stepper function for the integration.
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] dydx The derivates array.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
*/
|
||||
void DumbStepper( const G4double y[] ,
|
||||
const G4double dydx[] ,
|
||||
G4double h ,
|
||||
G4double yout[] ) override;
|
||||
|
||||
/**
|
||||
* Returns the order, 2, of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override { return 2; }
|
||||
/**
|
||||
* Returns the stepper type-ID, "kImplicitEuler".
|
||||
*/
|
||||
inline G4StepperType StepperType() const override { return kImplicitEuler; }
|
||||
|
||||
private:
|
||||
|
||||
/** Temporaries, created to avoid new/delete on every call. */
|
||||
G4double* dydxTemp = nullptr;
|
||||
G4double* yTemp = nullptr;
|
||||
// Temporaries, created to avoid new/delete on every call
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
// have extra capabilities, in particular First Same As Last (FSAL)
|
||||
// and/or interpolation.
|
||||
|
||||
// Author: Dmitry Sorokin, Google Summer of Code 2017
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// Author: Dmitry Sorokin (CERN, Google Summer of Code 2017), 20.10.2017
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4INTEGRATIONDRIVER_HH
|
||||
#define G4INTEGRATIONDRIVER_HH
|
||||
@@ -44,92 +44,172 @@
|
||||
#include "G4RKIntegrationDriver.hh"
|
||||
#include "G4ChordFinderDelegate.hh"
|
||||
|
||||
/**
|
||||
* @brief G4IntegrationDriver is a templated driver class which controls the
|
||||
* integration error of a Runge-Kutta stepper.
|
||||
* It serves as the driver of choice for steppers which do not have extra
|
||||
* capabilities, in particular First Same As Last (FSAL) and/or interpolation.
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
class G4IntegrationDriver : public G4RKIntegrationDriver<T>,
|
||||
public G4ChordFinderDelegate<G4IntegrationDriver<T>>
|
||||
{
|
||||
public:
|
||||
|
||||
G4IntegrationDriver( G4double hminimum,
|
||||
T* stepper,
|
||||
G4int numberOfComponents = 6,
|
||||
G4int statisticsVerbosity = 0 );
|
||||
~G4IntegrationDriver() override;
|
||||
/**
|
||||
* Constructor for G4IntegrationDriver.
|
||||
* @param[in] hminimum Minimum allowed step.
|
||||
* @param[in] stepper Pointer to the stepper algorithm.
|
||||
* @param[in] numberOfComponents The number of integration variables,
|
||||
* if not matching stepper's number of variables, issue exception.
|
||||
* @param[in] statisticsVerbosity Verbosity level.
|
||||
*/
|
||||
inline G4IntegrationDriver( G4double hminimum,
|
||||
T* stepper,
|
||||
G4int numberOfComponents = 6,
|
||||
G4int statisticsVerbosity = 0 );
|
||||
|
||||
/**
|
||||
* Destructor. Provides statistics if verbosity level is greater than zero.
|
||||
*/
|
||||
inline ~G4IntegrationDriver() override;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4IntegrationDriver(const G4IntegrationDriver &) = delete;
|
||||
const G4IntegrationDriver& operator =(const G4IntegrationDriver &) = delete;
|
||||
|
||||
G4double AdvanceChordLimited(G4FieldTrack& track,
|
||||
G4double stepMax,
|
||||
G4double epsStep,
|
||||
G4double chordDistance) override;
|
||||
/**
|
||||
* Computes the step to take, based on chord limits.
|
||||
* @param[in,out] track The current track in field.
|
||||
* @param[in] stepMax Proposed step length.
|
||||
* @param[in] epsStep Requested accuracy, y_err/hstep.
|
||||
* @param[in] chordDistance Maximum sagitta distance.
|
||||
* @returns The length of step taken.
|
||||
*/
|
||||
inline G4double AdvanceChordLimited(G4FieldTrack& track,
|
||||
G4double stepMax,
|
||||
G4double epsStep,
|
||||
G4double chordDistance) override;
|
||||
|
||||
void OnStartTracking() override;
|
||||
void OnComputeStep(const G4FieldTrack* /*track*/ = nullptr) override {}
|
||||
G4bool DoesReIntegrate() const override { return true; }
|
||||
/**
|
||||
* Dispatch interface method for initialisation/reset of driver.
|
||||
*/
|
||||
inline void OnStartTracking() override;
|
||||
|
||||
G4bool AccurateAdvance(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps, // Requested y_err/hstep
|
||||
G4double hinitial = 0 ) override;
|
||||
// Integrates ODE from current s (s=s0) to s=s0+h with accuracy eps.
|
||||
// On output track is replaced by value at end of interval.
|
||||
// The concept is similar to the odeint routine from NRC p.721-722.
|
||||
/**
|
||||
* Dispatch interface method for computing step. Does nothing here.
|
||||
*/
|
||||
inline void OnComputeStep(const G4FieldTrack* /*track*/ = nullptr) override;
|
||||
|
||||
G4bool QuickAdvance( G4FieldTrack& fieldTrack,
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr) override;
|
||||
// QuickAdvance just tries one Step - it does not ensure accuracy.
|
||||
/**
|
||||
* The driver does implement re-integration. Returns true.
|
||||
*/
|
||||
inline G4bool DoesReIntegrate() const override;
|
||||
|
||||
void SetVerboseLevel(G4int newLevel) override;
|
||||
G4int GetVerboseLevel() const override;
|
||||
/**
|
||||
* Advances integration accurately by relative accuracy better than 'eps'.
|
||||
* On output the track is replaced by the value at the end of interval.
|
||||
* @param[in,out] track The current track in field.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[in] eps Requested accuracy, y_err/hstep.
|
||||
* @param[in] hinitial Initial minimum integration step.
|
||||
* @returns true if integration succeeds.
|
||||
*/
|
||||
inline G4bool AccurateAdvance(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps, // Requested y_err/hstep
|
||||
G4double hinitial = 0 ) override;
|
||||
|
||||
void StreamInfo( std::ostream& os ) const override;
|
||||
// Write out the parameters / state of the driver
|
||||
/**
|
||||
* Attempts one integration step, and returns estimated error 'dyerr'.
|
||||
* It does not ensure accuracy.
|
||||
* @param[in,out] fieldTrack The current track in field.
|
||||
* @param[in] dydx dydx array.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[out] dchord_step Estimated sagitta distance.
|
||||
* @param[out] dyerr Estimated error.
|
||||
* @returns true if integration succeeds.
|
||||
*/
|
||||
inline G4bool QuickAdvance(G4FieldTrack& fieldTrack,
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr) override;
|
||||
|
||||
/**
|
||||
* Takes one Step that is as large as possible while satisfying the
|
||||
* accuracy criterion.
|
||||
* @param[in,out] yVar The current track state, y.
|
||||
* @param[in] dydx dydx array.
|
||||
* @param[in,out] curveLength Step start, x.
|
||||
* @param[in] htry Step to attempt.
|
||||
* @param[in] eps The relative accuracy.
|
||||
* @param[out] hdid Step achieved.
|
||||
* @param[out] hnext Proposed next step.
|
||||
*/
|
||||
inline void OneGoodStep(G4double yVar[], // InOut
|
||||
const G4double dydx[],
|
||||
G4double& curveLength,
|
||||
G4double htry,
|
||||
G4double eps,
|
||||
G4double& hdid,
|
||||
G4double& hnext);
|
||||
|
||||
/**
|
||||
* Setter and getter for verbosity.
|
||||
*/
|
||||
inline void SetVerboseLevel(G4int newLevel) override;
|
||||
inline G4int GetVerboseLevel() const override;
|
||||
|
||||
/**
|
||||
* Writes out to stream the parameters/state of the driver.
|
||||
*/
|
||||
inline void StreamInfo( std::ostream& os ) const override;
|
||||
|
||||
// Accessors
|
||||
//
|
||||
G4double GetMinimumStep() const;
|
||||
void SetMinimumStep(G4double newval);
|
||||
/**
|
||||
* Getter and Setter for minimum allowed step.
|
||||
*/
|
||||
inline G4double GetMinimumStep() const;
|
||||
inline void SetMinimumStep(G4double newval);
|
||||
|
||||
void OneGoodStep( G4double yVar[], // InOut
|
||||
const G4double dydx[],
|
||||
G4double& curveLength,
|
||||
G4double htry,
|
||||
G4double eps,
|
||||
G4double& hdid,
|
||||
G4double& hnext);
|
||||
// This takes one Step that is of size htry, or as large
|
||||
// as possible while satisfying the accuracy criterion of:
|
||||
// yerr < eps * |y_end-y_start|
|
||||
|
||||
G4double GetSmallestFraction() const;
|
||||
void SetSmallestFraction(G4double val);
|
||||
/**
|
||||
* Getter and Setter for smallest fraction.
|
||||
*/
|
||||
inline G4double GetSmallestFraction() const;
|
||||
inline void SetSmallestFraction(G4double val);
|
||||
|
||||
protected:
|
||||
|
||||
void IncrementQuickAdvanceCalls();
|
||||
/**
|
||||
* Increments the counter for the number of calls to QuickAdvance().
|
||||
*/
|
||||
inline void IncrementQuickAdvanceCalls();
|
||||
|
||||
private:
|
||||
|
||||
void CheckStep(const G4ThreeVector& posIn,
|
||||
const G4ThreeVector& posOut,
|
||||
G4double hdid);
|
||||
/**
|
||||
* Checks accuracy of step distance on the end point.
|
||||
*/
|
||||
inline void CheckStep(const G4ThreeVector& posIn,
|
||||
const G4ThreeVector& posOut, G4double hdid);
|
||||
|
||||
private:
|
||||
|
||||
/** Minimum Step allowed in a Step (in absolute units). */
|
||||
G4double fMinimumStep;
|
||||
// Minimum Step allowed in a Step (in absolute units)
|
||||
|
||||
/** Smallest fraction of (existing) curve length in relative units.
|
||||
* Below this fraction the current step will be the last.
|
||||
* The expected range: smaller than 0.1 * epsilon and bigger than 5e-13
|
||||
* (range not enforced). */
|
||||
G4double fSmallestFraction{1e-12};
|
||||
// Smallest fraction of (existing) curve length - in relative units
|
||||
// below this fraction the current step will be the last
|
||||
// Expected range: smaller than 0.1 * epsilon and bigger than 5e-13
|
||||
// Note: this range is not enforced.
|
||||
|
||||
|
||||
/** Verbosity level for printing (debug, etc..)
|
||||
* Could be varied during tracking to help identifying issues. */
|
||||
G4int fVerboseLevel;
|
||||
// Verbosity level for printing (debug, ..)
|
||||
// Could be varied during tracking - to help identify issues
|
||||
|
||||
G4int fNoQuickAvanceCalls{0};
|
||||
G4int fNoAccurateAdvanceCalls{0};
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
//
|
||||
// G4IntegrationDriver inline implementation
|
||||
//
|
||||
// Author: Dmitry Sorokin, Google Summer of Code 2017
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// Author: Dmitry Sorokin (CERN, Google Summer of Code 2017), 20.10.2017
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4FieldUtils.hh"
|
||||
@@ -41,30 +41,30 @@ G4IntegrationDriver ( G4double hminimum, T* pStepper,
|
||||
fMinimumStep(hminimum),
|
||||
fVerboseLevel(statisticsVerbose)
|
||||
{
|
||||
if (numComponents != Base::GetStepper()->GetNumberOfVariables())
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Driver's number of integrated components "
|
||||
<< numComponents
|
||||
<< " != Stepper's number of components "
|
||||
<< pStepper->GetNumberOfVariables();
|
||||
G4Exception("G4IntegrationDriver","GeomField0002",
|
||||
FatalException, message);
|
||||
}
|
||||
if (numComponents != Base::GetStepper()->GetNumberOfVariables())
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Driver's number of integrated components "
|
||||
<< numComponents
|
||||
<< " != Stepper's number of components "
|
||||
<< pStepper->GetNumberOfVariables();
|
||||
G4Exception("G4IntegrationDriver","GeomField0002",
|
||||
FatalException, message);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4IntegrationDriver<T>::~G4IntegrationDriver()
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
if (fVerboseLevel > 0)
|
||||
{
|
||||
G4cout << "G4Integration Driver Stats: "
|
||||
<< "#QuickAdvance " << fNoQuickAvanceCalls
|
||||
<< " - #AccurateAdvance " << fNoAccurateAdvanceCalls << " "
|
||||
<< "#good steps " << fNoAccurateAdvanceGoodSteps << " "
|
||||
<< "#bad steps " << fNoAccurateAdvanceBadSteps << G4endl;
|
||||
}
|
||||
if (fVerboseLevel > 0)
|
||||
{
|
||||
G4cout << "G4Integration Driver Stats: "
|
||||
<< "#QuickAdvance " << fNoQuickAvanceCalls
|
||||
<< " - #AccurateAdvance " << fNoAccurateAdvanceCalls << " "
|
||||
<< "#good steps " << fNoAccurateAdvanceGoodSteps << " "
|
||||
<< "#bad steps " << fNoAccurateAdvanceBadSteps << G4endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -74,14 +74,25 @@ G4double G4IntegrationDriver<T>::AdvanceChordLimited(G4FieldTrack& track,
|
||||
G4double epsStep,
|
||||
G4double chordDistance)
|
||||
{
|
||||
return ChordFinderDelegate::AdvanceChordLimitedImpl(track, stepMax, epsStep,
|
||||
chordDistance);
|
||||
return ChordFinderDelegate::AdvanceChordLimitedImpl(track, stepMax, epsStep,
|
||||
chordDistance);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::OnStartTracking()
|
||||
{
|
||||
ChordFinderDelegate::ResetStepEstimate();
|
||||
ChordFinderDelegate::ResetStepEstimate();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::OnComputeStep(const G4FieldTrack*)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4bool G4IntegrationDriver<T>::DoesReIntegrate() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Runge-Kutta driver with adaptive stepsize control. Integrate starting
|
||||
@@ -95,110 +106,110 @@ G4bool G4IntegrationDriver<T>::
|
||||
AccurateAdvance(G4FieldTrack& track, G4double hstep,
|
||||
G4double eps, G4double hinitial)
|
||||
{
|
||||
++fNoAccurateAdvanceCalls;
|
||||
++fNoAccurateAdvanceCalls;
|
||||
|
||||
if (hstep == 0.0)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Proposed step is zero; hstep = " << hstep << " !";
|
||||
G4Exception("G4IntegrationDriver::AccurateAdvance()",
|
||||
"GeomField1001", JustWarning, message);
|
||||
return true;
|
||||
}
|
||||
if (hstep == 0.0)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Proposed step is zero; hstep = " << hstep << " !";
|
||||
G4Exception("G4IntegrationDriver::AccurateAdvance()",
|
||||
"GeomField1001", JustWarning, message);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hstep < 0)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Invalid run condition." << G4endl
|
||||
<< "Proposed step is negative; hstep = " << hstep << "."
|
||||
<< G4endl
|
||||
<< "Requested step cannot be negative! Aborting event.";
|
||||
G4Exception("G4IntegrationDriver::AccurateAdvance()",
|
||||
"GeomField0003", EventMustBeAborted, message);
|
||||
return false;
|
||||
}
|
||||
if (hstep < 0)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Invalid run condition." << G4endl
|
||||
<< "Proposed step is negative; hstep = " << hstep << "."
|
||||
<< G4endl
|
||||
<< "Requested step cannot be negative! Aborting event.";
|
||||
G4Exception("G4IntegrationDriver::AccurateAdvance()",
|
||||
"GeomField0003", EventMustBeAborted, message);
|
||||
return false;
|
||||
}
|
||||
|
||||
G4double hnext, hdid;
|
||||
G4double hnext, hdid;
|
||||
|
||||
G4double dydx[G4FieldTrack::ncompSVEC];
|
||||
G4bool succeeded = true;
|
||||
G4double dydx[G4FieldTrack::ncompSVEC];
|
||||
G4bool succeeded = true;
|
||||
|
||||
G4double y[G4FieldTrack::ncompSVEC];
|
||||
track.DumpToArray(y);
|
||||
G4double y[G4FieldTrack::ncompSVEC];
|
||||
track.DumpToArray(y);
|
||||
|
||||
const G4double startCurveLength = track.GetCurveLength();
|
||||
const G4double endCurveLength = startCurveLength + hstep;
|
||||
const G4double hThreshold =
|
||||
const G4double startCurveLength = track.GetCurveLength();
|
||||
const G4double endCurveLength = startCurveLength + hstep;
|
||||
const G4double hThreshold =
|
||||
std::min(eps * hstep, fSmallestFraction * startCurveLength);
|
||||
|
||||
G4double h = hstep;
|
||||
if (hinitial > CLHEP::perMillion * hstep && hinitial < hstep)
|
||||
{
|
||||
h = hinitial;
|
||||
}
|
||||
G4double h = hstep;
|
||||
if (hinitial > CLHEP::perMillion * hstep && hinitial < hstep)
|
||||
{
|
||||
h = hinitial;
|
||||
}
|
||||
|
||||
G4double curveLength = startCurveLength;
|
||||
G4double curveLength = startCurveLength;
|
||||
|
||||
for (G4int nstp = 0; nstp < Base::GetMaxNoSteps(); ++nstp)
|
||||
{
|
||||
const G4ThreeVector StartPos =
|
||||
field_utils::makeVector(y, field_utils::Value3D::Position);
|
||||
for (G4int nstp = 0; nstp < Base::GetMaxNoSteps(); ++nstp)
|
||||
{
|
||||
const G4ThreeVector StartPos =
|
||||
field_utils::makeVector(y, field_utils::Value3D::Position);
|
||||
|
||||
Base::GetStepper()->RightHandSide(y, dydx);
|
||||
Base::GetStepper()->RightHandSide(y, dydx);
|
||||
|
||||
if (h > GetMinimumStep())
|
||||
{
|
||||
OneGoodStep(y, dydx, curveLength, h, eps, hdid, hnext);
|
||||
}
|
||||
else
|
||||
{
|
||||
G4FieldTrack yFldTrk('0');
|
||||
G4double dchord_step, dyerr, dyerr_len;
|
||||
yFldTrk.LoadFromArray(y, Base::GetStepper()->GetNumberOfVariables());
|
||||
yFldTrk.SetCurveLength(curveLength);
|
||||
|
||||
QuickAdvance(yFldTrk, dydx, h, dchord_step, dyerr_len);
|
||||
|
||||
yFldTrk.DumpToArray(y);
|
||||
|
||||
if (h == 0.0)
|
||||
{
|
||||
G4Exception("G4IntegrationDriver::AccurateAdvance()",
|
||||
"GeomField0003", FatalException,
|
||||
"Integration Step became Zero!");
|
||||
}
|
||||
dyerr = dyerr_len / h;
|
||||
hdid = h;
|
||||
curveLength += hdid;
|
||||
hnext = Base::ComputeNewStepSize(dyerr / eps, h);
|
||||
}
|
||||
|
||||
const G4ThreeVector EndPos =
|
||||
field_utils::makeVector(y, field_utils::Value3D::Position);
|
||||
|
||||
CheckStep(EndPos, StartPos, hdid);
|
||||
|
||||
// Avoid numerous small last steps
|
||||
if (h < hThreshold || curveLength >= endCurveLength)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
h = std::max(hnext, GetMinimumStep());
|
||||
if (curveLength + h > endCurveLength)
|
||||
{
|
||||
h = endCurveLength - curveLength;
|
||||
}
|
||||
if (h > GetMinimumStep())
|
||||
{
|
||||
OneGoodStep(y, dydx, curveLength, h, eps, hdid, hnext);
|
||||
}
|
||||
// Have we reached the end ?
|
||||
// --> a better test might be x-endCurveLength > an_epsilon
|
||||
succeeded = (curveLength >= endCurveLength);
|
||||
// If it was a "forced" last step
|
||||
else
|
||||
{
|
||||
G4FieldTrack yFldTrk('0');
|
||||
G4double dchord_step, dyerr, dyerr_len;
|
||||
yFldTrk.LoadFromArray(y, Base::GetStepper()->GetNumberOfVariables());
|
||||
yFldTrk.SetCurveLength(curveLength);
|
||||
|
||||
track.LoadFromArray(y, Base::GetStepper()->GetNumberOfVariables());
|
||||
track.SetCurveLength(curveLength);
|
||||
QuickAdvance(yFldTrk, dydx, h, dchord_step, dyerr_len);
|
||||
|
||||
return succeeded;
|
||||
yFldTrk.DumpToArray(y);
|
||||
|
||||
if (h == 0.0)
|
||||
{
|
||||
G4Exception("G4IntegrationDriver::AccurateAdvance()",
|
||||
"GeomField0003", FatalException,
|
||||
"Integration Step became Zero!");
|
||||
}
|
||||
dyerr = dyerr_len / h;
|
||||
hdid = h;
|
||||
curveLength += hdid;
|
||||
hnext = Base::ComputeNewStepSize(dyerr / eps, h);
|
||||
}
|
||||
|
||||
const G4ThreeVector EndPos =
|
||||
field_utils::makeVector(y, field_utils::Value3D::Position);
|
||||
|
||||
CheckStep(EndPos, StartPos, hdid);
|
||||
|
||||
// Avoid numerous small last steps
|
||||
if (h < hThreshold || curveLength >= endCurveLength)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
h = std::max(hnext, GetMinimumStep());
|
||||
if (curveLength + h > endCurveLength)
|
||||
{
|
||||
h = endCurveLength - curveLength;
|
||||
}
|
||||
}
|
||||
// Have we reached the end ?
|
||||
// --> a better test might be x-endCurveLength > an_epsilon
|
||||
succeeded = (curveLength >= endCurveLength);
|
||||
// If it was a "forced" last step
|
||||
|
||||
track.LoadFromArray(y, Base::GetStepper()->GetNumberOfVariables());
|
||||
track.SetCurveLength(curveLength);
|
||||
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
// Driver for one Runge-Kutta Step with monitoring of local truncation error
|
||||
@@ -224,46 +235,46 @@ void G4IntegrationDriver<T>::OneGoodStep(G4double y[], // InOut
|
||||
G4double& hnext) // Out
|
||||
|
||||
{
|
||||
G4double error2 = DBL_MAX;
|
||||
G4double error2 = DBL_MAX;
|
||||
|
||||
G4double yerr[G4FieldTrack::ncompSVEC], ytemp[G4FieldTrack::ncompSVEC];
|
||||
G4double yerr[G4FieldTrack::ncompSVEC], ytemp[G4FieldTrack::ncompSVEC];
|
||||
|
||||
G4double h = htry;
|
||||
G4double h = htry;
|
||||
|
||||
const G4int max_trials = 100;
|
||||
const G4int max_trials = 100;
|
||||
|
||||
for (G4int iter = 0; iter < max_trials; ++iter)
|
||||
{
|
||||
Base::GetStepper()->Stepper(y, dydx, h, ytemp, yerr);
|
||||
error2 = field_utils::relativeError2(y, yerr, std::max(h, fMinimumStep),
|
||||
for (G4int iter = 0; iter < max_trials; ++iter)
|
||||
{
|
||||
Base::GetStepper()->Stepper(y, dydx, h, ytemp, yerr);
|
||||
error2 = field_utils::relativeError2(y, yerr, std::max(h, fMinimumStep),
|
||||
eps_rel_max);
|
||||
if (error2 <= 1.0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
h = Base::ShrinkStepSize2(h, error2);
|
||||
|
||||
G4double xnew = curveLength + h;
|
||||
if(xnew == curveLength)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Stepsize underflow in Stepper !" << G4endl
|
||||
<< "- Step's start x=" << curveLength
|
||||
<< " and end x= " << xnew
|
||||
<< " are equal !! " << G4endl
|
||||
<< " Due to step-size= " << h
|
||||
<< ". Note that input step was " << htry;
|
||||
G4Exception("G4IntegrationDriver::OneGoodStep()",
|
||||
"GeomField1001", JustWarning, message);
|
||||
break;
|
||||
}
|
||||
if (error2 <= 1.0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
hnext = Base::GrowStepSize2(h, error2);
|
||||
curveLength += (hdid = h);
|
||||
h = Base::ShrinkStepSize2(h, error2);
|
||||
|
||||
field_utils::copy(y, ytemp, Base::GetStepper()->GetNumberOfVariables());
|
||||
G4double xnew = curveLength + h;
|
||||
if(xnew == curveLength)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Stepsize underflow in Stepper !" << G4endl
|
||||
<< "- Step's start x=" << curveLength
|
||||
<< " and end x= " << xnew
|
||||
<< " are equal !! " << G4endl
|
||||
<< " Due to step-size= " << h
|
||||
<< ". Note that input step was " << htry;
|
||||
G4Exception("G4IntegrationDriver::OneGoodStep()",
|
||||
"GeomField1001", JustWarning, message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hnext = Base::GrowStepSize2(h, error2);
|
||||
curveLength += (hdid = h);
|
||||
|
||||
field_utils::copy(y, ytemp, Base::GetStepper()->GetNumberOfVariables());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@@ -273,40 +284,22 @@ G4bool G4IntegrationDriver<T>::QuickAdvance(G4FieldTrack& track, // INOUT
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr)
|
||||
{
|
||||
++fNoQuickAvanceCalls;
|
||||
++fNoQuickAvanceCalls;
|
||||
|
||||
G4double yIn[G4FieldTrack::ncompSVEC],
|
||||
yOut[G4FieldTrack::ncompSVEC],
|
||||
yError[G4FieldTrack::ncompSVEC];
|
||||
G4double yIn[G4FieldTrack::ncompSVEC],
|
||||
yOut[G4FieldTrack::ncompSVEC],
|
||||
yError[G4FieldTrack::ncompSVEC];
|
||||
|
||||
track.DumpToArray(yIn);
|
||||
track.DumpToArray(yIn);
|
||||
|
||||
Base::GetStepper()->Stepper(yIn, dydx, hstep, yOut, yError);
|
||||
Base::GetStepper()->Stepper(yIn, dydx, hstep, yOut, yError);
|
||||
|
||||
dchord_step = Base::GetStepper()->DistChord();
|
||||
dyerr = field_utils::absoluteError(yOut, yError, hstep);
|
||||
track.LoadFromArray(yOut, Base::GetStepper()->GetNumberOfVariables());
|
||||
track.SetCurveLength(track.GetCurveLength() + hstep);
|
||||
dchord_step = Base::GetStepper()->DistChord();
|
||||
dyerr = field_utils::absoluteError(yOut, yError, hstep);
|
||||
track.LoadFromArray(yOut, Base::GetStepper()->GetNumberOfVariables());
|
||||
track.SetCurveLength(track.GetCurveLength() + hstep);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::SetSmallestFraction(G4double newFraction)
|
||||
{
|
||||
if (newFraction > 1.e-16 && newFraction < 1e-8)
|
||||
{
|
||||
fSmallestFraction = newFraction;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Smallest Fraction not changed. " << G4endl
|
||||
<< " Proposed value was " << newFraction << G4endl
|
||||
<< " Value must be between 1.e-8 and 1.e-16";
|
||||
G4Exception("G4IntegrationDriver::SetSmallestFraction()",
|
||||
"GeomField1001", JustWarning, message);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@@ -314,67 +307,86 @@ void G4IntegrationDriver<T>::CheckStep(const G4ThreeVector& posIn,
|
||||
const G4ThreeVector& posOut,
|
||||
G4double hdid)
|
||||
{
|
||||
const G4double endPointDist = (posOut - posIn).mag();
|
||||
if (endPointDist >= hdid * (1. + CLHEP::perMillion))
|
||||
{
|
||||
++fNoAccurateAdvanceBadSteps;
|
||||
const G4double endPointDist = (posOut - posIn).mag();
|
||||
if (endPointDist >= hdid * (1. + CLHEP::perMillion))
|
||||
{
|
||||
++fNoAccurateAdvanceBadSteps;
|
||||
#ifdef G4DEBUG_FIELD
|
||||
// Issue a warning only for gross differences -
|
||||
// we understand how small difference occur.
|
||||
if (endPointDist >= hdid * (1. + perThousand))
|
||||
{
|
||||
G4Exception("G4IntegrationDriver::CheckStep()",
|
||||
"GeomField1002", JustWarning,
|
||||
"endPointDist >= hdid!");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
// Issue a warning only for gross differences -
|
||||
// we understand how small difference occur.
|
||||
if (endPointDist >= hdid * (1. + perThousand))
|
||||
{
|
||||
++fNoAccurateAdvanceGoodSteps;
|
||||
G4Exception("G4IntegrationDriver::CheckStep()",
|
||||
"GeomField1002", JustWarning,
|
||||
"endPointDist >= hdid!");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
++fNoAccurateAdvanceGoodSteps;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline G4double G4IntegrationDriver<T>::GetMinimumStep() const
|
||||
{
|
||||
return fMinimumStep;
|
||||
return fMinimumStep;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::SetMinimumStep(G4double minimumStepLength)
|
||||
{
|
||||
fMinimumStep = minimumStepLength;
|
||||
fMinimumStep = minimumStepLength;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4int G4IntegrationDriver<T>::GetVerboseLevel() const
|
||||
{
|
||||
return fVerboseLevel;
|
||||
return fVerboseLevel;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::SetVerboseLevel(G4int newLevel)
|
||||
{
|
||||
fVerboseLevel = newLevel;
|
||||
fVerboseLevel = newLevel;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4double G4IntegrationDriver<T>::GetSmallestFraction() const
|
||||
{
|
||||
return fSmallestFraction;
|
||||
return fSmallestFraction;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::SetSmallestFraction(G4double newFraction)
|
||||
{
|
||||
if (newFraction > 1.e-16 && newFraction < 1e-8)
|
||||
{
|
||||
fSmallestFraction = newFraction;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Smallest Fraction not changed. " << G4endl
|
||||
<< " Proposed value was " << newFraction << G4endl
|
||||
<< " Value must be between 1.e-8 and 1.e-16";
|
||||
G4Exception("G4IntegrationDriver::SetSmallestFraction()",
|
||||
"GeomField1001", JustWarning, message);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::IncrementQuickAdvanceCalls()
|
||||
{
|
||||
++fNoQuickAvanceCalls;
|
||||
++fNoQuickAvanceCalls;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::StreamInfo( std::ostream& os ) const
|
||||
{
|
||||
// Write out the parameters / state of the driver
|
||||
// Write out the parameters / state of the driver
|
||||
|
||||
os << "State of G4IntegrationDriver: " << std::endl;
|
||||
os << "--Base state (G4RKIntegrationDriver): " << std::endl;
|
||||
Base::StreamInfo( os );
|
||||
|
||||
@@ -1,443 +0,0 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4IntegrationDriver inline implementation
|
||||
//
|
||||
// Author: Dmitry Sorokin, Google Summer of Code 2017
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4FieldUtils.hh"
|
||||
|
||||
#include "G4DriverReporter.hh"
|
||||
|
||||
template <class T>
|
||||
G4IntegrationDriver<T>::
|
||||
G4IntegrationDriver ( G4double hminimum, T* pStepper,
|
||||
G4int numComponents, G4int statisticsVerbose )
|
||||
: G4RKIntegrationDriver<T>(pStepper),
|
||||
fMinimumStep(hminimum),
|
||||
fSmallestFraction(1e-12),
|
||||
fVerboseLevel(statisticsVerbose),
|
||||
fNoQuickAvanceCalls(0),
|
||||
fNoAccurateAdvanceCalls(0),
|
||||
fNoAccurateAdvanceBadSteps(0),
|
||||
fNoAccurateAdvanceGoodSteps(0)
|
||||
{
|
||||
if (numComponents != Base::GetStepper()->GetNumberOfVariables())
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Driver's number of integrated components "
|
||||
<< numComponents
|
||||
<< " != Stepper's number of components "
|
||||
<< pStepper->GetNumberOfVariables();
|
||||
G4Exception("G4IntegrationDriver","GeomField0002",
|
||||
FatalException, message);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4IntegrationDriver<T>::~G4IntegrationDriver()
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
if (fVerboseLevel > 0)
|
||||
{
|
||||
G4cout << "G4Integration Driver Stats: "
|
||||
<< "#QuickAdvance " << fNoQuickAvanceCalls
|
||||
<< " - #AccurateAdvance " << fNoAccurateAdvanceCalls << " "
|
||||
<< "#good steps " << fNoAccurateAdvanceGoodSteps << " "
|
||||
<< "#bad steps " << fNoAccurateAdvanceBadSteps << G4endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4double G4IntegrationDriver<T>::AdvanceChordLimited(G4FieldTrack& track,
|
||||
G4double stepMax,
|
||||
G4double epsStep,
|
||||
G4double chordDistance)
|
||||
{
|
||||
return ChordFinderDelegate::AdvanceChordLimitedImpl(track, stepMax, epsStep,
|
||||
chordDistance);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::OnStartTracking()
|
||||
{
|
||||
ChordFinderDelegate::ResetStepEstimate();
|
||||
}
|
||||
|
||||
// Runge-Kutta driver with adaptive stepsize control. Integrate starting
|
||||
// values at y_current over hstep x2 with accuracy eps.
|
||||
// On output ystart is replaced by values at the end of the integration
|
||||
// interval. RightHandSide is the right-hand side of ODE system.
|
||||
// The source is similar to odeint routine from NRC p.721-722 .
|
||||
//
|
||||
template <class T>
|
||||
G4bool G4IntegrationDriver<T>::
|
||||
AccurateAdvance(G4FieldTrack& track, G4double hstep,
|
||||
G4double eps, G4double hinitial)
|
||||
{
|
||||
++fNoAccurateAdvanceCalls;
|
||||
|
||||
if (hstep == 0.0)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Proposed step is zero; hstep = " << hstep << " !";
|
||||
G4Exception("G4IntegrationDriver::AccurateAdvance()",
|
||||
"GeomField1001", JustWarning, message);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hstep < 0)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Invalid run condition." << G4endl
|
||||
<< "Proposed step is negative; hstep = " << hstep << "."
|
||||
<< G4endl
|
||||
<< "Requested step cannot be negative! Aborting event.";
|
||||
G4Exception("G4IntegrationDriver::AccurateAdvance()",
|
||||
"GeomField0003", EventMustBeAborted, message);
|
||||
return false;
|
||||
}
|
||||
|
||||
G4double hnext, hdid;
|
||||
|
||||
G4double dydx[G4FieldTrack::ncompSVEC];
|
||||
G4bool succeeded = true, lastStepSucceeded;
|
||||
|
||||
G4int noFullIntegr = 0, noSmallIntegr = 0;
|
||||
|
||||
G4double y[G4FieldTrack::ncompSVEC];
|
||||
track.DumpToArray(y);
|
||||
|
||||
const G4double startCurveLength = track.GetCurveLength();
|
||||
const G4double endCurveLength = startCurveLength + hstep;
|
||||
const G4double hThreshold =
|
||||
std::min(eps * hstep, fSmallestFraction * startCurveLength);
|
||||
|
||||
G4double h = hstep;
|
||||
if (hinitial > CLHEP::perMillion * hstep && hinitial < hstep)
|
||||
{
|
||||
h = hinitial;
|
||||
}
|
||||
|
||||
#ifdef G4DEBUG_FIELD
|
||||
if (fVerboseLevel > 3)
|
||||
G4cout << "IDriver::AccurAdv called. "
|
||||
<< " Input: hstep = " << hstep << " hinitial= " << hinitial
|
||||
<< " , current: h = " << h << G4endl;
|
||||
#endif
|
||||
|
||||
G4double curveLength = startCurveLength;
|
||||
|
||||
for (G4int nstp = 0; nstp < Base::GetMaxNoSteps(); ++nstp)
|
||||
{
|
||||
const G4ThreeVector StartPos =
|
||||
field_utils::makeVector(y, field_utils::Value3D::Position);
|
||||
|
||||
#ifdef G4DEBUG_FIELD
|
||||
const int nvar= Base::GetStepper()->GetNumberOfVariables();
|
||||
G4double xStepStart= curveLength; // Initial: track.GetCurveLength();
|
||||
G4double yStepStart[G4FieldTrack::ncompSVEC];
|
||||
for (int i=0; i<nvar; ++i) { yStepStart[i] = y[i]; }
|
||||
// G4FieldTrack yFldTrkStart( StartPos,
|
||||
// field_utils::makeVector(y, field_utils::Value3D::Momentum),
|
||||
// ... );
|
||||
// G4FieldTrack yFldTrkStart('0');
|
||||
// yFldTrkStart.LoadFromArray(y, Base::GetStepper()->GetNumberOfVariables());
|
||||
// yFldTrkStart.SetCurveLength(curveLength);
|
||||
G4cout << "----- Iteration = " << nstp << G4endl; // + 1
|
||||
#endif
|
||||
|
||||
Base::GetStepper()->RightHandSide(y, dydx);
|
||||
|
||||
if (h > GetMinimumStep())
|
||||
{
|
||||
OneGoodStep(y, dydx, curveLength, h, eps, hdid, hnext);
|
||||
lastStepSucceeded = (hdid == h);
|
||||
#ifdef G4DEBUG_FIELD
|
||||
G4cout << "IntegrationDriver -- after OneGoodStep / requesting step = " << h << G4endl;
|
||||
G4DriverReporter::PrintStatus( yStepStart, xStepStart, y, curveLength, h, nstp+1, nvar); // Only
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
G4FieldTrack yFldTrk('0');
|
||||
G4double dchord_step, dyerr, dyerr_len;
|
||||
yFldTrk.LoadFromArray(y, Base::GetStepper()->GetNumberOfVariables());
|
||||
yFldTrk.SetCurveLength(curveLength);
|
||||
|
||||
QuickAdvance(yFldTrk, dydx, h, dchord_step, dyerr_len);
|
||||
|
||||
yFldTrk.DumpToArray(y);
|
||||
|
||||
if (h == 0.0)
|
||||
{
|
||||
G4Exception("G4IntegrationDriver::AccurateAdvance()",
|
||||
"GeomField0003", FatalException,
|
||||
"Integration Step became Zero!");
|
||||
}
|
||||
dyerr = dyerr_len / h;
|
||||
hdid = h;
|
||||
curveLength += hdid;
|
||||
hnext = Base::ComputeNewStepSize(dyerr / eps, h);
|
||||
lastStepSucceeded = (dyerr <= eps);
|
||||
}
|
||||
|
||||
if (lastStepSucceeded) { ++noFullIntegr; }
|
||||
else { ++noSmallIntegr; }
|
||||
|
||||
const G4ThreeVector EndPos =
|
||||
field_utils::makeVector(y, field_utils::Value3D::Position);
|
||||
|
||||
CheckStep(EndPos, StartPos, hdid);
|
||||
|
||||
// Avoid numerous small last steps
|
||||
if (h < hThreshold || curveLength >= endCurveLength)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
h = std::max(hnext, GetMinimumStep());
|
||||
if (curveLength + h > endCurveLength)
|
||||
{
|
||||
h = endCurveLength - curveLength;
|
||||
}
|
||||
}
|
||||
// Have we reached the end ?
|
||||
// --> a better test might be x-endCurveLength > an_epsilon
|
||||
succeeded = (curveLength >= endCurveLength);
|
||||
// If it was a "forced" last step
|
||||
|
||||
track.LoadFromArray(y, Base::GetStepper()->GetNumberOfVariables());
|
||||
track.SetCurveLength(curveLength);
|
||||
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
// Driver for one Runge-Kutta Step with monitoring of local truncation error
|
||||
// to ensure accuracy and adjust stepsize. Input are dependent variable
|
||||
// array y[0,...,5] and its derivative dydx[0,...,5] at the
|
||||
// starting value of the independent variable x . Also input are stepsize
|
||||
// to be attempted htry, and the required accuracy eps. On output y and x
|
||||
// are replaced by their new values, hdid is the stepsize that was actually
|
||||
// accomplished, and hnext is the estimated next stepsize.
|
||||
// This is similar to the function rkqs from the book:
|
||||
// Numerical Recipes in C: The Art of Scientific Computing (NRC), Second
|
||||
// Edition, by William H. Press, Saul A. Teukolsky, William T.
|
||||
// Vetterling, and Brian P. Flannery (Cambridge University Press 1992),
|
||||
// 16.2 Adaptive StepSize Control for Runge-Kutta, p. 719
|
||||
//
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::OneGoodStep(G4double y[], // InOut
|
||||
const G4double dydx[],
|
||||
G4double& curveLength, // InOut
|
||||
G4double htry,
|
||||
G4double eps_rel_max,
|
||||
G4double& hdid, // Out
|
||||
G4double& hnext) // Out
|
||||
|
||||
{
|
||||
G4double error2 = DBL_MAX;
|
||||
|
||||
G4double yerr[G4FieldTrack::ncompSVEC], ytemp[G4FieldTrack::ncompSVEC];
|
||||
|
||||
G4double h = htry;
|
||||
|
||||
static G4ThreadLocal G4int tot_no_trials = 0;
|
||||
const G4int max_trials = 100;
|
||||
|
||||
for (G4int iter = 0; iter < max_trials; ++iter)
|
||||
{
|
||||
tot_no_trials++;
|
||||
|
||||
Base::GetStepper()->Stepper(y, dydx, h, ytemp, yerr);
|
||||
error2 = field_utils::relativeError2(y, yerr, std::max(h, fMinimumStep),
|
||||
eps_rel_max);
|
||||
if (error2 <= 1.0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
h = Base::ShrinkStepSize2(h, error2);
|
||||
|
||||
G4double xnew = curveLength + h;
|
||||
if(xnew == curveLength)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Stepsize underflow in Stepper !" << G4endl
|
||||
<< "- Step's start x=" << curveLength
|
||||
<< " and end x= " << xnew
|
||||
<< " are equal !! " << G4endl
|
||||
<< " Due to step-size= " << h
|
||||
<< ". Note that input step was " << htry;
|
||||
G4Exception("G4IntegrationDriver::OneGoodStep()",
|
||||
"GeomField1001", JustWarning, message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hnext = Base::GrowStepSize2(h, error2);
|
||||
curveLength += (hdid = h);
|
||||
|
||||
field_utils::copy(y, ytemp, Base::GetStepper()->GetNumberOfVariables());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4bool G4IntegrationDriver<T>::QuickAdvance(G4FieldTrack& track, // INOUT
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr)
|
||||
{
|
||||
++fNoQuickAvanceCalls;
|
||||
|
||||
G4double yIn[G4FieldTrack::ncompSVEC],
|
||||
yOut[G4FieldTrack::ncompSVEC],
|
||||
yError[G4FieldTrack::ncompSVEC];
|
||||
|
||||
G4FieldTrack startTrack( track ); // For debugging
|
||||
|
||||
track.DumpToArray(yIn);
|
||||
|
||||
Base::GetStepper()->Stepper(yIn, dydx, hstep, yOut, yError);
|
||||
|
||||
dchord_step = Base::GetStepper()->DistChord();
|
||||
dyerr = field_utils::absoluteError(yOut, yError, hstep);
|
||||
track.LoadFromArray(yOut, Base::GetStepper()->GetNumberOfVariables());
|
||||
track.SetCurveLength(track.GetCurveLength() + hstep);
|
||||
|
||||
#ifdef G4DEBUG_FIELD
|
||||
// For debugging
|
||||
static unsigned int numCall= 0;
|
||||
G4cout // << "G4IntegratorDriver::"
|
||||
<< "QuickAdvance call # " << ++numCall << G4endl
|
||||
<< " Input: hstep= " << hstep << G4endl
|
||||
<< " track= " << startTrack << G4endl
|
||||
<< " Output: track= " << track << G4endl
|
||||
<< " d_chord = " << dchord_step
|
||||
<< " dyerr = " << dyerr << G4endl;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::SetSmallestFraction(G4double newFraction)
|
||||
{
|
||||
if (newFraction > 1.e-16 && newFraction < 1e-8)
|
||||
{
|
||||
fSmallestFraction = newFraction;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Smallest Fraction not changed. " << G4endl
|
||||
<< " Proposed value was " << newFraction << G4endl
|
||||
<< " Value must be between 1.e-8 and 1.e-16";
|
||||
G4Exception("G4IntegrationDriver::SetSmallestFraction()",
|
||||
"GeomField1001", JustWarning, message);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::CheckStep(const G4ThreeVector& posIn,
|
||||
const G4ThreeVector& posOut,
|
||||
G4double hdid)
|
||||
{
|
||||
const G4double endPointDist = (posOut - posIn).mag();
|
||||
if (endPointDist >= hdid * (1. + CLHEP::perMillion))
|
||||
{
|
||||
++fNoAccurateAdvanceBadSteps;
|
||||
#ifdef G4DEBUG_FIELD
|
||||
// Issue a warning only for gross differences -
|
||||
// we understand how small difference occur.
|
||||
if (endPointDist >= hdid * (1. + perThousand))
|
||||
{
|
||||
G4Exception("G4IntegrationDriver::CheckStep()",
|
||||
"GeomField1002", JustWarning,
|
||||
"endPointDist >= hdid!");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
++fNoAccurateAdvanceGoodSteps;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline G4double G4IntegrationDriver<T>::GetMinimumStep() const
|
||||
{
|
||||
return fMinimumStep;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::SetMinimumStep(G4double minimumStepLength)
|
||||
{
|
||||
fMinimumStep = minimumStepLength;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4int G4IntegrationDriver<T>::GetVerboseLevel() const
|
||||
{
|
||||
return fVerboseLevel;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::SetVerboseLevel(G4int newLevel)
|
||||
{
|
||||
fVerboseLevel = newLevel;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
G4double G4IntegrationDriver<T>::GetSmallestFraction() const
|
||||
{
|
||||
return fSmallestFraction;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::IncrementQuickAdvanceCalls()
|
||||
{
|
||||
++fNoQuickAvanceCalls;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4IntegrationDriver<T>::StreamInfo( std::ostream& os ) const
|
||||
{
|
||||
// Write out the parameters / state of the driver
|
||||
os << "State of G4IntegrationDriver: " << std::endl;
|
||||
os << "--Base state (G4RKIntegrationDriver): " << std::endl;
|
||||
Base::StreamInfo( os );
|
||||
os << "--Own state (G4IntegrationDriver<>): " << std::endl;
|
||||
os << " fMinimumStep = " << fMinimumStep << std::endl;
|
||||
os << " Smallest Fraction = " << fSmallestFraction << std::endl;
|
||||
|
||||
os << " verbose level = " << fVerboseLevel << std::endl;
|
||||
os << " Reintegrates = " << DoesReIntegrate() << std::endl;
|
||||
os << "--Chord Finder Delegate state: " << std::endl;
|
||||
ChordFinderDelegate::StreamDelegateInfo( os );
|
||||
}
|
||||
@@ -30,7 +30,7 @@
|
||||
// Driver class which uses Runge-Kutta stepper with interpolation property
|
||||
// to integrate track with error control
|
||||
|
||||
// Created: D.Sorokin, 2018
|
||||
// Author: Dmitry Sorokin (CERN), 26.09.2018
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4INTERPOLATION_DRIVER_HH
|
||||
#define G4INTERPOLATION_DRIVER_HH
|
||||
@@ -42,43 +42,92 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @brief G4InterpolationDriver is a templated driver class which uses
|
||||
* Runge-Kutta stepper with interpolation property to integrate track with
|
||||
* error control.
|
||||
*/
|
||||
|
||||
template <class T, G4bool StepperCachesDchord = true>
|
||||
class G4InterpolationDriver : public G4RKIntegrationDriver<T>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4IntegrationDriver.
|
||||
* @param[in] hminimum Minimum allowed step.
|
||||
* @param[in] stepper Pointer to the stepper algorithm.
|
||||
* @param[in] numberOfComponents The number of integration variables,
|
||||
* if not matching stepper's number of variables, issue exception.
|
||||
* @param[in] statisticsVerbosity Verbosity level.
|
||||
*/
|
||||
G4InterpolationDriver(G4double hminimum,
|
||||
T* stepper,
|
||||
G4int numberOfComponents = 6,
|
||||
G4int statisticsVerbosity = 0);
|
||||
|
||||
~G4InterpolationDriver() override;
|
||||
/**
|
||||
* Destructor. Provides statistics if verbosity level is greater than zero.
|
||||
*/
|
||||
~G4InterpolationDriver() override;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4InterpolationDriver(const G4InterpolationDriver&) = delete;
|
||||
const G4InterpolationDriver& operator=(const G4InterpolationDriver&) = delete;
|
||||
|
||||
/**
|
||||
* Computes the step to take, based on chord limits.
|
||||
* @param[in,out] track The current track in field.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[in] eps Requested accuracy, y_err/hstep.
|
||||
* @param[in] chordDistance Maximum sagitta distance.
|
||||
* @returns The length of step taken.
|
||||
*/
|
||||
G4double AdvanceChordLimited(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps,
|
||||
G4double chordDistance) override;
|
||||
|
||||
/**
|
||||
* Dispatch interface method for initialisation/reset of driver.
|
||||
*/
|
||||
void OnStartTracking() override;
|
||||
void OnComputeStep(const G4FieldTrack* /*track*/ = nullptr) override;
|
||||
G4bool DoesReIntegrate() const override { return false; }
|
||||
// Interpolation driver does not recalculate when AccurateAdvance
|
||||
// is called -- reintegration would require other calls
|
||||
|
||||
/**
|
||||
* Dispatch interface method for computing step. Does nothing here.
|
||||
*/
|
||||
void OnComputeStep(const G4FieldTrack* /*track*/ = nullptr) override;
|
||||
|
||||
/**
|
||||
* The driver does not implement re-integration. Returns false.
|
||||
*/
|
||||
G4bool DoesReIntegrate() const override { return false; }
|
||||
|
||||
/**
|
||||
* Advances integration accurately by relative accuracy better than 'eps'.
|
||||
* On output the track is replaced by the value at the end of interval.
|
||||
* @param[in,out] track The current track in field.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[in] eps Requested accuracy, y_err/hstep.
|
||||
* @param[in] hinitial Initial minimum integration step.
|
||||
* @returns true if integration succeeds.
|
||||
*/
|
||||
G4bool AccurateAdvance(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps, // Requested y_err/hstep
|
||||
G4double hinitial = 0) override;
|
||||
// Integrates ODE from current s (s=s0) to s=s0+h with accuracy eps.
|
||||
// On output track is replaced by value at end of interval.
|
||||
// The concept is similar to the odeint routine from NRC p.721-722.
|
||||
|
||||
/**
|
||||
* Setter and getter for verbosity.
|
||||
*/
|
||||
void SetVerboseLevel(G4int level) override;
|
||||
G4int GetVerboseLevel() const override;
|
||||
|
||||
/**
|
||||
* Writes out to stream the parameters/state of the driver.
|
||||
*/
|
||||
void StreamInfo(std::ostream& os) const override;
|
||||
|
||||
protected:
|
||||
@@ -94,6 +143,18 @@ class G4InterpolationDriver : public G4RKIntegrationDriver<T>
|
||||
using StepperIterator = typename std::vector<InterpStepper>::iterator;
|
||||
using ConstStepperIterator = typename std::vector<InterpStepper>::const_iterator;
|
||||
|
||||
/**
|
||||
* Takes one Step that is as large as possible while satisfying the
|
||||
* accuracy criterion.
|
||||
* @param[in] it Stepper iterator.
|
||||
* @param[in,out] y The current track state, y.
|
||||
* @param[in] dydx dydx array.
|
||||
* @param[in,out] hstep Step to attempt.
|
||||
* @param[in] eps The relative accuracy.
|
||||
* @param[in] curveLength Step start, x.
|
||||
* @param[in,out] track Pointer to the Field track. Not used.
|
||||
* @returns The step achieved.
|
||||
*/
|
||||
virtual G4double OneGoodStep(StepperIterator it,
|
||||
field_utils::State& y,
|
||||
field_utils::State& dydx,
|
||||
@@ -101,37 +162,48 @@ class G4InterpolationDriver : public G4RKIntegrationDriver<T>
|
||||
G4double eps,
|
||||
G4double curveLength,
|
||||
G4FieldTrack* track = nullptr);
|
||||
// This takes one Step that is of size htry, or as large
|
||||
// as possible while satisfying the accuracy criterion of:
|
||||
// yerr < eps * |y_end-y_start|
|
||||
// return hdid
|
||||
|
||||
/**
|
||||
* Track interpolation.
|
||||
* @param[in] curveLength Step start, x.
|
||||
* @param[in,out] y The current track state, y.
|
||||
*/
|
||||
void Interpolate(G4double curveLength, field_utils::State& y) const;
|
||||
|
||||
/**
|
||||
* Wrapper method for interpolation.
|
||||
*/
|
||||
void InterpolateImpl(G4double curveLength,
|
||||
ConstStepperIterator it,
|
||||
field_utils::State& y) const;
|
||||
|
||||
/**
|
||||
* Methods for calculation of chord step and distance.
|
||||
*/
|
||||
G4double DistChord(const field_utils::State& yBegin,
|
||||
G4double curveLengthBegin,
|
||||
const field_utils::State& yEnd,
|
||||
G4double curveLengthEnd) const;
|
||||
|
||||
G4double FindNextChord(const field_utils::State& yBegin,
|
||||
G4double curveLengthBegin,
|
||||
field_utils::State& yEnd,
|
||||
G4double curveLengthEnd,
|
||||
G4double dChord,
|
||||
G4double maxChordDistance);
|
||||
|
||||
G4double CalcChordStep(G4double stepTrialOld,
|
||||
G4double dChordStep,
|
||||
G4double fDeltaChord);
|
||||
|
||||
void PrintState() const;
|
||||
|
||||
/**
|
||||
* Internal methods for printing/checking the state.
|
||||
*/
|
||||
void PrintState() const;
|
||||
void CheckState() const;
|
||||
|
||||
/**
|
||||
* Increments number of trials and calls.
|
||||
*/
|
||||
void AccumulateStatistics(G4int noTrials);
|
||||
|
||||
protected:
|
||||
@@ -140,11 +212,11 @@ class G4InterpolationDriver : public G4RKIntegrationDriver<T>
|
||||
StepperIterator fLastStepper;
|
||||
G4bool fKeepLastStepper = false;
|
||||
|
||||
/** Memory of last good step size for integration. */
|
||||
G4double fhnext = DBL_MAX;
|
||||
// Memory of last good step size for integration
|
||||
|
||||
/** Minimum Step allowed (in units of length). */
|
||||
G4double fMinimumStep;
|
||||
// Minimum Step allowed in a Step (in units of length) // Parameter
|
||||
|
||||
G4double fChordStepEstimate = DBL_MAX;
|
||||
const G4double fFractionNextEstimate = 0.98; // Constant
|
||||
@@ -158,7 +230,7 @@ class G4InterpolationDriver : public G4RKIntegrationDriver<T>
|
||||
G4int fMaxTrials = 100; // Constant
|
||||
G4int fTotalStepsForTrack = 0;
|
||||
|
||||
// statistics
|
||||
/** Statistics. */
|
||||
G4int fTotalNoTrials = 0;
|
||||
G4int fNoCalls = 0;
|
||||
G4int fmaxTrials = 0;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
//
|
||||
// G4InterpolationDriver inline implementation
|
||||
//
|
||||
// Created: D.Sorokin, 2018
|
||||
// Author: Dmitry Sorokin (CERN), 26.09.2018
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4Exception.hh"
|
||||
@@ -41,14 +41,16 @@ G4InterpolationDriver<T, StepperCachesDchord>::G4InterpolationDriver(
|
||||
G4double hminimum, T* pStepper, G4int numComponents, G4int statisticsVerbose)
|
||||
: G4RKIntegrationDriver<T>(pStepper), fMinimumStep(hminimum), fVerboseLevel(statisticsVerbose)
|
||||
{
|
||||
if (numComponents != Base::GetStepper()->GetNumberOfVariables()) {
|
||||
if (numComponents != Base::GetStepper()->GetNumberOfVariables())
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Driver's number of integrated components " << numComponents
|
||||
<< " != Stepper's number of components " << pStepper->GetNumberOfVariables();
|
||||
G4Exception("G4InterpolationDriver", "GeomField0002", FatalException, message);
|
||||
}
|
||||
|
||||
for (G4int i = 0; i < Base::GetMaxNoSteps(); ++i) {
|
||||
for (G4int i = 0; i < Base::GetMaxNoSteps(); ++i)
|
||||
{
|
||||
fSteppers.push_back(
|
||||
{std::unique_ptr<T>(
|
||||
new T(pStepper->GetSpecificEquation(), // Interpolating stepper must have this!
|
||||
@@ -63,7 +65,8 @@ template <class T, G4bool StepperCachesDchord>
|
||||
G4InterpolationDriver<T, StepperCachesDchord>::~G4InterpolationDriver()
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
if (fVerboseLevel > 0) {
|
||||
if (fVerboseLevel > 0)
|
||||
{
|
||||
G4cout << "G4ChordFinder statistics report: \n"
|
||||
<< " No trials: " << fTotalNoTrials << " No Calls: " << fNoCalls
|
||||
<< " Max-trial: " << fmaxTrials << G4endl;
|
||||
@@ -103,7 +106,8 @@ template <class T, G4bool StepperCachesDchord>
|
||||
void G4InterpolationDriver<T, StepperCachesDchord>::Interpolate(
|
||||
G4double curveLength, field_utils::State& y) const
|
||||
{
|
||||
if (fLastStepper == fSteppers.end()) {
|
||||
if (fLastStepper == fSteppers.end())
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "LOGICK ERROR: fLastStepper == end";
|
||||
G4Exception("G4InterpolationDriver::Interpolate()", "GeomField1001", FatalException, message);
|
||||
@@ -114,8 +118,10 @@ void G4InterpolationDriver<T, StepperCachesDchord>::Interpolate(
|
||||
|
||||
auto it = std::lower_bound(fSteppers.cbegin(), end, curveLength,
|
||||
[](const InterpStepper& stepper, G4double value) { return stepper.end < value; });
|
||||
if (it == end) {
|
||||
if (curveLength - fLastStepper->end > CLHEP::perMillion) {
|
||||
if (it == end)
|
||||
{
|
||||
if (curveLength - fLastStepper->end > CLHEP::perMillion)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "curveLength = " << curveLength << " > " << fLastStepper->end;
|
||||
G4Exception("G4InterpolationDriver::Interpolate()", "GeomField1001", JustWarning, message);
|
||||
@@ -124,8 +130,10 @@ void G4InterpolationDriver<T, StepperCachesDchord>::Interpolate(
|
||||
return fLastStepper->stepper->Interpolate(1, y);
|
||||
}
|
||||
|
||||
if (curveLength < it->begin) {
|
||||
if (it->begin - curveLength > CLHEP::perMillion) {
|
||||
if (curveLength < it->begin)
|
||||
{
|
||||
if (it->begin - curveLength > CLHEP::perMillion)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "curveLength = " << curveLength << " < " << it->begin;
|
||||
G4Exception("G4InterpolationDriver::Interpolate()", "GeomField1001", JustWarning, message);
|
||||
@@ -149,10 +157,12 @@ template <class T, G4bool StepperCachesDchord>
|
||||
G4double G4InterpolationDriver<T, StepperCachesDchord>::DistChord(const field_utils::State& yBegin,
|
||||
G4double curveLengthBegin, const field_utils::State& yEnd, G4double curveLengthEnd) const
|
||||
{
|
||||
if (StepperCachesDchord) {
|
||||
if (StepperCachesDchord)
|
||||
{
|
||||
// optimization check if it worth
|
||||
//
|
||||
if (curveLengthBegin == fLastStepper->begin && curveLengthEnd == fLastStepper->end) {
|
||||
if (curveLengthBegin == fLastStepper->begin && curveLengthEnd == fLastStepper->end)
|
||||
{
|
||||
return fLastStepper->stepper
|
||||
->DistChord(); // QssStepper Returns 0.0 !??? Not implemented => WRONG
|
||||
}
|
||||
@@ -184,21 +194,25 @@ G4double G4InterpolationDriver<T, StepperCachesDchord>::AdvanceChordLimited(
|
||||
track.DumpToArray(yBegin);
|
||||
track.DumpToArray(y);
|
||||
|
||||
if (fFirstStep) {
|
||||
if (fFirstStep)
|
||||
{
|
||||
Base::GetEquationOfMotion()->RightHandSide(y, fdydx);
|
||||
fFirstStep = false;
|
||||
}
|
||||
|
||||
if (fKeepLastStepper) {
|
||||
if (fKeepLastStepper)
|
||||
{
|
||||
std::swap(*fSteppers.begin(), *fLastStepper);
|
||||
it = fSteppers.begin(); // new begin, update iterator
|
||||
fLastStepper = it;
|
||||
hdid = it->end - curveLengthBegin;
|
||||
if (hdid > hend) {
|
||||
if (hdid > hend)
|
||||
{
|
||||
hdid = hend;
|
||||
InterpolateImpl(curveLengthBegin + hdid, it, y);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
field_utils::copy(y, it->stepper->GetYOut());
|
||||
}
|
||||
|
||||
@@ -209,7 +223,8 @@ G4double G4InterpolationDriver<T, StepperCachesDchord>::AdvanceChordLimited(
|
||||
|
||||
// accurate advance & check chord distance
|
||||
G4double h = fhnext;
|
||||
for (; hdid < hend && dChordStep < chordDistance && it != fSteppers.end(); ++it) {
|
||||
for (; hdid < hend && dChordStep < chordDistance && it != fSteppers.end(); ++it)
|
||||
{
|
||||
h = std::min(h, hstep - hdid);
|
||||
|
||||
// make one step
|
||||
@@ -229,7 +244,8 @@ G4double G4InterpolationDriver<T, StepperCachesDchord>::AdvanceChordLimited(
|
||||
// - reached maximum number of steps (from number of steppers.)
|
||||
|
||||
// update step estimation
|
||||
if (h > fMinimumStep) {
|
||||
if (h > fMinimumStep)
|
||||
{
|
||||
fhnext = h;
|
||||
}
|
||||
|
||||
@@ -257,7 +273,8 @@ G4double G4InterpolationDriver<T, StepperCachesDchord>::FindNextChord(
|
||||
G4double curveLength = curveLengthEnd;
|
||||
|
||||
G4int i = 1;
|
||||
for (; i < fMaxTrials && dChord > chordDistance && curveLength > fLastStepper->begin; ++i) {
|
||||
for (; i < fMaxTrials && dChord > chordDistance && curveLength > fLastStepper->begin; ++i)
|
||||
{
|
||||
// crop step size
|
||||
hstep = CalcChordStep(hstep, dChord, chordDistance);
|
||||
|
||||
@@ -274,11 +291,13 @@ G4double G4InterpolationDriver<T, StepperCachesDchord>::FindNextChord(
|
||||
|
||||
// dChord may be zero
|
||||
//
|
||||
if (dChord > 0.0) {
|
||||
if (dChord > 0.0)
|
||||
{
|
||||
fChordStepEstimate = hstep * std::sqrt(chordDistance / dChord);
|
||||
}
|
||||
|
||||
if (i == fMaxTrials) {
|
||||
if (i == fMaxTrials)
|
||||
{
|
||||
G4Exception(
|
||||
"G4InterpolationDriver::FindNextChord()", "GeomField1001", JustWarning, "cannot converge");
|
||||
}
|
||||
@@ -299,12 +318,16 @@ G4double G4InterpolationDriver<T, StepperCachesDchord>::CalcChordStep(
|
||||
const G4double chordStepEstimate = stepTrialOld * std::sqrt(chordDistance / dChordStep);
|
||||
G4double stepTrial = fFractionNextEstimate * chordStepEstimate;
|
||||
|
||||
if (stepTrial <= 0.001 * stepTrialOld) {
|
||||
if (dChordStep > 1000.0 * chordDistance) {
|
||||
if (stepTrial <= 0.001 * stepTrialOld)
|
||||
{
|
||||
if (dChordStep > 1000.0 * chordDistance)
|
||||
{
|
||||
stepTrial = stepTrialOld * 0.03;
|
||||
}
|
||||
else {
|
||||
if (dChordStep > 100. * chordDistance) {
|
||||
else
|
||||
{
|
||||
if (dChordStep > 100. * chordDistance)
|
||||
{
|
||||
stepTrial = stepTrialOld * 0.1;
|
||||
}
|
||||
else // Try halving the length until dChordStep OK
|
||||
@@ -313,11 +336,13 @@ G4double G4InterpolationDriver<T, StepperCachesDchord>::CalcChordStep(
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (stepTrial > 1000.0 * stepTrialOld) {
|
||||
else if (stepTrial > 1000.0 * stepTrialOld)
|
||||
{
|
||||
stepTrial = 1000.0 * stepTrialOld;
|
||||
}
|
||||
|
||||
if (stepTrial == 0.0) {
|
||||
if (stepTrial == 0.0)
|
||||
{
|
||||
stepTrial = 0.000001;
|
||||
}
|
||||
|
||||
@@ -338,14 +363,16 @@ G4bool G4InterpolationDriver<T, StepperCachesDchord>::AccurateAdvance(
|
||||
G4FieldTrack& track, G4double hstep, G4double /*eps*/, G4double /*hinitial*/
|
||||
)
|
||||
{
|
||||
if (hstep == 0.0) {
|
||||
if (hstep == 0.0)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Proposed step is zero; hstep = " << hstep << " !";
|
||||
G4Exception("G4InterpolationDriver::AccurateAdvance()", "GeomField1001", JustWarning, message);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hstep < 0) {
|
||||
if (hstep < 0)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Invalid run condition." << G4endl << "Proposed step is negative; hstep = " << hstep
|
||||
<< "." << G4endl << "Requested step cannot be negative! Aborting event.";
|
||||
@@ -390,17 +417,20 @@ G4double G4InterpolationDriver<T, StepperCachesDchord>::OneGoodStep(StepperItera
|
||||
G4double h = hstep;
|
||||
|
||||
G4int i = 0;
|
||||
for (; i < fMaxTrials; ++i) {
|
||||
for (; i < fMaxTrials; ++i)
|
||||
{
|
||||
it->stepper->Stepper(y, dydx, h, ytemp, yerr, dydxtemp);
|
||||
error2 = field_utils::relativeError2(y, yerr, h, epsStep);
|
||||
|
||||
if (error2 <= 1.0) {
|
||||
if (error2 <= 1.0)
|
||||
{
|
||||
hstep = std::max(Base::GrowStepSize2(h, error2), fMinimumStep);
|
||||
break;
|
||||
}
|
||||
|
||||
// don't control error for small steps
|
||||
if (h <= fMinimumStep) {
|
||||
if (h <= fMinimumStep)
|
||||
{
|
||||
hstep = fMinimumStep;
|
||||
break;
|
||||
}
|
||||
@@ -408,7 +438,8 @@ G4double G4InterpolationDriver<T, StepperCachesDchord>::OneGoodStep(StepperItera
|
||||
h = std::max(Base::ShrinkStepSize2(h, error2), fMinimumStep);
|
||||
}
|
||||
|
||||
if (i == fMaxTrials) {
|
||||
if (i == fMaxTrials)
|
||||
{
|
||||
G4Exception(
|
||||
"G4InterpolationDriver::OneGoodStep()", "GeomField1001", JustWarning, "cannot converge");
|
||||
hstep = std::max(Base::ShrinkStepSize2(h, error2), fMinimumStep);
|
||||
@@ -436,13 +467,15 @@ void G4InterpolationDriver<T, StepperCachesDchord>::PrintState() const
|
||||
auto prev = fSteppers.begin();
|
||||
|
||||
G4cout << "====== curr state ========" << G4endl;
|
||||
for (auto i = fSteppers.begin(); i <= fLastStepper; ++i) {
|
||||
for (auto i = fSteppers.begin(); i <= fLastStepper; ++i)
|
||||
{
|
||||
i->stepper->Interpolate(0, currBegin);
|
||||
|
||||
G4cout << "cl_begin: " << i->begin << " "
|
||||
<< "cl_end: " << i->end << " ";
|
||||
|
||||
if (prev != i) {
|
||||
if (prev != i)
|
||||
{
|
||||
prev->stepper->Interpolate(1, prevEnd);
|
||||
auto prevPos = makeVector(prevEnd, Value3D::Position);
|
||||
auto currPos = makeVector(currBegin, Value3D::Position);
|
||||
@@ -458,7 +491,8 @@ void G4InterpolationDriver<T, StepperCachesDchord>::PrintState() const
|
||||
const G4double hstep = (clEnd - clBegin) / 10.;
|
||||
State yBegin, yCurr;
|
||||
Interpolate(0, yBegin);
|
||||
for (G4double cl = clBegin; cl <= clEnd + 1e-12; cl += hstep) {
|
||||
for (G4double cl = clBegin; cl <= clEnd + 1e-12; cl += hstep)
|
||||
{
|
||||
Interpolate(cl, yCurr);
|
||||
auto d = DistChord(yBegin, clBegin, yCurr, cl);
|
||||
G4cout << "cl: " << cl << " chord_distance: " << d << G4endl;
|
||||
@@ -471,17 +505,21 @@ template <class T, G4bool StepperCachesDchord>
|
||||
void G4InterpolationDriver<T, StepperCachesDchord>::CheckState() const
|
||||
{
|
||||
G4int smallSteps = 0;
|
||||
for (auto i = fSteppers.begin(); i <= fLastStepper; ++i) {
|
||||
for (auto i = fSteppers.begin(); i <= fLastStepper; ++i)
|
||||
{
|
||||
G4double stepLength = i->end - i->begin;
|
||||
if (stepLength < fMinimumStep) {
|
||||
if (stepLength < fMinimumStep)
|
||||
{
|
||||
++smallSteps;
|
||||
}
|
||||
}
|
||||
|
||||
if (smallSteps > 1) {
|
||||
if (smallSteps > 1)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "====== curr state ========\n";
|
||||
for (auto i = fSteppers.begin(); i <= fLastStepper; ++i) {
|
||||
for (auto i = fSteppers.begin(); i <= fLastStepper; ++i)
|
||||
{
|
||||
message << "cl_begin: " << i->begin << " "
|
||||
<< "cl_end: " << i->end << "\n";
|
||||
}
|
||||
@@ -496,7 +534,8 @@ void G4InterpolationDriver<T, StepperCachesDchord>::AccumulateStatistics(G4int n
|
||||
fTotalNoTrials += noTrials;
|
||||
++fNoCalls;
|
||||
|
||||
if (noTrials > fmaxTrials) {
|
||||
if (noTrials > fmaxTrials)
|
||||
{
|
||||
fmaxTrials = noTrials;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,22 +32,44 @@
|
||||
// The line current is directed along Z axis and crosses the XY
|
||||
// plane in the origin point (0,0).
|
||||
|
||||
// Author: V.Grichine, 03.02.1997
|
||||
// Author: Vladimir Grichine (CERN), 03.02.1997
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4LINECURRENTMAGFIELD_HH
|
||||
#define G4LINECURRENTMAGFIELD_HH
|
||||
|
||||
#include "G4MagneticField.hh"
|
||||
|
||||
/**
|
||||
* @brief G4LineCurrentMagField is a class describing a line current magnetic
|
||||
* field. The line current is directed along the Z axis and crosses the XY
|
||||
* plane in the origin point.
|
||||
*/
|
||||
|
||||
class G4LineCurrentMagField : public G4MagneticField
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4LineCurrentMagField.
|
||||
* @param[in] pFieldConstant Value of the constant field.
|
||||
*/
|
||||
G4LineCurrentMagField(G4double pFieldConstant);
|
||||
~G4LineCurrentMagField() override;
|
||||
|
||||
void GetFieldValue(const G4double yTrack[],
|
||||
G4double B[] ) const override;
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4LineCurrentMagField() override = default;
|
||||
|
||||
/**
|
||||
* Returns the field value on the given position 'yTrack'.
|
||||
* @param[in] yTrack Time position array.
|
||||
* @param[out] B The returned field array.
|
||||
*/
|
||||
void GetFieldValue(const G4double yTrack[], G4double B[]) const override;
|
||||
|
||||
/**
|
||||
* Returns a pointer to a new allocated clone of this object.
|
||||
*/
|
||||
G4Field* Clone() const override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
// A utility class that calculates the distance of a point from a
|
||||
// line section.
|
||||
|
||||
// Created: J.Apostolakis, 1999
|
||||
// Author: John Apostolakis (CERN), 1999
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#ifndef G4LineSection_hh
|
||||
@@ -39,25 +39,49 @@
|
||||
#include "G4Types.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
|
||||
/**
|
||||
* @brief G4LineSection is a utility class that calculates the distance
|
||||
* of a point from a line section.
|
||||
*/
|
||||
|
||||
class G4LineSection
|
||||
{
|
||||
public: // with description
|
||||
public:
|
||||
|
||||
G4LineSection( const G4ThreeVector& PntA,
|
||||
const G4ThreeVector& PntB );
|
||||
/**
|
||||
* Constructor for G4LineSection.
|
||||
* @param[in] PntA Coordinates of point A defining the line.
|
||||
* @param[in] PntB Coordinates of point B defining the line.
|
||||
*/
|
||||
G4LineSection( const G4ThreeVector& PntA,
|
||||
const G4ThreeVector& PntB );
|
||||
|
||||
G4double Dist( const G4ThreeVector& OtherPnt ) const;
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4LineSection() = default;
|
||||
|
||||
inline G4double GetABdistanceSq() const;
|
||||
/**
|
||||
* Returns the distance of point 'OtherPnt' from the line.
|
||||
*/
|
||||
G4double Dist( const G4ThreeVector& OtherPnt ) const;
|
||||
|
||||
inline static G4double Distline( const G4ThreeVector& OtherPnt,
|
||||
const G4ThreeVector& LinePntA,
|
||||
const G4ThreeVector& LinePntB );
|
||||
/**
|
||||
* Returns the distance squared.
|
||||
*/
|
||||
inline G4double GetABdistanceSq() const;
|
||||
|
||||
/**
|
||||
* Defines line and returns the distance of point 'OtherPnt' from it.
|
||||
*/
|
||||
inline static G4double Distline( const G4ThreeVector& OtherPnt,
|
||||
const G4ThreeVector& LinePntA,
|
||||
const G4ThreeVector& LinePntB );
|
||||
private:
|
||||
|
||||
G4ThreeVector EndpointA;
|
||||
G4ThreeVector VecAtoB;
|
||||
G4double fABdistanceSq = 0.0;
|
||||
G4ThreeVector EndpointA;
|
||||
G4ThreeVector VecAtoB;
|
||||
G4double fABdistanceSq = 0.0;
|
||||
};
|
||||
|
||||
// Inline methods implementations
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
// Abstract base class for integrator of particle's equation of motion,
|
||||
// used in tracking in space dependent magnetic field.
|
||||
|
||||
// Author: W.Wander <wwc@mit.edu>, 09.12.1997
|
||||
// Author: W.Wander (MIT), 09.12.1997
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4MAGERRORSTEPPER_HH
|
||||
#define G4MAGERRORSTEPPER_HH
|
||||
@@ -40,47 +40,77 @@
|
||||
#include "G4Mag_EqRhs.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
|
||||
/**
|
||||
* @brief G4MagErrorStepper is an abstract base class for integrator of
|
||||
* particle's equation of motion, used in tracking in space dependent
|
||||
* magnetic field.
|
||||
*/
|
||||
|
||||
class G4MagErrorStepper : public G4MagIntegratorStepper
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4MagErrorStepper.
|
||||
* @param[in] EqRhs Pointer to the provided equation of motion.
|
||||
* @param[in] numberOfVariables The number of integration variables.
|
||||
* @param[in] numberOfVariables The number of state variables.
|
||||
*/
|
||||
G4MagErrorStepper(G4EquationOfMotion*EqRhs,
|
||||
G4int numberOfVariables,
|
||||
G4int numStateVariables = 12);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~G4MagErrorStepper() override;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4MagErrorStepper(const G4MagErrorStepper&) = delete;
|
||||
G4MagErrorStepper& operator=(const G4MagErrorStepper&) = delete;
|
||||
|
||||
/**
|
||||
* The stepper for the Runge Kutta integration.
|
||||
* The stepsize is fixed, with the step size given by 'h'.
|
||||
* Integrates ODE starting values y[0 to 6].
|
||||
* Outputs yout[] and its estimated error yerr[].
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
* @param[out] yerr The estimated error.
|
||||
*/
|
||||
void Stepper( const G4double y[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yout[],
|
||||
G4double yerr[] ) override;
|
||||
// The stepper for the Runge Kutta integration. The stepsize
|
||||
// is fixed, with the Step size given by h.
|
||||
// Integrates ODE starting values y[0 to 6].
|
||||
// Outputs yout[] and its estimated error yerr[].
|
||||
|
||||
virtual void DumbStepper( const G4double y[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yout[] ) = 0;
|
||||
// Performs a 'dump' Step without error calculation.
|
||||
/**
|
||||
* Same as Stepper() function above, but should perform a 'dump' step
|
||||
* without error calculation. To be implemented in concrete derived classes.
|
||||
*/
|
||||
virtual void DumbStepper( const G4double y[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yout[] ) = 0;
|
||||
|
||||
/**
|
||||
* Estimates the maximum distance of curved solution and chord.
|
||||
*/
|
||||
G4double DistChord() const override;
|
||||
|
||||
private:
|
||||
|
||||
// STATE
|
||||
/** Data stored in order to find the chord. */
|
||||
G4ThreeVector fInitialPoint, fMidPoint, fFinalPoint;
|
||||
// Data stored in order to find the chord
|
||||
|
||||
// Dependent Objects, owned --- part of the STATE
|
||||
/** Arrays used only for temporary storage; they are allocated at the
|
||||
class level only for efficiency, so that calls to new and delete are
|
||||
not made in Stepper(). */
|
||||
G4double *yInitial, *yMiddle, *dydxMid, *yOneStep;
|
||||
// The following arrays are used only for temporary storage
|
||||
// they are allocated at the class level only for efficiency -
|
||||
// so that calls to new and delete are not made in Stepper().
|
||||
};
|
||||
|
||||
#include "G4MagErrorStepper.icc"
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
//
|
||||
// G4MagErrorStepper inline methods implementation
|
||||
//
|
||||
// Author: W.Wander <wwc@mit.edu>, 09.12.1997
|
||||
// Author: W.Wander (MIT), 09.12.1997
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
inline
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
// - Most obtain an error by breaking up the step in two
|
||||
// - G4ExactHelicalStepper does not provide an error estimate
|
||||
|
||||
// Created: J.Apostolakis, CERN - 05.11.1998
|
||||
// Author: John Apostolakis (CERN), 05.11.1998
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4MAGHELICALSTEPPER_HH
|
||||
#define G4MAGHELICALSTEPPER_HH
|
||||
@@ -47,76 +47,115 @@
|
||||
#include "G4Mag_EqRhs.hh"
|
||||
#include "G4ThreeVector.hh"
|
||||
|
||||
/**
|
||||
* @brief G4MagHelicalStepper is an abstract base class for integrator of
|
||||
* particle's equation of motion, used in tracking in space dependent magnetic
|
||||
* field, and for a set of steppers which use the helix as 'first order'
|
||||
* solution.
|
||||
*/
|
||||
|
||||
class G4MagHelicalStepper : public G4MagIntegratorStepper
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4MagHelicalStepper.
|
||||
* @param[in] EqRhs Pointer to the provided equation of motion.
|
||||
*/
|
||||
G4MagHelicalStepper(G4Mag_EqRhs *EqRhs);
|
||||
~G4MagHelicalStepper() override;
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4MagHelicalStepper() override = default;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4MagHelicalStepper(const G4MagHelicalStepper&) = delete;
|
||||
G4MagHelicalStepper& operator=(const G4MagHelicalStepper&) = delete;
|
||||
|
||||
/**
|
||||
* The stepper for the Runge Kutta integration.
|
||||
* The stepsize is fixed, with the step size given by 'h'.
|
||||
* Integrates ODE starting values y[0 to 6].
|
||||
* Outputs yout[] and its estimated error yerr[].
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
* @param[out] yerr The estimated error.
|
||||
*/
|
||||
void Stepper( const G4double y[], // VIRTUAL for ExactHelix
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yout[],
|
||||
G4double yerr[] ) override;
|
||||
// The stepper for the Runge Kutta integration.
|
||||
// The stepsize is fixed, equal to h.
|
||||
// Integrates ODE starting values y[0 to 6]
|
||||
// Outputs yout[] and its estimated error yerr[].
|
||||
|
||||
virtual void DumbStepper( const G4double y[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yout[] ) = 0;
|
||||
// Performs a 'dump' Step without error calculation.
|
||||
/**
|
||||
* Same as Stepper() function above, but should perform a 'dump' step
|
||||
* without error calculation. To be implemented in concrete derived classes.
|
||||
*/
|
||||
virtual void DumbStepper( const G4double y[],
|
||||
G4ThreeVector Bfld,
|
||||
G4double h,
|
||||
G4double yout[] ) = 0;
|
||||
|
||||
/**
|
||||
* Estimates the maximum distance of curved solution and chord.
|
||||
*/
|
||||
G4double DistChord()const override ;
|
||||
// Estimate maximum distance of curved solution and chord ...
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Performs a linear Step in regions without magnetic field.
|
||||
*/
|
||||
inline void LinearStep( const G4double yIn[],
|
||||
G4double h,
|
||||
G4double yHelix[]) const;
|
||||
// A linear Step in regions without magnetic field.
|
||||
|
||||
/**
|
||||
* A first order Step along a helix inside the field.
|
||||
*/
|
||||
void AdvanceHelix( const G4double yIn[],
|
||||
const G4ThreeVector& Bfld,
|
||||
G4double h,
|
||||
G4double yHelix[], G4double yHelix2[] = nullptr);
|
||||
// A first order Step along a helix inside the field.
|
||||
|
||||
/**
|
||||
* Evaluates the field at a certain point.
|
||||
*/
|
||||
inline void MagFieldEvaluate( const G4double y[], G4ThreeVector& Bfield );
|
||||
// Evaluate the field at a certain point.
|
||||
|
||||
/**
|
||||
* Evaluates inverse of Curvature of Track.
|
||||
*/
|
||||
inline G4double GetInverseCurve( const G4double Momentum,
|
||||
const G4double Bmag );
|
||||
// Evaluate Inverse of Curvature of Track
|
||||
|
||||
// Store and use the parameters of track :
|
||||
// radius of curve, Stepping angle, Radius of projected helix
|
||||
|
||||
/**
|
||||
* Modifiers and accessors for storing and using the parameters of a track:
|
||||
* radius of curve, Stepping angle, Radius of projected helix.
|
||||
*/
|
||||
inline void SetAngCurve(const G4double Ang);
|
||||
inline G4double GetAngCurve()const;
|
||||
|
||||
inline void SetCurve(const G4double Curve);
|
||||
inline G4double GetCurve()const;
|
||||
|
||||
inline void SetRadHelix(const G4double Rad);
|
||||
inline G4double GetRadHelix()const;
|
||||
|
||||
private:
|
||||
|
||||
/** As in G4Mag_EqRhs.hh/cc where it is not used. */
|
||||
static const G4double fUnitConstant;
|
||||
// As in G4Mag_EqRhs.hh/cc where it is not used.
|
||||
|
||||
G4Mag_EqRhs* fPtrMagEqOfMot = nullptr;
|
||||
|
||||
// Data stored in order to find the chord
|
||||
//
|
||||
/** Data stored in order to find the chord. */
|
||||
G4double fAngCurve = 0.0;
|
||||
G4double frCurve = 0.0;
|
||||
G4double frHelix = 0.0;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
//
|
||||
// G4MagHelicalStepper inline methods implementation
|
||||
//
|
||||
// Created: J.Apostolakis, CERN - 05.11.1998
|
||||
// Author: John Apostolakis (CERN), 05.11.1998
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
inline void
|
||||
|
||||
@@ -30,9 +30,8 @@
|
||||
// Provides a driver that talks to the Integrator Stepper, and insures that
|
||||
// the error is within acceptable bounds.
|
||||
|
||||
// V.Grichine, 07.10.1996 - Created
|
||||
// W.Wander, 28.01.1998 - Added ability for low order integrators
|
||||
// J.Apostolakis, 08.11.2001 - Respect minimum step in AccurateAdvance
|
||||
// Author: Vladimir Grichine (CERN), 07.10.1996 - Created
|
||||
// W.Wander (MIT), 28.01.1998 - Added ability for low order integrators
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4MAGINT_DRIVER_HH
|
||||
#define G4MAGINT_DRIVER_HH
|
||||
@@ -41,61 +40,123 @@
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
#include "G4ChordFinderDelegate.hh"
|
||||
|
||||
/**
|
||||
* @brief G4MagInt_Driver provides a driver that talks to the Integrator
|
||||
* Stepper and insures that the error is within acceptable bounds.
|
||||
*/
|
||||
|
||||
class G4MagInt_Driver : public G4VIntegrationDriver,
|
||||
public G4ChordFinderDelegate<G4MagInt_Driver>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4MagInt_Driver.
|
||||
* @param[in] hminimum The minumum allowed step.
|
||||
* @param[in] pItsStepper Pointer to the integrator stepper.
|
||||
* @param[in] numberOfComponents The number of integration variables.
|
||||
* @param[in] statisticsVerbosity Flag for verbosity.
|
||||
*/
|
||||
G4MagInt_Driver(G4double hminimum,
|
||||
G4MagIntegratorStepper* pItsStepper,
|
||||
G4int numberOfComponents = 6,
|
||||
G4int statisticsVerbosity = 0);
|
||||
~G4MagInt_Driver() override;
|
||||
// Constructor, destructor.
|
||||
|
||||
/**
|
||||
* Destructor. Provides statistics if verbosity level is greater than 1.
|
||||
*/
|
||||
~G4MagInt_Driver() override;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4MagInt_Driver(const G4MagInt_Driver&) = delete;
|
||||
G4MagInt_Driver& operator=(const G4MagInt_Driver&) = delete;
|
||||
|
||||
/**
|
||||
* Computes the step to take, based on chord limits.
|
||||
* @param[in,out] track The current track in field.
|
||||
* @param[in] stepMax Proposed maximum step length.
|
||||
* @param[in] epsStep Requested accuracy, y_err/hstep.
|
||||
* @param[in] chordDistance Maximum sagitta distance.
|
||||
* @returns The length of step taken.
|
||||
*/
|
||||
inline G4double AdvanceChordLimited(G4FieldTrack& track,
|
||||
G4double stepMax,
|
||||
G4double epsStep,
|
||||
G4double chordDistance) override;
|
||||
|
||||
/**
|
||||
* Dispatch interface method for initialisation/reset of driver.
|
||||
*/
|
||||
inline void OnStartTracking() override;
|
||||
|
||||
/**
|
||||
* Dispatch interface method for computing step. Does nothing here.
|
||||
*/
|
||||
inline void OnComputeStep(const G4FieldTrack* = nullptr) override {}
|
||||
|
||||
/**
|
||||
* The driver implements re-integration, so returns true.
|
||||
*/
|
||||
G4bool DoesReIntegrate() const override { return true; }
|
||||
|
||||
/**
|
||||
* Advances integration accurately by relative accuracy better than 'eps'.
|
||||
* @param[in,out] y_current The current track in field.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[in] eps Requested accuracy, y_err/hstep.
|
||||
* @param[in] hinitial Initial minimum integration step.
|
||||
* @returns true if integration succeeds.
|
||||
*/
|
||||
G4bool AccurateAdvance(G4FieldTrack& y_current,
|
||||
G4double hstep,
|
||||
G4double eps, // Requested y_err/hstep
|
||||
G4double hinitial = 0.0) override;
|
||||
// Above drivers for integrator (Runge-Kutta) with stepsize control.
|
||||
// Integrates ODE starting values y_current
|
||||
// from current s (s=s0) to s=s0+h with accuracy eps.
|
||||
// On output ystart is replaced by value at end of interval.
|
||||
// The concept is similar to the odeint routine from NRC p.721-722.
|
||||
|
||||
G4bool QuickAdvance( G4FieldTrack& y_val, // INOUT
|
||||
/**
|
||||
* Attempts one integration step, and returns estimated error 'dyerr'.
|
||||
* It does not ensure accuracy.
|
||||
* @param[in,out] y_val The current track in field.
|
||||
* @param[in] dydx dydx array.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[out] dchord_step Estimated sagitta distance.
|
||||
* @param[out] dyerr Estimated error.
|
||||
* @returns true if integration succeeds.
|
||||
*/
|
||||
G4bool QuickAdvance(G4FieldTrack& y_val, // In/Out
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr) override;
|
||||
// QuickAdvance just tries one Step - it does not ensure accuracy.
|
||||
G4double hstep,
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr) override;
|
||||
|
||||
void StreamInfo( std::ostream& os ) const override;
|
||||
// Write out the parameters / state of the driver
|
||||
/**
|
||||
* Writes out to stream the parameters/state of the driver.
|
||||
*/
|
||||
void StreamInfo( std::ostream& os ) const override;
|
||||
|
||||
G4bool QuickAdvance( G4FieldTrack& y_posvel, // INOUT
|
||||
/**
|
||||
* Attempts one integration step, and returns estimated error 'dyerr'.
|
||||
* It does not ensure accuracy.
|
||||
* @param[in,out] y_posvel The current track in field.
|
||||
* @param[in] dydx dydx array.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[out] dchord_step Estimated sagitta distance.
|
||||
* @param[out] dyerr_pos_sq Estimated error in position.
|
||||
* @param[out] dyerr_mom_rel_sq Estimated error in momentum
|
||||
* (normalised: Delta_Integration(p^2)/(p^2)).
|
||||
* @returns true if integration succeeds.
|
||||
*/
|
||||
G4bool QuickAdvance(G4FieldTrack& y_posvel, // In/Out
|
||||
const G4double dydx[],
|
||||
G4double hstep, // IN
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr_pos_sq,
|
||||
G4double& dyerr_mom_rel_sq );
|
||||
// New QuickAdvance that also just tries one Step
|
||||
// (so also does not ensure accuracy)
|
||||
// but does return the errors in position and
|
||||
// momentum (normalised: Delta_Integration(p^2)/(p^2) )
|
||||
G4double hstep, // In
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr_pos_sq,
|
||||
G4double& dyerr_mom_rel_sq );
|
||||
|
||||
/**
|
||||
* Accessors.
|
||||
*/
|
||||
inline G4double GetHmin() const;
|
||||
inline G4double Hmin() const; // Obsolete
|
||||
inline G4double GetSafety() const;
|
||||
@@ -104,95 +165,125 @@ class G4MagInt_Driver : public G4VIntegrationDriver,
|
||||
inline G4double GetErrcon() const;
|
||||
void GetDerivatives(const G4FieldTrack& y_curr, // INput
|
||||
G4double dydx[]) const override; // OUTput
|
||||
|
||||
void GetDerivatives(const G4FieldTrack& track,
|
||||
G4double dydx[],
|
||||
G4double field[]) const override;
|
||||
// Accessors
|
||||
|
||||
/**
|
||||
* Getter and setter for the equation of motion.
|
||||
*/
|
||||
G4EquationOfMotion* GetEquationOfMotion() override;
|
||||
void SetEquationOfMotion(G4EquationOfMotion* equation) override;
|
||||
|
||||
/**
|
||||
* Sets a new stepper 'pItsStepper' for this driver. Then it calls
|
||||
* ResetParameters() to update its parameters accordingly.
|
||||
*/
|
||||
void RenewStepperAndAdjust(G4MagIntegratorStepper* pItsStepper) override;
|
||||
// Sets a new stepper pItsStepper for this driver. Then it calls
|
||||
// ReSetParameters to reset its parameters accordingly.
|
||||
|
||||
/**
|
||||
* Resets the qarameters according to the new provided safety value.
|
||||
* i) sets the exponents (pgrow & pshrnk), using the current order;
|
||||
* ii) sets the safety and calculates "errcon" according to the above values.
|
||||
*/
|
||||
inline void ReSetParameters(G4double new_safety = 0.9);
|
||||
// i) sets the exponents (pgrow & pshrnk),
|
||||
// using the current Stepper's order,
|
||||
// ii) sets the safety
|
||||
// ii) calculates "errcon" according to the above values.
|
||||
|
||||
/**
|
||||
* Modifiers. When setting safety or pgrow, errcon will be set
|
||||
* to a compatible value.
|
||||
*/
|
||||
inline void SetSafety(G4double valS);
|
||||
inline void SetPshrnk(G4double valPs);
|
||||
inline void SetPgrow (G4double valPg);
|
||||
inline void SetErrcon(G4double valEc);
|
||||
// When setting safety or pgrow, errcon will be set to a compatible value.
|
||||
|
||||
inline G4double ComputeAndSetErrcon();
|
||||
|
||||
/**
|
||||
* Accessors for the integrator stepper.
|
||||
*/
|
||||
const G4MagIntegratorStepper* GetStepper() const override;
|
||||
G4MagIntegratorStepper* GetStepper() override;
|
||||
G4MagIntegratorStepper* GetStepper() override;
|
||||
|
||||
void OneGoodStep( G4double ystart[], // Like old RKF45step()
|
||||
const G4double dydx[],
|
||||
G4double& x,
|
||||
G4double htry,
|
||||
G4double eps, // memb variables ?
|
||||
G4double& hdid,
|
||||
G4double& hnext ) ;
|
||||
// This takes one Step that is as large as possible while
|
||||
// satisfying the accuracy criterion of:
|
||||
// yerr < eps * |y_end-y_start|
|
||||
/**
|
||||
* Takes one Step that is as large as possible while satisfying the
|
||||
* accuracy criterion of: yerr < eps * |y_end-y_start|.
|
||||
* @param[in,out] ystart The current track state, y.
|
||||
* @param[in] dydx The derivatives array.
|
||||
* @param[in,out] x Step start, x.
|
||||
* @param[in] htry Step to attempt.
|
||||
* @param[in] eps The relative accuracy.
|
||||
* @param[out] hdid Step achieved.
|
||||
* @param[out] hnext Proposed next step.
|
||||
* @returns true if integration succeeds.
|
||||
*/
|
||||
void OneGoodStep(G4double ystart[], // Like old RKF45step()
|
||||
const G4double dydx[],
|
||||
G4double& x,
|
||||
G4double htry,
|
||||
G4double eps,
|
||||
G4double& hdid,
|
||||
G4double& hnext ) ;
|
||||
|
||||
/**
|
||||
* Takes the last step's normalised error and calculates a step size
|
||||
* for the next step. Does it limit the next step's size within a factor
|
||||
* of the current?
|
||||
* -- DOES NOT limit for very bad steps
|
||||
* -- DOES limit for very good (x5).
|
||||
*/
|
||||
G4double ComputeNewStepSize(G4double errMaxNorm, // normalised
|
||||
G4double hstepCurrent) override;
|
||||
// Taking the last step's normalised error, calculate
|
||||
// a step size for the next step.
|
||||
// Does it limit the next step's size within a factor of the current?
|
||||
// -- DOES NOT limit for very bad steps
|
||||
// -- DOES limit for very good (x5)
|
||||
|
||||
G4double
|
||||
ComputeNewStepSize_WithoutReductionLimit(G4double errMaxNorm,
|
||||
G4double hstepCurrent);
|
||||
// Taking the last step's normalised error, calculate
|
||||
// a step size for the next step.
|
||||
// Do not limit the next step's size within a factor of the
|
||||
// current one when *reducing* the size, i.e. for badly failing steps.
|
||||
/**
|
||||
* Taking the last step's normalised error, calculates a step size for
|
||||
* the next step. Does not limit the next step's size within a factor of
|
||||
* the current one when *reducing* the size, i.e. for badly failing steps.
|
||||
*/
|
||||
G4double ComputeNewStepSize_WithoutReductionLimit(G4double errMaxNorm,
|
||||
G4double hstepCurrent);
|
||||
|
||||
/**
|
||||
* Taking the last step's normalised error, calculates a step size for
|
||||
* the next step. Limits the next step's size within a range around the
|
||||
* current one.
|
||||
*/
|
||||
G4double ComputeNewStepSize_WithinLimits(G4double errMaxNorm, // normalised
|
||||
G4double hstepCurrent);
|
||||
// Taking the last step's normalised error, calculate
|
||||
// a step size for the next step.
|
||||
// Limit the next step's size within a range around the current one.
|
||||
|
||||
/**
|
||||
* Modifier and accessor for the maximum number of steps that can be taken
|
||||
* for the integration of a single segment, i.e. a single call to
|
||||
* AccurateAdvance().
|
||||
*/
|
||||
inline G4int GetMaxNoSteps() const;
|
||||
inline void SetMaxNoSteps(G4int val);
|
||||
// Modify and Get the Maximum number of Steps that can be
|
||||
// taken for the integration of a single segment -
|
||||
// (i.e. a single call to AccurateAdvance).
|
||||
|
||||
/**
|
||||
* More modifiers and accessors.
|
||||
*/
|
||||
inline void SetHmin(G4double newval);
|
||||
void SetVerboseLevel(G4int newLevel) override;
|
||||
G4int GetVerboseLevel() const override;
|
||||
|
||||
inline G4double GetSmallestFraction() const;
|
||||
void SetSmallestFraction( G4double val );
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Loggers, issuing warnings for undesirable situations.
|
||||
*/
|
||||
void WarnSmallStepSize(G4double hnext, G4double hstep,
|
||||
G4double h, G4double xDone,
|
||||
G4int noSteps);
|
||||
|
||||
void WarnTooManyStep(G4double x1start, G4double x2end, G4double xCurrent);
|
||||
void WarnEndPointTooFar(G4double endPointDist,
|
||||
G4double hStepSize ,
|
||||
G4double epsilonRelative,
|
||||
G4int debugFlag);
|
||||
// Issue warnings for undesirable situations
|
||||
|
||||
/**
|
||||
* Loggers for verbosity printouts.
|
||||
*/
|
||||
void PrintStatus(const G4double* StartArr,
|
||||
G4double xstart,
|
||||
const G4double* CurrentArr,
|
||||
@@ -209,10 +300,10 @@ class G4MagInt_Driver : public G4VIntegrationDriver,
|
||||
G4int subStepNo,
|
||||
G4double subStepSize,
|
||||
G4double dotVelocities);
|
||||
// Verbose output for debugging
|
||||
|
||||
/**
|
||||
* Reports on the number of steps, maximum errors etc.
|
||||
*/
|
||||
void PrintStatisticsReport();
|
||||
// Report on the number of steps, maximum errors etc.
|
||||
|
||||
#ifdef QUICK_ADV_TWO
|
||||
G4bool QuickAdvance( G4double yarrin[], // In
|
||||
@@ -228,25 +319,31 @@ class G4MagInt_Driver : public G4VIntegrationDriver,
|
||||
// ---------------------------------------------------------------
|
||||
// INVARIANTS
|
||||
|
||||
/** Minimum Step allowed in a Step (in absolute units). */
|
||||
G4double fMinimumStep = 0.0;
|
||||
// Minimum Step allowed in a Step (in absolute units)
|
||||
|
||||
/** Smallest fraction of (existing) curve length, in relative units.
|
||||
Below this fraction the current step will be the last. */
|
||||
G4double fSmallestFraction = 1.0e-12; // Expected range 1e-12 to 5e-15
|
||||
// Smallest fraction of (existing) curve length - in relative units
|
||||
// below this fraction the current step will be the last
|
||||
|
||||
const G4int fNoIntegrationVariables = 0; // Variables in integration
|
||||
const G4int fMinNoVars = 12; // Minimum number for FieldTrack
|
||||
const G4int fNoVars = 0; // Full number of variable
|
||||
/** Variables in integration. */
|
||||
const G4int fNoIntegrationVariables = 0;
|
||||
|
||||
/** Minimum number for FieldTrack. */
|
||||
const G4int fMinNoVars = 12;
|
||||
|
||||
/** Full number of variable. */
|
||||
const G4int fNoVars = 0;
|
||||
|
||||
/** Default maximum number of steps is Base divided by the order of Stepper. */
|
||||
G4int fMaxNoSteps;
|
||||
G4int fMaxStepBase = 250; // was 5000
|
||||
// Default maximum number of steps is Base divided by the order of Stepper
|
||||
|
||||
/** Parameters used to grow and shrink trial stepsize. */
|
||||
G4double safety;
|
||||
G4double pshrnk; // exponent for shrinking
|
||||
G4double pgrow; // exponent for growth
|
||||
G4double errcon;
|
||||
// Parameters used to grow and shrink trial stepsize.
|
||||
|
||||
G4int fStatisticsVerboseLevel = 0;
|
||||
|
||||
@@ -258,15 +355,15 @@ class G4MagInt_Driver : public G4VIntegrationDriver,
|
||||
// ---------------------------------------------------------------
|
||||
// STATE
|
||||
|
||||
/** Step Statistics. */
|
||||
unsigned long fNoTotalSteps=0, fNoBadSteps=0;
|
||||
unsigned long fNoSmallSteps=0, fNoInitialSmallSteps=0, fNoCalls=0;
|
||||
G4double fDyerr_max=0.0, fDyerr_mx2=0.0;
|
||||
G4double fDyerrPos_smTot=0.0, fDyerrPos_lgTot=0.0, fDyerrVel_lgTot=0.0;
|
||||
G4double fSumH_sm=0.0, fSumH_lg=0.0;
|
||||
// Step Statistics
|
||||
|
||||
/** Could be varied during tracking - to help identify issues. */
|
||||
G4int fVerboseLevel = 0; // Verbosity level for printing (debug, ..)
|
||||
// Could be varied during tracking - to help identify issues
|
||||
|
||||
using ChordFinderDelegate = G4ChordFinderDelegate<G4MagInt_Driver>;
|
||||
};
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
//
|
||||
// G4MagInt_Driver inline methods implementation
|
||||
//
|
||||
// V.Grichine, 07.10.1996 - Created
|
||||
// Author: Vladimir Grichine (CERN), 07.10.1996 - Created
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
inline
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
// Class description:
|
||||
//
|
||||
// Abstract base class for integrator of particle's equation of motion,
|
||||
// used in tracking in space dependent magnetic field
|
||||
// used in tracking in space dependent magnetic field.
|
||||
//
|
||||
// A Stepper must integrate over NumberOfVariables elements,
|
||||
// and also copy (from input to output) any of NoStateVariables
|
||||
@@ -36,117 +36,183 @@
|
||||
//
|
||||
// So it is expected that NoStateVariables >= NumberOfVariables
|
||||
|
||||
// Author: J.Apostolakis, CERN - 15.01.1997
|
||||
// Author: John Apostolakis (CERN), 15.01.1997
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4MAGINTEGRATORSTEPPER_HH
|
||||
#define G4MAGINTEGRATORSTEPPER_HH
|
||||
|
||||
#include "G4Types.hh"
|
||||
#include "G4EquationOfMotion.hh"
|
||||
#include "G4FieldParameters.hh"
|
||||
#include "G4VIntegrationDriver.hh"
|
||||
#include "G4IntegrationDriver.hh"
|
||||
|
||||
class G4VIntegrationDriver;
|
||||
|
||||
/**
|
||||
* @brief G4MagIntegratorStepper is an abstract base class for integrator
|
||||
* of particle's equation of motion, used in tracking in space dependent
|
||||
* magnetic field.
|
||||
*/
|
||||
|
||||
class G4MagIntegratorStepper
|
||||
{
|
||||
public: // with description
|
||||
public:
|
||||
|
||||
G4MagIntegratorStepper(G4EquationOfMotion* Equation,
|
||||
G4int numIntegrationVariables,
|
||||
G4int numStateVariables = 12,
|
||||
G4bool isFSAL = false );
|
||||
/**
|
||||
* Constructor for G4MagIntegratorStepper.
|
||||
* @param[in] Equation Pointer to the provided equation of motion.
|
||||
* @param[in] numIntegrationVariables The number of integration variables.
|
||||
* @param[in] numStateVariables The number of state variables.
|
||||
* @param[in] isFSAL Flag to indicate if it is an FSAL (First Same As Last)
|
||||
* type driver.
|
||||
*/
|
||||
G4MagIntegratorStepper(G4EquationOfMotion* Equation,
|
||||
G4int numIntegrationVariables,
|
||||
G4int numStateVariables = 12,
|
||||
G4bool isFSAL = false );
|
||||
|
||||
virtual ~G4MagIntegratorStepper() = default;
|
||||
// Constructor and destructor. No actions.
|
||||
/**
|
||||
* Default virtual Destructor.
|
||||
*/
|
||||
virtual ~G4MagIntegratorStepper() = default;
|
||||
|
||||
G4MagIntegratorStepper(const G4MagIntegratorStepper&) = delete;
|
||||
G4MagIntegratorStepper& operator=(const G4MagIntegratorStepper&) = delete;
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4MagIntegratorStepper(const G4MagIntegratorStepper&) = delete;
|
||||
G4MagIntegratorStepper& operator=(const G4MagIntegratorStepper&) = delete;
|
||||
|
||||
virtual void Stepper( const G4double y[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yout[],
|
||||
G4double yerr[] ) = 0;
|
||||
// The stepper for the Runge Kutta integration.
|
||||
// The stepsize is fixed, with the Step size given by h.
|
||||
// Integrates ODE starting values y[0 to 6].
|
||||
// Outputs yout[] and its estimated error yerr[].
|
||||
/**
|
||||
* The stepper for the Runge Kutta integration.
|
||||
* The stepsize is fixed, with the step size given by 'h'.
|
||||
* Integrates ODE starting values y[0 to 6].
|
||||
* Outputs yout[] and its estimated error yerr[].
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
* @param[out] yerr The estimated error.
|
||||
*/
|
||||
virtual void Stepper( const G4double y[],
|
||||
const G4double dydx[],
|
||||
G4double h,
|
||||
G4double yout[],
|
||||
G4double yerr[] ) = 0;
|
||||
|
||||
virtual G4double DistChord() const = 0;
|
||||
// Estimate the maximum distance of a chord from the true path
|
||||
// over the segment last integrated.
|
||||
/**
|
||||
* Estimates the maximum distance of a chord from the true path
|
||||
* over the segment last integrated.
|
||||
*/
|
||||
virtual G4double DistChord() const = 0;
|
||||
|
||||
inline void NormaliseTangentVector( G4double vec[6] );
|
||||
// Simple utility function to (re)normalise 'unit velocity' vector.
|
||||
/**
|
||||
* Simple utility function to (re)normalise 'unit velocity' vector.
|
||||
*/
|
||||
inline void NormaliseTangentVector( G4double vec[6] );
|
||||
|
||||
inline void NormalisePolarizationVector( G4double vec[12] );
|
||||
// Simple utility function to (re)normalise 'unit spin' vector.
|
||||
/**
|
||||
* Simple utility function to (re)normalise 'unit spin' vector.
|
||||
*/
|
||||
inline void NormalisePolarizationVector( G4double vec[12] );
|
||||
|
||||
inline void RightHandSide( const G4double y[], G4double dydx[] ) const;
|
||||
// Utility method to supply the standard Evaluation of the
|
||||
// Right Hand side of the associated equation.
|
||||
/**
|
||||
* Utility method to supply the standard Evaluation of the
|
||||
* Right Hand side of the associated equation.
|
||||
*/
|
||||
inline void RightHandSide( const G4double y[], G4double dydx[] ) const;
|
||||
|
||||
inline void RightHandSide( const G4double y[],
|
||||
G4double dydx[],
|
||||
G4double field[] ) const;
|
||||
// Calculate dydx and field at point y.
|
||||
/**
|
||||
* Calculates 'dydx' and 'field' at point 'y'.
|
||||
*/
|
||||
inline void RightHandSide( const G4double y[],
|
||||
G4double dydx[],
|
||||
G4double field[] ) const;
|
||||
|
||||
inline G4int GetNumberOfVariables() const;
|
||||
// Get the number of variables that the stepper will integrate over.
|
||||
/**
|
||||
* Returns the number of variables that the stepper will integrate over.
|
||||
*/
|
||||
inline G4int GetNumberOfVariables() const;
|
||||
|
||||
inline G4int GetNumberOfStateVariables() const;
|
||||
// Get the number of variables of state variables (>= above, integration)
|
||||
/**
|
||||
* Returns the number of variables of state variables (>= above, integration).
|
||||
*/
|
||||
inline G4int GetNumberOfStateVariables() const;
|
||||
|
||||
virtual G4int IntegratorOrder() const = 0;
|
||||
// Returns the order of the integrator
|
||||
// i.e. its error behaviour is of the order O(h^order).
|
||||
/**
|
||||
* Returns the order of the integrator, i.e. its error behaviour is of
|
||||
* the order O(h^order).
|
||||
*/
|
||||
virtual G4int IntegratorOrder() const = 0;
|
||||
|
||||
inline G4int IntegrationOrder();
|
||||
// Replacement method - using new data member
|
||||
/**
|
||||
* Returns the stepper type ID ('kUserStepper').
|
||||
* This function should be overriden in derived classes.
|
||||
*/
|
||||
virtual G4StepperType StepperType() const { return kUserStepper; }
|
||||
|
||||
/**
|
||||
* Replacement method - using new data member.
|
||||
*/
|
||||
inline G4int IntegrationOrder();
|
||||
|
||||
inline G4EquationOfMotion* GetEquationOfMotion();
|
||||
inline const G4EquationOfMotion* GetEquationOfMotion() const;
|
||||
// As some steppers (eg RKG3) require other methods of Eq_Rhs
|
||||
// this function allows for access to them.
|
||||
/**
|
||||
* Methods returning the pointer to the associated equation of motion.
|
||||
* As some steppers (e.g. RKG3) require other methods of Eq_Rhs this
|
||||
* function allows for access to them.
|
||||
*/
|
||||
inline G4EquationOfMotion* GetEquationOfMotion();
|
||||
inline const G4EquationOfMotion* GetEquationOfMotion() const;
|
||||
|
||||
inline void SetEquationOfMotion(G4EquationOfMotion* newEquation);
|
||||
/**
|
||||
* Setter for the equation of motion.
|
||||
*/
|
||||
inline void SetEquationOfMotion(G4EquationOfMotion* newEquation);
|
||||
|
||||
inline unsigned long GetfNoRHSCalls();
|
||||
inline void ResetfNORHSCalls();
|
||||
// Count number of calls to RHS method(s)
|
||||
/**
|
||||
* Methods for counting/resetting the number of calls to RHS method(s).
|
||||
*/
|
||||
inline unsigned long GetfNoRHSCalls();
|
||||
inline void ResetfNORHSCalls();
|
||||
|
||||
inline G4bool IsFSAL() const;
|
||||
/**
|
||||
* Returns true if the stepper is of FSAL (First Same As Last) type.
|
||||
*/
|
||||
inline G4bool IsFSAL() const;
|
||||
|
||||
// TODO - QSS
|
||||
inline G4bool isQSS() const { return fIsQSS; }
|
||||
void SetIsQSS(G4bool val){ fIsQSS= val;}
|
||||
/**
|
||||
* Returns true if the stepper is of QSS (Quantum State Simulation) type.
|
||||
*/
|
||||
inline G4bool isQSS() const;
|
||||
inline void SetIsQSS(G4bool val);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
|
||||
inline void SetIntegrationOrder(G4int order);
|
||||
inline void SetFSAL(G4bool flag = true);
|
||||
/**
|
||||
* Setters for the integration order and FSAL type.
|
||||
*/
|
||||
inline void SetIntegrationOrder(G4int order);
|
||||
inline void SetFSAL(G4bool flag = true);
|
||||
|
||||
private:
|
||||
|
||||
G4EquationOfMotion* fEquation_Rhs = nullptr;
|
||||
const G4int fNoIntegrationVariables = 0; // Variables in integration
|
||||
const G4int fNoStateVariables = 0; // Number required for FieldTrack
|
||||
G4EquationOfMotion* fEquation_Rhs = nullptr;
|
||||
const G4int fNoIntegrationVariables = 0; // Variables in integration
|
||||
const G4int fNoStateVariables = 0; // Number required for FieldTrack
|
||||
|
||||
mutable unsigned long fNoRHSCalls = 0UL;
|
||||
// Counter for calls to RHS method
|
||||
/** Counter for calls to RHS method. */
|
||||
mutable unsigned long fNoRHSCalls = 0UL;
|
||||
|
||||
// Parameters of a RK method -- must be shared by all steppers of a type
|
||||
// -- Invariants for a class
|
||||
// Parameters of a RK method -- must be shared by all steppers of a type
|
||||
// -- Invariants for a class
|
||||
|
||||
G4int fIntegrationOrder = -1; // must be set by stepper !!!
|
||||
// All ClassicalRK4 steppers are 4th order
|
||||
G4bool fIsFSAL = false;
|
||||
// Depends on RK method & implementation
|
||||
G4bool fIsQSS = false;
|
||||
|
||||
G4int fIntegrationOrder = -1; // must be set by stepper !!!
|
||||
// All ClassicalRK4 steppers are 4th order
|
||||
G4bool fIsFSAL = false;
|
||||
// Depends on RK method & implementation
|
||||
G4bool fIsQSS = false;
|
||||
};
|
||||
|
||||
#include "G4MagIntegratorStepper.icc"
|
||||
|
||||
#endif /* G4MAGIntegratorSTEPPER */
|
||||
#endif
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
//
|
||||
// G4MagIntegratorStepper inline methods implementation
|
||||
//
|
||||
// Author: J.Apostolakis, CERN - 15.01.1997
|
||||
// Author: John Apostolakis (CERN), 15.01.1997
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
inline
|
||||
@@ -73,6 +73,18 @@ G4bool G4MagIntegratorStepper::IsFSAL() const
|
||||
return fIsFSAL;
|
||||
}
|
||||
|
||||
inline
|
||||
G4bool G4MagIntegratorStepper::isQSS() const
|
||||
{
|
||||
return fIsQSS;
|
||||
}
|
||||
|
||||
inline
|
||||
void G4MagIntegratorStepper::SetIsQSS(G4bool val)
|
||||
{
|
||||
fIsQSS = val;
|
||||
}
|
||||
|
||||
inline
|
||||
void G4MagIntegratorStepper::SetIntegrationOrder(G4int order)
|
||||
{
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
// i) is when using a moving reference frame ... or
|
||||
// ii) extending for other forces, e.g. an electric field
|
||||
|
||||
// Created: J.Apostolakis, CERN - 13.01.1997
|
||||
// Author: John Apostolakis (CERN), 13.01.1997
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4MAG_EQRHS_HH
|
||||
#define G4MAG_EQRHS_HH
|
||||
@@ -43,36 +43,53 @@
|
||||
|
||||
class G4MagneticField;
|
||||
|
||||
/**
|
||||
* @brief G4Mag_EqRhs is the "standard" equation of motion of a particle
|
||||
* in a pure magnetic field.
|
||||
*/
|
||||
|
||||
class G4Mag_EqRhs : public G4EquationOfMotion
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4Mag_EqRhs.
|
||||
* @param[in] magField Pointer to the associated magnetic field.
|
||||
*/
|
||||
G4Mag_EqRhs(G4MagneticField* magField);
|
||||
~G4Mag_EqRhs() override;
|
||||
// Constructor and destructor. No actions.
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4Mag_EqRhs() override = default;
|
||||
|
||||
/**
|
||||
* Calculates the value of the derivative, given the value of the field.
|
||||
* @param[in] y Coefficients array.
|
||||
* @param[in] B Field value.
|
||||
* @param[out] dydx Derivatives array.
|
||||
*/
|
||||
void EvaluateRhsGivenB( const G4double y[],
|
||||
const G4double B[3],
|
||||
G4double dydx[] ) const override = 0;
|
||||
// Given the value of the field "B", this function
|
||||
// calculates the value of the derivative dydx.
|
||||
// This is the _only_ function a subclass must define.
|
||||
// The other two functions use Rhs_givenB.
|
||||
|
||||
/**
|
||||
* Returns and sets the charge momentum mass value.
|
||||
*/
|
||||
inline G4double FCof() const { return fCof_val; }
|
||||
|
||||
void SetChargeMomentumMass( G4ChargeState particleCharge,
|
||||
G4double MomentumXc,
|
||||
G4double mass ) override;
|
||||
private:
|
||||
|
||||
/** Charge momentum mass. */
|
||||
G4double fCof_val = 0.0;
|
||||
|
||||
/** Coefficient in the Lorentz motion equation (Lorentz force), if the
|
||||
magnetic field B is in Tesla, the particle charge in units of the
|
||||
elementary charge, the momentum P in MeV/c, and the space coordinates
|
||||
and path along the trajectory in mm. */
|
||||
static const G4double fUnitConstant; // Set to 0.299792458
|
||||
// Coefficient in the Lorentz motion equation (Lorentz force), if the
|
||||
// magnetic field B is in Tesla, the particle charge in units of the
|
||||
// elementary (positron?) charge, the momentum P in MeV/c, and the
|
||||
// space coordinates and path along the trajectory in mm.
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
// magnetic field. The three components of the particle's spin are
|
||||
// treated utilising BMT equation.
|
||||
|
||||
// Created: J.Apostolakis, P.Gumplinger - 08.02.1999
|
||||
// Authors: John Apostolakis (CERN) & Peter Gumplinger (TRIUMF), 08.02.1999
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4MAG_SPIN_EQRHS_HH
|
||||
#define G4MAG_SPIN_EQRHS_HH
|
||||
@@ -42,33 +42,60 @@
|
||||
|
||||
class G4MagneticField;
|
||||
|
||||
/**
|
||||
* @brief G4Mag_SpinEqRhs defines the equation of motion for a particle with
|
||||
* spin in a pure magnetic field. The three components of the particle's spin
|
||||
* are treated utilising BMT equation.
|
||||
*/
|
||||
|
||||
class G4Mag_SpinEqRhs : public G4Mag_EqRhs
|
||||
{
|
||||
public:
|
||||
public:
|
||||
|
||||
G4Mag_SpinEqRhs( G4MagneticField* MagField );
|
||||
~G4Mag_SpinEqRhs() override;
|
||||
// Constructor and destructor. No actions.
|
||||
/**
|
||||
* Constructor for G4Mag_SpinEqRhs.
|
||||
* @param[in] MagField Pointer to the associated magnetic field.
|
||||
*/
|
||||
G4Mag_SpinEqRhs( G4MagneticField* MagField );
|
||||
|
||||
void SetChargeMomentumMass(G4ChargeState particleCharge,
|
||||
G4double MomentumXc,
|
||||
G4double mass) override;
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4Mag_SpinEqRhs() override = default;
|
||||
|
||||
void EvaluateRhsGivenB( const G4double y[],
|
||||
const G4double B[3],
|
||||
G4double dydx[] ) const override;
|
||||
// Given the value of the magnetic field B, this function
|
||||
// calculates the value of the derivative dydx.
|
||||
/**
|
||||
* Sets the charge momentum mass value.
|
||||
*/
|
||||
void SetChargeMomentumMass(G4ChargeState particleCharge,
|
||||
G4double MomentumXc,
|
||||
G4double mass) override;
|
||||
|
||||
inline void SetAnomaly(G4double a) { anomaly = a; }
|
||||
inline G4double GetAnomaly() const { return anomaly; }
|
||||
// set/get magnetic anomaly
|
||||
/**
|
||||
* Calculates the value of the derivative, given the value of the field.
|
||||
* @param[in] y Coefficients array.
|
||||
* @param[in] B Field value.
|
||||
* @param[out] dydx Derivatives array.
|
||||
*/
|
||||
void EvaluateRhsGivenB( const G4double y[],
|
||||
const G4double B[3],
|
||||
G4double dydx[] ) const override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Setter and getter for the magnetic anomaly.
|
||||
*/
|
||||
inline void SetAnomaly(G4double a) { anomaly = a; }
|
||||
inline G4double GetAnomaly() const { return anomaly; }
|
||||
|
||||
G4double charge=0.0, mass=0.0, magMoment=0.0, spin=0.0;
|
||||
G4double omegac=0.0, anomaly=0.0011659208;
|
||||
G4double beta=0.0, gamma=0.0;
|
||||
/**
|
||||
* Returns the equation of motion type ID, i.e. "kEqMagneticWithSpin".
|
||||
*/
|
||||
inline G4EquationType GetEquationType() const override { return kEqMagneticWithSpin; }
|
||||
|
||||
private:
|
||||
|
||||
G4double charge=0.0, mass=0.0, magMoment=0.0, spin=0.0;
|
||||
G4double omegac=0.0, anomaly=0.0011659208;
|
||||
G4double beta=0.0, gamma=0.0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
// frame ... or extending the class to include additional Forces,
|
||||
// eg an electric field
|
||||
|
||||
// Created: J.Apostolakis, CERN - 13.01.1997
|
||||
// Author: John Apostolakis (CERN), 13.01.1997
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4MAG_USUAL_EQRHS
|
||||
#define G4MAG_USUAL_EQRHS
|
||||
@@ -42,23 +42,48 @@
|
||||
|
||||
class G4MagneticField;
|
||||
|
||||
/**
|
||||
* @brief G4Mag_UsualEqRhs defines the standard right-hand side
|
||||
* for equation of motion.
|
||||
*/
|
||||
|
||||
class G4Mag_UsualEqRhs : public G4Mag_EqRhs
|
||||
{
|
||||
public:
|
||||
public:
|
||||
|
||||
G4Mag_UsualEqRhs( G4MagneticField* MagField );
|
||||
~G4Mag_UsualEqRhs() override;
|
||||
// Constructor and destructor. No actions.
|
||||
/**
|
||||
* Constructor for G4Mag_UsualEqRhs.
|
||||
* @param[in] MagField Pointer to the associated magnetic field.
|
||||
*/
|
||||
G4Mag_UsualEqRhs( G4MagneticField* MagField );
|
||||
|
||||
void EvaluateRhsGivenB( const G4double y[],
|
||||
const G4double B[3],
|
||||
G4double dydx[] ) const override;
|
||||
// Given the value of the magnetic field B, this function
|
||||
// calculates the value of the derivative dydx.
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4Mag_UsualEqRhs() override = default;
|
||||
// Constructor and destructor. No actions.
|
||||
|
||||
void SetChargeMomentumMass( G4ChargeState particleCharge,
|
||||
G4double MomentumXc,
|
||||
G4double mass ) override;
|
||||
/**
|
||||
* Calculates the value of the derivative, given the value of the field.
|
||||
* @param[in] y Coefficients array.
|
||||
* @param[in] B Field value.
|
||||
* @param[out] dydx Derivatives array.
|
||||
*/
|
||||
void EvaluateRhsGivenB( const G4double y[],
|
||||
const G4double B[3],
|
||||
G4double dydx[] ) const override;
|
||||
|
||||
/**
|
||||
* Sets the charge momentum mass value.
|
||||
*/
|
||||
void SetChargeMomentumMass( G4ChargeState particleCharge,
|
||||
G4double MomentumXc,
|
||||
G4double mass ) override;
|
||||
|
||||
/**
|
||||
* Returns the equation of motion type ID, i.e. "kEqMagnetic".
|
||||
*/
|
||||
inline G4EquationType GetEquationType() const override { return kEqMagnetic; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
//
|
||||
// Magnetic Field abstract class, implements inquiry function interface.
|
||||
|
||||
// Created: J.Apostolakis, CERN - 13.01.1996
|
||||
// Author: John Apostolakis (CERN), 13.01.1996
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4MAGNETIC_FIELD_HH
|
||||
#define G4MAGNETIC_FIELD_HH
|
||||
@@ -41,19 +41,37 @@ class G4MagneticField : public G4Field
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default Constructor and Destructor.
|
||||
*/
|
||||
G4MagneticField();
|
||||
~G4MagneticField() override;
|
||||
// Constructor and destructor. No actions.
|
||||
~G4MagneticField() override = default;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator.
|
||||
*/
|
||||
G4MagneticField(const G4MagneticField& r);
|
||||
G4MagneticField& operator= (const G4MagneticField& p);
|
||||
// Copy constructor & assignment operator.
|
||||
|
||||
/**
|
||||
* Since a pure magnetic field does not change track energy, returns false.
|
||||
*/
|
||||
inline G4bool DoesFieldChangeEnergy() const override { return false; }
|
||||
// Since a pure magnetic field does not change track energy
|
||||
|
||||
/**
|
||||
* Given the position time vector 'Point', returns the value of the
|
||||
* field in the array 'Bfield'.
|
||||
* @param[in] Point The position time vector.
|
||||
* @param[out] Bfield The field array in output.
|
||||
*/
|
||||
void GetFieldValue( const G4double Point[4],
|
||||
G4double* Bfield ) const override = 0;
|
||||
|
||||
/**
|
||||
* Returns the field type-ID, "kMagnetic".
|
||||
* This should be overriden in derived classes.
|
||||
*/
|
||||
inline G4FieldType GetFieldType() const override { return kMagnetic; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -26,10 +26,10 @@
|
||||
//
|
||||
// Class description:
|
||||
//
|
||||
// Modified midpoint method implementation, based on Boost odeint
|
||||
// Modified midpoint method implementation, based on Boost odeint.
|
||||
|
||||
// Author: Dmitry Sorokin, Google Summer of Code 2016
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// Author: Dmitry Sorokin (CERN, Google Summer of Code 2016), 07.10.2016
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4MODIFIED_MIDPOINT_HH
|
||||
#define G4MODIFIED_MIDPOINT_HH
|
||||
@@ -38,31 +38,74 @@
|
||||
#include "G4EquationOfMotion.hh"
|
||||
#include "G4FieldTrack.hh"
|
||||
|
||||
/**
|
||||
* @brief G4ModifiedMidpoint implements a midpoint method adapted from
|
||||
* Boost odeint.
|
||||
*/
|
||||
|
||||
class G4ModifiedMidpoint
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4ModifiedMidpoint.
|
||||
* @param[in] equation Pointer to the provided equation of motion.
|
||||
* @param[in] nvar The number of integration variables.
|
||||
* @param[in] steps The minimum number of steps.
|
||||
*/
|
||||
G4ModifiedMidpoint( G4EquationOfMotion* equation,
|
||||
G4int nvar = 6, G4int steps = 2 );
|
||||
~G4ModifiedMidpoint() = default;
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4ModifiedMidpoint() = default;
|
||||
|
||||
/**
|
||||
* Computes one step.
|
||||
* @param[in] yIn Starting values array of integration variables.
|
||||
* @param[in] dydxIn Derivatives array in input.
|
||||
* @param[out] yOut Integration output.
|
||||
* @param[in] hstep The given step size.
|
||||
*/
|
||||
void DoStep( const G4double yIn[], const G4double dydxIn[],
|
||||
G4double yOut[], G4double hstep) const;
|
||||
|
||||
/**
|
||||
* Computes one step, as above but using also intermediate values.
|
||||
* @param[in] yIn Starting values array of integration variables.
|
||||
* @param[in] dydxIn Derivatives array in input.
|
||||
* @param[out] yOut Integration output.
|
||||
* @param[in] hstep The given step size.
|
||||
* @param[in] yMid Mid point integration variables.
|
||||
* @param[in] derivs Intermediate derivatives.
|
||||
*/
|
||||
void DoStep( const G4double yIn[], const G4double dydxIn[],
|
||||
G4double yOut[], G4double hstep, G4double yMid[],
|
||||
G4double derivs[][G4FieldTrack::ncompSVEC]) const;
|
||||
|
||||
/**
|
||||
* Setter and getter for steps.
|
||||
*/
|
||||
inline void SetSteps(G4int steps);
|
||||
inline G4int GetSteps() const;
|
||||
|
||||
/**
|
||||
* Setter and getter for the equation of motion.
|
||||
*/
|
||||
inline void SetEquationOfMotion(G4EquationOfMotion* equation);
|
||||
inline G4EquationOfMotion* GetEquationOfMotion();
|
||||
inline G4EquationOfMotion* GetEquationOfMotion() const;
|
||||
|
||||
/**
|
||||
* Returns the number of integration variables.
|
||||
*/
|
||||
inline G4int GetNumberOfVariables() const;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Utility for copying array content from 'src' to 'dst'.
|
||||
*/
|
||||
void copy(G4double dst[], const G4double src[]) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -25,31 +25,31 @@
|
||||
//
|
||||
// G4ModifiedMidpoint inline methods implementation
|
||||
//
|
||||
// Author: Dmitry Sorokin, Google Summer of Code 2016
|
||||
// Supervision: John Apostolakis, CERN
|
||||
// Author: Dmitry Sorokin (CERN, Google Summer of Code 2016), 07.10.2016
|
||||
// Supervision: John Apostolakis (CERN)
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
inline void G4ModifiedMidpoint::SetSteps(G4int steps)
|
||||
{
|
||||
fsteps = steps;
|
||||
fsteps = steps;
|
||||
}
|
||||
|
||||
inline G4int G4ModifiedMidpoint::GetSteps() const
|
||||
{
|
||||
return fsteps;
|
||||
return fsteps;
|
||||
}
|
||||
|
||||
inline void G4ModifiedMidpoint::SetEquationOfMotion(G4EquationOfMotion* eq)
|
||||
{
|
||||
fEquation = eq;
|
||||
fEquation = eq;
|
||||
}
|
||||
|
||||
inline G4EquationOfMotion* G4ModifiedMidpoint::GetEquationOfMotion()
|
||||
inline G4EquationOfMotion* G4ModifiedMidpoint::GetEquationOfMotion() const
|
||||
{
|
||||
return fEquation;
|
||||
return fEquation;
|
||||
}
|
||||
|
||||
inline G4int G4ModifiedMidpoint::GetNumberOfVariables() const
|
||||
{
|
||||
return fnvar;
|
||||
return fnvar;
|
||||
}
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
//
|
||||
// This is the right-hand side of equation of motion for monopole
|
||||
// in a combined electric and magnetic field:
|
||||
// d(p_c)/ds=g{c-energyB_ - p_c x E}/pc
|
||||
// d(p_c)/ds=g{c-energyB_ - p_c x E}/pc.
|
||||
|
||||
// Created: V.Grichine, 17.11.2009
|
||||
// Author: Vladimir Grichine (CERN), 17.11.2009
|
||||
// -------------------------------------------------------------------
|
||||
#ifndef G4EQMAGELECTRICFIELD_HH
|
||||
#define G4EQMAGELECTRICFIELD_HH
|
||||
@@ -40,22 +40,52 @@
|
||||
#include "G4EquationOfMotion.hh"
|
||||
#include "G4ElectroMagneticField.hh"
|
||||
|
||||
/**
|
||||
* @brief G4MonopoleEq defines the right-hand side of equation of motion
|
||||
* for monopole in a combined electric and magnetic field:
|
||||
* d(p_c)/ds=g{c-energyB_ - p_c x E}/pc.
|
||||
*/
|
||||
|
||||
class G4MonopoleEq : public G4EquationOfMotion
|
||||
{
|
||||
public:
|
||||
|
||||
G4MonopoleEq(G4ElectroMagneticField* emField );
|
||||
~G4MonopoleEq() override;
|
||||
/**
|
||||
* Constructor for G4MonopoleEq.
|
||||
* @param[in] emField Pointer to the field.
|
||||
*/
|
||||
G4MonopoleEq(G4ElectroMagneticField* emField);
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4MonopoleEq() override = default;
|
||||
|
||||
/**
|
||||
* Sets the charge, momentum and mass of the current particle.
|
||||
* Used to set the equation's coefficients.
|
||||
* @param[in] particleCharge Magnetic charge and moments in e+ units.
|
||||
* @param[in] MomentumXc Particle momentum.
|
||||
* @param[in] mass Particle mass.
|
||||
*/
|
||||
void SetChargeMomentumMass(G4ChargeState particleCharge,
|
||||
G4double MomentumXc,
|
||||
G4double mass) override;
|
||||
|
||||
/**
|
||||
* Calculates the value of the derivative, given the value of the field.
|
||||
* @param[in] y Coefficients array.
|
||||
* @param[in] Field Field value.
|
||||
* @param[out] dydx Derivatives array.
|
||||
*/
|
||||
void EvaluateRhsGivenB(const G4double y[],
|
||||
const G4double Field[],
|
||||
G4double dydx[] ) const override;
|
||||
// Given the value of the electromagnetic field, this function
|
||||
// calculates the value of the derivative dydx.
|
||||
|
||||
/**
|
||||
* Returns the equation type-ID, "kEqMonopole".
|
||||
*/
|
||||
inline G4EquationType GetEquationType() const override { return kEqMonopole; }
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -34,10 +34,9 @@
|
||||
// Notes: 1) field must be time-independent.
|
||||
// 2) time is not integrated
|
||||
|
||||
// Created: I.Gavrilenko, 15.05.2009 (as G4AtlasRK4)
|
||||
// Adaptations: J.Apostolakis, November 2009
|
||||
// Author: Igor Gavrilenko (CERN), 15.05.2009 (as G4AtlasRK4)
|
||||
// Adaptations: John Apostolakis (CERN), 05.11.2009
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
#ifndef G4NYSTROMRK4_HH
|
||||
#define G4NYSTROMRK4_HH
|
||||
|
||||
@@ -48,37 +47,81 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
/**
|
||||
* @brief G4NystromRK4 integrates the equations of the motion of a particle
|
||||
* in a magnetic field using 4th Runge-Kutta-Nystrom method with errors
|
||||
* estimation. The current form can be used only for 'pure' magnetic field.
|
||||
*/
|
||||
|
||||
class G4NystromRK4 : public G4MagIntegratorStepper
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4NystromRK4. Can be used only for Magnetic Fields
|
||||
* and for 6 variables (x,p).
|
||||
* @param[in] EquationMotion Pointer to the provided equation of motion.
|
||||
* @param[in] distanceConstField Distance value for constant field.
|
||||
*/
|
||||
G4NystromRK4(G4Mag_EqRhs* EquationMotion,
|
||||
G4double distanceConstField = 0.0);
|
||||
// Can be used only for Magnetic Fields - and for 6 variables (x,p)
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4NystromRK4() override = default;
|
||||
|
||||
/**
|
||||
* The stepper for the Runge Kutta integration.
|
||||
* The stepsize is fixed, with the step size given by 'hstep'.
|
||||
* Integrates ODE starting values y[0 to 6].
|
||||
* Outputs yOut[] and its estimated error yError[].
|
||||
* Provides error via analytical method.
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array.
|
||||
* @param[in] hstep The given step size.
|
||||
* @param[out] yOut Integration output.
|
||||
* @param[out] yError The estimated error.
|
||||
*/
|
||||
void Stepper(const G4double y[],
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double yOut[],
|
||||
G4double yError[]) override;
|
||||
// Single call for integration result and error
|
||||
// Provides error via analytical method
|
||||
|
||||
/**
|
||||
* Setter and getter for the distance value for constant field.
|
||||
*/
|
||||
void SetDistanceForConstantField(G4double length);
|
||||
G4double GetDistanceForConstantField() const;
|
||||
|
||||
G4int IntegratorOrder() const override { return 4; }
|
||||
/**
|
||||
* Returns the order, 4, of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override;
|
||||
|
||||
/**
|
||||
* Returns the distance from chord line.
|
||||
*/
|
||||
G4double DistChord() const override;
|
||||
|
||||
/**
|
||||
* Returns the stepper type-ID, "kNystromRK4".
|
||||
*/
|
||||
inline G4StepperType StepperType() const override;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Private accessors for field data.
|
||||
*/
|
||||
inline void GetFieldValue(const G4double point[4], G4double field[3]);
|
||||
inline G4double GetFCof();
|
||||
|
||||
G4CachedMagneticField* GetField();
|
||||
const G4CachedMagneticField* GetField() const;
|
||||
|
||||
private:
|
||||
|
||||
G4double fMomentum = 0.0;
|
||||
G4double fMomentum2 = 0.0;
|
||||
G4double fInverseMomentum = 0.0;
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
//
|
||||
// G4NystromRK4 inline methods implementation
|
||||
//
|
||||
// Created: I.Gavrilenko, 15.05.2009 (as G4AtlasRK4)
|
||||
// Adaptations: J.Apostolakis, November 2009
|
||||
// Author: Igor Gavrilenko (CERN), 15.05.2009 (as G4AtlasRK4)
|
||||
// Adaptations: John Apostolakis (CERN), 05.11.2009
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
void G4NystromRK4::GetFieldValue(const G4double point[4], G4double field[3])
|
||||
@@ -38,3 +38,13 @@ G4double G4NystromRK4::GetFCof()
|
||||
{
|
||||
return static_cast<G4Mag_EqRhs*>(GetEquationOfMotion())->FCof();
|
||||
}
|
||||
|
||||
G4int G4NystromRK4::IntegratorOrder() const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
G4StepperType G4NystromRK4::StepperType() const
|
||||
{
|
||||
return kNystromRK4;
|
||||
}
|
||||
|
||||
@@ -30,9 +30,8 @@
|
||||
// Provides a driver that talks to the Integrator Stepper, and insures that
|
||||
// the error is within acceptable bounds.
|
||||
|
||||
// V.Grichine, 07.10.1996 - Created
|
||||
// W.Wander, 28.01.1998 - Added ability for low order integrators
|
||||
// J.Apostolakis, 08.11.2001 - Respect minimum step in AccurateAdvance
|
||||
// Author: Vladimir Grichine (CERN), 07.10.1996 - Created
|
||||
// W.Wander (MIT), 28.01.1998 - Added ability for low order integrators
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4OLD_MAGINT_DRIVER_HH
|
||||
#define G4OLD_MAGINT_DRIVER_HH
|
||||
@@ -41,57 +40,118 @@
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
#include "G4ChordFinderDelegate.hh"
|
||||
|
||||
/**
|
||||
* @brief G4OldMagIntDriver provides a driver that talks to the Integrator
|
||||
* Stepper and insures that the error is within acceptable bounds.
|
||||
*/
|
||||
|
||||
class G4OldMagIntDriver : public G4VIntegrationDriver,
|
||||
public G4ChordFinderDelegate<G4OldMagIntDriver>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4OldMagIntDriver.
|
||||
* @param[in] hminimum The minumum allowed step.
|
||||
* @param[in] pItsStepper Pointer to the integrator stepper.
|
||||
* @param[in] numberOfComponents The number of integration variables.
|
||||
* @param[in] statisticsVerbosity Flag for verbosity.
|
||||
*/
|
||||
G4OldMagIntDriver(G4double hminimum,
|
||||
G4MagIntegratorStepper* pItsStepper,
|
||||
G4int numberOfComponents = 6,
|
||||
G4int statisticsVerbosity = 0);
|
||||
~G4OldMagIntDriver() override;
|
||||
// Constructor, destructor.
|
||||
|
||||
/**
|
||||
* Destructor. Provides statistics if verbosity level is greater than 1.
|
||||
*/
|
||||
~G4OldMagIntDriver() override;
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4OldMagIntDriver(const G4OldMagIntDriver&) = delete;
|
||||
G4OldMagIntDriver& operator=(const G4OldMagIntDriver&) = delete;
|
||||
|
||||
/**
|
||||
* Computes the step to take, based on chord limits.
|
||||
* @param[in,out] track The current track in field.
|
||||
* @param[in] stepMax Proposed maximum step length.
|
||||
* @param[in] epsStep Requested accuracy, y_err/hstep.
|
||||
* @param[in] chordDistance Maximum sagitta distance.
|
||||
* @returns The length of step taken.
|
||||
*/
|
||||
inline G4double AdvanceChordLimited(G4FieldTrack& track,
|
||||
G4double stepMax,
|
||||
G4double epsStep,
|
||||
G4double chordDistance) override;
|
||||
|
||||
/**
|
||||
* Dispatch interface method for initialisation/reset of driver.
|
||||
*/
|
||||
inline void OnStartTracking() override;
|
||||
inline void OnComputeStep(const G4FieldTrack* = nullptr) override {}
|
||||
inline G4bool DoesReIntegrate() const override { return true; }
|
||||
|
||||
/**
|
||||
* Dispatch interface method for computing step. Does nothing here.
|
||||
*/
|
||||
inline void OnComputeStep(const G4FieldTrack* = nullptr) override;
|
||||
|
||||
/**
|
||||
* The driver implements re-integration, so returns true.
|
||||
*/
|
||||
inline G4bool DoesReIntegrate() const override;
|
||||
|
||||
/**
|
||||
* Advances integration accurately by relative accuracy better than 'eps'.
|
||||
* @param[in,out] y_current The current track in field.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[in] eps Requested accuracy, y_err/hstep.
|
||||
* @param[in] hinitial Initial minimum integration step.
|
||||
* @returns true if integration succeeds.
|
||||
*/
|
||||
G4bool AccurateAdvance(G4FieldTrack& y_current,
|
||||
G4double hstep,
|
||||
G4double eps, // Requested y_err/hstep
|
||||
G4double hinitial = 0.0) override;
|
||||
// Above drivers for integrator (Runge-Kutta) with stepsize control.
|
||||
// Integrates ODE starting values y_current
|
||||
// from current s (s=s0) to s=s0+h with accuracy eps.
|
||||
// On output ystart is replaced by value at end of interval.
|
||||
// The concept is similar to the odeint routine from NRC p.721-722.
|
||||
|
||||
G4bool QuickAdvance(G4FieldTrack& y_val, // INOUT
|
||||
/**
|
||||
* Attempts one integration step, and returns estimated error 'dyerr'.
|
||||
* It does not ensure accuracy.
|
||||
* @param[in,out] y_val The current track in field.
|
||||
* @param[in] dydx dydx array.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[out] dchord_step Estimated sagitta distance.
|
||||
* @param[out] dyerr Estimated error.
|
||||
* @returns true if integration succeeds.
|
||||
*/
|
||||
G4bool QuickAdvance(G4FieldTrack& y_val, // In/Out
|
||||
const G4double dydx[],
|
||||
G4double hstep,
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr) override;
|
||||
// QuickAdvance just tries one Step - it does not ensure accuracy.
|
||||
|
||||
G4bool QuickAdvance( G4FieldTrack& y_posvel, // INOUT
|
||||
/**
|
||||
* Attempts one integration step, and returns estimated error 'dyerr'.
|
||||
* It does not ensure accuracy.
|
||||
* @param[in,out] y_posvel The current track in field.
|
||||
* @param[in] dydx dydx array.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[out] dchord_step Estimated sagitta distance.
|
||||
* @param[out] dyerr_pos_sq Estimated error in position.
|
||||
* @param[out] dyerr_mom_rel_sq Estimated error in momentum
|
||||
* (normalised: Delta_Integration(p^2)/(p^2)).
|
||||
* @returns true if integration succeeds.
|
||||
*/
|
||||
G4bool QuickAdvance(G4FieldTrack& y_posvel, // In/Out
|
||||
const G4double dydx[],
|
||||
G4double hstep, // IN
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr_pos_sq,
|
||||
G4double& dyerr_mom_rel_sq);
|
||||
// QuickAdvance that also just tries one Step (so also does not
|
||||
// ensure accuracy), but does return the errors in position and
|
||||
// momentum (normalised: Delta_Integration(p^2)/(p^2) ).
|
||||
G4double hstep, // In
|
||||
G4double& dchord_step,
|
||||
G4double& dyerr_pos_sq,
|
||||
G4double& dyerr_mom_rel_sq);
|
||||
|
||||
/**
|
||||
* Accessors.
|
||||
*/
|
||||
inline G4double GetHmin() const;
|
||||
inline G4double Hmin() const; // Obsolete
|
||||
inline G4double GetSafety() const;
|
||||
@@ -100,46 +160,63 @@ class G4OldMagIntDriver : public G4VIntegrationDriver,
|
||||
inline G4double GetErrcon() const;
|
||||
void GetDerivatives(const G4FieldTrack& y_curr, // INput
|
||||
G4double dydx[]) const override; // OUTput
|
||||
|
||||
void GetDerivatives(const G4FieldTrack& track,
|
||||
G4double dydx[],
|
||||
G4double field[]) const override;
|
||||
// Accessors
|
||||
|
||||
/**
|
||||
* Getter and setter for the equation of motion.
|
||||
*/
|
||||
G4EquationOfMotion* GetEquationOfMotion() override;
|
||||
void SetEquationOfMotion(G4EquationOfMotion* equation) override;
|
||||
|
||||
/**
|
||||
* Sets a new stepper 'pItsStepper' for this driver. Then it calls
|
||||
* ResetParameters() to update its parameters accordingly.
|
||||
*/
|
||||
void RenewStepperAndAdjust(G4MagIntegratorStepper* pItsStepper) override;
|
||||
// Sets a new stepper pItsStepper for this driver. Then it calls
|
||||
// ReSetParameters to reset its parameters accordingly.
|
||||
|
||||
/**
|
||||
* Resets the qarameters according to the new provided safety value.
|
||||
* i) sets the exponents (pgrow & pshrnk), using the current order;
|
||||
* ii) sets the safety and calculates "errcon" according to the above values.
|
||||
*/
|
||||
inline void ReSetParameters(G4double new_safety = 0.9);
|
||||
// i) sets the exponents (pgrow & pshrnk),
|
||||
// using the current Stepper's order,
|
||||
// ii) sets the safety
|
||||
// ii) calculates "errcon" according to the above values.
|
||||
|
||||
/**
|
||||
* Modifiers. When setting safety or pgrow, errcon will be set
|
||||
* to a compatible value.
|
||||
*/
|
||||
inline void SetSafety(G4double valS);
|
||||
inline void SetPshrnk(G4double valPs);
|
||||
inline void SetPgrow (G4double valPg);
|
||||
inline void SetErrcon(G4double valEc);
|
||||
// When setting safety or pgrow, errcon will be set to a compatible value.
|
||||
|
||||
inline G4double ComputeAndSetErrcon();
|
||||
|
||||
/**
|
||||
* Accessors for the integrator stepper.
|
||||
*/
|
||||
const G4MagIntegratorStepper* GetStepper() const override;
|
||||
G4MagIntegratorStepper* GetStepper() override;
|
||||
G4MagIntegratorStepper* GetStepper() override;
|
||||
|
||||
void OneGoodStep( G4double ystart[], // Like old RKF45step()
|
||||
const G4double dydx[],
|
||||
G4double& x,
|
||||
G4double htry,
|
||||
G4double eps, // memb variables ?
|
||||
G4double& hdid,
|
||||
G4double& hnext) ;
|
||||
// This takes one Step that is as large as possible while
|
||||
// satisfying the accuracy criterion of:
|
||||
// yerr < eps * |y_end-y_start|
|
||||
/**
|
||||
* Takes one Step that is as large as possible while satisfying the
|
||||
* accuracy criterion of: yerr < eps * |y_end-y_start|.
|
||||
* @param[in,out] ystart The current track state, y.
|
||||
* @param[in] dydx The derivatives array.
|
||||
* @param[in,out] x Step start, x.
|
||||
* @param[in] htry Step to attempt.
|
||||
* @param[in] eps The relative accuracy.
|
||||
* @param[out] hdid Step achieved.
|
||||
* @param[out] hnext Proposed next step.
|
||||
* @returns true if integration succeeds.
|
||||
*/
|
||||
void OneGoodStep(G4double ystart[], // Like old RKF45step()
|
||||
const G4double dydx[],
|
||||
G4double& x,
|
||||
G4double htry,
|
||||
G4double eps,
|
||||
G4double& hdid,
|
||||
G4double& hnext) ;
|
||||
|
||||
G4double ComputeNewStepSize(G4double errMaxNorm, // normalised
|
||||
G4double hstepCurrent) override;
|
||||
@@ -148,40 +225,53 @@ class G4OldMagIntDriver : public G4VIntegrationDriver,
|
||||
// Do not limit the next step's size within a factor of the
|
||||
// current one.
|
||||
|
||||
/**
|
||||
* Writes out to stream the parameters/state of the driver.
|
||||
*/
|
||||
void StreamInfo( std::ostream& os ) const override;
|
||||
|
||||
/**
|
||||
* Takes the last step's normalised error and calculates a step size
|
||||
* for the next step. Limits the next step's size within a range around
|
||||
* the current one.
|
||||
*/
|
||||
G4double ComputeNewStepSize_WithinLimits(G4double errMaxNorm, // normalised
|
||||
G4double hstepCurrent);
|
||||
// Taking the last step's normalised error, calculate
|
||||
// a step size for the next step.
|
||||
// Limit the next step's size within a range around the current one.
|
||||
|
||||
/**
|
||||
* Modifier and accessor for the maximum number of steps that can be taken
|
||||
* for the integration of a single segment, i.e. a single call to
|
||||
* AccurateAdvance().
|
||||
*/
|
||||
inline G4int GetMaxNoSteps() const;
|
||||
inline void SetMaxNoSteps(G4int val);
|
||||
// Modify and Get the Maximum number of Steps that can be
|
||||
// taken for the integration of a single segment -
|
||||
// (i.e. a single call to AccurateAdvance).
|
||||
|
||||
/**
|
||||
* More modifiers and accessors.
|
||||
*/
|
||||
inline void SetHmin(G4double newval);
|
||||
void SetVerboseLevel(G4int newLevel) override;
|
||||
G4int GetVerboseLevel() const override;
|
||||
|
||||
inline G4double GetSmallestFraction() const;
|
||||
void SetSmallestFraction( G4double val );
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Loggers, issuing warnings for undesirable situations.
|
||||
*/
|
||||
void WarnSmallStepSize(G4double hnext, G4double hstep,
|
||||
G4double h, G4double xDone,
|
||||
G4int noSteps);
|
||||
|
||||
void WarnTooManyStep(G4double x1start, G4double x2end, G4double xCurrent);
|
||||
void WarnEndPointTooFar(G4double endPointDist,
|
||||
G4double hStepSize ,
|
||||
G4double epsilonRelative,
|
||||
G4int debugFlag);
|
||||
// Issue warnings for undesirable situations
|
||||
|
||||
/**
|
||||
* Loggers for verbosity printouts.
|
||||
*/
|
||||
void PrintStatus(const G4double* StartArr,
|
||||
G4double xstart,
|
||||
const G4double* CurrentArr,
|
||||
@@ -198,10 +288,11 @@ class G4OldMagIntDriver : public G4VIntegrationDriver,
|
||||
G4int subStepNo,
|
||||
G4double subStepSize,
|
||||
G4double dotVelocities);
|
||||
// Verbose output for debugging
|
||||
|
||||
/**
|
||||
* Reports on the number of steps, maximum errors etc.
|
||||
*/
|
||||
void PrintStatisticsReport();
|
||||
// Report on the number of steps, maximum errors etc.
|
||||
|
||||
#ifdef QUICK_ADV_TWO
|
||||
G4bool QuickAdvance( G4double yarrin[], // In
|
||||
@@ -217,25 +308,31 @@ class G4OldMagIntDriver : public G4VIntegrationDriver,
|
||||
// ---------------------------------------------------------------
|
||||
// INVARIANTS
|
||||
|
||||
/** Minimum Step allowed in a Step (in absolute units). */
|
||||
G4double fMinimumStep = 0.0;
|
||||
// Minimum Step allowed in a Step (in absolute units)
|
||||
|
||||
/** Smallest fraction of (existing) curve length, in relative units.
|
||||
Below this fraction the current step will be the last. */
|
||||
G4double fSmallestFraction = 1.0e-12; // Expected range 1e-12 to 5e-15
|
||||
// Smallest fraction of (existing) curve length - in relative units
|
||||
// below this fraction the current step will be the last
|
||||
|
||||
const G4int fNoIntegrationVariables = 0; // Variables in integration
|
||||
const G4int fMinNoVars = 12; // Minimum number for FieldTrack
|
||||
const G4int fNoVars = 0; // Full number of variable
|
||||
/** Variables in integration. */
|
||||
const G4int fNoIntegrationVariables = 0;
|
||||
|
||||
/** Minimum number for FieldTrack. */
|
||||
const G4int fMinNoVars = 12;
|
||||
|
||||
/** Full number of variable. */
|
||||
const G4int fNoVars = 0;
|
||||
|
||||
/** Default maximum number of steps is Base divided by the order of Stepper. */
|
||||
G4int fMaxNoSteps;
|
||||
G4int fMaxStepBase = 250; // was 5000
|
||||
// Default maximum number of steps is Base divided by the order of Stepper
|
||||
|
||||
/** Parameters used to grow and shrink trial stepsize. */
|
||||
G4double safety;
|
||||
G4double pshrnk; // exponent for shrinking
|
||||
G4double pgrow; // exponent for growth
|
||||
G4double errcon;
|
||||
// Parameters used to grow and shrink trial stepsize.
|
||||
|
||||
G4int fStatisticsVerboseLevel = 0;
|
||||
|
||||
@@ -247,15 +344,15 @@ class G4OldMagIntDriver : public G4VIntegrationDriver,
|
||||
// ---------------------------------------------------------------
|
||||
// STATE
|
||||
|
||||
/** Step Statistics. */
|
||||
unsigned long fNoTotalSteps=0, fNoBadSteps=0;
|
||||
unsigned long fNoSmallSteps=0, fNoInitialSmallSteps=0, fNoCalls=0;
|
||||
G4double fDyerr_max=0.0, fDyerr_mx2=0.0;
|
||||
G4double fDyerrPos_smTot=0.0, fDyerrPos_lgTot=0.0, fDyerrVel_lgTot=0.0;
|
||||
G4double fSumH_sm=0.0, fSumH_lg=0.0;
|
||||
// Step Statistics
|
||||
|
||||
/** Could be varied during tracking - to help identify issues. */
|
||||
G4int fVerboseLevel = 0; // Verbosity level for printing (debug, ..)
|
||||
// Could be varied during tracking - to help identify issues
|
||||
|
||||
using ChordFinderDelegate = G4ChordFinderDelegate<G4OldMagIntDriver>;
|
||||
};
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
//
|
||||
// G4OldMagIntDriver inline methods implementation
|
||||
//
|
||||
// V.Grichine, 07.10.1996 - Created
|
||||
// Author: Vladimir Grichine (CERN), 07.10.1996 - Created
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
inline
|
||||
@@ -43,6 +43,17 @@ void G4OldMagIntDriver::OnStartTracking()
|
||||
ChordFinderDelegate::ResetStepEstimate();
|
||||
}
|
||||
|
||||
inline
|
||||
void G4OldMagIntDriver::OnComputeStep(const G4FieldTrack*)
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
G4bool G4OldMagIntDriver::DoesReIntegrate() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline
|
||||
G4double G4OldMagIntDriver::GetHmin() const
|
||||
{
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
//
|
||||
// G4QSS2 simulator
|
||||
|
||||
// Authors: Lucio Santi, Rodrigo Castro (Univ. Buenos Aires) - 2018-2021
|
||||
// Authors: Lucio Santi, Rodrigo Castro (Univ. Buenos Aires), 2018-2021
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef _G4QSS2_H_
|
||||
#define _G4QSS2_H_ 1
|
||||
#ifndef G4QSS2_HH
|
||||
#define G4QSS2_HH
|
||||
|
||||
#include "G4Types.hh"
|
||||
#include "G4qss_misc.hh"
|
||||
@@ -45,11 +45,15 @@
|
||||
#include "G4Log.hh"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief G4QSS2 defines the QSS2 simulator engine used in QSS field stepper.
|
||||
*/
|
||||
|
||||
class G4QSS2
|
||||
{
|
||||
public:
|
||||
|
||||
G4QSS2(QSS_simulator sim) : simulator(sim) {}
|
||||
inline G4QSS2(QSS_simulator sim) : simulator(sim) {}
|
||||
|
||||
inline QSS_simulator getSimulator() const { return this->simulator; }
|
||||
|
||||
|
||||
@@ -27,16 +27,20 @@
|
||||
//
|
||||
// G4QSS3 simulator
|
||||
|
||||
// Authors: Lucio Santi, Rodrigo Castro (Univ. Buenos Aires) - 2018-2021
|
||||
// Authors: Lucio Santi, Rodrigo Castro (Univ. Buenos Aires), 2018-2021
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef _G4QSS3_H_
|
||||
#define _G4QSS3_H_ 1
|
||||
#ifndef G4QSS3_HH
|
||||
#define G4QSS3_HH
|
||||
|
||||
#include "G4Types.hh"
|
||||
#include "G4qss_misc.hh"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
/**
|
||||
* @brief G4QSS3 defines the QSS3 simulator engine used in QSS field stepper.
|
||||
*/
|
||||
|
||||
class G4QSS3
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -27,47 +27,83 @@
|
||||
//
|
||||
// QSS Interpolator Driver
|
||||
|
||||
// Authors: Lucio Santi, Rodrigo Castro (Univ. Buenos Aires) - 2018-2021
|
||||
// Authors: Lucio Santi, Rodrigo Castro (Univ. Buenos Aires), 2018-2021
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4QSSDriver_HH
|
||||
#define G4QSSDriver_HH 1
|
||||
#define G4QSSDriver_HH
|
||||
|
||||
#include "G4InterpolationDriver.hh"
|
||||
#include "G4QSSMessenger.hh"
|
||||
|
||||
/**
|
||||
* @brief G4QSSDriver is a templated driver class defining the QSS
|
||||
* (Quantum State Simulation) Interpolator Driver.
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
class G4QSSDriver : public G4InterpolationDriver<T, true>
|
||||
{
|
||||
public:
|
||||
|
||||
G4QSSDriver(T* stepper);
|
||||
|
||||
// Hacky way of getting and setting precision parameters
|
||||
// from messenger on first run
|
||||
void OnStartTracking() override;
|
||||
/**
|
||||
* Constructor for G4QSSDriver.
|
||||
* @param[in] T Pointer to the stepper algorithm.
|
||||
*/
|
||||
inline G4QSSDriver(T* stepper);
|
||||
|
||||
/**
|
||||
* Copy constructor and assignment operator not allowed.
|
||||
*/
|
||||
G4QSSDriver(const G4QSSDriver&) = delete;
|
||||
const G4QSSDriver& operator=(const G4QSSDriver&) = delete;
|
||||
|
||||
G4double AdvanceChordLimited(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps,
|
||||
G4double chordDistance) override;
|
||||
/**
|
||||
* Dispatch interface method for initialisation/reset of driver.
|
||||
*/
|
||||
void OnStartTracking() override;
|
||||
|
||||
void OnComputeStep(const G4FieldTrack* track) override
|
||||
{
|
||||
Base::OnComputeStep(track);
|
||||
}
|
||||
/**
|
||||
* Computes the step to take, based on chord limits.
|
||||
* @param[in,out] track The current track in field.
|
||||
* @param[in] hstep Proposed step length.
|
||||
* @param[in] eps Requested accuracy, y_err/hstep.
|
||||
* @param[in] chordDistance Maximum sagitta distance.
|
||||
* @returns The length of step taken.
|
||||
*/
|
||||
inline G4double AdvanceChordLimited(G4FieldTrack& track,
|
||||
G4double hstep,
|
||||
G4double eps,
|
||||
G4double chordDistance) override;
|
||||
|
||||
void SetPrecision(G4double dq_rel, G4double dq_min);
|
||||
/**
|
||||
* Dispatch interface method for computing step.
|
||||
*/
|
||||
inline void OnComputeStep(const G4FieldTrack* track) override;
|
||||
|
||||
G4double OneGoodStep(typename G4InterpolationDriver<T, true>::StepperIterator it,
|
||||
field_utils::State& y,
|
||||
field_utils::State& dydx,
|
||||
G4double& hstep,
|
||||
G4double epsStep,
|
||||
G4double curveLength,
|
||||
G4FieldTrack* track) override;
|
||||
/**
|
||||
* Setter for driver precision parameters.
|
||||
*/
|
||||
inline void SetPrecision(G4double dq_rel, G4double dq_min);
|
||||
|
||||
/**
|
||||
* Takes one Step that is as large as possible while satisfying the
|
||||
* accuracy criterion.
|
||||
* @param[in] it Stepper iterator.
|
||||
* @param[in,out] y The current track state, y.
|
||||
* @param[in] dydx dydx array.
|
||||
* @param[in,out] hstep Step to attempt.
|
||||
* @param[in] epsStep The relative accuracy.
|
||||
* @param[in] curveLength Step start, x.
|
||||
* @param[in,out] track Pointer to the Field track. Not used.
|
||||
* @returns The step achieved.
|
||||
*/
|
||||
inline G4double OneGoodStep(typename G4InterpolationDriver<T, true>::StepperIterator it,
|
||||
field_utils::State& y,
|
||||
field_utils::State& dydx,
|
||||
G4double& hstep,
|
||||
G4double epsStep,
|
||||
G4double curveLength,
|
||||
G4FieldTrack* track) override;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Authors: Lucio Santi, Rodrigo Castro (Univ. Buenos Aires) - 2018-2021
|
||||
// Authors: Lucio Santi, Rodrigo Castro (Univ. Buenos Aires), 2018-2021
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
template <class T>
|
||||
@@ -37,23 +37,24 @@ template <class T>
|
||||
void G4QSSDriver<T>::OnStartTracking()
|
||||
{
|
||||
Base::OnStartTracking();
|
||||
if (! initializedOnFirstRun) {
|
||||
// this->SetPrecision( G4QSSMessenger::instance()->dQRel, G4QSSMessenger::instance()->dQMin);
|
||||
|
||||
G4double dqRel = G4QSSMessenger::instance()->dQRel;
|
||||
G4double dQMin = G4QSSMessenger::instance()->dQMin;
|
||||
if (dqRel == 0) {
|
||||
dqRel = 0.001;
|
||||
}
|
||||
if (dQMin == 0) {
|
||||
dQMin = 0.0001;
|
||||
}
|
||||
if (! initializedOnFirstRun)
|
||||
{
|
||||
G4double dqRel = G4QSSMessenger::instance()->Get_dQRel();
|
||||
G4double dQMin = G4QSSMessenger::instance()->Get_dQMin();
|
||||
if (dqRel == 0) { dqRel = 0.001; }
|
||||
if (dQMin == 0) { dQMin = 0.0001; }
|
||||
this->SetPrecision(dqRel, dQMin);
|
||||
|
||||
initializedOnFirstRun = true;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4QSSDriver<T>::OnComputeStep(const G4FieldTrack* track)
|
||||
{
|
||||
Base::OnComputeStep(track);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void G4QSSDriver<T>::SetPrecision(G4double dq_rel, G4double dq_min)
|
||||
{
|
||||
@@ -61,7 +62,8 @@ void G4QSSDriver<T>::SetPrecision(G4double dq_rel, G4double dq_min)
|
||||
<< "dQRel = " << dq_rel << " - "
|
||||
<< "dQMin = " << dq_min << G4endl;
|
||||
|
||||
for (const auto& item : this->fSteppers) {
|
||||
for (const auto& item : this->fSteppers)
|
||||
{
|
||||
item.stepper->SetPrecision(dq_rel, dq_min);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
//
|
||||
// Messenger for QSS Integrator driver
|
||||
|
||||
// Author: Leandro Gomez Vidal (Univ. Buenos Aires) - October 2021
|
||||
// Author: Leandro Gomez Vidal (Univ. Buenos Aires), October 2021
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef GEANT4_G4QSSMessenger_H
|
||||
#define GEANT4_G4QSSMessenger_H 1
|
||||
#ifndef G4QSSMessenger_HH
|
||||
#define G4QSSMessenger_HH
|
||||
|
||||
#include "G4UIcmdWithABool.hh"
|
||||
#include "G4UIcmdWithADouble.hh"
|
||||
@@ -41,48 +41,75 @@
|
||||
#include "G4UIdirectory.hh"
|
||||
#include "G4UImessenger.hh"
|
||||
|
||||
#include "G4QSSParameters.hh"
|
||||
|
||||
class G4QSSMessenger : public G4UImessenger
|
||||
{
|
||||
public:
|
||||
|
||||
G4QSSMessenger();
|
||||
~G4QSSMessenger() override;
|
||||
|
||||
void SetNewValue(G4UIcommand* command, G4String newValues) override;
|
||||
|
||||
/* Hacky - much easier to access G4QSSMessenger from G4QSSDriver than the other way around
|
||||
* Multithreading seems to cause weird stuff with Driver/Stepper instances, maybe making
|
||||
* some thread-local copies or something, outside of construction? */
|
||||
|
||||
static G4QSSMessenger* instance();
|
||||
|
||||
enum StepperSelection
|
||||
{
|
||||
None = 0,
|
||||
TemplatedDoPri,
|
||||
OldRK45,
|
||||
G4QSS2
|
||||
};
|
||||
void selectStepper(const std::string&);
|
||||
StepperSelection selectedStepper();
|
||||
|
||||
public:
|
||||
|
||||
G4double dQMin = 0.00001;
|
||||
G4double dQRel = 0.001;
|
||||
G4double trialProposedStepModifier = 1.0;
|
||||
G4int maxSubsteps = 5000;
|
||||
G4int QssOrder = 2;
|
||||
/**
|
||||
* Constructor and Destructor.
|
||||
*/
|
||||
G4QSSMessenger();
|
||||
~G4QSSMessenger() override;
|
||||
|
||||
/**
|
||||
* Applies command to the associated object.
|
||||
*/
|
||||
void SetNewValue(G4UIcommand* command, G4String newValues) override;
|
||||
|
||||
/* Hacky - much easier to access G4QSSMessenger from G4QSSDriver than the other way around
|
||||
* Multithreading seems to cause weird stuff with Driver/Stepper instances, maybe making
|
||||
* some thread-local copies or something, outside of construction? */
|
||||
|
||||
static G4QSSMessenger* instance();
|
||||
|
||||
/**
|
||||
* Accessors.
|
||||
*/
|
||||
inline G4int GetQssOrder() { return G4QSSParameters::Instance()->GetQssOrder(); }
|
||||
inline G4double Get_dQRel() { return G4QSSParameters::Instance()->Get_dQRel(); }
|
||||
inline G4double Get_dQMin() { return G4QSSParameters::Instance()->Get_dQMin(); }
|
||||
inline G4int GetMaxSubsteps() { return G4QSSParameters::Instance()->GetMaxSubsteps(); }
|
||||
|
||||
enum StepperSelection
|
||||
{
|
||||
None = 1,
|
||||
G4QSS2 = 2,
|
||||
G4QSS3 = 3,
|
||||
NumMethods,
|
||||
};
|
||||
|
||||
/**
|
||||
* Stepper selection, G4QSS2 or G4QSS3.
|
||||
*/
|
||||
void selectStepper(const std::string&);
|
||||
StepperSelection selectedStepper();
|
||||
|
||||
/**
|
||||
* Sets QSS order. To be suppressed in favour of the method
|
||||
* it calls in G4QSSParameters.
|
||||
*/
|
||||
G4bool SetQssOrder(G4int order);
|
||||
|
||||
private:
|
||||
|
||||
StepperSelection _selectedStepper;
|
||||
G4UIdirectory* qssCmdDir;
|
||||
/**
|
||||
* Internal methods -- could be suppressed in future.
|
||||
*/
|
||||
G4bool Set_dQMin( G4double dvalue );
|
||||
G4bool Set_dQRel( G4double value );
|
||||
G4bool SetMaxSubsteps( G4int number );
|
||||
|
||||
private:
|
||||
|
||||
StepperSelection _selectedStepper= StepperSelection::None;
|
||||
|
||||
G4UIdirectory* qssCmdDir;
|
||||
G4UIcmdWithADoubleAndUnit* dQMinCmd;
|
||||
G4UIcmdWithADouble* dQRelCmd;
|
||||
G4UIcmdWithAString* stepperSelectorCmd;
|
||||
G4UIcmdWithADouble* trialProposedStepModifierCmd;
|
||||
G4UIcmdWithAnInteger* maxSubstepsCmd;
|
||||
G4UIcmdWithADouble* dQRelCmd;
|
||||
G4UIcmdWithAString* stepperSelectorCmd;
|
||||
G4UIcmdWithAnInteger* maxSubstepsCmd;
|
||||
};
|
||||
|
||||
#endif // GEANT4_G4QSSMessenger_H
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// ********************************************************************
|
||||
// * License and Disclaimer *
|
||||
// * *
|
||||
// * The Geant4 software is copyright of the Copyright Holders of *
|
||||
// * the Geant4 Collaboration. It is provided under the terms and *
|
||||
// * conditions of the Geant4 Software License, included in the file *
|
||||
// * LICENSE and available at http://cern.ch/geant4/license . These *
|
||||
// * include a list of copyright holders. *
|
||||
// * *
|
||||
// * Neither the authors of this software system, nor their employing *
|
||||
// * institutes,nor the agencies providing financial support for this *
|
||||
// * work make any representation or warranty, express or implied, *
|
||||
// * regarding this software system or assume any liability for its *
|
||||
// * use. Please see the license in the file LICENSE and URL above *
|
||||
// * for the full disclaimer and the limitation of liability. *
|
||||
// * *
|
||||
// * This code implementation is the result of the scientific and *
|
||||
// * technical work of the GEANT4 collaboration. *
|
||||
// * By using, copying, modifying or distributing the software (or *
|
||||
// * any work based on the software) you agree to acknowledge its *
|
||||
// * use in resulting scientific publications, and indicate your *
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4QSSParameters
|
||||
//
|
||||
// Hold parameters for QSS Integrator driver -- used to create
|
||||
// all QSStepper objects (directly or via IntegrationDriver).
|
||||
// Checks consistency of values proposed.
|
||||
//
|
||||
// This design means that objects of only *one* order of QSS driver
|
||||
// can be created (QSS2 or QSS3 must be used globally).
|
||||
//
|
||||
// Author: John Apostolakis (CERN), 19.08.2025
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef G4QSSParameters_HH
|
||||
#define G4QSSParameters_HH
|
||||
|
||||
#include "G4Types.hh"
|
||||
|
||||
/**
|
||||
* @brief G4QSSParameters hold parameters for the QSS Integrator driver.
|
||||
* It is used to create all QSStepper objects, directly or via the
|
||||
* Integration Driver. Checks for consistency of the proposed values.
|
||||
*/
|
||||
|
||||
class G4QSSParameters
|
||||
{
|
||||
public:
|
||||
|
||||
static G4QSSParameters* Instance();
|
||||
|
||||
/**
|
||||
* Default Destructor.
|
||||
*/
|
||||
~G4QSSParameters() = default;
|
||||
|
||||
/**
|
||||
* Accessors.
|
||||
*/
|
||||
inline G4int GetQssOrder() { return fQssOrder; }
|
||||
inline G4double Get_dQRel() { return fdQRel; }
|
||||
inline G4double Get_dQMin() { return fdQMin; }
|
||||
inline G4int GetMaxSubsteps() { return fMaxSubsteps; }
|
||||
|
||||
/**
|
||||
* Modifiers.
|
||||
*/
|
||||
G4bool SetQssOrder( G4int value, G4bool onlyWarn= false );
|
||||
G4bool Set_dQRel( G4double dQRel );
|
||||
G4bool Set_dQMin( G4double dQMin );
|
||||
G4bool SetMaxSubsteps( G4int maxSubsteps );
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Private default Constructor.
|
||||
*/
|
||||
G4QSSParameters() = default;
|
||||
|
||||
private:
|
||||
|
||||
G4int fQssOrder = 2;
|
||||
G4double fdQMin = 0.00001;
|
||||
G4double fdQRel = 0.001;
|
||||
G4int fMaxSubsteps = 5000;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -27,10 +27,10 @@
|
||||
//
|
||||
// QSS statistics
|
||||
|
||||
// Authors: Lucio Santi, Rodrigo Castro (Univ. Buenos Aires) - 2018-2021
|
||||
// Authors: Lucio Santi, Rodrigo Castro (Univ. Buenos Aires), 2018-2021
|
||||
// --------------------------------------------------------------------
|
||||
#ifndef _QSS_CUSTOM_STATS_HH_
|
||||
#define _QSS_CUSTOM_STATS_HH_ 1
|
||||
#ifndef QSS_CUSTOM_STATS_HH
|
||||
#define QSS_CUSTOM_STATS_HH
|
||||
|
||||
#include <time.h>
|
||||
|
||||
@@ -44,8 +44,14 @@
|
||||
|
||||
#include "G4qss_misc.hh"
|
||||
#include "G4Types.hh"
|
||||
#include "G4ios.hh"
|
||||
|
||||
#include <atomic>
|
||||
#include <map>
|
||||
|
||||
/**
|
||||
* @brief QSSStats contains functions for statistics on the QSS drivers.
|
||||
*/
|
||||
|
||||
struct QSSStats
|
||||
{
|
||||
@@ -69,7 +75,8 @@ struct QSSStats
|
||||
reset_time = 0;
|
||||
integration_time = 0;
|
||||
|
||||
for (size_t i = 0; i < Qss_misc::VAR_IDX_END; i++) {
|
||||
for (std::size_t i = 0; i < Qss_misc::VAR_IDX_END; ++i)
|
||||
{
|
||||
dqrel_changes[i] = 0;
|
||||
dqmin_changes[i] = 0;
|
||||
max_error[i] = 0;
|
||||
@@ -98,12 +105,12 @@ struct QSSStats
|
||||
<< " Substeps average per step: " << avg_substeps << std::endl;
|
||||
|
||||
ss << " Substeps by track-step:" << std::endl;
|
||||
for (auto it = substepsByStepNumberByTrackID.begin(); it != substepsByStepNumberByTrackID.end();
|
||||
++it)
|
||||
for (const auto& stp : substepsByStepNumberByTrackID)
|
||||
{
|
||||
ss << " Track #" << it->first << std::endl;
|
||||
for (auto it2 = it->second.begin(); it2 != it->second.end(); ++it2) {
|
||||
ss << " Step " << it2->first << " => " << it2->second << " substeps" << std::endl;
|
||||
ss << " Track #" << stp.first << std::endl;
|
||||
for (const auto& stp2 : stp.second)
|
||||
{
|
||||
ss << " Step " << stp2.first << " => " << stp2.second << " substeps" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,14 +121,15 @@ struct QSSStats
|
||||
ss << " Reset time: " << reset_time << std::endl
|
||||
<< " Reset time average: " << avg_reset_time << std::endl;
|
||||
|
||||
for (G4int index = 0; index < Qss_misc::VAR_IDX_END; index++) {
|
||||
for (std::size_t index = 0; index < Qss_misc::VAR_IDX_END; ++index)
|
||||
{
|
||||
ss << " Variable " << vars[index] << ":" << std::endl;
|
||||
ss << " dQRel changes: " << dqrel_changes[index] << std::endl;
|
||||
ss << " dQMin changes: " << dqmin_changes[index] << std::endl;
|
||||
ss << " Max error: " << max_error[index] << std::endl;
|
||||
}
|
||||
|
||||
std::cout << ss.rdbuf();
|
||||
G4cout << ss.rdbuf();
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -27,174 +27,226 @@
|
||||
//
|
||||
// QSS Integrator Stepper
|
||||
//
|
||||
// Authors - version 1 : Lucio Santi, Rodrigo Castro (Univ. Buenos Aires) - 2018-2021
|
||||
// - version 2 : Mattias Portnoy (Univ. Buenos Aires) - 2024
|
||||
// Authors: version 1 - Lucio Santi, Rodrigo Castro (Univ. Buenos Aires), 2018-2021
|
||||
// version 2 - Mattias Portnoy (Univ. Buenos Aires), 2024
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#ifndef G4QSS_STEPPER_HH
|
||||
#define G4QSS_STEPPER_HH 1
|
||||
#define G4QSS_STEPPER_HH
|
||||
|
||||
#include "G4FieldTrack.hh"
|
||||
#include "G4MagIntegratorStepper.hh"
|
||||
#include "G4QSSMessenger.hh"
|
||||
#include "G4QSSubstepStruct.hh"
|
||||
|
||||
#include <cmath>
|
||||
#include <CLHEP/Units/PhysicalConstants.h>
|
||||
|
||||
/**
|
||||
* @brief G4QSStepper is an integrator of particle's equation of
|
||||
* motion based on the QSS implementation.
|
||||
*/
|
||||
|
||||
class G4QSStepper : public G4MagIntegratorStepper
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for G4QSStepper.
|
||||
* @param[in] equation Pointer to the provided equation of motion.
|
||||
* @param[in] num_integration_vars The number of integration variables.
|
||||
* @param[in] qssOrder The QSS order (2 or 3 expected; if <= 0 , use value
|
||||
* from Messenger.
|
||||
*/
|
||||
G4QSStepper( G4EquationOfMotion* equation,
|
||||
G4int num_integration_vars,
|
||||
G4int num_state_vars,
|
||||
G4bool isFSAL,
|
||||
G4int verbosity=0 );
|
||||
G4int num_integration_vars = 6, // always 6 -- ignore
|
||||
G4int qssOrder= -1 );
|
||||
|
||||
G4QSStepper(G4EquationOfMotion *EqRhs,
|
||||
G4int numberOfVariables = 6,
|
||||
G4bool primary = true);
|
||||
|
||||
virtual ~G4QSStepper();
|
||||
/**
|
||||
* Default Destructor. Freeing of memory is done in susbsteps destructor.
|
||||
*/
|
||||
~G4QSStepper() override = default;
|
||||
|
||||
/**
|
||||
* Utility methods.
|
||||
*/
|
||||
inline constexpr G4double Cubic_Function(const QSStateVector* states,
|
||||
G4int index, G4double delta_t);
|
||||
|
||||
inline constexpr G4double Parabolic_Function(const QSStateVector* states,
|
||||
G4int index, G4double delta_t);
|
||||
|
||||
inline constexpr G4double Linear_Function(const QSStateVector* states,
|
||||
G4int index, G4double delta_t);
|
||||
|
||||
/* 0 means position type, 1 means velocity type. */
|
||||
/**
|
||||
* 0 means position type, 1 means velocity type.
|
||||
*/
|
||||
inline constexpr int INDEX_TYPE(G4int i);
|
||||
|
||||
inline void set_qss_order(G4int order);
|
||||
|
||||
// auxiliary methods
|
||||
|
||||
/**
|
||||
* Auxiliary methods.
|
||||
*/
|
||||
inline void momentum_to_velocity(const G4double* momentum, G4double* out);
|
||||
|
||||
void set_relativistic_coeff(const G4double* momentum);
|
||||
|
||||
inline void velocity_to_momentum(G4double *y);
|
||||
|
||||
// Key methods
|
||||
|
||||
/**
|
||||
* Key methods.
|
||||
*/
|
||||
void initialize(const G4double y[]);
|
||||
|
||||
inline void compare_time_and_update(G4int index, G4int i);
|
||||
|
||||
inline void compare_time_and_update(G4int& index, G4int i);
|
||||
inline G4int get_next_sync_index();
|
||||
|
||||
inline void update_field();
|
||||
|
||||
inline G4double extrapolate_polynomial(QSStateVector* states,
|
||||
G4int index, G4double delta_t, G4int order);
|
||||
inline void extrapolate_all_states_to_t(Substep* substep,
|
||||
G4double t, G4double* yOut);
|
||||
|
||||
/* Moves all the x states of variable index to the current time t. */
|
||||
/**
|
||||
* Moves all the x states of variable index to the current time t.
|
||||
*/
|
||||
inline void update_x(G4int index, G4double t);
|
||||
|
||||
/* Moves all the q states of variable index to the current t. */
|
||||
/**
|
||||
* Moves all the q states of variable index to the current t.
|
||||
*/
|
||||
inline void update_q(G4int index, G4double t);
|
||||
|
||||
/**
|
||||
* Update methods.
|
||||
*/
|
||||
inline void update_x_position_derivates_using_q(G4int index);
|
||||
inline void update_x_velocity_derivates_using_q(G4int index);
|
||||
inline void update_x_derivates_using_q(G4int index);
|
||||
inline void update_sync_time_one_coefficient(G4int index);
|
||||
|
||||
/* Updates when does the x,q distance goes beyond the quantum.
|
||||
Uses polynomial roots-finding formulas. */
|
||||
/*
|
||||
* Updates when does the x,q distance goes beyond the quantum.
|
||||
* Uses polynomial roots-finding formulas.
|
||||
*/
|
||||
void update_sync_time(G4int index);
|
||||
|
||||
/* Key method called by driver. */
|
||||
/**
|
||||
* The stepper for the integration.
|
||||
* The stepsize is fixed, with the step size given by 'h'.
|
||||
* Integrates ODE starting values y[0 to 6]. Outputs yout[].
|
||||
* @param[in] y Starting values array of integration variables.
|
||||
* @param[in] dydx Derivatives array - Not used.
|
||||
* @param[in] h The given step size.
|
||||
* @param[out] yout Integration output.
|
||||
* @param[out] yError The estimated error - Not used.
|
||||
*/
|
||||
void Stepper( const G4double y[],
|
||||
const G4double /*dydx*/ [],
|
||||
G4double h,
|
||||
G4double yout[],
|
||||
G4double /* yerr */ [] ) override;
|
||||
|
||||
/* Obligatory G4InterpolationDriver methods. */
|
||||
/**
|
||||
* Returns the QSS order of integration.
|
||||
*/
|
||||
inline G4int IntegratorOrder() const override;
|
||||
|
||||
/**
|
||||
* Returns the stepper type-ID, "kQSStepper".
|
||||
*/
|
||||
inline G4StepperType StepperType() const override { return kQSStepper; }
|
||||
|
||||
/**
|
||||
* Returns a pointer to the equation of motion.
|
||||
*/
|
||||
inline G4EquationOfMotion* GetSpecificEquation();
|
||||
|
||||
/**
|
||||
* Returns current track state.
|
||||
*/
|
||||
inline const field_utils::State& GetYOut() const;
|
||||
|
||||
void Interpolate(G4double tau,G4double yOut[]);
|
||||
/**
|
||||
* Track interpolation.
|
||||
* @param[in] tau Step start, x.
|
||||
* @param[in,out] yOut The current track state, y.
|
||||
*/
|
||||
void Interpolate(G4double tau, G4double yOut[]);
|
||||
|
||||
/**
|
||||
* Returns the distance from chord line.
|
||||
*/
|
||||
inline G4double DistChord() const override;
|
||||
|
||||
/**
|
||||
* Wrapper for the Stepper() function above.
|
||||
*/
|
||||
inline void Stepper(const G4double yInput[],
|
||||
const G4double dydx[],
|
||||
G4double hstep, G4double yOutput[], G4double yError[],
|
||||
G4double hstep,
|
||||
G4double yOutput[],
|
||||
G4double yError[],
|
||||
G4double /*dydxOutput*/ []);
|
||||
|
||||
/**
|
||||
* Sets up interpolation. Does nothing.
|
||||
*/
|
||||
inline void SetupInterpolation();
|
||||
|
||||
/* obligatory qss driver methods. */
|
||||
|
||||
/*
|
||||
* Obligatory qss driver methods.
|
||||
*/
|
||||
inline void reset(const G4FieldTrack* track);
|
||||
|
||||
inline void SetPrecision(G4double dq_rel, G4double dq_min);
|
||||
|
||||
inline G4double GetLastStepLength();
|
||||
|
||||
/*
|
||||
* Sets the mass at rest. Checking/ensuring that it is positive.
|
||||
*/
|
||||
inline void setRestMass(G4double restMass);
|
||||
|
||||
private:
|
||||
|
||||
// Constants
|
||||
|
||||
static constexpr int DERIVATIVE_0 = 0;
|
||||
static constexpr int DERIVATIVE_1 = 1;
|
||||
static constexpr int DERIVATIVE_2 = 2;
|
||||
static constexpr int DERIVATIVE_3 = 3;
|
||||
static constexpr int DERIVATIVE_0{0};
|
||||
static constexpr int DERIVATIVE_1{1};
|
||||
static constexpr int DERIVATIVE_2{2};
|
||||
static constexpr int DERIVATIVE_3{3};
|
||||
|
||||
static constexpr int VX = 3;
|
||||
static constexpr int VY = 4;
|
||||
static constexpr int VZ = 5;
|
||||
static constexpr int VX{3};
|
||||
static constexpr int VY{4};
|
||||
static constexpr int VZ{5};
|
||||
|
||||
static constexpr int POSITION_IDX = 0;
|
||||
static constexpr int VELOCITY_IDX = 3;
|
||||
static constexpr int NUMBER_OF_VARIABLES_QSS = 6;
|
||||
static constexpr int POSITION_IDX{0};
|
||||
static constexpr int VELOCITY_IDX{3};
|
||||
|
||||
static constexpr G4double INFTY = 1e+20;
|
||||
static constexpr G4double INFTY{1e+20};
|
||||
|
||||
/* Used to check if field changed from last update field during substeps. */
|
||||
G4bool fField_changed = true;
|
||||
G4bool fTrack_changed = true;
|
||||
/** Used to check if field changed from last update field during substeps. */
|
||||
G4bool fField_changed{true};
|
||||
G4bool fTrack_changed{true};
|
||||
|
||||
G4int qss_order = 2;
|
||||
const G4int qss_order{2};
|
||||
|
||||
Substeps substeps;
|
||||
Substep current_substep;
|
||||
const G4FieldTrack* fCurrent_track = nullptr;
|
||||
const G4FieldTrack* fCurrent_track{nullptr};
|
||||
QSStateVector dq_vector;
|
||||
|
||||
// Invariants for this track -- during propagation
|
||||
//
|
||||
G4double fCharge;
|
||||
/** Invariants for this track -- during propagation. */
|
||||
G4double fCharge{-1.0};
|
||||
G4double fCharge_c2;
|
||||
G4double fRestMass;
|
||||
G4double fGamma;
|
||||
G4double fRestMass{CLHEP::electron_mass_c2};
|
||||
G4double fGamma{1.0};
|
||||
G4double fCoeff; // coeff;
|
||||
|
||||
// Cached values -- for tiny speed up
|
||||
//
|
||||
/** Cached values -- for tiny speed up. */
|
||||
G4double fMassOverC ; // was mass_times_gamma_over_speed_of_light;
|
||||
G4double fInv_mass_over_c;
|
||||
|
||||
/* used by interpolation driver, need to copy state here
|
||||
when stepper finished. */
|
||||
/** Used by interpolation driver, need to copy state here when stepper finished. */
|
||||
G4double fYout[12];
|
||||
|
||||
// QSS parameters separated into velocity and position
|
||||
//
|
||||
/** QSS parameters separated into velocity and position. */
|
||||
G4double dqrel[2] = {0.0,0.0};
|
||||
G4double dqmin[2] = {0.001,0.001};
|
||||
|
||||
G4double fVelocity;
|
||||
G4double fFinal_t;
|
||||
G4double fVelocity{0.0};
|
||||
G4double fFinal_t{0.0};
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user