Arcane  4.2.2.0
Developer documentation
Loading...
Searching...
No Matches
SampleProblemCommon.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/*---------------------------------------------------------------------------*/
9/*
10 * This file is based on the work on AMGCL library (version march 2026)
11 * which can be found at https://github.com/ddemidov/amgcl.
12 *
13 * Copyright (c) 2012-2022 Denis Demidov <dennis.demidov@gmail.com>
14 * SPDX-License-Identifier: MIT
15 */
16/*---------------------------------------------------------------------------*/
17/*---------------------------------------------------------------------------*/
18
19#ifndef TESTS_SAMPLE_PROBLEM_HPP
20#define TESTS_SAMPLE_PROBLEM_HPP
21
22#include "arccore/alina/ValueTypeInterface.h"
23
24#include <vector>
25#include <iostream>
26
27// Generates matrix for poisson problem in a unit cube.
28template <typename ValueType, typename ColType, typename PtrType, typename RhsType> PtrType
29sample_problem(Arcane::Int32 n,
30 std::vector<ValueType>& val,
31 std::vector<ColType>& col,
32 std::vector<PtrType>& ptr,
33 std::vector<RhsType>& rhs,
34 double anisotropy = 1.0)
35{
36 // In sequential, the global size never exceed 2^31.
37 PtrType n3 = n * n * n;
38
39 ptr.clear();
40 col.clear();
41 val.clear();
42 rhs.clear();
43
44 ptr.reserve(n3 + 1);
45 col.reserve(n3 * 7);
46 val.reserve(n3 * 7);
47 rhs.reserve(n3);
48
49 const auto one = Arcane::Alina::math::identity<ValueType>();
50
51 double hx = 1;
52 double hy = hx * anisotropy;
53 double hz = hy * anisotropy;
54
55 ptr.push_back(0);
56 for (ColType k = 0, idx = 0; k < n; ++k) {
57 for (int j = 0; j < n; ++j) {
58 for (int i = 0; i < n; ++i, ++idx) {
59 if (k > 0) {
60 col.push_back(idx - n * n);
61 val.push_back(-1.0 / (hz * hz) * one);
62 }
63
64 if (j > 0) {
65 col.push_back(idx - n);
66 val.push_back(-1.0 / (hy * hy) * one);
67 }
68
69 if (i > 0) {
70 col.push_back(idx - 1);
71 val.push_back(-1.0 / (hx * hx) * one);
72 }
73
74 col.push_back(idx);
75 val.push_back((2 / (hx * hx) + 2 / (hy * hy) + 2 / (hz * hz)) * one);
76
77 if (i + 1 < n) {
78 col.push_back(idx + 1);
79 val.push_back(-1.0 / (hx * hx) * one);
80 }
81
82 if (j + 1 < n) {
83 col.push_back(idx + n);
84 val.push_back(-1.0 / (hy * hy) * one);
85 }
86
87 if (k + 1 < n) {
88 col.push_back(idx + n * n);
89 val.push_back(-1.0 / (hz * hz) * one);
90 }
91
92 rhs.push_back(Arcane::Alina::math::constant<RhsType>(1.0));
93 ptr.push_back(static_cast<PtrType>(col.size()));
94 }
95 }
96 }
97
98 return n3;
99}
100
101//---------------------------------------------------------------------------
102// Generates a distributed matrix for poisson problem in a unit cube
103template <typename ValueType, typename ColType, typename PtrType, typename RhsType> PtrType
104sample_problem_distributed(int comm_rank, int comm_size,
105 Arcane::Int32 n, int block_size,
106 std::vector<PtrType>& ptr,
107 std::vector<ColType>& col,
108 std::vector<ValueType>& val,
109 std::vector<RhsType>& rhs)
110{
111 // We use `PtrType` for multiplication because the global size may exceed
112 // the maximum value of Int32
113 PtrType nx = n;
114 PtrType n3 = nx * nx * nx;
115
116 PtrType chunk = (n3 + comm_size - 1) / comm_size;
117 if (chunk % block_size != 0) {
118 chunk += block_size - chunk % block_size;
119 }
120 PtrType row_beg = std::min(n3, chunk * comm_rank);
121 PtrType row_end = std::min(n3, row_beg + chunk);
122 chunk = row_end - row_beg;
123
124 ptr.clear();
125 ptr.reserve(chunk + 1);
126 col.clear();
127 col.reserve(chunk * 7);
128 val.clear();
129 val.reserve(chunk * 7);
130
131 rhs.resize(chunk);
132 std::fill(rhs.begin(), rhs.end(), 1.0);
133
134 const double h2i = (n - 1) * (n - 1);
135 ptr.push_back(0);
136
137 for (PtrType idx = row_beg; idx < row_end; ++idx) {
138 PtrType k = idx / (n * n);
139 PtrType j = (idx / n) % n;
140 PtrType i = idx % n;
141
142 if (k > 0) {
143 col.push_back(idx - n * n);
144 val.push_back(-h2i);
145 }
146
147 if (j > 0) {
148 col.push_back(idx - n);
149 val.push_back(-h2i);
150 }
151
152 if (i > 0) {
153 col.push_back(idx - 1);
154 val.push_back(-h2i);
155 }
156
157 col.push_back(idx);
158 val.push_back(6 * h2i);
159
160 if (i + 1 < n) {
161 col.push_back(idx + 1);
162 val.push_back(-h2i);
163 }
164
165 if (j + 1 < n) {
166 col.push_back(idx + n);
167 val.push_back(-h2i);
168 }
169
170 if (k + 1 < n) {
171 col.push_back(idx + n * n);
172 val.push_back(-h2i);
173 }
174
175 ptr.push_back(col.size());
176 }
177
178 return chunk;
179}
180
181#endif
std::int32_t Int32
Signed integer type of 32 bits.