Arcane  v3.16.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
TestCartesianMeshV2.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 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#include <gtest/gtest.h>
9
10#include "arcane/cartesianmesh/v2/CartesianTypes.h"
11#include "arcane/cartesianmesh/v2/CartesianGrid.h"
12#include "arcane/cartesianmesh/v2/CartesianNumbering.h"
13
14#include <iostream>
15
16/*---------------------------------------------------------------------------*/
17/*---------------------------------------------------------------------------*/
18
19using namespace Arcane;
20using namespace Arcane::CartesianMesh::V2;
21
22/*---------------------------------------------------------------------------*/
23/*---------------------------------------------------------------------------*/
24template <typename IdType>
25void test_CartesianNumbering(const IdType (&nitem)[3], Integer dimension,
26 IdType first_item_id)
27{
29
30 cart_numb.initNumbering(nitem, dimension, first_item_id);
31
32 ASSERT_EQ(cart_numb.dimension(), dimension) << "Bad dimension";
33
34 IdType nitem_comp = 1;
35
36 for (Integer dir = 0; dir < dimension; ++dir) {
37 ASSERT_EQ(cart_numb.nbItem3()[dir], nitem[dir]) << "(A) Incorrect nb of items for the direction";
38 ASSERT_EQ(cart_numb.nbItemDir(dir), nitem[dir]) << "(B) Incorrect nb of items for the direction";
39
40 nitem_comp *= cart_numb.nbItemDir(dir);
41 }
42 for (Integer dir = dimension; dir < 3; ++dir) {
43 ASSERT_EQ(cart_numb.nbItem3()[dir], 1) << "(C) Incorrect nb of items for the direction";
44 ASSERT_EQ(cart_numb.nbItemDir(dir), 1) << "(D) Incorrect nb of items for the direction";
45 }
46 ASSERT_EQ(cart_numb.nbItem(), nitem_comp) << "Incorrect total nb of items";
47
48 // First item
49 ASSERT_EQ(cart_numb.firstId(), first_item_id) << "(A) Incorrect first item id";
50 ASSERT_EQ(cart_numb.id(0, 0, 0), first_item_id) << "(B) Incorrect first item id";
51 IdType idx0[3] = { 0, 0, 0 };
52 ASSERT_EQ(cart_numb.id(idx0), first_item_id) << "(C) Incorrect first item id";
53 ASSERT_EQ(cart_numb.id(IdxType{ 0, 0, 0 }), first_item_id) << "(D) Incorrect first item id";
54
55 IdType idx00[3] = { -1, -1, -1 };
56 cart_numb.ijk(first_item_id, idx00);
57 ASSERT_EQ(idx00[0], 0) << "(A) Incorrect I index";
58 ASSERT_EQ(idx00[1], 0) << "(A) Incorrect J index";
59 ASSERT_EQ(idx00[2], 0) << "(A) Incorrect K index";
60
61 IdxType idx000 = cart_numb.ijk(first_item_id);
62 ASSERT_EQ(idx000[0], 0) << "(B) Incorrect I index";
63 ASSERT_EQ(idx000[1], 0) << "(B) Incorrect J index";
64 ASSERT_EQ(idx000[2], 0) << "(B) Incorrect K index";
65
66 ASSERT_EQ(cart_numb.idxDir0(first_item_id), 0) << "(C) Incorrect first I index";
67 ASSERT_EQ(cart_numb.idxDir1(first_item_id), 0) << "(C) Incorrect first J index";
68 ASSERT_EQ(cart_numb.idxDir2(first_item_id), 0) << "(C) Incorrect first K index";
69
70 // Last item
71 IdType last_item_id = first_item_id + cart_numb.nbItem() - 1;
72 IdType litem[3] = {
73 cart_numb.nbItemDir(0) - 1,
74 cart_numb.nbItemDir(1) - 1,
75 cart_numb.nbItemDir(2) - 1
76 };
77 ASSERT_EQ(cart_numb.id(litem[0], litem[1], litem[2]), last_item_id) << "(A) Incorrect last item id";
78 ASSERT_EQ(cart_numb.id(litem), last_item_id) << "(B) Incorrect last item id";
79 ASSERT_EQ(cart_numb.id(IdxType{ litem[0], litem[1], litem[2] }), last_item_id) << "(C) Incorrect last item id";
80
81 IdType idx1[3] = { -1, -1, -1 };
82 cart_numb.ijk(last_item_id, idx1);
83 ASSERT_EQ(idx1[0], cart_numb.nbItemDir(0) - 1) << "(A) Incorrect last I index";
84 ASSERT_EQ(idx1[1], cart_numb.nbItemDir(1) - 1) << "(A) Incorrect last J index";
85 ASSERT_EQ(idx1[2], cart_numb.nbItemDir(2) - 1) << "(A) Incorrect last K index";
86
87 // Check numbering
88 IdType cur_id = cart_numb.firstId();
89 for (IdType k(0); k < cart_numb.nbItemDir(2); ++k) {
90 for (IdType j(0); j < cart_numb.nbItemDir(1); ++j) {
91 for (IdType i(0); i < cart_numb.nbItemDir(0); ++i) {
92
93 IdType ida = cart_numb.id(i, j, k);
94 ASSERT_EQ(ida, cur_id) << "(A) Incorrect current id";
95
96 IdType idxb[3] = { i, j, k };
97 IdType idb = cart_numb.id(idxb);
98 ASSERT_EQ(idb, cur_id) << "(B) Incorrect current id";
99
100 IdType idc = cart_numb.id(IdxType{ i, j, k });
101 ASSERT_EQ(idc, cur_id) << "(C) Incorrect current id";
102
103 // Inverse operation
104 IdType idd[3] = { -1, -1, -1 };
105 cart_numb.ijk(cur_id, idd);
106 ASSERT_EQ(idd[0], i) << "(A) Incorrect current I index";
107 ASSERT_EQ(idd[1], j) << "(A) Incorrect current J index";
108 ASSERT_EQ(idd[2], k) << "(A) Incorrect current K index";
109
110 IdxType ide = cart_numb.ijk(cur_id);
111 ASSERT_EQ(ide[0], static_cast<Int64>(i)) << "(B) Incorrect current I index";
112 ASSERT_EQ(ide[1], static_cast<Int64>(j)) << "(B) Incorrect current J index";
113 ASSERT_EQ(ide[2], static_cast<Int64>(k)) << "(B) Incorrect current K index";
114
115 cur_id++;
116 }
117 }
118 }
119
120 // Shift to neighbors
121 for (Integer dir = 0; dir < dimension; ++dir) {
122 ASSERT_EQ(cart_numb.delta3()[dir], cart_numb.deltaDir(dir)) << "Shifting numbers not equal";
123
124 IdType nitemD[3] = { cart_numb.nbItemDir(0), cart_numb.nbItemDir(1), cart_numb.nbItemDir(2) };
125 nitemD[dir] -= 1;
126 IdType delta = cart_numb.deltaDir(dir);
127
128 for (IdType k(0); k < nitemD[2]; ++k) {
129 for (IdType j(0); j < nitemD[1]; ++j) {
130 for (IdType i(0); i < nitemD[0]; ++i) {
131
132 IdType id_nei_comp = cart_numb.id({ i, j, k }) + delta; // neighbor by shifting
133
134 IdxType idxN{ i, j, k };
135 idxN[dir] += 1;
136 IdType id_nei = cart_numb.id(idxN);
137 ASSERT_EQ(id_nei, id_nei_comp) << "Incorrect neighbor id";
138 }
139 }
140 }
141 }
142}
143
144/*---------------------------------------------------------------------------*/
145/*---------------------------------------------------------------------------*/
146
147TEST(CartesianMeshV2, TestCartesianNumbering)
148{
149 std::cout << "TEST_CARTESIANMESHV2 LocalIdType for dimension=2\n";
150 {
151 LocalIdType3 nitem = { 5, 4, 0 };
152 test_CartesianNumbering<LocalIdType>(nitem, /*dim=*/2, /*first_id=*/42);
153 }
154 std::cout << "TEST_CARTESIANMESHV2 LocalIdType for dimension=3\n";
155 {
156 LocalIdType3 nitem = { 5, 4, 3 };
157 test_CartesianNumbering<LocalIdType>(nitem, /*dim=*/3, /*first_id=*/100);
158 }
159 std::cout << "TEST_CARTESIANMESHV2 UniqueIdType for dimension=2\n";
160 {
161 UniqueIdType3 nitem = { 5, 4, 0 };
162 UniqueIdType first_id = (UniqueIdType{ 1 } << 33) + UniqueIdType{ 42 };
163 test_CartesianNumbering<UniqueIdType>(nitem, /*dim=*/2, first_id);
164 }
165 std::cout << "TEST_CARTESIANMESHV2 UniqueIdType for dimension=3\n";
166 {
167 UniqueIdType3 nitem = { 5, 4, 3 };
168 UniqueIdType first_id = (UniqueIdType{ 1 } << 33) + UniqueIdType{ 100 };
169 test_CartesianNumbering<UniqueIdType>(nitem, /*dim=*/3, first_id);
170 }
171}
172
173/*---------------------------------------------------------------------------*/
174/*---------------------------------------------------------------------------*/
175template <typename IdType>
176void test_CartesianGrid(const IdType (&ncell)[3], Integer dimension,
177 bool only_center)
178{
179 CartesianGrid<IdType> cart_grid(ncell, dimension);
180
181 ASSERT_EQ(cart_grid.dimension(), dimension) << "Incorrect dimension";
182
183 ASSERT_EQ(&cart_grid.cartNumCell(), cart_grid.cartNumCellPtr()) << "(A) Pointers not equal";
184 ASSERT_EQ(&cart_grid.cartNumNode(), cart_grid.cartNumNodePtr()) << "(B) Pointers not equal";
185 ASSERT_EQ(&cart_grid.cartNumFace3(), cart_grid.cartNumFace3Ptr()) << "(C) Pointers not equal";
186 for (Integer dir = 0; dir < dimension; ++dir) {
187 ASSERT_EQ(&cart_grid.cartNumFace(dir), &(cart_grid.cartNumFace3()[dir])) << "(D) Pointers not equal";
188 }
189
190 auto cell_numb = cart_grid.cartNumCell();
191 auto node_numb = cart_grid.cartNumNode();
192
193 for (Integer dir = 0; dir < dimension; ++dir) {
194 auto face_numb_d = cart_grid.cartNumFace3()[dir];
195
196 ASSERT_EQ(cell_numb.nbItemDir(dir), ncell[dir]) << "Incorrect nb of cells";
197 ASSERT_EQ(cell_numb.nbItemDir(dir) + 1, node_numb.nbItemDir(dir)) << "Incorrect nb of cells/nodes";
198 ASSERT_EQ(cell_numb.nbItemDir(dir) + 1, face_numb_d.nbItemDir(dir)) << "Incorrect nb of cells/faces dir";
199
200 for (Integer idir = 1; idir < dimension; ++idir) {
201 Integer dtrans = (dir + idir) % dimension;
202 ASSERT_EQ(cell_numb.nbItemDir(dtrans), face_numb_d.nbItemDir(dtrans)) << "Incorrect nb of cells/faces dtrans";
203 }
204 }
205
206 // Connectivity
207 auto lbd_c2n = [&](IdType i, IdType j, IdType k) {
208 auto cid = cell_numb.id({ i, j, k });
209 auto nid = node_numb.id({ i, j, k });
210
211 IdType delta_c2n = node_numb.firstId() - cell_numb.firstId() +
212 j + k * (cell_numb.nbItemDir(0) + cell_numb.nbItemDir(1) + 1);
213 ASSERT_EQ(cid + delta_c2n, nid) << "Incorrect Cell/Node ids";
214 };
215 auto lbd_c2f = [&](Integer dir,
216 const CartesianNumbering<IdType>& face_numb_d,
217 IdType i, IdType j, IdType k) {
218 auto cid = cell_numb.id({ i, j, k });
219 auto fid = face_numb_d.id({ i, j, k });
220
221 IdType delta = face_numb_d.firstId() - cell_numb.firstId() +
222 (dir == 0 ? j + k * cell_numb.nbItemDir(1) : (dir == 1 ? k * cell_numb.nbItemDir(0) : 0));
223 ASSERT_EQ(cid + delta, fid) << "Incorrect Cell/Face ids";
224 };
225
226 if (only_center) {
227 IdType i = cell_numb.nbItemDir(0) / 2;
228 IdType j = cell_numb.nbItemDir(1) / 2;
229 IdType k = cell_numb.nbItemDir(2) / 2;
230 // Cell => Node
231 lbd_c2n(i, j, k);
232 // Cell => Face
233 for (Integer dir = 0; dir < dimension; ++dir) {
234 lbd_c2f(dir, cart_grid.cartNumFace3()[dir], i, j, k);
235 }
236 }
237 else {
238 // Cell => Node
239 for (IdType k(0); k < cell_numb.nbItemDir(2); ++k) {
240 for (IdType j(0); j < cell_numb.nbItemDir(1); ++j) {
241 for (IdType i(0); i < cell_numb.nbItemDir(0); ++i) {
242 lbd_c2n(i, j, k);
243 }
244 }
245 }
246 // Cell => Face
247 for (Integer dir = 0; dir < dimension; ++dir) {
248 auto face_numb_d = cart_grid.cartNumFace3()[dir];
249
250 for (IdType k(0); k < cell_numb.nbItemDir(2); ++k) {
251 for (IdType j(0); j < cell_numb.nbItemDir(1); ++j) {
252 for (IdType i(0); i < cell_numb.nbItemDir(0); ++i) {
253 lbd_c2f(dir, face_numb_d, i, j, k);
254 }
255 }
256 }
257 }
258 }
259}
260
261/*---------------------------------------------------------------------------*/
262/*---------------------------------------------------------------------------*/
263
264TEST(CartesianMeshV2, TestCartesianGrid)
265{
266 std::cout << "TEST_CARTESIANMESHV2_CARTESIANGRID LocalIdType for dimension=2\n";
267 {
268 LocalIdType3 ncell = { 5, 4, 0 };
269 test_CartesianGrid<LocalIdType>(ncell, /*dim=*/2, /*only_center=*/false);
270 }
271 std::cout << "TEST_CARTESIANMESHV2_CARTESIANGRID LocalIdType for dimension=3\n";
272 {
273 LocalIdType3 ncell = { 5, 4, 3 };
274 test_CartesianGrid<LocalIdType>(ncell, /*dim=*/3, /*only_center=*/false);
275 }
276 std::cout << "TEST_CARTESIANMESHV2_CARTESIANGRID UniqueIdType for dimension=2\n";
277 {
278 UniqueIdType3 ncell = { 150000, 75000, 0 };
279 test_CartesianGrid<UniqueIdType>(ncell, /*dim=*/2, /*only_center=*/true);
280 }
281 std::cout << "TEST_CARTESIANMESHV2_CARTESIANGRID UniqueIdType for dimension=3\n";
282 {
283 UniqueIdType3 ncell = { 3000, 2000, 1500 };
284 test_CartesianGrid<UniqueIdType>(ncell, /*dim=*/3, /*only_center=*/true);
285 }
286}
287
288/*---------------------------------------------------------------------------*/
289/*---------------------------------------------------------------------------*/
290
291// Effecttue des instantiations explicites pour tester la compilation.
294
297
298/*---------------------------------------------------------------------------*/
299/*---------------------------------------------------------------------------*/
Encapsulation d'une grille cartesienne avec les mailles, noeuds, faces d'une dimension au plus 3.
Gestion d'une numerotation cartesienne sur une grille d'items d'une dimension au plus 3 Permet le pas...
IdType deltaDir(Integer dir) const
Offset à ajouter à id() pour obtenir l'id de l'item suivant dans la direction dir (si cet item existe...
__host__ __device__ IdType id(IdType i, IdType j, IdType k) const
Passage (i,j,k) => numero.
void ijk(IdType item_id, IdType3 &item_ijk) const
Passage de numero => (i,j,k)
IdType idxDir0(IdType item_id) const
Passage numéro => i.
const IdType3 & nbItem3() const
Triplet du nb d'items dans chaque direction (définition de la grille)
IdType idxDir1(IdType item_id) const
Passage numéro => j.
IdType idxDir2(IdType item_id) const
Passage numéro => k.
Integer dimension() const
Dimension de la grille cartésienne sur laquelle s'appuit la numérotation.
IdType nbItem() const
Nb total d'items dans la grille cartésienne (produit du nb d'items dans chaque direction)
IdType nbItemDir(Integer dir) const
Nb d'items dans la grille cartésienne selon la direction dir (< dimension())
const IdType3 & delta3() const
Triplet des offsets dans toutes les directions pour passer aux items suivants dans chacune des direct...
IdType firstId() const
Plus petit identifiant de la numérotation cartésienne de la grille.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int64 UniqueIdType
Type des entiers utilisés pour stocker les identifiants uniques (globaux) des entités.
Int32 Integer
Type représentant un entier.