Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4DNAMolecularMaterial.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: G4DNAMolecularMaterial.cc 65022 2012-11-12 16:43:12Z gcosmo $
27 //
29 #include "G4Material.hh"
30 #include <utility>
31 #include "G4StateManager.hh"
32 
33 using namespace std;
34 
35 
36 bool CompareMaterial::operator() (const G4Material* mat1, const G4Material* mat2) const
37 {
38  if(mat1==0 && mat2==0) return false; //(mat1 == mat2)
39  if(mat1==0) return true; // mat1 < mat2
40  if(mat2==0) return false; //mat2 < mat1
41 
42  const G4Material* baseMat1 = mat1->GetBaseMaterial();
43  const G4Material* baseMat2 = mat2->GetBaseMaterial();
44 
45  if((baseMat1 || baseMat2) == 0) // None of the materials derives from a base material
46  {
47  return mat1 < mat2;
48  }
49  else if(baseMat1 && baseMat2) // Both materials derive from a base material
50  {
51  return baseMat1 < baseMat2;
52  }
53 
54  else if(baseMat1 && (baseMat2 == 0)) // Only the material 1 derives from a base material
55  {
56  return baseMat1 < mat2;
57  }
58  // only case baseMat1==0 && baseMat2 remains
59  return mat1 < baseMat2;
60 }
61 
63 
65 {
66  if(! fInstance) new G4DNAMolecularMaterial();
67  return fInstance;
68 }
69 
71 {
72  delete fInstance;
73  fInstance = 0;
74 }
75 
77 {
78  fpCompFractionTable = 0;
79  fpCompDensityTable = 0;
80  fpCompNumMolPerVolTable = 0;
81  fIsInitialized = false;
82  fInstance = this;
83 }
84 
86 {
87  Create();
88  fInstance = this;
89 }
90 
92 {
93  if(requestedState == G4State_Idle) Initialize();
94  return true;
95 }
96 
98 {
99  Create();
100 }
101 
103 {
104  if(this == &rhs) return *this;
105  Create();
106  return *this;
107 }
108 
110 {
112  {
113  fpCompFractionTable->clear();
114  delete fpCompFractionTable;
116  }
118  {
119  fpCompDensityTable->clear();
120  delete fpCompDensityTable;
121  fpCompDensityTable = 0;
122  }
124  {
125  fpCompNumMolPerVolTable->clear();
128  }
129 
130  std::map<const G4Material*,std::vector<double>*,CompareMaterial>::iterator it;
131 
132  for(it= fAskedDensityTable.begin() ; it != fAskedDensityTable.end() ;it++)
133  {
134  if(it->second)
135  {
136  delete it->second;
137  it->second = 0;
138  }
139  }
140 
141  for(it= fAskedNumPerVolTable.begin() ; it != fAskedNumPerVolTable.end() ;it++)
142  {
143  if(it->second)
144  {
145  delete it->second;
146  it->second = 0;
147  }
148  }
149 }
150 
151 void G4DNAMolecularMaterial::RecordMolecularMaterial(G4Material* parentMaterial, G4Material* molecularMaterial, G4double fraction)
152 {
153  ComponentMap& matComponent = (*fpCompFractionTable)[parentMaterial->GetIndex()];
154 
155  if(matComponent.empty())
156  {
157  matComponent[molecularMaterial] = fraction;
158  return;
159  }
160 
161  ComponentMap::iterator it = matComponent.find(molecularMaterial);
162 
163  if(it == matComponent.end())
164  {
165  matComponent[molecularMaterial] = fraction;
166  }
167  else
168  {
169  matComponent[molecularMaterial] = it->second + fraction;
170  }
171 }
172 
173 void G4DNAMolecularMaterial::SearchMolecularMaterial(G4Material* parentMaterial, G4Material* material, double currentFraction)
174 {
175  if(material->GetMassOfMolecule() != 0.0)
176  {
177  RecordMolecularMaterial(parentMaterial,material,currentFraction);
178  return;
179  }
180 
181  G4Material* compMat(0);
182  G4double fraction = -1;
183  std::map<G4Material*,G4double> matComponent = material->GetMatComponents();
184  std::map<G4Material*,G4double>::iterator it = matComponent.begin();
185 
186  for( ; it!=matComponent.end() ; it++)
187  {
188  compMat = it->first;
189  fraction = it->second;
190  if(compMat->GetMassOfMolecule() == 0.0)
191  {
192  SearchMolecularMaterial(parentMaterial,compMat,currentFraction*fraction);
193  }
194  else
195  {
196  RecordMolecularMaterial(parentMaterial,compMat,currentFraction*fraction);
197  }
198 
199  compMat = 0;
200  fraction = -1;
201  }
202 }
203 
205 {
207  {
208  const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
209  fpCompDensityTable = new vector<ComponentMap>(G4Material::GetMaterialTable()->size());
210 
211  G4Material* parentMat;
212  const G4Material* compMat(0);
213  double massFraction = -1;
214  double parentDensity = -1;
215 
216  for(int i = 0 ; i < int(materialTable->size()) ; i++)
217  {
218  parentMat = materialTable->at(i);
219  ComponentMap& massFractionComp = (*fpCompFractionTable)[i];
220  ComponentMap& densityComp = (*fpCompDensityTable)[i];
221 
222  parentDensity = parentMat->GetDensity();
223 
224  for(ComponentMap::iterator it = massFractionComp.begin() ; it!=massFractionComp.end() ; it++)
225  {
226  compMat = it->first;
227  massFraction = it->second;
228  densityComp[compMat] = massFraction*parentDensity;
229  compMat = 0;
230  massFraction = -1;
231  }
232  }
233  }
234  else
235  {
236  G4ExceptionDescription exceptionDescription;
237  exceptionDescription << "The pointer fpCompFractionTable is not initialized" << G4endl;
238  G4Exception("G4DNAMolecularMaterial::InitializeDensity","G4DNAMolecularMaterial001",
239  FatalException,exceptionDescription);
240  }
241 }
242 
244 {
246  {
247  const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
248  fpCompNumMolPerVolTable = new vector<ComponentMap>(G4Material::GetMaterialTable()->size());
249 
250  const G4Material* compMat(0);
251 
252  for(int i = 0 ; i < int(materialTable->size()) ; i++)
253  {
254  ComponentMap& massFractionComp = (*fpCompFractionTable)[i];
255  ComponentMap& densityComp = (*fpCompDensityTable)[i];
256  ComponentMap& numMolPerVol = (*fpCompNumMolPerVolTable)[i];
257 
258  for(ComponentMap::iterator it = massFractionComp.begin() ; it!=massFractionComp.end() ; it++)
259  {
260  compMat = it->first;
261  numMolPerVol[compMat] = densityComp[compMat]/ compMat->GetMassOfMolecule();
262  compMat = 0;
263  }
264  }
265  }
266  else
267  {
268  G4ExceptionDescription exceptionDescription;
269  exceptionDescription << "The pointer fpCompDensityTable is not initialized" << G4endl;
270  G4Exception("G4DNAMolecularMaterial::InitializeNumMolPerVol","G4DNAMolecularMaterial002",
271  FatalException,exceptionDescription);
272  }
273 }
274 
276 {
277  if(fIsInitialized) return;
278 
279  const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
280 
281  if(fpCompFractionTable==0)
282  {
283  fpCompFractionTable = new vector<ComponentMap>(materialTable->size());
284  }
285 
286  G4Material* mat(0);
287 
288  for(int i = 0 ; i < int(materialTable->size()) ; i++)
289  {
290  mat = materialTable->at(i);
291  SearchMolecularMaterial(mat,mat,1);
292 
293  mat = 0;
294  }
295 
298 
299  fIsInitialized = true;
300 }
301 
302 const std::vector<double>* G4DNAMolecularMaterial::GetDensityTableFor(const G4Material* lookForMaterial) const
303 {
304  if(!fpCompDensityTable)
305  {
306  if(fIsInitialized)
307  {
308  G4ExceptionDescription exceptionDescription;
309  exceptionDescription << "The pointer fpCompDensityTable is not initialized will the singleton of G4DNAMolecularMaterial "
310  << "has already been initialized."<< G4endl;
311  G4Exception("G4DNAMolecularMaterial::GetDensityTableFor","G4DNAMolecularMaterial003",
312  FatalException,exceptionDescription);
313  }
314 
315  if(G4StateManager::GetStateManager()->GetCurrentState() == G4State_Idle)
316  const_cast<G4DNAMolecularMaterial*>(this)->Initialize();
317  else
318  {
319  G4ExceptionDescription exceptionDescription;
320  exceptionDescription << "The geant4 application is at the wrong state. State must be: G4State_Idle."<< G4endl;
321  G4Exception("G4DNAMolecularMaterial::GetDensityTableFor",
322  "G4DNAMolecularMaterial_WRONG_STATE_APPLICATION",FatalException,exceptionDescription);
323  }
324  }
325 
326  std::map<const G4Material*,std::vector<double>*,CompareMaterial>::const_iterator it_askedDensityTable = fAskedDensityTable.find(lookForMaterial);
327  if(it_askedDensityTable != fAskedDensityTable.end())
328  {
329  return it_askedDensityTable->second;
330  }
331 
332  const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
333 
334  std::vector<double>* output = new std::vector<double>(materialTable->size());
335 
336  ComponentMap::const_iterator it;
337 
338  G4bool materialWasNotFound = true;
339 
340  for(int i = 0 ; i < int(materialTable->size()) ; i++)
341  {
342  ComponentMap& densityTable = (*fpCompDensityTable)[i];
343 
344  it = densityTable.find(lookForMaterial);
345 
346  if(it==densityTable.end())
347  {
348  (*output)[i] = 0.0;
349  }
350  else
351  {
352  materialWasNotFound = false;
353  (*output)[i] = it->second;
354  }
355  }
356 
357  if(materialWasNotFound)
358  {
359  PrintNotAMolecularMaterial("G4DNAMolecularMaterial::GetDensityTableFor",lookForMaterial);
360  }
361 
362  fAskedDensityTable.insert(make_pair(lookForMaterial, output));
363 
364  return output;
365 }
366 
367 const std::vector<double>* G4DNAMolecularMaterial::GetNumMolPerVolTableFor(const G4Material* lookForMaterial) const
368 {
370  {
371  if(fIsInitialized)
372  {
373  G4ExceptionDescription exceptionDescription;
374  exceptionDescription << "The pointer fpCompNumMolPerVolTable is not initialized will the singleton of G4DNAMolecularMaterial "
375  << "has already been initialized."<< G4endl;
376  G4Exception("G4DNAMolecularMaterial::GetNumMolPerVolTableFor","G4DNAMolecularMaterial005",
377  FatalException,exceptionDescription);
378  }
379 
380  if(G4StateManager::GetStateManager()->GetCurrentState() == G4State_Idle)
381  {
382  const_cast<G4DNAMolecularMaterial*>(this)->Initialize();
383  }
384  else
385  {
386  G4ExceptionDescription exceptionDescription;
387  exceptionDescription << "The geant4 application is at the wrong state. State must be : G4State_Idle."<< G4endl;
388  G4Exception("G4DNAMolecularMaterial::GetNumMolPerVolTableFor",
389  "G4DNAMolecularMaterial_WRONG_STATE_APPLICATION",FatalException,exceptionDescription);
390  }
391  }
392 
393  std::map<const G4Material*,std::vector<double>*,CompareMaterial>::const_iterator it_askedNumMolPerVolTable = fAskedNumPerVolTable.find(lookForMaterial);
394  if(it_askedNumMolPerVolTable != fAskedNumPerVolTable.end())
395  {
396  return it_askedNumMolPerVolTable->second;
397  }
398 
399  const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
400 
401  std::vector<double>* output = new std::vector<double>(materialTable->size());
402 
403  ComponentMap::const_iterator it;
404 
405  G4bool materialWasNotFound = true;
406 
407  for(int i = 0 ; i < int(materialTable->size()) ; i++)
408  {
409  ComponentMap& densityTable = (*fpCompNumMolPerVolTable)[i];
410 
411  it = densityTable.find(lookForMaterial);
412 
413  if(it==densityTable.end())
414  {
415  (*output)[i] = 0.0;
416  }
417  else
418  {
419  materialWasNotFound = false;
420  (*output)[i] = it->second;
421  }
422  }
423 
424  if(materialWasNotFound)
425  {
426  PrintNotAMolecularMaterial("G4DNAMolecularMaterial::GetNumMolPerVolTableFor",lookForMaterial);
427  }
428 
429  fAskedNumPerVolTable.insert(make_pair(lookForMaterial, output));
430 
431  return output;
432 }
433 
434 void G4DNAMolecularMaterial::PrintNotAMolecularMaterial(const char* methodName, const G4Material* lookForMaterial) const
435 {
436  std::map<const G4Material*,bool,CompareMaterial>::iterator it = fWarningPrinted.find(lookForMaterial);
437 
438  if(it == fWarningPrinted.end())
439  {
440  G4ExceptionDescription exceptionDescription;
441  exceptionDescription
442  << "The material " << lookForMaterial->GetName()
443  << " is not defined as a molecular material."<< G4endl
444  << "Meaning: The elements should be added to the material using atom count rather than mass fraction (cf. G4Material)"
445  << G4endl
446  << "If you want to use DNA processes on liquid water, you should better use the NistManager to create the water material."
447  << G4endl
448  << "Since this message is displayed, it means that the DNA models will not be called."
449  << "Please note that this message will only appear once even if you are using other methods of G4DNAMolecularMaterial."
450  << G4endl;
451 
452  G4Exception(methodName,"MATERIAL_NOT_DEFINE_USING_ATOM_COUNT",JustWarning,exceptionDescription);
453  fWarningPrinted[lookForMaterial] = true;
454  }
455 }