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