52 #define __func__ __FUNCTION__
69 return GetManager()->GetNumberOfCreatedSpecies();
84 fMoleculeDefinition = moleculeDef;
88 fMoleculeID = GetManager()->Insert(moleculeDef,
91 fElectronOccupancy = 0;
95 fDynMass = fMoleculeDefinition->GetMass();
97 fDynDiffusionCoefficient = fMoleculeDefinition->GetDiffusionCoefficient();
98 fDynVanDerVaalsRadius = fMoleculeDefinition->GetVanDerVaalsRadius();
99 fDynDecayTime = fMoleculeDefinition->GetDecayTime();
101 fName = fMoleculeDefinition->GetName();
105 fFormatedName = fMoleculeDefinition->GetFormatedName();
106 fFormatedName +=
"^";
107 fFormatedName +=
"{";
109 fFormatedName +=
"}";
112 fIsFinalized =
false;
120 errMsg <<
"This molecular configuration " << GetName()
121 <<
" is already finalized. Therefore its "
122 " properties cannot be changed.";
123 G4Exception(
"G4MolecularConfiguration::MakeExceptionIfFinalized",
156 G4MolecularConfigurationManager::MolElectronConfTable::iterator it1;
157 G4MolecularConfigurationManager::ElectronOccupancyTable::
160 for (it1 = fElecOccTable.begin(); it1 != fElecOccTable.end(); it1++)
162 for (it2 = it1->second.begin(); it2 != it1->second.end(); it2++)
170 fElecOccTable.clear();
184 ElectronOccupancyTable& table2 = fElecOccTable[molDef];
185 ElectronOccupancyTable::iterator it = table2.find(eOcc);
187 if(it == table2.end())
189 table2[eOcc] = molConf;
194 errMsg <<
"The same molecular configuration seemed to be recorded twice";
196 "SetMolecularConfiguration(const G4MoleculeDefinition* molDef,"
197 "const G4ElectronOccupancy& eOcc,"
198 "G4MolecularConfiguration* molConf)",
207 fMolConfPerID.push_back(molConf);
210 return fLastMoleculeID;
222 MolElectronConfTable::iterator it1 = fElecOccTable.find(molDef);
224 if(it1 == fElecOccTable.end())
230 ElectronOccupancyTable& table2 = it1->second;
231 ElectronOccupancyTable::iterator it2 = table2.find(eOcc);
235 if (it2 == table2.end())
241 return &(it2->first);
251 MolElectronConfTable::iterator it1 = fElecOccTable.find(molDef);
253 if(it1 == fElecOccTable.end())
return 0;
255 ElectronOccupancyTable& table2 = it1->second;
256 ElectronOccupancyTable::iterator it = table2.find(eOcc);
258 if(it == table2.end())
279 ChargeTable& table2 = fChargeTable[molDef];
280 ChargeTable::iterator it = table2.find(charge);
282 if(it == table2.end())
284 table2[charge] = molConf;
290 errMsg <<
"The same molecular configuration seemed to be recorded twice";
292 "SetMolecularConfiguration(const G4MoleculeDefinition* molDef,"
294 "G4MolecularConfiguration* molConf)",
299 fMolConfPerID.push_back(molConf);
301 return fLastMoleculeID;
313 MolChargeConfTable::iterator it1 = fChargeTable.find(molDef);
315 if(it1 == fChargeTable.end())
return 0;
317 ChargeTable& table2 = it1->second;
318 ChargeTable::iterator it = table2.find(charge);
320 if(it == table2.end())
430 if (fgManager)
delete fgManager;
442 fMoleculeDefinition = moleculeDef;
444 fMoleculeID = GetManager()->Insert(moleculeDef,
447 fElectronOccupancy = GetManager()->FindCommonElectronOccupancy(moleculeDef,
458 - fElectronOccupancy->GetTotalOccupancy()
460 fDynMass = fMoleculeDefinition->GetMass();
462 fDynDiffusionCoefficient = fMoleculeDefinition->GetDiffusionCoefficient();
463 fDynVanDerVaalsRadius = fMoleculeDefinition->GetVanDerVaalsRadius();
464 fDynDecayTime = fMoleculeDefinition->GetDecayTime();
466 fName = fMoleculeDefinition->GetName();
470 fFormatedName = fMoleculeDefinition->GetFormatedName();
471 fFormatedName +=
"^";
472 fFormatedName +=
"{";
474 fFormatedName +=
"}";
485 fIsFinalized =
false;
494 fMoleculeDefinition = moleculeDef;
496 fMoleculeID = GetManager()->Insert(moleculeDef,
499 fElectronOccupancy = 0;
502 fDynMass = fMoleculeDefinition->
GetMass();
504 fDynDiffusionCoefficient = fMoleculeDefinition->GetDiffusionCoefficient();
505 fDynVanDerVaalsRadius = fMoleculeDefinition->GetVanDerVaalsRadius();
506 fDynDecayTime = fMoleculeDefinition->GetDecayTime();
508 fName = fMoleculeDefinition->GetName();
512 fFormatedName = fMoleculeDefinition->GetFormatedName();
513 fFormatedName +=
"^";
514 fFormatedName +=
"{";
516 fFormatedName +=
"}";
522 fIsFinalized =
false;
529 if (fgManager) fgManager->RemoveMolecularConfigurationFromTable(
this);
549 newElectronOccupancy);
554 newElectronOccupancy);
591 CheckElectronOccupancy(__func__);
597 return ChangeConfiguration(newElectronOccupancy);
608 CheckElectronOccupancy(__func__);
611 if (newElectronOccupancy.
GetOccupancy(IonizedLevel) != 0)
617 G4String errMsg =
"There is no electron on the orbit "
619 +
" you want to free. The molecule's name you want to ionized is "
621 G4Exception(
"G4MolecularConfiguration::IonizeMolecule",
631 return ChangeConfiguration(newElectronOccupancy);
640 CheckElectronOccupancy(__func__);
643 return ChangeConfiguration(newElectronOccupancy);
653 CheckElectronOccupancy(__func__);
662 G4String errMsg =
"There is already no electron into the orbit "
664 +
" you want to free. The molecule's name is " + GetName();
665 G4Exception(
"G4MolecularConfiguration::RemoveElectron",
672 return ChangeConfiguration(newElectronOccupancy);
682 CheckElectronOccupancy(__func__);
685 if (newElectronOccupancy.
GetOccupancy(orbitToFree) >= 1)
692 G4String errMsg =
"There is no electron on the orbit "
694 +
" you want to free. The molecule's name is " + GetName();
695 G4Exception(
"G4MolecularConfiguration::MoveOneElectron",
702 return ChangeConfiguration(newElectronOccupancy);
732 return fFormatedName;
739 return fMoleculeDefinition->GetAtomsNumber();
746 CheckElectronOccupancy(__func__);
747 return fElectronOccupancy->GetTotalOccupancy();
754 G4cout <<
"-------------- Start Printing State " << GetName()
755 <<
" ---------------" <<
G4endl;
757 if (fElectronOccupancy)
759 G4cout <<
"--------------Print electronic state of " << GetName()
760 <<
"---------------" <<
G4endl;
761 fElectronOccupancy->DumpInfo();
762 if(fElectronOccupancy==fMoleculeDefinition->GetGroundStateElectronOccupancy())
769 G4cout <<
"--- No electron occupancy set up ---" <<
G4endl;
782 G4cout <<
"-------------- End Of State " << GetName()
783 <<
" -----------------------" <<
G4endl;
789 const vector<const G4MolecularDissociationChannel*>*
793 return fMoleculeDefinition->GetDecayChannels(
this);
800 if(fMoleculeDefinition)
return fMoleculeDefinition->GetPDGEncoding();
801 else G4Exception(
"G4MolecularConfiguration::GetMoleculeID",
804 "You should first enter a molecule defintion");
813 const char* pDelimeter = strrchr(path,
'\\');
814 if (pDelimeter) path = pDelimeter + 1;
816 pDelimeter = strrchr(path,
'/');
817 if (pDelimeter) path = pDelimeter + 1;
826 if (fElectronOccupancy == 0)
831 <<
"No G4ElectronOccupancy was defined for molecule definition : "
832 << fMoleculeDefinition->GetName()
833 <<
". The definition was probably defined using the charge state, "
834 "rather than electron state.";
849 LabelTable::iterator it = tmpMap.find(*molConf->
fLabel);
851 if(it == tmpMap.end())
853 tmpMap[*(molConf->
fLabel)] = molConf;
858 errMsg <<
"The same molecular configuration seemed to be recorded twice";
860 "SetMolecularConfiguration(const G4MoleculeDefinition* molDef,"
861 "const G4String& label,"
862 "G4MolecularConfiguration* molConf)",
872 UserIDTable::iterator it = fUserIDTable.find(userID);
874 if(it == fUserIDTable.end())
876 fUserIDTable[userID] = molecule;
878 else if(molecule != it->second)
883 description <<
"The user identifier " << userID
884 <<
" was already given in another configuration in the table"
886 G4Exception(
"G4MolecularConfiguration::G4MolecularConfigurationManager::AddUserID",
887 "CONF_ALREADY_RECORDED",
898 MolElectronConfTable::iterator it1 =
900 MolElectronConfTable::iterator end = fElecOccTable.end();
902 if (it1 == end)
return;
904 std::map<G4ElectronOccupancy, G4MolecularConfiguration*, comparator>::
908 if (it2 == it1->second.end())
return;
925 MolLabelConfTable::iterator it1 = fLabelTable.find(molDef);
927 if(it1 == fLabelTable.end())
return 0;
929 LabelTable& table2 = it1->second;
931 LabelTable::iterator it2 = table2.find(label);
935 if(it2 == table2.end())
return 0;
945 if(moleculeID > (
int) fMolConfPerID.size() ||
946 moleculeID < 0)
return 0;
948 return fMolConfPerID[moleculeID];
960 LabelTable& tmpMap = fLabelTable[molDef];
961 LabelTable::iterator it = tmpMap.find(label);
963 if(it == tmpMap.end())
966 tmpMap[label] = molConf;
973 errMsg <<
"The same molecular configuration seemed to be recorded twice";
975 "SetMolecularConfiguration(const G4MoleculeDefinition* molDef,"
976 "const G4String& label,"
977 "G4MolecularConfiguration* molConf)",
981 fMolConfPerID.push_back(molConf);
983 return fLastMoleculeID;
1010 bool& wasAlreadyCreated)
1012 wasAlreadyCreated =
false;
1022 wMsg <<
"The molecular configuration for the definition named "
1024 <<
" with charge " << charge <<
" has already been created "
1025 "but with NO label";
1026 G4Exception(
"G4MolecularConfiguration::CreateMolecularConfiguration",
1031 else if(*(molConf->
fLabel) ==
"" )
1035 else if(*(molConf->
fLabel) != label)
1038 errMsg <<
"The molecular configuration for the definition named "
1040 <<
" with charge " << charge <<
" has already been created "
1041 "but with a different label :"
1043 G4Exception(
"G4MolecularConfiguration::CreateMolecularConfiguration",
1055 wMsg <<
"The molecular configuration for the definition named "
1057 <<
" with label " << label <<
" has already been created.";
1058 G4Exception(
"G4MolecularConfiguration::CreateMolecularConfiguration",
1066 errMsg <<
"The molecular configuration for the definition named "
1068 <<
" with label " << label <<
" has already been created "
1069 "BUT with a different user ID :"
1071 G4Exception(
"G4MolecularConfiguration::CreateMolecularConfiguration",
1078 wasAlreadyCreated =
true;
1087 GetManager()->AddUserID(userIdentifier, newConf);
1101 bool& wasAlreadyCreated)
1103 wasAlreadyCreated =
false;
1107 if(preRegisteredMolConf)
1111 wasAlreadyCreated =
true;
1112 return preRegisteredMolConf;
1132 errMsg <<
"A molecular configuration for the definition named "
1133 << molDef->
GetName() <<
" has already been created "
1134 "and recorded with a different user ID "
1136 G4Exception(
"G4MolecularConfiguration::CreateMolecularConfiguration",
1143 errMsg <<
"A molecular configuration for the definition named "
1144 << molDef->
GetName() <<
" has already been created.";
1145 G4Exception(
"G4MolecularConfiguration::CreateMolecularConfiguration",
1149 wasAlreadyCreated =
true;
1159 GetManager()->AddUserID(userIdentifier, newConf);
1168 return CreateMolecularConfiguration(userIdentifier,
1183 bool& wasAlreadyCreated)
1185 assert(label !=
"");
1186 wasAlreadyCreated =
false;
1193 && *molConf->
fLabel == label)
1195 wasAlreadyCreated =
true;
1198 else if(molConf->
fLabel == 0)
1200 wasAlreadyCreated =
true;
1204 else if(*molConf->
fLabel ==
"")
1206 wasAlreadyCreated =
true;
1213 errMsg <<
"A molecular configuration for the definition named "
1215 <<
" has already been created "
1219 G4Exception(
"G4MolecularConfiguration::CreateMolecularConfiguration",
1233 GetManager()->AddUserID(userIdentifier, newConf);
1250 bool& wasAlreadyCreated)
1252 assert(label !=
"");
1253 wasAlreadyCreated =
false;
1266 wasAlreadyCreated =
true;
1269 else if(molConf->
fLabel == 0)
1271 wasAlreadyCreated =
true;
1275 else if(*molConf->
fLabel ==
"")
1277 wasAlreadyCreated =
true;
1287 errMsg <<
"A molecular configuration for the definition named "
1289 <<
" has already been created "
1292 <<
" and possible different electronic state";
1293 G4Exception(
"G4MolecularConfiguration::CreateMolecularConfiguration",
1306 GetManager()->AddUserID(userIdentifier, newConf);
1323 MolElectronConfTable::iterator it1 = fElecOccTable.find(molDef);
1325 if(it1 == fElecOccTable.end())
1330 ElectronOccupancyTable& table2 = it1->second;
1331 ElectronOccupancyTable::iterator it = table2.find(eOcc);
1333 if(it == table2.end())
1355 MolChargeConfTable::iterator it1 = fChargeTable.find(molDef);
1357 if(it1 == fChargeTable.end())
1365 ChargeTable& table2 = it1->second;
1366 ChargeTable::iterator it = table2.find(charge);
1368 if(it == table2.end())
1389 G4String moleculeName = fMoleculeDefinition->GetName();
1390 WRITE(out, moleculeName);
1396 WRITE(out,fDynDiffusionCoefficient);
1397 WRITE(out,fDynVanDerVaalsRadius);
1398 WRITE(out,fDynDecayTime);
1399 WRITE(out,fDynMass);
1400 WRITE(out,fDynCharge);
1401 WRITE(out,fMoleculeID);
1402 WRITE(out,fFormatedName);
1404 WRITE(out,fIsFinalized);
1412 READ(in, moleculeName);
1413 fMoleculeDefinition =
1424 READ(in,fDynDiffusionCoefficient);
1425 READ(in,fDynVanDerVaalsRadius);
1426 READ(in,fDynDecayTime);
1428 READ(in,fDynCharge);
1429 READ(in,fMoleculeID);
1430 READ(in,fFormatedName);
1432 READ(in,fIsFinalized);
1448 fMoleculeDefinition = 0;
1449 fElectronOccupancy = 0;
1450 if(fElectronOccupancy)
1452 GetManager()->Insert(fMoleculeDefinition, *fElectronOccupancy,
this);
1453 fElectronOccupancy =
1454 GetManager()->FindCommonElectronOccupancy(fMoleculeDefinition,
1455 *fElectronOccupancy);
1459 GetManager()->RecordNewlyLabeledConfiguration(
this);
1464 fMoleculeID = GetManager()->Insert(fMoleculeDefinition, *fLabel,
this);
1468 fMoleculeID = GetManager()->Insert(fMoleculeDefinition, fDynCharge,
this);
1476 fUserIdentifier = userID;
1477 GetManager()->AddUserID(userID,
this);
1485 return pow(10, 4.311
1486 - 2.722e3/temperature_K
1487 + 8.565e5/(temperature_K *temperature_K)
1488 - 1.181e8/(temperature_K*temperature_K*temperature_K ))*1e-9*
m2/
s;
1497 double D_water_0 = DiffCoeffWater(fgTemperature);
1498 double D_water_f = DiffCoeffWater(temperature_K);
1500 G4cout <<
"Scaling factor = " << D_water_f/D_water_0 <<
G4endl;
1509 double D_f = D_water_f * D_0 /D_water_0;
1518 if(
bool(fDiffParam) ==
false)
1528 ScaleAllDiffusionCoefficientsOnWater(temperature);
1529 fgTemperature = temperature;
1536 return fgTemperature;
1545 for(
auto it : fMolConfPerID)
1547 if(it->GetUserID() == userID)
return it;
1564 const std::vector<G4MolecularConfiguration*>& species =
1565 GetManager()->GetAllSpecies();
1567 for(
size_t i = 0; i < species.size() ; ++i)
1569 species[i]->Finalize();
G4double GetDiffusionCoefficient() const
void SetLabel(const G4String &)
static G4MolecularConfiguration * Load(std::istream &)
static constexpr double m2
const G4String & GetName() const
void Serialize(std::ostream &)
G4MoleculeDefinition * GetMoleculeDefinition(const G4String &, bool mustExist=true)
~G4MolecularConfiguration()
std::ostringstream G4ExceptionDescription
void CreateDefaultDiffCoeffParam()
G4MolecularConfiguration * ChangeConfiguration(const G4ElectronOccupancy &newElectronOccupancy)
static double fgTemperature
static G4Mutex fManagerCreationMutex
static G4MolecularConfiguration * GetMolecularConfiguration(const G4MoleculeDefinition *, const G4String &label)
G4double fDynDiffusionCoefficient
void AddUserID(const G4String &name, G4MolecularConfiguration *molecule)
void WRITE(std::ostream &out, const T &toBeSaved)
static G4String ConvertToString(G4bool boolVal)
G4double GetNbElectrons() const
const std::vector< const G4MolecularDissociationChannel * > * GetDecayChannel() const
G4MolecularConfiguration * GetOrCreateMolecularConfiguration(const G4MoleculeDefinition *molDef, const G4ElectronOccupancy &eOcc)
const G4ElectronOccupancy * FindCommonElectronOccupancy(const G4MoleculeDefinition *molDef, const G4ElectronOccupancy &eOcc)
const G4ElectronOccupancy * GetElectronOccupancy() const
G4int Insert(const G4MoleculeDefinition *molDef, const G4ElectronOccupancy &eOcc, G4MolecularConfiguration *molConf)
void SetUserID(const G4String &userID)
G4int GetFakeParticleID() const
static G4double GetGlobalTemperature()
static G4MolecularConfigurationManager * fgManager
static void ScaleAllDiffusionCoefficientsOnWater(double temperature_K)
void RecordNewlyLabeledConfiguration(G4MolecularConfiguration *molConf)
G4GLOB_DLL std::ostream G4cout
G4int GetOccupancy(G4int orbit) const
static int GetNumberOfSpecies()
G4MolecularConfiguration * IonizeMolecule(G4int)
G4MolecularConfiguration * AddElectron(G4int orbit, G4int n=1)
G4MolecularConfiguration::G4MolecularConfigurationManager MolecularConfigurationManager
static void FinalizeAll()
G4int AddElectron(G4int orbit, G4int number=1)
void CheckElectronOccupancy(const char *line) const
static double DiffCoeffWater(double temperature_K)
static G4MoleculeTable * Instance()
static void DeleteManager()
G4MolecularConfiguration * MoveOneElectron(G4int, G4int)
void SetDiffusionCoefficient(G4double)
G4MolecularConfiguration & operator=(G4MolecularConfiguration &right)
static void SetGlobalTemperature(G4double)
G4int GetNbElectrons() const
G4ConfigurationIterator GetConfigurationIterator()
static G4MolecularConfigurationManager * GetManager()
static G4MolecularConfiguration * GetOrCreateMolecularConfiguration(const G4MoleculeDefinition *)
static constexpr double s
static double ReturnDefaultDiffCoeff(const G4Material *, double, const G4MolecularConfiguration *molConf)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
G4MolecularConfiguration(const G4MoleculeDefinition *, const G4ElectronOccupancy &, const G4String &label="")
const char * removePath(const char *path)
const G4String & GetFormatedName() const
void RemoveMolecularConfigurationFromTable(G4MolecularConfiguration *)
G4int GetAtomsNumber() const
const G4String & GetName() const
const G4MoleculeDefinition * GetDefinition() const
const G4String & GetLabel() const
void Unserialize(std::istream &)
G4MolecularConfiguration * GetMolecularConfiguration(const G4MoleculeDefinition *molDef, const G4ElectronOccupancy &eOcc)
void READ(std::istream &in, T &toBeSaved)
const G4ElectronOccupancy * GetGroundStateElectronOccupancy() const
G4MolecularConfiguration * RemoveElectron(G4int, G4int number=1)
const G4ElectronOccupancy * fElectronOccupancy
G4MolecularConfiguration * ExciteMolecule(G4int)
~G4MolecularConfigurationManager()
void MakeExceptionIfFinalized()
static constexpr double m2
const G4MoleculeDefinition * fMoleculeDefinition
static constexpr double kelvin
G4int RemoveElectron(G4int orbit, G4int number=1)
static G4MolecularConfiguration * CreateMolecularConfiguration(const G4String &userIdentifier, const G4MoleculeDefinition *, bool &wasAlreadyCreated)