25 auto lower_left_front_corner =
convertToVector(cuboid.lower_left_front_corner());
29 auto grid_spacing = cuboid.grid_spacing();
30 auto mass = cuboid.mass();
31 auto type = cuboid.type();
32 auto epsilon = cuboid.epsilon();
33 auto sigma = cuboid.sigma();
34 auto temperature = cuboid.temperature();
37 if (grid_dimensions[0] <= 0 || grid_dimensions[1] <= 0 || grid_dimensions[2] <= 0) {
39 throw std::runtime_error(
"Cuboid grid dimensions must be positive");
43 Logger::logger->error(
"Cuboid grid dimensions must be 1 in z direction if third dimension is disabled");
44 throw std::runtime_error(
"Cuboid grid dimensions must be 1 in z direction if third dimension is disabled");
47 if (grid_spacing <= 0) {
49 throw std::runtime_error(
"Cuboid grid spacing must be positive");
54 throw std::runtime_error(
"Cuboid mass must be positive");
57 if (temperature < 0) {
59 throw std::runtime_error(
"Cuboid temperature must be positive");
63 lower_left_front_corner, grid_dimensions, grid_spacing, mass, initial_velocity,
static_cast<int>(type), epsilon, sigma, lock_state,
64 third_dimension, temperature};
69 auto lower_left_front_corner =
convertToVector(soft_body_cuboid.lower_left_front_corner());
73 auto grid_spacing = soft_body_cuboid.grid_spacing();
74 auto mass = soft_body_cuboid.mass();
75 auto type = soft_body_cuboid.type();
76 auto spring_constant = soft_body_cuboid.spring_constant();
77 auto epsilon = soft_body_cuboid.epsilon();
78 auto sigma = soft_body_cuboid.sigma();
79 auto temperature = soft_body_cuboid.temperature();
81 if (grid_dimensions[0] <= 0 || grid_dimensions[1] <= 0 || grid_dimensions[2] <= 0) {
83 throw std::runtime_error(
"Cuboid grid dimensions must be positive");
87 Logger::logger->error(
"Cuboid grid dimensions must be 1 in z direction if third dimension is disabled");
88 throw std::runtime_error(
"Cuboid grid dimensions must be 1 in z direction if third dimension is disabled");
91 if (grid_spacing <= 0) {
93 throw std::runtime_error(
"Cuboid grid spacing must be positive");
98 throw std::runtime_error(
"Cuboid mass must be positive");
101 if (temperature < 0) {
103 throw std::runtime_error(
"Cuboid temperature must be positive");
107 initial_velocity,
static_cast<int>(type), epsilon, sigma,
108 spring_constant, third_dimension, temperature};
115 auto radius = sphere.radius();
116 auto grid_spacing = sphere.grid_spacing();
117 auto mass = sphere.mass();
118 auto type = sphere.type();
119 auto epsilon = sphere.epsilon();
120 auto sigma = sphere.sigma();
121 auto temperature = sphere.temperature();
126 throw std::runtime_error(
"Sphere radius must be positive");
129 if (grid_spacing <= 0) {
131 throw std::runtime_error(
"Sphere grid spacing must be positive");
136 throw std::runtime_error(
"Sphere mass must be positive");
139 if (temperature < 0) {
141 throw std::runtime_error(
"Sphere temperature must be positive");
144 return SphereSpawner{center,
static_cast<int>(radius), grid_spacing, mass, initial_velocity,
static_cast<int>(type), epsilon, sigma,
145 lock_state, third_dimension, temperature};
153 auto mass = particle.mass();
154 auto type = particle.type();
155 auto epsilon = particle.epsilon();
156 auto sigma = particle.sigma();
164 static_cast<int>(type),
169 particle.temperature()};
173 const SimulationInterceptorsType& interceptors,
ThirdDimension third_dimension,
174 std::variant<SimulationParams::DirectSumType, SimulationParams::LinkedCellsType> container_type) {
175 std::vector<std::shared_ptr<SimulationInterceptor>> simulation_interceptors;
177 for (
auto frame_writer : interceptors.FrameWriter()) {
178 auto fps = frame_writer.fps();
179 auto video_length = frame_writer.video_length_s();
182 simulation_interceptors.push_back(std::make_shared<FrameWriterInterceptor>(output_format, fps, video_length));
185 for (
auto xsd_thermostat : interceptors.Thermostat()) {
186 auto target_temperature = xsd_thermostat.target_temperature();
187 auto max_temperature_change = xsd_thermostat.max_temperature_change();
188 auto application_interval = xsd_thermostat.application_interval();
190 std::shared_ptr<Thermostat> thermostat;
192 if (xsd_thermostat.type() == ThermostatType::value::absolute) {
193 thermostat = std::make_shared<AbsoluteThermostat>(target_temperature, max_temperature_change, third_dimension);
194 }
else if (xsd_thermostat.type() == ThermostatType::value::relative_motion) {
195 thermostat = std::make_shared<RelativeThermostat>(target_temperature, max_temperature_change, third_dimension);
198 throw std::runtime_error(
"Thermostat type not implemented");
201 simulation_interceptors.push_back(std::make_shared<ThermostatInterceptor>(thermostat, application_interval));
203 if (xsd_thermostat.temperature_sensor()) {
204 auto temperature_sensor = *xsd_thermostat.temperature_sensor();
205 auto sample_every_x_percent = temperature_sensor.sample_every_x_percent();
207 simulation_interceptors.push_back(std::make_shared<TemperatureSensorInterceptor>(thermostat, sample_every_x_percent));
211 if (interceptors.ParticleUpdatesPerSecond().size() > 0) {
212 simulation_interceptors.push_back(std::make_shared<ParticleUpdateCounterInterceptor>());
215 for (
auto diffusion_function : interceptors.DiffusionFunction()) {
216 auto sample_every_x_percent = diffusion_function.sample_every_x_percent();
217 simulation_interceptors.push_back(std::make_shared<DiffusionFunctionInterceptor>(sample_every_x_percent));
220 for (
auto xsd_rdf : interceptors.RadialDistributionFunction()) {
221 auto bin_width = xsd_rdf.bin_width();
222 auto sample_every_x_percent = xsd_rdf.sample_every_x_percent();
224 simulation_interceptors.push_back(std::make_shared<RadialDistributionFunctionInterceptor>(bin_width, sample_every_x_percent));
227 for (
auto xsd_vp : interceptors.VelocityProfile()) {
228 auto num_bins = xsd_vp.num_bins();
229 auto sample_every_x_percent = xsd_vp.sample_every_x_percent();
231 auto box_xsd = xsd_vp.box();
233 std::pair<std::array<double, 3>, std::array<double, 3>> box;
235 if (box_xsd.present()) {
236 auto box_data = *box_xsd;
238 auto bottom_left =
convertToVector(box_data.lower_left_front_corner());
241 box = std::make_pair(bottom_left, top_right);
244 [&box](
auto&& container) {
246 Logger::logger->error(
"Box must be specified if direct sum is used");
247 throw std::runtime_error(
"Box must be specified if direct sum is used");
249 auto bottom_left = std::array<double, 3>{0, 0, 0};
250 auto top_right = container.domain_size;
252 box = std::make_pair(bottom_left, top_right);
255 throw std::runtime_error(
"Container type not implemented");
261 simulation_interceptors.push_back(std::make_shared<VelocityProfileInterceptor>(box, num_bins, sample_every_x_percent));
264 simulation_interceptors.push_back(std::make_shared<ProgressBarInterceptor>());
266 return simulation_interceptors;
270 const ParticleContainerType& particle_container) {
271 std::variant<SimulationParams::DirectSumType, SimulationParams::LinkedCellsType> container;
273 if (particle_container.linkedcells_container().present()) {
274 auto container_data = *particle_container.linkedcells_container();
277 auto cutoff_radius = container_data.cutoff_radius();
281 }
else if (particle_container.directsum_container().present()) {
285 throw std::runtime_error(
"Container type not implemented");
292 const BoundaryConditionsType& boundary) {
293 std::array<LinkedCellsContainer::BoundaryCondition, 6> boundary_conditions;
302 return boundary_conditions;
307 case BoundaryType::value::Outflow:
309 case BoundaryType::value::Reflective:
311 case BoundaryType::value::Periodic:
315 throw std::runtime_error(
"Boundary condition not implemented");
324 auto type = particle.type();
325 auto mass = particle.mass();
326 auto epsilon = particle.epsilon();
327 auto sigma = particle.sigma();
332 throw std::runtime_error(
"Particle mass must be positive");
335 Particle output_particle{position, velocity, force, old_force, mass,
static_cast<int>(type), epsilon, sigma, lock_state};
337 for (
const auto& entry : particle.connected_particles().entries()) {
338 output_particle.
addConnectedParticle(entry.pointer_diff(), entry.rest_length(), entry.spring_constant());
341 return output_particle;
344 std::tuple<std::vector<std::shared_ptr<SimpleForceSource>>, std::vector<std::shared_ptr<PairwiseForceSource>>,
345 std::vector<std::shared_ptr<TargettedForceSource>>>
347 const ForcesType& forces,
const std::variant<SimulationParams::DirectSumType, SimulationParams::LinkedCellsType>& container_data) {
348 std::vector<std::shared_ptr<SimpleForceSource>> simple_force_sources;
349 std::vector<std::shared_ptr<PairwiseForceSource>> pairwise_force_sources;
350 std::vector<std::shared_ptr<TargettedForceSource>> targetted_force_sources;
353 if (forces.GlobalDownwardsGravity()) {
354 auto g = (*forces.GlobalDownwardsGravity()).g();
355 simple_force_sources.push_back(std::make_shared<GlobalDownwardsGravity>(g));
357 if (forces.HarmonicPotential()) {
358 simple_force_sources.push_back(std::make_shared<HarmonicForce>(container_data));
362 if (forces.LennardJones()) {
363 pairwise_force_sources.push_back(std::make_shared<LennardJonesForce>());
365 if (forces.LennardJonesRepulsive()) {
366 pairwise_force_sources.push_back(std::make_shared<LennardJonesRepulsiveForce>());
368 if (forces.SmoothedLennardJones()) {
369 double r_c = (*forces.SmoothedLennardJones()).r_c();
370 double r_l = (*forces.SmoothedLennardJones()).r_l();
371 pairwise_force_sources.push_back(std::make_shared<SmoothedLennardJonesForce>(r_c, r_l));
373 if (forces.Gravitational()) {
374 pairwise_force_sources.push_back(std::make_shared<GravitationalForce>());
378 if (forces.TargettedTemporaryConstant()) {
379 auto indices_list = forces.TargettedTemporaryConstant()->indices();
380 std::vector<size_t> indices_vector;
381 for (
auto& index : indices_list) {
382 indices_vector.push_back(index);
384 auto force =
convertToVector(forces.TargettedTemporaryConstant()->force());
385 auto start_time = forces.TargettedTemporaryConstant()->start_time();
386 auto end_time = forces.TargettedTemporaryConstant()->end_time();
388 targetted_force_sources.push_back(std::make_shared<TargettedTemporaryConstantForce>(indices_vector, force, start_time, end_time));
391 return {simple_force_sources, pairwise_force_sources, targetted_force_sources};
395 return {vector.x(), vector.y(), vector.z()};
ThirdDimension
Enum class to define the dimension count of the simulation (2D or 3D). Affects primarily the dimensio...
LockState
Enum class to define the lockstate of particles. Locked particles are not allowed to move.
Class to spawn particles in a cuboid. Implements the interface ParticleSpawner.
BoundaryCondition
Boundary type enum for labeling the sides of the domain.
static std::shared_ptr< spdlog::logger > logger
Publically accessible shared pointer to the logger.
Class to represent a particle.
void addConnectedParticle(long ptr_diff, double l_0, double k)
Adds a connected particle.
Class to spawn particles of a soft body in a cuboid. Implements the interface ParticleSpawner.
Class to spawn particles in a Sphere. Implements the interface ParticleSpawner.
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 LinkedCellsContainer::BoundaryCondition convertToBoundaryCondition(const BoundaryType &boundary)
Converts a boundary 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 std::array< LinkedCellsContainer::BoundaryCondition, 6 > convertToBoundaryConditionsArray(const BoundaryConditionsType &boundary)
Converts a boundary conditions type from the XSD format to the internal format.
static Particle convertToParticle(const ParticleType &particle)
Converts a particle 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::array< double, 3 > convertToVector(const DoubleVec3Type &vector)
Converts a double vector 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.
Struct to specify the type of the particle container as DirectSumType.
Struct to specify the type of the particle container as LinkedCellsType (needs domain_size and cutoff...