1 #pragma once
2
3 /// \file Settings.h
4 /// \brief Generic storage and input/output routines of settings.
5 /// \author Pavel Sevecek (sevecek at sirrah.troja.mff.cuni.cz)
6 /// \date 2016-2021
7
8 #include "objects/Exceptions.h"
9 #include "objects/geometry/TracelessTensor.h"
10 #include "objects/utility/EnumMap.h"
11 #include "objects/wrappers/ClonePtr.h"
12 #include "objects/wrappers/Expected.h"
13 #include "objects/wrappers/Flags.h"
14 #include "objects/wrappers/Interval.h"
15 #include "objects/wrappers/Outcome.h"
16 #include "objects/wrappers/Variant.h"
17 #include <typeinfo>
18
19 NAMESPACE_SPH_BEGIN
20
21 class Path;
22
23 template <typename TEnum>
24 class Settings;
25
26 template <typename TEnum>
27 class SettingsIterator;
28
29 /// Tag for initialization of empty settings object.
30 struct EmptySettingsTag {};
31
32 const EmptySettingsTag EMPTY_SETTINGS;
33
34 /// \brief Wrapper of an enum.
35 ///
36 /// Used to store an enum in settings while keeping the type safety.
37 struct EnumWrapper {
38 int value = 0;
39
40 EnumIndex index = NOTHING;
41
42 EnumWrapper() = default;
43
44 template <typename TEnum>
EnumWrapperEnumWrapper45 explicit EnumWrapper(TEnum e)
46 : value(int(e))
47 , index(typeid(TEnum)) {
48 static_assert(std::is_enum<TEnum>::value, "Can be used only for enums");
49 }
50
EnumWrapperEnumWrapper51 EnumWrapper(const int value, const EnumIndex& index)
52 : value(value)
53 , index(index) {}
54
55 explicit operator int() const {
56 return value;
57 }
58
59 template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
TEnumWrapper60 explicit operator T() const {
61 SPH_ASSERT(std::type_index(typeid(T)) == index);
62 return T(value);
63 }
64
65 bool operator==(const EnumWrapper& other) const {
66 return value == other.value && index == other.index;
67 }
68
69 template <typename TStream>
70 friend TStream& operator<<(TStream& ofs, const EnumWrapper& e) {
71 ofs << e.value << " (" << (e.index ? e.index->hash_code() : 0) << ")";
72 return ofs;
73 }
74 };
75
76 /// \brief Exception thrown on invalid access to entries of a \ref Settings object.
77 class InvalidSettingsAccess : public Exception {
78 public:
79 template <typename TEnum>
InvalidSettingsAccess(const TEnum key)80 explicit InvalidSettingsAccess(const TEnum key)
81 : Exception("Error accessing parameter '" +
82 Settings<TEnum>::getEntryName(key).valueOr("unknown parameter") + "'") {
83 static_assert(std::is_enum<TEnum>::value, "InvalidSettingsAccess can only be used with enums");
84 }
85 };
86
87 template <typename TEnum>
checkSettingsAccess(const bool result,const TEnum key)88 INLINE void checkSettingsAccess(const bool result, const TEnum key) {
89 if (!result) {
90 throw InvalidSettingsAccess(key);
91 }
92 }
93
94 /// \brief Generic object containing various settings and parameters of the run.
95 ///
96 /// Settings is a storage containing pairs key-value objects, where key is one of predefined enums. The value
97 /// can have multiple types within the same \ref Settings object. Currently following types can be stored:
98 /// bool, int, enums, float (or double), String, \ref Interval, \ref Vector, \ref SymmetricTensor, \ref
99 /// TracelessTensor.
100 ///
101 /// The template cannot be used directly as it is missing default values of parameters; instead
102 /// specializations for specific enums should be used. The code defines two base specializations:
103 /// - \ref BodySettings (specialization with enum \ref BodySettingsId)
104 /// - \ref RunSettings (specialization with enum \ref RunSettingsId)
105 template <typename TEnum>
106 class Settings {
107 template <typename>
108 friend class SettingsIterator;
109
110 private:
111 /// \brief List of types that can be stored in settings
112 enum Types {
113 BOOL,
114 INT,
115 FLOAT,
116 INTERVAL,
117 STRING,
118 VECTOR,
119 SYMMETRIC_TENSOR,
120 TRACELESS_TENSOR,
121 ENUM,
122 };
123
124 /// \brief Storage type of settings entries.
125 ///
126 /// Order of types in the variant must correspond to the values in enum \ref Types. It is possible to add
127 /// other types to the settings, but always to the END of the variant to keep the backwards compatibility
128 /// of serializer.
129 ///
130 /// \todo Possibly refactor by using some polymorphic holder (Any-type) rather than variant, this will
131 /// allow to add more types for other Settings specializations (GuiSettings, etc.)
132 using Value =
133 Variant<bool, int, Float, Interval, String, Vector, SymmetricTensor, TracelessTensor, EnumWrapper>;
134
135 struct Entry {
136 /// Index of the property
137 TEnum id;
138
139 /// Unique text identifier of the property
140 String name;
141
142 /// Current value
143 Value value;
144
145 /// Description of the property. Can be empty.
146 String desc;
147
148 Entry() = default;
149
150 Entry(TEnum id, const String& name, const Value& value, const String& desc = "")
idEntry151 : id(id)
152 , name(name)
153 , value(value)
154 , desc(desc) {}
155
156 template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
157 Entry(TEnum id, const String& name, const T& value, const String& desc = "")
idEntry158 : id(id)
159 , name(name)
160 , value(EnumWrapper(value))
161 , desc(desc) {}
162
163 template <typename T>
164 Entry(TEnum id, const String& name, Flags<T> flags, const String& desc = "")
idEntry165 : id(id)
166 , name(name)
167 , value(EnumWrapper(T(flags.value())))
168 , desc(desc) {}
169
170 template <typename T>
171 INLINE bool hasType(std::enable_if_t<!std::is_enum<T>::value, int> = 0) const {
172 return value.has<T>();
173 }
174
175 template <typename T>
176 INLINE bool hasType(std::enable_if_t<std::is_enum<T>::value, int> = 0) const {
177 return value.has<EnumWrapper>() && value.get<EnumWrapper>().index == std::type_index(typeid(T));
178 }
179 };
180
181 FlatMap<TEnum, Entry> entries;
182
183 public:
184 /// \brief Initialize settings by settings all value to their defaults.
185 Settings();
186
187 /// Constructs settings from list of key-value pairs.
188 Settings(std::initializer_list<Entry> list);
189
190 /// \brief Initialize empty settings object.
191 Settings(EmptySettingsTag);
192
193 Settings(const Settings& other);
194
195 Settings(Settings&& other);
196
197 /// \brief Assigns a list of settings into the object, erasing all previous entries.
198 Settings& operator=(std::initializer_list<Entry> list);
199
200 Settings& operator=(const Settings& other);
201
202 Settings& operator=(Settings&& other);
203
204 /// \brief Saves a value into the settings.
205 ///
206 /// Any previous value of the same ID is overriden.
207 /// \tparam TValue Type of the value to be saved. Does not have to be specified, type deduction can be
208 /// used to determine it. Must be one of types listed in object description. Using other
209 /// types will result in compile error.
210 /// \param idx Key identifying the value. This key can be used to retrive the value later.
211 /// \param value Value being stored into settings.
212 /// \returns Reference to the settings object, allowing to queue multiple set functions.
213 /// \throw InvalidSettingsAccess if settings value of different type than the one currently stored.
214 template <typename TValue>
215 Settings& set(const TEnum idx,
216 TValue&& value,
217 std::enable_if_t<!std::is_enum<std::decay_t<TValue>>::value, int> = 0) {
218 Optional<Entry&> entry = entries.tryGet(idx);
219 if (!entry) {
220 Entry& newEntry = entries.insert(idx, Entry{});
221 newEntry.value = std::forward<TValue>(value);
222 } else {
223 checkSettingsAccess(entry->template hasType<std::decay_t<TValue>>(), idx);
224 entry->value = std::forward<TValue>(value);
225 }
226 return *this;
227 }
228
229 /// \copydoc set
230 template <typename TValue>
231 Settings& set(const TEnum idx,
232 TValue&& value,
233 std::enable_if_t<std::is_enum<std::decay_t<TValue>>::value, int> = 0) {
234 Optional<Entry&> entry = entries.tryGet(idx);
235 if (!entry) {
236 Entry& newEntry = entries.insert(idx, Entry{});
237 newEntry.value = EnumWrapper(value);
238 } else {
239 checkSettingsAccess(entry->template hasType<std::decay_t<TValue>>(), idx);
240 entry->value = EnumWrapper(value);
241 }
242 return *this;
243 }
244
245 /// \brief Saves flags into the settings.
246 ///
247 /// Flags are not considered as a different type, they are internally saved as enum wrapper.
248 /// \returns Reference to the settings object.
249 /// \throw InvalidSettingsAccess if settings value of different type than the one currently stored.
250 template <typename TValue, typename = std::enable_if_t<std::is_enum<TValue>::value>>
set(const TEnum idx,const Flags<TValue> flags)251 Settings& set(const TEnum idx, const Flags<TValue> flags) {
252 return this->set(idx, EnumWrapper(TValue(flags.value())));
253 }
254
255 /// \brief Clear flags of given parameter in settings.
256 ///
257 /// This function can be used only if the value is already stored in the settings.
258 /// \returns Reference to the settings object.
259 /// \throw InvalidSettingsAccess if the value is not stored or has a different type.
set(const TEnum idx,EmptyFlags)260 Settings& set(const TEnum idx, EmptyFlags) {
261 Optional<Entry&> entry = entries.tryGet(idx);
262 checkSettingsAccess(entry && entry->value.template has<EnumWrapper>(), idx);
263 entry->value.template get<EnumWrapper>().value = 0;
264 return *this;
265 }
266
267 /// \brief Special setter for value of type EnumWrapper.
268 ///
269 /// While usually the enum can be stored directly, this overload is useful for deserialization, etc.
270 /// \returns Reference to the settings object.
271 /// \throw InvalidSettingsAccess if settings value of different type than the one currently stored.
set(const TEnum idx,const EnumWrapper ew)272 Settings& set(const TEnum idx, const EnumWrapper ew) {
273 Optional<Entry&> entry = entries.tryGet(idx);
274 if (entry) {
275 Optional<EnumWrapper> current = entry->value.template tryGet<EnumWrapper>();
276 checkSettingsAccess(current && current->index == ew.index, idx);
277 }
278 this->set(idx, ew, 0); // zero needed to call the other overload
279 return *this;
280 }
281
282 /// \brief Adds entries from different \ref Settings object into this one, overriding current entries.
283 ///
284 /// Entries not stored in the given settings are kept unchanged.
285 /// \throw InvalidSettingsAccess if the settings share entries that differ in type.
addEntries(const Settings & settings)286 void addEntries(const Settings& settings) {
287 for (const typename SettingsIterator<TEnum>::IteratorValue& iv : settings) {
288 Optional<Entry&> entry = entries.tryGet(iv.id);
289 if (!entry) {
290 Entry& newEntry = entries.insert(iv.id, getDefaults().entries[iv.id]);
291 newEntry.value = iv.value;
292 } else {
293 checkSettingsAccess(entry->value.getTypeIdx() == iv.value.getTypeIdx(), iv.id);
294 entry->value = iv.value;
295 }
296 }
297 }
298
299 /// \brief Removes given parameter from settings.
300 ///
301 /// If the parameter is not in settings, nothing happens (it isn't considered as an error).
unset(const TEnum idx)302 void unset(const TEnum idx) {
303 entries.tryRemove(idx);
304 }
305
306 /// \brief Returns a value of given type from the settings.
307 ///
308 /// Value must be stored in settings and must have corresponding type.
309 /// \tparam TValue Type of the value we wish to return. This type must match the type of the saved
310 /// quantity.
311 /// \param idx Key of the value.
312 /// \returns Value correponsing to given key.
313 /// \throw InvalidSettingsAccess if value is not stored in the settings or has a different type.
314 template <typename TValue>
315 TValue get(const TEnum idx, std::enable_if_t<!std::is_enum<std::decay_t<TValue>>::value, int> = 0) const {
316 Optional<const Entry&> entry = entries.tryGet(idx);
317 checkSettingsAccess(entry && entry->value.template has<TValue>(), idx);
318
319 return entry->value.template get<TValue>();
320 }
321
322 /// \copydoc get
323 template <typename TValue>
324 TValue get(const TEnum idx, std::enable_if_t<std::is_enum<std::decay_t<TValue>>::value, int> = 0) const {
325 Optional<const Entry&> entry = entries.tryGet(idx);
326 checkSettingsAccess(entry && entry->value.template has<EnumWrapper>(), idx);
327
328 const EnumWrapper wrapper = entry->value.template get<EnumWrapper>();
329 checkSettingsAccess(wrapper.index == std::type_index(typeid(TValue)), idx);
330 return TValue(wrapper.value);
331 }
332
333 /// \brief Returns Flags from underlying value stored in settings.
334 ///
335 /// Syntactic suggar, avoid cumbersome conversion to underlying type and then to Flags.
336 template <typename TValue>
getFlags(const TEnum idx)337 Flags<TValue> getFlags(const TEnum idx) const {
338 static_assert(std::is_enum<TValue>::value, "Can be only used for enums");
339 TValue value = this->get<TValue>(idx);
340 return Flags<TValue>::fromValue(std::underlying_type_t<TValue>(value));
341 }
342
343 /// \brief Returns the human-readable name of the entry with given index.
344 ///
345 /// If the index does not correspond to any parameter, returns string NOTHING.
getEntryName(const TEnum idx)346 static Optional<String> getEntryName(const TEnum idx) {
347 const Settings& settings = getDefaults();
348 Optional<const Entry&> entry = settings.entries.tryGet(idx);
349 if (entry) {
350 return entry->name;
351 } else {
352 // idx might be invalid if loaded from older config file
353 return NOTHING;
354 }
355 }
356
357 /// \brief Returns the type of the entry with given index.
358 ///
359 /// If the index does not correspond to any parameter, returns NOTHING.
getEntryType(const TEnum idx)360 static Optional<int> getEntryType(const TEnum idx) {
361 const Settings& settings = getDefaults();
362 Optional<const Entry&> entry = settings.entries.tryGet(idx);
363 if (entry) {
364 return entry->value.getTypeIdx();
365 } else {
366 return NOTHING;
367 }
368 }
369
370 /// \brief Returns the string name for given type index.
371 ///
372 /// \throw Exception for unknown type index
373 static String typeToString(const int type);
374
375 /// \brief Returns a description of the entry with given index.
376 ///
377 /// If the index does not correspond to any parameter, returns string NOTHING.
getEntryDesc(const TEnum idx)378 static Optional<String> getEntryDesc(const TEnum idx) {
379 const Settings& settings = getDefaults();
380 Optional<const Entry&> entry = settings.entries.tryGet(idx);
381 if (entry) {
382 return entry->desc;
383 } else {
384 // idx might be invalid if loaded from older config file
385 return NOTHING;
386 }
387 }
388
389 /// \brief Returns an ID for given entry name.
390 ///
391 /// This is the inverse of function \ref getEntryName.
getEntryId(const String & name)392 static Optional<TEnum> getEntryId(const String& name) {
393 const Settings& settings = getDefaults();
394 for (const auto& p : settings.entries) {
395 if (p.value().name == name) {
396 return p.key();
397 }
398 }
399 return NOTHING;
400 }
401
402 /// \brief Checks if the given entry is stored in the settings.
has(const TEnum idx)403 bool has(const TEnum idx) const {
404 return entries.contains(idx);
405 }
406
407 /// \brief Checks if the given entry has specified type.
408 ///
409 /// \throw InvalidSettingsAccess if the entry is not in settings.
410 template <typename TValue>
hasType(const TEnum idx)411 bool hasType(const TEnum idx) const {
412 Optional<const Entry&> entry = entries.tryGet(idx);
413 checkSettingsAccess(bool(entry), idx);
414 return entry->value.template has<TValue>();
415 }
416
417 /// \brief Saves all values stored in settings into file.
418 ///
419 /// \param path Path (relative or absolute) to the file. The file will be created, any previous
420 /// content will be overriden.
421 /// \returns SUCCESS if the file has been correctly written, otherwise returns encountered error.
422 Outcome saveToFile(const Path& path) const;
423
424 /// \brief Loads the settings from file.
425 ///
426 /// Previous values stored in settings are removed. The file must have a valid settings format.
427 /// \param path Path to the file. The file must exist.
428 /// \returns SUCCESS if the settings were correctly parsed from the file, otherwise returns encountered
429 /// error.
430 Outcome loadFromFile(const Path& path);
431
432 /// \brief If the specified file exists, loads the settings from it, otherwise creates the file and saves
433 /// the current values.
434 ///
435 /// This is a standard behavior of configuration files used in the simulation. First time the simulation
436 /// is started, the configuration files are created with default values. The files can then be modified by
437 /// the user and the next time simulation is started, the parameters are parsed and used instead of the
438 /// defaults.
439 ///
440 /// For convenience, it is possible to pass a set of overrides, which are used instead of the values
441 /// loaded from the configuration file (or defaults, if the file does not exist). This can be used to
442 /// specify settings as command-line parameters, for example.
443 /// \param path Path to the configuration file.
444 /// \param overrides Set of overrides applied on the current values or after the settings are loaded.
445 /// \returns True if the settings have been successfully loaded, false if the configuration file did not
446 /// exist, in which case the function attempted to create the file using current values (with
447 /// applied overrides).
448 /// \throw Exception if loading of the file failed (invalid content, unknown parameters, ...).
449 ///
450 /// \note Function returns a valid result (false) even if the configuration file cannot be created, for
451 /// example if the directory access is denied. This does not prohibit the simulation in any way, the
452 /// settings object is in valid state.
453 bool tryLoadFileOrSaveCurrent(const Path& path, const Settings& overrides = EMPTY_SETTINGS);
454
455 /// \brief Iterator to the first entry of the settings storage.
456 SettingsIterator<TEnum> begin() const;
457
458 /// \brief Iterator to the one-past-end entry the settings storage.
459 SettingsIterator<TEnum> end() const;
460
461 /// \brief Returns the number of entries in the settings.
462 ///
463 /// This includes default entries in case the object was not constructed with EMPTY_SETTINGS tag.
464 Size size() const;
465
466 /// \\brief Returns a reference to object containing default values of all settings.
467 static const Settings& getDefaults();
468
469 private:
470 bool setValueByType(Entry& entry, const Value& defaultValue, const String& str);
471 };
472
473 /// \brief Returns the default settings.
474 ///
475 /// Needs to be specialized for each TEnum.
476 template <typename TEnum>
477 const Settings<TEnum>& getDefaultSettings();
478
479 /// \brief Iterator useful for iterating over all entries in the settings.
480 template <typename TEnum>
481 class SettingsIterator {
482 private:
483 using ActIterator = Iterator<const typename FlatMap<TEnum, typename Settings<TEnum>::Entry>::Element>;
484
485 ActIterator iter;
486
487 public:
488 /// Constructs an iterator from iternal implementation; use Settings::begin and Settings::end.
489 SettingsIterator(const ActIterator& iter, Badge<Settings<TEnum>>);
490
491 struct IteratorValue {
492 /// ID of settings entry
493 TEnum id;
494
495 /// Variant holding the value of the entry
496 typename Settings<TEnum>::Value value;
497 };
498
499 /// Dereference the iterator, yielding a pair of entry ID and its value.
500 IteratorValue operator*() const;
501
502 /// Moves to next entry.
503 SettingsIterator& operator++();
504
505 /// Equality operator between settings operators.
506 bool operator==(const SettingsIterator& other) const;
507
508 /// Unequality operator between settings operators.
509 bool operator!=(const SettingsIterator& other) const;
510 };
511
512
513 enum class KernelEnum {
514 /// M4 B-spline (piecewise cubic polynomial)
515 CUBIC_SPLINE,
516
517 /// M5 B-spline (piecewise 4th-order polynomial)
518 FOURTH_ORDER_SPLINE,
519
520 /// Gaussian function
521 GAUSSIAN,
522
523 /// Simple triangle (piecewise linear) kernel
524 TRIANGLE,
525
526 /// Core Triangle (CT) kernel by Read et al. (2010)
527 CORE_TRIANGLE,
528
529 /// Modification of the standard M4 B-spline kernel, used to avoid particle clustering
530 THOMAS_COUCHMAN,
531
532 /// Wendland kernel C2
533 WENDLAND_C2,
534
535 /// Wendland kernel C4
536 WENDLAND_C4,
537
538 /// Wendland kernel C6
539 WENDLAND_C6,
540 };
541
542 enum class TimesteppingEnum {
543 /// Explicit (forward) 1st-order integration
544 EULER_EXPLICIT,
545
546 /// Leap-frog 2nd-order integration
547 LEAP_FROG,
548
549 /// Runge-Kutta 4-th order integration
550 RUNGE_KUTTA,
551
552 /// Predictor-corrector scheme
553 PREDICTOR_CORRECTOR,
554
555 /// Modified midpoint method with constant number of substeps
556 MODIFIED_MIDPOINT,
557
558 /// Bulirsch-Stoer integrator
559 BULIRSCH_STOER
560 };
561
562 enum class TimeStepCriterionEnum {
563 /// Time step determined using CFL condition
564 COURANT = 1 << 1,
565
566 /// Time step computed by limiting value-to-derivative ratio of quantiites.
567 DERIVATIVES = 1 << 2,
568
569 /// Time step computed from ratio of acceleration and smoothing length.
570 ACCELERATION = 1 << 3,
571
572 /// Time step computed from velocity divergence
573 DIVERGENCE = 1 << 4,
574
575 /// Value for using all criteria.
576 ALL = COURANT | DERIVATIVES | ACCELERATION | DIVERGENCE,
577 };
578
579 enum class FinderEnum {
580 /// Brute-force search by going through each pair of particles (O(N^2) complexity)
581 BRUTE_FORCE,
582
583 /// Using K-d tree
584 KD_TREE,
585
586 /// Using octree
587 OCTREE,
588
589 /// Using linked list
590 LINKED_LIST,
591
592 /// Partitioning particles into a grid uniform in space
593 UNIFORM_GRID,
594
595 /// Using hash map
596 HASH_MAP,
597 };
598
599 enum class BoundaryEnum {
600 /// Do not use any boundary conditions (= vacuum conditions)
601 NONE,
602
603 /// Highest derivatives of all particles close to the boundary are set to zero.
604 FROZEN_PARTICLES,
605
606 /// Create ghosts to keep particles inside domain.
607 GHOST_PARTICLES,
608
609 /// Creates dummy particles along the boundary.
610 FIXED_PARTICLES,
611
612 /// Extension of Frozen Particles, pushing particles inside the domain and removing them on the other end.
613 WIND_TUNNEL,
614
615 /// Periodic boundary conditions
616 PERIODIC,
617
618 /// Particles are duplicated along the z=0 plane
619 SYMMETRIC,
620
621 /// Removes particles outside the domain
622 KILL_ESCAPERS,
623
624 /// Project all movement onto a line, effectivelly reducing the simulation to 1D
625 PROJECT_1D
626 };
627
628 enum class DomainEnum {
629 /// No computational domain (can only be used with BoundaryEnum::NONE)
630 NONE,
631
632 /// Sphere with given radius
633 SPHERICAL,
634
635 /// Axis-aligned ellipsoid
636 ELLIPSOIDAL,
637
638 /// Block with edge sizes given by vector
639 BLOCK,
640
641 /// Cylindrical domain aligned with z axis
642 CYLINDER,
643
644 /// Gaussian random sphere
645 GAUSSIAN_SPHERE,
646
647 /// Half-space z>0
648 HALF_SPACE,
649 };
650
651 /// List of forces to compute by the solver. This does not include numerical terms, see
652 /// ArtificialViscosityEnum.
653 enum class ForceEnum {
654 /// Use force from pressure gradient in the solver.
655 PRESSURE = 1 << 0,
656
657 /// Use force from stress divergence in the model. Must be used together with PRESSURE_GRADIENT.
658 /// Stress tensor is then evolved in time using Hooke's equation.
659 SOLID_STRESS = 1 << 1,
660
661 /// Stress tensor for the simulation of fluids. Must be used together with PRESSURE_GRADIENT, cannot
662 /// be used together with solid stress force.
663 NAVIER_STOKES = 1 << 2,
664
665 /// Use internal friction given by the viscosity in the material.
666 INTERNAL_FRICTION = 1 << 3,
667
668 /// Use centrifugal force and Coriolis forces given by angular frequency of the coordinate frame.
669 INERTIAL = 1 << 4,
670
671 /// Use gravitational force in the model
672 SELF_GRAVITY = 1 << 5,
673
674 /// Surface force proportional to surface curvature
675 SURFACE_TENSION = 1 << 6,
676 };
677
678 enum class ArtificialViscosityEnum {
679 /// No artificial viscosity
680 NONE,
681
682 /// Standard artificial viscosity term by Monaghan (1989).
683 STANDARD,
684
685 /// Artificial viscosity term analogous to Riemann solvers by Monaghan (1997)
686 RIEMANN,
687
688 /// Time-dependent artificial viscosity by Morris & Monaghan (1997).
689 MORRIS_MONAGHAN,
690 };
691
692 enum class SolverEnum {
693 /// SPH formulation using symmetrized evaluation of derivatives.
694 SYMMETRIC_SOLVER,
695
696 /// Generic solver evaluating all derivatives asymmetrically.
697 ASYMMETRIC_SOLVER,
698
699 /// Density is obtained by direct summation over nearest SPH particles.
700 SUMMATION_SOLVER,
701
702 /// Special solver used to simulate deformations of perfectly elastic bodies
703 ELASTIC_DEFORMATION_SOLVER,
704
705 /// Density independent solver by Saitoh & Makino (2013).
706 DENSITY_INDEPENDENT,
707
708 /// Solver advancing internal energy using pair-wise work done by particles, by Owen (2009).
709 ENERGY_CONSERVING_SOLVER,
710
711 /// Simple solver with pressure gradient only, mainly used for supporting purposes (benchmarking,
712 /// teaching, etc.)
713 SIMPLE_SOLVER,
714 };
715
716 enum class ContinuityEnum {
717 /// Normal continuity equation, using velocity divergence computed from all neighbors.
718 STANDARD,
719
720 /// Computes the velocity divergence using only undamaged neighbors. For fully damaged particle, the
721 /// standard continuity equation is used instead.
722 SUM_ONLY_UNDAMAGED,
723 };
724
725 enum class DiscretizationEnum {
726 /// P_i / rho_i^2 + P_j / rho_j^2
727 STANDARD,
728
729 /// (P_i + P_j) / (rho_i rho_j)
730 BENZ_ASPHAUG,
731 };
732
733 enum class YieldingEnum {
734 /// Gass or material with no stress tensor
735 NONE,
736
737 /// No yielding, just elastic deformations following Hooke's law
738 ELASTIC,
739
740 /// Von Mises criterion
741 VON_MISES,
742
743 /// Drucker-Prager pressure dependent yielding stress
744 DRUCKER_PRAGER,
745
746 /// No stress tensor, only the pressure is limited to positive values.
747 DUST,
748 };
749
750 enum class FractureEnum {
751 /// No fragmentation
752 NONE,
753
754 /// Grady-Kipp model of fragmentation using scalar damage
755 SCALAR_GRADY_KIPP,
756
757 /// Grady-Kipp model of fragmentation using tensor damage
758 TENSOR_GRADY_KIPP
759 };
760
761 enum class SmoothingLengthEnum {
762 /// Smoothing length is evolved using continuity equation
763 CONTINUITY_EQUATION = 1 << 1,
764
765 /// Number of neighbors is kept fixed by adding additional derivatives of smoothing length, scaled by
766 /// local sound speed
767 SOUND_SPEED_ENFORCING = 1 << 2
768 };
769
770 enum class SignalSpeedEnum {
771 /// Signal speed given by the absolute value of pressure difference, as in Price (2008)
772 PRESSURE_DIFFERENCE,
773
774 /// Signal speed given by relative velocity projected to the positive vector, as in Valdarnini (2018),
775 VELOCITY_DIFFERENCE,
776 };
777
778 enum class GravityEnum {
779 /// Approximated gravity, assuming the matter is a simple homogeneous sphere.
780 SPHERICAL,
781
782 /// Brute-force summation over all particle pairs (O(N^2) complexity)
783 BRUTE_FORCE,
784
785 /// Use Barnes-Hut algorithm, approximating gravity by multipole expansion (up to octupole order)
786 BARNES_HUT,
787 };
788
789 enum class GravityKernelEnum {
790 /// Point-like particles with zero radius
791 POINT_PARTICLES,
792
793 /// Use gravity smoothing kernel corresponding to selected SPH kernel
794 SPH_KERNEL,
795
796 /// Use kernel representing gravity of solid spheres. Useful for N-body simulations where overlaps are
797 /// allowed.
798 SOLID_SPHERES,
799 };
800
801 enum class CollisionHandlerEnum {
802 /// No collision handling
803 NONE,
804
805 /// All collided particles merge, creating larger spherical particles. Particles are merged
806 /// unconditionally, regardless of their relative velocity or their angular frequencies.
807 PERFECT_MERGING,
808
809 /// Collided particles bounce with some energy dissipation, specified by the coefficients of restitution.
810 /// No merging, number of particles remains contant.
811 ELASTIC_BOUNCE,
812
813 /// If the relative speed of the collided particles is lower than the escape velocity, the particles are
814 /// merged, otherwise the particle bounce. To ensure that the particles are always merged, set the
815 /// COLLISION_MERGE_LIMIT to zero, on the other hand large values make particles more difficult to merge.
816 MERGE_OR_BOUNCE,
817 };
818
819 enum class OverlapEnum {
820 /// All overlaps are ignored
821 NONE,
822
823 /// Overlapping particles are merged
824 FORCE_MERGE,
825
826 /// Particles are shifted until no overlap happens
827 REPEL,
828
829 /// Particles are either repeled (and bounced) or merged, based on the ratio of their relative velocity to
830 /// the escape velocity (similar to MERGE_OR_BOUNCE).
831 REPEL_OR_MERGE,
832
833 /// Particles are allowed to overlap and they bounce if moving towards each other.
834 INTERNAL_BOUNCE,
835
836 PASS_OR_MERGE,
837 };
838
839 enum class LoggerEnum {
840 /// Do not log anything
841 NONE,
842
843 /// Print log to standard output
844 STD_OUT,
845
846 /// Print log to file
847 FILE
848
849 /// \todo print using callback to gui application
850 };
851
852 enum class IoEnum {
853 /// No input/output
854 NONE = 0,
855
856 /// Formatted human-readable text file
857 TEXT_FILE = 1,
858
859 /// Full binary output file. This data dump is lossless and can be use to restart run from saved snapshot.
860 /// Stores values, all derivatives and materials of the storage.
861 BINARY_FILE = 3,
862
863 /// Compressed binary output file, containing only few selected quantities. This is the most convenient
864 /// format for storing full simulation in high resolution in time.
865 DATA_FILE = 4,
866
867 /// File format used by Visualization Toolkit (VTK). Useful to view the results in Paraview and other
868 /// visualization tools.
869 VTK_FILE = 5,
870
871 /// File format for storing scientific data. Currently tailored for files generated by the code
872 /// miluphcuda. Requires to build code with libhdf5.
873 HDF5_FILE = 6,
874
875 /// Export from Minor Planet Center Orbit Database
876 MPCORP_FILE = 7,
877
878 /// Pkdgrav input file.
879 PKDGRAV_INPUT = 8,
880 };
881
882 /// \brief Returns the file extension associated with given IO type.
883 ///
884 /// Result NOTHING indicates there is no particular extension associated with the IO type.
885 Optional<String> getIoExtension(const IoEnum type);
886
887 /// \brief Returns the file type from file extension.
888 ///
889 /// Result NOTHING indicates there is no file type associated with the extension.
890 Optional<IoEnum> getIoEnum(const String& ext);
891
892 /// \brief Returns a short description of the file format.
893 String getIoDescription(const IoEnum type);
894
895 enum class IoCapability {
896 /// The format can be used as file input
897 INPUT = 1 << 1,
898
899 /// The format can be used as file output
900 OUTPUT = 1 << 2,
901 };
902
903 /// \brief Returns the capabilities of given file format.
904 Flags<IoCapability> getIoCapabilities(const IoEnum type);
905
906
907 enum class OutputSpacing {
908 /// Constant time between consecutive output times
909 LINEAR,
910
911 /// Constant ratio between consecutive output times
912 LOGARITHMIC,
913
914 /// User-defined list of output times
915 CUSTOM,
916 };
917
918 enum class RngEnum {
919 /// Mersenne Twister PRNG from Standard library
920 UNIFORM,
921
922 /// Halton QRNG
923 HALTON,
924
925 /// Same RNG as used in SPH5, used for 1-1 comparison
926 BENZ_ASPHAUG
927 };
928
929 enum class UvMapEnum {
930 /// Planar mapping
931 PLANAR,
932
933 /// Spherical mapping
934 SPHERICAL,
935 };
936
937 /// Settings relevant for whole run of the simulation
938 enum class RunSettingsId {
939 /// User-specified name of the run, used in some output files
940 RUN_NAME,
941
942 /// User-specified comment
943 RUN_COMMENT,
944
945 /// Name of the person running the simulation
946 RUN_AUTHOR,
947
948 /// E-mail of the person running the simulation.
949 RUN_EMAIL,
950
951 /// Specifies the type of the simulation. Does not have to be specified to run the simulation; this
952 /// information is saved in output files and taken into account by visualization tools, for example.
953 RUN_TYPE,
954
955 /// Selected format of the output file, see \ref IoEnum
956 RUN_OUTPUT_TYPE,
957
958 /// Time interval of dumping data to disk.
959 RUN_OUTPUT_INTERVAL,
960
961 /// Type of output spacing in time, see enum OutputSpacing
962 RUN_OUTPUT_SPACING,
963
964 /// List of comma-separated output times, used when RUN_OUTPUT_SPACING is set to CUSTOM
965 RUN_OUTPUT_CUSTOM_TIMES,
966
967 /// Index of the first generated output file. Might not be zero if the simulation is resumed.
968 RUN_OUTPUT_FIRST_INDEX,
969
970 /// File name of the output file (including extension), where %d is a placeholder for output number.
971 RUN_OUTPUT_NAME,
972
973 /// Path where all output files (dumps, logs, ...) will be written
974 RUN_OUTPUT_PATH,
975
976 /// List of quantities to write to text output. Binary output always stores all quantitites.
977 RUN_OUTPUT_QUANTITIES,
978
979 /// Number of threads used by the code. If 0, all available threads are used.
980 RUN_THREAD_CNT,
981
982 /// Number of particles processed by one thread in a single batch. Lower number can help to distribute
983 /// tasks between threads more evenly, higher number means faster processing of particles within single
984 /// thread.
985 RUN_THREAD_GRANULARITY,
986
987 /// Selected logger of a run, see LoggerEnum
988 RUN_LOGGER,
989
990 /// Path of a file where the log is printed, used only when selected logger is LoggerEnum::FILE
991 RUN_LOGGER_FILE,
992
993 /// Number specifying log verbosity. Can be between 0 and 3, going from least to most verbose.
994 RUN_LOGGER_VERBOSITY,
995
996 /// Enables verbose log of a simulation.
997 RUN_VERBOSE_ENABLE,
998
999 /// Path of a file where the verbose log is printed.
1000 RUN_VERBOSE_NAME,
1001
1002 /// Starting time of the simulation in seconds. This is usually 0, although it can be set to a non-zero
1003 /// for simulations resumed from saved state.
1004 RUN_START_TIME,
1005
1006 /// End time of the simulation in seconds. For new simulations (not resumed from saved state), this
1007 /// corresponds to the total duration of the simulation.
1008 RUN_END_TIME,
1009
1010 /// Maximum number of timesteps after which run ends. 0 means run duration is not limited by number of
1011 /// timesteps. Note that if adaptive timestepping is used, run can end at different times for
1012 /// different initial conditions. This condition should only be used for debugging purposes.
1013 RUN_TIMESTEP_CNT,
1014
1015 /// Maximum duration of the run in milliseconds, measured in real-world time. 0 means run duration is not
1016 /// limited by this value.
1017 RUN_WALLCLOCK_TIME,
1018
1019 /// Selected random-number generator used within the run.
1020 RUN_RNG,
1021
1022 /// Seed for the random-number generator
1023 RUN_RNG_SEED,
1024
1025 /// Time period (in run time) of running diagnostics of the run. 0 means the diagnostics are run every
1026 /// time step.
1027 RUN_DIAGNOSTICS_INTERVAL,
1028
1029 /// Selected solver for computing derivatives of physical variables.
1030 SPH_SOLVER_TYPE,
1031
1032 /// List of forces to compute by the solver.
1033 SPH_SOLVER_FORCES,
1034
1035 /// Solution for evolutions of the smoothing length
1036 SPH_ADAPTIVE_SMOOTHING_LENGTH,
1037
1038 /// Maximum number of iterations for self-consistent density computation of summation solver.
1039 SPH_SUMMATION_MAX_ITERATIONS,
1040
1041 /// Target relative difference of density in successive iterations. Density computation in summation
1042 /// solver is ended when the density changes by less than the delta or the iteration number exceeds
1043 /// SOLVER_SUMMATION_MAX_ITERATIONS.
1044 SPH_SUMMATION_DENSITY_DELTA,
1045
1046 /// If true, the SPH solver computes a hash map connecting position in space with required search radius.
1047 /// Otherwise, the radius is determined from the maximal smoothing length in the simulation. Used only by
1048 /// the AsymmetricSolver.
1049 SPH_ASYMMETRIC_COMPUTE_RADII_HASH_MAP,
1050
1051 /// Index of SPH Kernel, see KernelEnum
1052 SPH_KERNEL,
1053
1054 /// Structure for searching nearest neighbors of particles
1055 SPH_FINDER,
1056
1057 /// Specifies a discretization of SPH equations; see \ref DiscretizationEnum.
1058 SPH_DISCRETIZATION,
1059
1060 /// If true, the kernel gradient for evaluation of strain rate will be corrected for each particle by an
1061 /// inversion of an SPH-discretized identity matrix. This generally improves stability of the run and
1062 /// conservation of total angular momentum, but comes at the cost of higher memory consumption and slower
1063 /// evaluation of SPH derivatives.
1064 SPH_STRAIN_RATE_CORRECTION_TENSOR,
1065
1066 /// If true, derivatives with flag DerivativeFlag::SUM_ONLY_UNDAMAGED will evaluate only undamaged
1067 /// particles belonging to the same body. Otherwise, all particle are evaluated, regardless of derivative
1068 /// flags.
1069 SPH_SUM_ONLY_UNDAMAGED,
1070
1071 /// Specifies how the density is evolved, see \ref ContinuityEnum.
1072 SPH_CONTINUITY_MODE,
1073
1074 /// Evolve particle phase angle
1075 SPH_PHASE_ANGLE,
1076
1077 /// Minimum and maximum number of neighbors SPH solver tries to enforce. Note that the solver cannot
1078 /// guarantee the actual number of neighbors will be within the range.
1079 SPH_NEIGHBOR_RANGE,
1080
1081 /// Strength of enforcing neighbor number. Higher value makes enforcing more strict (number of neighbors
1082 /// gets into required range faster), but also makes code less stable. Can be a negative number, -INFTY
1083 /// technically disables enforcing altogether.
1084 SPH_NEIGHBOR_ENFORCING,
1085
1086 /// Artificial viscosity alpha coefficient
1087 SPH_AV_ALPHA,
1088
1089 /// Artificial viscosity beta coefficient
1090 SPH_AV_BETA,
1091
1092 /// Minimal value of smoothing length
1093 SPH_SMOOTHING_LENGTH_MIN,
1094
1095 /// Type of used artificial viscosity.
1096 SPH_AV_TYPE,
1097
1098 /// Whether to use balsara switch for computing artificial viscosity dissipation. If no artificial
1099 /// viscosity is used, the value has no effect.
1100 SPH_AV_USE_BALSARA,
1101
1102 /// If true, Balsara factors will be saved as quantity AV_BALSARA. Mainly for debugging purposes.
1103 SPH_AV_BALSARA_STORE,
1104
1105 /// Enables the artificial thermal conductivity term.
1106 SPH_USE_AC,
1107
1108 /// Artificial conductivity alpha coefficient
1109 SPH_AC_ALPHA,
1110
1111 /// Artificial conductivity beta coefficient
1112 SPH_AC_BETA,
1113
1114 /// Type of the signal speed used by artificial conductivity
1115 SPH_AC_SIGNAL_SPEED,
1116
1117 /// Turn on the XSPH correction
1118 SPH_USE_XSPH,
1119
1120 /// Epsilon-factor of XSPH correction (Monaghan, 1992). Value 0 turns off the correction, epsilon
1121 /// shouldn't be larger than 1.
1122 SPH_XSPH_EPSILON,
1123
1124 /// Turn on the delta-SPH correction
1125 SPH_USE_DELTASPH,
1126
1127 /// Delta-coefficient of the delta-SPH modification, see Marrone et al. 2011
1128 SPH_DENSITY_DIFFUSION_DELTA,
1129
1130 /// Alpha-coefficient of the delta-SPH modification.
1131 SPH_VELOCITY_DIFFUSION_ALPHA,
1132
1133 /// Whether to use artificial stress.
1134 SPH_AV_USE_STRESS,
1135
1136 /// Weighting function exponent n in artificial stress term
1137 SPH_AV_STRESS_EXPONENT,
1138
1139 /// Multiplicative factor of the artificial stress term (= strength of the viscosity)
1140 SPH_AV_STRESS_FACTOR,
1141
1142 /// Damping coefficient of particle velocities, mainly intended for setting up initial conditions. Higher
1143 /// values damp the oscillation/instabilities faster, but may converge to incorrect (unstable)
1144 /// configuration. Lower values lead to (slower) convergence to correct (stable) configuration, but it may
1145 /// cause body dissintegration if the initial conditions are to far from the stable solution. Zero
1146 /// disables the damping.
1147 SPH_STABILIZATION_DAMPING,
1148
1149 /// Alpha parameter of the density-independent solver.
1150 SPH_DI_ALPHA,
1151
1152 /// Enables or disables scripted term.
1153 SPH_SCRIPT_ENABLE,
1154
1155 /// Path of an arbitrary ChaiScript script executed each timestep.
1156 SPH_SCRIPT_FILE,
1157
1158 /// Period or time point to execute the script. Zero means the time step is executed immediately or every
1159 /// time step, depending on the value of SPH_SCRIPT_ONESHOT.
1160 SPH_SCRIPT_PERIOD,
1161
1162 /// Whether to execute the script only once or periodically.
1163 SPH_SCRIPT_ONESHOT,
1164
1165 /// If true, all particles have also a moment of inertia, representing a non-homogeneous mass
1166 /// distribution. Otherwise, particles are spherical with inertia tensor I = 2/5 mr^2
1167 NBODY_INERTIA_TENSOR,
1168
1169 /// \todo
1170 NBODY_MAX_ROTATION_ANGLE,
1171
1172 /// If true, colliding particles form aggregates, which then move and rotate as rigid bodies. There are no
1173 /// collisions between particles belonging to the same aggregate, only collisions of different aggregates
1174 /// need to be handled. Note that enabling aggregates overrides handlers of collisions and overlaps.
1175 NBODY_AGGREGATES_ENABLE,
1176
1177 /// Specifies the initial aggregates used in the simulation. See \ref AggregateEnum.
1178 NBODY_AGGREGATES_SOURCE,
1179
1180 /// Algorithm to compute gravitational acceleration
1181 GRAVITY_SOLVER,
1182
1183 /// Opening angle Theta for multipole approximation of gravity
1184 GRAVITY_OPENING_ANGLE,
1185
1186 /// Order of multipole expansion
1187 GRAVITY_MULTIPOLE_ORDER,
1188
1189 /// Gravity smoothing kernel
1190 GRAVITY_KERNEL,
1191
1192 /// Gravitational constant. To be generalized.
1193 GRAVITY_CONSTANT,
1194
1195 /// Period of gravity evaluation. If zero, gravity is computed every time step, for any positive value,
1196 /// gravitational acceleration is cached for each particle and used each time step until next
1197 /// recomputation.
1198 GRAVITY_RECOMPUTATION_PERIOD,
1199
1200 /// Specifies how the collisions of particles should be handler; see CollisionHandlerEnum.
1201 COLLISION_HANDLER,
1202
1203 /// Specifies how particle overlaps should be handled.
1204 COLLISION_OVERLAP,
1205
1206 /// Coefficient of restitution for normal component (alongside particle direction vector) of velocity.
1207 /// Applicable only for bounce collisions.
1208 COLLISION_RESTITUTION_NORMAL,
1209
1210 /// Coefficient of restitution for tangent component (perpendicular to particle direction vector) of
1211 /// velocity. Applicable only for bounce collisions.
1212 COLLISION_RESTITUTION_TANGENT,
1213
1214 /// Relative particle overlap (0 for particles in contact, 1 for particles lying on top of each other) for
1215 /// which the collision is handled as overlap. Used to avoid very small (<EPS) overlaps not being handled
1216 /// as collision due to numerical imprecisions.
1217 COLLISION_ALLOWED_OVERLAP,
1218
1219 /// Multiplier of the relative velocity, used when determining whether to merge the collided particles or
1220 /// reject the collision. If zero, particles are always merged. Larger values than 1 can be used to merge
1221 /// only very slowly moving particles.
1222 COLLISION_BOUNCE_MERGE_LIMIT,
1223
1224 /// Parameter analogous to COLLISION_BOUNCE_MERGE_LIMIT, but used for the rotation of the merger.
1225 /// Particles can only be merged if the angular frequency multiplied by this parameter is lower than the
1226 /// breakup frequency. If zero, particles are always merged, values larger than 1 can be used to avoid
1227 /// fast rotators in the simulation.
1228 COLLISION_ROTATION_MERGE_LIMIT,
1229
1230 /// Magnitude of the repel force for the soft-body solver
1231 SOFT_REPEL_STRENGTH,
1232
1233 /// Magnitude of the friction force for the soft-body solver
1234 SOFT_FRICTION_STRENGTH,
1235
1236 /// Selected timestepping integrator
1237 TIMESTEPPING_INTEGRATOR,
1238
1239 /// Courant number
1240 TIMESTEPPING_COURANT_NUMBER,
1241
1242 /// Upper limit of the time step. The timestep is guaranteed to never exceed this value for any timestep
1243 /// criterion. The lowest possible timestep is not set, timestep can be any positive value.
1244 TIMESTEPPING_MAX_TIMESTEP,
1245
1246 /// Initial value of time step. If dynamic timestep is disabled, the run will keep the initial timestep
1247 /// for the whole duration. Some timestepping algorithms might not use the initial timestep and directly
1248 /// compute new value of timestep, in which case this parameter has no effect.
1249 TIMESTEPPING_INITIAL_TIMESTEP,
1250
1251 /// Criterion used to determine value of time step. More criteria may be compined, in which case the
1252 /// smallest time step of all is selected.
1253 TIMESTEPPING_CRITERION,
1254
1255 /// Multiplicative factor k for the derivative criterion; dt = k * v / dv
1256 TIMESTEPPING_DERIVATIVE_FACTOR,
1257
1258 /// Multiplicative factor for the divergence criterion
1259 TIMESTEPPING_DIVERGENCE_FACTOR,
1260
1261 /// Power of the generalized mean, used to compute the final timestep from timesteps of individual
1262 /// particles. Negative infinity means the minimal timestep is used. This value will also set statistics
1263 /// of the restricting particle, namely the particle index and the quantity value and corresponding
1264 /// derivative of the particle; these statistics are not saved for other powers.
1265 TIMESTEPPING_MEAN_POWER,
1266
1267 /// Maximum relative increase of a timestep in two subsequent timesteps. Used to 'smooth' the timesteps,
1268 /// as it prevents very fast increase of the time step, especially if the initial time step is very low.
1269 /// Used only by \ref MultiCriterion.
1270 TIMESTEPPING_MAX_INCREASE,
1271
1272 /// Number of sub-steps in the modified midpoint method.
1273 TIMESTEPPING_MIDPOINT_COUNT,
1274
1275 /// Required relative accuracy of the Bulirsch-Stoer integrator.
1276 TIMESTEPPING_BS_ACCURACY,
1277
1278 /// Global rotation of the coordinate system around axis (0, 0, 1) passing through origin. If non-zero,
1279 /// causes non-intertial acceleration.
1280 FRAME_ANGULAR_FREQUENCY,
1281
1282 FRAME_CONSTANT_ACCELERATION,
1283
1284 FRAME_TIDES_MASS,
1285
1286 FRAME_TIDES_POSITION,
1287
1288 /// Maximum number of particles in a leaf node.
1289 FINDER_LEAF_SIZE,
1290
1291 /// Maximal in a a tree depth to be processed in parallel. While a larger value implies better
1292 /// distribution of work between threads, it also comes up with performance penalty due to scheduling
1293 /// overhead.
1294 FINDER_MAX_PARALLEL_DEPTH,
1295
1296 /// Computational domain, enforced by boundary conditions
1297 DOMAIN_TYPE,
1298
1299 /// Type of boundary conditions.
1300 DOMAIN_BOUNDARY,
1301
1302 /// Center point of the domain
1303 DOMAIN_CENTER,
1304
1305 /// Radius of a spherical and cylindrical domain
1306 DOMAIN_RADIUS,
1307
1308 /// Height of a cylindrical domain
1309 DOMAIN_HEIGHT,
1310
1311 /// (Vector) size of a block domain
1312 DOMAIN_SIZE,
1313
1314 /// Minimal distance between a particle and its ghost, in units of smoothing length.
1315 DOMAIN_GHOST_MIN_DIST,
1316
1317 /// Distance to the boundary in units of smoothing length under which the particles are frozen.
1318 DOMAIN_FROZEN_DIST,
1319
1320 /// If true, the mapping coordinates will be computed and saved for all bodies in the simulation.
1321 GENERATE_UVWS,
1322
1323 /// Type of the UV mapping
1324 UVW_MAPPING,
1325 };
1326
1327
1328 enum class DistributionEnum {
1329 /// Hexagonally close packing
1330 HEXAGONAL,
1331
1332 /// Cubic close packing
1333 CUBIC,
1334
1335 /// Random distribution of particles
1336 RANDOM,
1337
1338 /// Isotropic uniform distribution by Diehl et al. (2012)
1339 DIEHL_ET_AL,
1340
1341 /// Stratified distribution to reduce clustering
1342 STRATIFIED,
1343
1344 /// Parametrized spiraling scheme by Saff & Kuijlaars (1997)
1345 PARAMETRIZED_SPIRALING,
1346
1347 /// Distributes particles uniformly on line
1348 LINEAR
1349 };
1350
1351
1352 enum class EosEnum {
1353 /// No equation of state
1354 NONE,
1355
1356 /// Equation of state for ideal gas
1357 IDEAL_GAS,
1358
1359 /// Tait equation of state for simulations of liquids
1360 TAIT,
1361
1362 /// Mie-Gruneisen equation of state
1363 MIE_GRUNEISEN,
1364
1365 /// Tillotson (1962) equation of state
1366 TILLOTSON,
1367
1368 /// Murnaghan equation of state
1369 MURNAGHAN,
1370
1371 /// Simplified version of the Tillotson equation of state
1372 SIMPLIFIED_TILLOTSON,
1373
1374 /// ANEOS given by look-up table
1375 ANEOS
1376 };
1377
1378 /// \brief Settings of a single body / gas phase / ...
1379 ///
1380 /// Combines material parameters and numerical parameters of the SPH method specific for one body. Values of
1381 /// parameters CANNOT be changed to preserve backward compatibility of serializer. New IDs can be created as
1382 /// needed, parameters no longer needed can be removed.
1383 enum class BodySettingsId {
1384 /// Equation of state for this material, see EosEnum for options.
1385 EOS = 0,
1386
1387 /// Initial distribution of SPH particles within the domain, see DistributionEnum for options.
1388 INITIAL_DISTRIBUTION = 1,
1389
1390 /// If true, generated particles will be moved so that their center of mass corresponds to the center of
1391 /// selected domain. Note that this will potentially move some particles outside of the domain, which can
1392 /// clash with boundary conditions.
1393 CENTER_PARTICLES = 2,
1394
1395 /// If true, particles are sorted using Morton code, preserving locality in memory.
1396 PARTICLE_SORTING = 3,
1397
1398 /// Turns on 'SPH5 compatibility' mode when generating particle positions. This allows 1-1 comparison of
1399 /// generated arrays, but results in too many generated particles (by about factor 1.4). The option also
1400 /// implies CENTER_PARTICLES.
1401 DISTRIBUTE_MODE_SPH5 = 4,
1402
1403 /// Strength parameter of the Diehl's distribution.
1404 DIEHL_STRENGTH = 5,
1405
1406 /// Maximum allowed difference between the expected number of particles and the actual number of generated
1407 /// particles. Higher value speed up the generation of particle positions.
1408 DIEHL_MAX_DIFFERENCE = 6,
1409
1410 /// Number of iterations of particle repelling.
1411 DIEHL_ITERATION_COUNT = 71,
1412
1413 /// Eta-factor between smoothing length and particle concentration (h = eta * n^(-1/d) )
1414 SMOOTHING_LENGTH_ETA = 72,
1415
1416 /// Density at zero pressure
1417 DENSITY = 7,
1418
1419 /// Allowed range of density. Densities of all particles all clamped to fit in the range.
1420 DENSITY_RANGE = 8,
1421
1422 /// Estimated minimal value of density. This value is NOT used to clamp densities, but for
1423 /// determining error of timestepping.
1424 DENSITY_MIN = 9,
1425
1426 /// Initial specific internal energy
1427 ENERGY = 10,
1428
1429 /// Allowed range of specific internal energy.
1430 ENERGY_RANGE = 11,
1431
1432 /// Estimated minimal value of energy used to determine timestepping error.
1433 ENERGY_MIN = 12,
1434
1435 /// Initial values of the deviatoric stress tensor
1436 STRESS_TENSOR = 13,
1437
1438 /// Estimated minial value of stress tensor components used to determined timestepping error.
1439 STRESS_TENSOR_MIN = 14,
1440
1441 /// Initial damage of the body.
1442 DAMAGE = 15,
1443
1444 /// Allowed range of damage.
1445 DAMAGE_RANGE = 16,
1446
1447 /// Estimate minimal value of damage used to determine timestepping error.
1448 DAMAGE_MIN = 17,
1449
1450 /// Adiabatic index used by some equations of state (such as ideal gas)
1451 ADIABATIC_INDEX = 18,
1452
1453 /// Exponent of density, representing a compressibility of a fluid. Used in Tait equation of state.
1454 TAIT_GAMMA = 19,
1455
1456 /// Sound speed used in Tait equation of state
1457 TAIT_SOUND_SPEED = 20,
1458
1459 /// Bulk modulus of the material
1460 BULK_MODULUS = 21,
1461
1462 /// Coefficient B of the nonlinear compressive term in Tillotson equation
1463 TILLOTSON_NONLINEAR_B = 22,
1464
1465 /// "Small a" coefficient in Tillotson equation
1466 TILLOTSON_SMALL_A = 23,
1467
1468 /// "Small b" coefficient in Tillotson equation
1469 TILLOTSON_SMALL_B = 24,
1470
1471 /// Alpha coefficient in expanded phase of Tillotson equation
1472 TILLOTSON_ALPHA = 25,
1473
1474 /// Beta coefficient in expanded phase of Tillotson equation
1475 TILLOTSON_BETA = 26,
1476
1477 /// Specific sublimation energy
1478 TILLOTSON_SUBLIMATION = 27,
1479
1480 /// Specific energy of incipient vaporization
1481 TILLOTSON_ENERGY_IV = 28,
1482
1483 /// Specific energy of complete vaporization
1484 TILLOTSON_ENERGY_CV = 29,
1485
1486 /// Gruneisen's gamma paraemter used in Mie-Gruneisen equation of state
1487 GRUNEISEN_GAMMA = 30,
1488
1489 /// Used in Mie-Gruneisen equations of state
1490 BULK_SOUND_SPEED = 31,
1491
1492 /// Linear Hugoniot slope coefficient used in Mie-Gruneisen equation of state
1493 HUGONIOT_SLOPE = 32,
1494
1495 /// Model of stress reducing used within the rheological model
1496 RHEOLOGY_YIELDING = 33,
1497
1498 /// Model of fragmentation used within the rheological model
1499 RHEOLOGY_DAMAGE = 34,
1500
1501 /// Shear modulus mu (a.k.a Lame's second parameter) of the material
1502 SHEAR_MODULUS = 35,
1503
1504 /// Young modulus of the material
1505 YOUNG_MODULUS = 36,
1506
1507 /// Elastic modulus lambda (a.k.a Lame's first parameter) of the material
1508 ELASTIC_MODULUS = 37,
1509
1510 /// Elasticity limit of the von Mises yielding criterion
1511 ELASTICITY_LIMIT = 38,
1512
1513 /// Melting energy, used for temperature-dependence of the stress tensor
1514 MELT_ENERGY = 39,
1515
1516 /// Cohesion, yield strength at zero pressure
1517 COHESION = 40,
1518
1519 /// Coefficient of friction for undamaged material
1520 INTERNAL_FRICTION = 41,
1521
1522 /// Coefficient of friction for fully damaged material
1523 DRY_FRICTION = 42,
1524
1525 /// Whether to use the acoustic fludization model.
1526 USE_ACOUSTIC_FLUDIZATION = 43,
1527
1528 /// Characteristic decay time of acoustic oscillations in the material
1529 OSCILLATION_DECAY_TIME = 44,
1530
1531 /// Regeneration efficiency of acoustric oscillations
1532 OSCILLATION_REGENERATION = 74,
1533
1534 /// Effective viscosity of acoustic fludizations
1535 FLUIDIZATION_VISCOSITY = 45,
1536
1537 /// Speed of crack growth, in units of local sound speed.
1538 RAYLEIGH_SOUND_SPEED = 47,
1539
1540 /// Coefficient (multiplier) of the Weibull distribution of flaws
1541 WEIBULL_COEFFICIENT = 48,
1542
1543 /// Exponent of the Weibull distribution of flaws
1544 WEIBULL_EXPONENT = 49,
1545
1546 /// Whether to use precomputed distributions for flaw sampling. Otherwise, flaws are sampled using uniform
1547 /// random number generator, which may be prohibitively slow for large particle counts.
1548 WEIBULL_SAMPLE_DISTRIBUTIONS = 66,
1549
1550 /// Initial value of the material distention, used in the P-alpha model.
1551 DISTENTION = 81,
1552
1553
1554 BULK_VISCOSITY = 50,
1555
1556 SHEAR_VISCOSITY = 51,
1557
1558 DAMPING_COEFFICIENT = 52,
1559
1560 DIFFUSIVITY = 53,
1561
1562 /// Coefficient of surface tension
1563 SURFACE_TENSION = 54,
1564
1565 /// Number of SPH particles in the body
1566 PARTICLE_COUNT = 55,
1567
1568 /// Minimal number of particles per one body. Used when creating 'sub-bodies' withing one 'parent' body,
1569 /// for example when creating rubble-pile asteroids, ice blocks inside an asteroid, etc. Parameter has no
1570 /// effect for creation of a single monolithic body; the number of particles from PARTICLE_COUNT is used
1571 /// in any case.
1572 MIN_PARTICLE_COUNT = 56,
1573
1574 /// Initial alpha coefficient of the artificial viscosity. This is only used if the coefficient is
1575 /// different for each particle. For constant coefficient shared for all particles, use value from global
1576 /// settings.
1577 AV_ALPHA = 57,
1578
1579 /// Lower and upper bound of the alpha coefficient, used only for time-dependent artificial viscosity.
1580 AV_ALPHA_RANGE = 58,
1581
1582 /// Bulk (macro)porosity of the body
1583 BULK_POROSITY = 64,
1584
1585 /// Heat capacity at constant pressure,
1586 HEAT_CAPACITY = 67,
1587
1588 BODY_SHAPE_TYPE = 59,
1589
1590 /// Center point of the body. Currently used only by \ref StabilizationSolver.
1591 BODY_CENTER = 61,
1592
1593 BODY_RADIUS = 68,
1594
1595 BODY_DIMENSIONS = 69,
1596
1597 BODY_HEIGHT = 73,
1598
1599 BODY_SPIN_RATE = 70,
1600
1601 VISUALIZATION_TEXTURE = 80,
1602
1603 /// Arbitrary string identifying this material
1604 IDENTIFIER = 99,
1605 };
1606
1607 using RunSettings = Settings<RunSettingsId>;
1608 using BodySettings = Settings<BodySettingsId>;
1609
1610 NAMESPACE_SPH_END
1611