137 Logger::logger->info(
"Constructing configuration for file {} at depth {}", curr_file_path.string(), depth);
139 auto settings = config.settings();
140 auto particle_sources = config.particle_source();
144 std::vector<Particle> particles;
152 auto params =
SimulationParams{curr_file_path, settings.
delta_t(), settings.end_time(), container_type, interceptors,
153 std::get<0>(forces), std::get<1>(forces), std::get<2>(forces), fresh, output_base_path};
155 if (output_base_path.empty()) {
156 output_base_path = params.output_dir_path;
159 auto curr_folder = std::filesystem::path(curr_file_path).parent_path().string();
161 bool load_in_spawners =
true;
165 if (latest_checkpoint_path.has_value()) {
166 Logger::logger->warn(
"Found checkpoint file {}", latest_checkpoint_path.value().string());
168 Logger::logger->warn(
" [y] Continue from checkpoint [n] Start from scratch");
173 if (std::cin.fail() || std::cin.eof()) {
178 if (answer !=
'y' && answer !=
'n') {
189 params.start_iteration = end_iteration;
190 load_in_spawners =
false;
192 Logger::logger->warn(
"Continuing from checkpoint file {} with iteration {}", latest_checkpoint_path.value().string(),
193 params.start_iteration);
198 Logger::logger->warn(
"Error: No valid checkpoint file found in output directory {}", params.output_dir_path.string());
201 if (load_in_spawners) {
203 for (
auto cuboid_spawner : particle_sources.cuboid_spawner()) {
205 int num_spawned = spawner.spawnParticles(particles);
206 Logger::logger->info(
"Spawned {} particles from cuboid spawner", num_spawned);
209 for (
auto soft_body_cuboid_spawner : particle_sources.soft_body_cuboid_spawner()) {
211 if (std::holds_alternative<SimulationParams::LinkedCellsType>(container_type)) {
212 auto container = std::get<SimulationParams::LinkedCellsType>(container_type);
213 if (std::find(container.boundary_conditions.begin(), container.boundary_conditions.end(),
220 int num_spawned = spawner.spawnParticles(particles);
221 Logger::logger->info(
"Spawned {} particles from soft body cuboid spawner", num_spawned);
224 for (
auto sphere_spawner : particle_sources.sphere_spawner()) {
226 int num_spawned = spawner.spawnParticles(particles);
227 Logger::logger->info(
"Spawned {} particles from sphere spawner", num_spawned);
230 for (
auto single_particle_spawner : particle_sources.single_particle_spawner()) {
232 int num_spawned = spawner.spawnParticles(particles);
233 Logger::logger->info(
"Spawned {} particles from single particle spawner", num_spawned);
236 for (
auto check_point_loader : particle_sources.check_point_loader()) {
237 auto path =
convertToPath(curr_folder, std::filesystem::path(std::string(check_point_loader.path())));
241 for (
auto sub_simulation : particle_sources.sub_simulation()) {
242 if (!allow_recursion) {
243 Logger::logger->warn(
"Error: Recursion is disabled. Skipping sub simulation at depth {}", depth);
247 auto name = std::filesystem::path(std::string(sub_simulation.path())).stem().string();
249 Logger::logger->info(
"Found sub simulation {} at depth {}", name, depth);
251 std::filesystem::path new_output_base_path = output_base_path /
sanitizePath(name);
257 if (checkpoint_path.has_value()) {
259 "Using cached result for sub simulation {} at depth {}. To force a rerun, delete the checkpoint file at {}", name,
260 depth, checkpoint_path.value().string());
263 if (!checkpoint_path.has_value()) {
264 Logger::logger->info(
"Starting sub simulation {} at depth {}", name, depth);
267 auto [loaded_config, file_name] =
loadConfig(sub_simulation, curr_file_path, curr_folder);
270 auto [sub_particles, sub_config] =
271 prepareParticles(file_name, loaded_config, fresh, allow_recursion, new_output_base_path, depth + 1);
272 sub_config.output_dir_path = new_output_base_path;
275 Simulation simulation{sub_particles, sub_config};
277 sub_config.logSummary(depth);
284 checkpoint_path = file_output_handler.writeFile(result.total_iterations, result.resulting_particles);
286 Logger::logger->info(
"Wrote {} particles to checkpoint file in: {}", result.resulting_particles.size(),
287 (*checkpoint_path).string());
295 if (settings.log_level()) {
299 params.num_particles = particles.size();
301 return std::make_tuple(particles, std::move(params));
ThirdDimension
Enum class to define the dimension count of the simulation (2D or 3D). Affects primarily the dimensio...
auto loadConfig(const SubSimulationType &sub_simulation, const std::filesystem::path &curr_file_path, const std::filesystem::path &base_path)
int loadCheckpointFile(std::vector< Particle > &particles, const std::filesystem::path &path)
std::tuple< std::vector< Particle >, SimulationParams > prepareParticles(std::filesystem::path curr_file_path, ConfigurationType &config, bool fresh, bool allow_recursion, std::filesystem::path output_base_path="", int depth=0)
std::filesystem::path sanitizePath(const std::string &text)
std::optional< std::filesystem::path > loadLatestValidCheckpointFromFolder(const std::filesystem::path &base_path)
Wrapper class to abstract the writing of output files.
static void update_level(std::string &log_level)
Sets the log level of the logger.
void logSummary(int depth=0) const
Prints a summary of the simulation overview to the logger.
Contains all parameters needed to run a simulation.
double delta_t
Time step of a single simulation iteration.
Class to run a simulation.
SimulationOverview runSimulation()
Runs the simulation, using the parameters given at construction and returns a SimulationOverview obje...
static SoftBodyCuboidSpawner convertToSoftBodyCuboidSpawner(const SoftBodySpawnerType &soft_body_cuboid, ThirdDimension third_dimension)
Converts a soft body cuboid from the XSD format to the internal format.
static SphereSpawner convertToSphereSpawner(const SphereSpawnerType &sphere, ThirdDimension third_dimension)
Converts a sphere from the XSD format to the internal format.
static std::tuple< std::vector< std::shared_ptr< SimpleForceSource > >, std::vector< std::shared_ptr< PairwiseForceSource > >, std::vector< std::shared_ptr< TargettedForceSource > > > convertToForces(const ForcesType &forces, const std::variant< SimulationParams::DirectSumType, SimulationParams::LinkedCellsType > &container_data)
Converts a force type from the XSD format to the internal format.
static std::variant< SimulationParams::DirectSumType, SimulationParams::LinkedCellsType > convertToParticleContainer(const ParticleContainerType &container_type)
Converts a container type from the XSD format to the internal format.
static CuboidSpawner convertToSingleParticleSpawner(const SingleParticleSpawnerType &particle, ThirdDimension third_dimension)
Converts a particle from the XSD format to the internal format.
static std::vector< std::shared_ptr< SimulationInterceptor > > convertToSimulationInterceptors(const SimulationInterceptorsType &interceptors, ThirdDimension third_dimension, std::variant< SimulationParams::DirectSumType, SimulationParams::LinkedCellsType > container_type)
Converts the simulation interceptors from the XSD format to the internal format.
static CuboidSpawner convertToCuboidSpawner(const CuboidSpawnerType &cuboid, ThirdDimension third_dimension)
Converts a cuboid from the XSD format to the internal format.