35 double bz0 = fld->solenoidField();
36 LOG(info) <<
"Created default magnetic field for " << bz0 <<
"kG";
37 const double nomBz = 5.00685;
38 BOOST_CHECK_CLOSE(bz0, nomBz, 0.1);
40 const int ntst = 10000;
42 double xyz[ntst][3] = {}, bxyz[ntst][3] = {}, dummyAcc = 0.;
44 for (
int it = ntst; it--;) {
45 gRandom->RndmArray(3, rnd);
46 xyz[it][0] = rnd[0] * 400. * TMath::Cos(rnd[1] * TMath::Pi() * 2);
47 xyz[it][1] = rnd[1] * 400. * TMath::Sin(rnd[1] * TMath::Pi() * 2);
48 xyz[it][2] = (rnd[0] - 0.5) * 250;
51 const int repFactor = 50;
55 for (
int ii = repFactor; ii--;) {
56 for (
int it = ntst; it--;) {
57 fld->Field(xyz[it], bxyz[it]);
63 fld->AllowFastField(
true);
69 for (
int ii = repFactor; ii--;) {
70 for (
int it = ntst; it--;) {
71 fld->Field(xyz[it], bfast);
76 double sS = swSlow.CpuTime() / (ntst * repFactor);
77 double sF = swFast.CpuTime() / (ntst * repFactor);
78 double rat = sF > 0. ? sS / sF : -1;
79 LOG(info) <<
"Timing: Exact param: " << sS <<
" Fast param: " << sF
80 <<
"s/call -> factor " << rat;
83 double mean[3] = {0.}, rms[3] = {0.};
84 const char comp[] =
"XYZ";
85 LOG(info) <<
"Relative precision of fast field wrt exact field";
86 for (
int it = ntst; it--;) {
87 fld->Field(xyz[it], bfast);
88 for (
int i = 0;
i < 3;
i++) {
89 double df = bxyz[it][
i] - bfast[
i];
94 for (
int i = 0;
i < 3;
i++) {
97 rms[
i] -= mean[
i] * mean[
i];
98 rms[
i] = TMath::Sqrt(rms[
i]);
99 LOG(info) <<
"deltaB" << comp[
i] <<
": "
100 <<
" mean=" << mean[
i] <<
"(" << mean[
i] / nomBz * 100. <<
"%)"
101 <<
" RMS =" << rms[
i] <<
"(" << rms[
i] / nomBz * 100. <<
"%)";
112 const double points[][3] = {
120 const int npoints =
sizeof(points) /
sizeof(points[0]);
121 const double tolerance = 1.e-9;
123 std::unique_ptr<MagneticField> fld = std::make_unique<MagneticField>(
"Maps",
"Maps", 1., 1.,
MagFieldParam::k5kG);
124 const double facSol = fld->getFactorSolenoid(), facDip = fld->getFactorDipole();
125 double bref[npoints][3] = {};
126 for (
int ip = 0; ip < npoints; ip++) {
127 fld->Field(points[ip], bref[ip]);
129 BOOST_CHECK(TMath::Abs(bref[ip][0]) + TMath::Abs(bref[ip][1]) + TMath::Abs(bref[ip][2]) > tolerance);
132 const char* fname =
"testMagneticFieldReinitialization.root";
134 TFile fout(fname,
"recreate");
135 fout.WriteObject(fld.get(),
"field");
139 BOOST_REQUIRE(fldRead !=
nullptr);
140 fldRead->CreateField();
143 for (
int ip = 0; ip < npoints; ip++) {
145 fldRead->Field(points[ip],
b);
146 for (
int i = 0;
i < 3;
i++) {
147 BOOST_CHECK_SMALL(
b[
i] - bref[ip][
i], tolerance);
156 constexpr int npoints = 20000;
157 constexpr int nthreads = 8;
158 std::vector<std::array<double, 3>> xyz(npoints);
159 for (
auto& p : xyz) {
160 p = {gRandom->Uniform(-450., 450.), gRandom->Uniform(-450., 450.), gRandom->Uniform(-1500., 1500.)};
163 constexpr int nval = 10;
164 auto evaluate = [&fld, &xyz](std::vector<double>& out) {
165 out.resize(npoints * nval);
166 for (
int i = 0;
i < npoints; ++
i) {
175 std::vector<std::vector<double>> results(nthreads);
176 std::vector<std::thread> threads;
177 for (
int t = 0;
t < nthreads; ++
t) {
178 threads.emplace_back(evaluate, std::ref(results[
t]));
180 for (
auto& th : threads) {
183 for (
int t = 0;
t < nthreads; ++
t) {
185 BOOST_CHECK_MESSAGE(diff.first ==
reference.end(),
"thread " <<
t <<
" differs at value " << (diff.first -
reference.begin()));