23 : pathMask(pathMask) {
24 dumpNum = firstDumpIdx;
30 std::string path = pathMask.
native();
31 std::size_t n = path.find(
"%d");
32 if (n != std::string::npos) {
33 std::ostringstream ss;
34 ss << std::setw(4) << std::setfill(
'0') << dumpNum;
35 path.replace(n, 2, ss.str());
38 if (n != std::string::npos) {
39 std::ostringstream ss;
41 ss << std::fixed << t;
43 path.replace(n, 2, ss.str());
52 for (
int i = 0; i < int(s.size()) - 3; ++i) {
53 if (std::isdigit(s[i]) && std::isdigit(s[i + 1]) && std::isdigit(s[i + 2]) &&
54 std::isdigit(s[i + 3])) {
56 if (i + 4 <
int(s.size()) && std::isdigit(s[i + 4])) {
61 Size index = std::stoul(s.substr(i, 4));
63 }
catch (
const std::exception& e) {
75 for (
int i = 0; i < int(s.size()) - 3; ++i) {
76 if (std::isdigit(s[i]) && std::isdigit(s[i + 1]) && std::isdigit(s[i + 2]) &&
77 std::isdigit(s[i + 3])) {
78 if (i + 4 <
int(s.size()) && std::isdigit(s[i + 4])) {
81 std::string mask = s.substr(0, i) +
"%d" + s.substr(i + 4);
90 std::string path = pathMask.
native();
91 return path.find(
"%d") != std::string::npos || path.find(
"%t") != std::string::npos;
107 static void printHeader(std::ostream& ofs,
const std::string& name,
const ValueEnum type) {
111 ofs << std::setw(20) << name;
114 ofs << std::setw(20) << (name +
" [x]") << std::setw(20) << (name +
" [y]") << std::setw(20)
118 ofs << std::setw(20) << (name +
" [xx]") << std::setw(20) << (name +
" [yy]") << std::setw(20)
119 << (name +
" [zz]") << std::setw(20) << (name +
" [xy]") << std::setw(20) << (name +
" [xz]")
120 << std::setw(20) << (name +
" [yz]");
123 ofs << std::setw(20) << (name +
" [xx]") << std::setw(20) << (name +
" [yy]") << std::setw(20)
124 << (name +
" [xy]") << std::setw(20) << (name +
" [xz]") << std::setw(20) << (name +
" [yz]");
133 columns.push(makeAuto<ParticleNumberColumn>());
145 columns.push(makeAuto<SmoothingLengthColumn>());
174 template <
typename TValue>
181 const std::string& runName,
187 addColumns(quantities, columns);
197 columns.
push(makeAuto<ParticleNumberColumn>());
200 columns.
push(makeAuto<SmoothingLengthColumn>());
215 return makeUnexpected<Path>(
220 std::ofstream ofs(fileName.
native());
222 ofs <<
"# Run: " << runName << std::endl;
227 for (
auto& column : columns) {
228 printHeader(ofs, column->getName(), column->getType());
233 for (
auto& column : columns) {
236 ofs << std::scientific << std::setprecision(
PRECISION)
237 << column->evaluate(storage, stats, i);
239 ofs << std::setprecision(
PRECISION) << column->evaluate(storage, stats, i);
246 }
catch (
const std::exception& e) {
247 return makeUnexpected<Path>(
"Cannot save output file " + fileName.
native() +
": " + e.what());
252 columns.
push(std::move(column));
257 addColumns(quantities, columns);
262 std::ifstream ifs(path.
native());
271 Size particleCnt = 0;
272 while (std::getline(ifs, line)) {
273 if (line[0] ==
'#') {
276 std::stringstream ss(line);
278 switch (column->getType()) {
283 column->accumulate(storage, i, particleCnt);
289 column->accumulate(storage, f, particleCnt);
294 ss >> v[
X] >> v[
Y] >> v[
Z];
295 column->accumulate(storage, v, particleCnt);
299 Float xx, yy, xy, xz, yz;
300 ss >> xx >> yy >> xy >> xz >> yz;
302 column->accumulate(storage, t, particleCnt);
316 buffer.resize(particleCnt);
321 return makeFailed(
"Loaded storage is not valid");
324 }
catch (
const std::exception& e) {
331 columns.
push(std::move(column));
346 const std::string command =
"gnuplot -e \"filename='" + pathWithoutExt.
native() +
347 "'; time=" + std::to_string(time) +
"\" " + scriptPath;
348 const int returned = system(command.c_str());
360 template <
bool Precise>
361 struct SerializerDispatcher {
364 template <
typename T>
365 void operator()(
const T& value) {
366 serializer.
write(value);
368 void operator()(
const Interval& value) {
369 serializer.write(value.
lower(), value.
upper());
371 void operator()(
const Vector& value) {
372 serializer.write(value[
X], value[
Y], value[
Z], value[
H]);
375 serializer.write(t(0, 0), t(1, 1), t(2, 2), t(0, 1), t(0, 2), t(1, 2));
378 serializer.write(t(0, 0), t(1, 1), t(0, 1), t(0, 2), t(1, 2));
380 void operator()(
const Tensor& t) {
381 serializer.write(t(0, 0), t(0, 1), t(0, 2), t(1, 0), t(1, 1), t(1, 2), t(2, 0), t(2, 1), t(2, 2));
386 serializer.write(e.
value, 0);
390 template <
bool Precise>
391 struct DeserializerDispatcher {
394 template <
typename T>
395 void operator()(T& value) {
396 deserializer.
read(value);
400 deserializer.read(lower, upper);
403 void operator()(
Vector& value) {
404 deserializer.read(value[
X], value[
Y], value[
Z], value[
H]);
407 deserializer.read(t(0, 0), t(1, 1), t(2, 2), t(0, 1), t(0, 2), t(1, 2));
411 deserializer.read(a[0], a[1], a[2], a[3], a[4]);
414 void operator()(
Tensor& t) {
415 deserializer.read(t(0, 0), t(0, 1), t(0, 2), t(1, 0), t(1, 1), t(1, 2), t(2, 0), t(2, 1), t(2, 2));
419 deserializer.read(e.
value, dummy);
423 struct StoreBuffersVisitor {
424 template <
typename TValue>
426 SerializerDispatcher<true> dispatcher{ serializer };
428 for (
Size i : sequence) {
429 dispatcher(buffers[0][i]);
435 for (
Size i : sequence) {
436 dispatcher(buffers[1][i]);
440 for (
Size i : sequence) {
441 dispatcher(buffers[1][i]);
443 for (
Size i : sequence) {
444 dispatcher(buffers[2][i]);
453 struct LoadBuffersVisitor {
454 template <
typename TValue>
460 DeserializerDispatcher<true> dispatcher{ deserializer };
462 for (
Size i : sequence) {
463 dispatcher(buffer[i]);
465 storage.
insert<TValue>(id, order, std::move(buffer));
472 for (
Size i : sequence) {
480 for (
Size i : sequence) {
483 for (
Size i : sequence) {
496 for (
Size i = 0; i < 16; ++i) {
503 serializer.
write(buffer);
510 , runTypeId(runTypeId) {}
518 return makeUnexpected<Path>(
519 "Cannot create directory " + fileName.parentPath().native() +
": " + dirResult.
error());
530 serializer.write(
"SPH",
540 writeString(__DATE__, serializer);
542 serializer.write(wallclockTime);
545 serializer.addPadding(PADDING_SIZE);
554 cachedIds.
push(i.id);
559 SerializerDispatcher<true> dispatcher{ serializer };
560 const bool hasMaterials = materialCnt > 0;
562 for (
Size matIdx = 0; matIdx <
max(materialCnt,
Size(1)); ++matIdx) {
565 serializer.write(
"MAT", matIdx);
567 serializer.write(material->getParams().size());
569 for (
auto param : material->getParams()) {
570 serializer.write(param.id);
571 serializer.write(param.value.getTypeIdx());
576 const Interval range = material->range(
id);
577 const Float minimal = material->minimal(
id);
578 serializer.write(
id, range.
lower(), range.
upper(), minimal);
582 serializer.write(
"NOMAT");
594 serializer.write(*sequence.
begin(), *sequence.
end());
599 StoreBuffersVisitor visitor;
608 template <
typename T>
627 std::string identifier;
628 deserializer.
read(identifier, matIdxCheck);
630 if (identifier !=
"MAT") {
631 return makeUnexpected<Storage>(
"Invalid material identifier, expected MAT, got " + identifier);
633 if (matIdxCheck != matIdx) {
634 return makeUnexpected<Storage>(
"Unexpected material index, expected " + std::to_string(matIdx) +
635 ", got " + std::to_string(matIdxCheck));
639 deserializer.
read(matParamCnt);
641 for (
Size i = 0; i < matParamCnt; ++i) {
645 deserializer.
read(paramId, valueId);
653 body.
set(paramId, e);
660 { CONSTRUCT_TYPE_IDX, valueId } };
662 forValue(iteratorValue.value, [&deserializer, &body, paramId](
auto& entry) {
663 DeserializerDispatcher<true>{ deserializer }(entry);
667 setEnumIndex(body, paramId, entry);
668 body.set(paramId, entry);
679 for (
Size i = 0; i < ids.
size(); ++i) {
681 Float lower, upper, minimal;
682 deserializer.
read(
id, lower, upper, minimal);
684 return makeUnexpected<Storage>(
"Unexpected quantityId, expected " +
694 material->
setRange(
id, range, minimal);
697 return Storage(std::move(material));
701 std::string runTypeStr(buffer);
702 if (!runTypeStr.empty()) {
703 return EnumMap::fromString<RunTypeEnum>(runTypeStr).value();
712 return std::string(buffer);
721 std::string identifier;
722 Float time, timeStep;
724 Size particleCnt, quantityCnt, materialCnt;
727 char runTypeBuffer[16];
728 char buildDateBuffer[16];
729 deserializer.
read(identifier,
742 if (identifier !=
"SPH") {
743 return makeFailed(
"Invalid format specifier: expected SPH, got ", identifier);
751 deserializer.
skip(BinaryOutput::PADDING_SIZE);
759 for (
Size i = 0; i < quantityCnt; ++i) {
760 deserializer.
read(quantityIds[i], orders[i], valueTypes[i]);
767 const bool hasMaterials = materialCnt > 0;
768 for (
Size matIdx = 0; matIdx <
max(materialCnt,
Size(1)); ++matIdx) {
772 Expected<Storage> loadedStorage = loadMaterial(matIdx, deserializer, quantityIds, version);
773 if (!loadedStorage) {
776 bodyStorage = std::move(loadedStorage.
value());
783 deserializer.
read(identifier);
787 if (identifier !=
"NOMAT") {
788 return makeFailed(
"Unexpected missing material identifier, expected NOMAT, got ", identifier);
794 deserializer.
read(from, to);
795 LoadBuffersVisitor visitor;
796 for (
Size i = 0; i < quantityCnt; ++i) {
808 storage.
merge(std::move(bodyStorage));
816 char runTypeBuffer[16];
818 std::string identifier;
821 deserializer.
read(identifier,
832 return makeUnexpected<Info>(
"Invalid file format");
834 if (identifier !=
"SPH") {
835 return makeUnexpected<Info>(
"Invalid format specifier: expected SPH, got " + identifier);
850 , compression(compression)
851 , runTypeId(runTypeId) {}
855 template <
typename T>
859 SerializerDispatcher<false> dispatcher{ serializer };
866 for (
Size i = 0; i < values.
size(); ++i) {
875 dispatcher(values[i]);
876 lastValue = values[i];
880 dispatcher(lastValue);
891 for (
Size i = 0; i < values.
size(); ++i) {
892 dispatcher(values[i]);
897 template <
typename T>
901 DeserializerDispatcher<false> dispatcher{ deserializer };
910 T lastValue = T(NAN);
912 while (i < values.
size()) {
913 dispatcher(values[i]);
914 if (values[i] != lastValue) {
915 lastValue = values[i];
921 for (
Size j = 0; j < count; ++j) {
922 values[i++] = lastValue;
927 for (
Size i = 0; i < values.
size(); ++i) {
928 dispatcher(values[i]);
939 return makeUnexpected<Path>(
940 "Cannot create directory " + fileName.parentPath().native() +
": " + dirResult.
error());
949 serializer.write(runTypeId);
950 serializer.addPadding(230);
962 if (storage.
has(
id)) {
967 serializer.write(count);
970 serializer.write(
id);
971 compressQuantity(serializer, compression, storage.
getValue<
Float>(
id));
982 std::string identifier;
989 deserializer.
read(identifier, time, particleCnt, compression, version, runTypeId);
993 if (identifier !=
"CPRSPH") {
994 return makeFailed(
"Invalid format specifier: expected CPRSPH, got ", identifier);
998 deserializer.
skip(230);
1005 decompressQuantity(deserializer, compression, positions);
1009 decompressQuantity(deserializer, compression, velocities);
1013 deserializer.
read(count);
1014 for (
Size i = 0; i < count; ++i) {
1016 deserializer.
read(
id);
1018 decompressQuantity(deserializer, compression, values);
1032 std::string identifier;
1039 deserializer.
read(identifier, time, particleCnt, compression, version, runTypeId);
1041 return makeUnexpected<CompressedInput::Info>(
"Invalid file format");
1043 if (identifier !=
"CPRSPH") {
1044 return makeUnexpected<CompressedInput::Info>(
1045 "Invalid format specifier: expected CPRSPH, got " + identifier);
1059 static void writeDataArray(std::ofstream& of,
1065 of << R
"( <DataArray type="Float32" Name=")" << column.getName() << R"(" format="ascii">)";
1068 of << R
"( <DataArray type="Float32" Name=")" << column.getName()
1069 << R"(" NumberOfComponents="3" format="ascii">)";
1072 of << R
"( <DataArray type="Int32" Name=")" << column.getName() << R"(" format="ascii">)";
1075 of << R
"( <DataArray type="Float32" Name=")" << column.getName()
1076 << R"(" NumberOfComponents="6" format="ascii">)";
1079 of << R
"( <DataArray type="Float32" Name=")" << column.getName()
1080 << R"(" NumberOfComponents="5" format="ascii">)";
1088 of << column.
evaluate(storage, stats, i) <<
"\n";
1091 of << R
"( </DataArray>)"
1109 return makeUnexpected<Path>(
1110 "Cannot create directory " + fileName.parentPath().native() +
": " + dirResult.
error());
1114 std::ofstream of(fileName.native());
1115 of << R
"(<VTKFile type="UnstructuredGrid" version="0.1" byte_order="LittleEndian">
1117 <Piece NumberOfPoints=")"
1120 <DataArray name="Position" type="Float32" NumberOfComponents="3" format="ascii">)"
1123 for (
Size i = 0; i < r.
size(); ++i) {
1126 of << R
"( </DataArray>
1128 <PointData Vectors="vector">)"
1132 addColumns(flags, columns);
1134 for (
auto& column : columns) {
1135 writeDataArray(of, storage, stats, *column);
1138 of << R
"( </PointData>
1140 <DataArray type="Int32" Name="connectivity" format="ascii">
1142 <DataArray type="Int32" Name="offsets" format="ascii">
1144 <DataArray type="UInt8" Name="types" format="ascii">
1152 }
catch (
const std::exception& e) {
1153 return makeUnexpected<Path>(
"Cannot save file " + fileName.native() +
": " + e.what());
1163 template <
typename T>
1167 Size typeDim<Float> = 1;
1169 Size typeDim<Vector> = 3;
1171 template <
typename T>
1176 return Float(data[i]);
1180 return Vector(data[3 * i + 0], data[3 * i + 1], data[3 * i + 2]);
1183 template <
typename T>
1184 static void loadQuantity(
const hid_t fileId,
1185 const std::string& label,
1189 const hid_t hid = H5Dopen(fileId, label.c_str(), H5P_DEFAULT);
1195 H5Dread(hid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &data[0]);
1199 for (
Size i = 0; i < particleCnt; ++i) {
1200 values[i] = doubleToType<T>(data, i);
1207 storage.
getDt<T>(id) = std::move(values);
1210 storage.
getD2t<T>(id) = std::move(values);
1218 const hid_t fileId = H5Fopen(path.
native().c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
1225 const hid_t posId = H5Dopen(fileId,
"/x", H5P_DEFAULT);
1227 return makeFailed(
"Cannot read position data from file '", path.
native(),
"'");
1229 const hid_t dspace = H5Dget_space(posId);
1230 const Size ndims = H5Sget_simple_extent_ndims(dspace);
1232 H5Sget_simple_extent_dims(dspace, &dims[0],
nullptr);
1233 const Size particleCnt = dims[0];
1237 const hid_t timeId = H5Dopen(fileId,
"/time", H5P_DEFAULT);
1239 return makeFailed(
"Cannot read simulation time from file '", path.
native(),
"'");
1242 H5Dread(timeId, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &runTime);
1261 for (
Size i = 0; i < particleCnt; ++i) {
1271 return makeFailed(
"HDF5 support not enabled. Please rebuild the code with CONFIG+=use_hdf5.");
1282 return 0.5_f * d * 1.e3_f;
1285 static void parseMpcorp(std::ifstream& ifs,
Storage& storage,
const Float rho,
const Float albedo) {
1288 while (std::getline(ifs, line)) {
1289 if (line.size() >= 5 && line.substr(0, 5) ==
"-----") {
1298 while (std::getline(ifs, line)) {
1302 std::stringstream ss(line);
1304 ss >> dummy >> mag >> dummy >> dummy;
1308 Float M, omega, Omega, I, e, n, a;
1309 ss >> M >> omega >> Omega >> I >> e >> n >> a;
1317 ss >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy >> flag;
1329 r[
H] = computeRadius(mag, albedo);
1337 if (std::isdigit(flag.back())) {
1338 flags.
push(flag.back() -
'0');
1352 std::ifstream ifs(path.
native());
1356 parseMpcorp(ifs, storage, rho, albedo);
1358 }
catch (
const std::exception& e) {
1370 , params(
std::move(params)) {
1384 std::ofstream ofs(fileName.
native());
1385 ofs << std::setprecision(
PRECISION) << std::scientific;
1388 for (
Size i = 0; i < r.size(); ++i) {
1392 const Float radius = this->getRadius(r[idx][
H], m[idx], rho[idx]);
1395 ofs << std::setw(25) << idx <<
1396 std::setw(25) << idx <<
1401 std::setw(25) <<
Vector(0._f) <<
1402 std::setw(25) << params.
colors[flags[idx]] << std::endl;
1426 virtual std::string getName()
const override {
1430 virtual ValueEnum getType()
const override {
1457 Outcome outcome = input.load(path, storage, stats);
1475 for (
Size i = 0; i < r.
size(); ++i) {
1478 m[i] *= conversion.
mass;
1483 r[i][
H] =
root<3>(3._f * m[i] / (2700._f * 4._f *
PI));
1487 rho[i] = m[i] /
pow<3>(rho[i]);
1494 order.shuffle([&m](
const Size i1,
const Size i2) {
return m[i1] > m[i2]; });
1498 rho = order.apply(rho);
1499 omega = order.apply(omega);
1509 input = makeAuto<TextInput>(
1516 Outcome result = input->
load(path, storage, stats);
1523 for (
Size i = 0; i < r.
size(); ++i) {
INLINE bool almostEqual(const AffineMatrix &m1, const AffineMatrix &m2, const Float eps=EPS)
INLINE bool isReal(const AntisymmetricTensor &t)
#define SPH_ASSERT(x,...)
#define NOT_IMPLEMENTED
Helper macro marking missing implementation.
INLINE AutoPtr< T > makeAuto(TArgs &&... args)
Object for printing quantity values into output.
const EmptyFlags EMPTY_FLAGS
uint32_t Size
Integral type used to index arrays (by default).
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
constexpr int PRECISION
Number of valid digits of numbers on output.
Base class for all particle materials.
Logging routines of the run.
#define VERBOSE_LOG
Helper macro, creating.
constexpr INLINE T max(const T &f1, const T &f2)
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
INLINE T sqrt(const T f)
Return a squared root of a value.
constexpr INLINE Float pow< 3 >(const Float v)
constexpr INLINE Float sphereVolume(const Float radius)
Computes a volume of a sphere given its radius.
constexpr Float DEG_TO_RAD
INLINE T log10(const T f)
INLINE Float root< 3 >(const Float f)
INLINE T exp10(const T f)
constexpr Float PI
Mathematical constants.
#define MARK_USED(x)
Silences the "unused variable" warning for given variable.
#define NAMESPACE_SPH_END
const NothingType NOTHING
Helper object defining permutation.
const SuccessTag SUCCESS
Global constant for successful outcome.
INLINE Outcome makeFailed(TArgs &&... args)
Constructs failed object with error message.
void setEnumIndex(const BodySettings &settings, const BodySettingsId paramId, EnumWrapper &entry)
Saving and loading particle data.
@ STRAIN_RATE_CORRECTION_TENSOR
Symmetric tensor correcting kernel gradient for linear consistency.
@ DEVIATORIC_STRESS
Deviatoric stress tensor, always a traceless tensor stored in components xx, yy, xy,...
@ PRESSURE
Pressure, reduced by yielding and fracture model (multiplied by 1-damage); always a scalar quantity.
@ VELOCITY
Current velocities of particles, always a vector quantity.
@ DAMAGE
Damage, reducing the pressure and deviatoric stress.
@ POSITION
Positions of particles, always a vector quantity.
@ ENERGY
Specific internal energy, always a scalar quantity.
@ SMOOTHING_LENGTH
Smoothing lenghts of particles.
@ ANGULAR_FREQUENCY
Angular frequency of particles, used in N-body simulations.
@ DENSITY
Density, always a scalar quantity.
@ INDEX
Index of particle.
@ MASS
Particle masses, always a scalar quantity.
@ MATERIAL_ID
ID of material, indexed from 0 to (#bodies - 1).
RunTypeEnum
Type of simulation, stored as metadata in the binary file.
@ V2021_03_20
added wallclock time and build date
@ V2018_10_24
reverted enum (storing zero instead of hash), storing type of simulation
decltype(auto) dispatch(const ValueEnum value, TVisitor &&visitor, TArgs &&... args)
Selects type based on run-time ValueEnum value and runs visit<Type>() method of the visitor.
QuantityMetadata getMetadata(const QuantityId key)
Returns the quantity information using quantity ID.
QuantityId
Unique IDs of basic quantities of SPH particles.
@ FLAG
ID of original body, used to implement discontinuities between bodies in SPH.
@ STRAIN_RATE_CORRECTION_TENSOR
Correction tensor used to improve conservation of total angular momentum.
@ DEVIATORIC_STRESS
Deviatoric stress tensor, always a traceless tensor.
@ PRESSURE
Pressure, affected by yielding and fragmentation model, always a scalar quantity.
@ POSITION
Positions (velocities, accelerations) of particles, always a vector quantity,.
@ ENERGY
Specific internal energy, always a scalar quantity.
@ DENSITY
Density, always a scalar quantity.
@ MASS
Paricles masses, always a scalar quantity.
@ MATERIAL_ID
Index of material of the particle. Can be generally different than the flag value.
@ SECOND
Quantity with 1st and 2nd derivative.
@ FIRST
Quantity with 1st derivative.
@ ZERO
Quantity without derivatives, or "zero order" of quantity.
Data serialization and deserialization.
StaticArray< T0 &, sizeof...(TArgs)+1 > tie(T0 &t0, TArgs &... rest)
Creates a static array from a list of l-value references.
@ WALLCLOCK_TIME
Current wallclock duration of the simulation.
@ RUN_TIME
Current time of the simulation in code units. Does not necessarily have to be 0 when run starts.
@ TIMESTEP_VALUE
Current value of timestep.
decltype(auto) INLINE forValue(Variant< TArgs... > &variant, TFunctor &&functor)
INLINE BasicVector< float > cross(const BasicVector< float > &v1, const BasicVector< float > &v2)
Cross product between two vectors.
BasicVector< Float > Vector
static AffineMatrix rotateX(const Float angle)
static AffineMatrix rotateZ(const Float angle)
Object providing safe access to continuous memory of data.
INLINE TCounter size() const
Generic dynamically allocated resizable storage.
INLINE void push(U &&u)
Adds new element to the end of the array, resizing the array if necessary.
void clear()
Removes all elements from the array, but does NOT release the memory.
INLINE TCounter size() const noexcept
INLINE bool empty() const noexcept
Wrapper of pointer that deletes the resource from destructor.
INLINE const TError & error() const
Returns the error message.
virtual Expected< Path > dump(const Storage &storage, const Statistics &stats) override
Saves data from particle storage into the file.
BinaryOutput(const OutputFile &fileMask, const RunTypeEnum runTypeId=RunTypeEnum::SPH)
CompressedOutput(const OutputFile &fileMask, const CompressionEnum compression, const RunTypeEnum runTypeId=RunTypeEnum::SPH)
virtual Expected< Path > dump(const Storage &storage, const Statistics &stats) override
Saves data from particle storage into the file.
Returns first derivatives of given quantity as stored in storage.
Object for reading serialized primitives from input stream.
void skip(const Size size)
Skip a number of bytes in the stream; used to skip unused parameters or padding bytes.
void read(TArgs &... args)
Convenient object for storing a single value of different types.
static std::string toString(const TEnum value)
virtual const char * what() const noexcept
Wrapper of type that either contains a value of given type, or an error message.
const Error & error() const
Returns the error message.
Type & value()
Returns the reference to expected value.
INLINE void unset(const TEnum flag)
Removed a single flag.
constexpr INLINE bool has(const TEnum flag) const
Checks if the object has a given flag.
virtual Expected< Path > dump(const Storage &storage, const Statistics &stats) override
Saves data from particle storage into the file.
void setRange(const QuantityId id, const Interval &range, const Float minimal)
Sets the timestepping parameters of given quantity.
Interface for saving quantities of SPH particles to a file.
IOutput(const OutputFile &fileMask)
Constructs output given the file name of the output.
Base class for conversion of quantities into the output data.
virtual std::string getName() const =0
Returns a name of the column.
virtual ValueEnum getType() const =0
Returns the value type of the column.
virtual Dynamic evaluate(const Storage &storage, const Statistics &stats, const Size particleIdx) const =0
Returns the value of the output column for given particle.
INLINE IndexIterator begin() const
INLINE IndexIterator end() const
Object representing a 1D interval of real numbers.
INLINE Float lower() const
Returns lower bound of the interval.
INLINE Float upper() const
Returns upper bound of the interval.
static Interval unbounded()
Returns an unbounded (infinite) interval.
Exception thrown when file cannot be read, it has invalid format, etc.
Non-owning wrapper of a material and particles with this material.
INLINE IndexSequence sequence()
Returns iterable index sequence.
Permutation, i.e. (discrete) invertible function int->int.
Helper file generating file names for output files.
static Optional< Size > getDumpIdx(const Path &path)
Extracts the dump index from given path generated by OutputFile.
Path getNextPath(const Statistics &stats) const
Returns path to the next output file.
Path getMask() const
Returns the file mask as given in constructor.
static Optional< OutputFile > getMaskFromPath(const Path &path, const Size firstDumpIdx=0)
Attemps to get the OutputFile from one of the path generated from it.
bool hasWildcard() const
Returns true if the file mask contains (at least one) wildcard.
Object representing a path on a filesystem.
Path & removeExtension()
Removes the extension from the path.
std::string native() const
Returns the native version of the path.
bool empty() const
Checks if the path is empty.
Path fileName() const
Returns the filename of the path.
Path parentPath() const
Returns the parent directory. If the path is empty or root, return empty path.
virtual Expected< Path > dump(const Storage &storage, const Statistics &stats) override
Saves data from particle storage into the file.
PkdgravOutput(const OutputFile &fileMask, PkdgravParams &¶ms)
Generic container for storing scalar, vector or tensor quantity and its derivatives.
void setOrder(const OrderEnum order)
OrderEnum getOrderEnum() const
Returns the order of the quantity.
StaticArray< Array< TValue > &, 3 > getAll()
Returns all buffers of given type stored in this quantity.
ValueEnum getValueEnum() const
Returns the value order of the quantity.
Exception thrown by Deserializer on failure.
virtual const char * what() const noexcept override
Object providing serialization of primitives into a stream.
void write(const TArgs &... args)
TValue get(const TEnum idx, std::enable_if_t<!std::is_enum< std::decay_t< TValue >>::value, int >=0) const
Returns a value of given type from the settings.
static const Settings & getDefaults()
\brief Returns a reference to object containing default values of all settings.
Settings & set(const TEnum idx, TValue &&value, std::enable_if_t<!std::is_enum< std::decay_t< TValue >>::value, int >=0)
Saves a value into the settings.
bool hasType(const TEnum idx) const
Checks if the given entry has specified type.
Array with fixed number of allocated elements.
Object holding various statistics about current run.
TValue get(const StatisticsId idx) const
Returns value of a statistic.
Statistics & set(const StatisticsId idx, TValue &&value)
Sets new values of a statistic.
TValue getOr(const StatisticsId idx, const TValue &other) const
Returns value of a statistic, or a given value if the statistic is not stored.
bool has(const StatisticsId idx) const
Checks if the object contains a statistic with given ID.
Container storing all quantities used within the simulations.
Size getMaterialCnt() const
Return the number of materials in the storage.
void merge(Storage &&other)
Merges another storage into this object.
Quantity & getQuantity(const QuantityId key)
Retrieves quantity with given key from the storage.
Outcome isValid(const Flags< ValidFlag > flags=ValidFlag::COMPLETE) const
Checks whether the storage is in valid state.
Quantity & insert(const QuantityId key, const OrderEnum order, const TValue &defaultValue)
Creates a quantity in the storage, given its key, value type and order.
StaticArray< Array< TValue > &, 3 > getAll(const QuantityId key)
Retrieves quantity buffers from the storage, given its key and value type.
Array< TValue > & getDt(const QuantityId key)
Retrieves a quantity derivative from the storage, given its key and value type.
void removeAll()
Removes all particles with all quantities (including materials) from the storage.
Size getParticleCnt() const
Returns the number of particles.
StorageSequence getQuantities()
Returns the sequence of quantities.
auto getValues(const QuantityId first, const QuantityId second, const TArgs... others)
Retrieves an array of quantities from the key.
Size getQuantityCnt() const
Returns the number of stored quantities.
Array< TValue > & getD2t(const QuantityId key)
Retrieves a quantity second derivative from the storage, given its key and value type.
MaterialView getMaterial(const Size matIdx) const
Returns an object containing a reference to given material.
bool has(const QuantityId key) const
Checks if the storage contains quantity with given key.
Array< TValue > & getValue(const QuantityId key)
Retrieves a quantity values from the storage, given its key and value type.
Symmetric tensor of 2nd order.
Generic 2nd-order tensor with 9 independent components.
Input for the text file, generated by TextOutput or conforming to the same format.
virtual Outcome load(const Path &path, Storage &storage, Statistics &stats) override
Loads data from the file into the storage.
TextInput & addColumn(AutoPtr< ITextColumn > &&column)
TextInput(Flags< OutputQuantityFlag > quantities)
Output saving data to text (human readable) file.
TextOutput(const OutputFile &fileMask, const std::string &runName, Flags< OutputQuantityFlag > quantities, Flags< Options > options=EMPTY_FLAGS)
Creates a new text file output.
virtual Expected< Path > dump(const Storage &storage, const Statistics &stats) override
Saves data from particle storage into the file.
@ DUMP_ALL
Dumps all quantity values from the storage; this overrides the list of selected particles.
@ SCIENTIFIC
Writes all numbers in scientific format.
TextOutput & addColumn(AutoPtr< ITextColumn > &&column)
Adds a new column to be saved into the file.
Symmetric traceless 2nd order tensor.
Returns values of given quantity as stored in storage.
VtkOutput(const OutputFile &fileMask, const Flags< OutputQuantityFlag > flags)
virtual Expected< Path > dump(const Storage &storage, const Statistics &stats) override
Saves data from particle storage into the file.
Creating code components based on values from settings.
BodySettingsId
Settings of a single body / gas phase / ...
constexpr Float au
Astronomical unit (exactly)
constexpr Float day
Number of seconds in a day.
AutoPtr< IMaterial > getMaterial(const BodySettings &settings)
Outcome createDirectory(const Path &path, const Flags< CreateDirectoryFlag > flags=CreateDirectoryFlag::ALLOW_EXISTING)
Creates a directory with given path. Creates all parent directories as well.
Float solveKeplersEquation(const Float M, const Float e, const Size iterCnt=10)
Computes the eccentric anomaly by solving the Kepler's equation.
Overload of std::swap for Sph::Array.
void visit(QuantityId id, Array< AutoPtr< ITextColumn >> &columns)
Conversion factors for pkdgrav.
struct PkdgravParams::Conversion conversion