307{
308
309
310 const G4Material* theMaterial = aTrack.
GetMaterial();
313
314 G4bool findThermalElement =
false;
316 const G4Element* theElement = nullptr;
317 for (
G4int i = 0; i <
n; ++i) {
319
320 if (aNucleus.GetZ_asInt() == (
G4int)(theElement->
GetZ() + 0.5)) {
321
322 if (getTS_ID(nullptr, theElement) != -1) {
323 ielement = getTS_ID(nullptr, theElement);
324 findThermalElement = true;
325 break;
326 }
327 if (getTS_ID(theMaterial, theElement) != -1) {
328 ielement = getTS_ID(theMaterial, theElement);
329 findThermalElement = true;
330 break;
331 }
332 }
333 }
334
335 if (findThermalElement) {
336
338 auto dp =
new G4DynamicParticle(pd, aTrack.
Get4Momentum());
339 G4double total = theXSection->GetCrossSection(dp, theElement, theMaterial);
340 G4double inelastic = theXSection->GetInelasticCrossSection(dp, theElement, theMaterial);
341
342 auto inelELM = inelasticFSs->find(ielement);
343 G4bool mayBeInel = (inelELM != inelasticFSs->end());
344 auto coheELM = coherentFSs->find(ielement);
345 G4bool mayBeCohe = (coheELM != coherentFSs->end());
346 auto incoELM = incoherentFSs->find(ielement);
347 G4bool mayBeInco = (incoELM != incoherentFSs->end());
348
350 if ((total*random <= inelastic && mayBeInel) || (!mayBeCohe && !mayBeInco)) {
351
352
353 std::vector<G4double> v_temp;
354 v_temp.clear();
355 for (auto it = inelELM->second->begin(); it != inelELM->second->end(); ++it)
356 {
357 v_temp.push_back(it->first);
358 }
359
360 std::pair<G4double, G4double> tempLH = find_LH(aTemp, &v_temp);
361
362
363
364 std::vector<E_P_E_isoAng*>* vNEP_EPM_TL = nullptr;
365 std::vector<E_P_E_isoAng*>* vNEP_EPM_TH = nullptr;
366
367 if (tempLH.first != 0.0 && tempLH.second != 0.0) {
368 vNEP_EPM_TL = inelELM->second->find(tempLH.first / kelvin)->second;
369 vNEP_EPM_TH = inelELM->second->find(tempLH.second / kelvin)->second;
370 }
371 else if (tempLH.first == 0.0) {
372 auto itm = inelELM->second->begin();
373 vNEP_EPM_TL = itm->second;
374 ++itm;
375 vNEP_EPM_TH = itm->second;
376 tempLH.first = tempLH.second;
377 tempLH.second = itm->first;
378 }
379 else if (tempLH.second == 0.0) {
380 auto itm = inelELM->second->end();
381 --itm;
382 vNEP_EPM_TH = itm->second;
383 --itm;
384 vNEP_EPM_TL = itm->second;
385 tempLH.second = tempLH.first;
386 tempLH.first = itm->first;
387 }
388
390
391
392
393 std::pair<G4double, G4double> secondaryParam;
395 if (rand_temp < (aTemp - tempLH.first) / (tempLH.second - tempLH.first))
396 secondaryParam = sample_inelastic_E_mu(aTrack.
GetKineticEnergy(), vNEP_EPM_TH);
397 else
398 secondaryParam = sample_inelastic_E_mu(aTrack.
GetKineticEnergy(), vNEP_EPM_TL);
399
400 sE = secondaryParam.first;
401 mu = secondaryParam.second;
402
403
406 G4double sint = std::sqrt(1 - mu * mu);
407 theParticleChange.SetMomentumChange(sint * std::cos(phi), sint * std::sin(phi), mu);
408 }
409 else if (mayBeCohe &&
410 (!mayBeInco || random*total
411 <= (inelastic + theXSection->GetCoherentCrossSection(dp, theElement, theMaterial))))
412 {
413
414
416
417
418 std::vector<G4double> v_temp;
419 v_temp.clear();
420 for (auto it = coheELM->second->begin(); it != coheELM->second->end(); ++it)
421 {
422 v_temp.push_back(it->first);
423 }
424
425
426 std::pair<G4double, G4double> tempLH = find_LH(aTemp, &v_temp);
427
428
429
430
431 std::vector<std::pair<G4double, G4double>*>* pvE_p_TL = nullptr;
432 std::vector<std::pair<G4double, G4double>*>* pvE_p_TH = nullptr;
433
434 if (tempLH.first != 0.0 && tempLH.second != 0.0) {
435 pvE_p_TL = coheELM->second->find(tempLH.first / kelvin)->second;
436 pvE_p_TH = coheELM->second->find(tempLH.first / kelvin)->second;
437 }
438 else if (tempLH.first == 0.0) {
439 pvE_p_TL = coheELM->second->find(v_temp[0])->second;
440 pvE_p_TH = coheELM->second->find(v_temp[1])->second;
441 tempLH.first = tempLH.second;
442 tempLH.second = v_temp[1];
443 }
444 else if (tempLH.second == 0.0) {
445 pvE_p_TH = coheELM->second->find(v_temp.back())->second;
446 auto itv = v_temp.cend();
447 --itv;
448 --itv;
449 pvE_p_TL = coheELM->second->find(*itv)->second;
450 tempLH.second = tempLH.first;
451 tempLH.first = *itv;
452 }
453 else {
454
455 throw G4HadronicException(
456 __FILE__, __LINE__,
457 "A problem is found in Thermal Scattering Data! Unexpected temperature values in data");
458 }
459
460 std::vector<G4double> vE_T;
461 std::vector<G4double> vp_T;
462
463 auto n1 = (
G4int)pvE_p_TL->size();
464
465
466 std::vector<std::pair<G4double, G4double>*>* pvE_p_T_sampled;
468 if (rand_temp < (aTemp - tempLH.first) / (tempLH.second - tempLH.first))
469 pvE_p_T_sampled = pvE_p_TH;
470 else
471 pvE_p_T_sampled = pvE_p_TL;
472
473
474 for (
G4int i = 0; i < n1; ++i) {
475 vE_T.push_back((*pvE_p_T_sampled)[i]->first);
476 vp_T.push_back((*pvE_p_T_sampled)[i]->second);
477 }
478
480 for (
G4int i = 1; i < n1; ++i) {
481 if (E / eV < vE_T[i]) {
482 j = i - 1;
483 break;
484 }
485 }
486
488
490 for (
G4int i = 0; i <= j; ++i) {
492 if (rand_for_mu < Pi) {
493 k = i;
494 break;
495 }
496 }
497
499
500 G4double mu = 1 - 2 * Ei / (E / eV);
501
502 if (mu < -1.0) mu = -1.0;
503
506 G4double sint = std::sqrt(1 - mu * mu);
507 theParticleChange.SetMomentumChange(sint * std::cos(phi), sint * std::sin(phi), mu);
508 }
509 else if (mayBeInco) {
510
511
512
513 std::vector<G4double> v_temp;
514 v_temp.clear();
515 for (auto it = incoELM->second->cbegin(); it != incoELM->second->cend(); ++it)
516 {
517 v_temp.push_back(it->first);
518 }
519
520
521 std::pair<G4double, G4double> tempLH = find_LH(aTemp, &v_temp);
522
523
524
525
526
527 E_isoAng anEPM_TL_E;
528 E_isoAng anEPM_TH_E;
529
530 if (tempLH.first != 0.0 && tempLH.second != 0.0) {
531
532 anEPM_TL_E = create_E_isoAng_from_energy(
534 incoELM->second->find(tempLH.first / kelvin)->second);
535 anEPM_TH_E = create_E_isoAng_from_energy(
537 incoELM->second->find(tempLH.second / kelvin)->second);
538 }
539 else if (tempLH.first == 0.0) {
540
541 anEPM_TL_E = create_E_isoAng_from_energy(
543 incoELM->second->find(v_temp[0])->second);
544 anEPM_TH_E = create_E_isoAng_from_energy(
546 incoELM->second->find(v_temp[1])->second);
547 tempLH.first = tempLH.second;
548 tempLH.second = v_temp[1];
549 }
550 else if (tempLH.second == 0.0) {
551
552 std::size_t
nn = v_temp.size();
554 anEPM_TL_E = create_E_isoAng_from_energy(
556 incoELM->second->find(v_temp[nn - 2])->second);
557 anEPM_TH_E = create_E_isoAng_from_energy(
559 incoELM->second->find(v_temp.back())->second);
560 }
561
562
564
565
566 E_isoAng anEPM_T_E_sampled;
568 if (rand_temp < (aTemp - tempLH.first) / (tempLH.second - tempLH.first))
569 anEPM_T_E_sampled = std::move(anEPM_TH_E);
570 else
571 anEPM_T_E_sampled = std::move(anEPM_TL_E);
572
573 mu = getMu(&anEPM_T_E_sampled);
574
575
578 G4double sint = std::sqrt(1 - mu * mu);
579 theParticleChange.SetMomentumChange(sint * std::cos(phi), sint * std::sin(phi), mu);
580 }
581 delete dp;
582
584 }
585
586
587 return theHPElastic->ApplyYourself(aTrack, aNucleus,
588 true);
589}
const G4Material * GetMaterial() const
const G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
const G4LorentzVector & Get4Momentum() const
G4HadFinalState theParticleChange
G4double GetTemperature() const
const G4Element * GetElement(G4int iel) const
std::size_t GetNumberOfElements() const
G4double total(Particle const *const p1, Particle const *const p2)