Geant4  10.02
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 94289 2015-11-11 08:33:40Z 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 
1561 {
1562  const std::vector<G4MolecularConfiguration*>& species =
1563  GetManager()->GetAllSpecies();
1564 
1565  for(size_t i = 0; i < species.size() ; ++i)
1566  {
1567  species[i]->Finalize();
1568  }
1569 
1570 }
The pointer G4MolecularConfiguration will be shared by all the molecules having the same molecule def...
G4double GetDiffusionCoefficient() const
Returns the diffusion coefficient D.
void PrintState() const
Display the electronic state of the molecule.
static G4MolecularConfiguration * Load(std::istream &)
const G4String & GetName() const
Returns the name of the molecule.
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:371
G4double GetNbElectrons() const
Returns the number of electron.
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
Returns the object ElectronOccupancy describing the electronic configuration of the molecule...
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 const double s
Definition: G4SIunits.hh:168
static void ScaleAllDiffusionCoefficientsOnWater(double temperature_K)
void RecordNewlyLabeledConfiguration(G4MolecularConfiguration *molConf)
G4GLOB_DLL std::ostream G4cout
G4int GetOccupancy(G4int orbit) const
G4MolecularConfiguration * IonizeMolecule(G4int)
Method used in Geant4-DNA to ionize water molecules.
static const double m2
Definition: G4SIunits.hh:129
G4MolecularConfiguration * AddElectron(G4int orbit, G4int n=1)
Add n electrons to a given orbit.
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)
Move one electron from an orbit to another.
void SetDiffusionCoefficient(G4double)
Sets the diffusion coefficient D of the molecule used in diffusion processes to calculate the mean sq...
G4MolecularConfiguration & operator=(G4MolecularConfiguration &right)
static void SetGlobalTemperature(G4double)
G4ConfigurationIterator GetConfigurationIterator()
static G4MolecularConfigurationManager * GetManager()
static G4MolecularConfiguration * GetOrCreateMolecularConfiguration(const G4MoleculeDefinition *)
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
static const double kelvin
Definition: G4SIunits.hh:278
#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
Returns the formated name of the molecule.
std::map< G4ElectronOccupancy, G4MolecularConfiguration *, comparator > ElectronOccupancyTable
G4int GetAtomsNumber() const
Returns the nomber of atoms compouning the molecule.
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)
Remove n electrons to a given orbit.
static const G4double e3
std::map< const G4String, G4MolecularConfiguration * > LabelTable
const G4ElectronOccupancy * fElectronOccupancy
G4MolecularConfiguration * ExciteMolecule(G4int)
Method used in Geant4-DNA to excite water molecules.
const G4MoleculeDefinition * fMoleculeDefinition
G4int RemoveElectron(G4int orbit, G4int number=1)
static G4MolecularConfiguration * CreateMolecularConfiguration(const G4String &userIdentifier, const G4MoleculeDefinition *, bool &wasAlreadyCreated)