Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/dna/utils/src/G4DNAMolecularMaterial.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /processes/electromagnetic/dna/utils/src/G4DNAMolecularMaterial.cc (Version 11.3.0) and /processes/electromagnetic/dna/utils/src/G4DNAMolecularMaterial.cc (Version 11.1.1)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 //                                                 26 //
 27 // Author: Mathieu Karamitros                      27 // Author: Mathieu Karamitros
 28 //                                                 28 //
 29                                                    29 
 30 #include "G4DNAMolecularMaterial.hh"           <<  30 #include <utility>
 31                                                    31 
 32 #include "G4AutoLock.hh"                       <<  32 #include "G4DNAMolecularMaterial.hh"
 33 #include "G4Material.hh"                           33 #include "G4Material.hh"
 34 #include "G4MoleculeTable.hh"                  << 
 35 #include "G4StateManager.hh"                       34 #include "G4StateManager.hh"
 36 #include "G4Threading.hh"                          35 #include "G4Threading.hh"
 37                                                <<  36 #include "G4AutoLock.hh"
 38 #include <utility>                             <<  37 #include "G4StateManager.hh"
                                                   >>  38 #include "G4MoleculeTable.hh"
 39                                                    39 
 40 using namespace std;                               40 using namespace std;
 41                                                    41 
 42 G4DNAMolecularMaterial* G4DNAMolecularMaterial     42 G4DNAMolecularMaterial* G4DNAMolecularMaterial::fInstance(nullptr);
 43                                                    43 
 44 namespace                                          44 namespace
 45 {                                                  45 {
 46   G4Mutex aMutex = G4MUTEX_INITIALIZER;            46   G4Mutex aMutex = G4MUTEX_INITIALIZER;
 47 }                                                  47 }
 48                                                    48 
 49 //--------------------------------------------     49 //------------------------------------------------------------------------------
 50                                                    50 
 51 bool CompareMaterial::operator()(const G4Mater     51 bool CompareMaterial::operator()(const G4Material* mat1,
 52                                  const G4Mater     52                                  const G4Material* mat2) const
 53 {                                                  53 {
 54   if (mat1 == nullptr && mat2 == nullptr) retu     54   if (mat1 == nullptr && mat2 == nullptr) return false; //(mat1 == mat2)
 55   if (mat1 == nullptr) return true; // mat1 <      55   if (mat1 == nullptr) return true; // mat1 < mat2
 56   if (mat2 == nullptr) return false; //mat2 <      56   if (mat2 == nullptr) return false; //mat2 < mat1
 57                                                    57 
 58   const G4Material* baseMat1 = mat1->GetBaseMa     58   const G4Material* baseMat1 = mat1->GetBaseMaterial();
 59   const G4Material* baseMat2 = mat2->GetBaseMa     59   const G4Material* baseMat2 = mat2->GetBaseMaterial();
 60                                                    60 
 61   if ((baseMat1 == nullptr) && (baseMat2 == nu <<  61   if (((baseMat1 != nullptr) || (baseMat2 != nullptr)) == false){
 62     // None of the materials derives from a ba     62     // None of the materials derives from a base material
 63     return mat1 < mat2;                            63     return mat1 < mat2;
 64   }                                                64   }
 65   if ((baseMat1 != nullptr) && (baseMat2 != nu <<  65   else if ((baseMat1 != nullptr) && (baseMat2 != nullptr)){
 66     // Both materials derive from a base mater     66     // Both materials derive from a base material
 67     return baseMat1 < baseMat2;                    67     return baseMat1 < baseMat2;
 68   }                                                68   }
 69                                                    69 
 70   if ((baseMat1 != nullptr) && (baseMat2 == nu <<  70   else if ((baseMat1 != nullptr) && (baseMat2 == nullptr)){
 71     // Only the material 1 derives from a base     71     // Only the material 1 derives from a base material
 72     return baseMat1 < mat2;                        72     return baseMat1 < mat2;
 73   }                                                73   }
 74   // only case baseMat1==nullptr && baseMat2 r     74   // only case baseMat1==nullptr && baseMat2 remains
 75   return mat1 < baseMat2;                          75   return mat1 < baseMat2;
 76 }                                                  76 }
 77                                                    77 
 78 //--------------------------------------------     78 //------------------------------------------------------------------------------
 79                                                    79 
 80 G4DNAMolecularMaterial* G4DNAMolecularMaterial     80 G4DNAMolecularMaterial* G4DNAMolecularMaterial::Instance()
 81 {                                                  81 {
 82   if (fInstance == nullptr) fInstance = new G4 <<  82   if (!fInstance) fInstance = new G4DNAMolecularMaterial();
 83   return fInstance;                                83   return fInstance;
 84 }                                                  84 }
 85                                                    85 
 86 //--------------------------------------------     86 //------------------------------------------------------------------------------
 87                                                    87 
 88 void G4DNAMolecularMaterial::Create()              88 void G4DNAMolecularMaterial::Create()
 89 {                                                  89 {
 90   fpCompFractionTable = nullptr;                   90   fpCompFractionTable = nullptr;
 91   fpCompDensityTable = nullptr;                    91   fpCompDensityTable = nullptr;
 92   fpCompNumMolPerVolTable = nullptr;               92   fpCompNumMolPerVolTable = nullptr;
 93   fIsInitialized = false;                          93   fIsInitialized = false;
 94   fNMaterials = 0;                                 94   fNMaterials = 0;
 95 }                                                  95 }
 96                                                    96 
 97 //--------------------------------------------     97 //------------------------------------------------------------------------------
 98                                                    98 
 99 void G4DNAMolecularMaterial::Clear()               99 void G4DNAMolecularMaterial::Clear()
100 {                                                 100 {
101   G4AutoLock l2(&aMutex);                         101   G4AutoLock l2(&aMutex);
102   if (fpCompFractionTable != nullptr){            102   if (fpCompFractionTable != nullptr){
103     fpCompFractionTable->clear();                 103     fpCompFractionTable->clear();
104     delete fpCompFractionTable;                   104     delete fpCompFractionTable;
105     fpCompFractionTable = nullptr;                105     fpCompFractionTable = nullptr;
106   }                                               106   }
107   if (fpCompDensityTable != nullptr){             107   if (fpCompDensityTable != nullptr){
108     fpCompDensityTable->clear();                  108     fpCompDensityTable->clear();
109     delete fpCompDensityTable;                    109     delete fpCompDensityTable;
110     fpCompDensityTable = nullptr;                 110     fpCompDensityTable = nullptr;
111   }                                               111   }
112   if (fpCompNumMolPerVolTable != nullptr){        112   if (fpCompNumMolPerVolTable != nullptr){
113     fpCompNumMolPerVolTable->clear();             113     fpCompNumMolPerVolTable->clear();
114     delete fpCompNumMolPerVolTable;               114     delete fpCompNumMolPerVolTable;
115     fpCompNumMolPerVolTable = nullptr;            115     fpCompNumMolPerVolTable = nullptr;
116   }                                               116   }
117                                                   117 
118   std::map<const G4Material*, std::vector<G4do    118   std::map<const G4Material*, std::vector<G4double>*, CompareMaterial>::iterator it;
119                                                   119 
120   for (it = fAskedDensityTable.begin(); it !=     120   for (it = fAskedDensityTable.begin(); it != fAskedDensityTable.end(); ++it){
121     if (it->second != nullptr){                   121     if (it->second != nullptr){
122       delete it->second;                          122       delete it->second;
123       it->second = nullptr;                       123       it->second = nullptr;
124     }                                             124     }
125   }                                               125   }
126                                                   126 
127   for (it = fAskedNumPerVolTable.begin(); it !    127   for (it = fAskedNumPerVolTable.begin(); it != fAskedNumPerVolTable.end(); ++it){
128     if (it->second != nullptr){                   128     if (it->second != nullptr){
129       delete it->second;                          129       delete it->second;
130       it->second = nullptr;                       130       it->second = nullptr;
131     }                                             131     }
132   }                                               132   }
133   l2.unlock();                                    133   l2.unlock();
134 }                                                 134 }
135                                                   135 
136                                                   136 
137 //--------------------------------------------    137 //------------------------------------------------------------------------------
138                                                   138 
139 G4DNAMolecularMaterial::G4DNAMolecularMaterial << 139 G4DNAMolecularMaterial::G4DNAMolecularMaterial() :
                                                   >> 140     G4VStateDependent()
140 {                                                 141 {
141   Create();                                       142   Create();
142 }                                                 143 }
143                                                   144 
144 //--------------------------------------------    145 //------------------------------------------------------------------------------
145                                                   146 
146 G4bool G4DNAMolecularMaterial::Notify(G4Applic    147 G4bool G4DNAMolecularMaterial::Notify(G4ApplicationState requestedState)
147 {                                                 148 {
148   if (requestedState == G4State_Idle && G4Stat    149   if (requestedState == G4State_Idle && G4StateManager::GetStateManager()
149       ->GetPreviousState() == G4State_PreInit)    150       ->GetPreviousState() == G4State_PreInit){
150     Initialize();                                 151     Initialize();
151   }                                               152   }
152   return true;                                    153   return true;
153 }                                                 154 }
154                                                   155 
155 //--------------------------------------------    156 //------------------------------------------------------------------------------
156                                                   157 
                                                   >> 158 G4DNAMolecularMaterial::G4DNAMolecularMaterial(
                                                   >> 159     const G4DNAMolecularMaterial& /*rhs*/) :
                                                   >> 160     G4VStateDependent()
                                                   >> 161 {
                                                   >> 162   Create();
                                                   >> 163 }
                                                   >> 164 
                                                   >> 165 //------------------------------------------------------------------------------
                                                   >> 166 
                                                   >> 167 G4DNAMolecularMaterial&
                                                   >> 168 G4DNAMolecularMaterial::operator=(const G4DNAMolecularMaterial& rhs)
                                                   >> 169 {
                                                   >> 170   if (this == &rhs) return *this;
                                                   >> 171   Create();
                                                   >> 172   return *this;
                                                   >> 173 }
                                                   >> 174 
                                                   >> 175 //------------------------------------------------------------------------------
                                                   >> 176 
157 G4DNAMolecularMaterial::~G4DNAMolecularMateria    177 G4DNAMolecularMaterial::~G4DNAMolecularMaterial()
158 {                                                 178 {
159   Clear();                                        179   Clear();
160 }                                                 180 }
161                                                   181 
162 //--------------------------------------------    182 //------------------------------------------------------------------------------
163                                                   183 
164 void G4DNAMolecularMaterial::Initialize()         184 void G4DNAMolecularMaterial::Initialize()
165 {                                                 185 {
166   if (fIsInitialized){                            186   if (fIsInitialized){
167     return;                                       187     return;
168   }                                               188   }
169                                                   189 
170   const G4MaterialTable* materialTable = G4Mat    190   const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
171                                                   191 
172   fNMaterials = materialTable->size();            192   fNMaterials = materialTable->size();
173   // This is to prevent segment fault if mater    193   // This is to prevent segment fault if materials are created later on
174   // Actually this creation should not be done    194   // Actually this creation should not be done
175                                                   195 
176   G4AutoLock l1(&aMutex);                         196   G4AutoLock l1(&aMutex);
177   if (fpCompFractionTable == nullptr){            197   if (fpCompFractionTable == nullptr){
178     fpCompFractionTable = new vector<Component    198     fpCompFractionTable = new vector<ComponentMap>(materialTable->size());
179   }                                               199   }
180                                                   200 
181   G4Material* mat(nullptr);                       201   G4Material* mat(nullptr);
182                                                   202 
183   for (std::size_t i = 0; i < fNMaterials; ++i    203   for (std::size_t i = 0; i < fNMaterials; ++i){
184     mat = materialTable->at(i);                   204     mat = materialTable->at(i);
185     SearchMolecularMaterial(mat, mat, 1);         205     SearchMolecularMaterial(mat, mat, 1);
186   }                                               206   }
187                                                   207 
188   InitializeDensity();                            208   InitializeDensity();
189   InitializeNumMolPerVol();                       209   InitializeNumMolPerVol();
190   l1.unlock();                                    210   l1.unlock();
191                                                   211 
192   fIsInitialized = true;                          212   fIsInitialized = true;
193 }                                                 213 }
194                                                   214 
195 //--------------------------------------------    215 //------------------------------------------------------------------------------
196                                                   216 
197 void G4DNAMolecularMaterial::InitializeDensity    217 void G4DNAMolecularMaterial::InitializeDensity()
198 {                                                 218 {
199   if (fpCompFractionTable != nullptr){         << 219   if (fpCompFractionTable){
200     const G4MaterialTable* materialTable = G4M    220     const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
201     fpCompDensityTable = new vector<ComponentM    221     fpCompDensityTable = new vector<ComponentMap>(
202         G4Material::GetMaterialTable()->size()    222         G4Material::GetMaterialTable()->size());
203                                                   223 
204     G4Material* parentMat;                        224     G4Material* parentMat;
205     const G4Material* compMat(nullptr);           225     const G4Material* compMat(nullptr);
206     G4double massFraction = -1;                   226     G4double massFraction = -1;
207     G4double parentDensity = -1;                  227     G4double parentDensity = -1;
208                                                   228 
209     for (std::size_t i = 0; i < fNMaterials; +    229     for (std::size_t i = 0; i < fNMaterials; ++i){
210       parentMat = materialTable->at(i);           230       parentMat = materialTable->at(i);
211       ComponentMap& massFractionComp = (*fpCom    231       ComponentMap& massFractionComp = (*fpCompFractionTable)[i];
212       ComponentMap& densityComp = (*fpCompDens    232       ComponentMap& densityComp = (*fpCompDensityTable)[i];
213                                                   233 
214       parentDensity = parentMat->GetDensity();    234       parentDensity = parentMat->GetDensity();
215                                                   235 
216       for (const auto& it : massFractionComp){ << 236       for (auto it = massFractionComp.cbegin();
217         compMat = it.first;                    << 237           it != massFractionComp.cend(); ++it){
218         massFraction = it.second;              << 238         compMat = it->first;
                                                   >> 239         massFraction = it->second;
219         densityComp[compMat] = massFraction *     240         densityComp[compMat] = massFraction * parentDensity;
220         compMat = nullptr;                        241         compMat = nullptr;
221         massFraction = -1;                        242         massFraction = -1;
222       }                                           243       }
223     }                                             244     }
224   }                                               245   }
225   else{                                           246   else{
226     G4ExceptionDescription exceptionDescriptio    247     G4ExceptionDescription exceptionDescription;
227     exceptionDescription << "The pointer fpCom    248     exceptionDescription << "The pointer fpCompFractionTable is not initialized"
228                          << G4endl;               249                          << G4endl;
229     G4Exception("G4DNAMolecularMaterial::Initi    250     G4Exception("G4DNAMolecularMaterial::InitializeDensity",
230                 "G4DNAMolecularMaterial001", F    251                 "G4DNAMolecularMaterial001", FatalException,
231                 exceptionDescription);            252                 exceptionDescription);
232   }                                               253   }
233 }                                                 254 }
234                                                   255 
235 //--------------------------------------------    256 //------------------------------------------------------------------------------
236                                                   257 
237 void G4DNAMolecularMaterial::InitializeNumMolP    258 void G4DNAMolecularMaterial::InitializeNumMolPerVol()
238 {                                                 259 {
239   if (fpCompDensityTable != nullptr){          << 260   if (fpCompDensityTable){
240     fpCompNumMolPerVolTable = new vector<Compo    261     fpCompNumMolPerVolTable = new vector<ComponentMap>(fNMaterials);
241                                                   262 
242     const G4Material* compMat(nullptr);           263     const G4Material* compMat(nullptr);
243                                                   264 
244     for (std::size_t i = 0; i < fNMaterials; +    265     for (std::size_t i = 0; i < fNMaterials; ++i){
245       ComponentMap& massFractionComp = (*fpCom    266       ComponentMap& massFractionComp = (*fpCompFractionTable)[i];
246       ComponentMap& densityComp = (*fpCompDens    267       ComponentMap& densityComp = (*fpCompDensityTable)[i];
247       ComponentMap& numMolPerVol = (*fpCompNum    268       ComponentMap& numMolPerVol = (*fpCompNumMolPerVolTable)[i];
248                                                   269 
249       for (auto& it : massFractionComp){       << 270       for (auto it = massFractionComp.cbegin();
250         compMat = it.first;                    << 271           it != massFractionComp.cend(); ++it){
                                                   >> 272         compMat = it->first;
251         numMolPerVol[compMat] = densityComp[co    273         numMolPerVol[compMat] = densityComp[compMat]
252             / compMat->GetMassOfMolecule();       274             / compMat->GetMassOfMolecule();
253         compMat = nullptr;                        275         compMat = nullptr;
254       }                                           276       }
255     }                                             277     }
256   }                                               278   }
257   else{                                           279   else{
258     G4ExceptionDescription exceptionDescriptio    280     G4ExceptionDescription exceptionDescription;
259     exceptionDescription << "The pointer fpCom    281     exceptionDescription << "The pointer fpCompDensityTable is not initialized"
260                          << G4endl;               282                          << G4endl;
261     G4Exception("G4DNAMolecularMaterial::Initi    283     G4Exception("G4DNAMolecularMaterial::InitializeNumMolPerVol",
262                 "G4DNAMolecularMaterial002", F    284                 "G4DNAMolecularMaterial002", FatalException,
263                 exceptionDescription);            285                 exceptionDescription);
264   }                                               286   }
265 }                                                 287 }
266                                                   288 
267 //--------------------------------------------    289 //------------------------------------------------------------------------------
268                                                   290 
269 void                                              291 void
270 G4DNAMolecularMaterial::RecordMolecularMateria    292 G4DNAMolecularMaterial::RecordMolecularMaterial(G4Material* parentMaterial,
271                                                   293                                                 G4Material* molecularMaterial,
272                                                   294                                                 G4double fraction)
273 {                                                 295 {
274   ComponentMap& matComponent =                    296   ComponentMap& matComponent =
275       (*fpCompFractionTable)[parentMaterial->G    297       (*fpCompFractionTable)[parentMaterial->GetIndex()];
276                                                   298 
277   if (matComponent.empty()){                      299   if (matComponent.empty()){
278     matComponent[molecularMaterial] = fraction    300     matComponent[molecularMaterial] = fraction;
279     return;                                       301     return;
280   }                                               302   }
281                                                   303 
282   auto it = matComponent.find(molecularMateria    304   auto it = matComponent.find(molecularMaterial);
283                                                   305 
284   if (it == matComponent.cend()){                 306   if (it == matComponent.cend()){
285     matComponent[molecularMaterial] = fraction    307     matComponent[molecularMaterial] = fraction;
286   }                                               308   }
287   else{                                           309   else{
288     matComponent[molecularMaterial] = it->seco    310     matComponent[molecularMaterial] = it->second + fraction;
289     // handle "base material"                     311     // handle "base material"
290   }                                               312   }
291 }                                                 313 }
292                                                   314 
293 //--------------------------------------------    315 //------------------------------------------------------------------------------
294                                                   316 
295 void G4DNAMolecularMaterial::SearchMolecularMa    317 void G4DNAMolecularMaterial::SearchMolecularMaterial(G4Material* parentMaterial,
296                                                   318                                                      G4Material* material,
297                                                   319                                                      G4double currentFraction)
298 {                                                 320 {
299   if (material->GetMassOfMolecule() != 0.0){ /    321   if (material->GetMassOfMolecule() != 0.0){ // is a molecular material
300     RecordMolecularMaterial(parentMaterial, ma    322     RecordMolecularMaterial(parentMaterial, material, currentFraction);
301     return;                                       323     return;
302   }                                               324   }
303                                                   325 
304   G4Material* compMat(nullptr);                   326   G4Material* compMat(nullptr);
305   G4double fraction = -1.;                        327   G4double fraction = -1.;
306   std::map<G4Material*, G4double> matComponent    328   std::map<G4Material*, G4double> matComponent = material->GetMatComponents();
307   auto it = matComponent.cbegin();                329   auto it = matComponent.cbegin();
308                                                   330 
309   for (; it != matComponent.cend(); ++it){        331   for (; it != matComponent.cend(); ++it){
310     compMat = it->first;                          332     compMat = it->first;
311     fraction = it->second;                        333     fraction = it->second;
312     if (compMat->GetMassOfMolecule() == 0.0){     334     if (compMat->GetMassOfMolecule() == 0.0){ // is not a molecular material
313       SearchMolecularMaterial(parentMaterial,     335       SearchMolecularMaterial(parentMaterial, compMat,
314                               currentFraction     336                               currentFraction * fraction);
315     }                                             337     }
316     else{ // is a molecular material              338     else{ // is a molecular material
317       RecordMolecularMaterial(parentMaterial,     339       RecordMolecularMaterial(parentMaterial, compMat,
318                               currentFraction     340                               currentFraction * fraction);
319     }                                             341     }
320   }                                               342   }
321 }                                                 343 }
322                                                   344 
323 //--------------------------------------------    345 //------------------------------------------------------------------------------
324                                                   346 
325 const std::vector<G4double>*                      347 const std::vector<G4double>*
326 G4DNAMolecularMaterial::                          348 G4DNAMolecularMaterial::
327 GetDensityTableFor(const G4Material* lookForMa    349 GetDensityTableFor(const G4Material* lookForMaterial) const
328 {                                                 350 {
329   if (fpCompDensityTable == nullptr){          << 351   if (!fpCompDensityTable){
330     if (fIsInitialized){                          352     if (fIsInitialized){
331       G4ExceptionDescription exceptionDescript    353       G4ExceptionDescription exceptionDescription;
332       exceptionDescription                        354       exceptionDescription
333           << "The pointer fpCompDensityTable i    355           << "The pointer fpCompDensityTable is not initialized will the "
334           "singleton of G4DNAMolecularMaterial    356           "singleton of G4DNAMolecularMaterial "
335           << "has already been initialized." <    357           << "has already been initialized." << G4endl;
336       G4Exception("G4DNAMolecularMaterial::Get    358       G4Exception("G4DNAMolecularMaterial::GetDensityTableFor",
337                   "G4DNAMolecularMaterial003",    359                   "G4DNAMolecularMaterial003", FatalException,
338                   exceptionDescription);          360                   exceptionDescription);
339     }                                             361     }
340                                                   362 
341     if (G4StateManager::GetStateManager()->Get    363     if (G4StateManager::GetStateManager()->GetCurrentState() == G4State_Init){
342       const_cast<G4DNAMolecularMaterial*>(this    364       const_cast<G4DNAMolecularMaterial*>(this)->Initialize();
343     }                                             365     }
344     else{                                         366     else{
345       G4ExceptionDescription exceptionDescript    367       G4ExceptionDescription exceptionDescription;
346       exceptionDescription                        368       exceptionDescription
347           << "The geant4 application is at the    369           << "The geant4 application is at the wrong state. State must be: "
348           "G4State_Init."                         370           "G4State_Init."
349           << G4endl;                              371           << G4endl;
350       G4Exception("G4DNAMolecularMaterial::Get    372       G4Exception("G4DNAMolecularMaterial::GetDensityTableFor",
351                   "G4DNAMolecularMaterial_WRON    373                   "G4DNAMolecularMaterial_WRONG_STATE_APPLICATION",
352                   FatalException, exceptionDes    374                   FatalException, exceptionDescription);
353     }                                             375     }
354   }                                               376   }
355                                                   377 
356   auto it_askedDensityTable = fAskedDensityTab    378   auto it_askedDensityTable = fAskedDensityTable.find(lookForMaterial);
357                                                   379 
358   if (it_askedDensityTable != fAskedDensityTab    380   if (it_askedDensityTable != fAskedDensityTable.cend()){
359     return it_askedDensityTable->second;          381     return it_askedDensityTable->second;
360   }                                               382   }
361                                                   383 
362   const G4MaterialTable* materialTable = G4Mat    384   const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
363                                                   385 
364   auto  output = new std::vector<G4double>(mat << 386   std::vector<G4double>* output = new std::vector<G4double>(materialTable->size());
365                                                   387 
366   ComponentMap::const_iterator it;                388   ComponentMap::const_iterator it;
367                                                   389 
368   G4bool materialWasNotFound = true;              390   G4bool materialWasNotFound = true;
369                                                   391 
370   for (std::size_t i = 0; i < fNMaterials; ++i    392   for (std::size_t i = 0; i < fNMaterials; ++i){
371     ComponentMap& densityTable = (*fpCompDensi    393     ComponentMap& densityTable = (*fpCompDensityTable)[i];
372                                                   394 
373     it = densityTable.find(lookForMaterial);      395     it = densityTable.find(lookForMaterial);
374                                                   396 
375     if (it == densityTable.cend()){               397     if (it == densityTable.cend()){
376       (*output)[i] = 0.0;                         398       (*output)[i] = 0.0;
377     }                                             399     }
378     else{                                         400     else{
379       materialWasNotFound = false;                401       materialWasNotFound = false;
380       (*output)[i] = it->second;                  402       (*output)[i] = it->second;
381     }                                             403     }
382   }                                               404   }
383                                                   405 
384   if (materialWasNotFound){                       406   if (materialWasNotFound){
385     PrintNotAMolecularMaterial("G4DNAMolecular    407     PrintNotAMolecularMaterial("G4DNAMolecularMaterial::GetDensityTableFor",
386                                lookForMaterial    408                                lookForMaterial);
387   }                                               409   }
388                                                   410 
389   fAskedDensityTable.insert(make_pair(lookForM    411   fAskedDensityTable.insert(make_pair(lookForMaterial, output));
390                                                   412 
391   return output;                                  413   return output;
392 }                                                 414 }
393                                                   415 
394 //--------------------------------------------    416 //------------------------------------------------------------------------------
395                                                   417 
396 const std::vector<G4double>* G4DNAMolecularMat    418 const std::vector<G4double>* G4DNAMolecularMaterial::GetNumMolPerVolTableFor(
397     const G4Material* lookForMaterial) const      419     const G4Material* lookForMaterial) const
398 {                                                 420 {
399   if(lookForMaterial==nullptr) return nullptr;    421   if(lookForMaterial==nullptr) return nullptr;
400                                                   422 
401   if (fpCompNumMolPerVolTable == nullptr){     << 423   if (!fpCompNumMolPerVolTable){
402     if (fIsInitialized){                          424     if (fIsInitialized){
403       G4ExceptionDescription exceptionDescript    425       G4ExceptionDescription exceptionDescription;
404       exceptionDescription                        426       exceptionDescription
405           << "The pointer fpCompNumMolPerVolTa    427           << "The pointer fpCompNumMolPerVolTable is not initialized whereas "
406           "the singleton of G4DNAMolecularMate    428           "the singleton of G4DNAMolecularMaterial "
407           << "has already been initialized." <    429           << "has already been initialized." << G4endl;
408       G4Exception("G4DNAMolecularMaterial::Get    430       G4Exception("G4DNAMolecularMaterial::GetNumMolPerVolTableFor",
409                   "G4DNAMolecularMaterial005",    431                   "G4DNAMolecularMaterial005", FatalException,
410                   exceptionDescription);          432                   exceptionDescription);
411     }                                             433     }
412                                                   434 
413     if (G4StateManager::GetStateManager()->Get    435     if (G4StateManager::GetStateManager()->GetCurrentState() == G4State_Init){
414       const_cast<G4DNAMolecularMaterial*>(this    436       const_cast<G4DNAMolecularMaterial*>(this)->Initialize();
415     }                                             437     }
416     else{                                         438     else{
417       G4ExceptionDescription exceptionDescript    439       G4ExceptionDescription exceptionDescription;
418       exceptionDescription                        440       exceptionDescription
419           << "The geant4 application is at the    441           << "The geant4 application is at the wrong state. State must be : "
420           "G4State_Init."                         442           "G4State_Init."
421           << G4endl;                              443           << G4endl;
422       G4Exception("G4DNAMolecularMaterial::Get    444       G4Exception("G4DNAMolecularMaterial::GetNumMolPerVolTableFor",
423                   "G4DNAMolecularMaterial_WRON    445                   "G4DNAMolecularMaterial_WRONG_STATE_APPLICATION",
424                   FatalException, exceptionDes    446                   FatalException, exceptionDescription);
425     }                                             447     }
426   }                                               448   }
427                                                   449 
428   auto it_askedNumMolPerVolTable = fAskedNumPe    450   auto it_askedNumMolPerVolTable = fAskedNumPerVolTable.find(lookForMaterial);
429   if (it_askedNumMolPerVolTable != fAskedNumPe    451   if (it_askedNumMolPerVolTable != fAskedNumPerVolTable.cend()){
430     return it_askedNumMolPerVolTable->second;     452     return it_askedNumMolPerVolTable->second;
431   }                                               453   }
432                                                   454 
433   const G4MaterialTable* materialTable = G4Mat    455   const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
434                                                   456 
435   auto  output = new std::vector<G4double>(mat << 457   std::vector<G4double>* output = new std::vector<G4double>(materialTable->size());
436                                                   458 
437   ComponentMap::const_iterator it;                459   ComponentMap::const_iterator it;
438                                                   460 
439   G4bool materialWasNotFound = true;              461   G4bool materialWasNotFound = true;
440                                                   462 
441   for (std::size_t i = 0; i < fNMaterials; ++i    463   for (std::size_t i = 0; i < fNMaterials; ++i){
442     ComponentMap& densityTable = (*fpCompNumMo    464     ComponentMap& densityTable = (*fpCompNumMolPerVolTable)[i];
443                                                   465 
444     it = densityTable.find(lookForMaterial);      466     it = densityTable.find(lookForMaterial);
445                                                   467 
446     if (it == densityTable.cend()){               468     if (it == densityTable.cend()){
447       (*output)[i] = 0.0;                         469       (*output)[i] = 0.0;
448     }                                             470     }
449     else{                                         471     else{
450       materialWasNotFound = false;                472       materialWasNotFound = false;
451       (*output)[i] = it->second;                  473       (*output)[i] = it->second;
452     }                                             474     }
453   }                                               475   }
454                                                   476 
455   if (materialWasNotFound){                       477   if (materialWasNotFound){
456     PrintNotAMolecularMaterial(                   478     PrintNotAMolecularMaterial(
457         "G4DNAMolecularMaterial::GetNumMolPerV    479         "G4DNAMolecularMaterial::GetNumMolPerVolTableFor", lookForMaterial);
458   }                                               480   }
459                                                   481 
460   fAskedNumPerVolTable.insert(make_pair(lookFo    482   fAskedNumPerVolTable.insert(make_pair(lookForMaterial, output));
461                                                   483 
462   return output;                                  484   return output;
463 }                                                 485 }
464                                                   486 
465 //--------------------------------------------    487 //------------------------------------------------------------------------------
466                                                   488 
467 void G4DNAMolecularMaterial::                     489 void G4DNAMolecularMaterial::
468 PrintNotAMolecularMaterial(const char* methodN    490 PrintNotAMolecularMaterial(const char* methodName,
469                            const G4Material* l    491                            const G4Material* lookForMaterial) const
470 {                                                 492 {
471   auto it = fWarningPrinted.find(lookForMateri    493   auto it = fWarningPrinted.find(lookForMaterial);
472                                                   494 
473   if (it == fWarningPrinted.cend()){              495   if (it == fWarningPrinted.cend()){
474     G4ExceptionDescription exceptionDescriptio    496     G4ExceptionDescription exceptionDescription;
475     exceptionDescription << "The material " <<    497     exceptionDescription << "The material " << lookForMaterial->GetName()
476                          << " is not defined a    498                          << " is not defined as a molecular material."
477                          << G4endl                499                          << G4endl
478                          << "Meaning: The elem    500                          << "Meaning: The elements should be added to the "
479                          "material using atom     501                          "material using atom count rather than mass fraction "
480                          "(cf. G4Material)"       502                          "(cf. G4Material)"
481     << G4endl                                     503     << G4endl
482     << "If you want to use DNA processes on li    504     << "If you want to use DNA processes on liquid water, you should better use "
483     "the NistManager to create the water mater    505     "the NistManager to create the water material."
484     << G4endl                                     506     << G4endl
485     << "Since this message is displayed, it me    507     << "Since this message is displayed, it means that the DNA models will not "
486     "be called."                                  508     "be called."
487     << "Please note that this message will onl    509     << "Please note that this message will only appear once even if you are "
488     "using other methods of G4DNAMolecularMate    510     "using other methods of G4DNAMolecularMaterial."
489     << G4endl;                                    511     << G4endl;
490                                                   512 
491     G4Exception(methodName, "MATERIAL_NOT_DEFI    513     G4Exception(methodName, "MATERIAL_NOT_DEFINE_USING_ATOM_COUNT", JustWarning,
492                 exceptionDescription);            514                 exceptionDescription);
493     fWarningPrinted[lookForMaterial] = true;      515     fWarningPrinted[lookForMaterial] = true;
494   }                                               516   }
495 }                                                 517 }
496                                                   518 
497 //--------------------------------------------    519 //------------------------------------------------------------------------------
498                                                   520 
499 G4MolecularConfiguration*                         521 G4MolecularConfiguration*
500 G4DNAMolecularMaterial::                          522 G4DNAMolecularMaterial::
501 GetMolecularConfiguration(const G4Material* ma    523 GetMolecularConfiguration(const G4Material* material) const
502 {                                                 524 {
503   auto  material_id = (G4int)material->GetInde << 525   G4int material_id = (G4int)material->GetIndex();
504   auto it = fMaterialToMolecularConf.find(mate    526   auto it = fMaterialToMolecularConf.find(material_id);
505   if(it == fMaterialToMolecularConf.cend()) re    527   if(it == fMaterialToMolecularConf.cend()) return nullptr;
506   return it->second;                              528   return it->second;
507 }                                                 529 }
508                                                   530 
509 //--------------------------------------------    531 //------------------------------------------------------------------------------
510                                                   532 
511 void                                              533 void
512 G4DNAMolecularMaterial::                          534 G4DNAMolecularMaterial::
513 SetMolecularConfiguration(const G4Material* ma    535 SetMolecularConfiguration(const G4Material* material,
514                           G4MolecularConfigura    536                           G4MolecularConfiguration* molConf)
515 {                                                 537 {
516   assert(material != nullptr);                    538   assert(material != nullptr);
517   auto  material_id = (G4int)material->GetInde << 539   G4int material_id = (G4int)material->GetIndex();
518   fMaterialToMolecularConf[material_id] = molC    540   fMaterialToMolecularConf[material_id] = molConf;
519 }                                                 541 }
520                                                   542 
521 //--------------------------------------------    543 //------------------------------------------------------------------------------
522                                                   544 
523 void                                              545 void
524 G4DNAMolecularMaterial::SetMolecularConfigurat    546 G4DNAMolecularMaterial::SetMolecularConfiguration(const G4Material* material,
525                                                   547                                                   const G4String& molUserID)
526 {                                                 548 {
527   assert(material != nullptr);                    549   assert(material != nullptr);
528   auto  material_id = (G4int)material->GetInde << 550   G4int material_id = (G4int)material->GetIndex();
529   fMaterialToMolecularConf[material_id] =         551   fMaterialToMolecularConf[material_id] =
530     G4MoleculeTable::Instance()->GetConfigurat    552     G4MoleculeTable::Instance()->GetConfiguration(molUserID, true);
531 }                                                 553 }
532                                                   554 
533 //--------------------------------------------    555 //------------------------------------------------------------------------------
534                                                   556 
535 void                                              557 void
536 G4DNAMolecularMaterial::SetMolecularConfigurat    558 G4DNAMolecularMaterial::SetMolecularConfiguration(const G4String& materialName,
537                                                   559                                                   const G4String& molUserID)
538 {                                                 560 {
539   G4Material* material = G4Material::GetMateri    561   G4Material* material = G4Material::GetMaterial(materialName);
540                                                   562 
541   if(material == nullptr){                        563   if(material == nullptr){
542     G4cout<< "Material " << materialName          564     G4cout<< "Material " << materialName
543           << " was not found and therefore won    565           << " was not found and therefore won't be linked to "
544           << molUserID << G4endl;                 566           << molUserID << G4endl;
545     return;                                       567     return;
546   }                                               568   }
547   SetMolecularConfiguration(material, molUserI    569   SetMolecularConfiguration(material, molUserID);
548 }                                                 570 }
549                                                   571 
550 //--------------------------------------------    572 //------------------------------------------------------------------------------
551                                                   573 
552 G4double                                          574 G4double
553 G4DNAMolecularMaterial::                          575 G4DNAMolecularMaterial::
554 GetNumMoleculePerVolumeUnitForMaterial(const G    576 GetNumMoleculePerVolumeUnitForMaterial(const G4Material*)
555 {                                                 577 {
556   G4Exception("G4DNAMolecularMaterial::GetNumM    578   G4Exception("G4DNAMolecularMaterial::GetNumMolPerVolForComponentInComposite",
557               "DEPRECATED",                       579               "DEPRECATED",
558               FatalException,"Use standard met    580               FatalException,"Use standard method: GetNumMolPerVolTableFor"
559               " at the run initialization to r    581               " at the run initialization to retrieve a read-only table used"
560               " during stepping. The method is    582               " during stepping. The method is thread-safe.");
561   return 0.;                                      583   return 0.;
562 }                                                 584 }
563                                                   585 
564 //--------------------------------------------    586 //------------------------------------------------------------------------------
565                                                   587 
566 G4double                                          588 G4double
567 G4DNAMolecularMaterial::                          589 G4DNAMolecularMaterial::
568 GetNumMolPerVolForComponentInComposite(const G    590 GetNumMolPerVolForComponentInComposite(const G4Material*,
569                                        const G    591                                        const G4Material*,
570                                        G4doubl    592                                        G4double)
571 {                                                 593 {
572   G4Exception("G4DNAMolecularMaterial::GetNumM    594   G4Exception("G4DNAMolecularMaterial::GetNumMolPerVolForComponentInComposite",
573                "DEPRECATED",                      595                "DEPRECATED",
574                FatalException,"Use standard me    596                FatalException,"Use standard method: GetNumMolPerVolTableFor"
575               " at the run initialization to r    597               " at the run initialization to retrieve a read-only table used"
576               " during stepping. The method is    598               " during stepping. The method is thread-safe.");
577   return 0.;                                      599   return 0.;
578 }                                                 600 }
579                                                   601