Import Geant4 10.5.0 source tree

This commit is contained in:
Gabriele Cosmo
2018-12-07 15:15:39 +01:00
parent 6aa23be517
commit db49709b53
11370 changed files with 187480 additions and 160142 deletions
-1
View File
@@ -8,7 +8,6 @@
#
# Generated on : 24/9/2010
#
# $Id: CMakeLists.txt 85530 2014-10-30 16:17:43Z gcosmo $
#
#------------------------------------------------------------------------------
-1
View File
@@ -1,4 +1,3 @@
# $Id: GNUmakefile 101697 2016-11-21 16:10:08Z gcosmo $
# --------------------------------------------------------------
# GNUmakefile for geometry. Gabriele Cosmo, 16/11/96.
# --------------------------------------------------------------
-1
View File
@@ -1,4 +1,3 @@
$Id: History 85608 2014-10-31 11:23:30Z gcosmo $
-------------------------------------------------------------------
=========================================================
-1
View File
@@ -7,7 +7,6 @@
#
# Generated on : 24/9/2010
#
# $Id: CMakeLists.txt 66356 2012-12-18 09:02:32Z gcosmo $
#
#------------------------------------------------------------------------------
-1
View File
@@ -1,4 +1,3 @@
# $Id: GNUmakefile 66356 2012-12-18 09:02:32Z gcosmo $
# --------------------------------------------------------------------
# GNUmakefile for geometry/biasing library. Gabriele Cosmo, 25/03/02.
# --------------------------------------------------------------------
-1
View File
@@ -1,4 +1,3 @@
$Id: History 102994 2017-03-07 16:31:28Z gcosmo $
-------------------------------------------------------------------
=========================================================
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4GeometryCell.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// Class G4GeometryCell
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4GeometryCellComp.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// Class G4GeometryCellComp
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4GeometryCellImportance.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// Class G4GeometryCellImportance
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4GeometryCellStep.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// Class G4GeometryCellStep
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4GeometryCellStepStream.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// Declarations
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4GeometryCellWeight.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// Class G4GeometryCellWeight
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4IStore.hh 102994 2017-03-07 16:31:28Z gcosmo $
//
// ----------------------------------------------------------------------
// Class G4IStore
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ImportanceAlgorithm.hh 102994 2017-03-07 16:31:28Z gcosmo $
//
// ----------------------------------------------------------------------
// Class G4ImportanceAlgorithm
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4Nsplit_Weight.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// Class G4Nsplit_Weight
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4VGCellFinder.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// Class G4VGCellFinder
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4VIStore.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// Class G4VIStore
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4VImportanceAlgorithm.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// Class G4VImportanceAlgorithm
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4VImportanceSplitExaminer.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// Class G4VImportanceSplitExaminer
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4VWeightWindowAlgorithm.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// Class G4VWeightWindowAlgorithm
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4VWeightWindowStore.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// Class G4VWeightWindowStore
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4WeightWindowAlgorithm.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// Class G4WeightWindowAlgorithm
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4WeightWindowStore.hh 88801 2015-03-10 14:38:27Z gcosmo $
//
// ----------------------------------------------------------------------
// Class G4WeightWindowStore
-1
View File
@@ -11,7 +11,6 @@
#
# Generated on : 24/9/2010
#
# $Id: sources.cmake 66356 2012-12-18 09:02:32Z gcosmo $
#
#------------------------------------------------------------------------------
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4GeometryCell.cc 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// GEANT 4 class source file
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4GeometryCellComp.cc 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// GEANT 4 class source file
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4GeometryCellImportance.cc 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// GEANT 4 class source file
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4GeometryCellStep.cc 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// GEANT 4 class source file
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4GeometryCellStepStream.cc 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// GEANT 4 class source file
-1
View File
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4IStore.cc 102994 2017-03-07 16:31:28Z gcosmo $
//
// ----------------------------------------------------------------------
// GEANT 4 class source file
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ImportanceAlgorithm.cc 102994 2017-03-07 16:31:28Z gcosmo $
//
// ----------------------------------------------------------------------
// GEANT 4 class source file
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4Nsplit_Weight.cc 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// GEANT 4 class source file
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4VGCellFinder.cc 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// GEANT 4 class source file
-1
View File
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4VIStore.cc 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// GEANT 4 class source file
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4VImportanceAlgorithm.cc 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// GEANT 4 class source file
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4VImportanceSplitExaminer.cc 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// GEANT 4 class source file
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4VWeightWindowAlgorithm.cc 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// GEANT 4 class source file
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4VWeightWindowStore.cc 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// GEANT 4 class source file
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4WeightWindowAlgorithm.cc 66356 2012-12-18 09:02:32Z gcosmo $
//
// ----------------------------------------------------------------------
// GEANT 4 class source file
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4WeightWindowStore.cc 88801 2015-03-10 14:38:27Z gcosmo $
//
// ----------------------------------------------------------------------
// GEANT 4 class source file
-1
View File
@@ -7,7 +7,6 @@
#
# Generated on : 24/9/2010
#
# $Id: CMakeLists.txt 66356 2012-12-18 09:02:32Z gcosmo $
#
#------------------------------------------------------------------------------
-1
View File
@@ -1,4 +1,3 @@
# $Id: GNUmakefile 79490 2014-03-05 15:23:33Z gcosmo $
# ----------------------------------------------------------------------
# GNUmakefile for geometry/divisions library. Gabriele Cosmo, 16/06/03.
# ----------------------------------------------------------------------
-1
View File
@@ -1,4 +1,3 @@
$Id: History 103225 2017-03-22 14:31:02Z gcosmo $
-------------------------------------------------------------------
=========================================================
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4PVDivision.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
// class G4PVDivision
//
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4PVDivisionFactory.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
//
// class G4PVDivisionFactory
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ParameterisationBox.hh 73433 2013-08-27 11:05:39Z gcosmo $
//
// classes G4ParameterisationBoxX,
// G4ParameterisationBoxY,
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ParameterisationCons.hh 73433 2013-08-27 11:05:39Z gcosmo $
//
// classes G4ParameterisationConsRho,
// G4ParameterisationConsPhi,
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ParameterisationPara.hh 73433 2013-08-27 11:05:39Z gcosmo $
//
// classes G4ParameterisationParaX,
// G4ParameterisationParaY,
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ParameterisationPolycone.hh 73433 2013-08-27 11:05:39Z gcosmo $
//
// classes G4ParameterisationPolyconeRho,
// G4ParameterisationPolyconePhi,
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ParameterisationPolyhedra.hh 73433 2013-08-27 11:05:39Z gcosmo $
//
// classes G4ParameterisationPolyhedraRho,
// G4ParameterisationPolyhedraPhi,
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ParameterisationTrd.hh 73433 2013-08-27 11:05:39Z gcosmo $
//
// classes G4ParameterisationTrdX
// G4ParameterisationTrdY
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ParameterisationTubs.hh 73433 2013-08-27 11:05:39Z gcosmo $
//
// classes G4ParameterisationTubsRho
// G4ParameterisationTubsPhi
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ReplicatedSlice.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
// class G4ReplicatedSlice
//
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4VDivisionParameterisation.hh 92625 2015-09-09 12:34:07Z gcosmo $
//
// class G4VDivisionParameterisation
//
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4VDivisionParameterisation.icc 66356 2012-12-18 09:02:32Z gcosmo $
//
// class G4VDivisionParameterisation Inline Implementation file
//
-1
View File
@@ -11,7 +11,6 @@
#
# Generated on : 24/9/2010
#
# $Id: sources.cmake 79490 2014-03-05 15:23:33Z gcosmo $
#
#------------------------------------------------------------------------------
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4PVDivision.cc 92631 2015-09-09 12:53:04Z gcosmo $
//
// class G4PVDivision Implementation file
//
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4PVDivisionFactory.cc 68718 2013-04-05 09:16:24Z gcosmo $
//
// class G4PVDivisionFactory Implementation file
//
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ParameterisationBox.cc 68040 2013-03-13 14:19:04Z gcosmo $
//
// class G4ParameterisationBox Implementation file
//
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ParameterisationCons.cc 66356 2012-12-18 09:02:32Z gcosmo $
//
// class G4ParameterisationCons Implementation file
//
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ParameterisationPara.cc 66356 2012-12-18 09:02:32Z gcosmo $
//
// class G4ParameterisationPara Implementation file
//
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ParameterisationPolycone.cc 92635 2015-09-09 13:39:54Z gcosmo $
//
// class G4ParameterisationPolycone Implementation file
//
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ParameterisationPolyhedra.cc 92635 2015-09-09 13:39:54Z gcosmo $
//
// class G4ParameterisationPolyhedra Implementation file
//
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ParameterisationTrd.cc 68040 2013-03-13 14:19:04Z gcosmo $
//
// class G4ParameterisationTrd Implementation file
//
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ParameterisationTubs.cc 66356 2012-12-18 09:02:32Z gcosmo $
//
// class G4ParameterisationTubs Implementation file
//
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ReplicatedSlice.cc 89815 2015-04-30 14:50:22Z gcosmo $
//
// --------------------------------------------------------------------
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4VDivisionParameterisation.cc 92625 2015-09-09 12:34:07Z gcosmo $
//
// class G4VDivisionParameterisation Implementation file
//
@@ -7,7 +7,6 @@
#
# Generated on : 24/9/2010
#
# $Id: CMakeLists.txt 66356 2012-12-18 09:02:32Z gcosmo $
#
#------------------------------------------------------------------------------
@@ -1,4 +1,3 @@
# $Id: GNUmakefile 66356 2012-12-18 09:02:32Z gcosmo $
# --------------------------------------------------------------------
# GNUmakefile for geometry/magneticfield library. G.Cosmo, 22/01/97.
+52 -1
View File
@@ -1,4 +1,3 @@
$Id: History 110833 2018-06-15 15:01:33Z gcosmo $
-------------------------------------------------------------------
=========================================================
@@ -17,6 +16,58 @@ committal in the CVS repository !
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
November 9, 2018 J.Apostolakis - field-V10-04-17
------------------------------
- Small fixes for warnings in compilation.
- Revisions of descriptions of recent tags (for clarification.)
September 26, 2018 D.Sorokin - field-V10-04-15, -16
----------------------------
- Implement G4InterpolationDrvier. This driver uses a Runge-Kutta
stepper with interpolation property to integrate EoM with error control.
The field evaluations used to calculate the enpoint of an 'advance' can
be reused to obtain one or multiple internal points on the curve (x,p).
So in steps in which an intersection is found, the number of field
evaluations are expected to be reduced substantially.
September 13, 2018 D.Sorokin - field-V10-04-13, -14
----------------------------
- G4NystromRK4 creates G4CachedMagneticField if it was not provided.
- Removed G4MagIntegratorStepper::ComputeRightHandSide() method
(all calls now use non-virtual RightHandSide() method instead).
- Reversed declaration of final for the class G4UniformMagField.
Returned to previous status: only GetFieldValue method is final.
( This avoid need to change examples/tests and potentially migrate
users' code. )
September 12, 2018 D.Sorokin - field-V10-04-11, -12
----------------------------
- Created new experimental driver G4BFieldIntegrationDriver for pure
magnetic fields. In QuickAdvance it uses helix stepper when the
estimated 'helix' rotation angle is larger than pi/3.
- G4NystromRK4 uses G4CachedMagneticField for caching values.
NOTE: It now the user's responsibility to create G4CachedMagneticField.
( The alternative is to create G4CachedMagneticField inside G4NystromRK4.
But this would have several disadvantages:
* It would change the field in the user's equation of motion;
* G4NystromRK4 is not able to check whether the user calls the method
that changes the equation using SetEquationOfMotion method. )
July 10, 2018 D. Sorokin - field-V10-04-08, -09, -10
------------------------ Tags by J. Apostolakis
- Corrections in calculation of chord distance in G4DormandPrince745
( use 4th order interpolation from Shampine 1986 for mid-point. )
- Revised G4FieldUtils: moved copy() method from steppers,
added 2 new setValue: simple & variadic methods.
- Fixes to copy input time in ModifiedMidpoint, CashKarp, G4RK547FEq1/2/3
Bogacki-Shampine 4/5 and 2/3 (note: B-S 2/3 largely rewritten )
Dormand Prince 4/5, 5/6 and 7/8, and Tsitouras steppers.
- Trial revision in G4BulirschStoer to reduce number of division
operations (J.A.)
- Fix for unitialised pIntStepper pointer in G4FSALIntegrationDriver
constructor. Revision of data member variable names. ( J.A. )
June 15, 2018 G.Cosmo - field-V10-04-07
---------------------
- Fixed minor Coverity defects in G4BurlischStoer and G4ModifiedMidPoint.
@@ -23,56 +23,55 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
//
//
// class G4BFieldIntegrationDriver
//
// Class description:
//
// Specialized integration driver for pure magnetic field
// Create, recycle and Workspaces
// Only one object of this type exists - it is a true Singleton (not per thread).
// History:
// - Created. D.Sorokin
// --------------------------------------------------------------------
#ifndef G4SOLIDSWORKSPACEPOOL_HH
#define G4SOLIDSWORKSPACEPOOL_HH
#ifndef G4BFieldIntegrationDriver_HH
#define G4BFieldIntegrationDriver_HH
#include "geomwdefs.hh"
#include "G4IntegrationDriver.hh"
#include "G4HelixExplicitEuler.hh"
class G4SolidsWorkspace;
template <class T>
class G4BFieldIntegrationDriver : public G4IntegrationDriver<T> {
public:
G4BFieldIntegrationDriver( G4double hminimum,
T* stepper,
G4int numberOfComponents = 6,
G4int statisticsVerbosity = 1);
class G4SolidsWorkspacePool
{
public:
static G4SolidsWorkspacePool* GetInstance();
G4BFieldIntegrationDriver(const G4BFieldIntegrationDriver &) = delete;
const G4BFieldIntegrationDriver& operator =(const G4BFieldIntegrationDriver &) = delete;
G4SolidsWorkspace* CreateWorkspace();
// For use with simple MT mode - each thread gets a workspace
// and uses it until end
virtual G4bool QuickAdvance(
G4FieldTrack& fieldTrack,
const G4double dydx[],
G4double hstep,
G4double inverseCurvatureRadius,
G4double& dchord_step,
G4double& dyerr) override;
void CreateAndUseWorkspace(); // Create it (as above) and use it
G4SolidsWorkspace* FindOrCreateWorkspace();
// For use with 'dynamic' model of threading - workspaces can be recycled
// Reuse an existing workspace - or create a new one if needed.
// This will never fail, except if system is out of resources
virtual void SetEquationOfMotion(G4EquationOfMotion* equation) override;
inline G4SolidsWorkspace* GetWorkspace() { return fMyWorkspace(); }
// Give back the existing, active workspace for my thread / task
virtual G4double GetInverseCurvatureRadius(const G4FieldTrack& track,
G4double field[]) const override;
void Recycle( G4SolidsWorkspace * );
// Keep the unused Workspace - for recycling
void CleanUpAndDestroyAllWorkspaces();
// To be called once at the end of the job
protected:
// void RegisterWarehouse( G4GeometryWarehouse *) ;
// The (optional) warehouse keeps a list of free workspaces
private:
G4SolidsWorkspacePool();
~G4SolidsWorkspacePool();
private:
static G4SolidsWorkspacePool* thePool;
G4GEOM_DLL static G4SolidsWorkspace*& fMyWorkspace();
// The thread's workspace - if assigned.
private:
G4double fallbackThreshold;
G4Mag_EqRhs* fequation;
G4HelixExplicitEuler fallbackStepper;
};
#endif //G4GEOMETRYWORKSPACEPOOL_HH
#include "G4BFieldIntegrationDriver.icc"
#endif
@@ -0,0 +1,122 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
//
//
// class G4BFieldIntegrationDriver
//
// Class description:
//
// Specialized integration driver for pure magnetic field
// History:
// - Created. D.Sorokin
// --------------------------------------------------------------------
#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)
{
}
template <class T>
bool G4BFieldIntegrationDriver<T>::QuickAdvance(G4FieldTrack& fieldTrack,
const G4double dydx[],
G4double hstep,
G4double inverseCurvatureRadius,
G4double& dchord_step,
G4double& dyerr)
{
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;
}
template <class T>
void G4BFieldIntegrationDriver<T>::SetEquationOfMotion(G4EquationOfMotion* equation)
{
G4IntegrationDriver<T>::SetEquationOfMotion(equation);
fequation = internal::toMagneticEquation(equation);
}
template <class T>
G4double G4BFieldIntegrationDriver<T>::GetInverseCurvatureRadius(const G4FieldTrack& track,
G4double field[]) const
{
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));
}
@@ -46,81 +46,46 @@
#define G4BOGACKI_SHAMPINE23_H
#include "G4MagIntegratorStepper.hh"
#include "G4FieldTrack.hh"
class G4BogackiShampine23 : public G4MagIntegratorStepper{
public:
G4BogackiShampine23(G4EquationOfMotion* EqRhs,
G4int numberOfVariables = 6);
virtual void Stepper(const G4double yInput[],
const G4double dydx[],
G4double hstep,
G4double yOutput[],
G4double yError[]) override;
public:
//constructor
G4BogackiShampine23( G4EquationOfMotion *EqRhs,
G4int numberOfVariables = 6,
G4bool primary= true ) ;
void Stepper(const G4double yInput[],
const G4double dydx[],
G4double hstep,
G4double yOutput[],
G4double yError[],
G4double dydxOutput[]);
//destructor
~G4BogackiShampine23() ;
//Stepper
void Stepper(const G4double y[],
const G4double dydx[],
G4double h,
G4double yout[],
G4double yerr[] ) ;
G4double DistChord() const;
G4int IntegratorOrder() const { return 2; }
G4double *getLastDydx();
private:
G4BogackiShampine23(const G4BogackiShampine23&) = delete;
G4BogackiShampine23& operator=(const G4BogackiShampine23&) = delete;
G4BogackiShampine23& operator = (const G4BogackiShampine23&) = delete;
private:
virtual G4double DistChord() const override;
virtual G4int IntegratorOrder() const override { return 3; }
G4double *ak2, *ak3, *ak4, *yTemp, *yIn;
// for storing intermediate 'k' values in stepper
G4double *pseudoDydx_for_DistChord;
G4double fLastStepLength;
G4double *fLastInitialVector, *fLastFinalVector,
*fLastDyDx, *fMidVector, *fMidError;
// for DistChord calculations
private:
void makeStep(const G4double yInput[],
const G4double dydx[],
const G4double hstep,
G4double yOutput[],
G4double* dydxOutput = nullptr,
G4double* yError = nullptr) const;
G4BogackiShampine23* fAuxStepper;
// G4int No_of_vars;
// G4double hinit, tinit, tmax, *yinit;
// double hmax, hmin, safe_const, err0, Step_factor;
// void (*derivs)(double, double *, double *);
G4double fyIn[G4FieldTrack::ncompSVEC],
fdydx[G4FieldTrack::ncompSVEC],
fyOut[G4FieldTrack::ncompSVEC],
fdydxOut[G4FieldTrack::ncompSVEC];
G4double fhstep = -1.0;
};
#endif /* G4BogackiShampine23 */
#endif
@@ -23,7 +23,6 @@
// ********************************************************************
//
//
// $Id: $
//
// Description:
// G4BulirschStoer class implementation by Dmitry Sorokin
@@ -23,7 +23,6 @@
// ********************************************************************
//
//
// $Id: $
//
// Helper namespace 'magneticfield'
//
@@ -43,9 +42,12 @@
#include "G4IntegrationDriver.hh"
#include "G4BulirschStoer.hh"
#include "G4ChordFinderDelegate.hh"
template <>
class G4IntegrationDriver<G4BulirschStoer>: public G4VIntegrationDriver {
class G4IntegrationDriver<G4BulirschStoer>:
public G4VIntegrationDriver,
public G4ChordFinderDelegate<G4IntegrationDriver<G4BulirschStoer>> {
public:
G4IntegrationDriver(
G4double hminimum,
@@ -58,6 +60,21 @@ public:
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() override {};
virtual G4bool AccurateAdvance(
G4FieldTrack& track,
G4double stepLen,
@@ -68,6 +85,7 @@ public:
G4FieldTrack& y_val,
const G4double dydx[],
G4double hstep,
G4double inverseCurvatureRadius,
G4double& missDist,
G4double& dyerr) override;
@@ -84,6 +102,11 @@ public:
const G4FieldTrack& track,
G4double dydx[]) const override;
virtual void GetDerivatives(
const G4FieldTrack& track,
G4double dydx[],
G4double field[]) const override;
virtual void SetVerboseLevel(G4int level) override;
virtual G4int GetVerboseLevel() const override;
@@ -121,6 +144,8 @@ private:
G4double derivs[2][6][G4FieldTrack::ncompSVEC];
const G4int interval_sequence[2];
using ChordFinderDelegate = G4ChordFinderDelegate<G4IntegrationDriver<G4BulirschStoer>>;
};
#include "G4BulirschStoerDriver.icc"
@@ -29,7 +29,7 @@
G4IntegrationDriver<G4BulirschStoer>::G4IntegrationDriver(
G4double hminimum,
G4BulirschStoer* stepper,
G4int numberOfComponents,
G4int, // numberOfComponents,
G4int statisticsVerbosity)
: fMinimumStep(hminimum)
, fVerbosity(statisticsVerbosity)
@@ -146,7 +146,7 @@ G4bool G4IntegrationDriver<G4BulirschStoer>::AccurateAdvance(
yFldTrk.LoadFromArray(yCurrent, G4FieldTrack::ncompSVEC);
yFldTrk.SetCurveLength(curveLength);
QuickAdvance(yFldTrk, dydxCurrent, h, dchord_step, dyerr_len);
QuickAdvance(yFldTrk, dydxCurrent, h, -1, dchord_step, dyerr_len);
yFldTrk.DumpToArray(yCurrent);
@@ -243,6 +243,7 @@ G4bool G4IntegrationDriver<G4BulirschStoer>::QuickAdvance(
G4FieldTrack& track,
const G4double dydx[],
G4double hstep,
G4double /*inverseCurvatureRadius*/,
G4double& missDist,
G4double& dyerr)
{
@@ -279,7 +280,7 @@ G4bool G4IntegrationDriver<G4BulirschStoer>::QuickAdvance(
yError[i] = yOut[i] - yOut2[i];
}
dyerr = hstep * field_utils::relativeError(yOut, yError, hstep);
dyerr = field_utils::absoluteError(yOut, yError, hstep);
//copy non-integrated variables to output array
@@ -329,6 +330,16 @@ void G4IntegrationDriver<G4BulirschStoer>::GetDerivatives(
GetEquationOfMotion()->RightHandSide(y, dydx);
}
void G4IntegrationDriver<G4BulirschStoer>::GetDerivatives(
const G4FieldTrack& track,
G4double dydx[],
G4double field[]) const
{
G4double y[G4FieldTrack::ncompSVEC];
track.DumpToArray(y);
GetEquationOfMotion()->EvaluateRhsReturnB(y, dydx, field);
}
void G4IntegrationDriver<G4BulirschStoer>::SetVerboseLevel(G4int level)
{
fVerbosity = level;
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4CashKarpRKF45.hh 97598 2016-06-06 07:19:46Z gcosmo $
//
//
// class G4CashKarpRKF45
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ChargeState.hh $
//
//
// class G4ChargeState
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ChordFinder.hh 107470 2017-11-15 07:14:28Z gcosmo $
//
//
// Class G4ChordFinder
@@ -47,13 +46,16 @@
class G4VFSALIntegrationStepper;
// #include "G4VFSALIntegratorSteper.hh"
class G4MagneticField;
class G4MagneticField;
class G4CachedMagneticField;
class G4ChordFinder
{
{
public: // with description
explicit G4ChordFinder( G4VIntegrationDriver* pIntegrationDriver );
// The most flexible constructor, which allows the user to specify
// any type of field, equation, stepper and integration driver.
G4ChordFinder( G4MagneticField* itsMagField,
G4double stepMinimum = 1.0e-2, // * mm
@@ -61,14 +63,20 @@ class G4ChordFinder
// G4bool useHigherEfficiencyStepper = true,
G4bool useFSALstepper = false );
// 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 (old-style without themplates) integration driver.
// Except if 'useFSAL' is set (true), which provides a FSAL stepper
// and its corresponding specialised (templated) driver.
virtual ~G4ChordFinder();
G4double AdvanceChordLimited( G4FieldTrack& yCurrent,
G4double stepInitial,
G4double epsStep_Relative,
const G4ThreeVector& latestSafetyOrigin,
G4double lasestSafetyRadius);
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.
@@ -100,68 +108,18 @@ class G4ChordFinder
inline void ResetStepEstimate();
// Clear internal state (last step estimate)
inline G4int GetNoCalls();
inline G4int GetNoTrials(); // Total number of trials
inline G4int GetNoMaxTrials(); // Maximum # of trials for one call
// Get statistics about number of calls & trials in FindNextChord
virtual void PrintStatistics();
// A report with the above -- and possibly other stats
inline G4int SetVerbose( G4int newvalue=1);
// Set verbosity and return old value
void SetFractions_Last_Next( G4double fractLast= 0.90,
G4double fractNext= 0.95 );
// Parameters for performance ... change with great care
inline void SetFirstFraction(G4double fractFirst);
// Parameter for performance ... change with great care
public: // without description
void TestChordPrint( G4int noTrials,
G4int lastStepTrial,
G4double dChordStep,
G4double nextStepTrial );
// Printing for monitoring ...
inline G4double GetFirstFraction(); // Originally 0.999
inline G4double GetFractionLast(); // Originally 1.000
inline G4double GetFractionNextEstimate(); // Originally 0.980
inline G4double GetMultipleRadius(); // No original value
// Parameters for adapting performance ... use with great care
void OnComputeStep();
protected: // .........................................................
inline void AccumulateStatistics( G4int noTrials );
// Accumulate the basic statistics
// - other specialised ones must be kept by derived classes
inline G4bool AcceptableMissDist(G4double dChordStep) const;
G4double NewStep( G4double stepTrialOld,
G4double dChordStep, // Current dchord estimate
G4double& stepEstimate_Unconstrained ) ;
virtual G4double FindNextChord( const G4FieldTrack& yStart,
G4double stepMax,
G4FieldTrack& yEnd,
G4double& dyErr, // Error of endpoint
G4double epsStep,
G4double* pNextStepForAccuracy, // = 0,
const G4ThreeVector latestSafetyOrigin,
G4double latestSafetyRadius
);
void PrintDchordTrial(G4int noTrials,
G4double stepTrial,
G4double oldStepTrial,
G4double dChordStep);
inline G4double GetLastStepEstimateUnc();
inline void SetLastStepEstimateUnc( G4double stepEst );
private: // ............................................................
G4ChordFinder(const G4ChordFinder&);
@@ -177,9 +135,8 @@ class G4ChordFinder
// PARAMETERS
// ---------------------
G4double fDeltaChord; // Maximum miss distance
// Internal parameters
G4double fFirstFraction, fFractionLast, fFractionNextEstimate;
G4double fMultipleRadius;
// G4double fMultipleRadius; // Use forgotten
G4int fStatsVerbose; // if > 0, print Statistics in destructor
// DEPENDENT Objects
@@ -187,17 +144,9 @@ class G4ChordFinder
G4VIntegrationDriver* fIntgrDriver;
G4MagIntegratorStepper* fRegularStepperOwned= nullptr;
G4MagIntegratorStepper* fNewFSALStepperOwned= nullptr;
G4CachedMagneticField* fCachedField= nullptr;
// G4VFSALIntegrationStepper* fOldFSALStepperOwned= nullptr;
G4EquationOfMotion* fEquation;
// STATE information
// --------------------
G4double fLastStepEstimate_Unconstrained;
// State information for efficiency
// For Statistics
// -- G4int fNoTrials, fNoCalls;
G4int fTotalNoTrials_FNC, fNoCalls_FNC, fmaxTrials_FNC; // fnoTimesMaxTrFNC;
G4EquationOfMotion* fEquation;
};
// Inline function implementation:
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ChordFinder.icc 107059 2017-11-01 14:58:16Z gcosmo $
//
// G4ChordFinder inline implementations
//
@@ -42,12 +41,6 @@ G4VIntegrationDriver* G4ChordFinder::GetIntegrationDriver()
return fIntgrDriver;
}
inline
G4bool G4ChordFinder::AcceptableMissDist(G4double dChordStep) const
{
return (dChordStep <= fDeltaChord) ;
}
inline
G4double G4ChordFinder::GetDeltaChord() const
{
@@ -60,37 +53,12 @@ void G4ChordFinder::SetDeltaChord(G4double newval)
fDeltaChord=newval;
}
// ......................................................................
inline
G4double G4ChordFinder::GetLastStepEstimateUnc()
{
return fLastStepEstimate_Unconstrained;
}
inline
void G4ChordFinder::SetLastStepEstimateUnc( G4double stepEst )
{
fLastStepEstimate_Unconstrained = stepEst;
}
inline
void G4ChordFinder::ResetStepEstimate()
{
fLastStepEstimate_Unconstrained = DBL_MAX;
{
fIntgrDriver->OnStartTracking();
}
// ......................................................................
inline G4int G4ChordFinder::GetNoCalls() { return fNoCalls_FNC; }
inline G4int G4ChordFinder::GetNoTrials() { return fTotalNoTrials_FNC; }
inline G4int G4ChordFinder::GetNoMaxTrials() { return fmaxTrials_FNC; }
inline G4double G4ChordFinder::GetFirstFraction() { return fFirstFraction; }
inline G4double G4ChordFinder::GetFractionLast() { return fFractionLast; }
inline G4double G4ChordFinder::GetFractionNextEstimate()
{ return fFractionNextEstimate; }
inline G4double G4ChordFinder::GetMultipleRadius()
{ return fMultipleRadius; }
inline void G4ChordFinder::SetFirstFraction(G4double val){ fFirstFraction=val; }
inline G4int G4ChordFinder::SetVerbose( G4int newvalue )
{
G4int oldval= fStatsVerbose;
@@ -98,21 +66,6 @@ inline G4int G4ChordFinder::SetVerbose( G4int newvalue )
return oldval;
}
inline
void G4ChordFinder::AccumulateStatistics( G4int noTrials )
{
// Statistics
fTotalNoTrials_FNC += noTrials;
fNoCalls_FNC++;
// if( noTrials >= fmaxTrials_FNC ){
if (noTrials > fmaxTrials_FNC ) {
fmaxTrials_FNC=noTrials;
// fnoTimesMaxTrFNC=0;
} else {
// fnoTimesMaxTrFNC++;
}
// }
}
// A member that calculates the inverse parabolic through
// the three points (x,y) and returns the value x that, for the
// inverse parabolic, corresponds to y=0.
@@ -129,3 +82,19 @@ inline G4double G4ChordFinder::InvParabolic ( const G4double xa, const G4double
const G4double P = S*(T*(R-T)*(xc-xb) - (1-R)*(xb-xa));
return xb + P/Q;
}
inline
G4double G4ChordFinder::AdvanceChordLimited(G4FieldTrack& yCurrent,
G4double stepInitial,
G4double epsStep_Relative,
const G4ThreeVector& /*latestSafetyOrigin*/,
G4double /*lasestSafetyRadius*/)
{
return fIntgrDriver->AdvanceChordLimited(yCurrent, stepInitial, epsStep_Relative, fDeltaChord);
}
inline
void G4ChordFinder::OnComputeStep()
{
fIntgrDriver->OnComputeStep();
}
@@ -0,0 +1,113 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
//
//
// class G4ChordFinderDelegate
//
// Class description:
//
// Implementation of common algorithm of finding step size
// with distance to chord less then provided value.
// History:
// - Created. D.Sorokin
// --------------------------------------------------------------------
#ifndef G4CHORD_FINDER_DELEGATE_HH
#define G4CHORD_FINDER_DELEGATE_HH
#include "G4VIntegrationDriver.hh"
template <class Driver>
class G4ChordFinderDelegate {
public:
virtual ~G4ChordFinderDelegate();
G4double AdvanceChordLimitedImpl(G4FieldTrack& track,
G4double hstep,
G4double eps,
G4double chordDistance);
void ResetStepEstimate();
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);
private:
Driver& GetDriver();
G4double FindNextChord(const G4FieldTrack& yStart,
G4double stepMax,
G4double epsStep,
G4double chordDistance,
G4FieldTrack& yEnd, // Endpoint
G4double& dyErrPos, // Error of endpoint
G4double& pStepForAccuracy);
G4double NewStep(G4double stepTrialOld,
G4double dChordStep, // Curr. dchord achieved
G4double fDeltaChord,
G4double& stepEstimate_Unconstrained);
void AccumulateStatistics(G4int noTrials);
void PrintStatistics();
G4double fFirstFraction = 0.999;
G4double fFractionLast = 1.0;
G4double fFractionNextEstimate = 0.98;
G4double fLastStepEstimate_Unconstrained = DBL_MAX;
G4int fTotalNoTrials = 0;
G4int fNoCalls = 0;
G4int fmaxTrials = 0;
};
#include "G4ChordFinderDelegate.icc"
#endif
@@ -0,0 +1,397 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
//
//
// class G4ChordFinderDelegate
//
// Class description:
//
// Implementation of common algorithm of finding step size
// with distance to chord less then provided value.
// History:
// - Created. D.Sorokin
// --------------------------------------------------------------------
#include <iomanip>
template <class Driver>
G4ChordFinderDelegate<Driver>::~G4ChordFinderDelegate()
{
#ifdef G4VERBOSE
if (GetDriver().GetVerboseLevel() > 0)
{
PrintStatistics();
}
#endif
}
template <class Driver>
void G4ChordFinderDelegate<Driver>::ResetStepEstimate()
{
fLastStepEstimate_Unconstrained = DBL_MAX;
}
template <class Driver>
Driver& G4ChordFinderDelegate<Driver>::GetDriver()
{
return static_cast<Driver&>(*this);
}
template <class Driver>
G4double G4ChordFinderDelegate<Driver>::
AdvanceChordLimitedImpl(G4FieldTrack& yCurrent, G4double stepMax,
G4double epsStep, G4double chordDistance)
{
G4double dyErr;
G4FieldTrack yEnd = yCurrent;
G4double nextStep;
const G4double stepPossible = FindNextChord(yCurrent, stepMax, epsStep, chordDistance, yEnd, dyErr, nextStep);
if (dyErr < epsStep * stepPossible)
{
// Accept this accuracy.
yCurrent = yEnd;
return stepPossible;
}
// Advance more accurately to "end of chord"
const G4double startCurveLen = yCurrent.GetCurveLength();
const G4bool goodAdvance = GetDriver().AccurateAdvance(yCurrent, stepPossible, epsStep, nextStep);
return goodAdvance ? stepPossible : yCurrent.GetCurveLength() - startCurveLen;
}
// Returns Length of Step taken
template <class T>
G4double G4ChordFinderDelegate<T>::
FindNextChord(const G4FieldTrack& yStart,
G4double stepMax,
G4double epsStep,
G4double chordDistance,
G4FieldTrack& yEnd, // Endpoint
G4double& dyErrPos, // Error of endpoint
G4double& stepForAccuracy)
{
// 1.) Try to "leap" to end of interval
// 2.) Evaluate if resulting chord gives d_chord that is good enough.
// 2a.) If d_chord is not good enough, find one that is.
G4double dydx[G4FieldTrack::ncompSVEC];
G4double field[G4Field::MAX_NUMBER_OF_COMPONENTS];
G4bool validEndPoint = false;
G4double dChordStep, lastStepLength;
GetDriver().GetDerivatives(yStart, dydx, field);
const G4double inverseRadius = GetDriver().GetInverseCurvatureRadius(yStart, field);
const G4double safetyFactor = fFirstFraction; // 0.975 or 0.99 ? was 0.999
G4double stepTrial = std::min(stepMax, safetyFactor * fLastStepEstimate_Unconstrained);
G4double newStepEst_Uncons = 0.0;
G4double stepForChord;
G4int noTrials = 1;
constexpr G4int maxTrials = 75; // Avoid endless loop for bad convergence
for (; noTrials < maxTrials; ++noTrials)
{
yEnd = yStart; // Always start from initial point
GetDriver().QuickAdvance(yEnd, dydx, stepTrial, inverseRadius, dChordStep, dyErrPos);
lastStepLength = stepTrial;
validEndPoint = dChordStep < chordDistance;
stepForChord = NewStep(stepTrial, dChordStep, chordDistance, newStepEst_Uncons);
if (validEndPoint)
{
break;
}
if (stepTrial <= 0.0)
{
stepTrial = stepForChord;
}
else if (stepForChord <= stepTrial)
{
// Reduce by a fraction, possibly up to 20%
stepTrial = std::min( stepForChord, fFractionLast * stepTrial);
}
else
{
stepTrial *= 0.1;
}
}
if (noTrials >= maxTrials)
{
std::ostringstream message;
message << "Exceeded maximum number of trials= " << maxTrials << G4endl
<< "Current sagita dist= " << dChordStep << G4endl
<< "Max sagita dist= " << chordDistance << G4endl
<< "Step sizes (actual and proposed): " << G4endl
<< "Last trial = " << lastStepLength << G4endl
<< "Next trial = " << stepTrial << G4endl
<< "Proposed for chord = " << stepForChord << G4endl;
G4Exception("G4ChordFinder::FindNextChord()", "GeomField0003",
JustWarning, message);
}
if (newStepEst_Uncons > 0.0)
{
fLastStepEstimate_Unconstrained = newStepEst_Uncons;
}
AccumulateStatistics(noTrials);
// Calculate the step size required for accuracy, if it is needed
G4double dyErr_relative = dyErrPos / (epsStep * lastStepLength);
stepForAccuracy = dyErr_relative > 1 ?
GetDriver().ComputeNewStepSize(dyErr_relative, lastStepLength) : 0;
return stepTrial;
}
// Is called to estimate the next step size, even for successful steps,
// in order to predict an accurate 'chord-sensitive' first step
// which is likely to assist in more performant 'stepping'.
template <class T>
G4double G4ChordFinderDelegate<T>::
NewStep(G4double stepTrialOld,
G4double dChordStep, // Curr. dchord achieved
G4double fDeltaChord,
G4double& stepEstimate_Unconstrained)
{
G4double stepTrial;
if (dChordStep > 0.0)
{
stepEstimate_Unconstrained =
stepTrialOld * std::sqrt(fDeltaChord / dChordStep);
stepTrial = fFractionNextEstimate * stepEstimate_Unconstrained;
}
else
{
// Should not update the Unconstrained Step estimate: incorrect!
stepTrial = stepTrialOld * 2.;
}
if (stepTrial <= 0.001 * stepTrialOld)
{
if (dChordStep > 1000.0 * fDeltaChord)
{
stepTrial = stepTrialOld * 0.03;
}
else
{
if (dChordStep > 100. * fDeltaChord)
{
stepTrial = stepTrialOld * 0.1;
}
else // Try halving the length until dChordStep OK
{
stepTrial = stepTrialOld * 0.5;
}
}
}
else if (stepTrial > 1000.0 * stepTrialOld)
{
stepTrial = 1000.0 * stepTrialOld;
}
if (stepTrial == 0.0)
{
stepTrial= 0.000001;
}
// A more sophisticated chord-finder could figure out a better
// stepTrial, from dChordStep and the required d_geometry
// e.g.
// Calculate R, r_helix (eg at orig point)
// if( stepTrial < 2 pi R )
// stepTrial = R arc_cos( 1 - fDeltaChord / r_helix )
// else
// ??
return stepTrial;
}
template <class T>
void G4ChordFinderDelegate<T>::AccumulateStatistics(G4int noTrials)
{
fTotalNoTrials += noTrials;
++fNoCalls;
if (noTrials > fmaxTrials)
{
fmaxTrials = noTrials;
}
}
template <class T>
void G4ChordFinderDelegate<T>::PrintStatistics()
{
// Print Statistics
G4cout << "G4ChordFinder statistics report: \n"
<< " No trials: " << fTotalNoTrials
<< " No Calls: " << fNoCalls
<< " Max-trial: " << fmaxTrials << "\n"
<< " Parameters: "
<< " fFirstFraction " << fFirstFraction
<< " fFractionLast " << fFractionLast
<< " fFractionNextEstimate " << fFractionNextEstimate
<< G4endl;
}
template <class T>
G4int G4ChordFinderDelegate<T>::GetNoCalls()
{
return fNoCalls;
}
template <class T>
G4int G4ChordFinderDelegate<T>::GetNoTrials()
{
return fTotalNoTrials;
}
template <class T>
G4int G4ChordFinderDelegate<T>::GetNoMaxTrials()
{
return fmaxTrials;
}
template <class T>
void G4ChordFinderDelegate<T>::SetFractions_Last_Next(G4double fractLast,
G4double fractNext)
{
// Use -1.0 as request for Default.
if (fractLast == -1.0) fractLast = 1.0; // 0.9;
if (fractNext == -1.0) fractNext = 0.98; // 0.9;
// fFirstFraction = 0.999; // Orig 0.999 A safe value, range: ~ 0.95 - 0.999
if (GetDriver().GetVerboseLevel() > 0)
{
G4cout << " ChordFnd> Trying to set fractions: "
<< " first " << fFirstFraction
<< " last " << fractLast
<< " next " << fractNext
<< G4endl;
}
if (fractLast > 0 && fractLast <= 1)
{
fFractionLast = fractLast;
} else
{
std::ostringstream message;
message << "Invalid fraction Last = " << fractLast
<< "; must be 0 < fractionLast <= 1 ";
G4Exception("G4ChordFinderDelegate::SetFractions_Last_Next()",
"GeomField1001", JustWarning, message);
}
if (fractNext > 0. && fractNext < 1)
{
fFractionNextEstimate = fractNext;
} else
{
std::ostringstream message;
message << "Invalid fraction Next = " << fractNext
<< "; must be 0 < fractionNext < 1 ";
G4Exception("G4ChordFinderDelegate::SetFractions_Last_Next()",
"GeomField1001", JustWarning, message);
}
}
template <class T>
void G4ChordFinderDelegate<T>::SetFirstFraction(G4double fractFirst)
{
fFirstFraction = fractFirst;
}
template <class T>
G4double G4ChordFinderDelegate<T>::GetFirstFraction()
{
return fFirstFraction;
}
template <class T>
G4double G4ChordFinderDelegate<T>::GetFractionLast()
{
return fFractionLast;
}
template <class T>
G4double G4ChordFinderDelegate<T>::GetFractionNextEstimate()
{
return fFractionNextEstimate;
}
template <class T>
G4double G4ChordFinderDelegate<T>::GetLastStepEstimateUnc()
{
return fLastStepEstimate_Unconstrained;
}
template <class T>
void G4ChordFinderDelegate<T>::SetLastStepEstimateUnc(G4double stepEst)
{
fLastStepEstimate_Unconstrained = stepEst;
}
template <class T>
void G4ChordFinderDelegate<T>::TestChordPrint(G4int noTrials,
G4int lastStepTrial,
G4double dChordStep,
G4double fDeltaChord,
G4double nextStepTrial)
{
G4int oldprec= G4cout.precision(5);
G4cout << " ChF/fnc: notrial " << std::setw( 3) << noTrials
<< " this_step= " << std::setw(10) << lastStepTrial;
if( std::fabs( (dChordStep / fDeltaChord) - 1.0 ) < 0.001 )
{
G4cout.precision(8);
}
else
{
G4cout.precision(6);
}
G4cout << " dChordStep= " << std::setw(12) << dChordStep;
if( dChordStep > fDeltaChord ) { G4cout << " d+"; }
else { G4cout << " d-"; }
G4cout.precision(5);
G4cout << " new_step= " << std::setw(10)
<< fLastStepEstimate_Unconstrained
<< " new_step_constr= " << std::setw(10)
<< lastStepTrial << G4endl;
G4cout << " nextStepTrial = " << std::setw(10) << nextStepTrial << G4endl;
G4cout.precision(oldprec);
}
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ClassicalRK4.hh 101384 2016-11-16 11:03:44Z gcosmo $
//
//
// class G4ClassicalRK4
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ConstRK4.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
//
// Class G4ConstRK4
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4DELPHIMagField.hh 96751 2016-05-04 09:39:38Z gcosmo $
//
//
// class G4DELPHIMagField
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4DormandPrince745.hh 97387 2016-06-02 10:03:42Z gcosmo $
//
// Class desription:
// An implementation of the 5th order embedded RK method from the paper
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ElectricField.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
//
// class G4ElectricField
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ElectroMagneticField.hh 68055 2013-03-13 14:43:28Z gcosmo $
//
//
// class G4ElectroMagneticField
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4EqEMFieldWithEDM.hh 69699 2013-05-13 08:50:30Z gcosmo $
//
//
// class G4EqEMFieldWithEDM
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4EqEMFieldWithSpin.hh 69699 2013-05-13 08:50:30Z gcosmo $
//
//
// class G4EqEMFieldWithSpin
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4EqMagElectricField.hh 69699 2013-05-13 08:50:30Z gcosmo $
//
//
// class G4EqMagElectricField
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4EquationOfMotion.hh 71664 2013-06-20 08:36:05Z gcosmo $
//
//
// class G4EquationOfMotion
@@ -89,12 +88,10 @@ class G4EquationOfMotion
// Not protected, because G4RKG3_Stepper uses it directly.
const G4Field* GetFieldObj() const;
G4Field* GetFieldObj();
void SetFieldObj(G4Field* pField);
private:
// const int G4maximum_number_of_field_components = 24;
enum { G4maximum_number_of_field_components = 24 } ;
G4Field *itsField;
};
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4EquationOfMotion.icc 66356 2012-12-18 09:02:32Z gcosmo $
//
//
// Inline implementation
@@ -33,44 +32,47 @@
inline
G4EquationOfMotion::G4EquationOfMotion(G4Field* pField)
:itsField(pField)
: itsField(pField)
{}
inline
const G4Field* G4EquationOfMotion::GetFieldObj() const
{
return itsField;
return itsField;
}
inline
G4Field* G4EquationOfMotion::GetFieldObj()
{
return itsField;
}
inline
void G4EquationOfMotion::SetFieldObj(G4Field* pField)
{
itsField= pField;
itsField = pField;
}
inline
void G4EquationOfMotion::GetFieldValue( const G4double Point[4],
G4double Field[] ) const
void G4EquationOfMotion::GetFieldValue(const G4double Point[4], G4double Field[]) const
{
itsField-> GetFieldValue( Point, Field );
itsField->GetFieldValue(Point, Field);
}
inline
void
G4EquationOfMotion::RightHandSide( const G4double y[],
G4double dydx[] ) const
void G4EquationOfMotion::RightHandSide(const G4double y[], G4double dydx[]) const
{
G4double Field[G4maximum_number_of_field_components];
G4double PositionAndTime[4];
G4double Field[G4Field::MAX_NUMBER_OF_COMPONENTS];
G4double PositionAndTime[4];
// Position
PositionAndTime[0] = y[0];
PositionAndTime[1] = y[1];
PositionAndTime[2] = y[2];
// Global Time
PositionAndTime[3] = y[7]; // See G4FieldTrack::LoadFromArray
// Position
PositionAndTime[0] = y[0];
PositionAndTime[1] = y[1];
PositionAndTime[2] = y[2];
// Global Time
PositionAndTime[3] = y[7]; // See G4FieldTrack::LoadFromArray
GetFieldValue(PositionAndTime, Field) ;
EvaluateRhsGivenB( y, Field, dydx );
GetFieldValue(PositionAndTime, Field);
EvaluateRhsGivenB(y, Field, dydx);
}
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ErrorMag_UsualEqRhs.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
//
// --------------------------------------------------------------------
@@ -23,7 +23,6 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4ExactHelixStepper.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
//
// class G4ExactHelixStepper
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4ExplicitEuler.hh 66356 2012-12-18 09:02:32Z gcosmo $
//
//
// class G4ExplicitEuler
@@ -30,7 +30,6 @@
//
// First version: 25 May 2015
//
// $ID: FDormandPrince745.hh $
//
// History
// ----------------------------------------------------
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4FSALIntegrationDriver.hh 109569 2018-05-02 07:08:33Z gcosmo $
//
//
// class G4FSALIntegrationDriver
@@ -32,7 +31,7 @@
// Class description:
//
// Driver class which controls the integration error of a
// Runge-Kutta stepper with a FSAL property
// Runge-Kutta stepper
// History:
// - Created. D.Sorokin
@@ -41,24 +40,38 @@
#ifndef G4FSALIntegrationDriver_HH
#define G4FSALIntegrationDriver_HH
#include "G4Types.hh"
#include "G4FieldTrack.hh"
#include "G4VIntegrationDriver.hh"
#include "G4RKIntegrationDriver.hh"
#include "G4ChordFinderDelegate.hh"
template <class T>
class G4FSALIntegrationDriver : public G4VIntegrationDriver {
class G4FSALIntegrationDriver : public G4RKIntegrationDriver<T> ,
public G4ChordFinderDelegate<G4FSALIntegrationDriver<T>> {
public:
G4FSALIntegrationDriver(
G4double hminimum,
T* stepper,
G4int numberOfComponents = 6,
G4int statisticsVerbosity = 1);
G4FSALIntegrationDriver( G4double hminimum,
T* stepper,
G4int numberOfComponents = 6,
G4int statisticsVerbosity = 1);
virtual ~G4FSALIntegrationDriver() override;
G4FSALIntegrationDriver(const G4FSALIntegrationDriver &) = delete;
const G4FSALIntegrationDriver& operator =(const G4FSALIntegrationDriver &) = 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() 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.
@@ -73,115 +86,59 @@ public:
G4FieldTrack& fieldTrack,
const G4double dydx[],
G4double hstep,
G4double inverseCurvatureRadius,
G4double& dchord_step,
G4double& dyerr) override;
virtual void GetDerivatives(
const G4FieldTrack &track,
G4double dydx[]) const override;
// 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.
virtual G4double ComputeNewStepSize(
G4double errMaxNorm, // normalised error
G4double hstepCurrent) override; // current step size
virtual void SetVerboseLevel(G4int newLevel) override;
virtual G4int GetVerboseLevel() const override;
virtual G4EquationOfMotion* GetEquationOfMotion() override;
virtual void SetEquationOfMotion(G4EquationOfMotion* equation) override;
virtual const G4MagIntegratorStepper* GetStepper() const override;
virtual G4MagIntegratorStepper* GetStepper() override;
const T* GetStepperOfPreciseType() const; // Get ptr of precise type
T* GetStepperOfPreciseType();
// Accessors.
G4double GetMinimumStep() const;
G4double GetSafety() const;
G4double GetPshrnk() const;
G4double GetPgrow() const;
virtual void RenewStepperAndAdjust(G4MagIntegratorStepper *pItsStepper) override;
// Sets a new stepper pItsStepper for this driver. Then it calls
// ReSetParameters to reset its parameters accordingly.
inline void RenewStepperAndAdjustStrict(T *pItsStepper);
// i) sets the exponents (pgrow & pshrnk),
// using the current Stepper's order,
// ii) sets the safety
void ReSetParameters(G4double safety = 0.9);
void SetMinimumStep(G4double newval);
void SetSafety(G4double valS);
// This takes one Step that is as large as possible while
// satisfying the accuracy criterion of:
// yerr < eps * |y_end-y_start|
void OneGoodStep(
G4double ystart[],
G4double dydx[],
G4double& curveLength,
G4double htry,
G4double eps,
G4double& hdid,
G4double& hnext);
// Modify and Get the Maximum number of Steps that can be
// taken for the integration of a single segment -
// (ie a single call to AccurateAdvance).
G4int GetMaxNoSteps() const;
void SetMaxNoSteps( G4int val);
// 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|
void OneGoodStep(G4double y[], // InOut
G4double dydx[],
G4double& curveLength,
G4double htry,
G4double eps,
G4double& hdid,
G4double& hnext);
G4double GetSmallestFraction() const;
void SetSmallestFraction(G4double val);
protected:
void IncrementQuickAdvanceCalls();
private:
G4double ShrinkStepSize(G4double h, G4double error) const;
G4double GrowStepSize(G4double h, G4double error) const;
void UpdateErrorConstraints();
void CheckStep(const G4ThreeVector& posIn,
const G4ThreeVector& posOut,
G4double hdid);
void CheckStep(
const G4ThreeVector& posIn, const G4ThreeVector& posOut, G4double hdid);
// Minimum Step allowed in a Step (in absolute units)
G4double fMinimumStep;
// Minimum Step allowed in a Step (in absolute units)
G4double fMinimumStep;
// Smallest fraction of (existing) curve length - in relative units
// below this fraction the current step will be the last
G4double fSmallestFraction;
// Expected range: smaller than 0.1 * epsilon and bigger than 5e-13
// ( Note: this range is not enforced. )
// Smallest fraction of (existing) curve length - in relative units
// below this fraction the current step will be the last
// Expected range 1e-12 to 5e-15;
G4double fSmallestFraction;
// Verbosity level for printing (debug, ..)
// Could be varied during tracking - to help identify issues
G4int fVerboseLevel;
G4int fMaxNoSteps;
G4int fNoQuickAvanceCalls;
G4int fNoAccurateAdvanceCalls;
G4int fNoAccurateAdvanceBadSteps;
G4int fNoAccurateAdvanceGoodSteps;
// The (default) maximum number of steps is Base
// divided by the order of Stepper
G4int fMaxStepBase;
// Parameters used to grow and shrink trial stepsize.
G4double safety;
G4double pshrnk; // exponent for shrinking
G4double pgrow; // exponent for growth
// muximum error values for shrinking / growing (optimisation).
G4double errorConstraintShrink;
G4double errorConstraintGrow;
T* pIntStepper;
// Step Statistics
unsigned long fNoTotalSteps, fNoBadSteps, fNoGoodSteps;
G4int fVerboseLevel; // Verbosity level for printing (debug, ..)
// Could be varied during tracking - to help identify issues
G4int fNoQuickAvanceCalls;
using Base = G4RKIntegrationDriver<T>;
using ChordFinderDelegate = G4ChordFinderDelegate<G4FSALIntegrationDriver<T>>;
};
#include "G4FSALIntegrationDriver.icc"
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4FSALIntegrationDriver.icc 110753 2018-06-12 15:44:03Z gcosmo $
//
//
// class G4FSALIntegrationDriver
@@ -38,26 +37,23 @@
// - Created. D.Sorokin
// --------------------------------------------------------------------
#include "globals.hh"
#include "G4GeometryTolerance.hh"
#include "G4FieldTrack.hh"
#include "G4FieldUtils.hh"
#include <cassert>
template <class T>
G4FSALIntegrationDriver<T>::
G4FSALIntegrationDriver ( G4double hminimum, T* pStepper,
G4int numComponents, G4int statisticsVerbose )
: fSmallestFraction(1e-12),
fNoTotalSteps(0),
fNoBadSteps(0),
fNoGoodSteps(0),
: Base(pStepper),
fMinimumStep(hminimum),
fSmallestFraction(1e-12),
fVerboseLevel(statisticsVerbose),
fNoQuickAvanceCalls(0)
fNoQuickAvanceCalls(0),
fNoAccurateAdvanceCalls(0),
fNoAccurateAdvanceBadSteps(0),
fNoAccurateAdvanceGoodSteps(0)
{
if (numComponents != pStepper->GetNumberOfVariables())
if (numComponents != Base::GetStepper()->GetNumberOfVariables())
{
std::ostringstream message;
message << "Driver's number of integrated components "
@@ -67,10 +63,6 @@ G4FSALIntegrationDriver ( G4double hminimum, T* pStepper,
G4Exception("G4FSALIntegrationDriver","GeomField0002",
FatalException, message);
}
RenewStepperAndAdjust(pStepper);
fMinimumStep = hminimum;
fMaxStepBase = 250;
fMaxNoSteps = fMaxStepBase / pIntStepper->IntegratorOrder();
}
template <class T>
@@ -80,7 +72,9 @@ G4FSALIntegrationDriver<T>::~G4FSALIntegrationDriver()
if( fVerboseLevel > 0 )
G4cout << "G4FSALIntegration Driver Stats: "
<< "#QuickAdvance " << fNoQuickAvanceCalls
<< " - #AccurateAdvance " << fNoTotalSteps << G4endl;
<< " - #AccurateAdvance " << fNoAccurateAdvanceCalls << G4endl
<< "#good steps " << fNoAccurateAdvanceGoodSteps << " "
<< "#bad steps " << fNoAccurateAdvanceBadSteps << G4endl;
#endif
}
@@ -94,19 +88,20 @@ G4bool G4FSALIntegrationDriver<T>::
AccurateAdvance( G4FieldTrack& track, G4double hstep,
G4double eps, G4double hinitial )
{
++fNoAccurateAdvanceCalls;
if (hstep < GetMinimumStep())
{
G4double dchord_step = 0, dyerr = 0;
G4double dydx[G4FieldTrack::ncompSVEC];
GetDerivatives(track, dydx);
return QuickAdvance(track, dydx, hstep, dchord_step, dyerr);
Base::GetDerivatives(track, dydx);
return QuickAdvance(track, dydx, hstep, Base::UNKNOWN_CURVATURE_RADIUS, dchord_step, dyerr);
}
G4bool succeeded = false;
G4double hnext, hdid;
G4double y[G4FieldTrack::ncompSVEC], dydx[G4FieldTrack::ncompSVEC];
track.DumpToArray(y);
@@ -122,9 +117,9 @@ AccurateAdvance( G4FieldTrack& track, G4double hstep,
h = hinitial;
}
pIntStepper->RightHandSide(y, dydx);
Base::GetStepper()->RightHandSide(y, dydx);
for (G4int iter = 0; iter < fMaxNoSteps; ++iter)
for (G4int iter = 0; iter < Base::GetMaxNoSteps(); ++iter)
{
const G4ThreeVector StartPos =
field_utils::makeVector(y, field_utils::Value3D::Position);
@@ -148,36 +143,13 @@ AccurateAdvance( G4FieldTrack& track, G4double hstep,
if (succeeded)
{
track.LoadFromArray(y, pIntStepper->GetNumberOfVariables());
track.LoadFromArray(y, Base::GetStepper()->GetNumberOfVariables());
track.SetCurveLength(track.GetCurveLength() + curveLength);
}
return succeeded;
}
// Step failed; compute the size of retrial Step.
template <class T>
G4double G4FSALIntegrationDriver<T>::
ShrinkStepSize(G4double h, G4double error) const
{
if (error > errorConstraintShrink)
{
return max_stepping_decrease * h;
}
return GetSafety() * h * std::pow(error, GetPshrnk());
}
// Compute size of next Step
template<class T>
G4double G4FSALIntegrationDriver<T>::
GrowStepSize(G4double h, G4double error) const
{
if (error < errorConstraintGrow) {
return max_stepping_increase * h;
}
return GetSafety() * h * std::pow(error, GetPgrow());
}
// 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
@@ -193,13 +165,15 @@ GrowStepSize(G4double h, G4double error) const
//
template <class T>
void G4FSALIntegrationDriver<T>::
OneGoodStep( G4double y[], G4double dydx[],
G4double& curveLength, // InOut
G4double htry, G4double eps_rel_max,
G4double& hdid, // Out
G4double& hnext ) // Out
OneGoodStep(G4double y[],
G4double dydx[],
G4double& curveLength, // InOut
G4double htry,
G4double eps_rel_max,
G4double& hdid, // Out
G4double& hnext) // Out
{
G4double error = DBL_MAX;
G4double error2 = DBL_MAX;
G4double yError[G4FieldTrack::ncompSVEC],
yOut[G4FieldTrack::ncompSVEC],
@@ -215,19 +189,19 @@ OneGoodStep( G4double y[], G4double dydx[],
{
++tot_no_trials;
pIntStepper->Stepper(y, dydx, hstep, yOut, yError, dydxOut);
error = field_utils::relativeError(y, yError, hstep, eps_rel_max);
Base::GetStepper()->Stepper(y, dydx, hstep, yOut, yError, dydxOut);
error2 = field_utils::relativeError2(y, yError, hstep, eps_rel_max);
// Step succeeded.
if (error <= 1) break;
if (error2 <= 1) break;
hstep = ShrinkStepSize(hstep, error);
hstep = Base::ShrinkStepSize2(hstep, error2);
}
hnext = GrowStepSize(hstep, error);
hnext = Base::GrowStepSize2(hstep, error2);
curveLength += (hdid = hstep);
for(G4int k = 0; k < pIntStepper->GetNumberOfVariables(); ++k)
for(G4int k = 0; k < Base::GetStepper()->GetNumberOfVariables(); ++k)
{
y[k] = yOut[k];
dydx[k] = dydxOut[k];
@@ -237,7 +211,8 @@ OneGoodStep( G4double y[], G4double dydx[],
template <class T>
G4bool G4FSALIntegrationDriver<T>::
QuickAdvance( G4FieldTrack& fieldTrack, const G4double dydxIn[],
G4double hstep, G4double& dchord_step, G4double& dyerr )
G4double hstep, G4double /*inverseCurvatureRadius*/,
G4double& dchord_step, G4double& dyerr )
{
++fNoQuickAvanceCalls;
@@ -268,37 +243,17 @@ QuickAdvance( G4FieldTrack& fieldTrack, const G4double dydxIn[],
fieldTrack.DumpToArray(yIn);
pIntStepper->Stepper(yIn, dydxIn, hstep, yOut, yError, dydxOut);
dchord_step = pIntStepper->DistChord();
Base::GetStepper()->Stepper(yIn, dydxIn, hstep, yOut, yError, dydxOut);
dchord_step = Base::GetStepper()->DistChord();
fieldTrack.LoadFromArray(yOut, pIntStepper->GetNumberOfVariables());
fieldTrack.LoadFromArray(yOut, Base::GetStepper()->GetNumberOfVariables());
fieldTrack.SetCurveLength(fieldTrack.GetCurveLength() + hstep);
dyerr = field_utils::relativeError(yOut, yError, hstep) * hstep;
dyerr = field_utils::absoluteError(yOut, yError, hstep);
return true;
}
template <class T>
G4double G4FSALIntegrationDriver<T>::
ComputeNewStepSize( G4double errMaxNorm, // max error (normalised)
G4double hstepCurrent ) // current step size
{
if (errMaxNorm > 1)
{
return ShrinkStepSize(hstepCurrent, errMaxNorm);
}
else if(errMaxNorm >= 0)
{
return GrowStepSize(hstepCurrent, errMaxNorm);
}
G4Exception("G4FSALIntegrationDriver::ConputeNewStepSize", "GeomField0003",
FatalException, "Error is negative!");
return max_stepping_increase * hstepCurrent;
}
template <class T>
void G4FSALIntegrationDriver<T>::SetSmallestFraction(G4double newFraction)
{
@@ -317,25 +272,14 @@ void G4FSALIntegrationDriver<T>::SetSmallestFraction(G4double newFraction)
}
}
template <class T>
void G4FSALIntegrationDriver<T>::GetDerivatives(
const G4FieldTrack& track, G4double dydx[]) const
{
G4double y[G4FieldTrack::ncompSVEC];
track.DumpToArray(y);
pIntStepper->RightHandSide(y, dydx);
}
template <class T>
void G4FSALIntegrationDriver<T>::CheckStep(
const G4ThreeVector& posIn, const G4ThreeVector& posOut, G4double hdid)
{
++fNoTotalSteps;
const G4double endPointDist = (posOut - posIn).mag();
if (endPointDist >= hdid * (1. + perMillion))
{
++fNoBadSteps;
++fNoAccurateAdvanceBadSteps;
#ifdef G4DEBUG_FIELD
// Issue a warning only for gross differences -
// we understand how small difference occur.
@@ -349,127 +293,20 @@ void G4FSALIntegrationDriver<T>::CheckStep(
}
else
{
++fNoGoodSteps;
++fNoAccurateAdvanceGoodSteps;
}
}
template <class T>
void G4FSALIntegrationDriver<T>::UpdateErrorConstraints()
{
errorConstraintShrink = std::pow(
max_stepping_decrease / GetSafety(), 1. / GetPshrnk());
errorConstraintGrow = std::pow(
max_stepping_increase / GetSafety(), 1. / GetPgrow());
}
template <class T>
inline G4double G4FSALIntegrationDriver<T>::GetMinimumStep() const
{
return fMinimumStep;
}
template <class T>
inline G4double G4FSALIntegrationDriver<T>::GetSafety() const
{
return safety;
}
template <class T>
inline G4double G4FSALIntegrationDriver<T>::GetPshrnk() const
{
return pshrnk;
}
template <class T>
G4double G4FSALIntegrationDriver<T>::GetPgrow() const
{
return pgrow;
}
template <class T>
void G4FSALIntegrationDriver<T>::SetMinimumStep(G4double minimumStepLength)
{
fMinimumStep = minimumStepLength;
}
template <class T>
void G4FSALIntegrationDriver<T>::ReSetParameters(G4double new_safety)
{
safety = new_safety;
pshrnk = -1.0 / pIntStepper->IntegratorOrder();
pgrow = -1.0 / (1.0 + pIntStepper->IntegratorOrder());
UpdateErrorConstraints();
}
template <class T>
void G4FSALIntegrationDriver<T>::SetSafety(G4double val)
{
safety = val;
UpdateErrorConstraints();
}
template <class T>
void G4FSALIntegrationDriver<T>::
RenewStepperAndAdjust(G4MagIntegratorStepper* stepper)
{
T* ourStepper= dynamic_cast<T*>(stepper);
if ( ourStepper )
{
RenewStepperAndAdjustStrict( ourStepper );
}
else
{
G4Exception("G4FSALIntegrationDriver::RenewStepperAndAdjust()",
"GeomField0002", FatalException,
"The type of the stepper provided is incorrect for this templated driver");
}
}
template <class T>
void G4FSALIntegrationDriver<T>::RenewStepperAndAdjustStrict(T* stepper)
{
pIntStepper = stepper;
ReSetParameters();
}
template <class T>
const T* G4FSALIntegrationDriver<T>::GetStepperOfPreciseType() const
{
return pIntStepper;
}
template <class T>
T* G4FSALIntegrationDriver<T>::GetStepperOfPreciseType()
{
return pIntStepper;
}
template <class T>
const G4MagIntegratorStepper* G4FSALIntegrationDriver<T>::GetStepper() const
{
return nullptr; // pIntStepper;
// It can only return 'pIntStepper' if it is a compatible type
}
template <class T>
G4MagIntegratorStepper* G4FSALIntegrationDriver<T>::GetStepper()
{
return nullptr;
// It can only return 'pIntStepper' if it is a compatible type
}
template <class T>
G4int G4FSALIntegrationDriver<T>::GetMaxNoSteps() const
{
return fMaxNoSteps;
}
template <class T>
void G4FSALIntegrationDriver<T>::SetMaxNoSteps(G4int val)
{
fMaxNoSteps = val;
}
template <class T>
@@ -488,17 +325,10 @@ template <class T>
G4double G4FSALIntegrationDriver<T>::GetSmallestFraction() const
{
return fSmallestFraction;
}
template <class T>
G4EquationOfMotion* G4FSALIntegrationDriver<T>::GetEquationOfMotion()
{
return pIntStepper->GetEquationOfMotion();
}
template <class T>
void G4FSALIntegrationDriver<T>::
SetEquationOfMotion(G4EquationOfMotion* equation)
void G4FSALIntegrationDriver<T>::IncrementQuickAdvanceCalls()
{
pIntStepper->SetEquationOfMotion(equation);
++fNoQuickAvanceCalls;
}
@@ -24,7 +24,6 @@
// ********************************************************************
//
//
// $Id: G4Field.hh 96751 2016-05-04 09:39:38Z gcosmo $
//
//
// class G4Field
@@ -66,6 +65,8 @@ class G4Field
{
public: // with description
static constexpr G4int MAX_NUMBER_OF_COMPONENTS = 24;
virtual void GetFieldValue( const double Point[4],
double *fieldArr ) const = 0;
// Given the position time vector 'Point',

Some files were not shown because too many files have changed in this diff Show More