Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4Molecule.cc
Go to the documentation of this file.
1// ********************************************************************
2// * License and Disclaimer *
3// * *
4// * The Geant4 software is copyright of the Copyright Holders of *
5// * the Geant4 Collaboration. It is provided under the terms and *
6// * conditions of the Geant4 Software License, included in the file *
7// * LICENSE and available at http://cern.ch/geant4/license . These *
8// * include a list of copyright holders. *
9// * *
10// * Neither the authors of this software system, nor their employing *
11// * institutes,nor the agencies providing financial support for this *
12// * work make any representation or warranty, express or implied, *
13// * regarding this software system or assume any liability for its *
14// * use. Please see the license in the file LICENSE and URL above *
15// * for the full disclaimer and the limitation of liability. *
16// * *
17// * This code implementation is the result of the scientific and *
18// * technical work of the GEANT4 collaboration. *
19// * By using, copying, modifying or distributing the software (or *
20// * any work based on the software) you agree to acknowledge its *
21// * use in resulting scientific publications, and indicate your *
22// * acceptance of all terms of the Geant4 Software license. *
23// ********************************************************************
24//
25//
26// ---------------------------------------------------------------------
27// GEANT 4 class header file
28//
29// History: first implementation, based on G4DynamicParticle
30// New dependency : G4VUserTrackInformation
31//
32// ---------------- G4Molecule ----------------
33// first design&implementation by Alfonso Mantero, 7 Apr 2009
34// New developments Alfonso Mantero & Mathieu Karamitros
35// Oct/Nov 2009 Class Name changed to G4Molecule
36// Removed dependency from G4DynamicParticle
37// New constructors :
38// copy constructor
39// direct ionized/excited molecule
40// New methods :
41// Get : name,atoms' number,nb electrons,decayChannel
42// PrintState //To get the electronic level and the
43// corresponding name of the excitation
44// Kinematic :
45// BuildTrack,GetKineticEnergy,GetDiffusionVelocity
46// Change the way dynCharge and eNb is calculated
47// ---------------------------------------------------------------------
48
49#include "G4Molecule.hh"
51#include "G4MoleculeLocator.hh"
52#include "Randomize.hh"
54#include "G4SystemOfUnits.hh"
55#include "G4Track.hh"
56//#include "G4DNAChemistryManager.hh"
58using namespace std;
59
61{
63 return _instance;
64}
65
66//______________________________________________________________________________
67
68template<>
70 fPoint->SetNode(nullptr);
71}
72
73//______________________________________________________________________________
74
76{
77 return (G4Molecule*)(GetIT(track));
78}
79
80//______________________________________________________________________________
81
83{
84 return (G4Molecule*)(GetIT(track));
85}
86
87//______________________________________________________________________________
88
90{
91 return (G4Molecule*)(GetIT(track));
92}
93
94//______________________________________________________________________________
95
96void G4Molecule::Print() const
97{
98 G4cout << "The user track information is a molecule" << G4endl;
99}
100
101//______________________________________________________________________________
102
104 : G4VUserTrackInformation("G4Molecule")
105 , G4IT(right)
106{
107 fpMolecularConfiguration = right.fpMolecularConfiguration;
108}
109
110//______________________________________________________________________________
111
113{
114 if (&right == this) return *this;
115 fpMolecularConfiguration = right.fpMolecularConfiguration;
116 return *this;
117}
118
119//______________________________________________________________________________
120
122{
123 return fpMolecularConfiguration == right.fpMolecularConfiguration;
124}
125
126//______________________________________________________________________________
127
129{
130 return !(*this == right);
131}
132
133//______________________________________________________________________________
134/** The two methods below are the most called of the simulation :
135 * compare molecules in the MoleculeStackManager or in
136 * the InteractionTable
137 */
138
140{
141 return fpMolecularConfiguration < right.fpMolecularConfiguration;
142}
143
144//______________________________________________________________________________
145
147 : G4VUserTrackInformation("G4Molecule")
148{
149 fpMolecularConfiguration = nullptr;
150}
151
152//______________________________________________________________________________
153
155{
156 if (fpTrack != nullptr)
157 {
158 if (G4MoleculeCounterManager::Instance()->GetIsActive())
159 {
160 switch (fpTrack->GetTrackStatus())
161 {
162 case fAlive:
164 case fStopButAlive:
165 case fSuspend:
166 // do not remove molecule count if the track is not being killed
167 break;
168 case fStopAndKill:
170 default:
172 fpTrack->GetGlobalTime());
173 break;
174 }
175 }
176 fpTrack = nullptr;
177 }
178 fpMolecularConfiguration = nullptr;
179}
180
181//______________________________________________________________________________
182/** Build a molecule at ground state according to a given
183 * G4MoleculeDefinition that can be obtained from G4GenericMoleculeManager
184 */
186 : G4VUserTrackInformation("G4Molecule")
187{
188 fpMolecularConfiguration = G4MolecularConfiguration::GetOrCreateMolecularConfiguration(pMoleculeDefinition);
189}
190
191//______________________________________________________________________________
192
193G4Molecule::G4Molecule(G4MoleculeDefinition* pMoleculeDefinition, int charge)
194{
195 fpMolecularConfiguration = G4MolecularConfiguration::GetOrCreateMolecularConfiguration(pMoleculeDefinition,
196 charge);
197}
198
199//______________________________________________________________________________
200/** Build a molecule at a specific excitation/ionisation state according
201 * to a ground state that can be obtained from G4GenericMoleculeManager.
202 * Put 0 in the second option if this is a ionisation.
203 */
205 G4int OrbitalToFree,
206 G4int OrbitalToFill)
207 : G4VUserTrackInformation("G4Molecule")
208{
209 if (pMoleculeDefinition->GetGroundStateElectronOccupancy() != nullptr)
210 {
211 G4ElectronOccupancy dynElectronOccupancy(*pMoleculeDefinition->GetGroundStateElectronOccupancy());
212
213 if (OrbitalToFill != 0)
214 {
215 dynElectronOccupancy.RemoveElectron(OrbitalToFree - 1, 1);
216 dynElectronOccupancy.AddElectron(OrbitalToFill - 1, 1);
217 // dynElectronOccupancy.DumpInfo(); // DEBUG
218 }
219
220 if (OrbitalToFill == 0)
221 {
222 dynElectronOccupancy.RemoveElectron(OrbitalToFree - 1, 1);
223 // dynElectronOccupancy.DumpInfo(); // DEBUG
224 }
225
226 fpMolecularConfiguration =
228 pMoleculeDefinition, dynElectronOccupancy);
229 }
230 else
231 {
232 fpMolecularConfiguration = nullptr;
234 "G4Molecule::G4Molecule(G4MoleculeDefinition* pMoleculeDefinition, "
235 "G4int OrbitalToFree, G4int OrbitalToFill)",
236 "G4Molecule_wrong_usage_of_constructor",
238 "If you want to use this constructor, the molecule definition has to be "
239 "first defined with electron occupancies");
240 }
241}
242
243//______________________________________________________________________________
244/** Specific builder for water molecules to be used in Geant4-DNA,
245 * the last option Excitation is true if the molecule is excited, is
246 * false is the molecule is ionized.
247 */
249 G4int level,
250 G4bool excitation)
251 : G4VUserTrackInformation("G4Molecule")
252{
253 if (pMoleculeDefinition->GetGroundStateElectronOccupancy() != nullptr)
254 {
255 G4ElectronOccupancy dynElectronOccupancy(*pMoleculeDefinition->GetGroundStateElectronOccupancy());
256
257 if (excitation)
258 {
259 dynElectronOccupancy.RemoveElectron(level, 1);
260 dynElectronOccupancy.AddElectron(5, 1);
261 // dynElectronOccupancy.DumpInfo(); // DEBUG
262 }
263 else
264 {
265 dynElectronOccupancy.RemoveElectron(level, 1);
266 // dynElectronOccupancy.DumpInfo(); // DEBUG
267 }
268
269 fpMolecularConfiguration = G4MolecularConfiguration::GetOrCreateMolecularConfiguration(pMoleculeDefinition,
270 dynElectronOccupancy);
271 }
272 else
273 {
274 fpMolecularConfiguration = nullptr;
276 "G4Molecule::G4Molecule(G4MoleculeDefinition* pMoleculeDefinition, "
277 "G4int OrbitalToFree, G4int OrbitalToFill)",
278 "G4Molecule_wrong_usage_of_constructor",
280 "If you want to use this constructor, the molecule definition has to be "
281 "first defined with electron occupancies");
282 }
283}
284
285//______________________________________________________________________________
286
288{
289 fpMolecularConfiguration = pMolecularConfiguration;
290}
291
292//______________________________________________________________________________
293
295{
296 fpMolecularConfiguration =
297 G4MolecularConfiguration::GetOrCreateMolecularConfiguration(fpMolecularConfiguration->GetDefinition(),
298 *pElectronOcc);
299}
300
301//______________________________________________________________________________
302
304{
305 fpMolecularConfiguration = fpMolecularConfiguration->ExciteMolecule(excitationLevel);
306}
307
308//______________________________________________________________________________
309
311{
312 fpMolecularConfiguration = fpMolecularConfiguration->IonizeMolecule(ionizationLevel);
313}
314
315//______________________________________________________________________________
316
318{
319 fpMolecularConfiguration = fpMolecularConfiguration->AddElectron(orbit, number);
320}
321
322//______________________________________________________________________________
323
325{
326 fpMolecularConfiguration =
327 fpMolecularConfiguration->RemoveElectron(orbit, number);
328}
329
330//______________________________________________________________________________
331
332void G4Molecule::MoveOneElectron(G4int orbitToFree, G4int orbitToFill)
333{
334 fpMolecularConfiguration =
335 fpMolecularConfiguration->MoveOneElectron(orbitToFree, orbitToFill);
336}
337
338//______________________________________________________________________________
339
341{
342 return fpMolecularConfiguration->GetName();
343}
344
345//______________________________________________________________________________
346
348{
349 return fpMolecularConfiguration->GetFormatedName();
350}
351
352//______________________________________________________________________________
353
355{
356 return fpMolecularConfiguration->GetAtomsNumber();
357}
358
359//______________________________________________________________________________
360
362{
363 return fpMolecularConfiguration->GetNbElectrons();
364}
365
366//______________________________________________________________________________
367
369{
370 fpMolecularConfiguration->PrintState();
371}
372
373//______________________________________________________________________________
374
376 const G4ThreeVector &position,
377 const G4Track *parentTrack)
378{
379 if (fpTrack != nullptr)
380 {
381 G4Exception("G4Molecule::BuildTrack", "Molecule001", FatalErrorInArgument,
382 "A track was already assigned to this molecule");
383 }
384
385 // Kinetic Values
386 // Set a random direction to the molecule
387 G4double costheta = (2 * G4UniformRand() - 1);
388 G4double theta = acos(costheta);
389 G4double phi = 2 * pi * G4UniformRand();
390
391 G4double xMomentum = cos(phi) * sin(theta);
392 G4double yMomentum = sin(theta) * sin(phi);
393 G4double zMomentum = costheta;
394
395 G4ThreeVector MomentumDirection(xMomentum, yMomentum, zMomentum);
396 G4double KineticEnergy = GetKineticEnergy();
397
398 auto dynamicParticle = new G4DynamicParticle(
399 fpMolecularConfiguration->GetDefinition(), MomentumDirection,
400 KineticEnergy);
401
402 // Set the Track
403 fpTrack = new G4Track(dynamicParticle, globalTime, position);
404 fpTrack->SetUserInformation(this);
405
406 // Copy over touchable handle (see G4VEmProcess)
407 if (parentTrack == nullptr || parentTrack->GetTouchable() == nullptr ||
408 position != parentTrack->GetPosition())
409 {
410 // If (1) no track or touchable handle exists, or
411 // If (2) the new position is inconsistent with the track's position
412 // create a new touchable from the position:
413 // this way the subsequent calls *should* properly see its location (i.e. PV)
415 }
416 else
417 {
418 fpTrack->SetTouchableHandle(parentTrack->GetTouchableHandle());
419 }
420
421 if (G4MoleculeCounterManager::Instance()->GetIsActive())
422 {
424 fpTrack->GetGlobalTime());
425 // G4VMoleculeCounter::Instance()->
426 // AddAMoleculeAtTime(fpMolecularConfiguration,
427 // globalTime,
428 // &(fpTrack->GetPosition()));
429 }
430
431 return fpTrack;
432}
433
434//______________________________________________________________________________
435
437{
438 ////
439 // Ideal Gaz case
440 double v = GetDiffusionVelocity();
441 double E = (fpMolecularConfiguration->GetMass() / (c_squared)) * (v * v) / 2.;
442 ////
443 return E;
444}
445
446//______________________________________________________________________________
447
449{
450 double moleculeMass = fpMolecularConfiguration->GetMass() / (c_squared);
451
452 ////
453 // Different possibilities
454 ////
455 // Ideal Gaz case : Maxwell Boltzmann Distribution
456 // double sigma = k_Boltzmann * fgTemperature / mass;
457 // return G4RandGauss::shoot( 0, sigma );
458 ////
459 // Ideal Gaz case : mean velocity from equipartition theorem
460 return sqrt(3 * k_Boltzmann *
462 ////
463 // Using this approximation for liquid is wrong
464 // However the brownian process avoid taking
465 // care of energy consideration and plays only
466 // with positions
467}
468
469//______________________________________________________________________________
470
471// added - to be transformed in a "Decay method"
472const vector<const G4MolecularDissociationChannel*>*
474{
475 return fpMolecularConfiguration->GetDissociationChannels();
476}
477
478//______________________________________________________________________________
479
481{
482 return fpMolecularConfiguration->GetFakeParticleID();
483}
484
485//______________________________________________________________________________
486
488{
489 return fpMolecularConfiguration->GetMoleculeID();
490}
491
492//______________________________________________________________________________
493
495{
496 return fpMolecularConfiguration->GetDecayTime();
497}
498
499//______________________________________________________________________________
500
502{
503 return fpMolecularConfiguration->GetVanDerVaalsRadius();
504}
505
506//______________________________________________________________________________
507
509{
510 return fpMolecularConfiguration->GetCharge();
511}
512
513//______________________________________________________________________________
514
516{
517 return fpMolecularConfiguration->GetMass();
518}
519
520//______________________________________________________________________________
521
523{
524 return fpMolecularConfiguration->GetElectronOccupancy();
525}
526
527//______________________________________________________________________________
528
530{
531 return fpMolecularConfiguration->GetDefinition();
532}
533
534//______________________________________________________________________________
535
537{
538 return fpMolecularConfiguration->GetDiffusionCoefficient();
539}
540
541//______________________________________________________________________________
542
544 double temperature) const
545{
546 return fpMolecularConfiguration->GetDiffusionCoefficient(pMaterial,
547 temperature);
548}
549
550//______________________________________________________________________________
551
553{
554 return fpMolecularConfiguration;
555}
556
557//______________________________________________________________________________
558
560{
561 return fpMolecularConfiguration->GetLabel();
562}
563
564//______________________________________________________________________________
565
567{
568 // TODO check fpMolecularConfiguration already exists
569 // and new one as well
570 // TODO notify for stack change
572 fpMolecularConfiguration->GetDefinition(), label);
573
574 assert(fpMolecularConfiguration != nullptr);
575}
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4IT * GetIT(const G4Track *track)
Definition G4IT.cc:48
G4Molecule * GetMolecule(const G4Track &track)
Definition G4Molecule.cc:75
G4Allocator< G4Molecule > *& aMoleculeAllocator()
Definition G4Molecule.cc:60
CLHEP::Hep3Vector G4ThreeVector
@ fKillTrackAndSecondaries
@ fSuspend
@ fAlive
@ fStopAndKill
@ fStopButAlive
@ fPostponeToNextEvent
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
G4Track * fpTrack
Definition G4IT.hh:167
G4IT()
Definition G4IT.cc:67
void Print() const override
Definition G4IT.hh:97
~G4KDNode() override
PointT * fPoint
Definition G4KDNode.hh:167
static G4MolecularConfiguration * GetOrCreateMolecularConfiguration(const G4MoleculeDefinition *)
static G4MolecularConfiguration * GetMolecularConfiguration(const G4MoleculeDefinition *, const G4String &label)
void AddMolecule(const G4Track *, G4double, G4int=1)
static G4MoleculeCounterManager * Instance()
void RemoveMolecule(const G4Track *, G4double, G4int=1)
const G4ElectronOccupancy * GetGroundStateElectronOccupancy() const
void LocateMoleculeSetStateAndTouchable(G4Track *)
static G4MoleculeLocator * Instance()
~G4Molecule() override
void IonizeMolecule(G4int)
G4int GetCharge() const
G4Track * BuildTrack(G4double globalTime, const G4ThreeVector &Position, const G4Track *=nullptr)
void RemoveElectron(G4int, G4int number=1)
void AddElectron(G4int orbit, G4int n=1)
static G4Molecule * GetMolecule(const G4Track *)
Definition G4Molecule.cc:89
G4bool operator<(const G4Molecule &right) const
G4double GetVanDerVaalsRadius() const
const G4MolecularConfiguration * GetMolecularConfiguration() const
void SetElectronOccupancy(const G4ElectronOccupancy *)
void MoveOneElectron(G4int, G4int)
G4double GetMass() const
const G4String & GetName() const override
const G4String & GetLabel() const
void ChangeConfigurationToLabel(const G4String &label)
G4int GetMoleculeID() const
G4double GetKineticEnergy() const
G4Molecule(const G4Molecule &)
const G4String & GetFormatedName() const
G4int GetAtomsNumber() const
G4bool operator==(const G4Molecule &right) const
G4int GetFakeParticleID() const
G4double GetDiffusionVelocity() const
void PrintState() const
void ExciteMolecule(G4int)
G4bool operator!=(const G4Molecule &right) const
const G4ElectronOccupancy * GetElectronOccupancy() const
G4Molecule & operator=(const G4Molecule &right)
const G4MoleculeDefinition * GetDefinition() const
G4double GetDiffusionCoefficient() const
G4double GetDecayTime() const
const std::vector< const G4MolecularDissociationChannel * > * GetDissociationChannels() const
G4double GetNbElectrons() const
const G4ThreeVector & GetPosition() const
const G4TouchableHandle & GetTouchableHandle() const
const G4VTouchable * GetTouchable() const
G4VUserTrackInformation()=default
#define G4ThreadLocalStatic
Definition tls.hh:76