17#define DOCTEST_CONFIG_IMPLEMENT
24int main(
int argc,
char **argv)
26 MPI_Init(&argc, &argv);
28 ctx.applyCommandLine(argc, argv);
48template <
int M,
int N>
54 dof.
father->Resize(nCells, mRow, nCol);
55 dof.
son->Resize(0, mRow, nCol);
66 auto dof = makeDof<5, 1>(mpi,
N);
68 SUBCASE(
"setConstant with scalar")
74 for (
int r = 0;
r < mat.rows();
r++)
75 CHECK(mat(
r, 0) == doctest::Approx(2.0));
79 SUBCASE(
"setConstant with Eigen matrix")
81 Eigen::Matrix<real, 5, 1>
v;
82 v << 1.0, 2.0, 3.0, 4.0, 5.0;
88 CHECK(mat(0, 0) == doctest::Approx(1.0));
89 CHECK(mat(1, 0) == doctest::Approx(2.0));
90 CHECK(mat(2, 0) == doctest::Approx(3.0));
91 CHECK(mat(3, 0) == doctest::Approx(4.0));
92 CHECK(mat(4, 0) == doctest::Approx(5.0));
103 auto dof1 = makeDof<5, 1>(mpi,
N);
104 dof1.setConstant(1.0);
113 for (
int r = 0;
r < mat.rows();
r++)
114 CHECK(mat(
r, 0) == doctest::Approx(3.0));
118 SUBCASE(
"+= another ArrayDof")
122 auto dof2 = makeDof<5, 1>(mpi,
N);
123 dof2.setConstant(10.0);
130 for (
int r = 0;
r < mat.rows();
r++)
131 CHECK(mat(
r, 0) == doctest::Approx(13.0));
135 SUBCASE(
"+= Eigen matrix")
137 Eigen::Matrix<real, 5, 1>
v;
138 v << 10.0, 20.0, 30.0, 40.0, 50.0;
144 CHECK(mat(0, 0) == doctest::Approx(11.0));
145 CHECK(mat(1, 0) == doctest::Approx(21.0));
146 CHECK(mat(2, 0) == doctest::Approx(31.0));
147 CHECK(mat(3, 0) == doctest::Approx(41.0));
148 CHECK(mat(4, 0) == doctest::Approx(51.0));
154TEST_CASE(
"ArrayDOF operator-= and operator*=")
159 auto dof1 = makeDof<5, 1>(mpi,
N);
160 auto dof2 = makeDof<5, 1>(mpi,
N);
161 dof1.setConstant(10.0);
162 dof2.setConstant(3.0);
164 SUBCASE(
"-= array then *= scalar")
171 for (
int r = 0;
r < mat.rows();
r++)
172 CHECK(mat(
r, 0) == doctest::Approx(7.0));
180 for (
int r = 0;
r < mat.rows();
r++)
181 CHECK(mat(
r, 0) == doctest::Approx(14.0));
185 SUBCASE(
"*= by 1.0 is identity")
192 for (
int r = 0;
r < mat.rows();
r++)
193 CHECK(mat(
r, 0) == doctest::Approx(10.0));
204 auto dof1 = makeDof<5, 1>(mpi,
N);
205 auto dof2 = makeDof<5, 1>(mpi,
N);
206 dof1.setConstant(1.0);
207 dof2.setConstant(5.0);
215 for (
int r = 0;
r < mat.rows();
r++)
216 CHECK(mat(
r, 0) == doctest::Approx(16.0));
226 SUBCASE(
"uniform value")
230 auto dof = makeDof<1, 1>(mpi,
N);
238 SUBCASE(
"multi-component uniform")
243 auto dof = makeDof<5, 1>(mpi,
N);
251 SUBCASE(
"non-uniform values")
254 auto dof = makeDof<1, 1>(mpi,
N);
255 real val =
static_cast<real>(mpi.rank + 1);
260 real globalSqSum = 0;
262 globalSqSum +=
N *
static_cast<real>((
r + 1) * (
r + 1));
265 CHECK(n2 == doctest::Approx(std::sqrt(globalSqSum)));
268 SUBCASE(
"norm2 difference overload")
270 auto dof1 = makeDof<1, 1>(mpi,
N);
271 auto dof2 = makeDof<1, 1>(mpi,
N);
272 dof1.setConstant(5.0);
273 dof2.setConstant(2.0);
288 SUBCASE(
"scalar dof")
290 auto dof1 = makeDof<1, 1>(mpi,
N);
291 auto dof2 = makeDof<1, 1>(mpi,
N);
292 dof1.setConstant(2.0);
293 dof2.setConstant(3.0);
301 SUBCASE(
"multi-component dof")
303 auto dof1 = makeDof<5, 1>(mpi,
N);
304 auto dof2 = makeDof<5, 1>(mpi,
N);
305 dof1.setConstant(2.0);
306 dof2.setConstant(3.0);
322 auto dof = makeDof<3, 1>(mpi,
N);
330 if (mpi.rank == mpi.size - 1)
336 CHECK(gmin == doctest::Approx(-100.0));
337 CHECK(gmax == doctest::Approx(999.0));
347 auto dof = makeDof<1, 1>(mpi,
N);
361 auto dof = makeDof<3, 1>(mpi,
N);
364 Eigen::Matrix<real, 3, 1>
v;
371 real totalCells =
static_cast<real>(
N) * mpi.size;
372 CHECK(norm1(0, 0) == doctest::Approx(1.0 * totalCells));
373 CHECK(norm1(1, 0) == doctest::Approx(2.0 * totalCells));
374 CHECK(norm1(2, 0) == doctest::Approx(3.0 * totalCells));
383 auto dof1 = makeDof<3, 1>(mpi,
N);
384 auto dof2 = makeDof<3, 1>(mpi,
N);
386 Eigen::Matrix<real, 3, 1> v1, v2;
387 v1 << 5.0, 10.0, -3.0;
389 dof1.setConstant(v1);
390 dof2.setConstant(v2);
394 auto norm1 =
dof1.componentWiseNorm1(
dof2);
396 real totalCells =
static_cast<real>(
N) * mpi.size;
397 CHECK(norm1(0, 0) == doctest::Approx(3.0 * totalCells));
398 CHECK(norm1(1, 0) == doctest::Approx(3.0 * totalCells));
399 CHECK(norm1(2, 0) == doctest::Approx(4.0 * totalCells));
408 auto dof1 = makeDof<3, 1>(mpi,
N);
409 auto dof2 = makeDof<3, 1>(mpi,
N);
411 Eigen::Matrix<real, 3, 1> v1, v2;
412 v1 << 6.0, 8.0, 10.0;
414 dof1.setConstant(v1);
415 dof2.setConstant(v2);
417 SUBCASE(
"*= array (element-wise)")
424 CHECK(mat(0, 0) == doctest::Approx(12.0));
425 CHECK(mat(1, 0) == doctest::Approx(32.0));
426 CHECK(mat(2, 0) == doctest::Approx(50.0));
430 SUBCASE(
"/= array (element-wise)")
437 CHECK(mat(0, 0) == doctest::Approx(3.0));
438 CHECK(mat(1, 0) == doctest::Approx(2.0));
439 CHECK(mat(2, 0) == doctest::Approx(2.0));
443 SUBCASE(
"*= Eigen matrix (element-wise)")
445 Eigen::Matrix<real, 3, 1> scale;
446 scale << 0.5, 0.25, 0.1;
452 CHECK(mat(0, 0) == doctest::Approx(3.0));
453 CHECK(mat(1, 0) == doctest::Approx(2.0));
454 CHECK(mat(2, 0) == doctest::Approx(1.0));
460TEST_CASE(
"ArrayDOF operator= (copy values)")
468 Eigen::Matrix<real, 5, 1>
v;
469 v << 1.0, 2.0, 3.0, 4.0, 5.0;
471 dof2.setConstant(0.0);
480 CHECK(mat(0, 0) == doctest::Approx(1.0));
481 CHECK(mat(1, 0) == doctest::Approx(2.0));
482 CHECK(mat(2, 0) == doctest::Approx(3.0));
483 CHECK(mat(3, 0) == doctest::Approx(4.0));
484 CHECK(mat(4, 0) == doctest::Approx(5.0));
488 dof1.setConstant(-999.0);
493 CHECK(mat(0, 0) == doctest::Approx(1.0));
494 CHECK(mat(4, 0) == doctest::Approx(5.0));
504 auto dof1 = makeDof<3, 1>(mpi,
N);
505 Eigen::Matrix<real, 3, 1>
v;
516 CHECK(mat(0, 0) == doctest::Approx(7.0));
517 CHECK(mat(1, 0) == doctest::Approx(8.0));
518 CHECK(mat(2, 0) == doctest::Approx(9.0));
532 auto dof = makeDof<3, 1>(mpi,
N);
533 Eigen::Matrix<real, 3, 1>
v;
538 auto scale = makeDof<1, 1>(mpi,
N);
539 scale.setConstant(3.0);
547 CHECK(mat(0, 0) == doctest::Approx(6.0));
548 CHECK(mat(1, 0) == doctest::Approx(12.0));
549 CHECK(mat(2, 0) == doctest::Approx(18.0));
559 auto dof = makeDof<5, 1>(mpi,
N);
571 auto dof = makeDof<5, 1>(mpi,
N);
572 Eigen::Matrix<real, 5, 1>
v;
573 v << 1.0, -2.0, 3.0, -4.0, 5.0;
579 CHECK(d == doctest::Approx(n2 * n2));
589 static constexpr int m = M;
602 constexpr int M = T::m;
610 auto buildDof = [&]()
613 return makeDof<DNDS::DynamicSize, 1>(mpi,
N, rtRows, 1);
615 return makeDof<M, 1>(mpi,
N);
618 SUBCASE(
"setConstant scalar")
620 auto dof = buildDof();
626 CHECK(mat.rows() == effectiveRows);
627 for (
int r = 0;
r < mat.rows();
r++)
628 CHECK(mat(
r, 0) == doctest::Approx(3.0));
634 auto dof = buildDof();
641 for (
int r = 0;
r < mat.rows();
r++)
642 CHECK(mat(
r, 0) == doctest::Approx(5.0));
648 auto dof = buildDof();
659 auto dof1 = buildDof();
660 auto dof2 = buildDof();
661 dof1.setConstant(2.0);
662 dof2.setConstant(3.0);
672 auto dof1 = buildDof();
673 dof1.setConstant(7.0);
681 CHECK(mat.rows() == effectiveRows);
682 for (
int r = 0;
r < mat.rows();
r++)
683 CHECK(mat(
r, 0) == doctest::Approx(7.0));
687 dof1.setConstant(0.0);
688 CHECK(
dof2[0](0, 0) == doctest::Approx(7.0));
Degree-of-freedom array with vector-space operations (MPI-collective).
Primary solver state container: an ArrayEigenMatrix pair with MPI-collective vector-space operations.
real norm2()
Global L2 norm (MPI-collective). sqrt(sum_i sum_j x_ij^2).
t_element_mat componentWiseNorm1()
Per-component global L1 norm, returned as an n_m x n_n matrix (collective).
real dot(const t_self &R)
Global inner product: sum_i sum_j x_ij * R_ij (collective).
real max()
Global maximum across all entries (collective).
void clone(const t_self &R)
Deep copy from another ArrayDof. Delegates to the base-class clone.
real min()
Global minimum across all entries (collective).
void setConstant(real R)
Set every entry of every (father+son) row to the scalar R.
real sum()
Global sum of all entries (collective).
the host side operators are provided as implemented
int32_t rowsize
Row-width / per-row element-count type (signed 32-bit).
DNDS_CONSTANT const rowsize DynamicSize
Template parameter flag: "row width is set at runtime but uniform".
int64_t index
Global row / DOF index type (signed 64-bit; handles multi-billion-cell meshes).
double real
Canonical floating-point scalar used throughout DNDSR (double precision).
int MPI_int
MPI counterpart type for MPI_int (= C int). Used for counts and ranks in MPI calls.
DNDS_DEVICE_CALLABLE index Size() const
Combined father + son row count.
void TransAttach()
Bind the transformer to the current father / son pointers.
ssp< TArray > father
Owned-side array (must be resized before ghost setup).
void InitPair(const std::string &name, Args &&...args)
Allocate both father and son arrays, forwarding all args to TArray constructor.
ssp< TArray > son
Ghost-side array (sized automatically by createMPITypes / BorrowAndPull).
Lightweight bundle of an MPI communicator and the calling rank's coordinates.
CHECK(dof2[0](0, 0)==doctest::Approx(7.0))
Eigen::Matrix< real, 5, 1 > v
TYPE_TO_STRING(DofTag< 1 >)
TEST_CASE("ArrayDOF operator+= scalar and array")
TEST_CASE_TEMPLATE("ArrayDOF parametric over nVars", T, DofTag< 1 >, DofTag< 3 >, DofTag< 5 >, DofTag< DNDS::DynamicSize >)