6 const std::vector<double>& lengths,
7 const std::vector<std::map<int,double>>& rates,
8 const std::map<int,double>& nucleusLengths,
9 const double dt,
const double occurrence,
const double targetDraw,
const double positionDraw)
11 if(lengths.size()!=rates.size() || !std::isfinite(dt) || dt<0.0)
13 throw std::runtime_error(
"Invalid thermal cross-slip sampling data");
15 for(
const double draw : {occurrence,targetDraw,positionDraw})
17 if(!std::isfinite(draw) || draw<0.0 || draw>=1.0)
19 throw std::runtime_error(
"Thermal cross-slip uniforms must lie in [0,1)");
23 for(
const double value : lengths)
25 if(!std::isfinite(value) || value<0.0)
27 throw std::runtime_error(
"Invalid thermal branch length");
31 std::map<int,double> totals;
32 for(
const auto& segment : rates)
34 for(
const auto& [target,rate] : segment)
36 const double nucleus=nucleusLengths.at(target);
37 if(!std::isfinite(rate) || rate<0.0 || !std::isfinite(nucleus) || nucleus<=0.0)
39 throw std::runtime_error(
"Invalid thermal cross-slip rate or nucleation length");
48 for(
const auto& [target,rate] : totals)
52 if(!std::isfinite(total))
54 throw std::runtime_error(
"Thermal cross-slip total rate overflow");
56 if(total<=0.0 || occurrence>=-std::expm1(-total*dt))
60 double selection=targetDraw*total;
61 for(
const auto& [target,rate] : totals)
63 if(rate>0.0 && selection<rate)
65 double location=positionDraw*rate;
67 for(
size_t k=0;
k<rates.size();++
k)
69 const auto found=rates[
k].find(target);
70 const double local=found==rates[
k].end()? 0.0 : found->second;
71 if(local>0.0 && location<local)
73 const double nucleus=nucleusLengths.at(target);
74 const double center=std::clamp(offset+lengths[
k]*location/local,0.5*nucleus,length-0.5*nucleus);
83 throw std::runtime_error(
"Thermal cross-slip selection failed");
std::optional< ThermalCrossSlipEvent > sampleThermalCrossSlip(const std::vector< double > &lengths, const std::vector< std::map< int, double > > &rates, const std::map< int, double > &nucleusLengths, const double dt, const double occurrence, const double targetDraw, const double positionDraw)