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