Line data Source code
1 : /**********************************************************************/ 2 : /* DO NOT MODIFY THIS HEADER */ 3 : /* MAGPIE - Mesoscale Atomistic Glue Program for Integrated Execution */ 4 : /* */ 5 : /* Copyright 2017 Battelle Energy Alliance, LLC */ 6 : /* ALL RIGHTS RESERVED */ 7 : /**********************************************************************/ 8 : 9 : #include "PKAFissionFragmentEmpirical.h" 10 : 11 : registerMooseObject("MagpieApp", PKAFissionFragmentEmpirical); 12 : 13 : InputParameters 14 78 : PKAFissionFragmentEmpirical::validParams() 15 : { 16 78 : InputParameters params = PKAGeneratorBase::validParams(); 17 78 : params.addClassDescription( 18 : "Fission fragment PKA generator using an empirical mass and energy " 19 : "distribution for LWR UO2 fuel from H.R. Faust, Eur. Phys. J. A 14 (2002) 459."); 20 156 : params.addParam<PostprocessorName>("fission_rate", 21 156 : 1e-8, 22 : "Fission rate per unit volume (uses mesh units defined in the " 23 : "rasterizer and moose time units)"); 24 156 : params.addRequiredCoupledVar("relative_density", 25 : "Relative UO2 density (1 is fully dense, 0 is no UO2"); 26 78 : return params; 27 0 : } 28 : 29 43 : PKAFissionFragmentEmpirical::PKAFissionFragmentEmpirical(const InputParameters & parameters) 30 : : PKAGeneratorBase(parameters), 31 43 : _fission_rate(getPostprocessorValue("fission_rate")), 32 86 : _relative_density(coupledValue("relative_density")) 33 : { 34 43 : } 35 : 36 : void 37 26154 : PKAFissionFragmentEmpirical::appendPKAs(std::vector<MyTRIM_NS::IonBase> & ion_list, 38 : const MyTRIMRasterizer::PKAParameters & pka_parameters, 39 : const MyTRIMRasterizer::AveragedData &) const 40 : { 41 26154 : const auto dt = pka_parameters._dt; 42 26154 : const auto vol = pka_parameters._volume; 43 26154 : const auto recoil_rate_scaling = pka_parameters._recoil_rate_scaling; 44 : 45 : mooseAssert(dt >= 0, 46 : "Passed a negative time window into PKAFissionFragmentEmpirical::appendPKAs"); 47 : mooseAssert(vol >= 0, "Passed a negative volume into PKAFissionFragmentEmpirical::appendPKAs"); 48 : 49 26154 : unsigned int num_fission = std::floor( 50 26154 : recoil_rate_scaling * dt * vol * _fission_rate * _relative_density[0] + getRandomReal()); 51 : 52 : /// Mass inverter to sample PKA mass distribution 53 26154 : MyTRIM_NS::MassInverter mass_inverter; 54 : 55 633390 : for (unsigned i = 0; i < num_fission; ++i) 56 : { 57 : // each fission event generates a pair of recoils 58 607236 : MyTRIM_NS::IonBase ion1, ion2; 59 : 60 : // sample fission fragment masses 61 607236 : ion1._m = mass_inverter.x(getRandomReal()); 62 607236 : ion2._m = 235.0 - ion1._m - 2.0; // thermal fission emits 2n 63 : 64 : // Total energy in eV (energy inverter output MeV) 65 607236 : MyTRIM_NS::EnergyInverter energy_inverter; 66 607236 : energy_inverter.setMass(ion1._m); 67 607236 : Real Etot = energy_inverter.x(getRandomReal()) * 1e6; 68 607236 : ion1._E = Etot * ion2._m / (ion1._m + ion2._m); 69 607236 : ion2._E = Etot - ion1._E; 70 : 71 : // assume p/n ratio like U (Semi-empirical mass formula would be marginally better ~15%, 72 : // but it is harder to achieve charge neutrality 73 607236 : ion1._Z = std::round((ion1._m * 92.0) / (235.0 - 2.0)); 74 607236 : ion2._Z = 92 - ion1._Z; 75 : 76 : // set stopping criteria 77 607236 : ion1.setEf(); 78 607236 : ion2.setEf(); 79 : 80 : // the tag is the element this PKA get registered as upon stopping 81 : // -1 means the PKA will be ignored 82 607236 : ion1._tag = ionTag(pka_parameters, ion1._Z, ion1._m); 83 607236 : ion2._tag = ionTag(pka_parameters, ion2._Z, ion2._m); 84 : 85 : // set location of the fission event 86 607236 : setPosition(ion1); 87 607236 : ion2._pos = ion1._pos; 88 : 89 : // set random direction for ion 1 and opposite direction for ion 2 90 607236 : setRandomDirection(ion1); 91 607236 : ion2._dir = -ion1._dir; 92 : 93 : // add PKAs to list 94 607236 : ion_list.push_back(ion1); 95 607236 : ion_list.push_back(ion2); 96 : } 97 26154 : }