Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/physics_lists/constructors/electromagnetic/src/G4EmDNABuilder.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 ]

  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 //
 27 // Geant4 class G4EmDNABuilder
 28 //
 29 // Author V.Ivanchenko 22.05.2020
 30 //
 31 
 32 #include "G4EmDNABuilder.hh"
 33 #include "G4SystemOfUnits.hh"
 34 
 35 // particles
 36 #include "G4Gamma.hh"
 37 #include "G4Electron.hh"
 38 #include "G4Positron.hh"
 39 #include "G4Proton.hh"
 40 #include "G4Alpha.hh"
 41 #include "G4GenericIon.hh"
 42 #include "G4DNAGenericIonsManager.hh"
 43 #include "G4ParticleDefinition.hh"
 44 
 45 // utilities
 46 #include "G4SystemOfUnits.hh"
 47 #include "G4EmParameters.hh"
 48 #include "G4EmBuilder.hh"
 49 #include "G4PhysicsListHelper.hh"
 50 #include "G4LowEnergyEmProcessSubType.hh"
 51 #include "G4PhysListUtil.hh"
 52 #include "G4ProcessManager.hh"
 53 #include "G4Region.hh"
 54 
 55 // standard processes
 56 #include "G4ComptonScattering.hh"
 57 #include "G4GammaConversion.hh"
 58 #include "G4PhotoElectricEffect.hh"
 59 #include "G4RayleighScattering.hh"
 60 #include "G4eMultipleScattering.hh"
 61 #include "G4hMultipleScattering.hh"
 62 #include "G4eIonisation.hh"
 63 #include "G4hIonisation.hh"
 64 #include "G4ionIonisation.hh"
 65 #include "G4eBremsstrahlung.hh"
 66 #include "G4eplusAnnihilation.hh"
 67 #include "G4NuclearStopping.hh"
 68 
 69 // standard models
 70 #include "G4LivermorePhotoElectricModel.hh"
 71 #include "G4KleinNishinaModel.hh"
 72 #include "G4LowEPComptonModel.hh"
 73 #include "G4UrbanMscModel.hh"
 74 #include "G4LowEWentzelVIModel.hh"
 75 #include "G4GoudsmitSaundersonMscModel.hh"
 76 #include "G4MollerBhabhaModel.hh"
 77 #include "G4SeltzerBergerModel.hh"
 78 #include "G4Generator2BS.hh"
 79 #include "G4BraggModel.hh"
 80 #include "G4BraggIonModel.hh"
 81 #include "G4BetheBlochModel.hh"
 82 #include "G4DummyModel.hh"
 83 
 84 // DNA models
 85 #include "G4DNAOneStepThermalizationModel.hh"
 86 #include "G4DNAUeharaScreenedRutherfordElasticModel.hh"
 87 #include "G4DNACPA100ElasticModel.hh"
 88 #include "G4DNAChampionElasticModel.hh"
 89 #include "G4DNAEmfietzoglouExcitationModel.hh"
 90 #include "G4DNACPA100ExcitationModel.hh"
 91 #include "G4DNASancheExcitationModel.hh"
 92 #include "G4DNAEmfietzoglouIonisationModel.hh"
 93 #include "G4DNACPA100IonisationModel.hh"
 94 #include "G4DNABornIonisationModel1.hh"
 95 #include "G4DNAMeltonAttachmentModel.hh"
 96 #include "G4DNAIonElasticModel.hh"
 97 #include "G4DNAMillerGreenExcitationModel.hh"
 98 #include "G4DNABornExcitationModel.hh"
 99 #include "G4DNARuddIonisationModel.hh"
