Molecular Dynamics Simulation  1.0
DiffusionFunctionInterceptor.cpp
Go to the documentation of this file.
2 
3 #include <chrono>
4 #include <unordered_map>
5 #include <variant>
6 
8 #include "utils/ArrayUtils.h"
9 
11  bool append = simulation.params.start_iteration != 0;
12 
13  csv_writer = std::make_unique<CSVWriter>(simulation.params.output_dir_path / "statistics" / "diffusion_function.csv", append);
14 
15  csv_writer->initialize({"iteration", "var(t)"});
16 
17  auto expected_iterations = static_cast<size_t>(std::ceil(simulation.params.end_time / simulation.params.delta_t) + 1);
18  SimulationInterceptor::every_nth_iteration = std::max(1, static_cast<int>(sample_every_x_percent * expected_iterations / 100));
19 
20  if (simulation.params.start_iteration == 0) {
21  saveCurrentParticlePositions(simulation);
22  }
25 }
26 
27 void DiffusionFunctionInterceptor::operator()(size_t iteration, Simulation& simulation) {
28  if (simulation.particle_container->size() != old_particle_positions.size()) {
29  throw std::runtime_error(
30  "Particle container size changed during simulation. This is not supported by the diffusion function interceptor.");
31  }
32 
33  double var_t = calculateCurrentDiffusion(simulation);
34  csv_writer->writeRow({iteration, var_t});
35 
36  saveCurrentParticlePositions(simulation);
37  last_sampled_iteration = iteration;
38 }
39 
40 void DiffusionFunctionInterceptor::onSimulationEnd(size_t iteration, Simulation& simulation) {
41  if (iteration != last_sampled_iteration) {
42  double var_t = calculateCurrentDiffusion(simulation);
43  csv_writer->writeRow({iteration, var_t});
44  }
45 }
46 
48  std::string indent = std::string(depth * 2, ' ');
49 
50  Logger::logger->info("{}╟┤{}DiffusionFunctionInterceptor: {}", indent, ansi_orange_bold, ansi_end);
51  Logger::logger->info("{}║ ├Sample every x percent: {}", indent, sample_every_x_percent);
52 }
53 
54 DiffusionFunctionInterceptor::operator std::string() const { return ""; }
55 
57  old_particle_positions.clear();
58  for (auto& particle : *simulation.particle_container) {
59  old_particle_positions.push_back(particle.getX());
60  }
61 }
62 
64  double total_displacement = 0;
65 
66  for (size_t i = 0; i < simulation.particle_container->size(); i++) {
67  auto& particle = simulation.particle_container->getParticles()[i];
68  auto& old_particle_position = old_particle_positions[i];
69 
70  std::array<double, 3> displacement = particle.getX() - old_particle_position;
71 
72  // detect if particle has moved over the periodic boundary
73  if (std::holds_alternative<SimulationParams::LinkedCellsType>(simulation.params.container_type)) {
74  auto& container = std::get<SimulationParams::LinkedCellsType>(simulation.params.container_type);
75  auto& box_size = container.domain_size;
76 
77  for (size_t i = 0; i < displacement.size(); i++) {
78  if (std::abs(displacement[i]) > box_size[i] / 2) {
79  displacement[i] = box_size[i] - std::abs(displacement[i]);
80  }
81  }
82  }
83 
84  double distance = std::pow(ArrayUtils::L2Norm(displacement), 2);
85 
86  total_displacement += distance;
87  }
88 
89  double var_t = total_displacement / simulation.particle_container->size();
90 
91  return var_t;
92 }
const std::string ansi_end
Definition: Logger.h:13
const std::string ansi_orange_bold
Definition: Logger.h:10
void saveCurrentParticlePositions(const Simulation &simulation)
void operator()(size_t iteration, Simulation &simulation) override
This function is called on every nth iteration. It counts the number of particle updates which have b...
std::unique_ptr< CSVWriter > csv_writer
void onSimulationEnd(size_t iteration, Simulation &simulation) override
This function is empty as the thermostat doesnt need to do anything at the end of the simulation.
void logSummary(int depth) const override
Logs the summary of the radial distribution function.
std::vector< std::array< double, 3 > > old_particle_positions
void onSimulationStart(Simulation &simulation) override
This function is sets the particle_updates to 0 and initializes the start time of the simulation.
double calculateCurrentDiffusion(const Simulation &simulation) const
static std::shared_ptr< spdlog::logger > logger
Publically accessible shared pointer to the logger.
Definition: Logger.h:35
double delta_t
Time step of a single simulation iteration.
std::filesystem::path output_dir_path
Path to the directory in which to save the simulation output.
size_t start_iteration
Start iteration of the simulation.
std::variant< DirectSumType, LinkedCellsType > container_type
Type of the particle container.
double end_time
End time of the simulation.
Class to run a simulation.
Definition: Simulation.h:20
std::unique_ptr< ParticleContainer > particle_container
Reference to the ParticleContainer on whose content the simulation is performed.
Definition: Simulation.h:50
const SimulationParams & params
Reference to the simulation parameters object.
Definition: Simulation.h:45
auto L2Norm(const Container &c)
Definition: ArrayUtils.h:174