Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4DNABrownianTransportation.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// Author: Mathieu Karamitros (kara (AT) cenbg . in2p3 . fr)
28//
29// WARNING : This class is released as a prototype.
30// It might strongly evolve or even disapear in the next releases.
31//
32// History:
33// -----------
34// 10 Oct 2011 M.Karamitros created
35//
36// -------------------------------------------------------------------
37
38/// \brief { The transportation method implemented is the one from
39/// Ermak-McCammon : J. Chem. Phys. 69, 1352 (1978)}
40
41#include <CLHEP/Random/Stat.h>
42
44
45#include <G4Scheduler.hh>
47#include "G4SystemOfUnits.hh"
48#include "Randomize.hh"
49#include "G4Molecule.hh"
50#include "G4RandomDirection.hh"
51#include "G4ParticleTable.hh"
52#include "G4SafetyHelper.hh"
54#include "G4UnitsTable.hh"
55#include "G4NistManager.hh"
57#include "G4ITNavigator.hh"
58#include "G4ITSafetyHelper.hh" // Not used yet
60
61using namespace std;
62
63#ifndef State
64#define State(theXInfo) (GetState<G4ITBrownianState>()->theXInfo)
65#endif
66
67//#ifndef State
68//#define State(theXInfo) (fTransportationState->theXInfo)
69//#endif
70
71//#define USE_COLOR 1
72
73#ifdef USE_COLOR
74#define RED "\033[0;31m"
75#define LIGHT_RED "\33[1;31m"
76#define GREEN "\033[32;40m"
77#define GREEN_ON_BLUE "\033[1;32;44m"
78#define RESET_COLOR "\033[0m"
79#else
80#define RED ""
81#define LIGHT_RED ""
82#define GREEN ""
83#define GREEN_ON_BLUE ""
84#define RESET_COLOR ""
85#endif
86
87//#define DEBUG_MEM 1
88
89#ifdef DEBUG_MEM
90#include "G4MemStat.hh"
91using namespace G4MemStat;
93#endif
94
95static double InvErf(double x)
96{
98}
99
100static double InvErfc(double x)
101{
102 return CLHEP::HepStat::inverseErf(1. - x);
103}
104
105//static double Erf(double x)
106//{
107// return CLHEP::HepStat::erf(x);
108//}
109
110static double Erfc(double x)
111{
112 return 1 - CLHEP::HepStat::erf(1. - x);
113}
114
115#ifndef State
116#define State(theXInfo) (GetState<G4ITTransportationState>()->theXInfo)
117#endif
118
120 G4int verbosity) :
121 G4ITTransportation(aName, verbosity)
122{
123
124 fVerboseLevel = 0;
125
126 fpState.reset(new G4ITBrownianState());
127
128 //ctor
130
132 fpWaterDensity = 0;
133
136 fSpeedMeUp = true;
137
138 fInternalMinTimeStep = 1*picosecond;
140}
141
143{
145}
146
148 G4ITTransportation(right)
149{
150 //copy ctor
155 fNistWater = right.fNistWater;
158 fSpeedMeUp = right.fSpeedMeUp;
160}
161
163{
164 if(this == &rhs) return *this; // handle self assignment
165 //assignment operator
166 return *this;
167}
168
171{
173 fTimeStepReachedLimit = false;
174 fComputeLastPosition = false;
175 fRandomNumber = -1;
176}
177
179{
180 fpState.reset(new G4ITBrownianState());
181// G4cout << "G4DNABrownianTransportation::StartTracking : "
182// "Initialised track State" << G4endl;
185}
186
188{
189 if(verboseLevel > 0)
190 {
191 G4cout << G4endl<< GetProcessName() << ": for "
192 << setw(24) << particle.GetParticleName()
193 << "\tSubType= " << GetProcessSubType() << G4endl;
194 }
195 // Initialize water density pointer
197 GetDensityTableFor(G4Material::GetMaterial("G4_WATER"));
198
201}
202
204 const G4Step& step,
205 const double timeStep,
206 double& spaceStep)
207{
208 // G4cout << "G4ITBrownianTransportation::ComputeStep" << G4endl;
209
210 /* If this method is called, this step
211 * cannot be geometry limited.
212 * In case the step is limited by the geometry,
213 * this method should not be called.
214 * The fTransportEndPosition calculated in
215 * the method AlongStepIL should be taken
216 * into account.
217 * In order to do so, the flag IsLeadingStep
218 * is on. Meaning : this track has the minimum
219 * interaction length over all others.
220 */
221 if(GetIT(track)->GetTrackingInfo()->IsLeadingStep())
222 {
223 const G4VITProcess* ITProc = ((const G4VITProcess*) step.GetPostStepPoint()
225 bool makeException = true;
226
227 if(ITProc && ITProc->ProposesTimeStep()) makeException = false;
228
229 if(makeException)
230 {
231
232 G4ExceptionDescription exceptionDescription;
233 exceptionDescription << "ComputeStep is called while the track has"
234 "the minimum interaction time";
235 exceptionDescription << " so it should not recompute a timeStep ";
236 G4Exception("G4DNABrownianTransportation::ComputeStep",
237 "G4DNABrownianTransportation001", FatalErrorInArgument,
238 exceptionDescription);
239 }
240 }
241
242 State(fGeometryLimitedStep) = false;
243
244 G4Molecule* molecule = GetMolecule(track);
245
246 if(timeStep > 0)
247 {
248 spaceStep = DBL_MAX;
249
250 // TODO : generalize this process to all kind of Brownian objects
251 G4double diffCoeff = molecule->GetDiffusionCoefficient(track.GetMaterial(),
252 track.GetMaterial()->GetTemperature());
253
254 static double sqrt_2 = sqrt(2.);
255 double sqrt_Dt = sqrt(diffCoeff*timeStep);
256 double sqrt_2Dt = sqrt_2*sqrt_Dt;
257
258 if(State(fTimeStepReachedLimit)== true)
259 {
260 //========================================================================
261 State(fGeometryLimitedStep) = true;// important
262 //========================================================================
263 spaceStep = State(fEndPointDistance);
264 // G4cout << "State(fTimeStepReachedLimit)== true" << G4endl;
265 }
266 else
267 {
268 G4double x = G4RandGauss::shoot(0,sqrt_2Dt);
269 G4double y = G4RandGauss::shoot(0,sqrt_2Dt);
270 G4double z = G4RandGauss::shoot(0,sqrt_2Dt);
271
272 spaceStep = sqrt(x*x + y*y + z*z);
273
274 if(spaceStep >= State(fEndPointDistance))
275 {
276 //G4cout << "spaceStep >= State(fEndPointDistance)" << G4endl;
277 //======================================================================
278 State(fGeometryLimitedStep) = true;// important
279 //======================================================================
280/*
281 if(fSpeedMeUp)
282 {
283 G4cout << "SpeedMeUp" << G4endl;
284 }
285 else
286*/
287 if(fUseSchedulerMinTimeSteps == false)// jump over barrier NOT used
288 {
289#ifdef G4VERBOSE
290 if (fVerboseLevel > 1)
291 {
293 << "G4ITBrownianTransportation::ComputeStep() : "
294 << "Step was limited to boundary"
295 << RESET_COLOR
296 << G4endl;
297 }
298#endif
299 //TODO
300 if(State(fRandomNumber)>=0) // CDF is used
301 {
302 /*
303 //=================================================================
304 State(fGeometryLimitedStep) = true;// important
305 //=================================================================
306 spaceStep = State(fEndPointDistance);
307 */
308
309 //==================================================================
310 // BE AWARE THAT THE TECHNIQUE USED BELOW IS A 1D APPROXIMATION
311 // Cumulative density function for the 3D case is not yet
312 // implemented
313 //==================================================================
314// G4cout << GREEN_ON_BLUE
315// << "G4ITBrownianTransportation::ComputeStep() : "
316// << "A random number was selected"
317// << RESET_COLOR
318// << G4endl;
319 double value = State(fRandomNumber)+(1-State(fRandomNumber))*G4UniformRand();
320 double invErfc = InvErfc(value);
321 spaceStep = invErfc*2*sqrt_Dt;
322
323 if(State(fTimeStepReachedLimit)== false)
324 {
325 //================================================================
326 State(fGeometryLimitedStep) = false;// important
327 //================================================================
328 }
329 //==================================================================
330 // DEBUG
331// if(spaceStep > State(fEndPointDistance))
332// {
333// G4cout << "value = " << value << G4endl;
334// G4cout << "invErfc = " << invErfc << G4endl;
335// G4cout << "spaceStep = " << G4BestUnit(spaceStep, "Length")
336// << G4endl;
337// G4cout << "end point distance= " << G4BestUnit(State(fEndPointDistance), "Length")
338// << G4endl;
339// }
340//
341// assert(spaceStep <= State(fEndPointDistance));
342 //==================================================================
343
344 }
345 else if(fUseMaximumTimeBeforeReachingBoundary == false) // CDF is used
346 {
347 double min_randomNumber = Erfc(State(fEndPointDistance)/2*sqrt_Dt);
348 double value = min_randomNumber+(1-min_randomNumber)*G4UniformRand();
349 double invErfc = InvErfc(value);
350 spaceStep = invErfc*2*sqrt_Dt;
351 if(spaceStep >= State(fEndPointDistance))
352 {
353 //================================================================
354 State(fGeometryLimitedStep) = true;// important
355 //================================================================
356 }
357 else if(State(fTimeStepReachedLimit)== false)
358 {
359 //================================================================
360 State(fGeometryLimitedStep) = false;// important
361 //================================================================
362 }
363 }
364 else // CDF is NOT used
365 {
366 //==================================================================
367 State(fGeometryLimitedStep) = true;// important
368 //==================================================================
369 spaceStep = State(fEndPointDistance);
370 //TODO
371
372 /*
373 //==================================================================
374 // 1D approximation to place the brownian between its starting point
375 // and the geometry boundary
376 //==================================================================
377 double min_randomNumber = Erfc(State(fEndPointDistance)/2*sqrt_Dt);
378 double value = State(fRandomNumber)+(1-State(fRandomNumber))*G4UniformRand();
379 double invErfc = InvErfc(value*G4UniformRand());
380 spaceStep = invErfc*2*sqrt_Dt;
381 State(fGeometryLimitedStep) = false;
382 */
383 }
384 }
385
386 State(fTransportEndPosition)= spaceStep*
387// step.GetPostStepPoint()->GetMomentumDirection()
389 + track.GetPosition();
390 }
391 else
392 {
393 //======================================================================
394 State(fGeometryLimitedStep) = false;// important
395 //======================================================================
396 State(fTransportEndPosition)= spaceStep*step.GetPostStepPoint()->
397 GetMomentumDirection() + track.GetPosition();
398 }
399 }
400 }
401 else
402 {
403 spaceStep = 0.;
404 State(fTransportEndPosition) = track.GetPosition();
405 State(fGeometryLimitedStep) = false;
406 }
407
408 State(fCandidateEndGlobalTime) = step.GetPreStepPoint()->GetGlobalTime()
409 + timeStep;
410 State(fEndGlobalTimeComputed) = true;
411
412#ifdef G4VERBOSE
413 // DEBUG
414 if (fVerboseLevel > 1)
415 {
417 << "G4ITBrownianTransportation::ComputeStep() : "
418 << " trackID : " << track.GetTrackID() << " : Molecule name: "
419 << molecule->GetName() << G4endl
420 << "Initial position:" << G4BestUnit(track.GetPosition(), "Length")
421 << G4endl
422 << "Initial direction:" << track.GetMomentumDirection() << G4endl
423 << "Final position:" << G4BestUnit(State(fTransportEndPosition), "Length")
424 << G4endl
425 << "Initial magnitude:" << G4BestUnit(track.GetPosition().mag(), "Length")
426 << G4endl
427 << "Final magnitude:" << G4BestUnit(State(fTransportEndPosition).mag(), "Length")
428 << G4endl
429 << "Diffusion length : "
430 << G4BestUnit(spaceStep, "Length")
431 << " within time step : " << G4BestUnit(timeStep,"Time")
432 << G4endl
433 << "State(fTimeStepReachedLimit)= " << State(fTimeStepReachedLimit) << G4endl
434 << "State(fGeometryLimitedStep)=" << State(fGeometryLimitedStep) << G4endl
435 << "End point distance was: " << G4BestUnit(State(fEndPointDistance), "Length")
436 << G4endl
437 << RESET_COLOR
438 << G4endl<< G4endl;
439 }
440#endif
441
442//==============================================================================
443// DEBUG
444//assert(spaceStep < State(fEndPointDistance)
445// || (spaceStep >= State(fEndPointDistance) && State(fGeometryLimitedStep)));
446//assert(track.GetMomentumDirection() == State(fTransportEndMomentumDir));
447//==============================================================================
448}
449
451 const G4Step& step)
452{
454
455#ifdef G4VERBOSE
456 // DEBUG
457 if (fVerboseLevel > 1)
458 {
459 G4cout << GREEN_ON_BLUE << "G4ITBrownianTransportation::PostStepDoIt() :"
460 << " trackID : " << track.GetTrackID() << " Molecule name: "
461 << GetMolecule(track)->GetName() << G4endl;
462 G4cout << "Diffusion length : "
463 << G4BestUnit(step.GetStepLength(), "Length")
464 <<" within time step : " << G4BestUnit(step.GetDeltaTime(),"Time")
465 << "\t Current global time : "
466 << G4BestUnit(track.GetGlobalTime(),"Time")
467 << RESET_COLOR
468 << G4endl<< G4endl;
469 }
470#endif
471 return &fParticleChange;
472}
473
475{
476
477#ifdef DEBUG_MEM
478 MemStat mem_first = MemoryUsage();
479#endif
480
481#ifdef G4VERBOSE
482 // DEBUG
483 if (fVerboseLevel > 1)
484 {
485 G4cout << GREEN_ON_BLUE << setw(18)
486 << "G4DNABrownianTransportation::Diffusion :" << setw(8)
487 << GetIT(track)->GetName() << "\t trackID:" << track.GetTrackID()
488 << "\t" << " Global Time = "
489 << G4BestUnit(track.GetGlobalTime(), "Time")
490 << RESET_COLOR
491 << G4endl
492 << G4endl;
493 }
494#endif
495
496/*
497 fParticleChange.ProposePosition(State(fTransportEndPosition));
498 //fParticleChange.ProposeEnergy(State(fTransportEndKineticEnergy));
499 fParticleChange.SetMomentumChanged(State(fMomentumChanged));
500
501 fParticleChange.ProposeGlobalTime(State(fCandidateEndGlobalTime));
502 fParticleChange.ProposeLocalTime(State(fCandidateEndGlobalTime));
503 fParticleChange.ProposeTrueStepLength(track.GetStepLength());
504*/
505 G4Material* material = track.GetMaterial();
506
507 G4double waterDensity = (*fpWaterDensity)[material->GetIndex()];
508
509 if (waterDensity == 0.0)
510 {
512 {
513 // Let the user Brownian action class decide what to do
516 return;
517 }
518 else
519 {
520#ifdef G4VERBOSE
521 if(fVerboseLevel)
522 {
523 G4cout << "A track is outside water material : trackID = "
524 << track.GetTrackID() << " (" << GetMolecule(track)->GetName() <<")"
525 << G4endl;
526 G4cout << "Local Time : " << G4BestUnit(track.GetGlobalTime(), "Time")
527 << G4endl;
528 G4cout << "Step Number :" << track.GetCurrentStepNumber() << G4endl;
529 }
530#endif
533 return;// &fParticleChange is the final returned object
534 }
535 }
536
537
538 #ifdef DEBUG_MEM
539 MemStat mem_intermediaire = MemoryUsage();
540 mem_diff = mem_intermediaire-mem_first;
541 G4cout << "\t\t\t >> || MEM || In G4DNABrownianTransportation::Diffusion "
542 "after dealing with waterDensity for "<< track.GetTrackID()
543 << ", diff is : " << mem_diff << G4endl;
544 #endif
545
547 State(fMomentumChanged) = true;
549 //
550 #ifdef DEBUG_MEM
551 mem_intermediaire = MemoryUsage();
552 mem_diff = mem_intermediaire-mem_first;
553 G4cout << "\t\t\t >> || MEM || In G4DNABrownianTransportation::"
554 "After proposing new direction to fParticleChange for "
555 << track.GetTrackID() << ", diff is : " << mem_diff << G4endl;
556 #endif
557
558 return;// &fParticleChange is the final returned object
559}
560
561// NOT USED
563 G4double& presafety,
564 G4double limit)
565{
566 G4double res = DBL_MAX;
567 if(track.GetVolume() != fpSafetyHelper->GetWorldVolume())
568 {
569 G4TrackStateManager& trackStateMan = GetIT(track)->GetTrackingInfo()
571 fpSafetyHelper->LoadTrackState(trackStateMan);
573 track.GetStep()->GetPreStepPoint()->GetPosition(),
574 track.GetMomentumDirection(),
575 limit, presafety);
577 }
578 return res;
579}
580
582 G4double previousStepSize,
583 G4double currentMinimumStep,
584 G4double& currentSafety,
585 G4GPILSelection* selection)
586{
587#ifdef G4VERBOSE
588 if(fVerboseLevel)
589 {
590 G4cout << " G4DNABrownianTransportation::AlongStepGetPhysicalInteractionLength - track ID: "
591 << track.GetTrackID() << G4endl;
592 G4cout << "In volume : " << track.GetVolume()->GetName()
593 << " position : " << G4BestUnit(track.GetPosition() , "Length") << G4endl;
594 }
595#endif
596
597 G4double geometryStepLength =
599 track, previousStepSize, currentMinimumStep, currentSafety,
600 selection);
601
602 if(geometryStepLength==0)
603 {
604// G4cout << "geometryStepLength==0" << G4endl;
605 if(State(fGeometryLimitedStep))
606 {
607// G4cout << "if(State(fGeometryLimitedStep))" << G4endl;
608 G4TouchableHandle newTouchable = new G4TouchableHistory;
609
610 newTouchable->UpdateYourself(State(fCurrentTouchableHandle)->GetVolume(),
611 State(fCurrentTouchableHandle)->GetHistory());
612
613 fLinearNavigator->SetGeometricallyLimitedStep();
614 fLinearNavigator->LocateGlobalPointAndUpdateTouchableHandle(
615 track.GetPosition(), track.GetMomentumDirection(),
616 newTouchable, true);
617
618 if(newTouchable->GetVolume() == 0)
619 {
620 return 0;
621 }
622
623 State(fCurrentTouchableHandle) = newTouchable;
624
625 //=======================================================================
626 // TODO: speed up navigation update
627// geometryStepLength = fLinearNavigator->ComputeStep(track.GetPosition(),
628// track.GetMomentumDirection(),
629// currentMinimumStep,
630// currentSafety);
631 //=======================================================================
632
633
634 //=======================================
635 // Longer but safer ...
636 geometryStepLength =
638 track, previousStepSize, currentMinimumStep, currentSafety,
639 selection);
640
641 }
642 }
643
644 //============================================================================
645 // DEBUG
646 // G4cout << "geometryStepLength: " << G4BestUnit(geometryStepLength, "Length")
647 // << " | trackID: " << track.GetTrackID()
648 // << G4endl;
649 //============================================================================
650
651 G4double diffusionCoefficient = 0;
652
653 /*
654 G4Material* material = track.GetMaterial();
655 G4double waterDensity = (*fpWaterDensity)[material->GetIndex()];
656
657 if (waterDensity == 0.0)
658 {
659 if(fpBrownianAction)
660 {
661 diffusionCoefficient = fpBrownianAction->GetDiffusionCoefficient(material,
662 GetMolecule(track));
663 }
664
665 if(diffusionCoefficient <= 0)
666 {
667 State(fGeometryLimitedStep) = false;
668 State(theInteractionTimeLeft) = 0;
669 State(fTransportEndPosition) = track.GetPosition();
670 return 0;
671 }
672
673 }
674 else
675 {
676 diffusionCoefficient = GetMolecule(track)->GetDiffusionCoefficient();
677 }
678 */
679
680 diffusionCoefficient = GetMolecule(track)->GetDiffusionCoefficient();
681
682 // To avoid divide by zero of diffusionCoefficient
683 if(diffusionCoefficient <= 0)
684 {
685 State(fGeometryLimitedStep) = false;
686 State(theInteractionTimeLeft) = DBL_MAX;
687 State(fTransportEndPosition) = track.GetPosition();
688 return 0;
689 }
690
691
692 State(fComputeLastPosition) = false;
693 State(fTimeStepReachedLimit) = false;
694
695 if (State(fGeometryLimitedStep))
696 {
697 // 95 % of the space step distribution is lower than
698 // d_95 = 2 * sqrt(2*D*t)
699 // where t is the corresponding time step
700 // so by inversion :
702 {
703 if(fSpeedMeUp)
704 {
705 State(theInteractionTimeLeft) = (geometryStepLength * geometryStepLength)
706 / (diffusionCoefficient); // d_50 - use straight line
707 }
708 else
709 {
710 State(theInteractionTimeLeft) = (currentSafety * currentSafety)
711 / (diffusionCoefficient); // d_50 - use safety
712
713 //=====================================================================
714 // State(theInteractionTimeLeft) = (currentSafety * currentSafety)
715 // / (8 * diffusionCoefficient); // d_95
716 //=====================================================================
717 }
718 State(fComputeLastPosition) = true;
719 }
720 else
721 // Will use a random time - this is precise but long to compute in certain
722 // circumstances (many particles - small volumes)
723 {
724 State(fRandomNumber) = G4UniformRand();
725 State(theInteractionTimeLeft) = 1 / (4 * diffusionCoefficient)
726 * pow(geometryStepLength / InvErfc(State(fRandomNumber)),2);
727
728 State(fTransportEndPosition) = geometryStepLength*
729 track.GetMomentumDirection() + track.GetPosition();
730 }
731
733 {
734 double minTimeStepAllowed = G4VScheduler::Instance()->GetLimitingTimeStep();
735 //========================================================================
736 // TODO
737// double currentMinTimeStep = G4VScheduler::Instance()->GetTimeStep();
738 //========================================================================
739
740 if (State(theInteractionTimeLeft) < minTimeStepAllowed)
741 {
742 State(theInteractionTimeLeft) = minTimeStepAllowed;
743 State(fTimeStepReachedLimit) = true;
744 State(fComputeLastPosition) = true;
745 }
746 }
747 else if(State(theInteractionTimeLeft) < fInternalMinTimeStep)
748 // TODO: find a better way when fForceLimitOnMinTimeSteps is not used
749 {
750 State(fTimeStepReachedLimit) = true;
751 State(theInteractionTimeLeft) = fInternalMinTimeStep;
753 {
754 State(fComputeLastPosition) = true;
755 }
756 }
757
758 State(fCandidateEndGlobalTime) =
759 track.GetGlobalTime() + State(theInteractionTimeLeft);
760
761 State(fEndGlobalTimeComputed) = true; // MK: ADDED ON 20/11/2014
762
763 State(fPathLengthWasCorrected) = false;
764 }
765 else
766 {
767 // Transform geometrical step
768 geometryStepLength = 2
769 * sqrt(diffusionCoefficient * State(theInteractionTimeLeft))
770 * InvErf(G4UniformRand());
771 State(fPathLengthWasCorrected) = true;
772 //State(fEndPointDistance) = geometryStepLength;
773 State(fTransportEndPosition) = geometryStepLength*
774 track.GetMomentumDirection() + track.GetPosition();
775 }
776
777#ifdef G4VERBOSE
778 // DEBUG
779 if (fVerboseLevel > 1)
780 {
782 << "G4DNABrownianTransportation::AlongStepGetPhysicalInteractionLength = "
783 << G4BestUnit(geometryStepLength, "Length")
784 << " | trackID = "
785 << track.GetTrackID()
786 << RESET_COLOR
787 << G4endl;
788 }
789#endif
790
791// assert(geometryStepLength < State(fEndPointDistance)
792// || (geometryStepLength >= State(fEndPointDistance) && State(fGeometryLimitedStep)));
793
794 return geometryStepLength;
795}
796
797//////////////////////////////////////////////////////////////////////////
798//
799// Initialize ParticleChange (by setting all its members equal
800// to corresponding members in G4Track)
803 const G4Step& step)
804{
805#ifdef DEBUG_MEM
806 MemStat mem_first, mem_second, mem_diff;
807#endif
808
809#ifdef DEBUG_MEM
810 mem_first = MemoryUsage();
811#endif
812
813 if (GetIT(track)->GetTrackingInfo()->IsLeadingStep()
814 && State(fComputeLastPosition))
815 {
816 //==========================================================================
817 // DEBUG
818 //
819// assert(fabs(State(theInteractionTimeLeft)-
820// G4VScheduler::Instance()->GetTimeStep()) < DBL_EPSILON);
821 //==========================================================================
822
823 double spaceStep = DBL_MAX;
824
825 if(State(theInteractionTimeLeft) <= fInternalMinTimeStep)
826 {
827 spaceStep = State(fEndPointDistance);
828 State(fGeometryLimitedStep) = true;
829 }
830 else
831 {
832 G4double diffusionCoefficient = GetMolecule(track)->
833 GetDiffusionCoefficient();
834
835 double sqrt_2Dt= sqrt(2 * diffusionCoefficient * State(theInteractionTimeLeft));
836 G4double x = G4RandGauss::shoot(0, sqrt_2Dt);
837 G4double y = G4RandGauss::shoot(0, sqrt_2Dt);
838 G4double z = G4RandGauss::shoot(0, sqrt_2Dt);
839
840 spaceStep = sqrt(x * x + y * y + z * z);
841
842 if(spaceStep >= State(fEndPointDistance))
843 {
844 State(fGeometryLimitedStep) = true;
845 if (
846 //fSpeedMeUp == false&&
848 && spaceStep >= State(fEndPointDistance))
849 {
850 spaceStep = State(fEndPointDistance);
851 }
852 }
853 else
854 {
855 State(fGeometryLimitedStep) = false;
856 }
857 }
858
859// assert( (spaceStep < State(fEndPointDistance) && State(fGeometryLimitedStep) == false)
860//|| (spaceStep >= State(fEndPointDistance) && State(fGeometryLimitedStep)));
861
862 // Calculate final position
863 //
864 State(fTransportEndPosition) = track.GetPosition()
865 + spaceStep * track.GetMomentumDirection();
866 }
867
868 if(fVerboseLevel)
869 {
871 << "G4DNABrownianTransportation::AlongStepDoIt: "
872 "GeometryLimitedStep = "
873 << State(fGeometryLimitedStep)
874 << RESET_COLOR
875 << G4endl;
876 }
877
878// static G4ThreadLocal G4int noCalls = 0;
879// noCalls++;
880
881// fParticleChange.Initialize(track);
882
884
885#ifdef DEBUG_MEM
886 MemStat mem_intermediaire = MemoryUsage();
887 mem_diff = mem_intermediaire-mem_first;
888 G4cout << "\t\t\t >> || MEM || After calling G4ITTransportation::"
889 "AlongStepDoIt for "<< track.GetTrackID() << ", diff is : "
890 << mem_diff << G4endl;
891#endif
892
893 if(track.GetStepLength() != 0 // && State(fGeometryLimitedStep)
894 //========================================================================
895 // TODO: avoid changing direction after too small time steps
896// && (G4VScheduler::Instance()->GetTimeStep() > fInternalMinTimeStep
897// || fSpeedMeUp == false)
898 //========================================================================
899 )
900 {
901 Diffusion(track);
902 }
903 //else
904 //{
905 // fParticleChange.ProposeMomentumDirection(State(fTransportEndMomentumDir));
906 //}
907/*
908 if (State(fParticleIsLooping))
909 {
910 if ((State(fNoLooperTrials)>= fThresholdTrials))
911 {
912 fParticleChange.ProposeTrackStatus(fStopAndKill);
913 State(fNoLooperTrials) = 0;
914#ifdef G4VERBOSE
915 if ((fVerboseLevel > 1))
916 {
917 G4cout
918 << " G4DNABrownianTransportation is killing track that is looping or stuck "
919 << G4endl;
920 G4cout << " Number of trials = " << State(fNoLooperTrials)
921 << " No of calls to AlongStepDoIt = " << noCalls
922 << G4endl;
923 }
924#endif
925 }
926 else
927 {
928 State(fNoLooperTrials)++;
929 }
930 }
931 else
932 {
933 State(fNoLooperTrials)=0;
934 }
935*/
936#ifdef DEBUG_MEM
937 mem_intermediaire = MemoryUsage();
938 mem_diff = mem_intermediaire-mem_first;
939 G4cout << "\t\t\t >> || MEM || After calling G4DNABrownianTransportation::"
940 "Diffusion for "<< track.GetTrackID() << ", diff is : "
941 << mem_diff << G4endl;
942#endif
943
944 return &fParticleChange;
945}
946
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
G4GPILSelection
#define State(X)
G4IT * GetIT(const G4Track *track)
Definition: G4IT.cc:48
G4Molecule * GetMolecule(const G4Track &track)
Definition: G4Molecule.cc:76
G4ThreeVector G4RandomDirection()
#define GREEN_ON_BLUE
Definition: G4Scheduler.cc:85
#define RESET_COLOR
Definition: G4Scheduler.cc:86
@ fStopAndKill
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:52
double mag() const
static double erf(double x)
static double inverseErf(double t)
virtual void Transport(const G4Track &, G4ParticleChangeForTransport &)=0
virtual G4VParticleChange * AlongStepDoIt(const G4Track &track, const G4Step &)
G4DNABrownianTransportation & operator=(const G4DNABrownianTransportation &)
void Diffusion(const G4Track &track)
G4DNABrownianTransportation(const G4String &aName="DNABrownianTransportation", G4int verbosityLevel=0)
const std::vector< G4double > * fpWaterDensity
virtual void ComputeStep(const G4Track &, const G4Step &, const double, double &)
G4double ComputeGeomLimit(const G4Track &track, G4double &presafety, G4double limit)
virtual void StartTracking(G4Track *aTrack)
virtual G4double AlongStepGetPhysicalInteractionLength(const G4Track &, G4double, G4double, G4double &, G4GPILSelection *)
virtual G4VParticleChange * PostStepDoIt(const G4Track &track, const G4Step &)
virtual void BuildPhysicsTable(const G4ParticleDefinition &)
static G4DNAMolecularMaterial * Instance()
G4VPhysicalVolume * GetWorldVolume()
G4double CheckNextStep(const G4ThreeVector &position, const G4ThreeVector &direction, const G4double currentMaxStep, G4double &newSafety)
G4ParticleChangeForTransport fParticleChange
virtual void BuildPhysicsTable(const G4ParticleDefinition &)
void SetInstantiateProcessState(G4bool flag)
virtual G4VParticleChange * AlongStepDoIt(const G4Track &track, const G4Step &stepData)
virtual G4double AlongStepGetPhysicalInteractionLength(const G4Track &track, G4double, G4double currentMinimumStep, G4double &currentSafety, G4GPILSelection *selection)
G4ITSafetyHelper * fpSafetyHelper
G4ITNavigator * fLinearNavigator
virtual G4VParticleChange * PostStepDoIt(const G4Track &track, const G4Step &)
virtual void StartTracking(G4Track *aTrack)
G4TrackingInformation * GetTrackingInfo()
Definition: G4IT.hh:143
virtual const G4String & GetName() const =0
G4double GetTemperature() const
Definition: G4Material.hh:180
size_t GetIndex() const
Definition: G4Material.hh:258
static G4Material * GetMaterial(const G4String &name, G4bool warning=true)
Definition: G4Material.cc:651
const G4String & GetName() const
Definition: G4Molecule.cc:338
G4double GetDiffusionCoefficient() const
Definition: G4Molecule.cc:516
G4Material * FindOrBuildMaterial(const G4String &name, G4bool isotopes=true, G4bool warning=false)
static G4NistManager * Instance()
void SetMomentumChanged(G4bool b)
void ProposeEnergy(G4double finalEnergy)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
const G4String & GetParticleName() const
G4double GetGlobalTime() const
const G4VProcess * GetProcessDefinedStep() const
const G4ThreeVector & GetPosition() const
Definition: G4Step.hh:62
G4double GetDeltaTime() const
G4StepPoint * GetPreStepPoint() const
G4double GetStepLength() const
G4StepPoint * GetPostStepPoint() const
virtual void LoadTrackState(G4TrackStateManager &manager)
virtual void ResetTrackState()
G4int GetTrackID() const
G4VPhysicalVolume * GetVolume() const
const G4ThreeVector & GetPosition() const
G4double GetGlobalTime() const
G4int GetCurrentStepNumber() const
G4Material * GetMaterial() const
const G4ThreeVector & GetMomentumDirection() const
G4double GetStepLength() const
const G4Step * GetStep() const
G4TrackStateManager & GetTrackStateManager()
G4bool ProposesTimeStep() const
G4shared_ptr< G4ProcessState > fpState
void ProposeTrackStatus(G4TrackStatus status)
const G4String & GetName() const
G4int verboseLevel
Definition: G4VProcess.hh:356
void SetProcessSubType(G4int)
Definition: G4VProcess.hh:406
G4int GetProcessSubType() const
Definition: G4VProcess.hh:400
const G4String & GetProcessName() const
Definition: G4VProcess.hh:382
static G4VScheduler * Instance()
Definition: G4VScheduler.cc:48
virtual double GetLimitingTimeStep() const
Definition: G4VScheduler.hh:84
virtual G4VPhysicalVolume * GetVolume(G4int depth=0) const
Definition: G4VTouchable.cc:41
virtual void UpdateYourself(G4VPhysicalVolume *pPhysVol, const G4NavigationHistory *history=nullptr)
Definition: G4VTouchable.cc:69
#define DBL_MAX
Definition: templates.hh:62