5 #include "../src/nucleus.h"
16 #include "../src/hdf5_utils.h"
17 #include "../src/random.h"
19 using namespace trento;
24 CHECK( dynamic_cast<Proton*>(nucleus.get()) !=
nullptr );
31 CHECK( nucleus->radius() == 0. );
34 double offset = random::canonical<>();
35 nucleus->sample_nucleons(offset);
36 auto&& proton = *(nucleus->begin());
40 CHECK( proton.y() == 0. );
41 CHECK( proton.z() == 0. );
44 CHECK( !proton.is_participant() );
50 CHECK( dynamic_cast<Deuteron*>(nucleus.get()) !=
nullptr );
55 nucleus->sample_nucleons(0);
61 CHECK( nucleus->radius() == Approx(-std::log(.01)/(2*0.457)) );
67 CHECK( dynamic_cast<WoodsSaxonNucleus*>(nucleus.get()) !=
nullptr );
69 constexpr
int A = 208;
73 CHECK( nucleus->radius() > 6. );
75 double offset = nucleus->radius() * random::canonical<>();
76 nucleus->sample_nucleons(offset);
79 double x = 0.,
y = 0.,
z = 0.;
80 for (
const auto& nucleon : *nucleus) {
94 bool initial_participants = std::any_of(
95 nucleus->cbegin(), nucleus->cend(),
96 [](decltype(*nucleus->cbegin())&
n) {
97 return n.is_participant();
99 CHECK( !initial_participants );
106 CHECK( dynamic_cast<WoodsSaxonNucleus*>(nucleus.get()) !=
nullptr );
107 CHECK( dynamic_cast<DeformedWoodsSaxonNucleus*>(def_nucleus.get()) !=
nullptr );
109 constexpr
int A = 63;
113 CHECK( nucleus->radius() > 4. );
114 CHECK( def_nucleus->radius() > nucleus->radius() );
121 CHECK( dynamic_cast<WoodsSaxonNucleus*>(nucleus.get()) !=
nullptr );
122 CHECK( dynamic_cast<DeformedWoodsSaxonNucleus*>(def_nucleus.get()) !=
nullptr );
124 constexpr
int A = 197;
128 CHECK( nucleus->radius() > 6. );
129 CHECK( def_nucleus->radius() > nucleus->radius() );
135 CHECK( dynamic_cast<DeformedWoodsSaxonNucleus*>(nucleus.get()) !=
nullptr );
137 constexpr
int A = 238;
141 CHECK( nucleus->radius() > 8. );
156 const auto A = positions.size() / 3;
161 auto dataspace = hdf5::make_dataspace(std::array<hsize_t, 3>{1,
A, 3});
162 const auto& datatype = hdf5::type<decltype(positions)::value_type>();
164 H5::H5File
file{temp.path.string(), H5F_ACC_EXCL};
166 auto dataset =
file.createDataSet(
"test", datatype, dataspace);
167 dataset.write(positions.data(), datatype);
172 CHECK( dynamic_cast<ManualNucleus*>(nucleus.get()) !=
nullptr );
177 CHECK( nucleus->radius() == Approx(3.) );
179 nucleus->sample_nucleons(0.);
181 auto nucleon = nucleus->cbegin();
183 CHECK( nucleon->x() == Approx(0.) );
184 CHECK( nucleon->y() == Approx(0.) );
185 CHECK( nucleon->z() == Approx(0.) );
187 std::advance(nucleon, 1);
196 std::advance(nucleon, 3);
201 CHECK_THROWS_AS(
Nucleus::create(
"nonexistent.hdf"), std::invalid_argument );
204 #endif // TRENTO_HDF5
208 double R = 6.,
a = .5;
222 std::map<int, int>
hist{};
224 nucleus->sample_nucleons(0.);
225 for (
const auto& nucleon : *nucleus) {
226 auto x = nucleon.x();
227 auto y = nucleon.y();
228 auto z = nucleon.z();
229 auto r = std::sqrt(
x*
x +
y*
y +
z*
z);
230 ++
hist[
static_cast<int>(
r)];
235 auto integrate_woods_saxon = [
R,
a](
double rmin,
double rmax) ->
double {
236 auto nbins =
static_cast<int>((rmax - rmin)/.001);
237 auto dr = (rmax - rmin)/
nbins;
240 auto r = rmin +
n*dr;
241 auto f =
r*
r/(1. + std::exp((
r - R)/
a));
249 double ws_norm = integrate_woods_saxon(0,
hist.size());
252 auto all_bins_correct =
true;
253 std::ostringstream bin_output{};
254 bin_output << std::fixed << std::boolalpha
255 <<
"rmin rmax prob cprob ratio pass\n";
256 for (
const auto& bin :
hist) {
257 auto rmin = bin.first;
258 auto rmax = rmin + 1;
259 auto prob =
static_cast<double>(bin.second) /
nsamples;
260 auto correct_prob = integrate_woods_saxon(rmin, rmax) / ws_norm;
261 bool within_tol = prob == Approx(correct_prob).epsilon(.1).margin(1
e-4);
263 all_bins_correct =
false;
264 bin_output << std::setw(4) << rmin <<
' '
265 << std::setw(4) << rmax <<
" "
267 << correct_prob <<
" "
268 << prob/correct_prob <<
" "
269 << within_tol <<
'\n';
271 INFO( bin_output.str() );
272 CHECK( all_bins_correct );
285 double R = 6.,
a = .5, beta2 = .3, beta4 = .1;
290 auto mean_ecc2 = [](
Nucleus& nucleus) {
295 nucleus.sample_nucleons(0.);
298 for (
const auto& nucleon : nucleus) {
299 double x2 = std::pow(nucleon.x(), 2);
300 double y2 = std::pow(nucleon.y(), 2);
305 e2 += std::fabs(numer) / denom;
311 CHECK( mean_ecc2(nucleus_def) > 2.*mean_ecc2(nucleus_sym) );
315 constexpr
auto R = 5.,
a = .5;
316 constexpr
auto radius = R + 3*
a;
321 CHECK( nucleus.radius() == Approx(radius) );
322 CHECK( dummy_def_nucleus.radius() == Approx(radius) );
325 CHECK( def_nucleus.radius() > radius );
329 for (
const auto& species : {
"Pb",
"U"}) {
330 for (
auto repeat = 0; repeat < 10; ++repeat) {
331 const auto target_dmin = .2 + .4*random::canonical<>();
333 nucleus->sample_nucleons(10*random::canonical<>());
335 for (
auto n1 = nucleus->cbegin(); n1 != nucleus->cend(); ++n1) {
336 for (
auto n2 = n1 + 1; n2 != nucleus->cend(); ++n2) {
337 auto dx = n1->x() - n2->x();
338 auto dy = n1->y() - n2->y();
339 auto dz = n1->z() - n2->z();
340 dminsq = std::fmin(dx*dx +
dy*
dy +
dz*
dz, dminsq);
343 auto dmin = std::sqrt(dminsq);
344 INFO(
"species " << species <<
" repeat " << repeat );
345 CHECK( dmin >= target_dmin );