57{
58
59
60
61
62
63
70 G4bool veryForward =
false;
71
78 G4double centerofmassEnergy = std::sqrt(mOriginal*mOriginal +
79 targetMass*targetMass +
80 2.0*targetMass*etOriginal);
82 targetMass = targetParticle.
GetMass()/GeV;
83
84 if (currentMass == 0.0 && targetMass == 0.0) {
87 currentParticle = *vec[0];
88 targetParticle = *vec[1];
89 for (i = 0; i < (vecLen-2); ++i) *vec[i] = *vec[i+2];
90 if (vecLen < 2) {
91 for (
G4int j = 0; j < vecLen; j++)
delete vec[j];
92 vecLen = 0;
94 "G4RPGTwoCluster::ReactionStage : Negative number of particles");
95 }
96 delete vec[vecLen-1];
97 delete vec[vecLen-2];
98 vecLen -= 2;
99 currentMass = currentParticle.
GetMass()/GeV;
100 targetMass = targetParticle.
GetMass()/GeV;
101 incidentHasChanged = true;
102 targetHasChanged = true;
105 veryForward = true;
106 }
107
110
111
112
113
114
115
116 G4int forwardCount = 1;
120
121
122 G4int backwardCount = 1;
126
127
128 for (i = 0; i < vecLen; ++i) {
129 if (vec[i]->GetSide() < 0) vec[i]->SetSide(-1);
130
131
132 if (vec[i]->GetSide() == -1) {
133 ++backwardCount;
134 backwardMass += vec[i]->GetMass()/GeV;
135 } else {
136 ++forwardCount;
137 forwardMass += vec[i]->GetMass()/GeV;
138 }
139 }
140
141
142 G4double term1 =
G4Log(centerofmassEnergy*centerofmassEnergy);
143 if(term1 < 0) term1 = 0.0001;
148 xtarg = afc * (a13-1.0) * (2*backwardCount+vecLen+2)/2.0;
149 else
150 xtarg = afc * (a13-1.0) * (2*backwardCount);
151
152 if( xtarg <= 0.0 )xtarg = 0.01;
154
155 if(atomicWeight<1.0001) nuclearExcitationCount = 0;
156
157
158
159 if( nuclearExcitationCount > 0 )
160 {
161 G4int momentumBin = std::min( 4,
G4int(pOriginal/3.0) );
162 const G4double nucsup[] = { 1.0, 0.8, 0.6, 0.5, 0.4 };
163
164
165
166
167 for( i=0; i<nuclearExcitationCount; ++i )
168 {
171 {
174 else
176
177
178
179 }
180 else
181 {
183 if( ran < 0.3181 )
185 else if( ran < 0.6819 )
187 else
189
190
191
192
193 }
195
198 }
199 }
200
201
202
203
204
205 G4double forwardEnergy = (centerofmassEnergy-cMass-bMass)/2.0 +cMass - forwardMass;
206 G4double backwardEnergy = (centerofmassEnergy-cMass-bMass)/2.0 +bMass - backwardMass;
207 G4double eAvailable = centerofmassEnergy - (forwardMass+backwardMass);
210
213 ed <<
" While count exceeded " <<
G4endl;
214
215 while( eAvailable <= 0.0 ) {
216 loop++;
217 if (loop > 1000) {
219 break;
220 }
221
222 secondaryDeleted = false;
223 for( i=(vecLen-1); i>=0; --i )
224 {
225 if( vec[i]->GetSide() == 1 && vec[i]->GetMayBeKilled())
226 {
227 pMass = vec[i]->GetMass()/GeV;
228 for(
G4int j=i; j<(vecLen-1); ++j )*vec[j] = *vec[j+1];
229 --forwardCount;
230 forwardEnergy += pMass;
231 forwardMass -= pMass;
232 secondaryDeleted = true;
233 break;
234 }
235 else if( vec[i]->GetSide() == -1 && vec[i]->GetMayBeKilled())
236 {
237 pMass = vec[i]->GetMass()/GeV;
238 for(
G4int j=i; j<(vecLen-1); ++j )*vec[j] = *vec[j+1];
239 --backwardCount;
240 backwardEnergy += pMass;
241 backwardMass -= pMass;
242 secondaryDeleted = true;
243 break;
244 }
245 }
246
247 if( secondaryDeleted )
248 {
249 delete vec[vecLen-1];
250 --vecLen;
251
252 }
253 else
254 {
255 if( vecLen == 0 ) return false;
256 if( targetParticle.
GetSide() == -1 )
257 {
258 pMass = targetParticle.
GetMass()/GeV;
259 targetParticle = *vec[0];
260 for(
G4int j=0; j<(vecLen-1); ++j )*vec[j] = *vec[j+1];
261 --backwardCount;
262 backwardEnergy += pMass;
263 backwardMass -= pMass;
264 secondaryDeleted = true;
265 }
266 else if( targetParticle.
GetSide() == 1 )
267 {
268 pMass = targetParticle.
GetMass()/GeV;
269 targetParticle = *vec[0];
270 for(
G4int j=0; j<(vecLen-1); ++j )*vec[j] = *vec[j+1];
271 --forwardCount;
272 forwardEnergy += pMass;
273 forwardMass -= pMass;
274 secondaryDeleted = true;
275 }
276
277 if( secondaryDeleted )
278 {
279 delete vec[vecLen-1];
280 --vecLen;
281 }
282 else
283 {
284 if( currentParticle.
GetSide() == -1 )
285 {
286 pMass = currentParticle.
GetMass()/GeV;
287 currentParticle = *vec[0];
288 for(
G4int j=0; j<(vecLen-1); ++j )*vec[j] = *vec[j+1];
289 --backwardCount;
290 backwardEnergy += pMass;
291 backwardMass -= pMass;
292 secondaryDeleted = true;
293 }
294 else if( currentParticle.
GetSide() == 1 )
295 {
296 pMass = currentParticle.
GetMass()/GeV;
297 currentParticle = *vec[0];
298 for(
G4int j=0; j<(vecLen-1); ++j )*vec[j] = *vec[j+1];
299 --forwardCount;
300 forwardEnergy += pMass;
301 forwardMass -= pMass;
302 secondaryDeleted = true;
303 }
304 if( secondaryDeleted )
305 {
306 delete vec[vecLen-1];
307 --vecLen;
308 }
309 else break;
310
311 }
312 }
313
314 eAvailable = centerofmassEnergy - (forwardMass+backwardMass);
315 }
316
317
318
319
320
321
322
323
324
325
326 const G4double cpar[] = { 1.60, 1.35, 1.15, 1.10 };
327 const G4double gpar[] = { 2.60, 1.80, 1.30, 1.20 };
329
330 if (forwardCount < 1 || backwardCount < 1) return false;
331
333 if (forwardCount > 1) {
334 ntc = std::min(3,forwardCount-2);
336 }
338 if( backwardCount > 1 ) {
339 ntc = std::min(3,backwardCount-2);
341 }
342
343 loop = 0;
345 eda <<
" While count exceeded " <<
G4endl;
346 while( rmc+rmd > centerofmassEnergy ) {
347 loop++;
348 if (loop > 1000) {
350 break;
351 }
352
353 if( (rmc <= forwardMass) && (rmd <= backwardMass) )
354 {
355 G4double temp = 0.999*centerofmassEnergy/(rmc+rmd);
356 rmc *= temp;
357 rmd *= temp;
358 }
359 else
360 {
361 rmc = 0.1*forwardMass + 0.9*rmc;
362 rmd = 0.1*backwardMass + 0.9*rmd;
363 }
364 }
365
367 for( i=0; i<8; ++i )pseudoParticle[i].SetZero();
368
369 pseudoParticle[1].
SetMass( mOriginal*GeV );
371 pseudoParticle[1].
SetMomentum( 0.0, 0.0, pOriginal*GeV );
372
373 pseudoParticle[2].
SetMass( protonMass*MeV );
376
377
378
379 pseudoParticle[0] = pseudoParticle[1] + pseudoParticle[2];
380 pseudoParticle[1].
Lorentz( pseudoParticle[1], pseudoParticle[0] );
381 pseudoParticle[2].Lorentz( pseudoParticle[2], pseudoParticle[0] );
382
383
384
385
386
388 G4double pf = (centerofmassEnergy*centerofmassEnergy+rmd*rmd-rmc*rmc);
389 pf *= pf;
390 pf -= 4*centerofmassEnergy*centerofmassEnergy*rmd*rmd;
391 pf = std::sqrt( std::max(pf,pfMin) )/(2.0*centerofmassEnergy);
392
393
394
395 pseudoParticle[3].SetMass( rmc*GeV );
396 pseudoParticle[3].SetTotalEnergy( std::sqrt(pf*pf+rmc*rmc)*GeV );
397
398 pseudoParticle[4].SetMass( rmd*GeV );
399 pseudoParticle[4].SetTotalEnergy( std::sqrt(pf*pf+rmd*rmd)*GeV );
400
401
402
403
407 G4double pin = pseudoParticle[1].GetMomentum().mag()/GeV;
408 G4double dtb = 4.0*pin*pf*std::max( bMin, b1+b2*
G4Log(pOriginal) );
411
412 costheta = std::max(-1.0, std::min(1.0, costheta));
413 G4double sintheta = std::sqrt((1.0-costheta)*(1.0+costheta));
415
416
417
418 pseudoParticle[3].SetMomentum( pf*sintheta*std::cos(phi)*GeV,
419 pf*sintheta*std::sin(phi)*GeV,
420 pf*costheta*GeV );
421 pseudoParticle[4].SetMomentum( -pseudoParticle[3].GetMomentum());
422
423
424
425
427 if( nuclearExcitationCount > 0 )
428 {
432 if( ekOriginal <= 5.0 )
433 {
434 ekit1 *= ekOriginal*ekOriginal/25.0;
435 ekit2 *= ekOriginal*ekOriginal/25.0;
436 }
437 G4double scale = std::pow(ekit2/ekit1, 1.0-ga) - 1.0;
438 for( i=0; i<vecLen; ++i )
439 {
440 if( vec[i]->GetSide() == -2 )
441 {
443 vec[i]->SetKineticEnergy( kineticE*GeV );
444 G4double vMass = vec[i]->GetMass()/MeV;
445 G4double totalE = kineticE*GeV + vMass;
446 pp = std::sqrt( std::abs(totalE*totalE-vMass*vMass) );
448 G4double sint = std::sqrt(1.0-cost*cost);
450 vec[i]->SetMomentum( pp*sint*std::cos(phi)*MeV,
451 pp*sint*std::sin(phi)*MeV,
452 pp*cost*MeV );
453 vec[i]->Lorentz( *vec[i], pseudoParticle[0] );
454 }
455 }
456 }
457
458
459
460
461
462 currentParticle.
SetMomentum( pseudoParticle[3].GetMomentum() );
463 currentParticle.
SetTotalEnergy( pseudoParticle[3].GetTotalEnergy() );
464
465 targetParticle.
SetMomentum( pseudoParticle[4].GetMomentum() );
466 targetParticle.
SetTotalEnergy( pseudoParticle[4].GetTotalEnergy() );
467
468 pseudoParticle[5].SetMomentum( pseudoParticle[3].GetMomentum() * (-1.0) );
469 pseudoParticle[5].SetMass( pseudoParticle[3].GetMass() );
470 pseudoParticle[5].SetTotalEnergy( pseudoParticle[3].GetTotalEnergy() );
471
472 pseudoParticle[6].SetMomentum( pseudoParticle[4].GetMomentum() * (-1.0) );
473 pseudoParticle[6].SetMass( pseudoParticle[4].GetMass() );
474 pseudoParticle[6].SetTotalEnergy( pseudoParticle[4].GetTotalEnergy() );
475
477
478 if( forwardCount > 1 )
479 {
482 G4bool constantCrossSection =
true;
484 if( currentParticle.
GetSide() == 1 )
485 tempV.
SetElement( tempLen++, ¤tParticle );
486 if( targetParticle.
GetSide() == 1 )
487 tempV.
SetElement( tempLen++, &targetParticle );
488 for( i=0; i<vecLen; ++i )
489 {
490 if( vec[i]->GetSide() == 1 )
491 {
492 if( tempLen < 18 )
494 else
495 {
496 vec[i]->SetSide( -1 );
497 continue;
498 }
499 }
500 }
501 if( tempLen >= 2 )
502 {
503
504
505
507 tempV, tempLen);
508
509 if( currentParticle.
GetSide() == 1 )
510 currentParticle.
Lorentz( currentParticle, pseudoParticle[5] );
511 if( targetParticle.
GetSide() == 1 )
512 targetParticle.
Lorentz( targetParticle, pseudoParticle[5] );
513 for( i=0; i<vecLen; ++i )
514 {
515 if( vec[i]->GetSide() == 1 )vec[i]->Lorentz( *vec[i], pseudoParticle[5] );
516 }
517 }
518 }
519
520 if( backwardCount > 1 )
521 {
524 G4bool constantCrossSection =
true;
526 if( currentParticle.
GetSide() == -1 )
527 tempV.
SetElement( tempLen++, ¤tParticle );
528 if( targetParticle.
GetSide() == -1 )
529 tempV.
SetElement( tempLen++, &targetParticle );
530 for( i=0; i<vecLen; ++i )
531 {
532 if( vec[i]->GetSide() == -1 )
533 {
534 if( tempLen < 18 )
536 else
537 {
538 vec[i]->SetSide( -2 );
539 vec[i]->SetKineticEnergy( 0.0 );
540 vec[i]->SetMomentum( 0.0, 0.0, 0.0 );
541 continue;
542 }
543 }
544 }
545 if( tempLen >= 2 )
546 {
548 constantCrossSection, tempV, tempLen );
549 if( currentParticle.
GetSide() == -1 )
550 currentParticle.
Lorentz( currentParticle, pseudoParticle[6] );
551 if( targetParticle.
GetSide() == -1 )
552 targetParticle.
Lorentz( targetParticle, pseudoParticle[6] );
553 for( i=0; i<vecLen; ++i )
554 {
555 if( vec[i]->GetSide() == -1 )vec[i]->Lorentz( *vec[i], pseudoParticle[6] );
556 }
557 }
558 }
559
560
561
562
563
564 currentParticle.
Lorentz( currentParticle, pseudoParticle[2] );
565 targetParticle.
Lorentz( targetParticle, pseudoParticle[2] );
566 for( i=0; i<vecLen; ++i ) vec[i]->Lorentz( *vec[i], pseudoParticle[2] );
567
568
569
570
571
573 if( leadFlag )
574 {
575
576
577
578
579
580
582 dum = false;
584 dum = false;
585 else
586 {
587 for( i=0; i<vecLen; ++i )
588 {
589 if( vec[i]->GetDefinition() == leadingStrangeParticle.
GetDefinition() )
590 {
591 dum = false;
592 break;
593 }
594 }
595 }
596 if( dum )
597 {
600 if( ((leadMass < protonMass) && (targetParticle.
GetMass()/MeV < protonMass)) ||
601 ((leadMass >= protonMass) && (targetParticle.
GetMass()/MeV >= protonMass)) )
602 {
608 if( pp1 < 1.0e-3 ) {
611 } else {
613 }
614 targetHasChanged = true;
615 }
616 else
617 {
623 if( pp1 < 1.0e-3 ) {
626 } else {
628 }
629 incidentHasChanged = true;
630 }
631 }
632 }
633
634
635
636
637 std::pair<G4int, G4int> finalStateNucleons =
639
640 G4int protonsInFinalState = finalStateNucleons.first;
641 G4int neutronsInFinalState = finalStateNucleons.second;
642
643 G4int numberofFinalStateNucleons =
644 protonsInFinalState + neutronsInFinalState;
645
650 numberofFinalStateNucleons++;
651
652 numberofFinalStateNucleons = std::max(1, numberofFinalStateNucleons);
653
654 G4int PinNucleus = std::max(0,
656 G4int NinNucleus = std::max(0,
658
659
660
661
662 pseudoParticle[4].SetMass( mOriginal*GeV );
663 pseudoParticle[4].SetTotalEnergy( etOriginal*GeV );
664 pseudoParticle[4].SetMomentum( 0.0, 0.0, pOriginal*GeV );
665
669 if(numberofFinalStateNucleons == 1) diff = 0;
670 pseudoParticle[5].SetMomentum( 0.0, 0.0, 0.0 );
671 pseudoParticle[5].SetMass( protonMass*(numberofFinalStateNucleons-diff)*MeV);
672 pseudoParticle[5].SetTotalEnergy( protonMass*(numberofFinalStateNucleons-diff)*MeV);
673
675 pseudoParticle[4].GetTotalEnergy()/GeV + pseudoParticle[5].GetTotalEnergy()/GeV;
676
677 pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5];
678 pseudoParticle[4].Lorentz( pseudoParticle[4], pseudoParticle[6] );
679 pseudoParticle[5].Lorentz( pseudoParticle[5], pseudoParticle[6] );
680
681 if( vecLen < 16 )
682 {
684 tempR[0] = currentParticle;
685 tempR[1] = targetParticle;
686 for( i=0; i<vecLen; ++i )tempR[i+2] = *vec[i];
687
690 G4bool constantCrossSection =
true;
692 for( i=0; i<vecLen+2; ++i )tempV.
SetElement( tempLen++, &tempR[i] );
693
694 if( tempLen >= 2 )
695 {
696
698 pseudoParticle[5].GetTotalEnergy()/MeV,
699 constantCrossSection, tempV, tempLen );
700 if (wgt == -1) {
702 for (i = 0; i < tempLen; i++) Qvalue += tempV[i]->GetMass();
704 constantCrossSection, tempV, tempLen );
705 }
706 theoreticalKinetic = 0.0;
707 for( i=0; i<vecLen+2; ++i )
708 {
709 pseudoParticle[7].SetMomentum( tempV[i]->GetMomentum() );
710 pseudoParticle[7].SetMass( tempV[i]->GetMass() );
711 pseudoParticle[7].SetTotalEnergy( tempV[i]->GetTotalEnergy() );
712 pseudoParticle[7].Lorentz( pseudoParticle[7], pseudoParticle[5] );
713 theoreticalKinetic += pseudoParticle[7].GetKineticEnergy()/GeV;
714 }
715 }
716
717 }
718 else
719 {
720 theoreticalKinetic -=
722 for( i=0; i<vecLen; ++i )theoreticalKinetic -= vec[i]->GetMass()/GeV;
723 }
726 for( i=0; i<vecLen; ++i )simulatedKinetic += vec[i]->GetKineticEnergy()/GeV;
727
728
729
730
731 if( simulatedKinetic != 0.0 )
732 {
733 wgt = (theoreticalKinetic)/simulatedKinetic;
737 if( pp1 < 0.001*MeV ) {
740 } else {
742 }
743
747 if( pp1 < 0.001*MeV ) {
750 } else {
752 }
753
754 for( i=0; i<vecLen; ++i )
755 {
756 vec[i]->SetKineticEnergy( wgt*vec[i]->GetKineticEnergy() );
757 pp = vec[i]->GetTotalMomentum()/MeV;
758 pp1 = vec[i]->GetMomentum().mag()/MeV;
759 if( pp1 < 0.001 ) {
761 vec[i]->SetMomentum( iso.
x(), iso.
y(), iso.
z() );
762 } else {
763 vec[i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) );
764 }
765 }
766 }
767
768
769 Rotate( numberofFinalStateNucleons, pseudoParticle[4].GetMomentum(),
770 modifiedOriginal, originalIncident, targetNucleus,
771 currentParticle, targetParticle, vec, vecLen );
772
773
774
775
776
777 if( atomicWeight >= 1.5 )
778 {
779
780
781
782
783
784
785
788
790 if (veryForward) {
793 } else {
796 }
797
800
801
802
803
804
805
806
807
808 if( epnb >= pnCutOff )
809 {
810 npnb =
G4Poisson((1.5+1.25*numberofFinalStateNucleons)*epnb/(epnb+edta));
811 if( numberofFinalStateNucleons + npnb > atomicWeight )
812 npnb =
G4int(atomicWeight - numberofFinalStateNucleons);
813 npnb = std::min( npnb, 127-vecLen );
814 }
815 if( edta >= dtaCutOff )
816 {
817 ndta =
G4Poisson( (1.5+1.25*numberofFinalStateNucleons)*edta/(epnb+edta) );
818 ndta = std::min( ndta, 127-vecLen );
819 }
820 if (npnb == 0 && ndta == 0) npnb = 1;
821
822
823
825 PinNucleus, NinNucleus, targetNucleus,
826 vec, vecLen );
827
828 }
829
830
831
832
833
834
835 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) )
837 else
838 currentParticle.
SetTOF( 1.0 );
839
840 return true;
841}
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double G4Log(G4double x)
G4long G4Poisson(G4double mean)
void SetElement(G4int anIndex, Type *anElement)
void Initialize(G4int items)
const G4ParticleDefinition * GetDefinition() const
static G4Lambda * Lambda()
static G4Neutron * Neutron()
G4double GetAnnihilationPNBlackTrackEnergy() const
G4double GetPNBlackTrackEnergy() const
G4double GetAnnihilationDTABlackTrackEnergy() const
G4double GetDTABlackTrackEnergy() const
G4double GetPDGMass() const
G4int GetBaryonNumber() const
static G4PionMinus * PionMinus()
static G4PionPlus * PionPlus()
static G4PionZero * PionZero()
static G4Pow * GetInstance()
G4double A13(G4double A) const
static G4Proton * Proton()
void Rotate(const G4double numberofFinalStateNucleons, const G4ThreeVector &temp, const G4ReactionProduct &modifiedOriginal, const G4HadProjectile *originalIncident, const G4Nucleus &targetNucleus, G4ReactionProduct ¤tParticle, G4ReactionProduct &targetParticle, G4FastVector< G4ReactionProduct, 256 > &vec, G4int &vecLen)
std::pair< G4int, G4int > GetFinalStateNucleons(const G4DynamicParticle *originalTarget, const G4FastVector< G4ReactionProduct, 256 > &vec, const G4int &vecLen)
void AddBlackTrackParticles(const G4double, const G4int, const G4double, const G4int, const G4ReactionProduct &, G4int, G4int, const G4Nucleus &, G4FastVector< G4ReactionProduct, 256 > &, G4int &)
G4double GenerateNBodyEvent(const G4double totalEnergy, const G4bool constantCrossSection, G4FastVector< G4ReactionProduct, 256 > &vec, G4int &vecLen)
G4ThreeVector Isotropic(const G4double &)
void SetMomentum(const G4double x, const G4double y, const G4double z)
void SetTotalEnergy(const G4double en)
G4double GetTotalMomentum() const
G4double GetKineticEnergy() const
const G4ParticleDefinition * GetDefinition() const
G4double GetTotalEnergy() const
void SetNewlyAdded(const G4bool f)
G4ThreeVector GetMomentum() const
void SetSide(const G4int sid)
void Lorentz(const G4ReactionProduct &p1, const G4ReactionProduct &p2)
void SetDefinition(const G4ParticleDefinition *aParticleDefinition)
void SetKineticEnergy(const G4double en)
void SetTOF(const G4double t)
void SetMass(const G4double mas)