-
Notifications
You must be signed in to change notification settings - Fork 192
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MonteCarlo emission and TemplatedFunction structure
- Loading branch information
Showing
12 changed files
with
399 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
// Distributed under the MIT License. | ||
// See LICENSE.txt for details. | ||
|
||
#pragma once | ||
|
||
#include "Evolution/Particles/MonteCarlo/TemplatedLocalFunctions.hpp" | ||
|
||
#include <cmath> | ||
|
||
#include "Evolution/Particles/MonteCarlo/Packet.hpp" | ||
|
||
namespace Particles::MonteCarlo { | ||
|
||
template <size_t EnergyBins, size_t NeutrinoSpecies> | ||
void TemplatedLocalFunctions<EnergyBins, NeutrinoSpecies>::emit_packets( | ||
const gsl::not_null<std::vector<Packet>*> packets, | ||
const gsl::not_null<std::mt19937*> random_number_generator, | ||
const double& time_start_step, const double& time_step, | ||
const Mesh<3>& mesh, | ||
const std::array<std::array<DataVector, EnergyBins>, NeutrinoSpecies>& | ||
emission_in_cell, | ||
const std::array<DataVector, NeutrinoSpecies>& single_packet_energy, | ||
const std::array<double, EnergyBins>& energy_at_bin_center, | ||
const Jacobian<DataVector, 4, Frame::Inertial, Frame::Fluid>& | ||
inertial_to_fluid_jacobian, | ||
const InverseJacobian<DataVector, 4, Frame::Inertial, Frame::Fluid>& | ||
inertial_to_fluid_inverse_jacobian) { | ||
std::uniform_real_distribution<double> rng_uniform_zero_to_one(0.0, 1.0); | ||
// We begin by determining how many packets to create for each cell, neutrino | ||
// species, and energy group. | ||
const size_t grid_size = mesh.number_of_grid_points(); | ||
std::array<std::array<std::vector<size_t>, EnergyBins>, NeutrinoSpecies> | ||
number_of_packets_to_create_per_cell; | ||
size_t number_of_packets_to_create_total = 0; | ||
for (size_t s = 0; s < NeutrinoSpecies; s++) { | ||
for (size_t g = 0; g < EnergyBins; g++) { | ||
gsl::at(gsl::at(number_of_packets_to_create_per_cell, s), g) | ||
.resize(grid_size); | ||
for (size_t i = 0; i < grid_size; i++) { | ||
const double packets_to_create_double = | ||
gsl::at(gsl::at(emission_in_cell, s), g)[i] / | ||
gsl::at(single_packet_energy, s)[i]; | ||
size_t packets_to_create_int = floor(packets_to_create_double); | ||
if (rng_uniform_zero_to_one(*random_number_generator) < | ||
packets_to_create_double - | ||
static_cast<double>(packets_to_create_int)) { | ||
packets_to_create_int++; | ||
} | ||
gsl::at(gsl::at(number_of_packets_to_create_per_cell, s), g)[i] = | ||
packets_to_create_int; | ||
number_of_packets_to_create_total += packets_to_create_int; | ||
} | ||
} | ||
} | ||
|
||
// With the number of packets known, resize the vector holding the packets | ||
Packet default_packet(0, 0.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); | ||
const size_t initial_size = packets->size(); | ||
packets->resize(initial_size + number_of_packets_to_create_total, | ||
default_packet); | ||
|
||
// Allocate memory for some temporary data. | ||
double time_normalized = 0.0; | ||
std::array<double, 3> coord_normalized{{0.0, 0.0, 0.0}}; | ||
std::array<double, 3> three_momentum_normalized{{0.0, 0.0, 0.0}}; | ||
std::array<double, 4> four_momentum_fluid_frame{{0.0, 0.0, 0.0, 0.0}}; | ||
const Index<3> extents = mesh.extents(); | ||
const std::array<double, 3> logical_dx{2.0 / static_cast<double>(extents[0]), | ||
2.0 / static_cast<double>(extents[1]), | ||
2.0 / static_cast<double>(extents[2])}; | ||
std::array<double, 3> coord_bottom_cell{{0.0, 0.0, 0.0}}; | ||
|
||
// Now create the packets | ||
size_t next_packet_index = initial_size; | ||
for (size_t x_idx = 0; x_idx < extents[0]; x_idx++) { | ||
gsl::at(coord_bottom_cell, 0) = | ||
-1.0 + 2.0 * static_cast<double>(x_idx) * gsl::at(logical_dx, 0); | ||
for (size_t y_idx = 0; y_idx < extents[1]; y_idx++) { | ||
gsl::at(coord_bottom_cell, 1) = | ||
-1.0 + 2.0 * static_cast<double>(y_idx) * gsl::at(logical_dx, 1); | ||
for (size_t z_idx = 0; z_idx < extents[2]; z_idx++) { | ||
const size_t idx = mesh.storage_index(Index<3>{{x_idx, y_idx, z_idx}}); | ||
gsl::at(coord_bottom_cell, 2) = | ||
-1.0 + 2.0 * static_cast<double>(z_idx) * gsl::at(logical_dx, 2); | ||
for (size_t s = 0; s < NeutrinoSpecies; s++) { | ||
for (size_t g = 0; g < EnergyBins; g++) { | ||
for (size_t p = 0; | ||
p < gsl::at(gsl::at(number_of_packets_to_create_per_cell, s), | ||
g)[idx]; | ||
p++) { | ||
detail::draw_single_packet(&time_normalized, &coord_normalized, | ||
&three_momentum_normalized, | ||
random_number_generator); | ||
Packet& current_packet = (*packets)[next_packet_index]; | ||
current_packet.species = s; | ||
current_packet.time = | ||
time_start_step + time_normalized * time_step; | ||
current_packet.number_of_neutrinos = | ||
gsl::at(gsl::at(single_packet_energy, s), idx) / | ||
gsl::at(energy_at_bin_center, g); | ||
current_packet.index_of_closest_grid_point = idx; | ||
// 4_momentum_fluid_frame contains p^mu in an orthornormal | ||
// coordinate system moving with the fluid. | ||
gsl::at(four_momentum_fluid_frame, 0) = | ||
gsl::at(energy_at_bin_center, g); | ||
for (size_t d = 0; d < 3; d++) { | ||
current_packet.coordinates.get(d) = | ||
gsl::at(coord_bottom_cell, d) + | ||
gsl::at(coord_normalized, d) * gsl::at(logical_dx, d); | ||
gsl::at(four_momentum_fluid_frame, d + 1) = | ||
gsl::at(three_momentum_normalized, d) * | ||
gsl::at(four_momentum_fluid_frame, 0); | ||
} | ||
|
||
// The packet stores p^t and p_i in the inertial frame. We | ||
// transform the momentum accordingly. | ||
current_packet.momentum_upper_t = 0.0; | ||
for (size_t d = 0; d < 4; d++) { | ||
current_packet.momentum_upper_t += | ||
inertial_to_fluid_inverse_jacobian.get(0, d)[idx] * | ||
gsl::at(four_momentum_fluid_frame, d); | ||
} | ||
for (size_t d = 0; d < 3; d++) { | ||
// Multiply by -1.0 because p_t = -p^t in an orthonormal frame | ||
current_packet.momentum.get(d) = | ||
(-1.0) * gsl::at(four_momentum_fluid_frame, 0) * | ||
inertial_to_fluid_jacobian.get(d + 1, 0)[idx]; | ||
for (size_t dd = 0; dd < 3; dd++) { | ||
current_packet.momentum.get(d) += | ||
gsl::at(four_momentum_fluid_frame, dd + 1) * | ||
inertial_to_fluid_jacobian.get(d + 1, dd + 1)[idx]; | ||
} | ||
} | ||
next_packet_index++; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
} // namespace Particles::MonteCarlo |
4 changes: 2 additions & 2 deletions
4
...es/MonteCarlo/EvolveMonteCarloPackets.cpp → ...on/Particles/MonteCarlo/EvolvePackets.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...Particles/MonteCarlo/MonteCarloPacket.cpp → ...Evolution/Particles/MonteCarlo/Packet.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
src/Evolution/Particles/MonteCarlo/TemplatedLocalFunctions.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Distributed under the MIT License. | ||
// See LICENSE.txt for details. | ||
|
||
#include "Evolution/Particles/MonteCarlo/TemplatedLocalFunctions.hpp" | ||
|
||
#include <cmath> | ||
|
||
#include "Evolution/Particles/MonteCarlo/EmitPackets.tpp" | ||
#include "Evolution/Particles/MonteCarlo/Packet.hpp" | ||
|
||
namespace Particles::MonteCarlo::detail { | ||
// Draw a single packet with homogeneouse spatial distribution | ||
// in [0,1]x[0,1]x[0,1], energy of 1, isotropic momentum | ||
// distribution, and time in [0,1]. | ||
void draw_single_packet( | ||
const gsl::not_null<double*> time, | ||
const gsl::not_null<std::array<double, 3>*> coord, | ||
const gsl::not_null<std::array<double, 3>*> momentum, | ||
const gsl::not_null<std::mt19937*> random_number_generator) { | ||
std::uniform_real_distribution<double> rng_uniform_zero_to_one(0.0, 1.0); | ||
|
||
*time = rng_uniform_zero_to_one(*random_number_generator); | ||
for (size_t i = 0; i < 3; i++) { | ||
gsl::at(*coord, i) = rng_uniform_zero_to_one(*random_number_generator); | ||
} | ||
const double cos_theta = | ||
-1.0 + 2.0 * rng_uniform_zero_to_one(*random_number_generator); | ||
const double phi = | ||
2.0 * M_PI * rng_uniform_zero_to_one(*random_number_generator); | ||
const double sin_theta = sqrt(1.0 - cos_theta * cos_theta); | ||
gsl::at(*momentum, 0) = sin_theta * cos(phi); | ||
gsl::at(*momentum, 1) = sin_theta * sin(phi); | ||
gsl::at(*momentum, 2) = cos_theta; | ||
} | ||
} // namespace Particles::MonteCarlo::detail | ||
|
||
template struct Particles::MonteCarlo::TemplatedLocalFunctions<2, 2>; |
Oops, something went wrong.