Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4VDecayChannel.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 //
27 // $Id$
28 //
29 //
30 // ------------------------------------------------------------
31 // GEANT 4 class header file
32 //
33 // History: first implementation, based on object model of
34 // 27 July 1996 H.Kurashige
35 // 30 May 1997 H.Kurashige
36 // 23 Mar. 2000 H.Weber : add GetAngularMomentum
37 // ------------------------------------------------------------
38 
39 #include "G4ParticleDefinition.hh"
40 #include "G4SystemOfUnits.hh"
41 #include "G4ParticleTable.hh"
42 #include "G4DecayTable.hh"
43 #include "G4DecayProducts.hh"
44 #include "G4VDecayChannel.hh"
45 
47 
49  :kinematics_name(""),
50  rbranch(0.0),
51  numberOfDaughters(0),
52  parent_name(0), daughters_name(0),
53  particletable(0),
54  parent(0), daughters(0),
55  parent_mass(0.0), daughters_mass(0),
56  verboseLevel(1)
57 {
58  // set pointer to G4ParticleTable (static and singleton object)
60 }
61 
62 
64  :kinematics_name(aName),
65  rbranch(0.0),
66  numberOfDaughters(0),
67  parent_name(0), daughters_name(0),
68  particletable(0),
69  parent(0), daughters(0),
70  parent_mass(0.0), daughters_mass(0),
71  verboseLevel(Verbose)
72 {
73  // set pointer to G4ParticleTable (static and singleton object)
75 }
76 
78  const G4String& theParentName,
79  G4double theBR,
80  G4int theNumberOfDaughters,
81  const G4String& theDaughterName1,
82  const G4String& theDaughterName2,
83  const G4String& theDaughterName3,
84  const G4String& theDaughterName4 )
85  :kinematics_name(aName),
86  rbranch(theBR),
87  numberOfDaughters(theNumberOfDaughters),
88  parent_name(0), daughters_name(0),
89  particletable(0),
90  parent(0), daughters(0),
91  parent_mass(0.0), daughters_mass(0),
92  verboseLevel(1)
93 {
94  // set pointer to G4ParticleTable (static and singleton object)
96 
97  // parent name
98  parent_name = new G4String(theParentName);
99 
100  // cleate array
103 
104  // daughters' name
105  if (numberOfDaughters>0) daughters_name[0] = new G4String(theDaughterName1);
106  if (numberOfDaughters>1) daughters_name[1] = new G4String(theDaughterName2);
107  if (numberOfDaughters>2) daughters_name[2] = new G4String(theDaughterName3);
108  if (numberOfDaughters>3) daughters_name[3] = new G4String(theDaughterName4);
109 }
110 
111 
112 
114 {
116  verboseLevel = right.verboseLevel;
117  rbranch = right.rbranch;
118 
119  // copy parent name
120  parent_name = new G4String(*right.parent_name);
121  parent = 0;
122  parent_mass = 0.0;
123 
124  //create array
126 
127  daughters_name =0;
128  if ( numberOfDaughters >0 ) {
130  //copy daughters name
131  for (G4int index=0; index < numberOfDaughters; index++)
132  {
134  }
135  }
136 
137  //
138  daughters_mass = 0;
139  daughters = 0;
140 
141  // particle table
143 }
144 
146 {
147  if (this != &right) {
149  verboseLevel = right.verboseLevel;
150  rbranch = right.rbranch;
151 
152  // copy parent name
153  parent_name = new G4String(*right.parent_name);
154 
155  // clear daughters_name array
157 
158  // recreate array
160  if ( numberOfDaughters >0 ) {
163  //copy daughters name
164  for (G4int index=0; index < numberOfDaughters; index++) {
166  }
167  }
168  }
169 
170  //
171  parent = 0;
172  daughters = 0;
173  parent_mass = 0.0;
174  daughters_mass = 0;
175 
176  // particle table
178 
179  return *this;
180 }
181 
182 
184 {
186  if (parent_name != 0) delete parent_name;
187  parent_name = 0;
188  if (daughters_mass != 0) delete [] daughters_mass;
189  daughters_mass =0;
190 }
191 
193 {
194  if ( daughters_name != 0) {
195  if (numberOfDaughters>0) {
196 #ifdef G4VERBOSE
197  if (verboseLevel>1) {
198  G4cerr << "G4VDecayChannel::ClearDaughtersName "
199  << " for " << *parent_name << G4endl;
200  }
201 #endif
202  for (G4int index=0; index < numberOfDaughters; index++) {
203  if (daughters_name[index] != 0) delete daughters_name[index];
204  }
205  }
206  delete [] daughters_name;
207  daughters_name = 0;
208  }
209  //
210  if (daughters != 0) delete [] daughters;
211  if (daughters_mass != 0) delete [] daughters_mass;
212  daughters = 0;
213  daughters_mass = 0;
214 
215  numberOfDaughters = 0;
216 }
217 
219 {
220  if (size >0) {
221  // remove old contents
223  // cleate array
224  daughters_name = new G4String*[size];
225  for (G4int index=0;index<size;index++) daughters_name[index]=0;
226  numberOfDaughters = size;
227  }
228 }
229 
231  const G4String &particle_name)
232 {
233  // check numberOfDaughters is positive
234  if (numberOfDaughters<=0) {
235 #ifdef G4VERBOSE
236  if (verboseLevel>0) {
237  G4cerr << "G4VDecayChannel::SetDaughter: "
238  << "Number of daughters is not defined" << G4endl;
239  }
240 #endif
241  return;
242  }
243 
244  // check existence of daughters_name array
245  if (daughters_name == 0) {
246  // cleate array
250  }
251  }
252 
253  // check an index
254  if ( (anIndex<0) || (anIndex>=numberOfDaughters) ) {
255 #ifdef G4VERBOSE
256  if (verboseLevel>0) {
257  G4cerr << "G4VDecayChannel::SetDaughter"
258  << "index out of range " << anIndex << G4endl;
259  }
260 #endif
261  } else {
262  // delete the old name if it exists
263  if (daughters_name[anIndex]!=0) delete daughters_name[anIndex];
264  // fill the name
265  daughters_name[anIndex] = new G4String(particle_name);
266  // refill the array of daughters[] if it exists
267  if (daughters != 0) FillDaughters();
268 #ifdef G4VERBOSE
269  if (verboseLevel>1) {
270  G4cout << "G4VDecayChannel::SetDaughter[" << anIndex <<"] :";
271  G4cout << daughters_name[anIndex] << ":" << *daughters_name[anIndex]<<G4endl;
272  }
273 #endif
274  }
275 }
276 
277 void G4VDecayChannel::SetDaughter(G4int anIndex, const G4ParticleDefinition * parent_type)
278 {
279  if (parent_type != 0) SetDaughter(anIndex, parent_type->GetParticleName());
280 }
281 
283 {
284  G4int index;
285 
286 #ifdef G4VERBOSE
287  if (verboseLevel>1) G4cout << "G4VDecayChannel::FillDaughters()" <<G4endl;
288 #endif
289  if (daughters != 0) {
290  delete [] daughters;
291  daughters = 0;
292  }
293 
294  // parent mass
295  if (parent == 0) FillParent();
296  G4double parentmass = parent->GetPDGMass();
297 
298  //
299  G4double sumofdaughtermass = 0.0;
300  if ((numberOfDaughters <=0) || (daughters_name == 0) ){
301 #ifdef G4VERBOSE
302  if (verboseLevel>0) {
303  G4cerr << "G4VDecayChannel::FillDaughters "
304  << "[ " << parent->GetParticleName() << " ]"
305  << "numberOfDaughters is not defined yet";
306  }
307 #endif
308  daughters = 0;
309  G4Exception("G4VDecayChannel::FillDaughters",
310  "PART011", FatalException,
311  "Can not fill daughters: numberOfDaughters is not defined yet");
312  }
313 
314  //create and set the array of pointers to daughter particles
316  if (daughters_mass != 0) delete [] daughters_mass;
318  // loop over all daughters
319  for (index=0; index < numberOfDaughters; index++) {
320  if (daughters_name[index] == 0) {
321  // daughter name is not defined
322 #ifdef G4VERBOSE
323  if (verboseLevel>0) {
324  G4cerr << "G4VDecayChannel::FillDaughters "
325  << "[ " << parent->GetParticleName() << " ]"
326  << index << "-th daughter is not defined yet" << G4endl;
327  }
328 #endif
329  daughters[index] = 0;
330  G4Exception("G4VDecayChannel::FillDaughters",
331  "PART011", FatalException,
332  "Can not fill daughters: name of a daughter is not defined yet");
333  }
334  //search daughter particles in the particle table
336  if (daughters[index] == 0) {
337  // can not find the daughter particle
338 #ifdef G4VERBOSE
339  if (verboseLevel>0) {
340  G4cerr << "G4VDecayChannel::FillDaughters "
341  << "[ " << parent->GetParticleName() << " ]"
342  << index << ":" << *daughters_name[index]
343  << " is not defined !!" << G4endl;
344  G4cerr << " The BR of this decay mode is set to zero " << G4endl;
345  }
346 #endif
347  SetBR(0.0);
348  return;
349  }
350 #ifdef G4VERBOSE
351  if (verboseLevel>1) {
352  G4cout << index << ":" << *daughters_name[index];
353  G4cout << ":" << daughters[index] << G4endl;
354  }
355 #endif
357  sumofdaughtermass += daughters[index]->GetPDGMass();
358  } // end loop over all daughters
359 
360  // check sum of daghter mass
361  G4double widthMass = parent->GetPDGWidth();
362  if ( (parent->GetParticleType() != "nucleus") &&
363  (sumofdaughtermass > parentmass + 5*widthMass) ){
364  // !!! illegal mass !!!
365 #ifdef G4VERBOSE
366  if (GetVerboseLevel()>0) {
367  G4cerr << "G4VDecayChannel::FillDaughters "
368  << "[ " << parent->GetParticleName() << " ]"
369  << " Energy/Momentum conserevation breaks " <<G4endl;
370  if (GetVerboseLevel()>1) {
371  G4cerr << " parent:" << *parent_name
372  << " mass:" << parentmass/GeV << "[GeV/c/c]" <<G4endl;
373  for (index=0; index < numberOfDaughters; index++){
374  G4cerr << " daughter " << index << ":" << *daughters_name[index]
375  << " mass:" << daughters[index]->GetPDGMass()/GeV
376  << "[GeV/c/c]" <<G4endl;
377  }
378  }
379  }
380 #endif
381  }
382 }
383 
384 
386 {
387  if (parent_name == 0) {
388  // parent name is not defined
389 #ifdef G4VERBOSE
390  if (verboseLevel>0) {
391  G4cerr << "G4VDecayChannel::FillParent "
392  << ": parent name is not defined !!" << G4endl;
393  }
394 #endif
395  parent = 0;
396  G4Exception("G4VDecayChannel::FillParent()",
397  "PART012", FatalException,
398  "Can not fill parent: parent name is not defined yet");
399  }
400  // search parent particle in the particle table
402  if (parent == 0) {
403  // parent particle does not exist
404 #ifdef G4VERBOSE
405  if (verboseLevel>0) {
406  G4cerr << "G4VDecayChannel::FillParent "
407  << *parent_name << " does not exist !!" << G4endl;
408  }
409 #endif
410  G4Exception("G4VDecayChannel::FillParent()",
411  "PART012", FatalException,
412  "Can not fill parent: parent does not exist");
413  }
415 }
416 
418 {
419  if (parent_type != 0) SetParent(parent_type->GetParticleName());
420 }
421 
423 {
424  // determine angular momentum
425 
426  // fill pointers to daughter particles if not yet set
427  if (daughters == 0) FillDaughters();
428 
429  const G4int PiSpin = parent->GetPDGiSpin();
430  const G4int PParity = parent->GetPDGiParity();
431  if (2==numberOfDaughters) { // up to now we can only handle two particle decays
432  const G4int D1iSpin = daughters[0]->GetPDGiSpin();
433  const G4int D1Parity = daughters[0]->GetPDGiParity();
434  const G4int D2iSpin = daughters[1]->GetPDGiSpin();
435  const G4int D2Parity = daughters[1]->GetPDGiParity();
436  const G4int MiniSpin = std::abs (D1iSpin - D2iSpin);
437  const G4int MaxiSpin = D1iSpin + D2iSpin;
438  const G4int lMax = (PiSpin+D1iSpin+D2iSpin)/2; // l is allways int
439  G4int lMin;
440 #ifdef G4VERBOSE
441  if (verboseLevel>1) {
442  G4cout << "iSpin: " << PiSpin << " -> " << D1iSpin << " + " << D2iSpin << G4endl;
443  G4cout << "2*jmin, 2*jmax, lmax " << MiniSpin << " " << MaxiSpin << " " << lMax << G4endl;
444  }
445 #endif
446  for (G4int j=MiniSpin; j<=MaxiSpin; j+=2){ // loop over all possible spin couplings
447  lMin = std::abs(PiSpin-j)/2;
448 #ifdef G4VERBOSE
449  if (verboseLevel>1)
450  G4cout << "-> checking 2*j=" << j << G4endl;
451 #endif
452  for (G4int l=lMin; l<=lMax; l++) {
453 #ifdef G4VERBOSE
454  if (verboseLevel>1)
455  G4cout << " checking l=" << l << G4endl;
456 #endif
457  if (l%2==0) {
458  if (PParity == D1Parity*D2Parity) { // check parity for this l
459  return l;
460  }
461  } else {
462  if (PParity == -1*D1Parity*D2Parity) { // check parity for this l
463  return l;
464  }
465  }
466  }
467  }
468  } else {
469  G4Exception("G4VDecayChannel::GetAngularMomentum",
470  "PART111", JustWarning,
471  "Sorry, can't handle 3 particle decays (up to now)");
472  return 0;
473  }
474  G4Exception ("G4VDecayChannel::GetAngularMomentum",
475  "PART111", JustWarning,
476  "Can't find angular momentum for this decay");
477  return 0;
478 }
479 
481 {
482  G4cout << " BR: " << rbranch << " [" << kinematics_name << "]";
483  G4cout << " : " ;
484  for (G4int index=0; index < numberOfDaughters; index++)
485  {
486  if(daughters_name[index] != 0) {
487  G4cout << " " << *(daughters_name[index]);
488  } else {
489  G4cout << " not defined ";
490  }
491  }
492  G4cout << G4endl;
493 }
494 
495 const G4String& G4VDecayChannel::GetNoName() const
496 {
497  return noName;
498 }