DNDSR 0.1.0.dev1+gcd065ad
Distributed Numeric Data Structure for CFV
Loading...
Searching...
No Matches
Defines.hpp
Go to the documentation of this file.
1#pragma once
2/// @file Defines.hpp
3/// @brief Core type aliases, constants, and metaprogramming utilities for the DNDS framework.
4
5#include "Macros.hpp"
6// #define NDEBUG
7#include "Errors.hpp"
8#include "EigenPCH.hpp"
9#include <cassert>
10#include <cstddef>
11#include <cstdint>
12#include <cstdio>
13#include <vector>
14#include <memory>
15#include <tuple>
16#include <iostream>
17#include <cmath>
18#include <iomanip>
19#include <string>
20#include <type_traits>
21#include <filesystem>
22#include <functional>
23#include <locale>
24#include <csignal>
25#include <cstdarg>
26#include <cstdlib> // must be included before fmt headers for malloc/free with libc++ _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
27
28#include <fmt/core.h>
29
30#if defined(linux) || defined(_UNIX) || defined(__linux__) || defined(__unix__) || defined(__APPLE__)
31# define DNDS_UNIX_LIKE
32#endif
33
34#ifdef DNDS_USE_OMP
35# include <omp.h>
36#endif
37
38#if defined(_WIN32) || defined(__WINDOWS_)
39// #include <Windows.h>
40// #include <process.h>
41#endif
42
43#define DNDS_FMT_ARG(V) fmt::arg(#V, V)
44
45/***************/ // DNDS_assertS
46
47extern "C" void DNDS_signal_handler(int signal);
48
49namespace DNDS
50{
51 /// @brief Install SEGV / ABRT handlers that print a backtrace via @ref DNDS_signal_handler.
52 /// @details Optional opt-in; not installed automatically so unit test drivers
53 /// keep full control of their own handlers. Typical drivers call this once
54 /// after `MPI_Init` in `main()`.
56 {
57 std::signal(SIGSEGV, DNDS_signal_handler);
58 std::signal(SIGABRT, DNDS_signal_handler);
59 // std::signal(SIGKILL, DNDS_signal_handler);
60 }
61}
62
63/***************/
64
65#ifdef DNDS_USE_CUDA
66# include <cuda_runtime.h>
67#endif
68
69#if defined(DNDS_USE_CUDA)
70# define DNDS_DEVICE_CALLABLE __host__ __device__
71# define DNDS_DEVICE __device__
72# define DNDS_HOST __host__
73# define DNDS_GLOBAL __global__
74# define DNDS_CONSTANT __constant__
75#else
76# define DNDS_DEVICE_CALLABLE
77# define DNDS_DEVICE
78# define DNDS_HOST
79# define DNDS_GLOBAL
80# define DNDS_CONSTANT
81#endif
82
83#define DNDS_DEVICE_TRIVIAL_COPY_DEFINE(T, T_Self) \
84 DNDS_DEVICE_CALLABLE T() = default; \
85 DNDS_DEVICE_CALLABLE T(const T_Self &) = default; \
86 DNDS_DEVICE_CALLABLE T(T_Self &&) = default; \
87 DNDS_DEVICE_CALLABLE T &operator=(const T_Self &) = default; \
88 DNDS_DEVICE_CALLABLE T &operator=(T_Self &&) = default; \
89 DNDS_DEVICE_CALLABLE ~T() = default;
90
91#define DNDS_DEVICE_TRIVIAL_COPY_DEFINE_NO_EMPTY_CTOR(T, T_Self) \
92 DNDS_DEVICE_CALLABLE T(const T_Self &) = default; \
93 DNDS_DEVICE_CALLABLE T(T_Self &&) = default; \
94 DNDS_DEVICE_CALLABLE T &operator=(const T_Self &) = default; \
95 DNDS_DEVICE_CALLABLE T &operator=(T_Self &&) = default; \
96 DNDS_DEVICE_CALLABLE ~T() = default;
97
98/***************/
99
100static_assert(sizeof(uint8_t) == 1, "bad uint8_t");
101
102namespace DNDS
103{
104 /// @brief Canonical floating-point scalar used throughout DNDSR (double precision).
105 using real = double;
106 /// @brief Global row / DOF index type (signed 64-bit; handles multi-billion-cell meshes).
107 using index = int64_t;
108 /// @brief Row-width / per-row element-count type (signed 32-bit).
109 using rowsize = int32_t;
110 /// @brief Integer type with the same width as #real (used for type-punning / packing).
111 using real_sized_index = int64_t;
112 /// @brief Integer type with half the width of #real.
113 using real_half_sized_index = int32_t;
114 static_assert(sizeof(real_sized_index) == sizeof(real) && sizeof(real_half_sized_index) == sizeof(real) / 2);
115
116#define DNDS_INDEX_MAX INT64_MAX
117#define DNDS_INDEX_MIN INT64_MIN
118#define DNDS_ROWSIZE_MAX INT32_MAX
119#define DNDS_ROWSIZE_MIN INT32_MIN
120
121 /// @brief Default column separator for CLI / log output (tab character).
122 static const char *outputDelim = "\t";
123
124 /// @brief Split a global range `[0, nGlobal)` evenly among `nRanks` workers.
125 /// @details Used by the @ref EvenSplit serialization-offset mode and by
126 /// redistribution routines to pick per-rank slabs without exchanging sizes.
127 /// The partition is dense and balanced to within one item.
128 /// @return `[start, end)` for the caller's `rank`.
129 inline std::pair<index, index> EvenSplitRange(int rank, int nRanks, index nGlobal)
130 {
131 index start = index(rank) * nGlobal / index(nRanks);
132 index end = index(rank + 1) * nGlobal / index(nRanks);
133 return {start, end};
134 }
135
136 /// @brief Shortened alias for `std::shared_ptr` used pervasively in DNDSR.
137 template <typename T>
138 using ssp = std::shared_ptr<T>;
139
140 /// @brief Type trait that detects whether a type is a std::shared_ptr wrapping.
141 template <typename T>
142 struct is_ssp : std::false_type
143 {
144 };
145
146 template <typename T>
147 struct is_ssp<ssp<T>> : std::true_type
148 {
149 };
150
151 template <typename T>
152 inline constexpr bool is_ssp_v = is_ssp<T>::value;
153
154 /// @brief Convenience `remove_cv` + `remove_reference` composition (C++17 port of C++20's `std::remove_cvref_t`).
155 template <typename T>
156 using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
157
158 /// @brief Vector of row widths (one `rowsize` per row).
159 using t_RowsizeVec = std::vector<rowsize>;
160 /// @brief Vector of index values (global offsets, local ids, etc.).
161 using t_IndexVec = std::vector<index>;
162 /// @brief Shared pointer alias to t_IndexVec (used by mapping tables shared
163 /// between arrays, see IndexMapping.hpp).
165
166 /// @brief Paired indices, typically `(start, size)` or `(first, last)`.
167 using t_indexerPair = std::tuple<index, index>;
168
169 /// @brief Minimum representable #index value (= @ref INT64_MIN).
170 DNDS_CONSTANT const index indexMin = INT64_MIN;
171
172 /// @brief Sentinel "not initialised" real value (NaN). Cheap to detect with
173 /// `std::isnan` or @ref IsUnInitReal; survives MPI transport unchanged.
175 /// @brief Sentinel "not initialised" index value (= @ref INT64_MIN).
176 DNDS_CONSTANT const index UnInitIndex = INT64_MIN;
177 static_assert(UnInitIndex < 0);
178 /// @brief Sentinel "not initialised" rowsize value (= @ref INT32_MIN).
180 static_assert(UnInitRowsize < 0);
181
182 /// @brief Whether `v` equals the NaN sentinel @ref UnInitReal (tested via `isnan`).
183 inline bool IsUnInitReal(real v)
184 {
185 // return (*(int64_t *)(&v)) == (*(int64_t *)(&UnInitReal));
186 return std::isnan(v);
187 }
188
189 /// @brief Catch-all upper bound ("practically infinity") for physical scalars.
191 /// @brief Loose upper bound (e.g., for non-dimensional limits).
193 /// @brief Catch-all lower bound ("effectively zero").
195 /// @brief Loose lower bound (for iterative-solver tolerances etc.).
197#define DNDS_E_PI 3.1415926535897932384626433832795028841971693993751058209749445923078164062
198 /// @brief π in double precision (matches @ref DNDS_E_PI macro).
200
201 /// @brief Row-major dynamic Eigen matrix used by quadrature / basis tables.
202 using tDiFj = Eigen::Matrix<real, -1, -1, Eigen::RowMajor>;
203
204 /// @brief Column-major dynamic Eigen matrix of reals (default layout).
205 using MatrixXR = Eigen::Matrix<real, Eigen::Dynamic, Eigen::Dynamic>;
206 /// @brief Dynamic Eigen vector of reals.
207 using VectorXR = Eigen::Vector<real, Eigen::Dynamic>;
208 /// @brief Dynamic row-vector of reals.
209 using RowVectorXR = Eigen::RowVector<real, Eigen::Dynamic>;
210
211/// @deprecated Use make_ssp<T>() or make_ssp<T>(ObjName{...}, ...) instead.
212#define DNDS_MAKE_SSP(ssp, ...) (ssp = std::make_shared<typename decltype(ssp)::element_type>(__VA_ARGS__))
213
214 /// @brief Mixin base class providing a runtime instance name for tracing/debugging.
215 ///
216 /// Array and its subclasses inherit this to carry a human-readable name
217 /// (e.g., "coords", "cell2node") that appears in assertion messages.
218 /// Zero overhead when no name is set (empty string).
219 /// NOT added to device-callable types (ArrayView, ArrayLayout).
221 {
222 std::string _objectName;
223
224 public:
225 ObjectNaming() = default;
226 ObjectNaming(const ObjectNaming &) = default;
230 ~ObjectNaming() = default;
231
232 void setObjectName(const std::string &name) { _objectName = name; }
233 [[nodiscard]] const std::string &getObjectName() const { return _objectName; }
234
235 /// Returns "name(sig)" if name is set, or just "sig" otherwise.
236 /// Callers pass the type signature (e.g., GetArrayName()) as `sig`.
237 [[nodiscard]] std::string getObjectIdentity(const std::string &sig) const
238 {
239 if (_objectName.empty())
240 return sig;
241 return fmt::format("{}({})", _objectName, sig);
242 }
243 };
244
245 /// @brief Tag type for naming objects created via make_ssp.
246 ///
247 /// Usage: `auto p = make_ssp<ParArray<index>>(ObjName{"cell2node"}, mpi);`
248 struct ObjName
249 {
250 std::string name;
251 };
252
253 /// @brief Type-safe replacement for DNDS_MAKE_SSP. Creates ssp<T> with forwarded args.
254 template <typename T, typename... Args>
255 ssp<T> make_ssp(Args &&...args)
256 {
257 return std::make_shared<T>(std::forward<Args>(args)...);
258 }
259
260 /// @brief Named variant of make_ssp. If T inherits ObjectNaming, sets the name.
261 ///
262 /// Usage: `auto p = make_ssp<ParArray<index>>(ObjName{"cell2node"}, mpi);`
263 template <typename T, typename... Args>
264 ssp<T> make_ssp(ObjName objName, Args &&...args)
265 {
266 auto p = std::make_shared<T>(std::forward<Args>(args)...);
267 if constexpr (std::is_base_of_v<ObjectNaming, T>)
268 p->setObjectName(objName.name);
269 return p;
270 }
271
272} // namespace DNDS
273
274namespace DNDS
275{
276 /// @brief Template parameter flag: "row width is set at runtime but uniform".
278 /// @brief Template parameter flag: "each row has an independent width".
280 static_assert(DynamicSize != NonUniformSize, "DynamicSize, NonUniformSize definition conflict");
281 /// @brief Alignment flag: no padding applied to rows (the only currently-supported value).
283
284 /// @brief Convert a #rowsize constant to the corresponding Eigen compile-time size.
285 /// Fixed >= 0 -> the value; DynamicSize / NonUniformSize -> Eigen::Dynamic.
287 {
288 return rs >= 0 ? static_cast<int>(rs) : (rs == DynamicSize || rs == NonUniformSize ? Eigen::Dynamic : INT_MIN);
289 }
290
291 /// @brief Encode a #rowsize constant as a short Python-binding snippet:
292 /// "<number>" for fixed, "D" for DynamicSize, "I" for NonUniformSize.
293 /// Used when generating pybind11 class names.
294 inline std::string RowSize_To_PySnippet(rowsize rs)
295 {
296 if (rs >= 0)
297 return fmt::format("{}", rs);
298 else if (rs == DynamicSize)
299 return "D";
300 else if (rs == NonUniformSize)
301 return "I";
302 else
303 {
304 return "Unknown";
305 }
306 }
307
308 /// @brief Encode an alignment value as a Python-binding snippet:
309 /// "N" for @ref NoAlign, the number otherwise.
310 inline std::string Align_To_PySnippet(rowsize al)
311 {
312 if (al == NoAlign)
313 return "N";
314 else if (al < 0)
315 return "Invalid";
316 else
317 return fmt::format("{}", al);
318 }
319}
320
321namespace DNDS
322{
323 /// @brief Shared output stream: where `DNDS::log()` writes progress / diagnostics.
324 /// @details Defaults to `std::cout` when #useCout is true; otherwise refers
325 /// to the file/stream installed via #setLogStream.
326 extern ssp<std::ostream> logStream;
327
328 /// @brief Whether `DNDS::log()` is currently routed to `std::cout`.
329 extern bool useCout;
330
331 /// @brief Return the current DNDSR log stream (either `std::cout` or the installed file).
332 std::ostream &log();
333
334 /// @brief Heuristic detection of whether `ostream` is attached to a terminal.
335 bool ostreamIsTTY(std::ostream &ostream);
336
337 /// @brief Convenience: #ostreamIsTTY applied to the current #log() stream.
338 bool logIsTTY();
339
340 /// @brief Redirect `log()` output to a user-supplied stream. Ownership is shared.
341 void setLogStream(ssp<std::ostream> nstream);
342
343 /// @brief Restore the default `std::cout` routing for `log()`.
344 void setLogStreamCout();
345
346 /// @brief Terminal width in columns (falls back to a fixed default when not a TTY).
347 int get_terminal_width();
348
349 /// @brief Render a textual progress bar to `os` for `progress` in `[0, 1]`.
350 void print_progress(std::ostream &os, double progress);
351}
352
353namespace DNDS
354{
355 /// @brief Read `OMP_NUM_THREADS` env var, returning 1 if unset / invalid.
356 extern int get_env_OMP_NUM_THREADS();
357 /// @brief Read the DNDSR-specific @ref DNDS_DIST_OMP_NUM_THREADS override,
358 /// falling back to #get_env_OMP_NUM_THREADS.
360}
361
362/*
363
364
365
366
367
368
369
370
371
372*/
373
374namespace DNDS
375{
376 /// @brief Overflow-detecting test for `value + increment` on signed integers.
377 /// @return `true` if the addition would overflow.
378 // Generic function to check for overflow in signed integer addition
379 template <typename T>
380 bool signedIntWillAddOverflow(T value, T increment)
381 {
382 static_assert(std::is_signed_v<T> && std::is_integral_v<T>, "T must be a signed integral type");
383 if (increment > 0 && value > std::numeric_limits<T>::max() - increment)
384 return true; // Overflow when adding a positive increment
385 if (increment < 0 && value < std::numeric_limits<T>::min() - increment)
386 return true; // Overflow when adding a negative increment
387 return false; // No overflow
388 }
389
390 /// @brief Add two signed integers, asserting on overflow instead of silently wrapping.
391 /// @throws Dies via @ref DNDS_assert_info if the result would overflow.
392 // Generic function to safely add with overflow check
393 template <typename T>
394 T signedIntSafeAdd(T value, T increment)
395 {
396 static_assert(std::is_signed_v<T> && std::is_integral_v<T>, "T must be a signed integral type");
397 if (signedIntWillAddOverflow<T>(value, increment))
398 {
399 DNDS_assert_info(false, fmt::format("doing [{} + {}] overflow detected", value, increment));
400 return 0;
401 }
402 return value + increment;
403 }
404
405 /// @brief Narrowing `size_t -> T` conversion with range check.
406 /// @tparam T Signed integral target type.
407 /// @throws Dies via @ref DNDS_assert_info if `v > std::numeric_limits<T>::max()`.
408 template <typename T>
410 {
411 static_assert(std::is_signed_v<T> && std::is_integral_v<T>, "T must be a signed integral type");
412 static_assert(std::is_unsigned_v<size_t>, "size_t should be unsigned");
413 if (v <= std::numeric_limits<T>::max())
414 return T(v);
415 else
416 {
417 DNDS_assert_info(false, fmt::format("[{}] from {} to size_t overflow detected", v, typeid(T).name()));
418 return v;
419 }
420 }
421
422 /// @brief Range-checked conversion from size_t to DNDS::index.
423 /// @throws std::runtime_error (via DNDS_assert_info) if value exceeds index max.
424 /// Use this for safe conversions from container sizes (e.g., std::vector::size())
425 /// to DNDS index types, avoiding sign comparison warnings and overflow bugs.
426 inline index size_to_index(size_t v)
427 {
428 return size_t_to_signed<index>(v);
429 }
430
431 /// @brief Range-checked conversion from size_t to DNDS::rowsize.
432 /// @throws std::runtime_error (via DNDS_assert_info) if value exceeds rowsize max.
433 inline rowsize size_to_rowsize(size_t v)
434 {
435 return size_t_to_signed<rowsize>(v);
436 }
437
438 /**
439 * @brief Build a prefix-sum table from a row-size vector.
440 *
441 * @details Resizes `rowstarts` to `rowsizes.size() + 1` and fills it so that
442 * `rowstarts[i] = sum_{k<i} rowsizes[k]`. Asserts on overflow.
443 * Used extensively by CSR @ref DNDS::Array "Array" / ghost-indexing to turn row-count vectors
444 * into offset vectors.
445 *
446 * @tparam TtRowsizeVec `std::vector`-like of row sizes (e.g. `rowsize`).
447 * @tparam TtIndexVec `std::vector`-like of offsets (e.g. `index`), must
448 * have a strictly wider range than the row-size type.
449 */
450 // Note that TtIndexVec being accumulated could overflow
451 template <class TtRowsizeVec, class TtIndexVec>
452 inline void AccumulateRowSize(const TtRowsizeVec &rowsizes, TtIndexVec &rowstarts)
453 {
454 static_assert(std::is_signed_v<typename TtIndexVec::value_type>, "row starts should be signed");
455 static_assert(std::numeric_limits<typename TtIndexVec::value_type>::max() >=
456 std::numeric_limits<typename TtRowsizeVec::value_type>::max(),
457 "row starts should have larger upper limit");
458 rowstarts.resize(rowsizes.size() + 1);
459 rowstarts[0] = 0;
460 for (typename TtIndexVec::size_type i = 1; i < rowstarts.size(); i++)
461 {
462 rowstarts[i] = signedIntSafeAdd<typename TtIndexVec::value_type>(rowstarts[i - 1], rowsizes[i - 1]);
463 }
464 }
465
466 /// @brief Whether all elements of `dat` are equal; if so, stores the value into `value`.
467 /// @return false if the vector is empty or contains at least two distinct values.
468 template <class T>
469 inline bool checkUniformVector(const std::vector<T> &dat, T &value)
470 {
471 if (dat.empty())
472 return false;
473 value = dat[0];
474 for (auto i = 1; i < dat.size(); i++)
475 if (dat[i] != value)
476 return false;
477 return true;
478 }
479
480 /// @brief Print a vector to `out` with #outputDelim between elements.
481 /// @tparam TP Optional cast type (e.g., promote `int8_t` to `int` to avoid
482 /// character printing).
483 template <class T, class TP = T>
484 inline void PrintVec(const std::vector<T> &dat, std::ostream &out)
485 {
486 for (auto i = 0; i < dat.size(); i++)
487 out << TP(dat[i]) << outputDelim;
488 }
489
490 /// @brief Integer ceiling division. `l` must be non-negative, `r` positive.
491 /// @bug The current expression has incorrect precedence; see #divide_ceil for
492 /// the corrected version. Do not use new code with `divCeil`.
493 /// \brief l must be non-negative, r must be positive. integers
494 template <class TL, class TR>
495 constexpr auto divCeil(TL l, TR r)
496 {
497 return l / r + (l % r) ? 1 : 0;
498 }
499}
500
501/*
502
503
504
505
506
507
508
509
510
511*/
512
513namespace DNDS
514{
515 /// @brief `a * a`, constexpr. Works for all arithmetic types.
516 template <typename T>
517 constexpr T sqr(const T &a)
518 {
519 static_assert(std::is_arithmetic_v<T>, "need arithmetic");
520 return a * a;
521 }
522
523 /// @brief `a * a * a`, constexpr.
524 template <typename T>
525 constexpr T cube(const T &a)
526 {
527 static_assert(std::is_arithmetic_v<T>, "need arithmetic");
528 return a * a * a;
529 }
530
531 /// @brief Signum function: +1, 0, or -1.
532 constexpr real sign(real a)
533 {
534 return a > 0 ? 1 : (a < 0 ? -1 : 0);
535 }
536
537 /// @brief Tolerant signum: returns 0 inside `[-tol, tol]`.
538 constexpr real signTol(real a, real tol)
539 {
540 return a > tol ? 1 : (a < -tol ? -1 : 0);
541 }
542
543 /// @brief "Signum, biased toward +1": treats 0 as positive.
544 constexpr real signP(real a)
545 {
546 return a >= 0 ? 1 : -1;
547 }
548
549 /// @brief "Signum, biased toward -1": treats 0 as negative.
550 constexpr real signM(real a)
551 {
552 return a <= 0 ? -1 : 1;
553 }
554
555 /// @brief Mathematical modulo that always returns a non-negative result.
556 /// Unlike `%` in C++ where `(-1) % 3 == -1`, `mod(-1, 3) == 2`.
557 template <typename T>
558 constexpr T mod(T a, T b)
559 {
560 static_assert(std::is_signed<T>::value && std::is_integral<T>::value, "not legal mod type");
561 T val = a % b;
562 if (val < 0)
563 val += b;
564 return val;
565 }
566
567 /// @brief Integer ceiling division `ceil(a / b)`. Correct for all signs.
568 template <typename T>
569 constexpr T divide_ceil(T a, T b)
570 {
571 static_assert(std::is_integral<T>::value, "not legal mod type");
572 return a / b + (a % b ? 1 : 0);
573 }
574 // const int a = divide_ceil(23, 11);
575
576 /**
577 * @brief Floating-point modulo matching Python's `%` (result has sign of `b`).
578 * @param b Must be positive.
579 */
581 {
582 return a - std::floor(a / b) * b;
583 }
584
585 /**
586 * @brief Walk two ordered ranges in lockstep, calling `F` on each match.
587 *
588 * @details Two-pointer algorithm. Requires both ranges to be sorted in
589 * ascending order; advances the smaller side at each step. Exits early
590 * (returning `true`) if `F(value, pos1, pos2)` returns `true`.
591 *
592 * @tparam tF Callable `bool(value, size_t pos1, size_t pos2)`.
593 * @return true if the functor short-circuited, false if ranges were walked to completion.
594 */
595 template <class tIt1, class tIt1end, class tIt2, class tIt2end, class tF>
596 bool iterateIdentical(tIt1 it1, tIt1end it1end, tIt2 it2, tIt2end it2end, tF F)
597 {
598 size_t it1Pos{0}, it2Pos{0};
599 while (it1 != it1end && it2 != it2end)
600 {
601 if ((*it1) < (*it2))
602 ++it1, ++it1Pos;
603 else if ((*it1) > (*it2))
604 ++it2, ++it2Pos;
605 else if ((*it1) == (*it2))
606 {
607 if (F(*it1, it1Pos, it2Pos))
608 return true;
609 ++it1, ++it1Pos;
610 ++it2, ++it2Pos;
611 }
612 }
613 return false;
614 }
615
616 ///@todo //TODO: overflow_assign_int64_to_32
617
618 /// @brief Narrow #index to `int32_t` with range check; dies on overflow.
619 inline int32_t checkedIndexTo32(index v)
620 {
621 DNDS_assert_info(!(v > static_cast<index>(INT32_MAX) || v < static_cast<index>(INT32_MIN)),
622 fmt::format("Index {} to int32 overflow", v));
623 return static_cast<int32_t>(v);
624 }
625
626 /// @brief Convert a `wstring` to `string` (UTF-8 on Windows, byte-cast elsewhere).
627 std::string getStringForceWString(const std::wstring &v);
628
629 /// @brief Portable conversion of a platform-native path string to `std::string`.
630 inline std::string getStringForcePath(const std::filesystem::path::string_type &v)
631 {
632#ifdef _WIN32
633 return getStringForceWString(v);
634#else
635 return std::string{v};
636#endif
637 }
638
639}
640
641namespace DNDS
642{
643#if EIGEN_MAJOR_VERSION >= 5
644 /// @brief Eigen "select every index" placeholder (compatibility wrapper across Eigen versions).
645 static const auto EigenAll = Eigen::placeholders::all;
646 /// @brief Eigen "last index" placeholder (compatibility wrapper across Eigen versions).
647 static const auto EigenLast = Eigen::placeholders::last;
648#else
649 static const auto EigenAll = Eigen::all;
650 static const auto EigenLast = Eigen::last;
651#endif
652
653}
654
655/*-----------------------------------------*/
656// some meta-programming utilities
657namespace DNDS::Meta
658{
659 template <typename T>
660 inline constexpr bool always_false = false;
661
662 /// @brief Type trait that detects whether a type is a std::array.
663 template <class T>
664 struct is_std_array : std::false_type
665 {
666 };
667
668 template <class T, size_t N>
669 struct is_std_array<std::array<T, N>> : std::true_type
670 {
671 };
672
673 /// @brief Type trait that detects whether a type is a std::vector.
674 template <class T>
675 struct is_std_vector : std::false_type
676 {
677 };
678
679 template <class T, class Allocator>
680 struct is_std_vector<std::vector<T, Allocator>> : std::true_type
681 {
682 };
683
684 template <typename _Tp>
686
687 static_assert(is_std_array_v<std::array<real, 5>> && (!is_std_array_v<std::vector<real>>)); // basic test
688
689 /**
690 * @brief see if the Actual valid data is in the struct scope (memcpy copyable)
691 * @details
692 * generally a fixed size Eigen::Matrix, but it seems std::is_trivially_copyable_v<> does not distinguish that,
693 * see https://eigen.tuxfamily.org/dox/classEigen_1_1Matrix.html, ABI part
694 * ```
695 * static_assert(!is_fixed_data_real_eigen_matrix_v<std::array<real, 10>> &&
696 is_fixed_data_real_eigen_matrix_v<Eigen::Matrix<real, 2, 2>> &&
697 !is_fixed_data_real_eigen_matrix_v<Eigen::Matrix<real, -1, 2>> &&
698 is_fixed_data_real_eigen_matrix_v<Eigen::Vector2d> &&
699 !is_fixed_data_real_eigen_matrix_v<Eigen::Vector2f> &&
700 is_fixed_data_real_eigen_matrix_v<Eigen::Matrix<real, -1, -1, Eigen::DontAlign, 2, 2>> &&
701 !is_fixed_data_real_eigen_matrix_v<Eigen::Matrix<real, -1, -1, Eigen::DontAlign, -1, 2>> &&
702 !is_fixed_data_real_eigen_matrix_v<Eigen::MatrixXd>,
703 "is_fixed_data_real_eigen_matrix_v bad");
704 * ```
705 *
706 * @tparam T
707 */
708
709 template <class T>
711 {
712 static constexpr bool value = false;
713 };
714
715 template <class T, int M, int N, int options, int max_m, int max_n>
716 struct is_fixed_data_real_eigen_matrix<Eigen::Matrix<T, M, N, options, max_m, max_n>>
717 {
718 static constexpr bool value = std::is_same_v<real, T> &&
719 ((M > 0 && N > 0) ||
720 (max_m > 0 && max_n > 0));
721 };
722
723 template <typename _Tp>
725
726 static_assert(!is_fixed_data_real_eigen_matrix_v<std::array<real, 10>> &&
727 is_fixed_data_real_eigen_matrix_v<Eigen::Matrix<real, 2, 2>> &&
728 !is_fixed_data_real_eigen_matrix_v<Eigen::Matrix<real, -1, 2>> &&
729 is_fixed_data_real_eigen_matrix_v<Eigen::Vector2d> &&
730 !is_fixed_data_real_eigen_matrix_v<Eigen::Vector2f> &&
731 is_fixed_data_real_eigen_matrix_v<Eigen::Matrix<real, -1, -1, Eigen::DontAlign, 2, 2>> &&
732 !is_fixed_data_real_eigen_matrix_v<Eigen::Matrix<real, -1, -1, Eigen::DontAlign, -1, 2>> &&
733 !is_fixed_data_real_eigen_matrix_v<Eigen::MatrixXd>,
734 "is_fixed_data_real_eigen_matrix_v bad");
735
736 template <typename T>
737 inline constexpr bool is_eigen_dense_v = std::is_base_of_v<Eigen::DenseBase<T>, T>;
738
739 /// @brief Type trait that detects whether a type is an Eigen::Matrix with `real` scalar type.
740 template <class T>
742 {
743 static constexpr bool value = false;
744 };
745
746 template <int M, int N, int options, int max_m, int max_n>
747 struct is_real_eigen_matrix<Eigen::Matrix<real, M, N, options, max_m, max_n>>
748 {
749 static constexpr bool value = true;
750 };
751
752 template <class T>
754
755 /// @brief Type trait that detects whether std::hash is specialized for a given type.
756 template <typename T, typename = void>
757 struct has_std_hash : std::false_type
758 {
759 };
760
761 template <typename T>
762 struct has_std_hash<T, std::void_t<decltype(std::hash<T>{}(std::declval<T>()))>> : std::true_type
763 {
764 };
765
766 static_assert(has_std_hash<double>::value);
767 static_assert(!has_std_hash<std::vector<std::string>>::value);
768}
769
770namespace DNDS
771{
772 inline std::vector<std::string> splitSString(const std::string &str, char delim) // TODO: make more C++
773 {
774 std::vector<std::string> ret;
775 size_t top = 0;
776 size_t bot = 0;
777 while (top < str.size() + 1)
778 {
779 if (str[top] != delim && top != str.size())
780 {
781 top++;
782 continue;
783 }
784 ret.push_back(str.substr(bot, top - bot));
785 bot = ++top;
786 }
787 return ret;
788 }
789
790 inline std::vector<std::string> splitSStringClean(const std::string &str, char delim)
791 {
792 std::vector<std::string> ret0 = splitSString(str, delim);
793 std::vector<std::string> ret;
794 for (auto &v : ret0)
795 if (!v.empty())
796 ret.push_back(v);
797 return ret;
798 }
799
800 inline bool sstringHasSuffix(const std::string &str, const std::string &suffix)
801 {
802 if (str.size() < suffix.size())
803 return false;
804 return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
805 }
806
807 /// @brief Hash functor for std::vector<T>, combining element hashes via XOR.
808 template <typename T>
810 {
811 std::size_t operator()(const std::vector<T> &v) const noexcept
812 {
813 std::size_t r = 0;
814 if constexpr (Meta::has_std_hash<T>::value)
815 for (auto &i : v)
816 r = r ^ std::hash<T>{}(i);
817 else if constexpr (Meta::is_std_vector<T>::value)
818 for (auto &i : v)
820 else
821 {
822 for (size_t i = 0; i < v.size() * sizeof(T); i++)
823 r = r ^ std::hash<uint8_t>{}(((uint8_t *)(v.data()))[i]);
824 }
825 return r;
826 }
827
828 template <class TBegin, class TEnd>
829 std::size_t operator()(TBegin &&begin, TEnd &&end) const noexcept
830 {
831 std::size_t r = 0;
832 ptrdiff_t size = end - begin;
833 if constexpr (Meta::has_std_hash<T>::value)
834 for (ptrdiff_t i = 0; i < size; i++)
835 r = r ^ std::hash<T>{}(begin[i]);
836 else if constexpr (Meta::is_std_vector<T>::value)
837 for (ptrdiff_t i = 0; i < size; i++)
839 else
840 {
841 auto *start = reinterpret_cast<uint8_t *>(&(*begin));
842 for (size_t i = 0; i < size * sizeof(T); i++)
843 r = r ^ std::hash<uint8_t>{}(start[i]);
844 }
845 return r;
846 }
847 };
848
849 /// @brief Hash functor for std::array<T, s>, combining element hashes via XOR.
850 template <typename T, std::size_t s>
852 {
853 std::size_t operator()(const std::array<T, s> &v) const noexcept
854 {
855 std::size_t r = 0;
856 for (auto i : v)
857 {
858 r = r ^ std::hash<decltype(i)>()(i);
859 }
860 return r;
861 }
862 };
863
864}
865
867{
868 /// @brief ANSI escape: bright red foreground.
869 constexpr std::string_view Red = "\033[91m";
870 /// @brief ANSI escape: bright green foreground.
871 constexpr std::string_view Green = "\033[92m";
872 /// @brief ANSI escape: bright yellow foreground.
873 constexpr std::string_view Yellow = "\033[93m";
874 /// @brief ANSI escape: bright blue foreground.
875 constexpr std::string_view Blue = "\033[94m";
876 /// @brief ANSI escape: bright magenta foreground.
877 constexpr std::string_view Magenta = "\033[95m";
878 /// @brief ANSI escape: bright cyan foreground.
879 constexpr std::string_view Cyan = "\033[96m";
880 /// @brief ANSI escape: bright white foreground.
881 constexpr std::string_view White = "\033[97m";
882 /// @brief ANSI escape: reset all attributes.
883 constexpr std::string_view Reset = "\033[0m";
884 /// @brief ANSI escape: bold.
885 constexpr std::string_view Bold = "\033[1m";
886 /// @brief ANSI escape: underline.
887 constexpr std::string_view Underline = "\033[4m";
888 /// @brief ANSI escape: blinking text.
889 constexpr std::string_view Blink = "\033[5m";
890 /// @brief ANSI escape: reverse (swap fg/bg).
891 constexpr std::string_view Reverse = "\033[7m";
892 /// @brief ANSI escape: hidden text.
893 constexpr std::string_view Hidden = "\033[8m";
894
895}
896/*
897
898
899
900
901
902
903
904
905
906*/
907
908namespace DNDS
909{
910 /// @brief Trivially-copyable empty placeholder type that accepts any assignment.
911 struct Empty
912 {
914 template <class T>
915 DNDS_DEVICE_CALLABLE Empty &operator=(T v) { return *this; };
916 template <class T>
918 };
919
920 /// @brief Empty placeholder type without a default constructor; accepts any assignment.
931}
932/*
933
934
935
936
937
938
939
940
941
942*/
943
944namespace DNDS
945{
946 /// @brief Read/set the build version string accessible from code.
947 /// @details When `ver` is non-empty it replaces the stored value; always
948 /// returns the current value. Written into HDF5 attributes for traceability.
949 std::string GetSetVersionName(const std::string &ver = "");
950}
951
952/*
953
954
955
956
957
958
959
960
961
962
963
964*/
965
966#if defined(_MSC_VER)
967/// @brief `restrict`-pointer attribute (MSVC spelling).
968# define DNDS_RESTRICT __restrict
969/// @brief Force-inline attribute (MSVC spelling).
970# define DNDS_FORCEINLINE __forceinline
971#elif defined(__GNUC__) || defined(__clang__)
972/// @brief `restrict`-pointer attribute (GCC/Clang spelling).
973# define DNDS_RESTRICT __restrict__
974/// @brief Force-inline attribute (GCC/Clang spelling).
975# define DNDS_FORCEINLINE inline __attribute__((always_inline))
976#else
977# define DNDS_RESTRICT
978# define DNDS_FORCEINLINE
979#endif
void DNDS_signal_handler(int signal)
Definition Defines.cpp:26
#define DNDS_DEVICE_TRIVIAL_COPY_DEFINE(T, T_Self)
Definition Defines.hpp:83
#define DNDS_DEVICE_CALLABLE
Definition Defines.hpp:76
#define DNDS_E_PI
Definition Defines.hpp:197
void DNDS_signal_handler(int signal)
Definition Defines.cpp:26
#define DNDS_CONSTANT
Definition Defines.hpp:80
Pre-compiled-header style shim that includes the heavy Eigen headers under DNDSR's warning suppressio...
Assertion / error-handling macros and supporting helper functions.
#define DNDS_assert_info(expr, info)
Debug-only assertion with an extra std::string info message.
Definition Errors.hpp:113
Project-wide preprocessor flags, branch-hint macros, and version/build metadata strings....
Mixin base class providing a runtime instance name for tracing/debugging.
Definition Defines.hpp:221
std::string getObjectIdentity(const std::string &sig) const
Definition Defines.hpp:237
ObjectNaming(ObjectNaming &&)=default
ObjectNaming & operator=(ObjectNaming &&)=default
ObjectNaming & operator=(const ObjectNaming &)=default
ObjectNaming()=default
const std::string & getObjectName() const
Definition Defines.hpp:233
~ObjectNaming()=default
ObjectNaming(const ObjectNaming &)=default
void setObjectName(const std::string &name)
Definition Defines.hpp:232
constexpr bool is_fixed_data_real_eigen_matrix_v
Definition Defines.hpp:724
constexpr bool is_std_array_v
Definition Defines.hpp:685
constexpr bool is_eigen_dense_v
Definition Defines.hpp:737
constexpr bool always_false
Definition Defines.hpp:660
constexpr bool is_real_eigen_matrix_v
Definition Defines.hpp:753
constexpr std::string_view Blue
ANSI escape: bright blue foreground.
Definition Defines.hpp:875
constexpr std::string_view Blink
ANSI escape: blinking text.
Definition Defines.hpp:889
constexpr std::string_view Cyan
ANSI escape: bright cyan foreground.
Definition Defines.hpp:879
constexpr std::string_view Magenta
ANSI escape: bright magenta foreground.
Definition Defines.hpp:877
constexpr std::string_view Reverse
ANSI escape: reverse (swap fg/bg).
Definition Defines.hpp:891
constexpr std::string_view White
ANSI escape: bright white foreground.
Definition Defines.hpp:881
constexpr std::string_view Reset
ANSI escape: reset all attributes.
Definition Defines.hpp:883
constexpr std::string_view Green
ANSI escape: bright green foreground.
Definition Defines.hpp:871
constexpr std::string_view Yellow
ANSI escape: bright yellow foreground.
Definition Defines.hpp:873
constexpr std::string_view Red
ANSI escape: bright red foreground.
Definition Defines.hpp:869
constexpr std::string_view Bold
ANSI escape: bold.
Definition Defines.hpp:885
constexpr std::string_view Underline
ANSI escape: underline.
Definition Defines.hpp:887
constexpr std::string_view Hidden
ANSI escape: hidden text.
Definition Defines.hpp:893
the host side operators are provided as implemented
constexpr T cube(const T &a)
a * a * a, constexpr.
Definition Defines.hpp:525
bool signedIntWillAddOverflow(T value, T increment)
Overflow-detecting test for value + increment on signed integers.
Definition Defines.hpp:380
std::vector< rowsize > t_RowsizeVec
Vector of row widths (one rowsize per row).
Definition Defines.hpp:159
int32_t real_half_sized_index
Integer type with half the width of real.
Definition Defines.hpp:113
ssp< std::ostream > logStream
Shared output stream: where DNDS::log() writes progress / diagnostics.
Definition Defines.cpp:45
void PrintVec(const std::vector< T > &dat, std::ostream &out)
Print a vector to out with outputDelim between elements.
Definition Defines.hpp:484
constexpr real signM(real a)
"Signum, biased toward -1": treats 0 as negative.
Definition Defines.hpp:550
int get_env_OMP_NUM_THREADS()
Read OMP_NUM_THREADS env var, returning 1 if unset / invalid.
Definition Defines.cpp:119
DNDS_CONSTANT const index UnInitIndex
Sentinel "not initialised" index value (= INT64_MIN).
Definition Defines.hpp:176
rowsize size_to_rowsize(size_t v)
Range-checked conversion from size_t to DNDS::rowsize.
Definition Defines.hpp:433
bool sstringHasSuffix(const std::string &str, const std::string &suffix)
Definition Defines.hpp:800
int32_t checkedIndexTo32(index v)
Narrow index to int32_t with range check; dies on overflow.
Definition Defines.hpp:619
DNDS_CONSTANT const rowsize NoAlign
Alignment flag: no padding applied to rows (the only currently-supported value).
Definition Defines.hpp:282
DNDS_CONSTANT const real verySmallReal
Catch-all lower bound ("effectively zero").
Definition Defines.hpp:194
constexpr int RowSize_To_EigenSize(rowsize rs)
Convert a rowsize constant to the corresponding Eigen compile-time size. Fixed >= 0 -> the value; Dyn...
Definition Defines.hpp:286
T size_t_to_signed(size_t v)
Narrowing size_t -> T conversion with range check.
Definition Defines.hpp:409
constexpr bool is_ssp_v
Definition Defines.hpp:152
std::remove_cv_t< std::remove_reference_t< T > > remove_cvref_t
Convenience remove_cv + remove_reference composition (C++17 port of C++20's std::remove_cvref_t).
Definition Defines.hpp:156
int64_t real_sized_index
Integer type with the same width as real (used for type-punning / packing).
Definition Defines.hpp:111
void RegisterSignalHandler()
Install SEGV / ABRT handlers that print a backtrace via DNDS_signal_handler.
Definition Defines.hpp:55
int32_t rowsize
Row-width / per-row element-count type (signed 32-bit).
Definition Defines.hpp:109
DNDS_CONSTANT const real pi
π in double precision (matches DNDS_E_PI macro).
Definition Defines.hpp:199
constexpr real signTol(real a, real tol)
Tolerant signum: returns 0 inside [-tol, tol].
Definition Defines.hpp:538
DNDS_CONSTANT const rowsize DynamicSize
Template parameter flag: "row width is set at runtime but uniform".
Definition Defines.hpp:277
DNDS_CONSTANT const real UnInitReal
Sentinel "not initialised" real value (NaN). Cheap to detect with std::isnan or IsUnInitReal; survive...
Definition Defines.hpp:174
void AccumulateRowSize(const TtRowsizeVec &rowsizes, TtIndexVec &rowstarts)
Build a prefix-sum table from a row-size vector.
Definition Defines.hpp:452
constexpr T divide_ceil(T a, T b)
Integer ceiling division ceil(a / b). Correct for all signs.
Definition Defines.hpp:569
constexpr auto divCeil(TL l, TR r)
Integer ceiling division. l must be non-negative, r positive.
Definition Defines.hpp:495
constexpr real sign(real a)
Signum function: +1, 0, or -1.
Definition Defines.hpp:532
DNDS_CONSTANT const rowsize NonUniformSize
Template parameter flag: "each row has an independent width".
Definition Defines.hpp:279
std::pair< index, index > EvenSplitRange(int rank, int nRanks, index nGlobal)
Split a global range [0, nGlobal) evenly among nRanks workers.
Definition Defines.hpp:129
void setLogStream(ssp< std::ostream > nstream)
Redirect log() output to a user-supplied stream. Ownership is shared.
Definition Defines.cpp:53
std::string RowSize_To_PySnippet(rowsize rs)
Encode a rowsize constant as a short Python-binding snippet: "<number>" for fixed,...
Definition Defines.hpp:294
std::vector< index > t_IndexVec
Vector of index values (global offsets, local ids, etc.).
Definition Defines.hpp:161
bool checkUniformVector(const std::vector< T > &dat, T &value)
Whether all elements of dat are equal; if so, stores the value into value.
Definition Defines.hpp:469
std::tuple< index, index > t_indexerPair
Paired indices, typically (start, size) or (first, last).
Definition Defines.hpp:167
std::vector< std::string > splitSString(const std::string &str, char delim)
Definition Defines.hpp:772
bool logIsTTY()
Convenience: ostreamIsTTY applied to the current log() stream.
Definition Defines.cpp:51
T signedIntSafeAdd(T value, T increment)
Add two signed integers, asserting on overflow instead of silently wrapping.
Definition Defines.hpp:394
Eigen::Matrix< real, Eigen::Dynamic, Eigen::Dynamic > MatrixXR
Column-major dynamic Eigen matrix of reals (default layout).
Definition Defines.hpp:205
int get_terminal_width()
Terminal width in columns (falls back to a fixed default when not a TTY).
Definition Defines.cpp:57
index size_to_index(size_t v)
Range-checked conversion from size_t to DNDS::index.
Definition Defines.hpp:426
bool IsUnInitReal(real v)
Whether v equals the NaN sentinel UnInitReal (tested via isnan).
Definition Defines.hpp:183
DNDS_CONSTANT const real largeReal
Loose upper bound (e.g., for non-dimensional limits).
Definition Defines.hpp:192
int64_t index
Global row / DOF index type (signed 64-bit; handles multi-billion-cell meshes).
Definition Defines.hpp:107
constexpr T mod(T a, T b)
Mathematical modulo that always returns a non-negative result. Unlike % in C++ where (-1) % 3 == -1,...
Definition Defines.hpp:558
std::string getStringForcePath(const std::filesystem::path::string_type &v)
Portable conversion of a platform-native path string to std::string.
Definition Defines.hpp:630
std::string getStringForceWString(const std::wstring &v)
Convert a wstring to string (UTF-8 on Windows, byte-cast elsewhere).
Definition Defines.cpp:104
constexpr T sqr(const T &a)
a * a, constexpr. Works for all arithmetic types.
Definition Defines.hpp:517
Eigen::RowVector< real, Eigen::Dynamic > RowVectorXR
Dynamic row-vector of reals.
Definition Defines.hpp:209
Eigen::Matrix< real, -1, -1, Eigen::RowMajor > tDiFj
Row-major dynamic Eigen matrix used by quadrature / basis tables.
Definition Defines.hpp:202
int get_env_DNDS_DIST_OMP_NUM_THREADS()
Read the DNDSR-specific DNDS_DIST_OMP_NUM_THREADS override, falling back to get_env_OMP_NUM_THREADS.
Definition Defines.cpp:139
std::shared_ptr< T > ssp
Shortened alias for std::shared_ptr used pervasively in DNDSR.
Definition Defines.hpp:138
DNDS_CONSTANT const index indexMin
Minimum representable index value (= INT64_MIN).
Definition Defines.hpp:170
double real
Canonical floating-point scalar used throughout DNDSR (double precision).
Definition Defines.hpp:105
constexpr real signP(real a)
"Signum, biased toward +1": treats 0 as positive.
Definition Defines.hpp:544
ssp< T > make_ssp(Args &&...args)
Type-safe replacement for DNDS_MAKE_SSP. Creates ssp<T> with forwarded args.
Definition Defines.hpp:255
bool ostreamIsTTY(std::ostream &ostream)
Heuristic detection of whether ostream is attached to a terminal.
Definition Defines.cpp:36
ssp< t_IndexVec > t_pIndexVec
Shared pointer alias to t_IndexVec (used by mapping tables shared between arrays, see IndexMapping....
Definition Defines.hpp:164
std::vector< std::string > splitSStringClean(const std::string &str, char delim)
Definition Defines.hpp:790
void print_progress(std::ostream &os, double progress)
Render a textual progress bar to os for progress in [0, 1].
Definition Defines.cpp:75
real float_mod(real a, real b)
Floating-point modulo matching Python's % (result has sign of b).
Definition Defines.hpp:580
std::string Align_To_PySnippet(rowsize al)
Encode an alignment value as a Python-binding snippet: "N" for NoAlign, the number otherwise.
Definition Defines.hpp:310
DNDS_CONSTANT const real smallReal
Loose lower bound (for iterative-solver tolerances etc.).
Definition Defines.hpp:196
Eigen::Vector< real, Eigen::Dynamic > VectorXR
Dynamic Eigen vector of reals.
Definition Defines.hpp:207
std::ostream & log()
Return the current DNDSR log stream (either std::cout or the installed file).
Definition Defines.cpp:49
bool iterateIdentical(tIt1 it1, tIt1end it1end, tIt2 it2, tIt2end it2end, tF F)
Walk two ordered ranges in lockstep, calling F on each match.
Definition Defines.hpp:596
DNDS_CONSTANT const real veryLargeReal
Catch-all upper bound ("practically infinity") for physical scalars.
Definition Defines.hpp:190
bool useCout
Whether DNDS::log() is currently routed to std::cout.
Definition Defines.cpp:47
void setLogStreamCout()
Restore the default std::cout routing for log().
Definition Defines.cpp:55
std::string GetSetVersionName(const std::string &ver)
Read/set the build version string accessible from code.
Definition Defines.cpp:172
DNDS_CONSTANT const rowsize UnInitRowsize
Sentinel "not initialised" rowsize value (= INT32_MIN).
Definition Defines.hpp:179
Empty placeholder type without a default constructor; accepts any assignment.
Definition Defines.hpp:922
DNDS_DEVICE_CALLABLE EmptyNoDefault(EmptyNoDefault &&v)=default
DNDS_DEVICE_CALLABLE EmptyNoDefault(const EmptyNoDefault &v)=default
DNDS_DEVICE_CALLABLE EmptyNoDefault & operator=(T v)
Definition Defines.hpp:927
DNDS_DEVICE_CALLABLE EmptyNoDefault(T v)
Definition Defines.hpp:929
DNDS_DEVICE_CALLABLE EmptyNoDefault & operator=(const EmptyNoDefault &)=default
Trivially-copyable empty placeholder type that accepts any assignment.
Definition Defines.hpp:912
DNDS_DEVICE_CALLABLE Empty & operator=(T v)
Definition Defines.hpp:915
DNDS_DEVICE_CALLABLE Empty(T v)
Definition Defines.hpp:917
Type trait that detects whether std::hash is specialized for a given type.
Definition Defines.hpp:758
see if the Actual valid data is in the struct scope (memcpy copyable)
Definition Defines.hpp:711
Type trait that detects whether a type is an Eigen::Matrix with real scalar type.
Definition Defines.hpp:742
static constexpr bool value
Definition Defines.hpp:743
Type trait that detects whether a type is a std::array.
Definition Defines.hpp:665
Type trait that detects whether a type is a std::vector.
Definition Defines.hpp:676
Tag type for naming objects created via make_ssp.
Definition Defines.hpp:249
std::string name
Definition Defines.hpp:250
Hash functor for std::array<T, s>, combining element hashes via XOR.
Definition Defines.hpp:852
std::size_t operator()(const std::array< T, s > &v) const noexcept
Definition Defines.hpp:853
Type trait that detects whether a type is a std::shared_ptr wrapping.
Definition Defines.hpp:143
Hash functor for std::vector<T>, combining element hashes via XOR.
Definition Defines.hpp:810
std::size_t operator()(const std::vector< T > &v) const noexcept
Definition Defines.hpp:811
std::size_t operator()(TBegin &&begin, TEnd &&end) const noexcept
Definition Defines.hpp:829
Eigen::Matrix< real, 5, 1 > v
constexpr DNDS::index N
tVec r(NCells)
tVec b(NCells)