Geant4  v4-10.4-release
 모두 클래스 네임스페이스들 파일들 함수 변수 타입정의 열거형 타입 열거형 멤버 Friends 매크로 그룹들 페이지들
G4DNAMolecularMaterial.cc
이 파일의 문서화 페이지로 가기
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: G4DNAMolecularMaterial.cc 108397 2018-02-12 10:21:10Z gcosmo $
27 //
28 // Author: Mathieu Karamitros
29 //
30 
32 #include "G4Material.hh"
33 #include <utility>
34 #include "G4StateManager.hh"
35 #include "G4Threading.hh"
36 #include "G4AutoLock.hh"
37 #include "G4StateManager.hh"
38 #include "G4MoleculeTable.hh"
39 
40 using namespace std;
41 
44 
45 //------------------------------------------------------------------------------
46 
48  const G4Material* mat2) const
49 {
50  if (mat1 == 0 && mat2 == 0) return false; //(mat1 == mat2)
51  if (mat1 == 0) return true; // mat1 < mat2
52  if (mat2 == 0) return false; //mat2 < mat1
53 
54  const G4Material* baseMat1 = mat1->GetBaseMaterial();
55  const G4Material* baseMat2 = mat2->GetBaseMaterial();
56 
57  if ((baseMat1 || baseMat2) == 0){
58  // None of the materials derives from a base material
59  return mat1 < mat2;
60  }
61  else if (baseMat1 && baseMat2){
62  // Both materials derive from a base material
63  return baseMat1 < baseMat2;
64  }
65 
66  else if (baseMat1 && (baseMat2 == 0)){
67  // Only the material 1 derives from a base material
68  return baseMat1 < mat2;
69  }
70  // only case baseMat1==0 && baseMat2 remains
71  return mat1 < baseMat2;
72 }
73 
74 //------------------------------------------------------------------------------
75 
77 {
78  if (!fInstance) new G4DNAMolecularMaterial();
79  return fInstance;
80 }
81 
82 //------------------------------------------------------------------------------
83 
85 {
86  if (fInstance){
87  delete fInstance;
88  fInstance = 0;
89  }
90 }
91 
92 //------------------------------------------------------------------------------
93 
95 {
96  fpCompFractionTable = 0;
97  fpCompDensityTable = 0;
98  fpCompNumMolPerVolTable = 0;
99  fIsInitialized = false;
100  fNMaterials = 0;
101  fInstance = this;
102 }
103 
104 //------------------------------------------------------------------------------
105 
107 {
108  if (fpCompFractionTable){
109  fpCompFractionTable->clear();
110  delete fpCompFractionTable;
111  fpCompFractionTable = 0;
112  }
113  if (fpCompDensityTable){
114  fpCompDensityTable->clear();
115  delete fpCompDensityTable;
116  fpCompDensityTable = 0;
117  }
118  if (fpCompNumMolPerVolTable){
119  fpCompNumMolPerVolTable->clear();
120  delete fpCompNumMolPerVolTable;
121  fpCompNumMolPerVolTable = 0;
122  }
123 
124  map<const G4Material*, std::vector<double>*, CompareMaterial>::iterator it;
125 
126  for (it = fAskedDensityTable.begin(); it != fAskedDensityTable.end(); it++){
127  if (it->second){
128  delete it->second;
129  it->second = 0;
130  }
131  }
132 
133  for (it = fAskedNumPerVolTable.begin(); it != fAskedNumPerVolTable.end();
134  it++){
135  if (it->second){
136  delete it->second;
137  it->second = 0;
138  }
139  }
140 }
141 
142 //------------------------------------------------------------------------------
143 
146 {
147  Create();
148  fInstance = this;
149 }
150 
151 //------------------------------------------------------------------------------
152 
154 {
155  if (requestedState == G4State_Idle && G4StateManager::GetStateManager()
156  ->GetPreviousState() == G4State_PreInit){
157  Initialize();
158  }
159  else if (requestedState == G4State_Quit){
160 // G4cout << "G4DNAMolecularMaterial::Notify ---> received G4State_Quit"
161 // << G4endl;
162  Clear();
163  //DeleteInstance();
164  }
165  return true;
166 }
167 
168 //------------------------------------------------------------------------------
169 
171  const G4DNAMolecularMaterial& /*rhs*/) :
173 {
174  Create();
175 }
176 
177 //------------------------------------------------------------------------------
178 
181 {
182  if (this == &rhs) return *this;
183  Create();
184  return *this;
185 }
186 
187 //------------------------------------------------------------------------------
188 
190 {
191 // G4cout << "Deleting G4DNAMolecularMaterial" << G4endl;
192  Clear();
193  fInstance = 0;
194  //assert(G4StateManager::GetStateManager()->DeregisterDependent(this) == true);
195 }
196 
197 //------------------------------------------------------------------------------
198 
200 {
201  G4AutoLock l(&aMutex);
202  if (fIsInitialized){
203  return;
204  }
205 
206  const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
207 
208  fNMaterials = materialTable->size();
209  // This is to prevent segment fault if materials are created later on
210  // Actually this creation should not be done
211 
212  if (fpCompFractionTable == 0){
213  fpCompFractionTable = new vector<ComponentMap>(materialTable->size());
214  }
215 
216  G4Material* mat(0);
217 
218  for (size_t i = 0; i < fNMaterials; i++){
219  mat = materialTable->at(i);
220  SearchMolecularMaterial(mat, mat, 1);
221 
222  mat = 0;
223  }
224 
227 
228  fIsInitialized = true;
229 }
230 
231 //------------------------------------------------------------------------------
232 
234 {
235  if (fpCompFractionTable){
236  const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
237  fpCompDensityTable = new vector<ComponentMap>(
238  G4Material::GetMaterialTable()->size());
239 
240  G4Material* parentMat;
241  const G4Material* compMat(0);
242  double massFraction = -1;
243  double parentDensity = -1;
244 
245  for (size_t i = 0; i < fNMaterials; i++){
246  parentMat = materialTable->at(i);
247  ComponentMap& massFractionComp = (*fpCompFractionTable)[i];
248  ComponentMap& densityComp = (*fpCompDensityTable)[i];
249 
250  parentDensity = parentMat->GetDensity();
251 
252  for (ComponentMap::iterator it = massFractionComp.begin();
253  it != massFractionComp.end(); it++){
254  compMat = it->first;
255  massFraction = it->second;
256  densityComp[compMat] = massFraction * parentDensity;
257  compMat = 0;
258  massFraction = -1;
259  }
260  }
261  }
262  else{
263  G4ExceptionDescription exceptionDescription;
264  exceptionDescription << "The pointer fpCompFractionTable is not initialized"
265  << G4endl;
266  G4Exception("G4DNAMolecularMaterial::InitializeDensity",
267  "G4DNAMolecularMaterial001", FatalException,
268  exceptionDescription);
269  }
270 }
271 
272 //------------------------------------------------------------------------------
273 
275 {
276  if (fpCompDensityTable){
277  fpCompNumMolPerVolTable = new vector<ComponentMap>(fNMaterials);
278 
279  const G4Material* compMat(0);
280 
281  for (size_t i = 0; i < fNMaterials; i++){
282  ComponentMap& massFractionComp = (*fpCompFractionTable)[i];
283  ComponentMap& densityComp = (*fpCompDensityTable)[i];
284  ComponentMap& numMolPerVol = (*fpCompNumMolPerVolTable)[i];
285 
286  for (ComponentMap::iterator it = massFractionComp.begin();
287  it != massFractionComp.end(); it++){
288  compMat = it->first;
289  numMolPerVol[compMat] = densityComp[compMat]
290  / compMat->GetMassOfMolecule();
291  compMat = 0;
292  }
293  }
294  }
295  else{
296  G4ExceptionDescription exceptionDescription;
297  exceptionDescription << "The pointer fpCompDensityTable is not initialized"
298  << G4endl;
299  G4Exception("G4DNAMolecularMaterial::InitializeNumMolPerVol",
300  "G4DNAMolecularMaterial002", FatalException,
301  exceptionDescription);
302  }
303 }
304 
305 //------------------------------------------------------------------------------
306 
307 void
309  G4Material* molecularMaterial,
310  G4double fraction)
311 {
312  ComponentMap& matComponent =
313  (*fpCompFractionTable)[parentMaterial->GetIndex()];
314 
315  if (matComponent.empty()){
316  matComponent[molecularMaterial] = fraction;
317  return;
318  }
319 
320  ComponentMap::iterator it = matComponent.find(molecularMaterial);
321 
322  if (it == matComponent.end()){
323  matComponent[molecularMaterial] = fraction;
324  }
325  else{
326  matComponent[molecularMaterial] = it->second + fraction;
327  // handle "base material"
328  }
329 }
330 
331 //------------------------------------------------------------------------------
332 
334  G4Material* material,
335  double currentFraction)
336 {
337  if (material->GetMassOfMolecule() != 0.0){ // is a molecular material
338  RecordMolecularMaterial(parentMaterial, material, currentFraction);
339  return;
340  }
341 
342  G4Material* compMat(nullptr);
343  G4double fraction = -1.;
344  std::map<G4Material*, G4double> matComponent = material->GetMatComponents();
345  std::map<G4Material*, G4double>::iterator it = matComponent.begin();
346 
347  for (; it != matComponent.end(); it++){
348  compMat = it->first;
349  fraction = it->second;
350  if (compMat->GetMassOfMolecule() == 0.0){ // is not a molecular material
351  SearchMolecularMaterial(parentMaterial, compMat,
352  currentFraction * fraction);
353  }
354  else{ // is a molecular material
355  RecordMolecularMaterial(parentMaterial, compMat,
356  currentFraction * fraction);
357  }
358  }
359 }
360 
361 //------------------------------------------------------------------------------
362 
363 const std::vector<double>*
365 GetDensityTableFor(const G4Material* lookForMaterial) const
366 {
367  if (!fpCompDensityTable){
368  if (fIsInitialized){
369  G4ExceptionDescription exceptionDescription;
370  exceptionDescription
371  << "The pointer fpCompDensityTable is not initialized will the "
372  "singleton of G4DNAMolecularMaterial "
373  << "has already been initialized." << G4endl;
374  G4Exception("G4DNAMolecularMaterial::GetDensityTableFor",
375  "G4DNAMolecularMaterial003", FatalException,
376  exceptionDescription);
377  }
378 
379  if (G4StateManager::GetStateManager()->GetCurrentState() == G4State_Init){
380  const_cast<G4DNAMolecularMaterial*>(this)->Initialize();
381  }
382  else{
383  G4ExceptionDescription exceptionDescription;
384  exceptionDescription
385  << "The geant4 application is at the wrong state. State must be: "
386  "G4State_Init."
387  << G4endl;
388  G4Exception("G4DNAMolecularMaterial::GetDensityTableFor",
389  "G4DNAMolecularMaterial_WRONG_STATE_APPLICATION",
390  FatalException, exceptionDescription);
391  }
392  }
393 
394  std::map<const G4Material*, std::vector<double>*, CompareMaterial>::
395  const_iterator it_askedDensityTable =
396  fAskedDensityTable.find(lookForMaterial);
397 
398  if (it_askedDensityTable != fAskedDensityTable.end()){
399  return it_askedDensityTable->second;
400  }
401 
402  const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
403 
404  std::vector<double>* output = new std::vector<double>(materialTable->size());
405 
406  ComponentMap::const_iterator it;
407 
408  G4bool materialWasNotFound = true;
409 
410  for (size_t i = 0; i < fNMaterials; i++){
411  ComponentMap& densityTable = (*fpCompDensityTable)[i];
412 
413  it = densityTable.find(lookForMaterial);
414 
415  if (it == densityTable.end()){
416  (*output)[i] = 0.0;
417  }
418  else{
419  materialWasNotFound = false;
420  (*output)[i] = it->second;
421  }
422  }
423 
424  if (materialWasNotFound){
425  PrintNotAMolecularMaterial("G4DNAMolecularMaterial::GetDensityTableFor",
426  lookForMaterial);
427  }
428 
429  fAskedDensityTable.insert(make_pair(lookForMaterial, output));
430 
431  return output;
432 }
433 
434 //------------------------------------------------------------------------------
435 
437  const G4Material* lookForMaterial) const
438 {
439  if(lookForMaterial==0) return nullptr;
440 
442  if (fIsInitialized){
443  G4ExceptionDescription exceptionDescription;
444  exceptionDescription
445  << "The pointer fpCompNumMolPerVolTable is not initialized whereas "
446  "the singleton of G4DNAMolecularMaterial "
447  << "has already been initialized." << G4endl;
448  G4Exception("G4DNAMolecularMaterial::GetNumMolPerVolTableFor",
449  "G4DNAMolecularMaterial005", FatalException,
450  exceptionDescription);
451  }
452 
453  if (G4StateManager::GetStateManager()->GetCurrentState() == G4State_Init){
454  const_cast<G4DNAMolecularMaterial*>(this)->Initialize();
455  }
456  else{
457  G4ExceptionDescription exceptionDescription;
458  exceptionDescription
459  << "The geant4 application is at the wrong state. State must be : "
460  "G4State_Init."
461  << G4endl;
462  G4Exception("G4DNAMolecularMaterial::GetNumMolPerVolTableFor",
463  "G4DNAMolecularMaterial_WRONG_STATE_APPLICATION",
464  FatalException, exceptionDescription);
465  }
466  }
467 
468  std::map<const G4Material*, std::vector<double>*, CompareMaterial>::
469  const_iterator it_askedNumMolPerVolTable =
470  fAskedNumPerVolTable.find(lookForMaterial);
471  if (it_askedNumMolPerVolTable != fAskedNumPerVolTable.end()){
472  return it_askedNumMolPerVolTable->second;
473  }
474 
475  const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
476 
477  std::vector<double>* output = new std::vector<double>(materialTable->size());
478 
479  ComponentMap::const_iterator it;
480 
481  G4bool materialWasNotFound = true;
482 
483  for (size_t i = 0; i < fNMaterials; i++){
484  ComponentMap& densityTable = (*fpCompNumMolPerVolTable)[i];
485 
486  it = densityTable.find(lookForMaterial);
487 
488  if (it == densityTable.end()){
489  (*output)[i] = 0.0;
490  }
491  else{
492  materialWasNotFound = false;
493  (*output)[i] = it->second;
494  }
495  }
496 
497  if (materialWasNotFound){
499  "G4DNAMolecularMaterial::GetNumMolPerVolTableFor", lookForMaterial);
500  }
501 
502  fAskedNumPerVolTable.insert(make_pair(lookForMaterial, output));
503 
504  return output;
505 }
506 
507 //------------------------------------------------------------------------------
508 
510 PrintNotAMolecularMaterial(const char* methodName,
511  const G4Material* lookForMaterial) const
512 {
513  std::map<const G4Material*, bool, CompareMaterial>::iterator it =
514  fWarningPrinted.find(lookForMaterial);
515 
516  if (it == fWarningPrinted.end()){
517  G4ExceptionDescription exceptionDescription;
518  exceptionDescription << "The material " << lookForMaterial->GetName()
519  << " is not defined as a molecular material."
520  << G4endl
521  << "Meaning: The elements should be added to the "
522  "material using atom count rather than mass fraction "
523  "(cf. G4Material)"
524  << G4endl
525  << "If you want to use DNA processes on liquid water, you should better use "
526  "the NistManager to create the water material."
527  << G4endl
528  << "Since this message is displayed, it means that the DNA models will not "
529  "be called."
530  << "Please note that this message will only appear once even if you are "
531  "using other methods of G4DNAMolecularMaterial."
532  << G4endl;
533 
534  G4Exception(methodName, "MATERIAL_NOT_DEFINE_USING_ATOM_COUNT", JustWarning,
535  exceptionDescription);
536  fWarningPrinted[lookForMaterial] = true;
537  }
538 }
539 
540 //------------------------------------------------------------------------------
541 
544 GetMolecularConfiguration(const G4Material* material) const
545 {
546  int material_id = material->GetIndex();
547  auto it = fMaterialToMolecularConf.find(material_id);
548  if(it == fMaterialToMolecularConf.end()) return 0;
549  return it->second;
550 }
551 
552 //------------------------------------------------------------------------------
553 
554 void
557  G4MolecularConfiguration* molConf)
558 {
559  assert(material != 0);
560  int material_id = material->GetIndex();
561  fMaterialToMolecularConf[material_id] = molConf;
562 }
563 
564 //------------------------------------------------------------------------------
565 
566 void
568  const G4String& molUserID)
569 {
570  assert(material != 0);
571  int material_id = material->GetIndex();
572  fMaterialToMolecularConf[material_id] =
573  G4MoleculeTable::Instance()->GetConfiguration(molUserID, true);
574 }
575 
576 //------------------------------------------------------------------------------
577 
578 void
580  const G4String& molUserID)
581 {
582  G4Material* material = G4Material::GetMaterial(materialName);
583 
584  if(material == 0){
585  G4cout<< "Material " << materialName
586  << " was not found and therefore won't be linked to "
587  << molUserID << G4endl;
588  return;
589  }
590  SetMolecularConfiguration(material, molUserID);
591 }
592 
593 //------------------------------------------------------------------------------
594 
595 G4double
598 {
599  G4Exception("G4DNAMolecularMaterial::GetNumMolPerVolForComponentInComposite",
600  "DEPRECATED",
601  FatalException,"Use standard method: GetNumMolPerVolTableFor"
602  " at the run initialization to retrieve a read-only table used"
603  " during stepping. The method is thread-safe.");
604  return 0;
605 }
606 
607 //------------------------------------------------------------------------------
608 
609 G4double
612  const G4Material*,
613  G4double)
614 {
615  G4Exception("G4DNAMolecularMaterial::GetNumMolPerVolForComponentInComposite",
616  "DEPRECATED",
617  FatalException,"Use standard method: GetNumMolPerVolTableFor"
618  " at the run initialization to retrieve a read-only table used"
619  " during stepping. The method is thread-safe.");
620  return 0;
621 }
std::vector< ComponentMap > * fpCompDensityTable
static G4MoleculeTable * Instance()
void SearchMolecularMaterial(G4Material *parentMaterial, G4Material *material, double currentFraction)
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:45
void SetMolecularConfiguration(const G4Material *, G4MolecularConfiguration *)
Associate a molecular configuration to a G4material.
static G4MaterialTable * GetMaterialTable()
Definition: G4Material.cc:593
G4DNAMolecularMaterial builds tables of molecular densities for chosen molecular materials. The class handles homogeneous, composite and derived materials. A material of interest is labeled as molecular if built using the number of atoms rather than the mass fractions.
Materials can be described as a derivation of existing &quot;parent&quot; materials in order to alter few of th...
std::map< int, G4MolecularConfiguration * > fMaterialToMolecularConf
size_t GetIndex() const
Definition: G4Material.hh:262
#define G4endl
Definition: G4ios.hh:61
static G4DNAMolecularMaterial * fInstance
G4double GetNumMoleculePerVolumeUnitForMaterial(const G4Material *mat)
Deprecated.
std::map< const G4Material *, std::vector< double > *, CompareMaterial > fAskedDensityTable
static G4Material * GetMaterial(const G4String &name, G4bool warning=true)
Definition: G4Material.cc:608
std::vector< ComponentMap > * fpCompFractionTable
const std::vector< double > * GetNumMolPerVolTableFor(const G4Material *) const
Retrieve a table of molecular densities (number of molecules per unit volume) in the G4 unit system f...
std::map< const G4Material *, double, CompareMaterial > ComponentMap
const G4String & GetName() const
Definition: G4Material.hh:179
bool operator()(const G4Material *mat1, const G4Material *mat2) const
double G4double
Definition: G4Types.hh:76
bool G4bool
Definition: G4Types.hh:79
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:88
void RecordMolecularMaterial(G4Material *parentMaterial, G4Material *molecularMaterial, G4double fraction)
const std::vector< double > * GetDensityTableFor(const G4Material *) const
Retrieve a table of volumetric mass densities (mass per unit volume) in the G4 unit system for chosen...
static G4DNAMolecularMaterial * Instance()
Float_t mat
G4Mutex aMutex
G4DNAMolecularMaterial & operator=(const G4DNAMolecularMaterial &)
std::vector< ComponentMap > * fpCompNumMolPerVolTable
std::vector< G4Material * > G4MaterialTable
std::map< const G4Material *, bool, CompareMaterial > fWarningPrinted
G4double GetNumMolPerVolForComponentInComposite(const G4Material *composite, const G4Material *component, G4double massFraction)
Deprecated.
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.hh:65
void PrintNotAMolecularMaterial(const char *methodName, const G4Material *lookForMaterial) const
G4GLOB_DLL std::ostream G4cout
G4MolecularConfiguration * GetConfiguration(const G4String &, bool mustExist=true)
G4ApplicationState
G4MolecularConfiguration * GetMolecularConfiguration(const G4Material *) const
std::map< const G4Material *, std::vector< double > *, CompareMaterial > fAskedNumPerVolTable
const std::map< G4Material *, G4double > & GetMatComponents() const
Definition: G4Material.hh:238
const G4Material * GetBaseMaterial() const
Definition: G4Material.hh:234
G4double GetMassOfMolecule() const
Definition: G4Material.hh:243
virtual G4bool Notify(G4ApplicationState requestedState)
static G4StateManager * GetStateManager()
std::mutex G4Mutex
Definition: G4Threading.hh:84