Arcane  4.2.3.0
Developer documentation
Loading...
Searching...
No Matches
DynamicMeshIncrementalBuilder.cc
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/* DynamicMeshIncrementalBuilder.cc (C) 2000-2026 */
9/* */
10/* Incremental mesh construction. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/Iterator.h"
15#include "arcane/utils/ArgumentException.h"
16#include "arcane/utils/NotImplementedException.h"
17#include "arcane/utils/NotSupportedException.h"
18#include "arcane/utils/ITraceMng.h"
19#include "arcane/utils/ValueConvert.h"
20
21#include "arcane/core/ItemTypeMng.h"
23#include "arcane/core/IParallelMng.h"
24#include "arcane/core/SerializeBuffer.h"
25#include "arcane/core/ItemPrinter.h"
26#include "arcane/core/Connectivity.h"
27#include "arcane/core/MeshToMeshTransposer.h"
28#include "arcane/core/IItemFamilyModifier.h"
29
30#include "arcane/mesh/DynamicMesh.h"
31#include "arcane/mesh/DynamicMeshIncrementalBuilder.h"
32#include "arcane/mesh/OneMeshItemAdder.h"
33#include "arcane/mesh/GhostLayerBuilder.h"
34#include "arcane/mesh/FaceUniqueIdBuilder.h"
35#include "arcane/mesh/EdgeUniqueIdBuilder.h"
36#include "arcane/mesh/CellFamily.h"
37#include "arcane/mesh/EdgeFamily.h"
38#include "arcane/utils/SmallArray.h"
39#include "arcane/utils/FixedArray.h"
40#include "arcane/utils/HashTableMap2.h"
41#include "arcane/utils/CheckedConvert.h"
42#include "arcane/mesh/IncrementalItemConnectivity.h"
43#include "arcane/mesh/FaceFamily.h"
44#include "arcane/mesh/NodeFamily.h"
45#include "arcane/core/NodesOfItemReorderer.h"
46#include "arcane/mesh/GraphDoFs.h"
47#include "arcane/mesh/ParticleFamily.h"
48
49#include <set>
50#include <map>
51#include <algorithm>
52#include <utility>
53
54/*---------------------------------------------------------------------------*/
55/*---------------------------------------------------------------------------*/
56
57namespace Arcane::mesh
58{
59
60/*---------------------------------------------------------------------------*/
61/*---------------------------------------------------------------------------*/
62
63// #define ARCANE_DEBUG_DYNAMIC_MESH
64// #define ARCANE_DEBUG_DYNAMIC_MESH2
65
66/*---------------------------------------------------------------------------*/
67/*---------------------------------------------------------------------------*/
68
71: TraceAccessor(mesh->traceMng())
72, m_mesh(mesh)
73, m_item_type_mng(mesh->itemTypeMng())
74, m_has_amr(mesh->isAmrActivated())
76{
77 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_VERBOSE_MESH_BUILDER", true))
78 m_verbose = (v.value() != 0);
79 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_BULK_ADD_CELLS", true))
80 m_use_bulk_add_cells = (v.value() != 0);
81}
82
83/*---------------------------------------------------------------------------*/
84/*---------------------------------------------------------------------------*/
85
86DynamicMeshIncrementalBuilder::
87~DynamicMeshIncrementalBuilder()
88{
90 delete m_face_unique_id_builder;
91 delete m_edge_unique_id_builder;
93}
94
95/*---------------------------------------------------------------------------*/
96/*---------------------------------------------------------------------------*/
97
98void DynamicMeshIncrementalBuilder::
99_printCellFaceInfos(ItemInternal* icell, const String& str)
100{
101 Cell cell(icell);
102 Integer nb_num_back_face = 0;
103 Integer nb_num_front_face = 0;
104 Integer index = 0;
105 for (Face face : cell.faces()) {
106 String add_msg;
107 if (face.backCell() == cell) {
108 ++nb_num_back_face;
109 add_msg = "is a back face";
110 }
111 else {
112 ++nb_num_front_face;
113 add_msg = "is a front face";
114 }
115 info() << str << ": celluid=" << cell.uniqueId()
116 << " faceuid=" << face.uniqueId()
117 << " faceindex=" << index
118 << add_msg;
119 ++index;
120 }
121 info() << str << ": celluid=" << cell.uniqueId()
122 << " nbback=" << nb_num_back_face
123 << " nbfront=" << nb_num_front_face;
124}
125
126/*---------------------------------------------------------------------------*/
127/*---------------------------------------------------------------------------*/
137addCells(Integer nb_cell, Int64ConstArrayView cells_infos,
138 Int32 owner, Int32ArrayView cells,
139 bool allow_build_face)
140{
141 // With ARCANE_BULK_ADD_CELLS=1, addCellsBulk() builds the same mesh by filling
142 // the family arrays instead of walking item by item. It returns false, having
143 // touched nothing, on a mesh it does not build, and the loop below then does
144 // the work.
145 if (m_use_bulk_add_cells && addCellsBulk(nb_cell, cells_infos, owner, cells, allow_build_face))
146 return;
147 ItemTypeMng* itm = m_item_type_mng;
148
149 Integer cells_infos_index = 0;
150 bool add_to_cells = cells.size() != 0;
151 if (add_to_cells && nb_cell != cells.size())
152 ARCANE_THROW(ArgumentException, "return array 'cells' has to have same size as number of cells");
153 auto* adder = m_one_mesh_item_adder;
154 for (Integer i_cell = 0; i_cell < nb_cell; ++i_cell) {
155 ItemTypeId item_type_id(CheckedConvert::toInt16(cells_infos[cells_infos_index]));
156 ++cells_infos_index;
157 Int64 cell_unique_id = cells_infos[cells_infos_index];
158 ++cells_infos_index;
159
160 Int32 current_cell_nb_node = 0;
161 if (item_type_id == ITI_GenericPolyhedron) {
162 // For poly types, the number of nodes is the first value in the connectivity
163 current_cell_nb_node = static_cast<Int32>(cells_infos[cells_infos_index]);
164 }
165 else {
166 ItemTypeInfo* it = itm->typeFromId(item_type_id);
167 current_cell_nb_node = it->nbLocalNode();
168 }
169 ConstArrayView<Int64> current_cell_nodes_uid(current_cell_nb_node, &cells_infos[cells_infos_index]);
170
171 ItemInternal* cell = adder->addOneCell(item_type_id, cell_unique_id, owner,
172 current_cell_nodes_uid, allow_build_face);
173
174 if (add_to_cells)
175 cells[i_cell] = cell->localId();
176 cells_infos_index += current_cell_nb_node;
177 }
178}
179
180/*---------------------------------------------------------------------------*/
181/*---------------------------------------------------------------------------*/
184static const Integer MAX_BULK_FACE_NODE = 32;
185
206addCellsBulk(Integer nb_cell, Int64ConstArrayView cells_infos,
207 Integer sub_domain_id, Int32ArrayView cells,
208 bool allow_build_face)
209{
210 DynamicMesh* mesh = m_mesh;
211 ItemTypeMng* itm = m_item_type_mng;
212 const bool add_to_cells = cells.size() != 0;
213 if (add_to_cells && nb_cell != cells.size())
214 ARCANE_THROW(ArgumentException, "return array 'cells' has to have same size as number of cells");
215
216 // What this path does not know how to build. Anything here falls back.
217 if (nb_cell <= 0 || !allow_build_face)
218 return false;
219 if (mesh->parentMesh())
220 return false;
221 if (!mesh->meshKind().isMonoDimension())
222 return false;
223 const Int32 dimension = mesh->dimension();
224 if (dimension < 1 || dimension > 3)
225 return false;
226 NodeFamily& node_family = mesh->trueNodeFamily();
227 EdgeFamily& edge_family = mesh->trueEdgeFamily();
228 FaceFamily& face_family = mesh->trueFaceFamily();
229 CellFamily& cell_family = mesh->trueCellFamily();
230 // With edges, addCells() always connects a cell to its edges and an edge to
231 // its nodes, and the other edge connectivities only when the mesh keeps them.
232 const bool has_edge = hasEdge();
233 auto has_connectivity = [&](Integer c) { return Connectivity::hasConnectivity(m_connectivity, c); };
234 const bool has_node_edge = has_edge && has_connectivity(Connectivity::CT_NodeToEdge);
235 const bool has_edge_cell = has_edge && has_connectivity(Connectivity::CT_EdgeToCell);
236 const bool has_face_edge = has_edge && has_connectivity(Connectivity::CT_FaceToEdge);
237 const bool has_edge_face = has_edge && has_connectivity(Connectivity::CT_EdgeToFace);
238 if (has_edge) {
239 if (!has_connectivity(Connectivity::CT_CellToEdge) || !has_connectivity(Connectivity::CT_EdgeToNode))
240 return false;
241 if (!edge_family.canAllocateBulk())
242 return false;
243 }
244 // Only a fresh allocation: the localIds handed out are consecutive from 0,
245 // and an item already present would have to be looked up, not created. A
246 // family that was deallocated reports no item but keeps its ItemInternal
247 // slots on a free list, so it is not fresh either.
248 if (!node_family.canAllocateBulk() || !face_family.canAllocateBulk() || !cell_family.canAllocateBulk())
249 return false;
250
251 // ------------------------------------------------------------- pre-scan
252 // Sizes every array of the discovery pass, so that not one of them grows while
253 // it is being filled.
254 UniqueArray<Int64> cell_uids(nb_cell);
255 UniqueArray<Int16> cell_type_ids(nb_cell);
256 UniqueArray<Int32> cell_node_index(nb_cell + 1);
257 UniqueArray<Int32> cell_face_index(nb_cell + 1);
258 UniqueArray<Int32> cell_edge_index(nb_cell + 1);
259 Int32 total_cell_node = 0;
260 Int32 total_cell_face = 0;
261 Int32 total_cell_edge = 0;
262 Int32 total_face_edge = 0;
263 Int32 max_face_node = 0;
264 bool has_high_order_face = false;
265 {
266 Integer k = 0;
267 for (Integer i = 0; i < nb_cell; ++i) {
268 ItemTypeId type_id{ static_cast<Int16>(cells_infos[k]) };
269 // A generic polyhedron carries its own node count in cells_infos and
270 // its faces elsewhere: addCells() builds it.
271 if (type_id == ITI_GenericPolyhedron)
272 return false;
273 ItemTypeInfo* type = itm->typeFromId(type_id);
274 const Integer nb_node = type->nbLocalNode();
275 const Integer nb_face = type->nbLocalFace();
276 cell_type_ids[i] = type_id;
277 cell_uids[i] = cells_infos[k + 1];
278 cell_node_index[i] = total_cell_node;
279 cell_face_index[i] = total_cell_face;
280 cell_edge_index[i] = total_cell_edge;
281 total_cell_node += nb_node;
282 total_cell_face += nb_face;
283 if (has_edge)
284 total_cell_edge += type->nbLocalEdge();
285 for (Integer f = 0; f < nb_face; ++f) {
286 const Integer n = type->localFace(f).nbNode();
287 if (n > MAX_BULK_FACE_NODE)
288 return false; // the per-face scratch below is fixed-size
289 if (n > max_face_node)
290 max_face_node = n;
291 if (has_edge)
292 total_face_edge += type->localFace(f).nbEdge();
293 // A face of order 2 or more is connected to all its nodes, but only its
294 // linear nodes know it (see the node to face fill below).
295 ItemTypeInfo* face_type = itm->typeFromId(ItemTypeId::fromInteger(type->localFace(f).typeId()));
296 if (face_type->linearTypeInfo()->nbLocalNode() != n)
297 has_high_order_face = true;
298 }
299 k += 2 + nb_node;
300 if (k > cells_infos.size())
301 return false;
302 }
303 cell_node_index[nb_cell] = total_cell_node;
304 cell_face_index[nb_cell] = total_cell_face;
305 cell_edge_index[nb_cell] = total_cell_edge;
306 }
307
308 // ---------------------------------------------------------------- phase A
309 // Discovery. One pass over cells_infos, in the order addCells() uses, so that
310 // every localId, every uid and every face orientation come out the same.
311
312 UniqueArray<Int32> cell_nodes(total_cell_node);
313 UniqueArray<Int32> cell_faces(total_cell_face);
314 // A cell face creates at most one face, so these bound the face arrays.
315 UniqueArray<Int64> face_uids(total_cell_face);
316 UniqueArray<Int16> face_type_ids(total_cell_face);
317 UniqueArray<Int32> face_node_index(total_cell_face + 1);
318 UniqueArray<Int32> face_nodes(static_cast<Int64>(total_cell_face) * max_face_node);
319 // With faces of order 2 or more, the linear nodes of each face apart: they
320 // are the first of its sorted nodes.
321 UniqueArray<Int32> face_linear_index(has_high_order_face ? total_cell_face + 1 : 0);
322 UniqueArray<Int32> face_linear_nodes(has_high_order_face ? static_cast<Int64>(total_cell_face) * max_face_node : 0);
323 Int32 nb_face_linear_node = 0;
324 if (has_high_order_face)
325 face_linear_index[0] = 0;
326 UniqueArray<Int32> face_back_cell(total_cell_face);
327 UniqueArray<Int32> face_front_cell(total_cell_face);
328 UniqueArray<Int64> node_uids(total_cell_node);
329 Int32 nb_node = 0;
330 Int32 nb_face = 0;
331 Int32 nb_face_node = 0;
332 face_node_index[0] = 0;
333
334 impl::HashTableMap2<Int64, Int32> node_map(total_cell_node / 4 + 16, true);
335 /*
336 * A face is found by walking the faces already attached to its first sorted
337 * node: they are a handful, and they were created within a few cells of each
338 * other, so the walk stays in cache. This is what findFaceInNode2() does, over
339 * arrays this pass owns.
340 */
341 UniqueArray<Int32> node_first_face(total_cell_node);
342 node_first_face.fill(-1);
343 UniqueArray<Int32> face_chain_next(total_cell_face);
344
345 // The edges, when the mesh has some. An edge is its two nodes, the one of
346 // smaller uniqueId first, and is found among the edges attached to that node,
347 // as findEdgeInNode2() finds it. A cell edge creates at most one edge.
348 UniqueArray<Int32> cell_edges(total_cell_edge);
349 UniqueArray<Int64> edge_uids(total_cell_edge);
350 UniqueArray<Int32> edge_node_index(total_cell_edge + 1);
351 UniqueArray<Int32> edge_nodes(2 * static_cast<Int64>(total_cell_edge));
352 UniqueArray<Int32> node_first_edge(has_edge ? total_cell_node : 0);
353 node_first_edge.fill(-1);
354 UniqueArray<Int32> edge_chain_next(total_cell_edge);
355 // A face's edges are connected when the face is created, so they follow the
356 // face order, as the faces' nodes do.
357 UniqueArray<Int32> face_edge_index(has_edge ? total_cell_face + 1 : 0);
358 UniqueArray<Int32> face_edges(total_face_edge);
359 Int32 nb_edge = 0;
360 Int32 nb_face_edge = 0;
361 if (has_edge)
362 face_edge_index[0] = 0;
363 Int64 next_edge_uid = m_one_mesh_item_adder->nextEdgeUid();
364
365 NodesOfItemReorderer reorderer(itm);
366 SmallArray<Int64, 16> work_face_nodes;
369 Int64 next_face_uid = m_one_mesh_item_adder->nextFaceUid();
370 // As in addCells(), a face's uniqueId is either the next one or a hash of its
371 // sorted node uniqueIds.
372 const bool use_hash = m_one_mesh_item_adder->isUseNodeUniqueIdToGenerateEdgeAndFaceUniqueId();
374
375 Integer infos_index = 0;
376 for (Integer i_cell = 0; i_cell < nb_cell; ++i_cell) {
377 ItemTypeId cell_type_id{ static_cast<Int16>(cells_infos[infos_index]) };
378 ItemTypeInfo* cell_type = itm->typeFromId(cell_type_id);
379 const Integer cell_nb_node = cell_type->nbLocalNode();
380 Int64ConstArrayView cell_nodes_uid(cell_nb_node, &cells_infos[infos_index + 2]);
381 infos_index += 2 + cell_nb_node;
382
383 const Int32 node_base = cell_node_index[i_cell];
384 for (Integer i = 0; i < cell_nb_node; ++i) {
385 auto r = node_map.try_emplace(cell_nodes_uid[i], nb_node);
386 if (r.second)
387 node_uids[nb_node++] = cell_nodes_uid[i];
388 cell_nodes[node_base + i] = r.first->second;
389 }
390
391 // addCells() adds a cell's edges before its faces.
392 const Int32 edge_base = cell_edge_index[i_cell];
393 if (has_edge) {
394 const Integer cell_nb_edge = cell_type->nbLocalEdge();
395 for (Integer i_edge = 0; i_edge < cell_nb_edge; ++i_edge) {
396 const ItemTypeInfo::LocalEdge& le = cell_type->localEdge(i_edge);
397 Int32 first = cell_nodes[node_base + le.beginNode()];
398 Int32 second = cell_nodes[node_base + le.endNode()];
399 if (node_uids[first] > node_uids[second])
400 std::swap(first, second);
401 Int32 edge_index = -1;
402 for (Int32 e = node_first_edge[first]; e >= 0; e = edge_chain_next[e]) {
403 if (edge_nodes[2 * e + 1] == second) {
404 edge_index = e;
405 break;
406 }
407 }
408 if (edge_index < 0) {
409 edge_index = nb_edge;
410 if (use_hash) {
412 uids[0] = node_uids[first];
413 uids[1] = node_uids[second];
414 edge_uids[nb_edge] = MeshUtils::generateHashUniqueId(uids.view());
415 }
416 else
417 edge_uids[nb_edge] = next_edge_uid++;
418 edge_nodes[2 * nb_edge] = first;
419 edge_nodes[2 * nb_edge + 1] = second;
420 edge_node_index[nb_edge] = 2 * nb_edge;
421 edge_chain_next[nb_edge] = node_first_edge[first];
422 node_first_edge[first] = nb_edge;
423 ++nb_edge;
424 }
425 cell_edges[edge_base + i_edge] = edge_index;
426 }
427 }
428
429 // A face is identified by its sorted node list, exactly as findFaceInNode2()
430 // identifies it.
431 const Integer cell_nb_face = cell_type->nbLocalFace();
432 const Int32 face_base = cell_face_index[i_cell];
433 for (Integer i_face = 0; i_face < cell_nb_face; ++i_face) {
434 const ItemTypeInfo::LocalFace& lf = cell_type->localFace(i_face);
435 const Integer face_nb_node = lf.nbNode();
436 work_face_nodes.resize(face_nb_node);
437 for (Integer z = 0; z < face_nb_node; ++z) {
438 const Int32 local = lf.node(z);
439 work_face_nodes[z] = cell_nodes_uid[local];
440 work_face_lids[z] = cell_nodes[node_base + local];
441 }
442 bool is_reorder = false;
443 if (dimension == 1)
444 is_reorder = reorderer.reorder1D(i_face, work_face_nodes[0]);
445 else
446 is_reorder = reorderer.reorder(ItemTypeId::fromInteger(lf.typeId()), work_face_nodes);
447 ConstArrayView<Int64> sorted_nodes = reorderer.sortedNodes();
448
449 // The sorted nodes are a permutation of the face's own nodes, so their
450 // localIds are found among the handful just gathered, with no trip through
451 // the node map.
452 for (Integer z = 0; z < face_nb_node; ++z) {
453 const Int64 uid = sorted_nodes[z];
454 Int32 lid = NULL_ITEM_LOCAL_ID;
455 for (Integer w = 0; w < face_nb_node; ++w) {
456 if (work_face_nodes[w] == uid) {
457 lid = work_face_lids[w];
458 break;
459 }
460 }
461 sorted_lids[z] = lid;
462 }
463
464 const Int32 first_node = sorted_lids[0];
465 Int32 face_index = -1;
466 for (Int32 f = node_first_face[first_node]; f >= 0; f = face_chain_next[f]) {
467 const Int32 begin = face_node_index[f];
468 if (face_node_index[f + 1] - begin != face_nb_node)
469 continue;
470 bool same = true;
471 for (Integer z = 0; same && z < face_nb_node; ++z)
472 same = (face_nodes[begin + z] == sorted_lids[z]);
473 if (same) {
474 face_index = f;
475 break;
476 }
477 }
478 if (face_index < 0) {
479 face_index = nb_face;
480 if (use_hash) {
481 for (Integer z = 0; z < face_nb_node; ++z)
482 sorted_uids[z] = node_uids[sorted_lids[z]];
483 face_uids[nb_face] = MeshUtils::generateHashUniqueId(SmallSpan<const Int64>(sorted_uids.data(), face_nb_node));
484 }
485 else
486 face_uids[nb_face] = next_face_uid++;
487 face_type_ids[nb_face] = static_cast<Int16>(lf.typeId());
488 face_back_cell[nb_face] = NULL_ITEM_LOCAL_ID;
489 face_front_cell[nb_face] = NULL_ITEM_LOCAL_ID;
490 for (Integer z = 0; z < face_nb_node; ++z)
491 face_nodes[nb_face_node + z] = sorted_lids[z];
492 nb_face_node += face_nb_node;
493 face_node_index[nb_face + 1] = nb_face_node;
494 if (has_high_order_face) {
495 const Integer face_nb_linear_node = itm->typeFromId(ItemTypeId::fromInteger(lf.typeId()))->linearTypeInfo()->nbLocalNode();
496 for (Integer z = 0; z < face_nb_linear_node; ++z)
497 face_linear_nodes[nb_face_linear_node + z] = sorted_lids[z];
498 nb_face_linear_node += face_nb_linear_node;
499 face_linear_index[nb_face + 1] = nb_face_linear_node;
500 }
501 face_chain_next[nb_face] = node_first_face[first_node];
502 node_first_face[first_node] = nb_face;
503 if (has_edge) {
504 const Integer face_nb_edge = lf.nbEdge();
505 for (Integer z = 0; z < face_nb_edge; ++z)
506 face_edges[nb_face_edge + z] = cell_edges[edge_base + lf.edge(z)];
507 nb_face_edge += face_nb_edge;
508 face_edge_index[nb_face + 1] = nb_face_edge;
509 }
510 ++nb_face;
511 }
512 cell_faces[face_base + i_face] = face_index;
513 // is_reorder means this cell is in FRONT of the face.
514 Int32& side = is_reorder ? face_front_cell[face_index] : face_back_cell[face_index];
515 if (side != NULL_ITEM_LOCAL_ID)
516 ARCANE_FATAL("face already has a cell on this side (face index={0})", face_index);
517 side = i_cell;
518 }
519 }
520
521 // ---------------------------------------------------------------- phase B
522 // The items themselves, one batch per family. The discovery order is also the
523 // local id order, so the arrays above index the families directly.
524
525 UniqueArray<Int32> lids(std::max(std::max(nb_node, nb_edge), std::max(nb_face, static_cast<Int32>(nb_cell))));
526 node_family.allocateItemsBulk(node_uids.subConstView(0, nb_node), sub_domain_id,
527 lids.subView(0, nb_node));
528 if (has_edge) {
529 edge_node_index[nb_edge] = 2 * nb_edge;
530 edge_family.allocateItemsBulk(edge_uids.subConstView(0, nb_edge), sub_domain_id,
531 lids.subView(0, nb_edge));
532 for (Int32 i = 0; i < nb_edge; ++i) {
533 if (lids[i] != i)
534 ARCANE_FATAL("unexpected localId {0} for index {1} in family {2}", lids[i], i, edge_family.name());
535 }
536 }
537 _allocateBulkByType(&face_family, face_uids.subConstView(0, nb_face),
538 face_type_ids.subConstView(0, nb_face), sub_domain_id, lids);
539 _allocateBulkByType(&cell_family, cell_uids.constView(), cell_type_ids.constView(),
540 sub_domain_id, lids);
541
542 // ---------------------------------------------------------------- phase C
543 // The connectivities. Each is three arrays; the layout has to be the one the
544 // incremental path produces, since compactConnectivityList() checks it: the
545 // null item holds the first block, and every block starts on a multiple of
546 // preAllocatedSize().
547
548 _fillBulkConnectivity(cell_family.nodeConnectivity(), nb_cell, cell_node_index, cell_nodes);
549 _fillBulkConnectivity(cell_family.faceConnectivity(), nb_cell, cell_face_index, cell_faces);
550 _fillBulkConnectivity(face_family.nodeConnectivity(), nb_face,
551 face_node_index.subConstView(0, nb_face + 1),
552 face_nodes.subConstView(0, nb_face_node));
553 // face -> cell is written by FaceFamily, the class allowed to set the
554 // II_Boundary / II_HasBackCell / II_HasFrontCell flags that go with it.
555 face_family.setBulkBackAndFrontCells(face_back_cell.subConstView(0, nb_face),
556 face_front_cell.subConstView(0, nb_face));
557 _fillBulkReverseConnectivity(node_family.cellConnectivity(), nb_node, nb_cell,
558 cell_node_index, cell_nodes);
559 // As in addCells(), a face is added to its linear nodes only, and only when
560 // the mesh keeps the node to face connectivity (a 1D mesh does not, by default).
561 if (has_connectivity(Connectivity::CT_NodeToFace)) {
562 if (has_high_order_face)
563 _fillBulkReverseConnectivity(node_family.faceConnectivity(), nb_node, nb_face,
564 face_linear_index.subConstView(0, nb_face + 1),
565 face_linear_nodes.subConstView(0, nb_face_linear_node));
566 else
567 _fillBulkReverseConnectivity(node_family.faceConnectivity(), nb_node, nb_face,
568 face_node_index.subConstView(0, nb_face + 1),
569 face_nodes.subConstView(0, nb_face_node));
570 }
571 if (has_edge) {
572 const ConstArrayView<Int32> e_index = edge_node_index.subConstView(0, nb_edge + 1);
573 const ConstArrayView<Int32> e_nodes = edge_nodes.subConstView(0, 2 * nb_edge);
574 const ConstArrayView<Int32> f_index = face_edge_index.subConstView(0, nb_face + 1);
575 const ConstArrayView<Int32> f_edges = face_edges.subConstView(0, nb_face_edge);
576 _fillBulkConnectivity(cell_family.edgeConnectivity(), nb_cell, cell_edge_index, cell_edges);
577 _fillBulkConnectivity(edge_family.nodeConnectivity(), nb_edge, e_index, e_nodes);
578 if (has_node_edge)
579 _fillBulkReverseConnectivity(node_family.edgeConnectivity(), nb_node, nb_edge, e_index, e_nodes);
580 if (has_edge_cell)
581 _fillBulkReverseConnectivity(edge_family.cellConnectivity(), nb_edge, nb_cell, cell_edge_index, cell_edges);
582 if (has_face_edge)
583 _fillBulkConnectivity(face_family.edgeConnectivity(), nb_face, f_index, f_edges);
584 if (has_edge_face)
585 _fillBulkReverseConnectivity(edge_family.faceConnectivity(), nb_edge, nb_face, f_index, f_edges);
586 }
587 if (add_to_cells) {
588 for (Integer i = 0; i < nb_cell; ++i)
589 cells[i] = i;
590 }
591
592 m_one_mesh_item_adder->setNextFaceUid(next_face_uid);
593 m_one_mesh_item_adder->setNextEdgeUid(next_edge_uid);
594 m_one_mesh_item_adder->addBulkMeshInfos(nb_node, nb_edge, nb_face, nb_cell);
595
596 return true;
597}
598
599/*---------------------------------------------------------------------------*/
600/*---------------------------------------------------------------------------*/
607template <typename FamilyType> void DynamicMeshIncrementalBuilder::
608_allocateBulkByType(FamilyType* family, Int64ConstArrayView uids,
609 ConstArrayView<Int16> type_ids, Int32 owner, Int32ArrayView lids)
610{
611 ItemTypeMng* itm = m_item_type_mng;
612 const Int32 nb = uids.size();
613 Int32 begin = 0;
614 while (begin < nb) {
615 Int32 end = begin + 1;
616 while (end < nb && type_ids[end] == type_ids[begin])
617 ++end;
618 ItemTypeInfo* type = itm->typeFromId(ItemTypeId(type_ids[begin]));
619 Int32ArrayView batch = lids.subView(begin, end - begin);
620 family->allocateItemsBulk(uids.subConstView(begin, end - begin), type, owner, batch);
621 begin = end;
622 }
623 for (Int32 i = 0; i < nb; ++i) {
624 if (lids[i] != i)
625 ARCANE_FATAL("unexpected localId {0} for index {1} in family {2}",
626 lids[i], i, family->name());
627 }
628}
629
630/*---------------------------------------------------------------------------*/
631/*---------------------------------------------------------------------------*/
640{
641 const Int32 prealloc = c->preAllocatedSize();
642 const Int32 head = (prealloc <= 0) ? 1 : prealloc;
643 Int64 total = head;
644 for (Int32 i = 0; i < nb_source; ++i) {
645 const Int32 n = offsets[i + 1] - offsets[i];
646 if (n > 0)
647 total += (prealloc > 0) ? (prealloc * ((n + prealloc - 1) / prealloc)) : n;
648 }
649 Int32ArrayView nb_item, index, list;
650 c->resizeBulkConnectivity(nb_source, total, nb_item, index, list);
651 for (Int32 z = 0; z < head; ++z)
652 list[z] = NULL_ITEM_LOCAL_ID;
653 Int64 pos = head;
654 for (Int32 i = 0; i < nb_source; ++i) {
655 const Int32 begin = offsets[i];
656 const Int32 n = offsets[i + 1] - begin;
657 if (n == 0) {
658 index[i] = 0;
659 nb_item[i] = 0;
660 continue;
661 }
662 index[i] = CheckedConvert::toInt32(pos);
663 nb_item[i] = n;
664 for (Int32 z = 0; z < n; ++z)
665 list[pos + z] = targets[begin + z];
666 const Int32 alloc = (prealloc > 0) ? (prealloc * ((n + prealloc - 1) / prealloc)) : n;
667 for (Int32 z = n; z < alloc; ++z)
668 list[pos + z] = NULL_ITEM_LOCAL_ID;
669 pos += alloc;
670 }
672}
673
674/*---------------------------------------------------------------------------*/
675/*---------------------------------------------------------------------------*/
686 Int32 nb_source, ConstArrayView<Int32> offsets,
687 ConstArrayView<Int32> targets)
688{
689 const Int32 prealloc = c->preAllocatedSize();
690 const Int32 head = (prealloc <= 0) ? 1 : prealloc;
691 UniqueArray<Int32> count(nb_target);
692 count.fill(0);
693 for (Int32 i = 0; i < nb_source; ++i) {
694 for (Int32 z = offsets[i]; z < offsets[i + 1]; ++z)
695 ++count[targets[z]];
696 }
697
698 UniqueArray<Int32> fill_pos(nb_target);
699 Int64 total = head;
700 for (Int32 t = 0; t < nb_target; ++t) {
701 const Int32 n = count[t];
702 if (n == 0) {
703 fill_pos[t] = 0;
704 continue;
705 }
706 fill_pos[t] = CheckedConvert::toInt32(total);
707 total += (prealloc > 0) ? (prealloc * ((n + prealloc - 1) / prealloc)) : n;
708 }
709 Int32ArrayView nb_item, index, list;
710 c->resizeBulkConnectivity(nb_target, total, nb_item, index, list);
711 list.fill(NULL_ITEM_LOCAL_ID);
712 for (Int32 t = 0; t < nb_target; ++t) {
713 nb_item[t] = count[t];
714 index[t] = fill_pos[t];
715 }
716 for (Int32 i = 0; i < nb_source; ++i) {
717 for (Int32 z = offsets[i]; z < offsets[i + 1]; ++z) {
718 const Int32 t = targets[z];
719 list[fill_pos[t]] = i;
720 ++fill_pos[t];
721 }
722 }
724}
725
726/*---------------------------------------------------------------------------*/
727/*---------------------------------------------------------------------------*/
736
737/*---------------------------------------------------------------------------*/
738
740addCells3(Integer nb_cell, Int64ConstArrayView cells_infos,
741 Integer sub_domain_id, Int32ArrayView cells,
742 bool allow_build_face)
743{
744 bool add_to_cells = cells.size() != 0;
745 if (add_to_cells && nb_cell != cells.size())
746 throw ArgumentException(A_FUNCINFO,
747 "return array 'cells' has to have same size as number of cells");
748 ItemDataList item_data_list; // store item ids and dependency connectivities
749 ItemDataList item_relation_data_list; // store relation connectivities
750 ItemData& cell_data = item_data_list.itemData(Integer(m_mesh->cellFamily()->itemKind()),
751 nb_cell, 0, cells, &mesh()->trueCellFamily(), &mesh()->trueCellFamily(), sub_domain_id);
752 // item info_size cannot be guessed
753 Int64UniqueArray faces_infos, edges_infos, nodes_infos, node_uids;
754 Int32UniqueArray face_lids, edge_lids, node_lids;
755 Integer nb_face = 0, nb_edge = 0, nb_node = 0;
756 std::map<Int64, Int64SharedArray> cell_to_face_connectivity_info;
757 std::map<std::pair<Int64, Int64>, Int64> edge_uid_map;
758
759 // Fill classical info
760 _fillFaceInfo(nb_face, nb_cell, faces_infos, cells_infos, cell_to_face_connectivity_info);
761 _fillEdgeInfo(nb_edge, nb_face, edges_infos, faces_infos, edge_uid_map);
762 _fillNodeInfo(nb_node, nb_face, nodes_infos, faces_infos);
763
764 // Fill Cell info 2
765 _fillCellNewInfoNew(nb_cell, cells_infos, cell_data.itemInfos(), cell_to_face_connectivity_info, edge_uid_map);
766 // Fill Face info 2
767 if (allow_build_face) {
768 ItemData& face_data = item_data_list.itemData(Integer(m_mesh->faceFamily()->itemKind()), nb_face, 0, face_lids, &mesh()->trueFaceFamily(), &mesh()->trueFaceFamily(), sub_domain_id);
769 face_lids.resize(item_data_list[m_mesh->faceFamily()->itemKind()].nbItems());
770 _fillFaceNewInfoNew(nb_face, faces_infos, face_data.itemInfos(), edge_uid_map); // todo voir appel depuis add Faces
771 ItemData& face_relation_data = item_relation_data_list.itemData(Integer(m_mesh->faceFamily()->itemKind()), nb_face, 0, face_lids, &mesh()->trueFaceFamily(), &mesh()->trueFaceFamily(), sub_domain_id);
772 _initFaceRelationInfo(face_relation_data, cell_data, faces_infos); // face-cell relations
773 }
774 // Fill Edge info 2
775 if (hasEdge()) {
776 Integer edge_info_size = 1 + nb_edge * 6; //New info = Nb_connected_family + for each edge : type, uid, connected_family_kind, nb_node_connected, first_node_uid, second_node_uid
777 ItemData& edge_data = item_data_list.itemData(Integer(m_mesh->edgeFamily()->itemKind()), nb_edge, edge_info_size, edge_lids, &mesh()->trueEdgeFamily(), &mesh()->trueEdgeFamily(), sub_domain_id);
778 edge_lids.resize(item_data_list[m_mesh->edgeFamily()->itemKind()].nbItems());
779 _fillEdgeNewInfoNew(nb_edge, edges_infos, edge_data.itemInfos()); // reprendre fillEdgeInfo et voir l'appel depuis add Edges + attention ordre des noeuds,
780 ItemData& edge_relation_data = item_relation_data_list.itemData(Integer(m_mesh->edgeFamily()->itemKind()), nb_edge, edge_info_size, edge_lids, &mesh()->trueEdgeFamily(), &mesh()->trueEdgeFamily(), sub_domain_id);
781 _initEdgeRelationInfo(edge_relation_data, cell_data, edges_infos); // edge-cell relations
782 if (allow_build_face) {
783 _appendEdgeRelationInfo(edge_relation_data, item_data_list[IK_Face], edges_infos); // edge-face relations
784 _appendFaceRelationInfo(item_relation_data_list[IK_Face], edge_data, faces_infos); // face-edge relations
785 }
786 }
787 // Fill Node info 2
788 Integer node_info_size = 1 + nb_node * 2; //New info = Nb_connected_family + for each node : type, uid (no connected family)
789 ItemData& node_data = item_data_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()), nb_node, node_info_size, node_lids, &mesh()->trueNodeFamily(), &mesh()->trueNodeFamily(), sub_domain_id);
790 node_lids.resize(item_data_list[m_mesh->nodeFamily()->itemKind()].nbItems());
791 _fillNodeNewInfo(nodes_infos, node_data.itemInfos());
792 ItemData& node_relation_data = item_relation_data_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()), nb_node, node_info_size, node_lids, &mesh()->trueNodeFamily(), &mesh()->trueNodeFamily(), sub_domain_id);
793 _initNodeRelationInfo(node_relation_data, cell_data, nodes_infos); // node-cell relations
794 if (allow_build_face)
795 _appendNodeRelationInfo(node_relation_data, item_data_list[IK_Face], nodes_infos); // node-face relations
796 if (hasEdge())
797 _appendNodeRelationInfo(node_relation_data, item_data_list[IK_Edge], nodes_infos); // node-edge relations
798
799 // Launch node, face and edges (not mandatory) and cell creation
800 addItems(item_data_list, item_relation_data_list);
801}
802
803/*---------------------------------------------------------------------------*/
804
805void DynamicMeshIncrementalBuilder::
806addCells2(Integer nb_cell, Int64ConstArrayView cells_infos,
807 Integer sub_domain_id, Int32ArrayView cells,
808 bool allow_build_face)
809{
810 ItemDataList item_data_list;
811 ItemData& cell_data = item_data_list.itemData(Integer(m_mesh->cellFamily()->itemKind()),
812 nb_cell, 0, cells, &mesh()->trueCellFamily(), &mesh()->trueCellFamily(), sub_domain_id);
813 // item info_size cannot be guessed
814 Int64Array& cell_infos2 = cell_data.itemInfos();
815 Int64UniqueArray faces_infos;
816 Int64UniqueArray node_uids;
817 Int32UniqueArray face_lids;
818 Integer nb_face;
819
820 // Fill cell info 2
821 _fillCellInfo2(nb_cell, cells_infos, cell_infos2, nb_face, faces_infos, node_uids, allow_build_face);
822
823 // Fill face info 2
824 if (allow_build_face) {
825 Integer face_infos2_size = faces_infos.size() + 1 + 2 * nb_face; // additive info nb_connected_family + nb_face * (family_id + nb_connected_element)
826 face_lids.resize(nb_face);
827 ItemData& face_data = item_data_list.itemData(Integer(m_mesh->faceFamily()->itemKind()),
828 nb_face, face_infos2_size, face_lids, &mesh()->trueFaceFamily(), &mesh()->trueFaceFamily(), sub_domain_id);
829 Int64ArrayView face_infos2 = face_data.itemInfos().view();
830 _fillFaceInfo2(nb_face, faces_infos, face_infos2, node_uids); // if allow_build_face false, node_uids built in fillCellInfo3
831 }
832
833 // Fill node info 2
834 Integer nb_node_to_add = node_uids.size();
835 Int32UniqueArray node_lids(nb_node_to_add);
836 ItemData& node_data = item_data_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()),
837 nb_node_to_add, 2 * nb_node_to_add + 1, node_lids, &mesh()->trueNodeFamily(), &mesh()->trueNodeFamily(), sub_domain_id);
838 Int64Array& node_infos2 = node_data.itemInfos();
839 _fillNodeNewInfo(node_uids, node_infos2);
840
841 // Launch node and face and cell creation
842 addItems(item_data_list);
843}
844
845/*---------------------------------------------------------------------------*/
846/*---------------------------------------------------------------------------*/
856_fillFaceInfo(Integer& nb_face, Integer nb_cell, Int64Array& faces_infos, Int64ConstArrayView cells_infos, std::map<Int64, Int64SharedArray>& cell_to_face_connectivity_info)
857{
858 faces_infos.reserve(2 * cells_infos.size());
859 Int64UniqueArray work_face_sorted_nodes;
860 Int64UniqueArray work_face_orig_nodes;
861 ItemTypeMng* itm = m_item_type_mng;
862 Integer cells_infos_index = 0;
863 nb_face = 0;
864 NodeInFaceSet face_nodes_set;
865 for (Integer i_cell = 0; i_cell < nb_cell; ++i_cell) {
866 Integer item_type_id = (Integer)cells_infos[cells_infos_index++];
867 Int64 current_cell_unique_id = cells_infos[cells_infos_index++];
868 ItemTypeInfo* it = itm->typeFromId(item_type_id);
869 Integer current_cell_nb_node = it->nbLocalNode();
870 Int64ConstArrayView current_cell_node_uids(current_cell_nb_node, &cells_infos[cells_infos_index]);
871 Integer current_cell_nb_face = it->nbLocalFace();
872 for (Integer face_in_cell_index = 0; face_in_cell_index < current_cell_nb_face; ++face_in_cell_index) {
873 const ItemTypeInfo::LocalFace& current_face = it->localFace(face_in_cell_index);
874 Integer current_face_nb_node = current_face.nbNode();
875 work_face_orig_nodes.resize(current_face_nb_node);
876 work_face_sorted_nodes.resize(current_face_nb_node);
877 Integer i = 0;
878 for (Integer node_in_face_index = 0; node_in_face_index < current_face_nb_node; ++node_in_face_index) {
879 work_face_orig_nodes[i++] = current_cell_node_uids[current_face.node(node_in_face_index)];
880 }
881 mesh_utils::reorderNodesOfFace(work_face_orig_nodes, work_face_sorted_nodes);
882 // get face uid: we shouldn't have to guess, it should be given in arguments...
883 Int64 current_face_uid = _findFaceUniqueId(work_face_sorted_nodes, face_nodes_set);
884 if (current_face_uid == NULL_ITEM_ID) // face not already known add to face info
885 {
886 current_face_uid = m_face_uid_pool++;
887 faces_infos.add(current_face.typeId()); // face info type
888 faces_infos.add(current_face_uid); // face info uid
889 faces_infos.addRange(work_face_sorted_nodes); // face info node uids
890 _addFaceNodes(face_nodes_set, work_face_sorted_nodes, current_face_uid);
891 ++nb_face;
892 }
893 cell_to_face_connectivity_info[current_cell_unique_id].add(current_face_uid);
894 }
895 cells_infos_index += current_cell_nb_node;
896 }
897}
898
899/*---------------------------------------------------------------------------*/
900
901void DynamicMeshIncrementalBuilder::
902_fillEdgeInfo(Integer& nb_edge, Integer nb_face, Int64Array& edges_infos,
903 Int64ConstArrayView faces_infos, std::map<std::pair<Int64, Int64>, Int64>& edge_uid_map)
904{
905 edges_infos.reserve(2 * faces_infos.size());
906 ItemTypeMng* itm = m_item_type_mng;
907 Integer faces_infos_index = 0;
908 nb_edge = 0;
909 for (Integer i_face = 0; i_face < nb_face; ++i_face) {
910 Integer item_type_id = (Integer)faces_infos[faces_infos_index++]; // face type
911 ++faces_infos_index; // face uid (unused)
912 ItemTypeInfo* it = itm->typeFromId(item_type_id);
913 Integer current_face_nb_node = it->nbLocalNode();
914 Int64ConstArrayView current_face_node_uids(current_face_nb_node, &faces_infos[faces_infos_index]);
915 Integer current_face_nb_edge = it->nbLocalEdge();
916 for (Integer edge_in_face_index = 0; edge_in_face_index < current_face_nb_edge; ++edge_in_face_index) {
917 const ItemTypeInfo::LocalEdge& current_edge = it->localEdge(edge_in_face_index);
918 Int64 first_node = current_face_node_uids[current_edge.beginNode()];
919 Int64 second_node = current_face_node_uids[current_edge.endNode()];
920 if (first_node > second_node)
921 std::swap(first_node, second_node);
922 auto edge_it = edge_uid_map.insert(std::make_pair(std::make_pair(first_node, second_node), m_edge_uid_pool));
923 if (edge_it.second) {
924 edges_infos.add(m_edge_uid_pool); // edge uid
925 edges_infos.add(first_node); // first node uid
926 edges_infos.add(second_node); // second node uid
927 ++nb_edge;
929 }
930 }
931 faces_infos_index += current_face_nb_node;
932 }
933}
934
935/*---------------------------------------------------------------------------*/
936
937void DynamicMeshIncrementalBuilder::
938_fillNodeInfo(Integer& nb_node, Integer nb_face, Int64Array& nodes_infos, Int64ConstArrayView faces_infos)
939{
940 nodes_infos.reserve(faces_infos.size());
941 Integer faces_infos_index = 0;
942 std::set<Int64> nodes_set;
943 ItemTypeMng* itm = m_item_type_mng;
944 for (Integer i_face = 0; i_face < nb_face; ++i_face) {
945 Int32 type_id = CheckedConvert::toInt32(faces_infos[faces_infos_index++]);
946 Integer current_face_nb_node = itm->typeFromId(type_id)->nbLocalNode(); // face type
947 ++faces_infos_index; //face_uid (unused)
948 for (auto node_uid : faces_infos.subConstView(faces_infos_index, current_face_nb_node)) {
949 nodes_set.insert(node_uid);
950 }
951 faces_infos_index += current_face_nb_node;
952 }
953 nb_node = CheckedConvert::toInteger(nodes_set.size());
954 for (auto node_uid : nodes_set) {
955 nodes_infos.add(node_uid);
956 }
957}
958
959/*---------------------------------------------------------------------------*/
960
961void DynamicMeshIncrementalBuilder::
962_fillNodeInfoFromEdge(Integer& nb_node, Integer nb_edge, Int64Array& nodes_infos, Int64ConstArrayView edges_infos)
963{
964 nodes_infos.reserve(2 * edges_infos.size());
965 Integer edges_infos_index = 0;
966 std::set<Int64> nodes_set;
967 for (Integer i_edge = 0; i_edge < nb_edge; ++i_edge) {
968 ++edges_infos_index; //edge_uid (unused)
969 nodes_set.insert(edges_infos[edges_infos_index++]);
970 nodes_set.insert(edges_infos[edges_infos_index++]);
971 }
972 nb_node = CheckedConvert::toInteger(nodes_set.size());
973 for (auto node_uid : nodes_set) {
974 nodes_infos.add(node_uid);
975 }
976}
977/*---------------------------------------------------------------------------*/
978
979void DynamicMeshIncrementalBuilder::
980_fillCellNewInfoNew(Integer nb_cell, Int64ConstArrayView cells_infos, Int64Array& cell_infos2,
981 const std::map<Int64, Int64SharedArray>& cell_to_face_connectivity_info, const std::map<std::pair<Int64, Int64>, Int64>& edge_uid_map)
982{
983 Integer cell_infos2_size_approx = 1 + 3 * (cells_infos.size() + 2 * nb_cell); // supposes as many faces as nodes as edges...
984 cell_infos2.reserve(cell_infos2_size_approx);
985 ItemTypeMng* itm = m_item_type_mng;
986 Integer cells_infos_index = 0;
987 Integer nb_connected_families = hasEdge() ? 3 : 2;
988 cell_infos2.add(nb_connected_families); // nb_connected_families (node and face +/- edge)
989 for (Integer i_cell = 0; i_cell < nb_cell; ++i_cell) {
990 Integer item_type_id = (Integer)cells_infos[cells_infos_index];
991 cell_infos2.add(cells_infos[cells_infos_index++]); // cell type
992 Int64 current_cell_uid = cells_infos[cells_infos_index];
993 cell_infos2.add(cells_infos[cells_infos_index++]); // cell uid
994 ItemTypeInfo* it = itm->typeFromId(item_type_id);
995 //--- Cell node connectivity
996 cell_infos2.add(mesh()->nodeFamily()->itemKind()); // connected_family_id: node family
997 Integer current_cell_nb_node = it->nbLocalNode();
998 cell_infos2.add(current_cell_nb_node); // nb_connected_nodes
999 Int64ConstArrayView current_cell_node_uids(current_cell_nb_node, &cells_infos[cells_infos_index]);
1000 cell_infos2.addRange(current_cell_node_uids); // node ids
1001 //--- Cell face connectivity
1002 cell_infos2.add(mesh()->faceFamily()->itemKind()); // connected_family_id: face family
1003 Integer current_cell_nb_face = it->nbLocalFace();
1004 cell_infos2.add(current_cell_nb_face); // nb_connected_faces
1005 Int64ArrayView current_cell_faces = cell_to_face_connectivity_info.find(current_cell_uid)->second.view();
1006 if (current_cell_nb_face != current_cell_faces.size())
1007 ARCANE_FATAL("Incoherent number of faces for cell {0}. Expected {1} found {2}",
1008 current_cell_uid, current_cell_nb_face, current_cell_faces.size());
1009 cell_infos2.addRange(current_cell_faces); // face ids
1010 //-- Cell edge connectivity
1011 if (hasEdge()) {
1012 cell_infos2.add(mesh()->edgeFamily()->itemKind()); // connected_family_id: edge family
1013 Integer current_cell_nb_edge = it->nbLocalEdge();
1014 cell_infos2.add(current_cell_nb_edge); // nb_connected_edges
1015 for (int edge_index = 0; edge_index < current_cell_nb_edge; ++edge_index) {
1016 Int64 first_node = current_cell_node_uids[it->localEdge(edge_index).beginNode()];
1017 Int64 second_node = current_cell_node_uids[it->localEdge(edge_index).endNode()];
1018 if (first_node > second_node)
1019 std::swap(first_node, second_node); // edge may be oriented negatively in the cell
1020 auto edge_it = edge_uid_map.find(std::make_pair(first_node, second_node));
1021 if (edge_it == edge_uid_map.end())
1022 ARCANE_FATAL("Do not find edge with nodes {0}-{1} in edge uid map. Exiting",
1023 current_cell_node_uids[it->localEdge(edge_index).beginNode()],
1024 current_cell_node_uids[it->localEdge(edge_index).endNode()]);
1025 cell_infos2.add(edge_it->second);
1026 }
1027 }
1028 cells_infos_index += current_cell_nb_node;
1029 }
1030}
1031
1032/*---------------------------------------------------------------------------*/
1033/*---------------------------------------------------------------------------*/
1034
1035void DynamicMeshIncrementalBuilder::
1036_fillCellInfo2(Integer nb_cell, Int64ConstArrayView cells_infos, Int64Array& cell_infos2,
1037 Integer& nb_face, Int64Array& faces_infos, Int64Array& node_uids, bool allow_build_face)
1038{
1039 Integer cell_infos2_size_approx = 1 + 2 * (cells_infos.size() + 2 * nb_cell); // supposes as many faces as nodes...
1040 cell_infos2.reserve(cell_infos2_size_approx);
1041 // Fill infos
1042 ItemTypeMng* itm = m_item_type_mng;
1043 Integer cells_infos_index = 0;
1044 cell_infos2.add(2); // nb_connected_families (node and face)
1045
1046 nb_face = 0;
1047 faces_infos.reserve(2 * cells_infos.size());
1048 Int64UniqueArray work_face_sorted_nodes;
1049 Int64UniqueArray work_face_orig_nodes;
1050 NodeInFaceSet face_nodes_set;
1051 std::set<Int64> node_uid_set;
1052 // Fill face_infos2 from faces_infos
1053 for (Integer i_cell = 0; i_cell < nb_cell; ++i_cell) {
1054
1055 Integer item_type_id = (Integer)cells_infos[cells_infos_index];
1056 cell_infos2.add(cells_infos[cells_infos_index++]); // cell type
1057 cell_infos2.add(cells_infos[cells_infos_index++]); // cell uid
1058 cell_infos2.add(mesh()->nodeFamily()->itemKind()); // connected_family_id: node family
1059
1060 ItemTypeInfo* it = itm->typeFromId(item_type_id);
1061 // Cell node connectivity
1062 Integer current_cell_nb_node = it->nbLocalNode();
1063 cell_infos2.add(current_cell_nb_node); // nb_connected_nodes
1064 Int64ConstArrayView current_cell_node_uids(current_cell_nb_node, &cells_infos[cells_infos_index]);
1065 cell_infos2.addRange(current_cell_node_uids); // node ids
1066 if (!allow_build_face)
1067 node_uid_set.insert(current_cell_node_uids.begin(), current_cell_node_uids.end()); // otherwise node ids will be computed in face info build
1068 // cell face connectivity
1069 cell_infos2.add(mesh()->faceFamily()->itemKind()); // connected_family_id: face family
1070 Integer current_cell_nb_face = it->nbLocalFace();
1071 cell_infos2.add(current_cell_nb_face); // nb_connected_faces
1072 for (Integer face_in_cell_index = 0; face_in_cell_index < current_cell_nb_face; ++face_in_cell_index) {
1073 ItemTypeInfo::LocalFace current_face = it->localFace(face_in_cell_index);
1074 Integer current_face_nb_node = current_face.nbNode();
1075 work_face_orig_nodes.resize(current_face_nb_node);
1076 work_face_sorted_nodes.resize(current_face_nb_node);
1077 Integer i = 0;
1078 for (Integer node_in_face_index = 0; node_in_face_index < current_face_nb_node; ++node_in_face_index) {
1079 work_face_orig_nodes[i++] = current_cell_node_uids[current_face.node(node_in_face_index)];
1080 }
1081 mesh_utils::reorderNodesOfFace(work_face_orig_nodes, work_face_sorted_nodes);
1082 // get face uid: we shouldn't have to guess, it should be given in arguments...
1083 Int64 current_face_uid = _findFaceUniqueId(work_face_sorted_nodes, face_nodes_set);
1084 if (current_face_uid == NULL_ITEM_ID) // face not already known add to face info
1085 {
1086 current_face_uid = m_face_uid_pool++;
1087 faces_infos.add(current_face.typeId()); // face info type
1088 faces_infos.add(current_face_uid); // face info uid
1089 faces_infos.addRange(work_face_sorted_nodes); // face info node uids
1090 _addFaceNodes(face_nodes_set, work_face_sorted_nodes, current_face_uid);
1091 ++nb_face;
1092 }
1093 cell_infos2.add(current_face_uid); // face ids
1094 }
1095 cells_infos_index += current_cell_nb_node;
1096 }
1097 if (!allow_build_face) {
1098 node_uids.resize(node_uid_set.size());
1099 Integer index = 0;
1100 for (Int64 node_uid : node_uid_set)
1101 node_uids[index++] = node_uid;
1102 }
1103}
1104
1105/*---------------------------------------------------------------------------*/
1106/*---------------------------------------------------------------------------*/
1116_initFaceRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView faces_info)
1117{
1118 _fillFaceRelationInfo(source_item_relation_data, target_item_dependencies_data, faces_info, true);
1119}
1120
1121/*---------------------------------------------------------------------------*/
1122
1123void DynamicMeshIncrementalBuilder::
1124_appendFaceRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView faces_info)
1125{
1126 _fillFaceRelationInfo(source_item_relation_data, target_item_dependencies_data, faces_info, false);
1127}
1128
1129/*---------------------------------------------------------------------------*/
1130
1131void DynamicMeshIncrementalBuilder::
1132_fillFaceRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data,
1133 Int64ConstArrayView faces_info, bool is_source_relation_data_empty)
1134{
1135 // face_infos = [{face_type, face_uid, {face_node_uids}]
1136 Int64UniqueArray face_uids_and_types;
1137 face_uids_and_types.reserve(2 * source_item_relation_data.nbItems());
1138 ItemTypeMng* itm = m_item_type_mng;
1139 for (Integer face_info_index = 0; face_info_index < faces_info.size();) {
1140 face_uids_and_types.add(faces_info[face_info_index + 1]); // face_uid
1141 face_uids_and_types.add(faces_info[face_info_index]); // face_type
1142 Integer type_id = CheckedConvert::toInteger(face_uids_and_types.back());
1143 face_info_index += (2 + itm->typeFromId(type_id)->nbLocalNode()); // increment and skip info (first & second_node_uid)
1144 }
1145 _fillItemRelationInfo(source_item_relation_data, target_item_dependencies_data, face_uids_and_types, is_source_relation_data_empty);
1146}
1147
1148/*---------------------------------------------------------------------------*/
1149
1150void DynamicMeshIncrementalBuilder::
1151_initEdgeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView edges_info)
1152{
1153 _fillEdgeRelationInfo(source_item_relation_data, target_item_dependencies_data, edges_info, true);
1154}
1155
1156/*---------------------------------------------------------------------------*/
1157
1158void DynamicMeshIncrementalBuilder::
1159_appendEdgeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView edges_info)
1160{
1161 _fillEdgeRelationInfo(source_item_relation_data, target_item_dependencies_data, edges_info, false);
1162}
1163
1164/*---------------------------------------------------------------------------*/
1165
1166void DynamicMeshIncrementalBuilder::
1167_fillEdgeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data,
1168 Int64ConstArrayView edges_info, bool is_source_relation_data_empty)
1169{
1170 // edge_infos = [{edge_uid, first_node_uid, second_node_uid}
1171 ARCANE_ASSERT((source_item_relation_data.nbItems() * 3 == edges_info.size()), ("source_item_relation_data and edges_info size incoherent. Exiting."));
1172 Int64UniqueArray edge_uids_and_types;
1173 edge_uids_and_types.reserve(2 * source_item_relation_data.nbItems());
1174 for (Integer edge_info_index = 0; edge_info_index < edges_info.size();) {
1175 edge_uids_and_types.add(edges_info[edge_info_index++]); // edge_uid
1176 edge_uids_and_types.add(IT_Line2); // edge_type
1177 edge_info_index += 2; // skip info (first & second_node_uid)
1178 }
1179 _fillItemRelationInfo(source_item_relation_data, target_item_dependencies_data, edge_uids_and_types, is_source_relation_data_empty);
1180}
1181
1182/*---------------------------------------------------------------------------*/
1183
1184void DynamicMeshIncrementalBuilder::
1185_initNodeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView nodes_info)
1186{
1187 _fillNodeRelationInfo(source_item_relation_data, target_item_dependencies_data, nodes_info, true);
1188}
1189
1190/*---------------------------------------------------------------------------*/
1191
1192void DynamicMeshIncrementalBuilder::
1193_appendNodeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView nodes_info)
1194{
1195 _fillNodeRelationInfo(source_item_relation_data, target_item_dependencies_data, nodes_info, false);
1196}
1197
1198/*---------------------------------------------------------------------------*/
1199
1200void DynamicMeshIncrementalBuilder::
1201_fillNodeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView nodes_info, bool is_source_relation_data_empty)
1202{
1203 // nodes_info = [node_uids]
1204 ARCANE_ASSERT((source_item_relation_data.nbItems() == nodes_info.size()), ("source_item_relation_data and nodes_info size incoherent. Exiting."));
1205 Int64UniqueArray node_uids_and_types(2 * nodes_info.size());
1206 for (Integer node_index = 0; node_index < nodes_info.size(); ++node_index) {
1207 node_uids_and_types[2 * node_index] = nodes_info[node_index];
1208 node_uids_and_types[2 * node_index + 1] = IT_Vertex;
1209 }
1210 _fillItemRelationInfo(source_item_relation_data, target_item_dependencies_data, node_uids_and_types, is_source_relation_data_empty);
1211}
1212
1213/*---------------------------------------------------------------------------*/
1214
1215void DynamicMeshIncrementalBuilder::
1216_fillItemRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data,
1217 Int64ConstArrayView source_item_uids_and_types,
1218 bool is_source_item_relation_data_empty)
1219{
1220 ARCANE_ASSERT((source_item_relation_data.nbItems() * 2 == source_item_uids_and_types.size()),
1221 ("source item number incoherent between source_item_relation_data and source_item_uids_and_types. Exiting."));
1222 // Fill an ItemData containing source to target relations (target to source relations are included in target_item_data)
1223 auto& source_relation_info = source_item_relation_data.itemInfos();
1224 const auto& target_dependencies_info = target_item_dependencies_data.itemInfos();
1225 auto source_family = source_item_relation_data.itemFamily();
1226 auto target_family = target_item_dependencies_data.itemFamily();
1227 if (!source_family || !target_family)
1228 return;
1229 std::map<Int64, Int64SharedArray> source_to_target_uids;
1230 Integer nb_families_connected_to_target = CheckedConvert::toInteger(target_dependencies_info[0]);
1231 Integer target_info_index = 1; // 0 is nb_connected_families
1232
1233 // Fill map source to target traversing target_item_dependencies_data
1234 for (; target_info_index < target_dependencies_info.size();) {
1235 target_info_index++; // current target item_type
1236 Int64 target_item_uid = target_dependencies_info[target_info_index++]; // current target item uid
1237 for (Integer family_connected_to_target = 0; family_connected_to_target < nb_families_connected_to_target; ++family_connected_to_target) {
1238 Int64 family_connected_to_target_kind = target_dependencies_info[target_info_index++]; // current target item connected family kind
1239 if (family_connected_to_target_kind != source_family->itemKind()) { //this connection info does not concern source family. Skip
1240 Integer nb_non_read_values = CheckedConvert::toInteger(target_dependencies_info[target_info_index++]); // nb_connected_item on this other family (/= to source family)
1241 target_info_index += nb_non_read_values;
1242 continue;
1243 }
1244 else {
1245 Int32 nb_source_item_connected_to_target_item = CheckedConvert::toInt32(target_dependencies_info[target_info_index++]);
1246 for (Integer source_item_index = 0; source_item_index < nb_source_item_connected_to_target_item; ++source_item_index) {
1247 source_to_target_uids[target_dependencies_info[source_item_index + target_info_index]].add(target_item_uid);
1248 }
1249 target_info_index += nb_source_item_connected_to_target_item;
1250 }
1251 }
1252 }
1253 // Fill or append source_item_relation_data traversing the map source_to_target_connectivity
1254 if (is_source_item_relation_data_empty)
1255 _initEmptyRelationInfo(source_relation_info, source_to_target_uids, source_item_uids_and_types,
1256 target_dependencies_info.size(), target_family);
1257 else
1258 _appendInitializedRelationInfo(source_relation_info, source_to_target_uids, source_item_uids_and_types,
1259 target_dependencies_info.size(), target_family);
1260}
1261
1262/*---------------------------------------------------------------------------*/
1263
1264void DynamicMeshIncrementalBuilder::
1265_initEmptyRelationInfo(Int64Array& source_relation_info, std::map<Int64, Int64SharedArray>& source_to_target_uids, Int64ConstArrayView source_item_uids_and_types,
1266 Integer approx_relation_size,
1267 IItemFamily const* target_family)
1268{
1269 if (!source_relation_info.empty())
1270 source_relation_info.clear();
1271 source_relation_info.reserve(approx_relation_size); // clearly too much elements...but only available info. Do better ?
1272 source_relation_info.add(1); // nb_connected_families
1273 // Fill source_item_relation_data
1274 for (Integer source_item_uids_and_types_index = 0; source_item_uids_and_types_index < source_item_uids_and_types.size(); source_item_uids_and_types_index += 2) {
1275 Int64 source_item_uid = source_item_uids_and_types[source_item_uids_and_types_index];
1276 source_relation_info.add(source_item_uids_and_types[source_item_uids_and_types_index + 1]); // item type
1277 source_relation_info.add(source_item_uid); // item uid
1278 source_relation_info.add(target_family->itemKind()); // connected family kind
1279 auto& connected_items = source_to_target_uids[source_item_uid];
1280 source_relation_info.add(connected_items.size()); // nb_connected_item
1281 source_relation_info.addRange(connected_items.view()); // connected_items uids
1282 }
1283}
1284
1285/*---------------------------------------------------------------------------*/
1286
1287void DynamicMeshIncrementalBuilder::
1288_appendInitializedRelationInfo(Int64Array& source_relation_info, std::map<Int64, Int64SharedArray>& source_to_target_uids, Int64ConstArrayView source_item_uids_and_types,
1289 Integer approx_relation_size,
1290 IItemFamily const* target_family)
1291{
1292 // Create a working array to build the consolidated info. This array will be copied in to source_relation_info at the end.
1293 Int64UniqueArray source_relation_info_wrk_copy;
1294 source_relation_info_wrk_copy.reserve(source_relation_info.size() + approx_relation_size);
1295 std::set<Int64> treated_items; // To detect eventual source_items not already present in source_relation_info
1296 Integer source_relation_info_index = 0;
1297 Integer nb_connected_family = CheckedConvert::toInteger(source_relation_info[source_relation_info_index++]);
1298 source_relation_info_wrk_copy.add(nb_connected_family + 1); // adding a new connected family
1299 for (; source_relation_info_index < source_relation_info.size();) {
1300 source_relation_info_wrk_copy.add(source_relation_info[source_relation_info_index++]); // item type
1301 Int64 source_item_uid = source_relation_info[source_relation_info_index++]; // get item uid
1302 source_relation_info_wrk_copy.add(source_item_uid);
1303 treated_items.insert(source_item_uid);
1304 for (Integer connected_family_index = 0; connected_family_index < nb_connected_family; ++connected_family_index) {
1305 source_relation_info_wrk_copy.add(source_relation_info[source_relation_info_index++]); // family kind
1306 Integer nb_connected_elements = CheckedConvert::toInteger(source_relation_info[source_relation_info_index++]); // nb connected elements
1307 source_relation_info_wrk_copy.add(nb_connected_elements);
1308 source_relation_info_wrk_copy.addRange(source_relation_info.subConstView(source_relation_info_index, nb_connected_elements));
1309 source_relation_info_index += nb_connected_elements;
1310 }
1311 // Add new connection info
1312 source_relation_info_wrk_copy.add(target_family->itemKind()); // family kind
1313 const auto& connected_items = source_to_target_uids[source_item_uid]; // get connected items
1314 source_relation_info_wrk_copy.add(connected_items.size()); // nb connected elements
1315 source_relation_info_wrk_copy.addRange(connected_items);
1316 }
1317 // Find eventual source_items not already present in source_relation_info : todo check this can happen
1318 for (Integer source_item_uids_and_types_index = 0; source_item_uids_and_types_index < source_item_uids_and_types.size(); source_item_uids_and_types_index += 2) {
1319 Int64 source_item_uid = source_item_uids_and_types[source_item_uids_and_types_index];
1320 if (treated_items.find(source_item_uid) == treated_items.end()) {
1321 source_relation_info_wrk_copy.add(source_item_uids_and_types[source_item_uids_and_types_index + 1]); // item type
1322 source_relation_info_wrk_copy.add(source_item_uid); // item uid
1323 source_relation_info_wrk_copy.add(target_family->itemKind()); // family kind
1324 const auto& connected_items = source_to_target_uids[source_item_uid]; // get connected items
1325 source_relation_info_wrk_copy.add(connected_items.size()); // nb connected elements
1326 source_relation_info_wrk_copy.addRange(connected_items);
1327 // Padd this item info with family info : we added only one family, add void values for the other nb_connected_family families
1328 for (Integer connected_family_index = 0; connected_family_index < nb_connected_family; ++connected_family_index) {
1329 source_relation_info_wrk_copy.add(0); // family id (does not matter)
1330 source_relation_info_wrk_copy.add(0); // nb_connected_elements for this family
1331 }
1332 }
1333 }
1334 // Copy working array into destination array
1335 source_relation_info.resize(source_relation_info_wrk_copy.size());
1336 std::copy(source_relation_info_wrk_copy.begin(), source_relation_info_wrk_copy.end(), source_relation_info.begin());
1337}
1338
1339/*---------------------------------------------------------------------------*/
1340/*---------------------------------------------------------------------------*/
1341
1342Int64 DynamicMeshIncrementalBuilder::
1343_findFaceUniqueId(Int64ConstArrayView work_face_sorted_nodes, NodeInFaceSet& face_nodes_set)
1344{
1345 // check if first node exist
1346 Integer index = 0;
1347 // return _findFaceInFaceNodesSet(face_nodes_set,index,work_face_sorted_nodes,std::make_shared<NodeInFace>(NULL_ITEM_ID));
1348 return _findFaceInFaceNodesSet(face_nodes_set, index, work_face_sorted_nodes, NodeInFacePtr(NULL_ITEM_ID));
1349}
1350
1351/*---------------------------------------------------------------------------*/
1352
1353Int64 DynamicMeshIncrementalBuilder::
1354_findFaceInFaceNodesSet(const NodeInFaceSet& face_nodes_set, Integer index, Int64ConstArrayView face_nodes, NodeInFacePtr node)
1355{
1356 if (index < face_nodes.size()) {
1357 auto found_node = std::find(face_nodes_set.begin(), face_nodes_set.end(), NodeInFacePtr(face_nodes[index]));
1358 if (found_node == face_nodes_set.end())
1359 return node->faceUid();
1360 else
1361 return _findFaceInFaceNodesSet((*found_node)->nextNodeSet(), ++index, face_nodes, *found_node);
1362 }
1363 else
1364 return node->faceUid();
1365}
1366
1367/*---------------------------------------------------------------------------*/
1368
1369void DynamicMeshIncrementalBuilder::
1370_addFaceNodes(NodeInFaceSet& face_nodes_set, Int64ConstArrayView face_nodes, Int64 face_uid)
1371{
1372 Integer index = 0;
1373 // _addFaceInFaceNodesSet(face_nodes_set, index,face_nodes, std::make_shared<NodeInFace>(NULL_ITEM_ID), face_uid);
1374 _addFaceInFaceNodesSet(face_nodes_set, index, face_nodes, NodeInFacePtr(NULL_ITEM_ID), face_uid);
1375}
1376
1377/*---------------------------------------------------------------------------*/
1378
1379void DynamicMeshIncrementalBuilder::
1380_addFaceInFaceNodesSet(NodeInFaceSet& face_nodes_set, Integer index, Int64ConstArrayView face_nodes, NodeInFacePtr node, Int64 face_uid)
1381{
1382 if (index < face_nodes.size()) {
1383 // auto next_node = std::make_shared<NodeInFace>(face_nodes[index]);
1384 auto next_node = _insertNode(face_nodes_set, face_nodes[index]);
1385 // debug() << "Add node " << face_nodes[index] << " in set " << &face_nodes_set;
1386 // debug() << "set size " << face_nodes_set.size();
1387 _addFaceInFaceNodesSet(next_node->nextNodeSet(), ++index, face_nodes, next_node, face_uid);
1388 // else
1389 // _addFaceInFaceNodesSet((*insertion_return.first)->nextNodeSet(),++index,face_nodes,*insertion_return.first,face_uid); // pbe du const. Change from set to map ?
1390 }
1391 else {
1392 node->setFaceUid(face_uid);
1393 // debug() << "Set face uid " << face_uid << " for node " << node->m_uid;
1394 }
1395}
1396
1398DynamicMeshIncrementalBuilder::_insertNode(NodeInFaceSet& face_nodes_set, Int64 inserted_node_uid)
1399{
1400 NodeInFacePtr new_node(inserted_node_uid);
1401 auto found_node = std::find(face_nodes_set.begin(), face_nodes_set.end(), new_node);
1402 if (found_node == face_nodes_set.end()) {
1403 face_nodes_set.push_back(std::move(new_node));
1404 return face_nodes_set.back();
1405 }
1406 else
1407 return *found_node;
1408}
1409
1410/*---------------------------------------------------------------------------*/
1411/*---------------------------------------------------------------------------*/
1419addParentCells(const ItemVectorView& items)
1420{
1421 const Integer nb_cell = items.size();
1422
1423 for (Integer i_cell = 0; i_cell < nb_cell; ++i_cell) {
1424 m_one_mesh_item_adder->addOneParentItem(items[i_cell], IK_Cell);
1425 }
1426}
1427
1428/*---------------------------------------------------------------------------*/
1429/*---------------------------------------------------------------------------*/
1430
1440addHChildrenCells(Cell hParent_cell, Integer nb_cell, Int64ConstArrayView cells_infos,
1441 Integer sub_domain_id, Int32ArrayView cells,
1442 bool allow_build_face)
1443{
1444 ItemTypeMng* itm = m_item_type_mng;
1445 CellFamily& cell_family = m_mesh->trueCellFamily();
1446
1447 debug() << "[DynamicMeshIncrementalBuilder::addHChildrenCells] ADD CELLS mesh=" << m_mesh->name() << " nb_cell=" << nb_cell;
1448 Integer cells_infos_index = 0;
1449 bool add_to_cells = cells.size() != 0;
1450 if (add_to_cells && nb_cell != cells.size())
1451 throw ArgumentException(A_FUNCINFO,
1452 "return array 'cells' has to have same size as number of cells");
1453 for (Integer i_cell = 0; i_cell < nb_cell; ++i_cell) {
1454 debug(Trace::Highest) << "\t\t[DynamicMeshIncrementalBuilder::addHChildrenCells]cell " << i_cell << "/" << nb_cell;
1455
1456 ItemTypeId item_type_id{ (Int16)cells_infos[cells_infos_index] };
1457 debug(Trace::Highest) << "\t\t[DynamicMeshIncrementalBuilder::addHChildrenCells]cells_infos[" << cells_infos_index << "]=" << cells_infos[cells_infos_index] << ", type_id=" << item_type_id;
1458 ++cells_infos_index;
1459
1460 Int64 cell_unique_id = cells_infos[cells_infos_index];
1461 debug(Trace::Highest) << "\t\t[DynamicMeshIncrementalBuilder::addHChildrenCells]cells_infos[" << cells_infos_index << "]=" << cells_infos[cells_infos_index] << ", uid=" << cell_unique_id;
1462 ++cells_infos_index;
1463
1464 ItemTypeInfo* it = itm->typeFromId(item_type_id);
1465 Integer current_cell_nb_node = it->nbLocalNode();
1466 debug(Trace::Highest) << "\t\t[DynamicMeshIncrementalBuilder::addHChildrenCells]DM ADD_CELL uid=" << cell_unique_id << " type_id=" << item_type_id
1467 << " nb_node=" << current_cell_nb_node;
1468 Int64ConstArrayView current_cell_nodes_uid(current_cell_nb_node, &cells_infos[cells_infos_index]);
1469 for (Integer i = 0; i < current_cell_nb_node; ++i)
1470 debug(Trace::Highest) << "\t\t\t[DynamicMeshIncrementalBuilder::addHChildrenCells]DM NODE uid=" << current_cell_nodes_uid[i];
1471
1472 ItemInternal* cell = m_one_mesh_item_adder->addOneCell(item_type_id,
1473 cell_unique_id,
1474 sub_domain_id,
1475 current_cell_nodes_uid,
1476 allow_build_face);
1477
1478 cell_family._addParentCellToCell(cell, hParent_cell);
1479 if (add_to_cells)
1480 cells[i_cell] = cell->localId();
1481 cells_infos_index += current_cell_nb_node;
1482 }
1483 cell_family._addChildrenCellsToCell(hParent_cell, cells);
1484
1485 debug() << "[DynamicMeshIncrementalBuilder::addHChildrenCells] done";
1486}
1487
1488/*---------------------------------------------------------------------------*/
1489/*---------------------------------------------------------------------------*/
1497addParentItems(const ItemVectorView& items, const eItemKind submesh_kind)
1498{
1499 const Integer nb_item = items.size();
1500
1501 for (Integer i_item = 0; i_item < nb_item; ++i_item) {
1502 m_one_mesh_item_adder->addOneParentItem(items[i_item], submesh_kind, false);
1503 }
1504}
1505
1506/*---------------------------------------------------------------------------*/
1507/*---------------------------------------------------------------------------*/
1516addNodes(Int64ConstArrayView nodes_uid, Integer owner, Int32ArrayView nodes)
1517{
1518 Integer nb_node_to_add = nodes_uid.size();
1519 bool add_to_nodes = nodes.size() != 0;
1520 if (add_to_nodes && nb_node_to_add != nodes.size())
1521 throw ArgumentException(A_FUNCINFO,
1522 "return array 'nodes' has to have same size as number of nodes");
1523 for (Integer i_node = 0; i_node < nb_node_to_add; ++i_node) {
1524 ItemInternal* node = m_one_mesh_item_adder->addOneNode(nodes_uid[i_node], owner);
1525 if (add_to_nodes)
1526 nodes[i_node] = node->localId();
1527 }
1528}
1529
1530/*---------------------------------------------------------------------------*/
1531/*---------------------------------------------------------------------------*/
1540addNodes2(Int64ConstArrayView nodes_uid, Integer owner, Int32ArrayView nodes)
1541{
1542 Integer nb_node_to_add = nodes_uid.size();
1543 bool add_to_nodes = nodes.size() != 0;
1544 if (add_to_nodes && nb_node_to_add != nodes.size())
1545 throw ArgumentException(A_FUNCINFO,
1546 "return array 'nodes' has to have same size as number of nodes");
1547 ItemDataList item_info_list;
1548 ItemData& node_data = item_info_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()),
1549 nb_node_to_add, 2 * nb_node_to_add + 1, nodes, &mesh()->trueNodeFamily(), &mesh()->trueNodeFamily(), owner);
1550 Int64Array& node_infos2 = node_data.itemInfos();
1551 // Copy node_info : to decrease the footprint of the copy, use references instead of int64
1552 _fillNodeNewInfo(nodes_uid, node_infos2);
1553
1554 addItems(item_info_list);
1555}
1556
1557/*---------------------------------------------------------------------------*/
1558/*---------------------------------------------------------------------------*/
1559
1560void DynamicMeshIncrementalBuilder::
1561_fillNodeNewInfo(Int64ConstArrayView node_uids, Int64ArrayView node_infos2)
1562{
1563 node_infos2[0] = 0; // nb_connected_families
1564 Integer index = 0;
1565 for (auto node_uid : node_uids) {
1566 node_infos2[2 * index + 1] = IT_Vertex; // type
1567 node_infos2[2 * index + 2] = node_uid; // id
1568 index++;
1569 }
1570}
1571
1572/*---------------------------------------------------------------------------*/
1573/*---------------------------------------------------------------------------*/
1592
1594addItems(ItemDataList& item_info_list)
1595{
1596 // Add items : item construction done from leaves to root
1597 _addItemsOrRelations(item_info_list, IItemFamilyNetwork::InverseTopologicalOrder);
1598}
1599
1600/*---------------------------------------------------------------------------*/
1601
1603addItems(ItemDataList& item_info_list, ItemDataList& item_relation_info_list)
1604{
1605 if (item_info_list.size() == 0 || item_relation_info_list.size() == 0)
1606 return;
1607 addItems(item_info_list);
1608 addRelations(item_relation_info_list);
1609}
1610
1611/*---------------------------------------------------------------------------*/
1612
1613void DynamicMeshIncrementalBuilder::
1614addRelations(ItemDataList& item_relation_list)
1615{
1616 // Add relations : items are already added. Do it from root to leaves
1617 _addItemsOrRelations(item_relation_list, IItemFamilyNetwork::TopologicalOrder);
1618}
1619
1620/*---------------------------------------------------------------------------*/
1621
1622void DynamicMeshIncrementalBuilder::
1623_addItemsOrRelations(ItemDataList& info_list, IItemFamilyNetwork::eSchedulingOrder family_graph_traversal_order)
1624{
1625 // Add relations : items are already added. Do it from root to leaves
1626 if (info_list.size() == 0)
1627 return;
1628 m_mesh->itemFamilyNetwork()->schedule([&](IItemFamily* family) {
1629 ItemData i_infos = info_list[family->itemKind()];
1630 this->addFamilyItems(i_infos);
1631 },
1632 family_graph_traversal_order); // item construction done from leaves to root
1633}
1634
1635/*---------------------------------------------------------------------------*/
1636/*---------------------------------------------------------------------------*/
1641
1643addFamilyItems(ItemData& item_data)
1644{
1645 if (item_data.nbItems() == 0)
1646 return;
1647 bool add_to_items = item_data.itemLids().size() != 0;
1648 if (add_to_items && item_data.nbItems() != item_data.itemLids().size())
1649 throw ArgumentException(A_FUNCINFO,
1650 "return array containing item lids has to have be of size number of items");
1651 // Prepare info and call OneMeshItemAdder->addOneItem
1652 Int64 item_uid;
1653 Int64ConstArrayView item_infos = item_data.itemInfos();
1654 Integer nb_connected_family = CheckedConvert::toInteger(item_infos[0]);
1655 if (nb_connected_family == 0)
1656 return;
1657 Int64UniqueArray connectivity_info;
1658 Integer nb_item_info = 0;
1659 Integer item_index = 0;
1660 for (Integer info_index = 1; info_index < item_data.itemInfos().size();) {
1661 ItemTypeId item_type_id{ (Int16)item_infos[info_index++] }; // item_type
1662 item_uid = item_infos[info_index++]; // item_uid
1663 Integer item_info_begin_index = info_index;
1664 for (Integer connected_family_index = 0; connected_family_index < nb_connected_family; ++connected_family_index) {
1665 Integer current_index = CheckedConvert::toInteger(item_infos[info_index + 1]);
1666 Integer nb_item_info_increment = 2 + current_index;
1667 nb_item_info += nb_item_info_increment; // family_id , nb_connected_elements
1668 info_index += nb_item_info_increment; // pointing on next family id
1669 }
1670 ItemInternal* item = m_one_mesh_item_adder->addOneItem2(item_data.itemFamily(),
1671 item_data.itemFamilyModifier(),
1672 item_type_id,
1673 item_uid,
1674 item_data.itemOwners()[item_index],
1675 item_data.subDomainId(),
1676 nb_connected_family,
1677 item_infos.subView(item_info_begin_index, nb_item_info));
1678 if (add_to_items)
1679 item_data.itemLids()[item_index++] = item->localId();
1680 nb_item_info = 0;
1681 }
1682}
1683
1684/*---------------------------------------------------------------------------*/
1685/*---------------------------------------------------------------------------*/
1695addFaces(Integer nb_face, Int64ConstArrayView faces_infos,
1696 Int32 rank, Int32ArrayView faces)
1697{
1698 ItemTypeMng* itm = m_item_type_mng;
1699
1700 bool add_to_faces = faces.size() != 0;
1701 if (add_to_faces && nb_face != faces.size())
1702 throw ArgumentException(A_FUNCINFO,
1703 "return array 'faces' has to have same size as number of faces");
1704
1705 Integer faces_infos_index = 0;
1706 for (Integer i_face = 0; i_face < nb_face; ++i_face) {
1707
1708 ItemTypeId item_type_id = ItemTypeId::fromInteger(faces_infos[faces_infos_index]);
1709 ++faces_infos_index;
1710 Int64 face_unique_id = faces_infos[faces_infos_index];
1711 ++faces_infos_index;
1712
1713 ItemTypeInfo* it = itm->typeFromId(item_type_id);
1714
1715 Integer current_face_nb_node = it->nbLocalNode();
1716 Int64ConstArrayView nodes_uid(current_face_nb_node, &faces_infos[faces_infos_index]);
1717 faces_infos_index += current_face_nb_node;
1718
1719 ItemInternal* face = m_one_mesh_item_adder->addOneFace(item_type_id, face_unique_id, rank, nodes_uid);
1720
1721 if (add_to_faces)
1722 faces[i_face] = face->localId();
1723 }
1724}
1725
1726/*---------------------------------------------------------------------------*/
1727/*---------------------------------------------------------------------------*/
1737addFaces2(Integer nb_face, Int64ConstArrayView faces_infos,
1738 Integer sub_domain_id, Int32ArrayView faces)
1739{
1740 bool add_to_faces = faces.size() != 0;
1741 if (add_to_faces && nb_face != faces.size())
1742 throw ArgumentException(A_FUNCINFO,
1743 "return array 'faces' has to have same size as number of faces");
1744 // Prepare face infos 2
1745 Integer face_infos2_size = faces_infos.size() + 1 + 2 * nb_face; // additive info nb_connected_family + nb_face * (family_id + nb_connected_element)
1746 ItemDataList item_info_list;
1747 ItemData& face_data = item_info_list.itemData(Integer(m_mesh->faceFamily()->itemKind()),
1748 nb_face, face_infos2_size, faces, &mesh()->trueFaceFamily(), &mesh()->trueFaceFamily(), sub_domain_id);
1749
1750 Int64ArrayView face_infos2 = face_data.itemInfos().view();
1751 Int64UniqueArray node_uids;
1752 Int64UniqueArray edge_uids;
1753
1754 _fillFaceInfo2(nb_face, faces_infos, face_infos2, node_uids);
1755
1756 // Prepare edge data if needed
1757 // if (m_has_edge) {
1758 // Integer nb_edge_to_add = edge_uids.size();
1759 // Int32UniqueArray edge_lids(nb_edge_to_add);
1760 // ItemData& edge_data = item_info_list.itemData(Integer(m_mesh->edgeFamily()->itemKind()),
1761 // nb_edge_to_add,2*nb_edge_to_add+1,edge_lids,&mesh()->trueNodeFamily(),&mesh()->trueNodeFamily(),sub_domain_id);
1762 // Int64Array& edge_infos2 = edge_data.itemInfos();
1763 // _fillEdgeInfo2(nb_edge_to_add,edge_uids,edge_infos2);
1764 // }
1765
1766 // Prepare node data (mutualize)
1767 Integer nb_node_to_add = node_uids.size();
1768 Int32UniqueArray node_lids(nb_node_to_add);
1769 ItemData& node_data = item_info_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()),
1770 nb_node_to_add, 2 * nb_node_to_add + 1, node_lids, &mesh()->trueNodeFamily(), &mesh()->trueNodeFamily(), sub_domain_id);
1771 Int64Array& node_infos2 = node_data.itemInfos();
1772 _fillNodeNewInfo(node_uids, node_infos2);
1773
1774 // Launch node and face creation
1775 addItems(item_info_list);
1776}
1777
1778/*---------------------------------------------------------------------------*/
1779
1780void DynamicMeshIncrementalBuilder::
1781addFaces3(Integer nb_face, Int64ConstArrayView faces_infos,
1782 Integer sub_domain_id, Int32ArrayView faces)
1783{
1784 bool add_to_faces = faces.size() != 0;
1785 if (add_to_faces && nb_face != faces.size())
1786 throw ArgumentException(A_FUNCINFO,
1787 "return array 'faces' has to have same size as number of faces");
1788 ItemDataList item_data_list;
1789 ItemDataList item_relation_data_list;
1790 // item info_size cannot be guessed
1791 Int64UniqueArray edges_infos;
1792 Int64UniqueArray nodes_infos;
1793 Int64UniqueArray node_uids;
1794 Int32UniqueArray edge_lids;
1795 Int32UniqueArray node_lids;
1796 Integer nb_edge = 0;
1797 Integer nb_node = 0;
1798 std::map<std::pair<Int64, Int64>, Int64> edge_uid_map;
1799
1800 // Fill classical info
1801 _fillEdgeInfo(nb_edge, nb_face, edges_infos, faces_infos, edge_uid_map);
1802 _fillNodeInfo(nb_node, nb_face, nodes_infos, faces_infos);
1803
1804 // Face info New
1805 ItemData& face_data = item_data_list.itemData(Integer(m_mesh->faceFamily()->itemKind()), nb_face, 0, faces, &mesh()->trueFaceFamily(), &mesh()->trueFaceFamily(), sub_domain_id);
1806 _fillFaceNewInfoNew(nb_face, faces_infos, face_data.itemInfos(), edge_uid_map);
1807
1808 // Edge info New
1809 if (hasEdge()) {
1810 Integer edge_info_size = 1 + nb_edge * 6; //New info = Nb_connected_family + for each edge : type, uid, connected_family_kind, nb_node_connected, first_node_uid, second_node_uid
1811 ItemData& edge_data = item_data_list.itemData(Integer(m_mesh->edgeFamily()->itemKind()), nb_edge, edge_info_size, edge_lids, &mesh()->trueEdgeFamily(), &mesh()->trueEdgeFamily(), sub_domain_id);
1812 edge_lids.resize(item_data_list[m_mesh->edgeFamily()->itemKind()].nbItems());
1813 _fillEdgeNewInfoNew(nb_edge, edges_infos, edge_data.itemInfos()); // reprendre fillEdgeInfo et voir l'appel depuis add Edges + attention ordre des noeuds,
1814 ItemData& edge_relation_data = item_relation_data_list.itemData(Integer(m_mesh->edgeFamily()->itemKind()), nb_edge, edge_info_size, edge_lids, &mesh()->trueEdgeFamily(), &mesh()->trueEdgeFamily(), sub_domain_id);
1815 _initEdgeRelationInfo(edge_relation_data, face_data, edges_infos); // edge-face relation
1816 }
1817
1818 // Node info New
1819 Integer node_info_size = 1 + nb_node * 2; //New info = Nb_connected_family + for each node : type, uid (no connected family)
1820 ItemData& node_data = item_data_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()), nb_node, node_info_size, node_lids, &mesh()->trueNodeFamily(), &mesh()->trueNodeFamily(), sub_domain_id);
1821 node_lids.resize(item_data_list[m_mesh->nodeFamily()->itemKind()].nbItems());
1822 _fillNodeNewInfo(nodes_infos, node_data.itemInfos());
1823 ItemData& node_relation_data = item_relation_data_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()), nb_node, node_info_size, node_lids, &mesh()->trueNodeFamily(), &mesh()->trueNodeFamily(), sub_domain_id);
1824 _initNodeRelationInfo(node_relation_data, face_data, nodes_infos); // node-face relation
1825
1826 // Launch node, face and edges (not compulsory) creation
1827 addItems(item_data_list, item_relation_data_list);
1828}
1829
1830/*---------------------------------------------------------------------------*/
1831/*---------------------------------------------------------------------------*/
1832
1833void DynamicMeshIncrementalBuilder::
1834_fillFaceNewInfoNew(Integer nb_face, Int64ConstArrayView faces_infos, Int64Array& face_infos2, const std::map<std::pair<Int64, Int64>, Int64>& edge_uid_map)
1835{
1836 ItemTypeMng* itm = m_item_type_mng;
1837 Integer nb_connected_family = hasEdge() ? 2 : 1;
1838 Integer face_infos2_size_approx = 1 + 2 * (faces_infos.size() + 2 * nb_face); // supposes as many faces as edges...
1839 face_infos2.reserve(face_infos2_size_approx);
1840 Int64UniqueArray work_face_sorted_nodes;
1841 Int64UniqueArray work_face_orig_nodes;
1842 Integer faces_infos_index = 0;
1843 // Integer face_infos2_index = 0;
1844 std::set<Int64> node_uids_set;
1845 face_infos2.add(nb_connected_family); // nb_connected_families nodes +/- Edges !!
1846 // Fill face_infos2 from faces_infos
1847 for (Integer i_face = 0; i_face < nb_face; ++i_face) {
1848 Integer current_face_type = (Integer)faces_infos[faces_infos_index++];
1849 Integer current_face_uid = (Integer)faces_infos[faces_infos_index++];
1850 face_infos2.add(current_face_type); // type
1851 face_infos2.add(current_face_uid); // uid
1852 //--Node connectivity
1853 face_infos2.add(mesh()->nodeFamily()->itemKind()); // connected_family_id
1854 ItemTypeInfo* it = itm->typeFromId(current_face_type);
1855 Integer current_face_nb_node = it->nbLocalNode();
1856 face_infos2.add(current_face_nb_node); // nb_connected_nodes
1857 // Nodes are not necessarily sorted (if caller is addFaces...)
1858 Int64ConstArrayView current_face_node_uids(current_face_nb_node, &faces_infos[faces_infos_index]);
1859 work_face_orig_nodes.resize(current_face_nb_node);
1860 work_face_sorted_nodes.resize(current_face_nb_node);
1861 work_face_orig_nodes.copy(current_face_node_uids);
1862 mesh_utils::reorderNodesOfFace(work_face_orig_nodes, work_face_sorted_nodes);
1863 face_infos2.addRange(work_face_sorted_nodes); // connected node uids
1864 faces_infos_index += current_face_nb_node;
1865 //--Edge Connectivity
1866 if (hasEdge()) {
1867 face_infos2.add(mesh()->edgeFamily()->itemKind());
1868 face_infos2.add(it->nbLocalEdge()); // nb_connected_edges
1869 for (int edge_index = 0; edge_index < it->nbLocalEdge(); ++edge_index) {
1870 Int64 first_node = work_face_sorted_nodes[it->localEdge(edge_index).beginNode()];
1871 Int64 second_node = work_face_sorted_nodes[it->localEdge(edge_index).endNode()];
1872 if (first_node > second_node)
1873 std::swap(first_node, second_node); // edge may be oriented negatively in the face
1874 auto edge_it = edge_uid_map.find(std::make_pair(first_node, second_node));
1875 if (edge_it == edge_uid_map.end())
1876 ARCANE_FATAL("Do not find edge with nodes {0}-{1} in edge uid map. Exiting",
1877 work_face_sorted_nodes[it->localEdge(edge_index).beginNode()],
1878 work_face_sorted_nodes[it->localEdge(edge_index).endNode()]);
1879 face_infos2.add(edge_it->second); // connected edge uid
1880 }
1881 }
1882 }
1883}
1884
1885/*---------------------------------------------------------------------------*/
1886
1887void DynamicMeshIncrementalBuilder::
1888_fillFaceInfo2(Integer nb_face, Int64ConstArrayView faces_infos, Int64ArrayView face_infos2, Int64Array& node_uids)
1889{
1890 ItemTypeMng* itm = m_item_type_mng;
1891 Integer faces_infos_index = 0;
1892 Integer face_infos2_index = 0;
1893 face_infos2[face_infos2_index++] = 1; // nb_connected_families (node only)
1894 Int64UniqueArray work_face_sorted_nodes;
1895 Int64UniqueArray work_face_orig_nodes;
1896 std::set<Int64> node_uids_set;
1897 // Fill face_infos2 from faces_infos
1898 for (Integer i_face = 0; i_face < nb_face; ++i_face) {
1899
1900 Integer item_type_id = (Integer)faces_infos[faces_infos_index];
1901 face_infos2[face_infos2_index++] = faces_infos[faces_infos_index++]; // type
1902 face_infos2[face_infos2_index++] = faces_infos[faces_infos_index++]; // uid
1903 face_infos2[face_infos2_index++] = mesh()->nodeFamily()->itemKind(); // connected_family_id
1904
1905 ItemTypeInfo* it = itm->typeFromId(item_type_id);
1906 Integer current_face_nb_node = it->nbLocalNode();
1907 face_infos2[face_infos2_index++] = current_face_nb_node; // nb_connected_items
1908 Int64ConstArrayView current_face_node_uids(current_face_nb_node, &faces_infos[faces_infos_index]);
1909 work_face_orig_nodes.resize(current_face_nb_node);
1910 work_face_sorted_nodes.resize(current_face_nb_node);
1911 work_face_orig_nodes.copy(current_face_node_uids);
1912 mesh_utils::reorderNodesOfFace(work_face_orig_nodes, work_face_sorted_nodes);
1913 face_infos2.subView(face_infos2_index, current_face_nb_node).copy(work_face_sorted_nodes); // connected node uids
1914 faces_infos_index += current_face_nb_node;
1915 face_infos2_index += current_face_nb_node;
1916 node_uids_set.insert(current_face_node_uids.begin(), current_face_node_uids.end());
1917 }
1918 node_uids.resize(node_uids_set.size());
1919 Integer index = 0;
1920 for (Int64 node_uid : node_uids_set)
1921 node_uids[index++] = node_uid;
1922}
1923
1924/*---------------------------------------------------------------------------*/
1925/*---------------------------------------------------------------------------*/
1935addEdges(Integer nb_edge, Int64ConstArrayView edge_infos,
1936 Integer sub_domain_id, Int32ArrayView edges)
1937{
1938 bool add_to_edges = edges.size() != 0;
1939 if (add_to_edges && nb_edge != edges.size())
1940 throw ArgumentException(A_FUNCINFO,
1941 "return array 'edges' has to have same size as number of edges");
1942
1943 Integer edge_info_index = 0;
1944 for (Integer i_edge = 0; i_edge < nb_edge; ++i_edge) {
1945
1946 Int64 edge_unique_id = edge_infos[edge_info_index];
1947 ++edge_info_index;
1948
1949 Int64ConstArrayView nodes_uid(2, &edge_infos[edge_info_index]);
1950 edge_info_index += 2;
1951
1952 ItemInternal* edge = m_one_mesh_item_adder->addOneEdge(edge_unique_id, sub_domain_id, nodes_uid);
1953
1954 if (add_to_edges)
1955 edges[i_edge] = edge->localId();
1956 }
1957}
1958
1959/*---------------------------------------------------------------------------*/
1960/*---------------------------------------------------------------------------*/
1970addEdges2(Integer nb_edge, Int64ConstArrayView edge_infos,
1971 Integer sub_domain_id, Int32ArrayView edges)
1972{
1973 bool add_to_edges = edges.size() != 0;
1974 if (add_to_edges && nb_edge != edges.size())
1975 throw ArgumentException(A_FUNCINFO,
1976 "return array 'edges' has to have same size as number of edges");
1977
1978 // Prepare face infos 2
1979 Integer edge_infos2_size = edge_infos.size() + 1 + 2 * nb_edge; // additive info nb_connected_family + nb_face * (family_id + nb_connected_element)
1980 ItemDataList item_info_list;
1981 ItemData& edge_data = item_info_list.itemData(Integer(m_mesh->edgeFamily()->itemKind()),
1982 nb_edge, edge_infos2_size, edges, &mesh()->trueEdgeFamily(), &mesh()->trueEdgeFamily(), sub_domain_id);
1983
1984 Int64ArrayView edge_infos2 = edge_data.itemInfos().view();
1985 Int64UniqueArray node_uids;
1986
1987 _fillEdgeInfo2(nb_edge, edge_infos, edge_infos2, node_uids);
1988
1989 // Prepare node data (mutualize)
1990 Integer nb_node_to_add = node_uids.size();
1991 Int32UniqueArray node_lids(nb_node_to_add);
1992 ItemData& node_data = item_info_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()),
1993 nb_node_to_add, 2 * nb_node_to_add + 1, node_lids, &mesh()->trueNodeFamily(), &mesh()->trueNodeFamily(), sub_domain_id);
1994 Int64Array& node_infos2 = node_data.itemInfos();
1995 _fillNodeNewInfo(node_uids, node_infos2);
1996
1997 // Launch node and face creation
1998 addItems(item_info_list);
1999}
2000
2001void DynamicMeshIncrementalBuilder::
2002addEdges3(Integer nb_edge, Int64ConstArrayView edges_infos,
2003 Integer sub_domain_id, Int32ArrayView edges)
2004{
2005 bool add_to_edges = edges.size() != 0;
2006 if (add_to_edges && nb_edge != edges.size())
2007 throw ArgumentException(A_FUNCINFO,
2008 "return array 'edges' has to have same size as number of edges");
2009 ItemDataList item_data_list;
2010 ItemDataList item_relation_data_list;
2011 // item info_size cannot be guessed
2012 Int64UniqueArray nodes_infos;
2013 Int32UniqueArray node_lids;
2014 Integer nb_node = 0;
2015
2016 // Fill classical info
2017 _fillNodeInfoFromEdge(nb_node, nb_edge, nodes_infos, edges_infos);
2018
2019 // Edge new info : edge data stores edge uids and dependency connectivities
2020 ItemData& edge_data = item_data_list.itemData(Integer(m_mesh->edgeFamily()->itemKind()), nb_edge, 0, edges, &mesh()->trueEdgeFamily(), &mesh()->trueEdgeFamily(), sub_domain_id);
2021 _fillEdgeNewInfoNew(nb_edge, edges_infos, edge_data.itemInfos());
2022
2023 // Node new info & relationsm
2024 ItemData& node_data = item_data_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()), nb_node, 0, node_lids, &mesh()->trueNodeFamily(), &mesh()->trueNodeFamily(), sub_domain_id);
2025 node_lids.resize(nb_node);
2026 _fillNodeNewInfo(nodes_infos, node_data.itemInfos());
2027 ItemData& node_relations_data = item_relation_data_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()), nb_node, 0, node_lids, &mesh()->trueNodeFamily(), &mesh()->trueNodeFamily(), sub_domain_id);
2028 _initNodeRelationInfo(node_relations_data, edge_data, nodes_infos); // node-edge relation
2029
2030 // Launch node and edges creation
2031 addItems(item_data_list, item_relation_data_list);
2032}
2033
2034/*---------------------------------------------------------------------------*/
2035/*---------------------------------------------------------------------------*/
2036
2037void DynamicMeshIncrementalBuilder::
2038_fillEdgeInfo2(Integer nb_edge, Int64ConstArrayView edges_infos, Int64ArrayView edge_infos2, Int64Array& node_uids)
2039{
2040 Integer edges_infos_index = 0;
2041 Integer edge_infos2_index = 0;
2042 std::set<Int64> node_uids_set;
2043
2044 // Fill edge_infos2 from edges_infos
2045 edge_infos2[edge_infos2_index++] = 1; // nb_connected_families (node only)
2046
2047 for (Integer i_edge = 0; i_edge < nb_edge; ++i_edge) {
2048 edge_infos2[edge_infos2_index++] = IT_Line2; // type
2049 edge_infos2[edge_infos2_index++] = edges_infos[edges_infos_index++]; // uid
2050 edge_infos2[edge_infos2_index++] = mesh()->nodeFamily()->itemKind(); // connected_family_id
2051 edge_infos2[edge_infos2_index++] = 2; // nb_connected_items Attention : ordre des noeuds !! TODO
2052 edge_infos2[edge_infos2_index++] = edges_infos[edges_infos_index]; // first connected node uid
2053 node_uids_set.insert(edges_infos[edges_infos_index++]);
2054 edge_infos2[edge_infos2_index++] = edges_infos[edges_infos_index]; // second connected node uid
2055 node_uids_set.insert(edges_infos[edges_infos_index++]);
2056 }
2057 node_uids.resize(node_uids_set.size());
2058 Integer index = 0;
2059 for (Int64 node_uid : node_uids_set)
2060 node_uids[index++] = node_uid;
2061}
2062
2063void DynamicMeshIncrementalBuilder::
2064_fillEdgeNewInfoNew(Integer nb_edge, Int64ConstArrayView edges_infos, Int64ArrayView edges_new_infos)
2065{
2066 Integer edges_infos_index = 0;
2067 Integer edges_new_infos_index = 0;
2068
2069 // Fill edge_infos2 from edges_infos
2070 edges_new_infos[edges_new_infos_index++] = 1; // nb_connected_families (node only)
2071
2072 for (Integer i_edge = 0; i_edge < nb_edge; ++i_edge) {
2073 edges_new_infos[edges_new_infos_index++] = IT_Line2; // type
2074 edges_new_infos[edges_new_infos_index++] = edges_infos[edges_infos_index++]; // uid
2075 edges_new_infos[edges_new_infos_index++] = mesh()->nodeFamily()->itemKind(); // connected_family_id
2076 edges_new_infos[edges_new_infos_index++] = 2; // nb_connected_items
2077 Int64 first_node = edges_infos[edges_infos_index++];
2078 Int64 second_node = edges_infos[edges_infos_index++];
2079 if (first_node > second_node)
2080 std::swap(first_node, second_node);
2081 edges_new_infos[edges_new_infos_index++] = first_node; // first connected node uid
2082 edges_new_infos[edges_new_infos_index++] = second_node; // second connected node uid
2083 }
2084}
2085
2086/*---------------------------------------------------------------------------*/
2087/*---------------------------------------------------------------------------*/
2088
2089void DynamicMeshIncrementalBuilder::
2090readFromDump()
2091{
2092 // Recalculate the max uniqueId() of faces to know what value
2093 // to use in case of face creation.
2094 ItemInternalMap& faces_map = m_mesh->facesMap();
2095 Int64 max_uid = -1;
2096 faces_map.eachItem([&](Item face) {
2097 if (face.uniqueId() > max_uid)
2098 max_uid = face.uniqueId();
2099 });
2100 m_one_mesh_item_adder->setNextFaceUid(max_uid + 1);
2101
2102 if (m_has_edge) {
2103 ItemInternalMap& edges_map = m_mesh->edgesMap();
2104 Int64 max_uid = -1;
2105 edges_map.eachItem([&](Item edge) {
2106 if (edge.uniqueId() > max_uid)
2107 max_uid = edge.uniqueId();
2108 });
2109 m_one_mesh_item_adder->setNextEdgeUid(max_uid + 1);
2110 }
2111
2112 info(5) << "NEXT FACE UID mesh=" << m_mesh->name() << " Next=" << m_one_mesh_item_adder->nextFaceUid();
2113 info(5) << "NEXT EDGE UID mesh=" << m_mesh->name() << " Next=" << m_one_mesh_item_adder->nextEdgeUid();
2114}
2115
2116/*---------------------------------------------------------------------------*/
2117/*---------------------------------------------------------------------------*/
2118
2119void DynamicMeshIncrementalBuilder::
2120printInfos()
2121{
2122 info() << "-- Mesh information (Arcane2):";
2123 info() << "Number of nodes " << m_one_mesh_item_adder->nbNode();
2124 info() << "Number of edges " << m_one_mesh_item_adder->nbEdge();
2125 info() << "Number of faces " << m_one_mesh_item_adder->nbFace();
2126 info() << "Number of cells " << m_one_mesh_item_adder->nbCell();
2127 info() << "-- Graph information (Arcane2):";
2128}
2129
2130/*---------------------------------------------------------------------------*/
2131/*---------------------------------------------------------------------------*/
2132
2133void DynamicMeshIncrementalBuilder::
2134printStats(Int32 level)
2135{
2136 info(level) << "-- -- Statistics";
2137 info(level) << "Number of nodes after addition &: " << m_one_mesh_item_adder->nbNode()
2138 << " hashmap=" << m_mesh->nodesMap().count();
2139 info(level) << "Number of edges after addition : " << m_one_mesh_item_adder->nbEdge()
2140 << " hashmap=" << m_mesh->edgesMap().count();
2141 info(level) << "Number of faces after addition : " << m_one_mesh_item_adder->nbFace()
2142 << " hashmap=" << m_mesh->facesMap().count();
2143 info(level) << "Number of cells after addition : " << m_one_mesh_item_adder->nbCell()
2144 << " hashmap=" << m_mesh->cellsMap().count();
2145 info(level) << "--";
2146}
2147
2148/*---------------------------------------------------------------------------*/
2149/*---------------------------------------------------------------------------*/
2171{
2172 if (!m_face_unique_id_builder)
2173 m_face_unique_id_builder = new FaceUniqueIdBuilder(this);
2174 m_face_unique_id_builder->computeFacesUniqueIds();
2175
2176 if (m_has_edge) {
2177 if (!m_edge_unique_id_builder)
2178 m_edge_unique_id_builder = new EdgeUniqueIdBuilder(this);
2179 m_edge_unique_id_builder->computeEdgesUniqueIds();
2180 }
2181}
2182
2183/*---------------------------------------------------------------------------*/
2184/*---------------------------------------------------------------------------*/
2185
2186void DynamicMeshIncrementalBuilder::
2187addGhostLayers(bool is_allocate)
2188{
2189 debug() << "Add one ghost layer";
2192 m_ghost_layer_builder->addGhostLayers(is_allocate);
2193}
2194
2195/*---------------------------------------------------------------------------*/
2196/*---------------------------------------------------------------------------*/
2197
2200addGhostChildFromParent(Array<Int64>& ghost_cell_to_refine)
2201{
2202 debug() << "Add one ghost layer";
2205 m_ghost_layer_builder->addGhostChildFromParent2(ghost_cell_to_refine);
2206}
2207
2208/*---------------------------------------------------------------------------*/
2209/*---------------------------------------------------------------------------*/
2210
2211void DynamicMeshIncrementalBuilder::
2212_removeNeedRemoveMarkedItems(ItemInternalMap& map, UniqueArray<Int32>& items_local_id)
2213{
2214 // Removal of links
2215 SharedArray<ItemInternal*> items_to_remove;
2216 items_to_remove.reserve(1000);
2217
2218 map.eachItem([&](Item item) {
2219 impl::MutableItemBase mb_item = item.mutableItemBase();
2220 Integer f = mb_item.flags();
2221 if (f & ItemFlags::II_NeedRemove) {
2222 f &= ~ItemFlags::II_NeedRemove;
2223 mb_item.setFlags(f);
2224 items_local_id.add(item.localId());
2225 }
2226 });
2227}
2228
2229/*---------------------------------------------------------------------------*/
2230/*---------------------------------------------------------------------------*/
2231
2242{
2243 if (!m_mesh->useMeshItemFamilyDependencies()) {
2244
2245 IItemFamily* links_family = m_mesh->findItemFamily(IK_DoF, GraphDoFs::linkFamilyName(), false, false);
2246 if (links_family) {
2247 info() << "Remove Items for family : " << links_family->name();
2248 links_family->removeNeedRemoveMarkedItems();
2249 }
2250
2251 for (IItemFamily* family : m_mesh->itemFamilies()) {
2252 if (family->itemKind() != IK_DoF || family->name() == GraphDoFs::linkFamilyName())
2253 continue;
2254 info() << "Remove Items for family : " << family->name();
2255 family->removeNeedRemoveMarkedItems();
2256 }
2257 // Suppression of particles from the Particle family
2258
2259 for (IItemFamilyCollection::Enumerator i(m_mesh->itemFamilies()); ++i;) {
2260 IItemFamily* family = *i;
2261 if (family->itemKind() == IK_Particle) {
2262 ParticleFamily* particle_family = dynamic_cast<ParticleFamily*>(family);
2263 ARCANE_CHECK_POINTER(particle_family);
2264 if (particle_family && particle_family->getEnableGhostItems() == true) {
2265 UniqueArray<Integer> lids_to_remove;
2266 lids_to_remove.reserve(1000);
2267
2268 ItemInternalMap& particle_map = particle_family->itemsMap();
2269 particle_map.eachItem([&](Item item) {
2270 impl::MutableItemBase mb_item = item.mutableItemBase();
2271 Integer f = mb_item.flags();
2272 if (f & ItemFlags::II_NeedRemove) {
2273 f &= ~ItemFlags::II_NeedRemove;
2274 mb_item.setFlags(f);
2275 lids_to_remove.add(item.localId());
2276 }
2277 });
2278
2279 info() << "Number of particles of family " << family->name() << " to remove: " << lids_to_remove.size();
2280 if (lids_to_remove.size() > 0)
2281 particle_family->removeParticles(lids_to_remove);
2282 }
2283 }
2284 }
2285
2286 // Suppression of cells
2287 CellFamily& cell_family = m_mesh->trueCellFamily();
2288 UniqueArray<Int32> cells_to_remove;
2289 cells_to_remove.reserve(1000);
2290 _removeNeedRemoveMarkedItems(cell_family.itemsMap(), cells_to_remove);
2291
2292 info() << "Number of cells to remove: " << cells_to_remove.size();
2293
2294#ifdef ARCANE_DEBUG_DYNAMIC_MESH
2295 for (Integer i = 0, is = cells_to_remove.size(); i < is; ++i)
2296 info() << "remove cell with uid=" << cells_to_remove[i]->uniqueId()
2297 << ",lid=" << cells_to_remove[i]->localId()
2298 << ",owner=" << cells_to_remove[i]->owner();
2299#endif /* ARCANE_DEBUG_DYNAMIC_MESH */
2300
2301 cell_family.removeCells(cells_to_remove);
2302 }
2303 // With ItemFamilyNetwork
2304 else {
2305 // handle families already in the network
2306 m_mesh->itemFamilyNetwork()->schedule([](IItemFamily* family) {
2308 // Remove items from family graph leaves to root
2309 },
2310 IItemFamilyNetwork::InverseTopologicalOrder);
2311 for (auto family : m_mesh->itemFamilies()) {
2312 // handle remaining families (particles, links, dual nodes & dof).
2313 // Will have no effect on the families already handled in the graph (since NeedRemove flag is reset)
2315 }
2316 }
2317}
2318
2319/*---------------------------------------------------------------------------*/
2320/*---------------------------------------------------------------------------*/
2321
2323setConnectivity(const Integer connectivity)
2324{
2325 if (connectivity == 0)
2326 ARCANE_FATAL("Undefined connectivity !");
2327 if (m_connectivity != 0)
2328 ARCANE_FATAL("Connectivity already set: cannot redefine it");
2329 m_connectivity = connectivity;
2330 m_has_edge = Connectivity::hasConnectivity(connectivity, Connectivity::CT_HasEdge);
2331}
2332
2333/*---------------------------------------------------------------------------*/
2334/*---------------------------------------------------------------------------*/
2335
2338{
2339 m_face_uid_pool = 0;
2340 m_edge_uid_pool = 0;
2341 m_one_mesh_item_adder->resetAfterDeallocate();
2342}
2343
2344/*---------------------------------------------------------------------------*/
2345/*---------------------------------------------------------------------------*/
2346
2347} // End namespace Arcane::mesh
2348
2349/*---------------------------------------------------------------------------*/
2350/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro returning the pointer ptr if it is not null or throwing an exception if it is null.
#define ARCANE_THROW(exception_class,...)
Macro for throwing an exception with formatting.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Utility functions for the mesh.
bool reorderNodesOfFace(Int64ConstArrayView before_ids, Int64ArrayView after_ids)
Reorders the nodes of a face.
Int64 generateHashUniqueId(SmallSpan< const Int64 > nodes_unique_id)
Generates a unique identifier from a list of node identifiers.
Integer size() const
Number of elements in the vector.
constexpr ArrayView< T > subView(Integer abegin, Integer asize) noexcept
Sub-view starting from element abegin and containing asize elements.
void fill(const T &o) noexcept
Fills the array with the value o.
constexpr Integer size() const noexcept
Returns the size of the array.
Base class for 1D data vectors.
void fill(ConstReferenceType value)
Fills the array with the value value.
void addRange(ConstReferenceType val, Int64 n)
Adds n elements of value val to the end of the array.
void resize(Int64 s)
Changes the number of elements in the array to s.
ConstArrayView< T > subConstView(Int64 abegin, Int32 asize) const
Sub-view starting from element abegin and containing asize elements.
void add(ConstReferenceType val)
Adds element val to the end of the array.
ConstArrayView< T > constView() const
Constant view of this array.
T & back()
Last element of the array.
void reserve(Int64 new_capacity)
Reserves memory for new_capacity elements.
ArrayView< T > subView(Int64 abegin, Integer asize)
Sub-view starting from element abegin and containing asize elements.
ArrayView< T > view() const
Mutable view of this array.
Cell of a mesh.
Definition Item.h:1300
Constant view of an array of type T.
constexpr ConstArrayView< T > subView(Integer abegin, Integer asize) const noexcept
Sub-view (constant) starting from element abegin and containing asize elements.
constexpr Integer size() const noexcept
Number of elements in the array.
constexpr ConstArrayView< T > subConstView(Integer abegin, Integer asize) const noexcept
Sub-view (constant) starting from element abegin and containing asize elements.
Template class for converting a type.
Face of a cell.
Definition Item.h:1032
constexpr __host__ __device__ ArrayView< T > view()
Modifiable view of the array.
virtual void schedule(IItemFamilyNetworkTask task, eSchedulingOrder order=TopologicalOrder)=0
Schedules the execution of a task, in topological or inverse topological order.
Interface of an entity family.
Definition IItemFamily.h:85
virtual void removeNeedRemoveMarkedItems()=0
Removes entities and updates connectivities.
virtual String name() const =0
Family name.
virtual eItemKind itemKind() const =0
Entity kind.
Int32 flags() const
Flags of the entity.
Int32 localId() const
Local number (in the subdomain) of the entity.
Flags for entity characteristics.
Definition ItemFlags.h:39
@ II_NeedRemove
The entity must be removed.
Definition ItemFlags.h:63
Internal structure of a mesh entity.
Type of an entity (Item).
Definition ItemTypeId.h:33
static ItemTypeId fromInteger(Int64 v)
Creates an instance from an integer.
Local information about a cell edge.
Integer endNode() const
Local index in the cell of the ending node of the edge.
Integer beginNode() const
Local index in the cell of the starting node of the edge.
Local information about a cell face.
Integer node(Integer i) const
Local index in the cell of the i-th node of the face.
Integer nbEdge() const
Number of edges of the face.
Integer typeId() const
Type of the face entity.
Integer edge(Integer i) const
Edge of the face.
Integer nbNode() const
Number of nodes of the face.
Info on a mesh entity type.
LocalEdge localEdge(Integer id) const
Local connectivity of the i-th edge of the cell.
LocalFace localFace(Integer id) const
Local connectivity of the i-th face of the cell.
const ItemTypeInfo * linearTypeInfo() const
Type of the corresponding linear element.
Integer nbLocalEdge() const
Number of edges of the entity.
Integer nbLocalNode() const
Number of nodes of the entity.
Integer nbLocalFace() const
Number of faces of the entity.
Mesh entity type manager.
Definition ItemTypeMng.h:64
ItemTypeInfo * typeFromId(Integer id) const
Type corresponding to the number id.
View on a vector of entities.
Int32 size() const
Number of elements in the vector.
Base class for a mesh element.
Definition Item.h:84
impl::MutableItemBase mutableItemBase() const
Mutable internal part of the entity.
Definition Item.h:394
constexpr Int32 localId() const
Local identifier of the entity in the processor subdomain.
Definition Item.h:233
void setFlags(Int32 f)
Sets the entity flags.
Utility class to reorder the nodes of an entity.
1D vector of data with reference semantics.
1D data array with pre-allocated stack buffer.
View of an array of elements of type T.
Definition Span.h:803
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
TraceMessage info() const
Flow for an information message.
ITraceMng * traceMng() const
Trace manager.
1D data vector with value semantics (STL style).
Implementation of std::unordered_map.
void removeCells(ConstArrayView< Int32 > cells_local_id)
Removes the cells whose local numbers are cells_local_id.
IncrementalItemConnectivity * nodeConnectivity() const
The true connectivity behind the selector, for a bulk fill.
void _addParentCellToCell(Cell cell, Cell parent_cell)
AMR.
void addNodes2(Int64ConstArrayView nodes_uid, Integer sub_domain_id, Int32ArrayView nodes)
Ajoute des noeuds au maillage actuel. Utilise l'ajout d'item générique basé sur dépendances entre fam...
void _fillBulkConnectivity(IncrementalItemConnectivity *c, Int32 nb_source, ConstArrayView< Int32 > offsets, ConstArrayView< Int32 > targets)
Fills a connectivity whose blocks are given in source-item order.
void computeFacesUniqueIds()
Calculates the unique IDs for each face.
void setConnectivity(Integer c)
Sets the active connectivity for the associated mesh.
void addParentCells(const ItemVectorView &items)
Add to the current mesh items coming from a parent mesh.
void addCells(Integer nb_cell, Int64ConstArrayView cell_infos, Integer sub_domain_id, Int32ArrayView cells, bool allow_build_face=true)
Adds cells to the current mesh.
void _initFaceRelationInfo(ItemData &source_item_relation_data, const ItemData &target_item_dependencies_data, Int64ConstArrayView faces_info)
Initializes face relation info.
void addParentItems(const ItemVectorView &items, const eItemKind submesh_kind)
Add to the current mesh items coming from a parent mesh.
OneMeshItemAdder * m_one_mesh_item_adder
Mesh building utilities.
void _fillFaceInfo(Integer &nb_face, Integer nb_cell, Int64Array &faces_infos, Int64ConstArrayView cells_infos, std::map< Int64, Int64SharedArray > &cell_to_face_connectivity_info)
Adds cells to the current mesh.
Int64 m_face_uid_pool
uniqueId() number used for generating faces
void resetAfterDeallocate()
Resets the structures to allow for a new allocation.
void addGhostChildFromParent(Array< Int64 > &ghost_cell_to_refine)
AMR.
void _fillBulkReverseConnectivity(IncrementalItemConnectivity *c, Int32 nb_target, Int32 nb_source, ConstArrayView< Int32 > offsets, ConstArrayView< Int32 > targets)
Fills the reverse of a connectivity given in source-item order.
bool addCellsBulk(Integer nb_cell, Int64ConstArrayView cell_infos, Integer sub_domain_id, Int32ArrayView cells, bool allow_build_face)
Same as addCells(), filling the family arrays in bulk.
void addEdges2(Integer nb_edge, Int64ConstArrayView edge_infos, Integer sub_domain_id, Int32ArrayView edges)
Adds edges to the current mesh. Uses generic item addition based on family dependencies.
Int64 m_edge_uid_pool
uniqueId() number used for generating edges
void addItems(ItemDataList &item_info_list)
Ajout générique d'items d'un ensemble de famille pour lesquelles on fournit un ItemData.
void addNodes(Int64ConstArrayView nodes_uid, Integer sub_domain_id, Int32ArrayView nodes)
Ajoute des noeuds au maillage actuel.
void addFaces(Integer nb_face, Int64ConstArrayView face_infos, Integer sub_domain_id, Int32ArrayView faces)
Ajoute des faces au maillage actuel.
void addEdges(Integer nb_edge, Int64ConstArrayView edge_infos, Integer sub_domain_id, Int32ArrayView edges)
Adds edges to the current mesh.
GhostLayerBuilder * m_ghost_layer_builder
Utility to build ghost elements.
void addHChildrenCells(Cell hParent_cell, Integer nb_cell, Int64ConstArrayView cells_infos, Int32 sub_domain_id, Int32ArrayView cells, bool allow_build_face)
Ajoute des mailles au maillage actuel.
void _allocateBulkByType(FamilyType *family, Int64ConstArrayView uids, ConstArrayView< Int16 > type_ids, Int32 owner, Int32ArrayView lids)
Allocates items in batches of one type, since a batch carries one shared info.
bool m_has_edge
Info on the presence of an edge (accelerates access to general connectivity).
void addFamilyItems(ItemData &item_info)
Ajout générique d'items d'une famille, décrite par son ItemInfo.
DynamicMeshIncrementalBuilder(DynamicMesh *mesh)
Constructs an instance for the mesh mesh.
bool m_use_bulk_add_cells
ARCANE_BULK_ADD_CELLS=1: addCells() fills the families in bulk.
void addCells3(Integer nb_cell, Int64ConstArrayView cell_infos, Integer sub_domain_id, Int32ArrayView cells, bool allow_build_face=true)
Adds cells to the current mesh. Uses generic item addition based on family dependencies.
void addFaces2(Integer nb_face, Int64ConstArrayView face_infos, Integer sub_domain_id, Int32ArrayView faces)
Ajoute des faces au maillage actuel. Utilise l'ajout d'item générique basé sur dépendances entre fami...
Integer m_connectivity
Connectivity info of the current mesh.
Implementation of a mesh.
Definition DynamicMesh.h:98
IItemFamily * nodeFamily() override
Returns the node family.
IItemFamily * cellFamily() override
Returns the cell family.
IItemFamily * faceFamily() override
Returns the face family.
IItemFamilyNetwork * itemFamilyNetwork() override
Family network interface (connected families).
IItemFamily * edgeFamily() override
Returns the edge family.
void allocateItemsBulk(Int64ConstArrayView uids, Int32 owner, Int32ArrayView lids)
Allocates every edge of uids at once, in one pass per family array.
IncrementalItemConnectivity * nodeConnectivity() const
The true connectivity behind the selector, for a bulk fill.
Construction of ghost layers.
IncrementalItemConnectivity * nodeConnectivity() const
The true connectivity behind the selector, for a bulk fill.
void setBulkBackAndFrontCells(Int32ConstArrayView back_cells, Int32ConstArrayView front_cells)
Sets the cells of every face at once.
Construction of ghost layers.
Construction of ghost layers.
void resizeBulkConnectivity(Int32 nb_source, Int64 list_size, Int32ArrayView &nb_items, Int32ArrayView &indexes, Int32ArrayView &list)
Sizes the storage for a bulk fill and hands out the arrays to write.
void endBulkConnectivity()
Closes a fill started by resizeBulkConnectivity().
Integer preAllocatedSize() const final
Number of entities pre-allocated for the connectivity of each entity.
bool canAllocateBulk() const
Whether _allocateInfosBulk() can be used: nothing allocated, nothing freed.
String name() const override
Family name.
Definition ItemFamily.h:140
Associative array of ItemInternal.
void eachItem(const Lambda &lambda)
Template function to iterate over the instance's entities.
void allocateItemsBulk(Int64ConstArrayView uids, Int32 owner, Int32ArrayView lids)
Allocates every node of uids at once, in one pass per family array.
IncrementalItemConnectivity * edgeConnectivity() const
The true connectivity behind the selector, for a bulk fill.
bool getEnableGhostItems() const override
Retrieves the flag to manage ghost particles for the family.
Array< Int64 > Int64Array
Dynamic one-dimensional array of 64-bit integers.
Definition UtilsTypes.h:119
ArrayView< Int64 > Int64ArrayView
C equivalent of a 1D array of 64-bit integers.
Definition UtilsTypes.h:445
UniqueArray< Int64 > Int64UniqueArray
Dynamic 1D array of 64-bit integers.
Definition UtilsTypes.h:333
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
ConstArrayView< Int64 > Int64ConstArrayView
C equivalent of a 1D array of 64-bit integers.
Definition UtilsTypes.h:474
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
Definition UtilsTypes.h:335
ArrayView< Int32 > Int32ArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:447
eItemKind
Mesh entity type.
@ IK_Particle
Particle mesh entity.
@ IK_Cell
Cell mesh entity.
@ IK_Face
Face mesh entity.
@ IK_DoF
Degree of Freedom mesh entity.
@ IK_Edge
Edge mesh entity.
std::int16_t Int16
Signed integer type of 16 bits.
std::int32_t Int32
Signed integer type of 32 bits.