100 #include "G4DNARuddIonisationExtendedModel.hh"
101 #include "G4DNADingfelderChargeDecreaseModel.hh"
102 #include "G4DNADingfelderChargeIncreaseModel.hh"
103 #include "G4DNARPWBAExcitationModel.hh"
104 #include "G4DNARPWBAIonisationModel.hh"
105 
106 static const G4double lowEnergyRPWBA = 100*CLHEP::MeV;
107 static const G4double lowEnergyMSC = 1*CLHEP::MeV;
108 static const G4double lowEnergyProtonIoni = 2*CLHEP::MeV;
109 
110 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
111 
112 void G4EmDNABuilder::ConstructDNAParticles()
113 {
114   // standard particles
115   G4EmBuilder::ConstructMinimalEmSet();
116 
117   // DNA ions
118   G4DNAGenericIonsManager* genericIonsManager
119     = G4DNAGenericIonsManager::Instance();
120   genericIonsManager->GetIon("alpha+");
121   genericIonsManager->GetIon("helium");
122   genericIonsManager->GetIon("hydrogen");
123 }
124 
125 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
126 
127 void 
128 G4EmDNABuilder::ConstructStandardEmPhysics(const G4double emin_elec,
129                                            const G4double emin_proton,
130                                            const G4double emin_alpha,
131                                            const G4double emin_ion,
132                                            const G4EmDNAMscModelType mscType,
133                                            const G4bool)
134 {
135   G4PhysicsListHelper* ph = G4PhysicsListHelper::GetPhysicsListHelper();
136   G4EmParameters* param = G4EmParameters::Instance();
137   const G4double emax = param->MaxKinEnergy();
138   G4EmBuilder::PrepareEMPhysics();
139 
140   // gamma
141   G4ParticleDefinition* gamma = G4Gamma::Gamma();
142 
143   // photoelectric effect - Livermore model 
144   auto thePEEffect = new G4PhotoElectricEffect();
145   thePEEffect->SetEmModel(new G4LivermorePhotoElectricModel());
146   ph->RegisterProcess(thePEEffect, gamma);
147 
148   // Compton scattering - Klein-Nishina
149   auto theComptonScattering = new G4ComptonScattering();
150   theComptonScattering->SetEmModel(new G4KleinNishinaModel());
151   auto cModel = new G4LowEPComptonModel();
152   cModel->SetHighEnergyLimit(20*CLHEP::MeV);
153   theComptonScattering->AddEmModel(0, cModel);
154   ph->RegisterProcess(theComptonScattering, gamma);
155 
156   // gamma conversion - 5D model
157   auto theGammaConversion = new G4GammaConversion();
158   ph->RegisterProcess(theGammaConversion, gamma);
159 
160   // Rayleigh scattering - Livermore model
161   auto theRayleigh = new G4RayleighScattering();
162   ph->RegisterProcess(theRayleigh, gamma);
163 
164   // electron 
165   if(emin_elec < emax) {
166     G4ParticleDefinition* elec = G4Electron::Electron();
167     auto msc_el = new G4eMultipleScattering();
168     G4VMscModel* msc_model_el;
169     if(mscType == dnaWVI) {
170       msc_model_el = new G4LowEWentzelVIModel();
171     } else if(mscType == dnaGS) {
172       msc_model_el = new G4GoudsmitSaundersonMscModel();
173     } else {
174       msc_model_el = new G4UrbanMscModel();
175     }
176     msc_model_el->SetActivationLowEnergyLimit(lowEnergyMSC);
177     msc_el->SetEmModel(msc_model_el);
178     ph->RegisterProcess(msc_el, elec);
179 
180     auto ioni = new G4eIonisation();
181     auto mb_el = new G4MollerBhabhaModel();
182     mb_el->SetActivationLowEnergyLimit(emin_elec);
183     ioni->SetEmModel(mb_el);
184     ph->RegisterProcess(ioni, elec);
185 
186     auto brem = new G4eBremsstrahlung();
187     auto sb_el = new G4SeltzerBergerModel();
188     sb_el->SetActivationLowEnergyLimit(emin_elec);
189     sb_el->SetHighEnergyLimit(emax);
190     sb_el->SetAngularDistribution(new G4Generator2BS());
191     brem->SetEmModel(sb_el);
192     ph->RegisterProcess(brem, elec);
193   }
194 
195   // positron
196   G4ParticleDefinition* posi = G4Positron::Positron();
197   auto msc_pos = new G4eMultipleScattering();
198   G4VMscModel* msc_model_pos;
199   if(mscType == dnaWVI) {
200     msc_model_pos = new G4LowEWentzelVIModel();
201   } else if(mscType == dnaGS) {
202     msc_model_pos = new G4GoudsmitSaundersonMscModel();
203   } else {
204     msc_model_pos = new G4UrbanMscModel();
205   }
206   msc_pos->SetEmModel(msc_model_pos);
207   ph->RegisterProcess(msc_pos, posi);
208   ph->RegisterProcess(new G4eIonisation(), posi);
209 
210   auto brem = new G4eBremsstrahlung();
211   auto sb = new G4SeltzerBergerModel();
212   sb->SetHighEnergyLimit(emax);
213   sb->SetAngularDistribution(new G4Generator2BS());
214   brem->SetEmModel(sb);
215   ph->RegisterProcess(brem, posi);
216   ph->RegisterProcess(new G4eplusAnnihilation(), posi);
217 
218   // proton
219   if(emin_proton < emax) {
220     G4ParticleDefinition* part = G4Proton::Proton();
221     StandardHadronPhysics(part, lowEnergyMSC, emin_proton, emax,
222                           mscType, false);
223   }
224 
225   // GenericIon
226   if(emin_ion < emax) {
227     G4ParticleDefinition* ion = G4GenericIon::GenericIon();
228     StandardHadronPhysics(ion, lowEnergyMSC, emin_ion, emax,
229                           dnaUrban, true);
230   }
231 
232   // alpha
233   if(emin_alpha < emax) {
234     G4ParticleDefinition* part = G4Alpha::Alpha();
235     StandardHadronPhysics(part, lowEnergyMSC, emin_alpha, emax,
236                           dnaUrban, true);
237     
238     // alpha+
239     G4DNAGenericIonsManager* genericIonsManager
240       = G4DNAGenericIonsManager::Instance();
241     part = genericIonsManager->GetIon("alpha+");
242     StandardHadronPhysics(part, lowEnergyMSC, emin_alpha, emax,
243                           dnaUrban, false);
244   }
245   // list of main standard particles
246   const std::vector<G4int> chargedParticles = {
247     13, -13, 211, -211, 321, -321, -2212,
248     1000010020, 1000010030, 1000020030
249   };
250   auto msc = new G4hMultipleScattering();
251   msc->SetEmModel(new G4WentzelVIModel()); 
252   G4EmBuilder::ConstructBasicEmPhysics(msc, chargedParticles);
253 }
254 
255 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
256 
257 void G4EmDNABuilder::StandardHadronPhysics(G4ParticleDefinition* part,
258              const G4double lowELimitForMSC,
259              const G4double lowELimitForIoni,
260              const G4double maxEnergy,
261              const G4EmDNAMscModelType mscType,
262              const G4bool isIon)
263 {
264   G4PhysicsListHelper* ph = G4PhysicsListHelper::GetPhysicsListHelper();
265   G4hMultipleScattering* msc = new G4hMultipleScattering();
266   G4VMscModel* msc_model = nullptr;
267   if(mscType == dnaWVI) {
268     msc_model = new G4LowEWentzelVIModel();
269   } else {
270     msc_model = new G4UrbanMscModel();
271   }
272   msc_model->SetActivationLowEnergyLimit(lowELimitForMSC);
273   msc_model->SetLowEnergyLimit(lowELimitForMSC);
274   msc_model->SetHighEnergyLimit(maxEnergy);
275   msc->SetEmModel(msc_model);
276   ph->RegisterProcess(msc, part);
277 
278   G4VEnergyLossProcess* ioni = nullptr;
279   G4VEmModel* mod1 = nullptr;
280   if(isIon) {
281     ioni = new G4ionIonisation();
282     mod1 = new G4BraggIonModel();
283   } else {
284     ioni = new G4hIonisation();
285     mod1 = new G4BraggModel();
286   }
287   G4double eth = lowEnergyProtonIoni*part->GetPDGMass()/CLHEP::proton_mass_c2;
288   mod1->SetActivationLowEnergyLimit(lowELimitForIoni);
289   mod1->SetHighEnergyLimit(eth);
290   ioni->SetEmModel(mod1);
291 
292   G4VEmModel* mod2 = new G4BetheBlochModel();
293   mod2->SetActivationLowEnergyLimit(lowELimitForIoni);
294   mod2->SetLowEnergyLimit(eth);
295   ioni->SetEmModel(mod2);
296  
297   ph->RegisterProcess(ioni, part);
298 }
299 
300 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
301 
302 void 
303 G4EmDNABuilder::ConstructDNAElectronPhysics(const G4double emaxDNA,
304                                             const G4int opt,
305                                             const G4bool fast,
306                                             const G4bool stationary,
307                                             const G4Region* reg)
308 {
309   G4ParticleDefinition* part = G4Electron::Electron();
310 
311   // limit of the Emfietzoglou models
312   G4double emaxE = 0.0;
313   // limit of the elastic and solvation models
314   G4double emaxT = 7.4*CLHEP::eV;
315   // limit for CPA100 models
316   G4double emaxCPA100 = 250*CLHEP::keV;
317   if(4 == opt) {
318     emaxE = 10.*CLHEP::keV;
319     emaxT = 10.*CLHEP::eV;
320   } else if(5 < opt) {
321     emaxT = 11.*CLHEP::eV;
322   }
323 
324   // *** Solvation ***
325   G4DNAElectronSolvation* pSolvation = FindOrBuildElectronSolvation();
326   auto therm = G4DNASolvationModelFactory::GetMacroDefinedModel();
327   therm->SetHighEnergyLimit(emaxT);
328   pSolvation->AddEmModel(-1, therm, reg);
329  
330   // *** Elastic scattering ***
331   auto pElasticProcess = FindOrBuildElastic(part, "e-_G4DNAElastic");
332   G4VEmModel* elast = nullptr;
333   G4VEmModel* elast2 = nullptr;
334   if(4 == opt) {
335     elast = new G4DNAUeharaScreenedRutherfordElasticModel();
336   } else if(5 < opt) {
337     auto mod = new G4DNACPA100ElasticModel();
338     mod->SelectStationary(stationary);
339     elast = mod;
340     elast2 = new G4DNAChampionElasticModel();
341   } else {
342     elast = new G4DNAChampionElasticModel();
343   }
344   elast->SetHighEnergyLimit(lowEnergyMSC);
345   pElasticProcess->AddEmModel(-2, elast, reg);
346 
347   if(nullptr != elast2) {
348     elast->SetHighEnergyLimit(emaxCPA100);
349     elast2->SetLowEnergyLimit(emaxCPA100);
350     elast2->SetHighEnergyLimit(lowEnergyMSC);
351     pElasticProcess->AddEmModel(-3, elast2, reg);
352   }
353 
354   // *** Excitation ***
355   auto theDNAExc = FindOrBuildExcitation(part, "e-_G4DNAExcitation");
356   if(emaxE > 0.0) {
357     auto modE = new G4DNAEmfietzoglouExcitationModel();
358     theDNAExc->AddEmModel(-1, modE, reg);
359     modE->SelectStationary(stationary);
360     modE->SetHighEnergyLimit(emaxE);
361   }
362   G4VEmModel* modB = nullptr;
363   G4VEmModel* modB2 = nullptr;
364   if(6 == opt) {
365     auto mod = new G4DNACPA100ExcitationModel();
366     mod->SelectStationary(stationary);
367     modB = mod;
368     auto mod1 = new G4DNABornExcitationModel();
369     mod1->SelectStationary(stationary);
370     modB2 = mod1;
371   } else {
372     auto mod = new G4DNABornExcitationModel();
373     mod->SelectStationary(stationary);
374     modB = mod;
375   }
376   modB->SetLowEnergyLimit(emaxE);
377   modB->SetHighEnergyLimit(emaxDNA);
378   theDNAExc->AddEmModel(-2, modB, reg);
379   if(nullptr != modB2) {
380     modB->SetHighEnergyLimit(emaxCPA100);
381     modB2->SetLowEnergyLimit(emaxCPA100);
382     modB2->SetHighEnergyLimit(emaxDNA);
383     theDNAExc->AddEmModel(-3, modB2, reg);
384   }
385 
386   // *** Ionisation ***
387   auto theDNAIoni = FindOrBuildIonisation(part, "e-_G4DNAIonisation");
388   if(emaxE > 0.0) {
389     auto modE = new G4DNAEmfietzoglouIonisationModel();
390     theDNAIoni->AddEmModel(-1, modE, reg);
391     modE->SelectFasterComputation(fast);
392     modE->SelectStationary(stationary);
393     modE->SetHighEnergyLimit(emaxE);
394   }
395   G4VEmModel* modI = nullptr;
396   G4VEmModel* modI2 = nullptr;
397   if(6 == opt) {
398     auto mod = new G4DNACPA100IonisationModel();
399     mod->SelectStationary(stationary);
400     mod->SelectFasterComputation(fast);
401     modI = mod;
402     auto mod1 = new G4DNABornIonisationModel();
403     mod1->SelectStationary(stationary);
404     modI2 = mod1;
405   } else {
406     auto mod = new G4DNABornIonisationModel1();
407     mod->SelectStationary(stationary);
408     mod->SelectFasterComputation(fast);
409     modI = mod;
410   }
411   modI->SetLowEnergyLimit(emaxE);
412   modI->SetHighEnergyLimit(emaxDNA);
413   theDNAIoni->AddEmModel(-2, modI, reg);  
414   if(nullptr != modI2) {
415     modI->SetHighEnergyLimit(emaxCPA100);
416     modI2->SetLowEnergyLimit(emaxCPA100);
417     modI2->SetHighEnergyLimit(emaxDNA);
418     theDNAIoni->AddEmModel(-3, modI2, reg);
419   }
420 
421   if(4 != opt && 6 != opt) {
422     // *** Vibrational excitation ***
423     auto theDNAVibExc = FindOrBuildVibExcitation(part, "e-_G4DNAVibExcitation");
424     auto modS = new G4DNASancheExcitationModel();
425     theDNAVibExc->AddEmModel(-1, modS, reg);
426     modS->SelectStationary(stationary);
427       
428     // *** Attachment ***
429     auto theDNAAttach = FindOrBuildAttachment(part, "e-_G4DNAAttachment");
430     auto modM = new G4DNAMeltonAttachmentModel();
431     theDNAAttach->AddEmModel(-1, modM, reg);
432     modM->SelectStationary(stationary);
433   }
434 }
435 
436 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
437 
438 void 
439 G4EmDNABuilder::ConstructDNAProtonPhysics(const G4double e1DNA,
440             const G4double emaxIonDNA,
441                                           const G4int opt,
442                                           const G4bool fast,
443                                           const G4bool stationary,
444                                           const G4Region* reg)
445 {
446   G4EmParameters* param = G4EmParameters::Instance();
447   const G4double emax = param->MaxKinEnergy();
448   G4ParticleDefinition* part = G4Proton::Proton();
449 
450   // *** Elastic scattering ***
451   auto pElasticProcess = FindOrBuildElastic(part, "proton_G4DNAElastic");
452   auto modE = new G4DNAIonElasticModel();
453   modE->SetHighEnergyLimit(lowEnergyMSC);
454   modE->SelectStationary(stationary);
455   pElasticProcess->AddEmModel(-1, modE, reg);
456 
457   // *** Excitation ***
458   G4double e2DNA = std::min(e1DNA, lowEnergyRPWBA);
459   auto theDNAExc = FindOrBuildExcitation(part, "proton_G4DNAExcitation");
460   auto modMGE = new G4DNAMillerGreenExcitationModel();
461   modMGE->SetHighEnergyLimit(e2DNA);
462   modMGE->SelectStationary(stationary);
463   theDNAExc->AddEmModel(-1, modMGE, reg);
464 
465   if(e2DNA < lowEnergyRPWBA) {
466     auto modB = new G4DNABornExcitationModel();
467     modB->SelectStationary(stationary);
468     modB->SetLowEnergyLimit(e2DNA);
469     modB->SetHighEnergyLimit(lowEnergyRPWBA);
470     theDNAExc->AddEmModel(-2, modB, reg);
471   }
472   if(lowEnergyRPWBA < emaxIonDNA) {
473     auto modC = new G4DNARPWBAExcitationModel();
474     modC->SelectStationary(stationary);
475     modC->SetLowEnergyLimit(lowEnergyRPWBA);
476     modC->SetHighEnergyLimit(emaxIonDNA);
477     theDNAExc->AddEmModel(-3, modC, reg);
478   }
479 
480   // *** Ionisation ***
481   auto theDNAIoni = FindOrBuildIonisation(part, "proton_G4DNAIonisation");
482   G4VEmModel* modRI = nullptr;
483   if(2 == opt) {
484     auto mod = new G4DNARuddIonisationExtendedModel();
485     mod->SelectStationary(stationary);
486     modRI = mod;
487   } else {
488     auto mod = new G4DNARuddIonisationModel();
489     mod->SelectStationary(stationary);
490     modRI = mod;
491   }
492   modRI->SetHighEnergyLimit(e1DNA);
493   theDNAIoni->AddEmModel(-1, modRI, reg);
494 
495   if(e2DNA < lowEnergyRPWBA) {
496     auto modI = new G4DNABornIonisationModel1();
497     modI->SelectFasterComputation(fast);
498     modI->SelectStationary(stationary);
499     modI->SetLowEnergyLimit(e2DNA);
500     modI->SetHighEnergyLimit(lowEnergyRPWBA);
501     theDNAIoni->AddEmModel(-2, modI, reg);
502   }
503   if(lowEnergyRPWBA < emaxIonDNA) {
504     auto modJ = new G4DNARPWBAIonisationModel();
505     modJ->SelectFasterComputation(fast);
506     modJ->SelectStationary(stationary);
507     modJ->SetLowEnergyLimit(lowEnergyRPWBA);
508     modJ->SetHighEnergyLimit(emaxIonDNA);
509     theDNAIoni->AddEmModel(-3, modJ, reg);
510   }
511 
512   // *** Charge decrease ***
513   auto theDNAChargeDecreaseProcess = 
514     FindOrBuildChargeDecrease(part, "proton_G4DNAChargeDecrease");
515   auto modDCD = new G4DNADingfelderChargeDecreaseModel();
516   modDCD->SelectStationary(stationary);
517   modDCD->SetLowEnergyLimit(0.0);
518   modDCD->SetHighEnergyLimit(emax);
519   theDNAChargeDecreaseProcess->AddEmModel(-1, modDCD, reg);
520 
521   FindOrBuildCapture(0.1*CLHEP::keV, part);
522 }
523 
524 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
525 
526 void 
527 G4EmDNABuilder::ConstructDNAIonPhysics(const G4double emaxIonDNA,
528                                        const G4bool stationary,
529                                        const G4Region* reg)
530 {
531   G4ParticleDefinition* part = G4GenericIon::GenericIon();
532 
533   // *** Ionisation ***
534   auto theDNAIoni = FindOrBuildIonisation(part, "GenericIon_G4DNAIonisation");
535   auto mod = new G4DNARuddIonisationExtendedModel();
536   mod->SelectStationary(stationary);
537   mod->SetHighEnergyLimit(emaxIonDNA);
538   theDNAIoni->AddEmModel(-1, mod, reg);
539 
540   // *** NIEL ***
541   FindOrBuildNuclearStopping(part, CLHEP::MeV);
542 
543   // *** Tracking cut ***
544   FindOrBuildCapture(1*CLHEP::keV, part);
545 }
546 
547 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
548 
549 void
550 G4EmDNABuilder::ConstructDNALightIonPhysics(G4ParticleDefinition* part,
551                                             const G4int charge,
552                                             const G4int opt,
553                                             const G4double emaxIonDNA,
554               const G4bool,
555                                             const G4bool stationary,
556                                             const G4Region* reg)
557 {
558   G4EmParameters* param = G4EmParameters::Instance();
559   const G4double emax = param->MaxKinEnergy();
560   const G4String& name = part->GetParticleName();
561 
562   // *** Elastic ***
563   auto theDNAElastic = FindOrBuildElastic(part, name + "_G4DNAElastic");
564   auto modEI = new G4DNAIonElasticModel();
565   modEI->SelectStationary(stationary);
566   modEI->SetHighEnergyLimit(lowEnergyMSC);
567   theDNAElastic->AddEmModel(-1, modEI, reg);
568 
569   // *** Excitation ***
570   auto theDNAExc = FindOrBuildExcitation(part, name + "_G4DNAExcitation");
571   auto modMGE = new G4DNAMillerGreenExcitationModel();
572   modMGE->SelectStationary(stationary);
573   modMGE->SetLowEnergyLimit(0.0);
574   modMGE->SetHighEnergyLimit(emaxIonDNA);
575   theDNAExc->AddEmModel(-1, modMGE, reg);
576 
577   // *** Ionisation ***
578   auto theDNAIoni = FindOrBuildIonisation(part, name + "_G4DNAIonisation");
579   G4VEmModel* modRI = nullptr;
580   if(2 == opt) {
581     auto mod = new G4DNARuddIonisationExtendedModel();
582     mod->SelectStationary(stationary);
583     modRI = mod;
584   } else {
585     auto mod = new G4DNARuddIonisationModel();
586     mod->SelectStationary(stationary);
587     modRI = mod;
588   }
589   modRI->SetHighEnergyLimit(emaxIonDNA);
590   theDNAIoni->AddEmModel(-1, modRI, reg);
591 
592   // *** Charge increase ***
593   if(2 > charge) {
594     auto theDNAChargeIncrease = 
595       FindOrBuildChargeIncrease(part, name + "_G4DNAChargeIncrease");
596     auto modDCI = new G4DNADingfelderChargeIncreaseModel();
597     modDCI->SelectStationary(stationary);
598     modDCI->SetLowEnergyLimit(0.0);
599     modDCI->SetHighEnergyLimit(emax);
600     theDNAChargeIncrease->AddEmModel(-1, modDCI, reg);
601   }
602 
603   // *** Charge decrease ***
604   if(0 < charge) {
605     auto theDNAChargeDecrease = 
606       FindOrBuildChargeDecrease(part, name + "_G4DNAChargeDecrease");
607     auto modDCD = new G4DNADingfelderChargeDecreaseModel();
608     modDCD->SelectStationary(stationary);
609     modDCD->SetLowEnergyLimit(0.0);
610     modDCD->SetHighEnergyLimit(emax);
611     theDNAChargeDecrease->AddEmModel(-1, modDCD, reg);
612   }
613 
614   // *** Tracking cut ***
615   FindOrBuildCapture(1*CLHEP::keV, part);
616 }
617 
618 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
619 
620 G4DNAElectronSolvation* G4EmDNABuilder::FindOrBuildElectronSolvation()
621 {
622   auto elec = G4Electron::Electron();
623   auto* p = G4PhysListUtil::FindProcess(elec, fLowEnergyElectronSolvation);
624   G4DNAElectronSolvation* ptr = dynamic_cast<G4DNAElectronSolvation*>(p);
625   if(nullptr == ptr) {
626     ptr = new G4DNAElectronSolvation("e-_G4DNAElectronSolvation");
627     G4PhysicsListHelper* ph = G4PhysicsListHelper::GetPhysicsListHelper();
628     ph->RegisterProcess(ptr, elec);
629     ptr->SetEmModel(new G4DummyModel());
630   }
631   return ptr;
632 }
633 
634 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
635 
636 G4DNAElastic* 
637 G4EmDNABuilder::FindOrBuildElastic(G4ParticleDefinition* part,
638                                    const G4String& name)
639 {
640   auto p = G4PhysListUtil::FindProcess(part, fLowEnergyElastic);
641   G4DNAElastic* ptr = dynamic_cast<G4DNAElastic*>(p);
642   if(nullptr == ptr) {
643     ptr = new G4DNAElastic(name);
644     G4PhysicsListHelper* ph = G4PhysicsListHelper::GetPhysicsListHelper();
645     ph->RegisterProcess(ptr, part);
646     ptr->SetEmModel(new G4DummyModel());
647   }
648   return ptr;
649 }
650 
651 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
652 
653 G4DNAExcitation* 
654 G4EmDNABuilder::FindOrBuildExcitation(G4ParticleDefinition* part,
655                                       const G4String& name)
656 {
657   auto p = G4PhysListUtil::FindProcess(part, fLowEnergyExcitation);
658   G4DNAExcitation* ptr = dynamic_cast<G4DNAExcitation*>(p);
659   if(nullptr == ptr) { 
660     ptr = new G4DNAExcitation(name);
661     G4PhysicsListHelper* ph = G4PhysicsListHelper::GetPhysicsListHelper();
662     ph->RegisterProcess(ptr, part);
663     ptr->SetEmModel(new G4DummyModel());
664   }
665   return ptr;
666 }
667 
668 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
669 
670 G4DNAVibExcitation* 
671 G4EmDNABuilder::FindOrBuildVibExcitation(G4ParticleDefinition* part,
672                                          const G4String& name)
673 {
674   auto p = G4PhysListUtil::FindProcess(part, fLowEnergyVibrationalExcitation);
675   G4DNAVibExcitation* ptr = dynamic_cast<G4DNAVibExcitation*>(p);
676   if(nullptr == ptr) { 
677     ptr = new G4DNAVibExcitation(name);
678     G4PhysicsListHelper* ph = G4PhysicsListHelper::GetPhysicsListHelper();
679     ph->RegisterProcess(ptr, part);
680     ptr->SetEmModel(new G4DummyModel());
681   }
682   return ptr;
683 }
684 
685 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
686 
687 G4DNAIonisation* 
688 G4EmDNABuilder::FindOrBuildIonisation(G4ParticleDefinition* part,
689                                       const G4String& name)
690 {
691   auto p = G4PhysListUtil::FindProcess(part, fLowEnergyIonisation);
692   G4DNAIonisation* ptr = dynamic_cast<G4DNAIonisation*>(p);
693   if(nullptr == ptr) { 
694     ptr = new G4DNAIonisation(name);
695     G4PhysicsListHelper* ph = G4PhysicsListHelper::GetPhysicsListHelper();
696     ph->RegisterProcess(ptr, part);
697     ptr->SetEmModel(new G4DummyModel());
698   }
699   return ptr;
700 }
701 
702 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
703 
704 G4DNAAttachment* 
705 G4EmDNABuilder::FindOrBuildAttachment(G4ParticleDefinition* part,
706                                       const G4String& name)
707 {
708   auto p = G4PhysListUtil::FindProcess(part, fLowEnergyAttachment);
709   G4DNAAttachment* ptr = dynamic_cast<G4DNAAttachment*>(p);
710   if(nullptr == ptr) { 
711     ptr = new G4DNAAttachment(name);
712     G4PhysicsListHelper* ph = G4PhysicsListHelper::GetPhysicsListHelper();
713     ph->RegisterProcess(ptr, part);
714     ptr->SetEmModel(new G4DummyModel());
715   }
716   return ptr;
717 }
718 
719 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
720 
721 G4DNAChargeDecrease*
722 G4EmDNABuilder::FindOrBuildChargeDecrease(G4ParticleDefinition* part,
723                                           const G4String& name)
724 {
725   auto p = G4PhysListUtil::FindProcess(part, fLowEnergyChargeDecrease);
726   G4DNAChargeDecrease* ptr = dynamic_cast<G4DNAChargeDecrease*>(p);
727   if(nullptr == ptr) { 
728     ptr = new G4DNAChargeDecrease(name);
729     G4PhysicsListHelper* ph = G4PhysicsListHelper::GetPhysicsListHelper();
730     ph->RegisterProcess(ptr, part);
731     ptr->SetEmModel(new G4DummyModel());
732   }
733   return ptr;
734 }
735 
736 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
737 
738 G4DNAChargeIncrease*
739 G4EmDNABuilder::FindOrBuildChargeIncrease(G4ParticleDefinition* part,
740                                           const G4String& name)
741 {
742   auto p = G4PhysListUtil::FindProcess(part, fLowEnergyChargeIncrease);
743   G4DNAChargeIncrease* ptr = dynamic_cast<G4DNAChargeIncrease*>(p);
744   if(nullptr == ptr) { 
745     ptr = new G4DNAChargeIncrease(name);
746     G4PhysicsListHelper* ph = G4PhysicsListHelper::GetPhysicsListHelper();
747     ph->RegisterProcess(ptr, part);
748     ptr->SetEmModel(new G4DummyModel());
749   }
750   return ptr;
751 }
752 
753 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
754 
755 G4LowECapture*
756 G4EmDNABuilder::FindOrBuildCapture(const G4double elim, G4ParticleDefinition* part)
757 {
758   auto p = G4PhysListUtil::FindProcess(part, -1);
759   G4LowECapture* ptr = dynamic_cast<G4LowECapture*>(p);
760   if (nullptr == ptr) { 
761     ptr = new G4LowECapture(elim);
762     auto mng = part->GetProcessManager();
763     mng->AddDiscreteProcess(ptr);
764   }
765   return ptr;
766 }
767 
768 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
769 
770 void G4EmDNABuilder::FindOrBuildNuclearStopping(G4ParticleDefinition* part,
771                                                 const G4double elim)
772 {
773   auto p = G4PhysListUtil::FindProcess(part, fNuclearStopping);
774   auto ptr = dynamic_cast<G4NuclearStopping*>(p);
775   if (nullptr == ptr) {
776     ptr = new G4NuclearStopping();
777   }
778   ptr->SetMaxKinEnergy(elim);
779   auto ph = G4PhysicsListHelper::GetPhysicsListHelper();
780   ph->RegisterProcess(ptr, part);
781 }
782   
783 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
784