54 const G4TouchableHandle& thisTouchable(aTrack.GetTouchableHandle());
57 aParticleChange.Initialize(aTrack);
58 const G4DynamicParticle* IncidentRhadron = aTrack.GetDynamicParticle();
59 CustomParticle* CustomIncident = static_cast<CustomParticle*>(IncidentRhadron->GetDefinition());
60 const G4ThreeVector& aPosition = aTrack.GetPosition();
62 const G4int theIncidentPDG = IncidentRhadron->GetDefinition()->GetPDGEncoding();
63 G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
64 std::vector<G4ParticleDefinition*> theParticleDefinitions;
65 G4bool IncidentSurvives =
false;
66 G4bool TargetSurvives =
false;
67 G4Nucleus targetNucleus(aTrack.GetMaterial());
68 G4ParticleDefinition* outgoingRhadron =
nullptr;
69 G4ParticleDefinition* outgoingCloud =
nullptr;
70 G4ParticleDefinition* outgoingTarget =
nullptr;
72 G4ThreeVector p_0 = IncidentRhadron->GetMomentum();
73 G4double e_kin_0 = IncidentRhadron->GetKineticEnergy();
76 G4DynamicParticle* cloudParticle =
new G4DynamicParticle();
83 cloudParticle->SetDefinition(CustomIncident->
GetCloud());
85 if (cloudParticle->GetDefinition() ==
nullptr) {
86 G4cout <<
"FullModelHadronicProcess::PostStepDoIt Definition of particle cloud not available!!" << G4endl;
93 double scale = cloudParticle->GetDefinition()->GetPDGMass() / IncidentRhadron->GetDefinition()->GetPDGMass();
95 G4LorentzVector cloudMomentum(IncidentRhadron->GetMomentum() *
scale, cloudParticle->GetDefinition()->GetPDGMass());
96 G4LorentzVector gluinoMomentum(IncidentRhadron->GetMomentum() * (1. -
scale),
100 G4LorentzVector FullRhadron4Momentum = IncidentRhadron->Get4Momentum();
101 const G4LorentzVector& Cloud4Momentum = cloudMomentum;
103 cloudParticle->Set4Momentum(cloudMomentum);
105 G4DynamicParticle* OrgPart = cloudParticle;
117 double E_0 = IncidentRhadron->GetKineticEnergy();
118 G4double ek = OrgPart->GetKineticEnergy();
119 G4double amas = OrgPart->GetDefinition()->GetPDGMass();
120 G4ThreeVector
dir = (OrgPart->GetMomentum()).
unit();
121 G4double tkin = targetNucleus.Cinema(ek);
125 tkin = targetNucleus.EvaporationEffects(ek);
128 if (ek + gluinoMomentum.e() - gluinoMomentum.m() <= 0.1 *
MeV || ek <= 0.) {
130 G4cout <<
"Kinetic energy is sick" << G4endl;
131 G4cout <<
"Full R-hadron: " << (ek + gluinoMomentum.e() - gluinoMomentum.m()) /
MeV <<
" MeV" << G4endl;
132 G4cout <<
"Quark system: " << ek /
MeV <<
" MeV" << G4endl;
133 aParticleChange.ProposeTrackStatus(fStopButAlive);
134 return &aParticleChange;
136 OrgPart->SetKineticEnergy(ek);
138 OrgPart->SetMomentum(
dir *
p);
141 G4ParticleDefinition* aTarget;
143 G4bool force2to2 =
false;
145 while (rp.size() != 2 && force2to2) {
148 G4int NumberOfSecondaries = rp.size();
152 G4LorentzVector Target4Momentum(0., 0., 0., aTarget->GetPDGMass());
154 G4LorentzVector psum_full = FullRhadron4Momentum + Target4Momentum;
155 G4LorentzVector psum_cloud = Cloud4Momentum + Target4Momentum;
156 G4ThreeVector trafo_full_cms = (-1) * psum_full.boostVector();
157 G4ThreeVector trafo_cloud_cms = (-1) * psum_cloud.boostVector();
161 for (ReactionProduct::iterator it = rp.begin(); it != rp.end(); ++it) {
162 G4ParticleDefinition* tempDef = theParticleTable->FindParticle(*it);
163 CustomParticle* tempCust = dynamic_cast<CustomParticle*>(tempDef);
164 if (tempDef == aTarget)
165 TargetSurvives =
true;
168 if (tempCust !=
nullptr) {
169 outgoingRhadron = tempDef;
171 outgoingCloud = tempCust->
GetCloud();
172 if (outgoingCloud ==
nullptr) {
173 G4cout <<
"FullModelHadronicProcess::PostStepDoIt Definition of outgoing particle cloud not available!"
182 if (tempDef == G4Proton::Proton() || tempDef == G4Neutron::Neutron())
183 outgoingTarget = tempDef;
184 if (tempCust ==
nullptr && rp.size() == 2)
185 outgoingTarget = tempDef;
186 if (tempDef->GetPDGEncoding() == theIncidentPDG) {
187 IncidentSurvives =
true;
189 theParticleDefinitions.push_back(tempDef);
193 if (outgoingTarget ==
nullptr)
194 outgoingTarget = theParticleTable->FindParticle(rp[1]);
208 if (IncidentSurvives)
209 NumberOfSecondaries--;
210 aParticleChange.SetNumberOfSecondaries(NumberOfSecondaries);
217 const G4HadProjectile* originalIncident =
new G4HadProjectile(*OrgPart);
220 G4HadProjectile* org2 =
new G4HadProjectile(*OrgPart);
221 G4LorentzRotation trans = org2->GetTrafoToLab();
226 G4DynamicParticle* originalTarget =
new G4DynamicParticle;
227 originalTarget->SetDefinition(aTarget);
229 G4ReactionProduct targetParticle(aTarget);
231 G4ReactionProduct currentParticle(const_cast<G4ParticleDefinition*>(originalIncident->GetDefinition()));
232 currentParticle.SetMomentum(originalIncident->Get4Momentum().vect());
233 currentParticle.SetKineticEnergy(originalIncident->GetKineticEnergy());
242 G4ReactionProduct modifiedOriginal = currentParticle;
244 currentParticle.SetSide(1);
245 targetParticle.SetSide(-1);
246 G4bool incidentHasChanged =
false;
247 if (!IncidentSurvives)
248 incidentHasChanged =
true;
249 G4bool targetHasChanged =
false;
251 targetHasChanged =
true;
252 G4bool quasiElastic =
false;
255 G4FastVector<G4ReactionProduct, MYGHADLISTSIZE> vec;
262 for (G4int
i = 0;
i != NumberOfSecondaries;
i++) {
263 if (theParticleDefinitions[
i] != aTarget && theParticleDefinitions[
i] != originalIncident->GetDefinition() &&
264 theParticleDefinitions[
i] != outgoingRhadron && theParticleDefinitions[
i] != outgoingTarget) {
265 G4ReactionProduct* pa =
new G4ReactionProduct;
266 pa->SetDefinition(theParticleDefinitions[
i]);
267 (G4UniformRand() < 0.5) ? pa->SetSide(-1) : pa->SetSide(1);
268 vec.SetElement(vecLen++, pa);
272 if (incidentHasChanged)
273 currentParticle.SetDefinitionAndUpdateE(outgoingCloud);
274 if (incidentHasChanged)
275 modifiedOriginal.SetDefinition(
277 if (targetHasChanged)
278 targetParticle.SetDefinitionAndUpdateE(outgoingTarget);
301 G4String cPname = currentParticle.GetDefinition()->GetParticleName();
328 aParticleChange.SetNumberOfSecondaries(vecLen + NumberOfSecondaries);
330 G4LorentzVector cloud_p4_new;
342 cloud_p4_new.setVectM(currentParticle.GetMomentum(), currentParticle.GetMass());
343 cloud_p4_new *= trans;
345 G4LorentzVector cloud_p4_old_full = Cloud4Momentum;
346 cloud_p4_old_full.boost(trafo_full_cms);
347 G4LorentzVector cloud_p4_old_cloud = Cloud4Momentum;
348 cloud_p4_old_cloud.boost(trafo_cloud_cms);
349 G4LorentzVector cloud_p4_full = cloud_p4_new;
350 cloud_p4_full.boost(trafo_full_cms);
351 G4LorentzVector cloud_p4_cloud = cloud_p4_new;
352 cloud_p4_cloud.boost(trafo_cloud_cms);
354 G4LorentzVector p_g_cms = gluinoMomentum;
355 p_g_cms.boost(trafo_full_cms);
357 double e = cloud_p4_new.e() + gluinoMomentum.e();
359 e += outgoingRhadron->GetPDGMass();
360 G4LorentzVector p4_new(cloud_p4_new.v() + gluinoMomentum.v(),
e);
364 G4ThreeVector p_new = p4_new.vect();
366 aParticleChange.ProposeLocalEnergyDeposit((p4_new - cloud_p4_new - gluinoMomentum).
m());
368 if (incidentHasChanged) {
369 G4DynamicParticle* p0 =
new G4DynamicParticle;
370 p0->SetDefinition(outgoingRhadron);
371 p0->SetMomentum(p_new);
374 G4Track* Track0 =
new G4Track(p0, aTrack.GetGlobalTime(), aPosition);
375 Track0->SetTouchableHandle(thisTouchable);
376 aParticleChange.AddSecondary(Track0);
382 if (p0->GetKineticEnergy() > e_kin_0) {
383 G4cout <<
"ALAAAAARM!!! (incident changed from " << IncidentRhadron->GetDefinition()->GetParticleName() <<
" to "
384 << p0->GetDefinition()->GetParticleName() <<
")" << G4endl;
385 G4cout <<
"Energy loss: " << (e_kin_0 - p0->GetKineticEnergy()) /
GeV <<
" GeV (should be positive)" << G4endl;
388 G4cout <<
"DOUBLE ALAAAAARM!!!" << G4endl;
392 if (
std::abs(p0->GetKineticEnergy() - e_kin_0) > 100 *
GeV) {
393 G4cout <<
"Diff. too big" << G4endl;
395 aParticleChange.ProposeTrackStatus(fStopAndKill);
397 G4double
p = p_new.mag();
399 aParticleChange.ProposeMomentumDirection(p_new.x() /
p, p_new.y() /
p, p_new.z() /
p);
401 aParticleChange.ProposeMomentumDirection(1.0, 0.0, 0.0);
405 if (targetParticle.GetMass() > 0.0)
407 G4DynamicParticle*
p1 =
new G4DynamicParticle;
408 p1->SetDefinition(targetParticle.GetDefinition());
410 G4ThreeVector momentum = targetParticle.GetMomentum();
412 p1->SetMomentum(momentum);
413 p1->SetMomentum((trans *
p1->Get4Momentum()).vect());
414 G4Track* Track1 =
new G4Track(
p1, aTrack.GetGlobalTime(), aPosition);
415 Track1->SetTouchableHandle(thisTouchable);
416 aParticleChange.AddSecondary(Track1);
418 G4DynamicParticle* pa;
424 for (
int i = 0;
i < vecLen; ++
i) {
425 pa =
new G4DynamicParticle();
426 pa->SetDefinition(vec[
i]->GetDefinition());
427 pa->SetMomentum(vec[
i]->GetMomentum());
428 pa->Set4Momentum(trans * (pa->Get4Momentum()));
429 G4ThreeVector pvec = pa->GetMomentum();
430 G4Track* Trackn =
new G4Track(pa, aTrack.GetGlobalTime(), aPosition);
431 Trackn->SetTouchableHandle(thisTouchable);
432 aParticleChange.AddSecondary(Trackn);
438 const G4DynamicParticle* theRhadron =
FindRhadron(&aParticleChange);
440 if (theRhadron !=
nullptr || IncidentSurvives) {
442 if (IncidentSurvives) {
445 E_new = theRhadron->GetKineticEnergy();
458 G4LorentzVector p4_old_full = FullRhadron4Momentum;
459 p4_old_full.boost(trafo_full_cms);
460 G4LorentzVector p4_old_cloud = FullRhadron4Momentum;
461 p4_old_cloud.boost(trafo_cloud_cms);
462 G4LorentzVector p4_full = p4_new;
464 p4_full = p4_full.boost(trafo_full_cms);
466 G4LorentzVector p4_cloud = p4_new;
467 p4_cloud.boost(trafo_cloud_cms);
469 G4double AbsDeltaE = E_0 - E_new;
471 if (AbsDeltaE > 10 *
GeV) {
472 G4cout <<
"Energy loss larger than 10 GeV..." << G4endl;
473 G4cout <<
"E_0: " << E_0 /
GeV <<
" GeV" << G4endl;
474 G4cout <<
"E_new: " << E_new /
GeV <<
" GeV" << G4endl;
475 G4cout <<
"Gamma: " << IncidentRhadron->GetTotalEnergy() / IncidentRhadron->GetDefinition()->GetPDGMass()
477 G4cout <<
"x: " << aPosition.x() / cm <<
" cm" << G4endl;
480 delete originalIncident;
481 delete originalTarget;
486 ClearNumberOfInteractionLengthLeft();
488 return &aParticleChange;