Molecular Dynamics Simulation  1.0
SimulationParams.cpp
Go to the documentation of this file.
1 #include "SimulationParams.h"
2 
3 #include <omp.h>
4 
5 #include <filesystem>
6 #include <fstream>
7 #include <numeric>
8 
10 #include "io/logger/Logger.h"
12 #include "physics/ForcePicker.h"
15 #include "utils/StringUtils.h"
16 
17 std::filesystem::path constructOutputPath(const std::filesystem::path& base_path, const std::string& name) {
18  auto base = base_path;
19 
20  if (base.empty()) {
21  base = "./output";
22  }
23 
24  return std::filesystem::absolute(base) / name;
25 }
26 
27 SimulationParams::SimulationParams(const std::filesystem::path& input_file_path, double delta_t, double end_time,
28  const std::variant<DirectSumType, LinkedCellsType>& container_type,
29  const std::vector<std::shared_ptr<SimulationInterceptor>>& interceptors,
30  const std::vector<std::shared_ptr<SimpleForceSource>>& simple_forces,
31  const std::vector<std::shared_ptr<PairwiseForceSource>>& pairwise_forces,
32  const std::vector<std::shared_ptr<TargettedForceSource>>& targetted_forces, bool fresh,
33  const std::filesystem::path& base_path, size_t start_iteration)
34  : input_file_path(std::filesystem::absolute(input_file_path)),
35  delta_t(delta_t),
36  end_time(end_time),
37  interceptors(interceptors),
38  container_type(container_type),
39  simple_forces(simple_forces),
40  pairwise_forces(pairwise_forces),
41  targetted_forces(targetted_forces),
42  fresh(fresh),
43  start_iteration(start_iteration) {
44  if (end_time < 0) {
45  Logger::logger->error("End time must be positive");
46  throw std::runtime_error("End time must be positive");
47  }
48  if (delta_t < 0) {
49  Logger::logger->error("Delta t must be positive");
50  throw std::runtime_error("Delta t must be positive");
51  }
52 
53  this->output_dir_path = constructOutputPath(base_path, input_file_path.stem().string());
54 
56 
57  this->num_particles = 0;
58 }
59 
60 void SimulationParams::logSummary(int depth) const {
61  std::string indent = std::string(depth * 2, ' ');
62 
63  std::string force_names =
64  std::accumulate(
65  simple_forces.begin(), simple_forces.end(), std::string{},
66  [](const std::string& acc, const std::shared_ptr<SimpleForceSource>& force) { return acc + std::string(*force) + ", "; }) +
67  std::accumulate(
68  pairwise_forces.begin(), pairwise_forces.end(), std::string{},
69  [](const std::string& acc, const std::shared_ptr<PairwiseForceSource>& force) { return acc + std::string(*force) + ", "; });
70 
71  Logger::logger->info("{}╔════════════════════════════════════════", indent);
72  Logger::logger->info("{}╟┤{}Simulation arguments: {}", indent, ansi_yellow_bold, ansi_end);
73  Logger::logger->info("{}║ Input file path: {}", indent, input_file_path.string());
74  Logger::logger->info("{}║ Output directory path: {}", indent, output_dir_path.string());
75  Logger::logger->info("{}║ Start iteration: {}", indent, start_iteration);
76  Logger::logger->info("{}║ Delta_t: {}", indent, delta_t);
77  Logger::logger->info("{}║ End_time: {}", indent, end_time);
78  Logger::logger->info("{}║ Reuse cached data: {}", indent, !fresh);
79 
80  // Print Physical setup
81  Logger::logger->info("{}╟┤{}Physical setup: {}", indent, ansi_yellow_bold, ansi_end);
82  Logger::logger->info("{}║ Number of particles: {}", indent, num_particles);
83  Logger::logger->info("{}║ Number of forces: {}", indent, pairwise_forces.size() + simple_forces.size());
84  Logger::logger->info("{}║ Forces: {}", indent, force_names);
85 
86  Logger::logger->info("{}╟┤{}Container: {}", indent, ansi_yellow_bold, ansi_end);
87 
88  if (std::holds_alternative<SimulationParams::LinkedCellsType>(container_type)) {
89  auto lc_container = std::get<SimulationParams::LinkedCellsType>(container_type);
90 
91  using LC = LinkedCellsContainer;
92 
93  auto domain_size = lc_container.domain_size;
94  Logger::logger->info("{}║ Linked Cells", indent);
95  Logger::logger->info("{}║ Domain size: {} x {} x {}", indent, domain_size[0], domain_size[1], domain_size[2]);
96  Logger::logger->info("{}║ Cutoff radius: {}", indent, lc_container.cutoff_radius);
97  Logger::logger->info("{}║ ┌Left: {}", indent, LC::boundaryConditionToString(lc_container.boundary_conditions[0]));
98  Logger::logger->info("{}║ ├Right: {}", indent, LC::boundaryConditionToString(lc_container.boundary_conditions[1]));
99  Logger::logger->info("{}║ ├Bottom: {}", indent, LC::boundaryConditionToString(lc_container.boundary_conditions[2]));
100  Logger::logger->info("{}║ ├Top: {}", indent, LC::boundaryConditionToString(lc_container.boundary_conditions[3]));
101  Logger::logger->info("{}║ ├Back: {}", indent, LC::boundaryConditionToString(lc_container.boundary_conditions[4]));
102  Logger::logger->info("{}║ └Front: {}", indent, LC::boundaryConditionToString(lc_container.boundary_conditions[5]));
103  } else if (std::holds_alternative<SimulationParams::DirectSumType>(container_type)) {
104  Logger::logger->info("{}║ Direct Sum", indent);
105  } else {
106  Logger::logger->error("Invalid container type");
107  throw std::runtime_error("Invalid container type");
108  }
109 
110  Logger::logger->info("{}╟┤{}Interceptors: {}", indent, ansi_yellow_bold, ansi_end);
111  if (interceptors.empty()) {
112  Logger::logger->info("{}║ None", indent);
113  } else {
114  for (auto& interceptor : interceptors) {
115  interceptor->logSummary(depth);
116  }
117  }
118 
119 #ifdef _OPENMP
120  Logger::logger->info("{}╟┤{}Maximum Number of Threads:{} {}", indent, ansi_yellow_bold, ansi_end, omp_get_max_threads());
121 #endif
122 
123  Logger::logger->info("{}╚════════════════════════════════════════", indent);
124 }
const std::string ansi_yellow_bold
Definition: Logger.h:11
const std::string ansi_end
Definition: Logger.h:13
std::filesystem::path constructOutputPath(const std::filesystem::path &base_path, const std::string &name)
static size_t calculateHash(const std::filesystem::path &filepath)
Calculates the hash for the given input file.
Extension of the ParticleContainer class using a linked cells data structure for improved performance...
std::array< double, 3 > domain_size
Domain size in each dimension.
static std::shared_ptr< spdlog::logger > logger
Publically accessible shared pointer to the logger.
Definition: Logger.h:35
std::vector< std::shared_ptr< PairwiseForceSource > > pairwise_forces
Pairwise Forces to be applied to the particles.
size_t num_particles
Number of particles in the simulation.
double delta_t
Time step of a single simulation iteration.
std::vector< std::shared_ptr< SimulationInterceptor > > interceptors
List of interceptors to be used in the simulation.
bool fresh
Flag to indicate whether the simulation should be run from scratch, or whether cached data should be ...
std::filesystem::path output_dir_path
Path to the directory in which to save the simulation output.
SimulationParams(const std::filesystem::path &input_file_path, double delta_t, double end_time, const std::variant< DirectSumType, LinkedCellsType > &container_type, const std::vector< std::shared_ptr< SimulationInterceptor >> &interceptors, const std::vector< std::shared_ptr< SimpleForceSource >> &simple_forces, const std::vector< std::shared_ptr< PairwiseForceSource >> &pairwise_forces, const std::vector< std::shared_ptr< TargettedForceSource >> &targetted_forces, bool fresh=false, const std::filesystem::path &base_path="./output", size_t start_iteration=0)
Construct a new SimulationParams object.
std::filesystem::path input_file_path
Path to the input file of the simulation.
std::size_t input_file_hash
Hash of the input file of the simulation.
size_t start_iteration
Start iteration of the simulation.
std::vector< std::shared_ptr< SimpleForceSource > > simple_forces
Simple Forces to be applied to the particles.
void logSummary(int depth=0) const
Prints a summary of the simulation parameters to the console.
std::variant< DirectSumType, LinkedCellsType > container_type
Type of the particle container.
double end_time
End time of the simulation.