Geant4  10.03.p03
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 // $Id: G4MolecularConfiguration.cc 101354 2016-11-15 08:27:51Z gcosmo $
27 //
28 // Author: Mathieu Karamitros (kara (AT) cenbg . in2p3 . fr)
29 //
30 // History:
31 // -----------
32 // 10 Oct 2011 M.Karamitros created
33 //
34 // -------------------------------------------------------------------
35 
37 #include "G4MoleculeDefinition.hh"
38 #include "G4UIcommand.hh"
39 #include "G4AllocatorList.hh"
40 #include "G4AutoLock.hh"
41 #include "G4MoleculeTable.hh"
42 #include "G4Serialize.hh"
43 #include <fstream>
44 
45 using CLHEP::m2;
46 using CLHEP::s;
47 using CLHEP::kelvin;
48 
49 using namespace std;
50 
51 #if defined ( WIN32 )
52 #define __func__ __FUNCTION__
53 #endif
54 
55 /*G4ThreadLocal*/G4double G4MolecularConfiguration::fgTemperature = 298; // 310*kelvin;
56 // 25°C, used to shoot an energy
57 
58 //______________________________________________________________________________
59 // G4MolecularConfigurationManager
62 
64 
66 
68 {
69  return GetManager()->GetNumberOfCreatedSpecies();
70 }
71 
73  double,
75  molConf)
76 {
77  return molConf->fDynDiffusionCoefficient;
78 }
79 
81  const G4String& label,
82  int charge)
83 {
84  fMoleculeDefinition = moleculeDef;
85 
86  fLabel = new G4String(label);
87 
88  fMoleculeID = GetManager()->Insert(moleculeDef,
89  label,
90  this);
91  fElectronOccupancy = 0;
92 
93  fDynCharge = charge;
94 
95  fDynMass = fMoleculeDefinition->GetMass();
96 
97  fDynDiffusionCoefficient = fMoleculeDefinition->GetDiffusionCoefficient();
98  fDynVanDerVaalsRadius = fMoleculeDefinition->GetVanDerVaalsRadius();
99  fDynDecayTime = fMoleculeDefinition->GetDecayTime();
100 
101  fName = fMoleculeDefinition->GetName();
102  fName += "^";
103  fName += G4UIcommand::ConvertToString(fDynCharge);
104 
105  fFormatedName = fMoleculeDefinition->GetFormatedName();
106  fFormatedName += "^";
107  fFormatedName += "{";
108  fFormatedName += G4UIcommand::ConvertToString(fDynCharge);
109  fFormatedName += "}";
110 
112  fIsFinalized = false;
113 }
114 
116 {
117  if(fIsFinalized)
118  {
119  G4ExceptionDescription errMsg;
120  errMsg << "This molecular configuration " << GetName()
121  << " is already finalized. Therefore its "
122  " properties cannot be changed.";
123  G4Exception("G4MolecularConfiguration::MakeExceptionIfFinalized",
124  "CONF_FINALIZED",FatalException,errMsg);
125  }
126 }
127 
128 //______________________________________________________________________________
129 
132 {
133  if (!fgManager)
134  {
136  if (!fgManager) // double check for MT
137  {
138  fgManager = new G4MolecularConfiguration::
140  }
141  lock.unlock();
142  }
143 
144  return fgManager;
145 }
146 
147 //______________________________________________________________________________
148 
151 {
152 // G4cout << "Does G4AllocatorList exists= ";
153 // G4cout << (G4AllocatorList::GetAllocatorListIfExist() ? "true":"false")
154 // << G4endl;
155 
156  G4MolecularConfigurationManager::MolElectronConfTable::iterator it1;
157  G4MolecularConfigurationManager::ElectronOccupancyTable::
158  iterator it2;
159 
160  for (it1 = fElecOccTable.begin(); it1 != fElecOccTable.end(); it1++)
161  {
162  for (it2 = it1->second.begin(); it2 != it1->second.end(); it2++)
163  {
164  if (it2->second)
165  {
166  delete it2->second;
167  }
168  }
169  }
170  fElecOccTable.clear();
171  fgManager = 0;
172 }
173 
174 //______________________________________________________________________________
175 // G4MolecularConfigurationManager
179  const G4ElectronOccupancy& eOcc,
180  G4MolecularConfiguration* molConf)
181 {
182  //G4AutoLock lock(&fMoleculeCreationMutex);
183 
184  ElectronOccupancyTable& table2 = fElecOccTable[molDef];
185  ElectronOccupancyTable::iterator it = table2.find(eOcc);
186 
187  if(it == table2.end())
188  {
189  table2[eOcc] = molConf;
190  }
191  else
192  {
193  G4ExceptionDescription errMsg;
194  errMsg << "The same molecular configuration seemed to be recorded twice";
195  G4Exception("G4MolecularConfigurationManager::"
196  "SetMolecularConfiguration(const G4MoleculeDefinition* molDef,"
197  "const G4ElectronOccupancy& eOcc,"
198  "G4MolecularConfiguration* molConf)",
199  "",
201  errMsg
202  );
203  }
204 
205  fLastMoleculeID++;
206 
207  fMolConfPerID.push_back(molConf);
208 
209  //lock.unlock();
210  return fLastMoleculeID;
211 }
212 
213 //______________________________________________________________________________
214 
215 const G4ElectronOccupancy*
218  const G4ElectronOccupancy& eOcc)
219 {
220  //G4AutoLock lock(&fMoleculeCreationMutex);
221 
222  MolElectronConfTable::iterator it1 = fElecOccTable.find(molDef);
223 
224  if(it1 == fElecOccTable.end())
225  {
226  // TODO = handle exception ?
227  return 0;
228  }
229 
230  ElectronOccupancyTable& table2 = it1->second;
231  ElectronOccupancyTable::iterator it2 = table2.find(eOcc);
232 
233  //lock.unlock();
234 
235  if (it2 == table2.end())
236  {
237  // TODO = handle exception ?
238  return 0;
239  }
240 
241  return &(it2->first);
242 }
243 
244 //______________________________________________________________________________
245 
249  const G4ElectronOccupancy& eOcc)
250 {
251  MolElectronConfTable::iterator it1 = fElecOccTable.find(molDef);
252 
253  if(it1 == fElecOccTable.end()) return 0;
254 
255  ElectronOccupancyTable& table2 = it1->second;
256  ElectronOccupancyTable::iterator it = table2.find(eOcc);
257 
258  if(it == table2.end())
259  {
260  return 0;
261  }
262  else
263  {
264  return it->second;
265  }
266 
267  return 0;
268 }
269 
270 //______________________________________________________________________________
271 
274  int charge,
275  G4MolecularConfiguration* molConf)
276 {
277 
278  //G4AutoLock lock(&fMoleculeCreationMutex);
279  ChargeTable& table2 = fChargeTable[molDef];
280  ChargeTable::iterator it = table2.find(charge);
281 
282  if(it == table2.end())
283  {
284  table2[charge] = molConf;
285  }
286  else
287  {
288  //lock.unlock();
289  G4ExceptionDescription errMsg;
290  errMsg << "The same molecular configuration seemed to be recorded twice";
291  G4Exception("G4MolecularConfigurationManager::"
292  "SetMolecularConfiguration(const G4MoleculeDefinition* molDef,"
293  "int charge,"
294  "G4MolecularConfiguration* molConf)",
295  "", FatalException, errMsg);
296  }
297 
298  fLastMoleculeID++;
299  fMolConfPerID.push_back(molConf);
300  //lock.unlock();
301  return fLastMoleculeID;
302 }
303 
304 //______________________________________________________________________________
305 
309  int charge)
310 {
311  //G4AutoLock lock(&fMoleculeCreationMutex);
312 
313  MolChargeConfTable::iterator it1 = fChargeTable.find(molDef);
314 
315  if(it1 == fChargeTable.end()) return 0;
316 
317  ChargeTable& table2 = it1->second;
318  ChargeTable::iterator it = table2.find(charge);
319 
320  if(it == table2.end())
321  {
322  return 0;
323  }
324  else
325  {
326  return it->second;
327  }
328 
329  return 0;
330 
331  //lock.unlock();
332  return 0;
333 }
334 
335 //______________________________________________________________________________
336 // Static method in G4MolecularConfiguration
340 {
341  if (molDef->GetGroundStateElectronOccupancy())
342  {
343  const G4ElectronOccupancy& elecOcc =
345  G4MolecularConfiguration* molConf =
346  GetManager()->GetMolecularConfiguration(molDef, elecOcc);
347 
348  if (molConf)
349  {
350  return molConf;
351  }
352  else
353  {
354  G4MolecularConfiguration* newConf =
355  new G4MolecularConfiguration(molDef,
356  elecOcc);
357  newConf->SetUserID(molDef->GetName());
358  return newConf;
359  }
360  }
361  else
362  {
363  G4MolecularConfiguration* molConf =
364  GetManager()->GetMolecularConfiguration(molDef, molDef->GetCharge());
365  if(molConf)
366  {
367  return molConf;
368  }
369  else
370  {
371  G4MolecularConfiguration* newConf =
372  new G4MolecularConfiguration(molDef, molDef->GetCharge());
373  newConf->SetUserID(molDef->GetName());
374  return newConf;
375  }
376  }
377 }
378 
379 //______________________________________________________________________________
380 
384  const G4ElectronOccupancy& elecOcc)
385 {
386  return GetManager()->GetOrCreateMolecularConfiguration(molDef, elecOcc);
387 
388 // G4MolecularConfiguration* molConf =
389 // GetManager()->GetMolecularConfiguration(molDef, elecOcc);
390 //
391 // if (molConf)
392 // {
393 // return molConf;
394 // }
395 // else
396 // {
397 // G4MolecularConfiguration* newConf =
398 // new G4MolecularConfiguration(molDef, elecOcc);
399 // return newConf;
400 // }
401 }
402 
403 //______________________________________________________________________________
404 
408  int charge)
409 {
410  G4MolecularConfiguration* molConf =
411  GetManager()->GetMolecularConfiguration(molDef, charge);
412 
413  if(molConf)
414  {
415  return molConf;
416  }
417  else
418  {
419  G4MolecularConfiguration* newConf =
420  new G4MolecularConfiguration(molDef, charge);
421  return newConf;
422  }
423 }
424 
425 //______________________________________________________________________________
426 
428 {
430  if (fgManager) delete fgManager;
431  fgManager = 0;
432  lock.unlock();
433 }
434 
435 //______________________________________________________________________________
436 // G4MolecularConfiguration
439  const G4ElectronOccupancy& elecOcc,
440  const G4String& label)
441 {
442  fMoleculeDefinition = moleculeDef;
443 
444  fMoleculeID = GetManager()->Insert(moleculeDef,
445  elecOcc,
446  this);
447  fElectronOccupancy = GetManager()->FindCommonElectronOccupancy(moleculeDef,
448  elecOcc);
449 
450  /*
451  fgManager->fTable[fMoleculeDefinition][elecOcc] = this;
452  std::map<G4ElectronOccupancy, G4MolecularConfiguration*, comparator>::iterator it ;
453  it = fgManager->fTable[moleculeDef].find(elecOcc);
454  fElectronOccupancy = &(it->first);
455  */
456 
457  fDynCharge = fMoleculeDefinition->GetNbElectrons()
458  - fElectronOccupancy->GetTotalOccupancy()
459  + moleculeDef->GetCharge();
460  fDynMass = fMoleculeDefinition->GetMass();
461 
462  fDynDiffusionCoefficient = fMoleculeDefinition->GetDiffusionCoefficient();
463  fDynVanDerVaalsRadius = fMoleculeDefinition->GetVanDerVaalsRadius();
464  fDynDecayTime = fMoleculeDefinition->GetDecayTime();
465 
466  fName = fMoleculeDefinition->GetName();
467  fName += "^";
468  fName += G4UIcommand::ConvertToString(fDynCharge);
469 
470  fFormatedName = fMoleculeDefinition->GetFormatedName();
471  fFormatedName += "^";
472  fFormatedName += "{";
473  fFormatedName += G4UIcommand::ConvertToString(fDynCharge);
474  fFormatedName += "}";
475 
476  fLabel = 0; // let it here
477 
478  if(label != "")
479  {
480  SetLabel(label);
481  }
482 
484 
485  fIsFinalized = false;
486 }
487 
488 //______________________________________________________________________________
489 
492  int charge)
493 {
494  fMoleculeDefinition = moleculeDef;
495 
496  fMoleculeID = GetManager()->Insert(moleculeDef,
497  charge,
498  this);
499  fElectronOccupancy = 0;
500 
501  fDynCharge = charge;
502  fDynMass = fMoleculeDefinition->GetMass();
503 
504  fDynDiffusionCoefficient = fMoleculeDefinition->GetDiffusionCoefficient();
505  fDynVanDerVaalsRadius = fMoleculeDefinition->GetVanDerVaalsRadius();
506  fDynDecayTime = fMoleculeDefinition->GetDecayTime();
507 
508  fName = fMoleculeDefinition->GetName();
509  fName += "^";
510  fName += G4UIcommand::ConvertToString(fDynCharge);
511 
512  fFormatedName = fMoleculeDefinition->GetFormatedName();
513  fFormatedName += "^";
514  fFormatedName += "{";
515  fFormatedName += G4UIcommand::ConvertToString(fDynCharge);
516  fFormatedName += "}";
517 
518  fLabel = 0;
519 
521 
522  fIsFinalized = false;
523 }
524 
525 //______________________________________________________________________________
526 
528 {
529  if (fgManager) fgManager->RemoveMolecularConfigurationFromTable(this);
530 
531 // if (G4AllocatorList::GetAllocatorListIfExist())
532 // {
533 // if (fElectronOccupancy)
534 // {
535 // delete fElectronOccupancy;
536 // fElectronOccupancy = 0;
537 // }
538 // }
539 }
540 
541 //______________________________________________________________________________
542 
545 ChangeConfiguration(const G4ElectronOccupancy& newElectronOccupancy)
546 {
547  G4MolecularConfiguration* output =
548  GetManager()->GetMolecularConfiguration(fMoleculeDefinition,
549  newElectronOccupancy);
550 
551  if (!output)
552  {
553  output = new G4MolecularConfiguration(fMoleculeDefinition,
554  newElectronOccupancy);
555  }
556  return output;
557 }
558 
559 //______________________________________________________________________________
560 
563 {
564  G4MolecularConfiguration* output =
565  GetManager()->GetMolecularConfiguration(fMoleculeDefinition, charge);
566 
567  if (!output)
568  {
569  output = new G4MolecularConfiguration(fMoleculeDefinition, charge);
570  }
571  return output;
572 }
573 
574 //______________________________________________________________________________
575 
578 {
579 // if (&right == this) return *this;
580  return *this;
581 }
582 
583 //______________________________________________________________________________
584 
589 {
590 // MakeExceptionIfFinalized();
591  CheckElectronOccupancy(__func__);
592  G4ElectronOccupancy newElectronOccupancy(*fElectronOccupancy);
593 
594  newElectronOccupancy.RemoveElectron(ExcitedLevel, 1);
595  newElectronOccupancy.AddElectron(5, 1);
596 
597  return ChangeConfiguration(newElectronOccupancy);
598 }
599 
600 //______________________________________________________________________________
601 
606 {
607 // MakeExceptionIfFinalized();
608  CheckElectronOccupancy(__func__);
609  G4ElectronOccupancy newElectronOccupancy(*fElectronOccupancy);
610 
611  if (newElectronOccupancy.GetOccupancy(IonizedLevel) != 0)
612  {
613  newElectronOccupancy.RemoveElectron(IonizedLevel, 1);
614  }
615  else
616  {
617  G4String errMsg = "There is no electron on the orbit "
618  + G4UIcommand::ConvertToString(IonizedLevel)
619  + " you want to free. The molecule's name you want to ionized is "
620  + GetName();
621  G4Exception("G4MolecularConfiguration::IonizeMolecule",
622  "",
624  errMsg);
625  PrintState();
626  }
627 
628  // DEBUG
629  // PrintState();
630 
631  return ChangeConfiguration(newElectronOccupancy);
632 }
633 
634 //______________________________________________________________________________
635 
637  G4int number)
638 {
639 // MakeExceptionIfFinalized();
640  CheckElectronOccupancy(__func__);
641  G4ElectronOccupancy newElectronOccupancy(*fElectronOccupancy);
642  newElectronOccupancy.AddElectron(orbit, number);
643  return ChangeConfiguration(newElectronOccupancy);
644 }
645 
646 //______________________________________________________________________________
647 
650  G4int number)
651 {
652 // MakeExceptionIfFinalized();
653  CheckElectronOccupancy(__func__);
654  G4ElectronOccupancy newElectronOccupancy(*fElectronOccupancy);
655 
656  if (newElectronOccupancy.GetOccupancy(orbit) != 0)
657  {
658  newElectronOccupancy.RemoveElectron(orbit, number);
659  }
660  else
661  {
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",
666  "",
667  JustWarning,
668  errMsg);
669  PrintState();
670  }
671 
672  return ChangeConfiguration(newElectronOccupancy);
673 }
674 
675 //______________________________________________________________________________
676 
679  G4int orbitToFill)
680 {
681 // MakeExceptionIfFinalized();
682  CheckElectronOccupancy(__func__);
683  G4ElectronOccupancy newElectronOccupancy(*fElectronOccupancy);
684 
685  if (newElectronOccupancy.GetOccupancy(orbitToFree) >= 1)
686  {
687  newElectronOccupancy.RemoveElectron(orbitToFree, 1);
688  newElectronOccupancy.AddElectron(orbitToFill, 1);
689  }
690  else
691  {
692  G4String errMsg = "There is no electron on the orbit "
693  + G4UIcommand::ConvertToString(orbitToFree)
694  + " you want to free. The molecule's name is " + GetName();
695  G4Exception("G4MolecularConfiguration::MoveOneElectron",
696  "",
698  errMsg);
699  PrintState();
700  }
701 
702  return ChangeConfiguration(newElectronOccupancy);
703 }
704 
705 //______________________________________________________________________________
706 
708 {
709 // if (fName.isNull())
710 // {
711 // fName = fMoleculeDefinition->GetName();
712 // fName += "^";
713 // // fName+= "{";
714 // fName += G4UIcommand::ConvertToString(fDynCharge);
715 // // fName+= "}";
716 // }
717  return fName;
718 }
719 
720 //______________________________________________________________________________
721 
723 {
724 // if (fFormatedName.isNull())
725 // {
726 // fFormatedName = fMoleculeDefinition->GetFormatedName();
727 // fFormatedName += "^";
728 // fFormatedName += "{";
729 // fFormatedName += G4UIcommand::ConvertToString(fDynCharge);
730 // fFormatedName += "}";
731 // }
732  return fFormatedName;
733 }
734 
735 //______________________________________________________________________________
736 
738 {
739  return fMoleculeDefinition->GetAtomsNumber();
740 }
741 
742 //______________________________________________________________________________
743 
745 {
746  CheckElectronOccupancy(__func__);
747  return fElectronOccupancy->GetTotalOccupancy();
748 }
749 
750 //______________________________________________________________________________
751 
753 {
754  G4cout << "-------------- Start Printing State " << GetName()
755  << " ---------------" << G4endl;
756 
757  if (fElectronOccupancy)
758  {
759  G4cout << "--------------Print electronic state of " << GetName()
760  << "---------------" << G4endl;
761  fElectronOccupancy->DumpInfo();
762  if(fElectronOccupancy==fMoleculeDefinition->GetGroundStateElectronOccupancy())
763  {
764  G4cout<<"At ground state"<<G4endl;
765  }
766  }
767  else
768  {
769  G4cout << "--- No electron occupancy set up ---" << G4endl;
770  }
771 
772  G4cout << "Charge :"
773  << fDynCharge
774  << G4endl;
775 
776  if(fLabel)
777  {
778  G4cout << "Label :"
779  << GetLabel()
780  << G4endl;
781  }
782  G4cout << "-------------- End Of State " << GetName()
783  << " -----------------------" << G4endl;
784 }
785 
786 //______________________________________________________________________________
787 
788 // added - to be transformed in a "Decay method"
789 const vector<const G4MolecularDissociationChannel*>*
791 {
792  // if (fElectronOccupancy == 0) return 0;
793  return fMoleculeDefinition->GetDecayChannels(this);
794 }
795 
796 //______________________________________________________________________________
797 
799 {
800  if(fMoleculeDefinition) return fMoleculeDefinition->GetPDGEncoding();
801  else G4Exception("G4MolecularConfiguration::GetMoleculeID",
802  "",
804  "You should first enter a molecule defintion");
805 
806  return INT_MAX;
807 }
808 
809 //______________________________________________________________________________
810 
811 const char* removePath(const char* path)
812 {
813  const char* pDelimeter = strrchr(path, '\\');
814  if (pDelimeter) path = pDelimeter + 1;
815 
816  pDelimeter = strrchr(path, '/');
817  if (pDelimeter) path = pDelimeter + 1;
818 
819  return path;
820 }
821 
822 //______________________________________________________________________________
823 
824 void G4MolecularConfiguration::CheckElectronOccupancy(const char* function) const
825 {
826  if (fElectronOccupancy == 0)
827  {
828  G4String functionName(function);
829  G4ExceptionDescription description;
830  description
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.";
835 
836  G4Exception(functionName, "", FatalErrorInArgument, description);
837  }
838 }
839 
840 //______________________________________________________________________________
841 
844 {
845  //G4AutoLock lock(&fMoleculeCreationMutex);
846 
847  LabelTable& tmpMap = fLabelTable[molConf->fMoleculeDefinition];
848 
849  LabelTable::iterator it = tmpMap.find(*molConf->fLabel);
850 
851  if(it == tmpMap.end())
852  {
853  tmpMap[*(molConf->fLabel)] = molConf;
854  }
855  else
856  {
857  G4ExceptionDescription errMsg;
858  errMsg << "The same molecular configuration seemed to be recorded twice";
859  G4Exception("G4MolecularConfigurationManager::"
860  "SetMolecularConfiguration(const G4MoleculeDefinition* molDef,"
861  "const G4String& label,"
862  "G4MolecularConfiguration* molConf)",
863  "", FatalException, errMsg);
864  }
865 
866  //lock.unlock();
867 }
868 
870  G4MolecularConfiguration* molecule)
871 {
872  UserIDTable::iterator it = fUserIDTable.find(userID);
873 
874  if(it == fUserIDTable.end())
875  {
876  fUserIDTable[userID] = molecule;
877  }
878  else if(molecule != it->second)
879  {
880  // TODO improve exception
881  // exception
882  G4ExceptionDescription description;
883  description << "The user identifier " << userID
884  << " was already given in another configuration in the table"
885  << G4endl;
886  G4Exception("G4MolecularConfiguration::G4MolecularConfigurationManager::AddUserID",
887  "CONF_ALREADY_RECORDED",
889  description);
890  }
891 }
892 
893 //______________________________________________________________________________
894 
897 {
898  MolElectronConfTable::iterator it1 =
899  fElecOccTable.find(configuration->GetDefinition());
900  MolElectronConfTable::iterator end = fElecOccTable.end();
901 
902  if (it1 == end) return;
903 
904  std::map<G4ElectronOccupancy, G4MolecularConfiguration*, comparator>::
905  iterator it2 =
906  it1->second.find(*configuration->GetElectronOccupancy());
907 
908  if (it2 == it1->second.end()) return;
909 
910  it2->second = 0;
911 // it1->second.erase(it2);
912 
913  configuration->fElectronOccupancy = 0;
914 }
915 
916 //______________________________________________________________________________
917 
921  const G4String& label)
922 {
923  //G4AutoLock lock(&fMoleculeCreationMutex);
924 
925  MolLabelConfTable::iterator it1 = fLabelTable.find(molDef);
926 
927  if(it1 == fLabelTable.end()) return 0;
928 
929  LabelTable& table2 = it1->second;
930 
931  LabelTable::iterator it2 = table2.find(label);
932 
933  //lock.unlock();
934 
935  if(it2 == table2.end()) return 0;
936  return it2->second;
937 }
938 
939 //______________________________________________________________________________
940 
944 {
945  if(moleculeID > (int) fMolConfPerID.size() ||
946  moleculeID < 0) return 0;
947 
948  return fMolConfPerID[moleculeID];
949 }
950 
951 //______________________________________________________________________________
952 
953 G4int
956  const G4String& label,
957  G4MolecularConfiguration* molConf)
958 {
959  G4AutoLock lock(&fMoleculeCreationMutex);
960  LabelTable& tmpMap = fLabelTable[molDef];
961  LabelTable::iterator it = tmpMap.find(label);
962 
963  if(it == tmpMap.end())
964  {
965  fLastMoleculeID++;
966  tmpMap[label] = molConf;
967  lock.unlock();
968  }
969  else
970  {
971  lock.unlock();
972  G4ExceptionDescription errMsg;
973  errMsg << "The same molecular configuration seemed to be recorded twice";
974  G4Exception("G4MolecularConfigurationManager::"
975  "SetMolecularConfiguration(const G4MoleculeDefinition* molDef,"
976  "const G4String& label,"
977  "G4MolecularConfiguration* molConf)",
978  "", FatalException, errMsg);
979  }
980 
981  fMolConfPerID.push_back(molConf);
982 
983  return fLastMoleculeID;
984 }
985 
986 //______________________________________________________________________________
987 
990  const G4String& label)
991 {
992  return GetManager()->GetMolecularConfiguration(molDef, label);
993 }
994 
995 //______________________________________________________________________________
996 
999 {
1000  return GetManager()->GetMolecularConfiguration(moleculeID);
1001 }
1002 
1003 //______________________________________________________________________________
1004 
1007  const G4MoleculeDefinition* molDef,
1008  int charge,
1009  const G4String& label,
1010  bool& wasAlreadyCreated)
1011 {
1012  wasAlreadyCreated = false;
1013  G4MolecularConfiguration* molConf =
1014  GetManager()->GetMolecularConfiguration(molDef, charge);
1015 
1016  if (molConf)
1017  {
1018  if(molConf->fLabel == 0)
1019  {
1020  molConf->SetLabel(label);
1021  G4ExceptionDescription wMsg ;
1022  wMsg << "The molecular configuration for the definition named "
1023  << molDef->GetName()
1024  << " with charge " << charge << " has already been created "
1025  "but with NO label";
1026  G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1027  "DOUBLE_CREATION",
1028  JustWarning,
1029  wMsg);
1030  }
1031  else if(*(molConf->fLabel) == "" )
1032  {
1033  molConf->SetLabel(label);
1034  }
1035  else if(*(molConf->fLabel) != label)
1036  {
1037  G4ExceptionDescription errMsg ;
1038  errMsg << "The molecular configuration for the definition named "
1039  << molDef->GetName()
1040  << " with charge " << charge << " has already been created "
1041  "but with a different label :"
1042  << molConf->GetLabel();
1043  G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1044  "DOUBLE_CREATION",
1046  errMsg);
1047  // KILL APP
1048  }
1049 
1050  if(molConf->fUserIdentifier == "")
1051  {
1052  molConf->fUserIdentifier = userIdentifier;
1053 
1054  G4ExceptionDescription wMsg ;
1055  wMsg << "The molecular configuration for the definition named "
1056  << molDef->GetName()
1057  << " with label " << label << " has already been created.";
1058  G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1059  "DOUBLE_CREATION",
1060  JustWarning,
1061  wMsg);
1062  }
1063  else if(molConf->fUserIdentifier != userIdentifier)
1064  {
1065  G4ExceptionDescription errMsg ;
1066  errMsg << "The molecular configuration for the definition named "
1067  << molDef->GetName()
1068  << " with label " << label << " has already been created "
1069  "BUT with a different user ID :"
1070  << molConf->fUserIdentifier;
1071  G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1072  "DOUBLE_CREATION",
1074  errMsg);
1075  // KILL APP
1076  }
1077 
1078  wasAlreadyCreated = true;
1079  return molConf;
1080  }
1081  else
1082  {
1083  G4MolecularConfiguration* newConf =
1084  new G4MolecularConfiguration(molDef, label, charge);
1085  newConf->fUserIdentifier = userIdentifier;
1086 
1087  GetManager()->AddUserID(userIdentifier, newConf);
1088 
1089 // G4MoleculeTable::Instance()->RecordMolecularConfiguration(userIdentifier,
1090 // newConf);
1091  return newConf;
1092  }
1093 }
1094 
1095 //______________________________________________________________________________
1096 
1100  const G4MoleculeDefinition* molDef,
1101  bool& wasAlreadyCreated)
1102 {
1103  wasAlreadyCreated = false;
1104  G4MolecularConfiguration* preRegisteredMolConf =
1105  GetManager()->GetMolecularConfiguration(userIdentifier);
1106 
1107  if(preRegisteredMolConf)
1108  {
1109  if(preRegisteredMolConf->GetDefinition() == molDef)
1110  {
1111  wasAlreadyCreated = true;
1112  return preRegisteredMolConf;
1113  }
1114  }
1115 
1116  if(molDef->GetGroundStateElectronOccupancy())
1117  {
1118  const G4ElectronOccupancy& elecOcc = *molDef
1120  G4MolecularConfiguration* molConf =
1121  GetManager()->GetMolecularConfiguration(molDef, elecOcc);
1122 
1123  if(molConf)
1124  {
1125  if(molConf->fUserIdentifier == "")
1126  {
1127  molConf->fUserIdentifier = userIdentifier;
1128  }
1129  else if(molConf->fUserIdentifier != userIdentifier)
1130  {
1131  G4ExceptionDescription errMsg;
1132  errMsg << "A molecular configuration for the definition named "
1133  << molDef->GetName() << " has already been created "
1134  "and recorded with a different user ID "
1135  << molConf->fUserIdentifier;
1136  G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1137  "DOUBLE_CREATION",
1139  errMsg);
1140  }
1141 // TODO exception
1142  G4ExceptionDescription errMsg;
1143  errMsg << "A molecular configuration for the definition named "
1144  << molDef->GetName() << " has already been created.";
1145  G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1146  "DOUBLE_CREATION",
1147  JustWarning,
1148  errMsg);
1149  wasAlreadyCreated = true;
1150  return molConf;
1151  }
1152  else
1153  {
1154  // G4cout << "Create molConf for " << molDef->GetName() << G4endl;
1155  G4MolecularConfiguration* newConf = new G4MolecularConfiguration(molDef,
1156  elecOcc);
1157  newConf->fUserIdentifier = userIdentifier;
1158 
1159  GetManager()->AddUserID(userIdentifier, newConf);
1160 
1161 // G4MoleculeTable::Instance()->RecordMolecularConfiguration(userIdentifier,
1162 // newConf);
1163  return newConf;
1164  }
1165  }
1166  else
1167  {
1168  return CreateMolecularConfiguration(userIdentifier,
1169  molDef,
1170  molDef->GetName(),
1171  molDef->GetCharge(),
1172  wasAlreadyCreated);
1173  }
1174 }
1175 
1176 //______________________________________________________________________________
1177 
1181  const G4MoleculeDefinition* molDef,
1182  const G4String& label,
1183  bool& wasAlreadyCreated)
1184 {
1185  assert(label != "");
1186  wasAlreadyCreated = false;
1187 
1188  G4MolecularConfiguration* molConf =
1189  GetManager()->GetMolecularConfiguration(molDef, label);
1190  if(molConf)
1191  {
1192  if(molConf->fLabel
1193  && *molConf->fLabel == label)
1194  {
1195  wasAlreadyCreated = true;
1196  return molConf;
1197  }
1198  else if(molConf->fLabel == 0)
1199  {
1200  wasAlreadyCreated = true;
1201  molConf->SetLabel(label);
1202  return molConf;
1203  }
1204  else if(*molConf->fLabel == "")
1205  {
1206  wasAlreadyCreated = true;
1207  molConf->SetLabel(label);
1208  return molConf;
1209  }
1210 
1211  molConf->PrintState();
1212  G4ExceptionDescription errMsg ;
1213  errMsg << "A molecular configuration for the definition named "
1214  << molDef->GetName()
1215  << " has already been created "
1216  "with user ID "
1217  << molConf->fUserIdentifier << " and label "
1218  << molConf->GetLabel();
1219  G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1220  "DOUBLE_CREATION",
1222  errMsg);
1223  // KILL APP
1224  }
1225  else
1226  {
1227  G4MolecularConfiguration* newConf =
1228  new G4MolecularConfiguration(molDef,
1229  label,
1230  molDef->GetCharge());
1231  newConf->fUserIdentifier = userIdentifier;
1232 
1233  GetManager()->AddUserID(userIdentifier, newConf);
1234 
1235 // G4MoleculeTable::Instance()->
1236 // RecordMolecularConfiguration(userIdentifier, newConf);
1237  return newConf;
1238  }
1239  return molConf;
1240 }
1241 
1242 //______________________________________________________________________________
1243 
1247  const G4MoleculeDefinition* molDef,
1248  const G4String& label,
1249  const G4ElectronOccupancy& eOcc,
1250  bool& wasAlreadyCreated)
1251 {
1252  assert(label != "");
1253  wasAlreadyCreated = false;
1254 
1255  G4MolecularConfiguration* molConf =
1256  GetManager()->GetMolecularConfiguration(molDef, eOcc);
1257 
1258  if(molConf)
1259  {
1260  if(molConf->GetElectronOccupancy())
1261  {
1262  if(*molConf->GetElectronOccupancy() == eOcc)
1263  {
1264  if(molConf->fLabel && *molConf->fLabel == label)
1265  {
1266  wasAlreadyCreated = true;
1267  return molConf;
1268  }
1269  else if(molConf->fLabel == 0)
1270  {
1271  wasAlreadyCreated = true;
1272  molConf->SetLabel(label);
1273  return molConf;
1274  }
1275  else if(*molConf->fLabel == "")
1276  {
1277  wasAlreadyCreated = true;
1278  molConf->SetLabel(label);
1279  return molConf;
1280  }
1281  }
1282  }
1283 
1284 
1285  molConf->PrintState();
1286  G4ExceptionDescription errMsg ;
1287  errMsg << "A molecular configuration for the definition named "
1288  << molDef->GetName()
1289  << " has already been created "
1290  "with user ID "
1291  << molConf->fUserIdentifier
1292  << " and possible different electronic state";
1293  G4Exception("G4MolecularConfiguration::CreateMolecularConfiguration",
1294  "DOUBLE_CREATION",
1296  errMsg);
1297  }
1298  else
1299  {
1300  G4MolecularConfiguration* newConf =
1301  new G4MolecularConfiguration(molDef,
1302  eOcc,
1303  label);
1304  newConf->fUserIdentifier = userIdentifier;
1305 
1306  GetManager()->AddUserID(userIdentifier, newConf);
1307 
1308 // G4MoleculeTable::Instance()->
1309 // RecordMolecularConfiguration(userIdentifier, newConf);
1310  return newConf;
1311  }
1312  return molConf;
1313 }
1314 
1315 
1316 //______________________________________________________________________________
1317 
1321  const G4ElectronOccupancy& eOcc)
1322 {
1323  MolElectronConfTable::iterator it1 = fElecOccTable.find(molDef);
1324 
1325  if(it1 == fElecOccTable.end())
1326  {
1327  return new G4MolecularConfiguration(molDef, eOcc);
1328  }
1329 
1330  ElectronOccupancyTable& table2 = it1->second;
1331  ElectronOccupancyTable::iterator it = table2.find(eOcc);
1332 
1333  if(it == table2.end())
1334  {
1335  G4MolecularConfiguration* molConf =
1336  new G4MolecularConfiguration(molDef, eOcc);
1337 // molConf->Finalize();
1338  return molConf;
1339  }
1340  else
1341  {
1342  return it->second;
1343  }
1344 
1345  return 0;
1346 }
1347 
1348 //______________________________________________________________________________
1349 
1353  int charge)
1354 {
1355  MolChargeConfTable::iterator it1 = fChargeTable.find(molDef);
1356 
1357  if(it1 == fChargeTable.end())
1358  {
1359  G4AutoLock lock(&fMoleculeCreationMutex);
1360 
1361  G4MolecularConfiguration* newConf = new G4MolecularConfiguration(molDef, charge);
1362  return newConf ;
1363  }
1364 
1365  ChargeTable& table2 = it1->second;
1366  ChargeTable::iterator it = table2.find(charge);
1367 
1368  if(it == table2.end())
1369  {
1370  G4AutoLock lock(&fMoleculeCreationMutex);
1371 
1372  G4MolecularConfiguration* newConf =
1373  new G4MolecularConfiguration(molDef, charge);
1374 // newConf->Finalize();
1375  return newConf ;
1376  }
1377  else
1378  {
1379  return it->second;
1380  }
1381 
1382  return 0;
1383 }
1384 
1385 //______________________________________________________________________________
1386 
1388 {
1389  G4String moleculeName = fMoleculeDefinition->GetName();
1390  WRITE(out, moleculeName);
1391 
1392 // if(fLabel)
1393 // out << fLabel;
1394 // else
1395 // out << "";
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);
1403  WRITE(out,fName);
1404  WRITE(out,fIsFinalized);
1405 }
1406 
1407 //______________________________________________________________________________
1408 
1410 {
1411  G4String moleculeName;
1412  READ(in, moleculeName);
1413  fMoleculeDefinition =
1415 
1416 // G4String label;
1417 //
1418 // in.read((char*)(&label), sizeof(label));
1419 //
1420 // if(label)
1421 // fLabel = new G4String(label);
1422 // else
1423 // fLabel = 0;
1424  READ(in,fDynDiffusionCoefficient);
1425  READ(in,fDynVanDerVaalsRadius);
1426  READ(in,fDynDecayTime);
1427  READ(in,fDynMass);
1428  READ(in,fDynCharge);
1429  READ(in,fMoleculeID);
1430  READ(in,fFormatedName);
1431  READ(in,fName);
1432  READ(in,fIsFinalized);
1433 }
1434 
1435 //______________________________________________________________________________
1436 
1438 {
1439  return new G4MolecularConfiguration(in);
1440 }
1441 
1442 //______________________________________________________________________________
1443 
1445 {
1446  fLabel = 0; // TODO: for now not serialized
1447  Unserialize(in);
1448  fMoleculeDefinition = 0;
1449  fElectronOccupancy = 0;
1450  if(fElectronOccupancy)
1451  {
1452  GetManager()->Insert(fMoleculeDefinition, *fElectronOccupancy, this);
1453  fElectronOccupancy =
1454  GetManager()->FindCommonElectronOccupancy(fMoleculeDefinition,
1455  *fElectronOccupancy);
1456 
1457  if(fLabel)
1458  {
1459  GetManager()->RecordNewlyLabeledConfiguration(this);
1460  }
1461  }
1462  else if(fLabel)
1463  {
1464  fMoleculeID = GetManager()->Insert(fMoleculeDefinition, *fLabel, this);
1465  }
1466  else if(fDynCharge)
1467  {
1468  fMoleculeID = GetManager()->Insert(fMoleculeDefinition, fDynCharge, this);
1469  }
1470 }
1471 
1472 //______________________________________________________________________________
1473 
1475 {
1476  fUserIdentifier = userID;
1477  GetManager()->AddUserID(userID, this);
1478 // G4MoleculeTable::Instance()->RecordMolecularConfiguration(userID, this);
1479 }
1480 
1481 //______________________________________________________________________________
1482 
1483 double G4MolecularConfiguration::DiffCoeffWater(double temperature_K)
1484 {
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;
1489 }
1490 
1491 //______________________________________________________________________________
1492 
1493 void
1496 {
1497  double D_water_0 = DiffCoeffWater(fgTemperature);
1498  double D_water_f = DiffCoeffWater(temperature_K);
1499 
1500  G4cout << "Scaling factor = " << D_water_f/D_water_0 << G4endl;
1501 
1504 
1505  while(it())
1506  {
1507  G4MolecularConfiguration* conf = it.value();
1508  double D_0 = conf->GetDiffusionCoefficient() ;
1509  double D_f = D_water_f * D_0 /D_water_0;
1510  conf->SetDiffusionCoefficient(D_f);
1511  };
1512 }
1513 
1514 //______________________________________________________________________________
1515 
1517 {
1518  if(bool(fDiffParam) == false)
1519  {
1521  }
1522 }
1523 
1524 //______________________________________________________________________________
1525 
1527 {
1528  ScaleAllDiffusionCoefficientsOnWater(temperature);
1529  fgTemperature = temperature;
1530 }
1531 
1532 //______________________________________________________________________________
1533 
1535 {
1536  return fgTemperature;
1537 }
1538 
1539 //______________________________________________________________________________
1540 
1544 {
1545  for(auto it : fMolConfPerID)
1546  {
1547  if(it->GetUserID() == userID) return it;
1548  }
1549  return 0;
1550 }
1551 
1552 //______________________________________________________________________________
1553 
1556 {
1557  return GetManager()->GetMolecularConfiguration(userID);
1558 }
1559 
1560 //______________________________________________________________________________
1561 
1563 {
1564  const std::vector<G4MolecularConfiguration*>& species =
1565  GetManager()->GetAllSpecies();
1566 
1567  for(size_t i = 0; i < species.size() ; ++i)
1568  {
1569  species[i]->Finalize();
1570  }
1571 
1572 }
static G4MolecularConfiguration * Load(std::istream &)
static constexpr double m2
const G4String & GetName() const
G4MoleculeDefinition * GetMoleculeDefinition(const G4String &, bool mustExist=true)
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
G4String fName
Definition: G4AttUtils.hh:55
G4MolecularConfiguration * ChangeConfiguration(const G4ElectronOccupancy &newElectronOccupancy)
static G4MolecularConfiguration * GetMolecularConfiguration(const G4MoleculeDefinition *, const G4String &label)
void AddUserID(const G4String &name, G4MolecularConfiguration *molecule)
void WRITE(std::ostream &out, const T &toBeSaved)
Definition: G4Serialize.hh:41
static G4String ConvertToString(G4bool boolVal)
Definition: G4UIcommand.cc:372
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)
int G4int
Definition: G4Types.hh:78
void SetUserID(const G4String &userID)
static G4MolecularConfigurationManager * fgManager
static void ScaleAllDiffusionCoefficientsOnWater(double temperature_K)
const XML_Char * s
Definition: expat.h:262
void RecordNewlyLabeledConfiguration(G4MolecularConfiguration *molConf)
G4GLOB_DLL std::ostream G4cout
G4int GetOccupancy(G4int orbit) const
G4MolecularConfiguration * IonizeMolecule(G4int)
G4MolecularConfiguration * AddElectron(G4int orbit, G4int n=1)
G4MolecularConfiguration::G4MolecularConfigurationManager MolecularConfigurationManager
G4int AddElectron(G4int orbit, G4int number=1)
void CheckElectronOccupancy(const char *line) const
static double DiffCoeffWater(double temperature_K)
static G4MoleculeTable * Instance()
G4MolecularConfiguration * MoveOneElectron(G4int, G4int)
G4MolecularConfiguration & operator=(G4MolecularConfiguration &right)
static void SetGlobalTemperature(G4double)
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)
Definition: G4Exception.cc:41
#define INT_MAX
Definition: templates.hh:111
G4MolecularConfiguration(const G4MoleculeDefinition *, const G4ElectronOccupancy &, const G4String &label="")
G4int G4Mutex
Definition: G4Threading.hh:173
const char * removePath(const char *path)
const G4String & GetFormatedName() const
const G4String & GetName() const
const G4MoleculeDefinition * GetDefinition() const
const G4String & GetLabel() const
#define G4endl
Definition: G4ios.hh:61
G4MolecularConfiguration * GetMolecularConfiguration(const G4MoleculeDefinition *molDef, const G4ElectronOccupancy &eOcc)
void READ(std::istream &in, T &toBeSaved)
Definition: G4Serialize.hh:49
double G4double
Definition: G4Types.hh:76
const G4ElectronOccupancy * GetGroundStateElectronOccupancy() const
G4MolecularConfiguration * RemoveElectron(G4int, G4int number=1)
const G4ElectronOccupancy * fElectronOccupancy
G4MolecularConfiguration * ExciteMolecule(G4int)
static constexpr double m2
Definition: G4SIunits.hh:130
const G4MoleculeDefinition * fMoleculeDefinition
static constexpr double kelvin
G4int RemoveElectron(G4int orbit, G4int number=1)
static G4MolecularConfiguration * CreateMolecularConfiguration(const G4String &userIdentifier, const G4MoleculeDefinition *, bool &wasAlreadyCreated)