Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
testThermalCrossSlipSampling.cpp
Go to the documentation of this file.
1#include <CrossSlipBranch.h>
2#include <random>
3#include <iostream>
4#include <stdexcept>
5
6void require(bool value,const char* message)
7{
8 if(!value)
9 {
10 throw std::runtime_error(message);
11 }
12}
13
14int main()
15{
16 try
17 {
18 const std::map<int,double> nuclei{{2,20.0},{7,30.0}};
19 std::mt19937 gen(42);
20 std::uniform_real_distribution<double> uniform(0.0,1.0);
21 size_t events=0,second=0;
22 for(size_t trial=0;trial<100000;++trial)
23 {
24 const double u=uniform(gen),v=uniform(gen),w=uniform(gen);
25 const auto reference=model::sampleThermalCrossSlip({100.0},{{{2,2.0},{7,6.0}}},nuclei,0.1,u,v,w);
26 for(const size_t count : {2,10,100})
27 {
28 const std::vector<double> lengths(count,100.0/count);
29 const std::vector<std::map<int,double>> rates(count,{{2,2.0/count},{7,6.0/count}});
30 const auto result=model::sampleThermalCrossSlip(lengths,rates,nuclei,0.1,u,v,w);
31 require(bool(result)==bool(reference),"Segmentation changed event occurrence");
32 if(result)
33 {
34 require(result->target==reference->target,"Segmentation changed target competition");
35 require(std::abs(result->centerFraction-reference->centerFraction)<1.e-12,"Segmentation changed nucleation position");
36 require(result->length==reference->length,"Segmentation changed nucleus length");
37 }
38 }
39 if(reference)
40 {
41 ++events;
42 second+=reference->target==7;
43 }
44 }
45 require(std::abs(double(events)/100000.0-(-std::expm1(-0.8)))<0.005,"Incorrect total hazard");
46 require(std::abs(double(second)/events-0.75)<0.01,"Incorrect target competition");
47 require(!model::sampleThermalCrossSlip({10.0},{{{2,2.0}}},nuclei,100.0,0.0,0.0,0.0),"Nucleated on a branch shorter than physical nucleus");
48 require(!model::sampleThermalCrossSlip({100.0},{{{2,2.0}}},nuclei,0.0,0.0,0.0,0.0),"Nucleated in zero time");
49 require(!model::sampleThermalCrossSlip({100.0},{{{2,0.0}}},nuclei,1.0,0.0,0.0,0.0),"Nucleated with zero rate");
50 for(const double v : {0.1,0.6})
51 {
52 const auto event=model::sampleThermalCrossSlip({100.0},{{{2,2.0},{7,2.0}}},nuclei,100.0,0.0,v,0.5);
53 require(event && event->target==(v<0.5? 2 : 7),"Equal rates discarded a target");
54 }
55 // Nonuniform physical rate: subdivide each half without changing its density.
56 const auto a=model::sampleThermalCrossSlip({40.0,60.0},{{{2,1.0}},{{2,9.0}}},nuclei,1.0,0.1,0.1,0.6);
57 const auto b=model::sampleThermalCrossSlip({10.0,30.0,20.0,40.0},{{{2,0.25}},{{2,0.75}},{{2,3.0}},{{2,6.0}}},nuclei,1.0,0.1,0.1,0.6);
58 require(a && b && std::abs(a->centerFraction-b->centerFraction)<1.e-12,"Nonuniform rates depend on segmentation");
59 std::cout<<"PASS: thermal branch sampling independent of segmentation, competing hazards and physical nucleus lengths\n";
60 }
61 catch(const std::exception& error)
62 {
63 std::cerr<<error.what()<<'\n';
64 return 1;
65 }
66}
a
Definition int_R.m:14
b
Definition int_R.m:16
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)
void require(bool value, const char *message)
REAL w[16]
REAL u[4]
void events
result
REAL v[4]