15 #include <boost/math/constants/constants.hpp>
19 #define BOOST_DISABLE_ASSERTS
21 #include <boost/multi_array.hpp>
30 constexpr
auto c = 0.61;
31 constexpr
auto a_min = 0.01;
32 return std::sqrt(std::fmax(a*a - c*c*w*w, a_min*a_min));
40 else if (species ==
"d")
42 else if (species ==
"Cu")
44 63, 4.20, 0.596, nucleon_dmin
46 else if (species ==
"Cu2")
48 63, 4.20, 0.596, 0.162, -0.006, nucleon_dmin
50 else if (species ==
"Xe")
52 129, 5.36, 0.590, nucleon_dmin
54 else if (species ==
"Au")
56 197, 6.38, 0.535, nucleon_dmin
58 else if (species ==
"Au2")
60 197, 6.38, 0.535, -0.131, -0.031, nucleon_dmin
62 else if (species ==
"Pb")
64 208, 6.62, 0.546, nucleon_dmin
66 else if (species ==
"U")
68 238, 6.81, 0.600, 0.280, 0.093, nucleon_dmin
70 else if (species ==
"U2")
72 238, 6.86, 0.420, 0.265, 0.000, nucleon_dmin
74 else if (species ==
"U3")
76 238, 6.67, 0.440, 0.280, 0.093, nucleon_dmin
83 throw std::invalid_argument{
"HDF5 output was not compiled"};
87 throw std::invalid_argument{
"unknown projectile species: " + species};
99 nucleon->set_position(x +
offset_, y, z);
125 return -std::log(.01)/(2*
a_);
139 auto u = random::canonical<double>();
141 r = -std::log(
u) / (2*
a_);
146 prob = std::pow(std::exp(-
a_*r) - std::exp(-
b_*r), 2) /
u;
147 }
while (prob < random::canonical<double>());
150 auto cos_theta = random::cos_theta<double>();
151 auto phi = random::phi<double>();
155 auto x = r_sin_theta * std::cos(phi);
156 auto y = r_sin_theta * std::sin(phi);
174 auto dx = nucleon->x() - nucleon2->x();
175 auto dy = nucleon->y() - nucleon2->y();
176 auto dz = nucleon->z() - nucleon2->z();
186 std::size_t
A,
double R,
double a,
double dmin)
190 woods_saxon_dist_(1000, 0., R + 10.*a,
191 [R, a](
double r) {
return r*
r/(1.+std::exp((
r-R)/a)); })
212 std::vector<double> radii(
size());
213 for (
auto&&
r : radii)
218 auto r_iter = radii.cbegin();
227 auto cos_theta = random::cos_theta<double>();
228 auto phi = random::phi<double>();
232 auto x = r_sin_theta * std::cos(phi);
233 auto y = r_sin_theta * std::sin(phi);
255 std::size_t
A,
double R,
double a,
double beta2,
double beta4,
double dmin)
256 : MinDistNucleus(A, dmin),
261 rmax_(R*(1. + .63*std::fabs(beta2) + .85*std::fabs(beta4)) + 10.*a)
277 using math::double_constants::one_div_root_pi;
278 auto Y20 = std::sqrt(5)/4. * one_div_root_pi * (3.*cos_theta_sq - 1.);
279 auto Y40 = 3./16. * one_div_root_pi *
280 (35.*cos_theta_sq*cos_theta_sq - 30.*cos_theta_sq + 3.);
285 return 1. / (1. + std::exp((r - Reff) /
a_));
302 const auto cos_a = random::cos_theta<double>();
303 const auto sin_a = std::sqrt(1. - cos_a*cos_a);
306 const auto angle_b = random::phi<double>();
307 const auto cos_b = std::cos(angle_b);
308 const auto sin_b = std::sin(angle_b);
316 std::vector<Sample> samples(
size());
318 for (
auto&& sample : samples) {
322 sample.r =
rmax_ * std::cbrt(random::canonical<double>());
323 sample.cos_theta = random::cos_theta<double>();
325 random::canonical<double>() >
334 samples.begin(), samples.end(),
335 [](
const Sample&
a,
const Sample&
b) {
341 auto sample = samples.cbegin();
353 auto phi = random::phi<double>();
356 auto x = r_sin_theta * std::cos(
phi);
357 auto y = r_sin_theta * std::sin(
phi);
362 auto x_rot = x*cos_b -
y*cos_a*sin_b +
z*sin_a*sin_b;
363 auto y_rot = x*sin_b +
y*cos_a*cos_b -
z*sin_a*cos_b;
364 auto z_rot =
y*sin_a +
z*cos_a;
390 template <
typename T, std::
size_t FileDims, std::
size_t MemDims>
391 boost::multi_array<T, MemDims>
394 const std::array<hsize_t, FileDims>&
count,
395 const std::array<hsize_t, FileDims>&
start,
396 const std::array<hsize_t, MemDims>&
shape) {
397 boost::multi_array<T, MemDims>
array{shape};
398 auto filespace = dataset.getSpace();
399 filespace.selectHyperslab(H5S_SELECT_SET, count.data(), start.data());
400 auto memspace = hdf5::make_dataspace(shape);
402 dataset.read(
array.data(), hdf5::type<T>(), memspace, filespace);
410 auto file = hdf5::try_open_file(path);
414 if (
file.getNumObjs() != 1)
415 throw std::invalid_argument{
416 "file '" + path +
"' must contain exactly one object"
419 auto name =
file.getObjnameByIdx(0);
420 #if H5_VERSION_GE(1, 8, 13)
421 if (
file.childObjType(
name) != H5O_TYPE_DATASET)
423 if (
file.getObjTypeByIdx(0) != H5G_DATASET)
425 throw std::invalid_argument{
426 "object '" +
name +
"' in file '" + path +
"' is not a dataset"
430 auto dataset = std::unique_ptr<H5::DataSet>{
435 std::array<hsize_t, 3>
shape;
436 auto ndim = dataset->getSpace().getSimpleExtentDims(shape.data());
439 throw std::invalid_argument{
440 "dataset '" +
name +
"' in file '" + path +
"' has " +
445 throw std::invalid_argument{
446 "dataset '" +
name +
"' in file '" + path +
"' has " +
451 const auto& nconfigs = shape[0];
452 const auto&
A = shape[1];
456 std::array<hsize_t, 3> count = {
n,
A, 3};
457 std::array<hsize_t, 3> start = {0, 0, 0};
458 std::array<hsize_t, 2> shape_n = {
n*
A, 3};
467 auto r_sq =
x*
x +
y*
y +
z*
z;
472 auto rmax = std::sqrt(rmax_sq);
474 return std::unique_ptr<ManualNucleus>{
475 new ManualNucleus{
std::move(dataset), nconfigs,
A, rmax}
479 ManualNucleus::ManualNucleus(std::unique_ptr<H5::DataSet> dataset,
480 std::size_t nconfigs, std::size_t
A,
double rmax)
482 dataset_(std::
move(dataset)),
484 index_dist_(0, nconfigs - 1)
487 ManualNucleus::~ManualNucleus() =
default;
489 double ManualNucleus::radius()
const {
493 void ManualNucleus::sample_nucleons_impl() {
496 const auto angle_1 = random::phi<double>();
497 const auto c1 = std::cos(angle_1);
498 const auto s1 = std::sin(angle_1);
500 const auto c2 = random::cos_theta<double>();
501 const auto s2 = std::sqrt(1. -
c2*
c2);
503 const auto angle_3 = random::phi<double>();
504 const auto c3 = std::cos(angle_3);
505 const auto s3 = std::sin(angle_3);
508 std::array<hsize_t, 3> count = {1,
size(), 3};
509 std::array<hsize_t, 3> start = {index_dist_(
random::engine), 0, 0};
510 std::array<hsize_t, 2> shape = {
size(), 3};
511 const auto positions = read_dataset<float>(*dataset_,
count,
start,
shape);
514 auto positions_iter = positions.begin();
515 for (iterator nucleon =
begin(); nucleon !=
end(); ++nucleon) {
523 auto x_rot =
x*(c1*c3 -
c2*s1*s3) -
y*(c3*s1 + c1*
c2*s3) +
z*s2*s3;
524 auto y_rot =
x*(c1*s3 +
c2*c3*s1) -
y*(s1*s3 - c1*
c2*c3) -
z*c3*s2;
525 auto z_rot =
x*s1*s2 +
y*c1*s2 +
z*
c2;
527 set_nucleon_position(nucleon, x_rot, y_rot, z_rot);
531 #endif // TRENTO_HDF5