Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4MolecularConfiguration.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// History:
30// -----------
31// 10 Oct 2011 M.Karamitros created
32//
33// -------------------------------------------------------------------
34
37#include "G4UIcommand.hh"
38#include "G4AutoLock.hh"
39#include "G4MoleculeTable.hh"
40#include "G4Serialize.hh"
41#include <fstream>
42
43using CLHEP::m2;
44using CLHEP::s;
45using CLHEP::kelvin;
46
47using namespace std;
48
49#if defined ( WIN32 )
50#define __func__ __FUNCTION__
51#endif
52
53/*G4ThreadLocal*/G4double G4MolecularConfiguration::fgTemperature = 298; // 310*kelvin;
54// 25°C, used to shoot an energy
55
56//______________________________________________________________________________
57// G4MolecularConfigurationManager
59
61
63
68
70 double,
72 molConf)
73{
74 return molConf->fDynDiffusionCoefficient;
75}
76
78 const G4String& label,
79 int charge)
80{
81 fMoleculeDefinition = moleculeDef;
82
83 fLabel = new G4String(label);
84
85 fMoleculeID = GetManager()->Insert(moleculeDef,
86 label,
87 this);
88 fElectronOccupancy = nullptr;
89
90 fDynCharge = charge;
91
92 fDynMass = fMoleculeDefinition->GetMass();
93
94 fDynDiffusionCoefficient = fMoleculeDefinition->GetDiffusionCoefficient();
95 fDynVanDerVaalsRadius = fMoleculeDefinition->GetVanDerVaalsRadius();
96 fDynDecayTime = fMoleculeDefinition->GetDecayTime();
97
98 fName = fMoleculeDefinition->GetName();
99 fName += "^";
101
102 fFormatedName = fMoleculeDefinition->GetFormatedName();
103 fFormatedName += "^";
104 fFormatedName += "{";
106 fFormatedName += "}";
107
109 fIsFinalized = false;
110}
111
113{
114 if(fIsFinalized)
115 {
117 errMsg << "This molecular configuration " << GetName()
118 << " is already finalized. Therefore its "
119 " properties cannot be changed.";
120 G4Exception("G4MolecularConfiguration::MakeExceptionIfFinalized",
121 "CONF_FINALIZED",FatalException,errMsg);
122 }
123}
124
125//______________________________________________________________________________
126
129{
130 if (fgManager == nullptr)
131 {
133 if (fgManager == nullptr) // double check for MT
134 {
135 fgManager = new G4MolecularConfiguration::
136 G4MolecularConfigurationManager();
137 }
138 lock.unlock();
139 }
140
141 return fgManager;
142}
143
144//______________________________________________________________________________
145
148{
149 G4MolecularConfigurationManager::MolElectronConfTable::iterator it1;
150 G4MolecularConfigurationManager::ElectronOccupancyTable::
151 iterator it2;
152
153 for (it1 = fElecOccTable.begin(); it1 != fElecOccTable.end(); it1++)
154 {
155 for (it2 = it1->second.begin(); it2 != it1->second.end(); it2++)
156 {
157
158
159 delete it2->second;
160
161 }
162 }
163 fElecOccTable.clear();
164 fgManager = nullptr;
165}
166
167//______________________________________________________________________________
168// G4MolecularConfigurationManager
171Insert(const G4MoleculeDefinition* molDef,
172 const G4ElectronOccupancy& eOcc,
174{
175 //G4AutoLock lock(&fMoleculeCreationMutex);
176
177 ElectronOccupancyTable& table2 = fElecOccTable[molDef];
178 auto it = table2.find(eOcc);
179
180 if(it == table2.end())
181 {
182 table2[eOcc] = molConf;
183 }
184 else
185 {
187 errMsg << "The same molecular configuration seemed to be recorded twice";
188 G4Exception("G4MolecularConfigurationManager::"
189 "SetMolecularConfiguration(const G4MoleculeDefinition* molDef,"
190 "const G4ElectronOccupancy& eOcc,"
191 "G4MolecularConfiguration* molConf)",
192 "",
194 errMsg
195 );
196 }
197
198 fLastMoleculeID++;
199
200 fMolConfPerID.push_back(molConf);
201
202 //lock.unlock();
203 return fLastMoleculeID;
204}
205
206//______________________________________________________________________________
207
211 const G4ElectronOccupancy& eOcc)
212{
213 //G4AutoLock lock(&fMoleculeCreationMutex);
214
215 auto it1 = fElecOccTable.find(molDef);
216
217 if(it1 == fElecOccTable.end())
218 {
219 // TODO = handle exception ?
220 return nullptr;
221 }
222
223 ElectronOccupancyTable& table2 = it1->second;
224 auto it2 = table2.find(eOcc);
225
226 //lock.unlock();
227
228 if (it2 == table2.end())
229 {
230 // TODO = handle exception ?
231 return nullptr;
232 }
233
234 return &(it2->first);
235}
236
237//______________________________________________________________________________
238
242 const G4ElectronOccupancy& eOcc)
243{
244 auto it1 = fElecOccTable.find(molDef);
245
246 if(it1 == fElecOccTable.end()) return nullptr;
247
248 ElectronOccupancyTable& table2 = it1->second;
249 auto it = table2.find(eOcc);
250
251 if(it == table2.end())
252 {
253 return nullptr;
254 }
255
256 return it->second;
257}
258
259//______________________________________________________________________________
260
262Insert(const G4MoleculeDefinition* molDef,
263 int charge,
265{
266
267 //G4AutoLock lock(&fMoleculeCreationMutex);
268 ChargeTable& table2 = fChargeTable[molDef];
269 auto it = table2.find(charge);
270
271 if(it == table2.end())
272 {
273 table2[charge] = molConf;
274 }
275 else
276 {
277 //lock.unlock();
279 errMsg << "The same molecular configuration seemed to be recorded twice";
280 G4Exception("G4MolecularConfigurationManager::"
281 "SetMolecularConfiguration(const G4MoleculeDefinition* molDef,"
282 "int charge,"
283 "G4MolecularConfiguration* molConf)",
284 "", FatalException, errMsg);
285 }
286
287 fLastMoleculeID++;
288 fMolConfPerID.push_back(molConf);
289 //lock.unlock();
290 return fLastMoleculeID;
291}
292
293//______________________________________________________________________________
294
298 int charge)
299{
300 //G4AutoLock lock(&fMoleculeCreationMutex);
301
302 auto it1 = fChargeTable.find(molDef);
303
304 if(it1 == fChargeTable.end()) return nullptr;
305
306 ChargeTable& table2 = it1->second;
307 auto it = table2.find(charge);
308
309 if(it == table2.end())
310 {
311 return nullptr;
312 }
313
314 return it->second;
315
316}
317
318//______________________________________________________________________________
319// Static method in G4MolecularConfiguration
323{
324 if (molDef->GetGroundStateElectronOccupancy() != nullptr)
325 {
326 const G4ElectronOccupancy& elecOcc =
328 G4MolecularConfiguration* molConf =
329 GetManager()->GetMolecularConfiguration(molDef, elecOcc);
330
331 if (molConf != nullptr)
332 {
333 return molConf;
334 }
335
336 auto newConf =
337 new G4MolecularConfiguration(molDef,
338 elecOcc);
339 newConf->SetUserID(molDef->GetName());
340 return newConf;
341 }
342
343 G4MolecularConfiguration* molConf =
344 GetManager()->GetMolecularConfiguration(molDef, molDef->GetCharge());
345 if(molConf != nullptr)
346 {
347 return molConf;
348 }
349
350 auto newConf =
351 new G4MolecularConfiguration(molDef, molDef->GetCharge());
352 newConf->SetUserID(molDef->GetName());
353 return newConf;
354}
355
356//______________________________________________________________________________
357
361 const G4ElectronOccupancy& elecOcc)
362{
363 return GetManager()->GetOrCreateMolecularConfiguration(molDef, elecOcc);
364
365// G4MolecularConfiguration* molConf =
366// GetManager()->GetMolecularConfiguration(molDef, elecOcc);
367//
368// if (molConf)
369// {
370// return molConf;
371// }
372// else
373// {
374// G4MolecularConfiguration* newConf =
375// new G4MolecularConfiguration(molDef, elecOcc);
376// return newConf;
377// }
378}
379
380//______________________________________________________________________________
381
385 int charge)
386{
387 G4MolecularConfiguration* molConf =
388 GetManager()->GetMolecularConfiguration(molDef, charge);
389
390 if(molConf != nullptr)
391 {
392 return molConf;
393 }
394
395 auto newConf =
396 new G4MolecularConfiguration(molDef, charge);
397 return newConf;
398}
399
400//______________________________________________________________________________
401
409
410//______________________________________________________________________________
411// G4MolecularConfiguration
414 const G4ElectronOccupancy& elecOcc,
415 const G4String& label)
416{
417 fMoleculeDefinition = moleculeDef;
418
419 fMoleculeID = GetManager()->Insert(moleculeDef,
420 elecOcc,
421 this);
423 elecOcc);
424
425 /*
426 fgManager->fTable[fMoleculeDefinition][elecOcc] = this;
427 std::map<G4ElectronOccupancy, G4MolecularConfiguration*, comparator>::iterator it ;
428 it = fgManager->fTable[moleculeDef].find(elecOcc);
429 fElectronOccupancy = &(it->first);
430 */
431
432 fDynCharge = fMoleculeDefinition->GetNbElectrons()
433 - fElectronOccupancy->GetTotalOccupancy()
434 + moleculeDef->GetCharge();
435 fDynMass = fMoleculeDefinition->GetMass();
436
437 fDynDiffusionCoefficient = fMoleculeDefinition->GetDiffusionCoefficient();
438 fDynVanDerVaalsRadius = fMoleculeDefinition->GetVanDerVaalsRadius();
439 fDynDecayTime = fMoleculeDefinition->GetDecayTime();
440
441 fName = fMoleculeDefinition->GetName();
442 fName += "^";
444
445 fFormatedName = fMoleculeDefinition->GetFormatedName();
446 fFormatedName += "^";
447 fFormatedName += "{";
449 fFormatedName += "}";
450
451 fLabel = nullptr; // let it here
452
453 if(!label.empty())
454 {
455 SetLabel(label);
456 }
457
459
460 fIsFinalized = false;
461}
462
463//______________________________________________________________________________
464
467 int charge)
468{
469 fMoleculeDefinition = moleculeDef;
470
471 fMoleculeID = GetManager()->Insert(moleculeDef,
472 charge,
473 this);
474 fElectronOccupancy = nullptr;
475
476 fDynCharge = charge;
477 fDynMass = fMoleculeDefinition->GetMass();
478
479 fDynDiffusionCoefficient = fMoleculeDefinition->GetDiffusionCoefficient();
480 fDynVanDerVaalsRadius = fMoleculeDefinition->GetVanDerVaalsRadius();
481 fDynDecayTime = fMoleculeDefinition->GetDecayTime();
482
483 fName = fMoleculeDefinition->GetName();
484 fName += "^";
486
487 fFormatedName = fMoleculeDefinition->GetFormatedName();
488 fFormatedName += "^";
489 fFormatedName += "{";
491 fFormatedName += "}";
492
493 fLabel = nullptr;
494
496
497 fIsFinalized = false;
498}
499
500//______________________________________________________________________________
501
503{
504 if (fgManager != nullptr) fgManager->RemoveMolecularConfigurationFromTable(this);
505}
506
507//______________________________________________________________________________
508
511ChangeConfiguration(const G4ElectronOccupancy& newElectronOccupancy) const
512{
515 newElectronOccupancy);
516
517 if (output == nullptr)
518 {
520 newElectronOccupancy);
521 }
522 return output;
523}
524
525//______________________________________________________________________________
526
529{
532
533 if (output == nullptr)
534 {
535 output = new G4MolecularConfiguration(fMoleculeDefinition, charge);
536 }
537 return output;
538}
539
540//______________________________________________________________________________
541
544{
545// if (&right == this) return *this;
546 return *this;
547}
548
549//______________________________________________________________________________
550
551/** Method used in Geant4-DNA to excite water molecules
552 */
555{
556// MakeExceptionIfFinalized();
557 CheckElectronOccupancy(__func__);
558 G4ElectronOccupancy newElectronOccupancy(*fElectronOccupancy);
559
560 newElectronOccupancy.RemoveElectron(ExcitedLevel, 1);
561 newElectronOccupancy.AddElectron(5, 1);
562
563 return ChangeConfiguration(newElectronOccupancy);
564}
565
566//______________________________________________________________________________
567
568/** Method used in Geant4-DNA to ionize water molecules
569 */
572{
573// MakeExceptionIfFinalized();
574 CheckElectronOccupancy(__func__);
575 G4ElectronOccupancy newElectronOccupancy(*fElectronOccupancy);
576
577 if (newElectronOccupancy.GetOccupancy(IonizedLevel) != 0)
578 {
579 newElectronOccupancy.RemoveElectron(IonizedLevel, 1);
580 }
581 else
582 {
583 G4String errMsg = "There is no electron on the orbit "
584 + G4UIcommand::ConvertToString(IonizedLevel)
585 + " you want to free. The molecule's name you want to ionized is "
586 + GetName();
587 G4Exception("G4MolecularConfiguration::IonizeMolecule",
588 "",
590 errMsg);
591 PrintState();
592 }
593
594 // DEBUG
595 // PrintState();
596
597 return ChangeConfiguration(newElectronOccupancy);
598}
599
600//______________________________________________________________________________
601
603 G4int number) const
604{
605// MakeExceptionIfFinalized();
606 CheckElectronOccupancy(__func__);
607 G4ElectronOccupancy newElectronOccupancy(*fElectronOccupancy);
608 newElectronOccupancy.AddElectron(orbit, number);
609 return ChangeConfiguration(newElectronOccupancy);
610}
611
612//______________________________________________________________________________
613
616 G4int number) const
617{
618// MakeExceptionIfFinalized();
619 CheckElectronOccupancy(__func__);
620 G4ElectronOccupancy newElectronOccupancy(*fElectronOccupancy);
621
622 if (newElectronOccupancy.GetOccupancy(orbit) != 0)
623 {
624 newElectronOccupancy.RemoveElectron(orbit, number);
625 }
626 else
627 {
628 G4String errMsg = "There is already no electron into the orbit "
630 + " you want to free. The molecule's name is " + GetName();
631 G4Exception("G4MolecularConfiguration::RemoveElectron",
632 "",
634 errMsg);
635 PrintState();
636 }
637
638 return ChangeConfiguration(newElectronOccupancy);
639}
640
641//______________________________________________________________________________
642
645 G4int orbitToFill) const
646{
647// MakeExceptionIfFinalized();
648 CheckElectronOccupancy(__func__);
649 G4ElectronOccupancy newElectronOccupancy(*fElectronOccupancy);
650
651 if (newElectronOccupancy.GetOccupancy(orbitToFree) >= 1)
652 {
653 newElectronOccupancy.RemoveElectron(orbitToFree, 1);
654 newElectronOccupancy.AddElectron(orbitToFill, 1);
655 }
656 else
657 {
658 G4String errMsg = "There is no electron on the orbit "
659 + G4UIcommand::ConvertToString(orbitToFree)
660 + " you want to free. The molecule's name is " + GetName();
661 G4Exception("G4MolecularConfiguration::MoveOneElectron",
662 "",
664 errMsg);
665 PrintState();
666 }
667
668 return ChangeConfiguration(newElectronOccupancy);
669}
670
671//______________________________________________________________________________
672
674{
675 return fName;
676}
677
678//______________________________________________________________________________
679
684
685//______________________________________________________________________________
686
688{
689 return fMoleculeDefinition->GetAtomsNumber();
690}
691
692//______________________________________________________________________________
693
695{
696 CheckElectronOccupancy(__func__);
697 return fElectronOccupancy->GetTotalOccupancy();
698}
699
700//______________________________________________________________________________
701
703{
704 G4cout << "-------------- Start Printing State " << GetName()
705 << " ---------------" << G4endl;
706
707 if (fElectronOccupancy != nullptr)
708 {
709 G4cout << "--------------Print electronic state of " << GetName()
710 << "---------------" << G4endl;
711 fElectronOccupancy->DumpInfo();
712 if(fElectronOccupancy==fMoleculeDefinition->GetGroundStateElectronOccupancy())
713 {
714 G4cout<<"At ground state"<<G4endl;
715 }
716 }
717 else
718 {
719 G4cout << "--- No electron occupancy set up ---" << G4endl;
720 }
721
722 G4cout << "Charge :"
723 << fDynCharge
724 << G4endl;
725
726 if(fLabel != nullptr)
727 {
728 G4cout << "Label :"
729 << GetLabel()
730 << G4endl;
731 }
732 G4cout << "-------------- End Of State " << GetName()
733 << " -----------------------" << G4endl;
734}
735
736//______________________________________________________________________________
737
738// added - to be transformed in a "Decay method"
739const vector<const G4MolecularDissociationChannel*>*
741{
742 // if (fElectronOccupancy == 0) return 0;
743 return fMoleculeDefinition->GetDecayChannels(this);
744}
745
746//______________________________________________________________________________
747
749{
750 if(fMoleculeDefinition != nullptr) return fMoleculeDefinition->GetPDGEncoding();
751 G4Exception("G4MolecularConfiguration::GetMoleculeID",
752 "",
754 "You should first enter a molecule definition");
755
756 return INT_MAX;
757}
758
759//______________________________________________________________________________
760
761const char* removePath(const char* path)
762{
763 const char* pDelimeter = strrchr(path, '\\');
764 if (pDelimeter != nullptr) path = pDelimeter + 1;
765
766 pDelimeter = strrchr(path, '/');
767 if (pDelimeter != nullptr) path = pDelimeter + 1;
768
769 return path;
770}
771
772//______________________________________________________________________________
773
775{
776 if (fElectronOccupancy == nullptr)
777 {
778 G4String functionName(function);
779 G4ExceptionDescription description;
780 description
781 << "No G4ElectronOccupancy was defined for molecule definition : "
782 << fMoleculeDefinition->GetName()
783 << ". The definition was probably defined using the charge state, "
784 "rather than electron state.";
785
786 G4Exception(functionName, "", FatalErrorInArgument, description);
787 }
788}
789
790//______________________________________________________________________________
791
794{
795 //G4AutoLock lock(&fMoleculeCreationMutex);
796
797 LabelTable& tmpMap = fLabelTable[molConf->fMoleculeDefinition];
798
799 auto it = tmpMap.find(*molConf->fLabel);
800
801 if(it == tmpMap.end())
802 {
803 tmpMap[*(molConf->fLabel)] = molConf;
804 }
805 else
806 {
808 errMsg << "The same molecular configuration seemed to be recorded twice";
809 G4Exception("G4MolecularConfigurationManager::"
810 "SetMolecularConfiguration(const G4MoleculeDefinition* molDef,"
811 "const G4String& label,"
812 "G4MolecularConfiguration* molConf)",
813 "", FatalException, errMsg);
814 }
815
816 //lock.unlock();
817}
818
820 G4MolecularConfiguration* molecule)
821{
822 auto it = fUserIDTable.find(userID);
823
824 if(it == fUserIDTable.end())
825 {
826 fUserIDTable[userID] = molecule;
827 }
828 else if(molecule != it->second)
829 {
830 // TODO improve exception
831 // exception
832 G4ExceptionDescription description;
833 description << "The user identifier " << userID
834 << " was already given in another configuration in the table"
835 << G4endl;
836 G4Exception("G4MolecularConfiguration::G4MolecularConfigurationManager::AddUserID",
837 "CONF_ALREADY_RECORDED",
839 description);
840 }
841}
842
843//______________________________________________________________________________
844
847{
848 auto it1 =
849 fElecOccTable.find(configuration->GetDefinition());
850 auto end = fElecOccTable.end();
851
852 if (it1 == end) return;
853
854 auto it2 =
855 it1->second.find(*configuration->GetElectronOccupancy());
856
857 if (it2 == it1->second.end()) return;
858
859 it2->second = 0;
860// it1->second.erase(it2);
861
862 configuration->fElectronOccupancy = nullptr;
863}
864
865//______________________________________________________________________________
866
870 const G4String& label)
871{
872 //G4AutoLock lock(&fMoleculeCreationMutex);
873
874 auto it1 = fLabelTable.find(molDef);
875
876 if(it1 == fLabelTable.end()) return nullptr;
877
878 LabelTable& table2 = it1->second;
879
880 auto it2 = table2.find(label);
881
882 //lock.unlock();
883
884 if(it2 == table2.end()) return nullptr;
885 return it2->second;
886}
887
888//______________________________________________________________________________
889
892GetMolecularConfiguration(int moleculeID)
893{
894 if(moleculeID > (int) fMolConfPerID.size() ||
895 moleculeID < 0) return nullptr;
896
897 return fMolConfPerID[moleculeID];
898}
899
900//______________________________________________________________________________
901
902G4int
904Insert(const G4MoleculeDefinition* molDef,
905 const G4String& label,
907{
908 G4AutoLock lock(&fMoleculeCreationMutex);
909 LabelTable& tmpMap = fLabelTable[molDef];
910 auto it = tmpMap.find(label);
911
912 if(it == tmpMap.end())
913 {
914 fLastMoleculeID++;
915 tmpMap[label] = molConf;
916 lock.unlock();
917 }
918 else
919 {
920 lock.unlock();
922 errMsg << "The same molecular configuration seemed to be recorded twice";
923 G4Exception("G4MolecularConfigurationManager::"
924 "SetMolecularConfiguration(const G4MoleculeDefinition* molDef,"
925 "const G4String& label,"
926 "G4MolecularConfiguration* molConf)",
927 "", FatalException, errMsg);
928 }
929
930 fMolConfPerID.push_back(molConf);
931
932 return fLastMoleculeID;
933}
934
935//______________________________________________________________________________
936
943
944//______________________________________________________________________________
945
951
952//______________________________________________________________________________
953
956 const G4MoleculeDefinition* molDef,
957 int charge,
958 const G4String& label,
959 bool& wasAlreadyCreated)
960{
961 wasAlreadyCreated = false;
962 G4MolecularConfiguration* molConf =
963 GetManager()->GetMolecularConfiguration(molDef, charge);
964
965 if (molConf != nullptr)
966 {
967 if(molConf->fLabel == nullptr)
968 {
969 molConf->SetLabel(label);
971 wMsg << "The molecular configuration for the definition named "
972 << molDef->GetName()
973 << " with charge " << charge << " has already been created "
974 "but with NO label";
975 G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
976 "DOUBLE_CREATION",
978 wMsg);
979 }
980 else if(molConf->fLabel->empty() )
981 {
982 molConf->SetLabel(label);
983 }
984 else if(*(molConf->fLabel) != label)
985 {
987 errMsg << "The molecular configuration for the definition named "
988 << molDef->GetName()
989 << " with charge " << charge << " has already been created "
990 "but with a different label :"
991 << molConf->GetLabel();
992 G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
993 "DOUBLE_CREATION",
995 errMsg);
996 // KILL APP
997 }
998
999 if(molConf->fUserIdentifier.empty())
1000 {
1001 molConf->fUserIdentifier = userIdentifier;
1002
1004 wMsg << "The molecular configuration for the definition named "
1005 << molDef->GetName()
1006 << " with label " << label << " has already been created.";
1007 G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1008 "DOUBLE_CREATION",
1010 wMsg);
1011 }
1012 else if(molConf->fUserIdentifier != userIdentifier)
1013 {
1014 G4ExceptionDescription errMsg ;
1015 errMsg << "The molecular configuration for the definition named "
1016 << molDef->GetName()
1017 << " with label " << label << " has already been created "
1018 "BUT with a different user ID :"
1019 << molConf->fUserIdentifier;
1020 G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1021 "DOUBLE_CREATION",
1023 errMsg);
1024 // KILL APP
1025 }
1026
1027 wasAlreadyCreated = true;
1028 return molConf;
1029 }
1030
1031 auto newConf =
1032 new G4MolecularConfiguration(molDef, label, charge);
1033 newConf->fUserIdentifier = userIdentifier;
1034
1035 GetManager()->AddUserID(userIdentifier, newConf);
1036
1037// G4MoleculeTable::Instance()->RecordMolecularConfiguration(userIdentifier,
1038// newConf);
1039 return newConf;
1040}
1041
1042//______________________________________________________________________________
1043
1046CreateMolecularConfiguration(const G4String& userIdentifier,
1047 const G4MoleculeDefinition* molDef,
1048 bool& wasAlreadyCreated)
1049{
1050 wasAlreadyCreated = false;
1051 G4MolecularConfiguration* preRegisteredMolConf =
1052 GetManager()->GetMolecularConfiguration(userIdentifier);
1053
1054 if(preRegisteredMolConf != nullptr)
1055 {
1056 if(preRegisteredMolConf->GetDefinition() == molDef)
1057 {
1058 wasAlreadyCreated = true;
1059 return preRegisteredMolConf;
1060 }
1061 }
1062
1063 if(molDef->GetGroundStateElectronOccupancy() != nullptr)
1064 {
1065 const G4ElectronOccupancy& elecOcc = *molDef
1067 G4MolecularConfiguration* molConf =
1068 GetManager()->GetMolecularConfiguration(molDef, elecOcc);
1069
1070 if(molConf != nullptr)
1071 {
1072 if(molConf->fUserIdentifier.empty())
1073 {
1074 molConf->fUserIdentifier = userIdentifier;
1075 }
1076 else if(molConf->fUserIdentifier != userIdentifier)
1077 {
1079 errMsg << "A molecular configuration for the definition named "
1080 << molDef->GetName() << " has already been created "
1081 "and recorded with a different user ID "
1082 << molConf->fUserIdentifier;
1083 G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1084 "DOUBLE_CREATION",
1086 errMsg);
1087 }
1088// TODO exception
1090 errMsg << "A molecular configuration for the definition named "
1091 << molDef->GetName() << " has already been created.";
1092 G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1093 "DOUBLE_CREATION",
1095 errMsg);
1096 wasAlreadyCreated = true;
1097 return molConf;
1098 }
1099
1100 // G4cout << "Create molConf for " << molDef->GetName() << G4endl;
1101 auto newConf = new G4MolecularConfiguration(molDef,
1102 elecOcc);
1103 newConf->fUserIdentifier = userIdentifier;
1104
1105 GetManager()->AddUserID(userIdentifier, newConf);
1106
1107// G4MoleculeTable::Instance()->RecordMolecularConfiguration(userIdentifier,
1108// newConf);
1109 return newConf;
1110 }
1111
1112 return CreateMolecularConfiguration(userIdentifier,
1113 molDef,
1114 molDef->GetName(),
1115 molDef->GetCharge(),
1116 wasAlreadyCreated);
1117}
1118
1119//______________________________________________________________________________
1120
1123CreateMolecularConfiguration(const G4String& userIdentifier,
1124 const G4MoleculeDefinition* molDef,
1125 const G4String& label,
1126 bool& wasAlreadyCreated)
1127{
1128 assert(label != "");
1129 wasAlreadyCreated = false;
1130
1131 G4MolecularConfiguration* molConf =
1132 GetManager()->GetMolecularConfiguration(molDef, label);
1133 if(molConf != nullptr)
1134 {
1135 if((molConf->fLabel != nullptr)
1136 && *molConf->fLabel == label)
1137 {
1138 wasAlreadyCreated = true;
1139 return molConf;
1140 }
1141 if(molConf->fLabel == nullptr)
1142 {
1143 wasAlreadyCreated = true;
1144 molConf->SetLabel(label);
1145 return molConf;
1146 }
1147 if(molConf->fLabel->empty())
1148 {
1149 wasAlreadyCreated = true;
1150 molConf->SetLabel(label);
1151 return molConf;
1152 }
1153
1154 molConf->PrintState();
1155 G4ExceptionDescription errMsg ;
1156 errMsg << "A molecular configuration for the definition named "
1157 << molDef->GetName()
1158 << " has already been created "
1159 "with user ID "
1160 << molConf->fUserIdentifier << " and label "
1161 << molConf->GetLabel();
1162 G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1163 "DOUBLE_CREATION",
1165 errMsg);
1166 // KILL APP
1167 }
1168 else
1169 {
1170 auto newConf =
1171 new G4MolecularConfiguration(molDef,
1172 label,
1173 molDef->GetCharge());
1174 newConf->fUserIdentifier = userIdentifier;
1175
1176 GetManager()->AddUserID(userIdentifier, newConf);
1177
1178// G4MoleculeTable::Instance()->
1179// RecordMolecularConfiguration(userIdentifier, newConf);
1180 return newConf;
1181 }
1182 return molConf;
1183}
1184
1185//______________________________________________________________________________
1186
1189CreateMolecularConfiguration(const G4String& userIdentifier,
1190 const G4MoleculeDefinition* molDef,
1191 const G4String& label,
1192 const G4ElectronOccupancy& eOcc,
1193 bool& wasAlreadyCreated)
1194{
1195 assert(label != "");
1196 wasAlreadyCreated = false;
1197
1198 G4MolecularConfiguration* molConf =
1199 GetManager()->GetMolecularConfiguration(molDef, eOcc);
1200
1201 if(molConf != nullptr)
1202 {
1203 if(molConf->GetElectronOccupancy() != nullptr)
1204 {
1205 if(*molConf->GetElectronOccupancy() == eOcc)
1206 {
1207 if((molConf->fLabel != nullptr) && *molConf->fLabel == label)
1208 {
1209 wasAlreadyCreated = true;
1210 return molConf;
1211 }
1212 if(molConf->fLabel == nullptr)
1213 {
1214 wasAlreadyCreated = true;
1215 molConf->SetLabel(label);
1216 return molConf;
1217 }
1218 if(molConf->fLabel->empty())
1219 {
1220 wasAlreadyCreated = true;
1221 molConf->SetLabel(label);
1222 return molConf;
1223 }
1224 }
1225 }
1226
1227
1228 molConf->PrintState();
1229 G4ExceptionDescription errMsg ;
1230 errMsg << "A molecular configuration for the definition named "
1231 << molDef->GetName()
1232 << " has already been created "
1233 "with user ID "
1234 << molConf->fUserIdentifier
1235 << " and possible different electronic state";
1236 G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1237 "DOUBLE_CREATION",
1239 errMsg);
1240 }
1241 else
1242 {
1243 auto newConf =
1244 new G4MolecularConfiguration(molDef,
1245 eOcc,
1246 label);
1247 newConf->fUserIdentifier = userIdentifier;
1248
1249 GetManager()->AddUserID(userIdentifier, newConf);
1250
1251// G4MoleculeTable::Instance()->
1252// RecordMolecularConfiguration(userIdentifier, newConf);
1253 return newConf;
1254 }
1255 return molConf;
1256}
1257
1258
1259//______________________________________________________________________________
1260
1264 const G4ElectronOccupancy& eOcc)
1265{
1266 auto it1 = fElecOccTable.find(molDef);
1267
1268 if(it1 == fElecOccTable.end())
1269 {
1270 return new G4MolecularConfiguration(molDef, eOcc);
1271 }
1272
1273 ElectronOccupancyTable& table2 = it1->second;
1274 auto it = table2.find(eOcc);
1275
1276 if(it == table2.end())
1277 {
1278 auto molConf =
1279 new G4MolecularConfiguration(molDef, eOcc);
1280// molConf->Finalize();
1281 return molConf;
1282 }
1283
1284 return it->second;
1285}
1286
1287//______________________________________________________________________________
1288
1292 int charge)
1293{
1294 auto it1 = fChargeTable.find(molDef);
1295
1296 if(it1 == fChargeTable.end())
1297 {
1298 G4AutoLock lock(&fMoleculeCreationMutex);
1299
1300 auto newConf = new G4MolecularConfiguration(molDef, charge);
1301 return newConf ;
1302 }
1303
1304 ChargeTable& table2 = it1->second;
1305 auto it = table2.find(charge);
1306
1307 if(it == table2.end())
1308 {
1309 G4AutoLock lock(&fMoleculeCreationMutex);
1310
1311 auto newConf =
1312 new G4MolecularConfiguration(molDef, charge);
1313// newConf->Finalize();
1314 return newConf ;
1315 }
1316
1317 return it->second;
1318}
1319
1320//______________________________________________________________________________
1321
1323{
1324 G4String moleculeName = fMoleculeDefinition->GetName();
1325 WRITE(out, moleculeName);
1326
1327// if(fLabel)
1328// out << fLabel;
1329// else
1330// out << "";
1333 WRITE(out,fDynDecayTime);
1334 WRITE(out,fDynMass);
1335 WRITE(out,fDynCharge);
1336 WRITE(out,fMoleculeID);
1337 WRITE(out,fFormatedName);
1338 WRITE(out,fName);
1339 WRITE(out,fIsFinalized);
1340}
1341
1342//______________________________________________________________________________
1343
1345{
1346 G4String moleculeName;
1347 READ(in, moleculeName);
1350
1351// G4String label;
1352//
1353// in.read((char*)(&label), sizeof(label));
1354//
1355// if(label)
1356// fLabel = new G4String(label);
1357// else
1358// fLabel = 0;
1361 READ(in,fDynDecayTime);
1362 READ(in,fDynMass);
1363 READ(in,fDynCharge);
1364 READ(in,fMoleculeID);
1365 READ(in,fFormatedName);
1366 READ(in,fName);
1367 READ(in,fIsFinalized);
1368}
1369
1370//______________________________________________________________________________
1371
1376
1377//______________________________________________________________________________
1378
1380{
1381 fLabel = nullptr; // TODO: for now not serialized
1382 Unserialize(in);
1383 fMoleculeDefinition = nullptr;
1384 fElectronOccupancy = nullptr;
1385 if(fElectronOccupancy != nullptr)
1386 {
1391
1392 if(fLabel != nullptr)
1393 {
1395 }
1396 }
1397 else if(fLabel != nullptr)
1398 {
1400 }
1401 else if(fDynCharge != 0)
1402 {
1404 }
1405}
1406
1407//______________________________________________________________________________
1408
1410{
1411 fUserIdentifier = userID;
1412 GetManager()->AddUserID(userID, this);
1413// G4MoleculeTable::Instance()->RecordMolecularConfiguration(userID, this);
1414}
1415
1416//______________________________________________________________________________
1417
1419{
1420 return pow(10, 4.311
1421 - 2.722e3/temperature_K
1422 + 8.565e5/(temperature_K *temperature_K)
1423 - 1.181e8/(temperature_K*temperature_K*temperature_K ))*1e-9*m2/s;
1424}
1425
1426//______________________________________________________________________________
1427
1428void
1430ScaleAllDiffusionCoefficientsOnWater(double temperature_K)
1431{
1432 double D_water_0 = DiffCoeffWater(fgTemperature);
1433 double D_water_f = DiffCoeffWater(temperature_K);
1434
1435 G4cout << "Scaling factor = " << D_water_f/D_water_0 << G4endl;
1436
1439
1440 while(it())
1441 {
1442 G4MolecularConfiguration* conf = it.value();
1443 double D_0 = conf->GetDiffusionCoefficient() ;
1444 double D_f = D_water_f * D_0 /D_water_0;
1445 conf->SetDiffusionCoefficient(D_f);
1446 };
1447}
1448
1449//______________________________________________________________________________
1450
1458
1459//______________________________________________________________________________
1460
1462{
1464 fgTemperature = temperature;
1465}
1466
1467//______________________________________________________________________________
1468
1473
1474//______________________________________________________________________________
1475
1479{
1480 for(auto it : fMolConfPerID)
1481 {
1482 if(it->GetUserID() == userID) return it;
1483 }
1484 return nullptr;
1485}
1486
1487//______________________________________________________________________________
1488
1494
1495//______________________________________________________________________________
1496
1498{
1499 const std::vector<G4MolecularConfiguration*>& species =
1501
1502 for(auto specie : species)
1503 {
1504 specie->Finalize();
1505 }
1506
1507}
1508
1510{
1511 const std::vector<G4MolecularConfiguration*>& species =
1513 G4cout<<G4endl;
1514 G4cout<<"Molecular Config"<<std::setw(25)<<" | Diffusion Coefficient (m2 / s) "<<std::setw(20)<<" | Radius (nm) "<<G4endl;
1515 G4cout<<"__________________________________________"
1516 "___________________________________"<<G4endl;
1517 for(auto specie : species)
1518 {
1519 G4cout<<specie->GetName()
1520 <<std::setw(G4int(30 - specie->GetName().length()))
1521 <<right<<specie->GetDiffusionCoefficient() * 1.0e3<<std::setw(30)
1522 <<specie->GetVanDerVaalsRadius()/CLHEP::nm<<G4endl;
1523 G4cout<<"__________________________________________"
1524 "___________________________________"<<G4endl;
1525 }
1526
1527}
G4TemplateAutoLock< G4Mutex > G4AutoLock
G4double(*)(G4double) function
@ JustWarning
@ FatalException
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
const char * removePath(const char *path)
G4MolecularConfiguration::G4MolecularConfigurationManager MolecularConfigurationManager
G4MoleculeIterator< G4MolecularConfiguration > G4ConfigurationIterator
void WRITE(std::ostream &out, const T &toBeSaved)
void READ(std::istream &in, T &toBeSaved)
std::mutex G4Mutex
double G4double
Definition G4Types.hh:83
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
G4int AddElectron(G4int orbit, G4int number=1)
G4int RemoveElectron(G4int orbit, G4int number=1)
G4int GetOccupancy(G4int orbit) const
const G4ElectronOccupancy * FindCommonElectronOccupancy(const G4MoleculeDefinition *molDef, const G4ElectronOccupancy &eOcc)
G4int Insert(const G4MoleculeDefinition *molDef, const G4ElectronOccupancy &eOcc, G4MolecularConfiguration *molConf)
const std::vector< G4MolecularConfiguration * > & GetAllSpecies()
void RecordNewlyLabeledConfiguration(G4MolecularConfiguration *molConf)
G4MolecularConfiguration * GetOrCreateMolecularConfiguration(const G4MoleculeDefinition *molDef, const G4ElectronOccupancy &eOcc)
G4MolecularConfiguration * GetMolecularConfiguration(const G4MoleculeDefinition *molDef, const G4ElectronOccupancy &eOcc)
void AddUserID(const G4String &name, G4MolecularConfiguration *molecule)
static G4MolecularConfiguration * Load(std::istream &)
void SetUserID(const G4String &userID)
static G4MolecularConfigurationManager * GetManager()
const G4String & GetName() const
const G4ElectronOccupancy * fElectronOccupancy
G4MolecularConfiguration * IonizeMolecule(G4int) const
const G4String & GetLabel() const
G4MolecularConfiguration * ChangeConfiguration(const G4ElectronOccupancy &newElectronOccupancy) const
G4MolecularConfiguration & operator=(G4MolecularConfiguration &right)
G4MolecularConfiguration * RemoveElectron(G4int, G4int number=1) const
const G4MoleculeDefinition * GetDefinition() const
static void ScaleAllDiffusionCoefficientsOnWater(double temperature_K)
G4MolecularConfiguration * MoveOneElectron(G4int, G4int) const
static double ReturnDefaultDiffCoeff(const G4Material *, double, const G4MolecularConfiguration *molConf)
const G4MoleculeDefinition * fMoleculeDefinition
static void SetGlobalTemperature(G4double)
static G4MolecularConfiguration * GetOrCreateMolecularConfiguration(const G4MoleculeDefinition *)
const G4ElectronOccupancy * GetElectronOccupancy() const
void CheckElectronOccupancy(const char *line) const
const std::vector< const G4MolecularDissociationChannel * > * GetDissociationChannels() const
const G4String & GetFormatedName() const
static G4MolecularConfigurationManager * fgManager
G4MolecularConfiguration(const G4MoleculeDefinition *, const G4ElectronOccupancy &, const G4String &label="")
static G4MolecularConfiguration * GetMolecularConfiguration(const G4MoleculeDefinition *, const G4String &label)
G4MolecularConfiguration * ExciteMolecule(G4int) const
static double DiffCoeffWater(double temperature_K)
G4MolecularConfiguration * AddElectron(G4int orbit, G4int n=1) const
static G4MolecularConfiguration * CreateMolecularConfiguration(const G4String &userIdentifier, const G4MoleculeDefinition *, bool &wasAlreadyCreated)
const G4ElectronOccupancy * GetGroundStateElectronOccupancy() const
const G4String & GetName() const
G4MoleculeDefinition * GetMoleculeDefinition(const G4String &, bool mustExist=true)
static G4MoleculeTable * Instance()
G4ConfigurationIterator GetConfigurationIterator()
static G4String ConvertToString(G4bool boolVal)
#define INT_MAX
Definition templates.hh:90