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/GraphDoFs.h"
38#include "arcane/mesh/ParticleFamily.h"
39
40#include <set>
41#include <map>
42#include <algorithm>
43
44/*---------------------------------------------------------------------------*/
45/*---------------------------------------------------------------------------*/
46
47namespace Arcane::mesh
48{
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
52
53// #define ARCANE_DEBUG_DYNAMIC_MESH
54// #define ARCANE_DEBUG_DYNAMIC_MESH2
55
56/*---------------------------------------------------------------------------*/
57/*---------------------------------------------------------------------------*/
58
61: TraceAccessor(mesh->traceMng())
62, m_mesh(mesh)
63, m_item_type_mng(mesh->itemTypeMng())
64, m_has_amr(mesh->isAmrActivated())
66{
67 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_VERBOSE_MESH_BUILDER", true))
68 m_verbose = (v.value() != 0);
69}
70
71/*---------------------------------------------------------------------------*/
72/*---------------------------------------------------------------------------*/
73
74DynamicMeshIncrementalBuilder::
75~DynamicMeshIncrementalBuilder()
76{
78 delete m_face_unique_id_builder;
79 delete m_edge_unique_id_builder;
81}
82
83/*---------------------------------------------------------------------------*/
84/*---------------------------------------------------------------------------*/
85
86void DynamicMeshIncrementalBuilder::
87_printCellFaceInfos(ItemInternal* icell, const String& str)
88{
89 Cell cell(icell);
90 Integer nb_num_back_face = 0;
91 Integer nb_num_front_face = 0;
92 Integer index = 0;
93 for (Face face : cell.faces()) {
94 String add_msg;
95 if (face.backCell() == cell) {
96 ++nb_num_back_face;
97 add_msg = "is a back face";
98 }
99 else {
100 ++nb_num_front_face;
101 add_msg = "is a front face";
102 }
103 info() << str << ": celluid=" << cell.uniqueId()
104 << " faceuid=" << face.uniqueId()
105 << " faceindex=" << index
106 << add_msg;
107 ++index;
108 }
109 info() << str << ": celluid=" << cell.uniqueId()
110 << " nbback=" << nb_num_back_face
111 << " nbfront=" << nb_num_front_face;
112}
113
114/*---------------------------------------------------------------------------*/
115/*---------------------------------------------------------------------------*/
125addCells(Integer nb_cell, Int64ConstArrayView cells_infos,
126 Int32 owner, Int32ArrayView cells,
127 bool allow_build_face)
128{
129 ItemTypeMng* itm = m_item_type_mng;
130
131 Integer cells_infos_index = 0;
132 bool add_to_cells = cells.size() != 0;
133 if (add_to_cells && nb_cell != cells.size())
134 ARCANE_THROW(ArgumentException, "return array 'cells' has to have same size as number of cells");
135 auto* adder = m_one_mesh_item_adder;
136 for (Integer i_cell = 0; i_cell < nb_cell; ++i_cell) {
137 ItemTypeId item_type_id(CheckedConvert::toInt16(cells_infos[cells_infos_index]));
138 ++cells_infos_index;
139 Int64 cell_unique_id = cells_infos[cells_infos_index];
140 ++cells_infos_index;
141
142 Int32 current_cell_nb_node = 0;
143 if (item_type_id == ITI_GenericPolyhedron) {
144 // For poly types, the number of nodes is the first value in the connectivity
145 current_cell_nb_node = static_cast<Int32>(cells_infos[cells_infos_index]);
146 }
147 else {
148 ItemTypeInfo* it = itm->typeFromId(item_type_id);
149 current_cell_nb_node = it->nbLocalNode();
150 }
151 ConstArrayView<Int64> current_cell_nodes_uid(current_cell_nb_node, &cells_infos[cells_infos_index]);
152
153 ItemInternal* cell = adder->addOneCell(item_type_id, cell_unique_id, owner,
154 current_cell_nodes_uid, allow_build_face);
155
156 if (add_to_cells)
157 cells[i_cell] = cell->localId();
158 cells_infos_index += current_cell_nb_node;
159 }
160}
161
162/*---------------------------------------------------------------------------*/
163/*---------------------------------------------------------------------------*/
172
173/*---------------------------------------------------------------------------*/
174
176addCells3(Integer nb_cell, Int64ConstArrayView cells_infos,
177 Integer sub_domain_id, Int32ArrayView cells,
178 bool allow_build_face)
179{
180 bool add_to_cells = cells.size() != 0;
181 if (add_to_cells && nb_cell != cells.size())
182 throw ArgumentException(A_FUNCINFO,
183 "return array 'cells' has to have same size as number of cells");
184 ItemDataList item_data_list; // store item ids and dependency connectivities
185 ItemDataList item_relation_data_list; // store relation connectivities
186 ItemData& cell_data = item_data_list.itemData(Integer(m_mesh->cellFamily()->itemKind()),
187 nb_cell, 0, cells, &mesh()->trueCellFamily(), &mesh()->trueCellFamily(), sub_domain_id);
188 // item info_size cannot be guessed
189 Int64UniqueArray faces_infos, edges_infos, nodes_infos, node_uids;
190 Int32UniqueArray face_lids, edge_lids, node_lids;
191 Integer nb_face = 0, nb_edge = 0, nb_node = 0;
192 std::map<Int64, Int64SharedArray> cell_to_face_connectivity_info;
193 std::map<std::pair<Int64, Int64>, Int64> edge_uid_map;
194
195 // Fill classical info
196 _fillFaceInfo(nb_face, nb_cell, faces_infos, cells_infos, cell_to_face_connectivity_info);
197 _fillEdgeInfo(nb_edge, nb_face, edges_infos, faces_infos, edge_uid_map);
198 _fillNodeInfo(nb_node, nb_face, nodes_infos, faces_infos);
199
200 // Fill Cell info 2
201 _fillCellNewInfoNew(nb_cell, cells_infos, cell_data.itemInfos(), cell_to_face_connectivity_info, edge_uid_map);
202 // Fill Face info 2
203 if (allow_build_face) {
204 ItemData& face_data = item_data_list.itemData(Integer(m_mesh->faceFamily()->itemKind()), nb_face, 0, face_lids, &mesh()->trueFaceFamily(), &mesh()->trueFaceFamily(), sub_domain_id);
205 face_lids.resize(item_data_list[m_mesh->faceFamily()->itemKind()].nbItems());
206 _fillFaceNewInfoNew(nb_face, faces_infos, face_data.itemInfos(), edge_uid_map); // todo voir appel depuis add Faces
207 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);
208 _initFaceRelationInfo(face_relation_data, cell_data, faces_infos); // face-cell relations
209 }
210 // Fill Edge info 2
211 if (hasEdge()) {
212 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
213 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);
214 edge_lids.resize(item_data_list[m_mesh->edgeFamily()->itemKind()].nbItems());
215 _fillEdgeNewInfoNew(nb_edge, edges_infos, edge_data.itemInfos()); // reprendre fillEdgeInfo et voir l'appel depuis add Edges + attention ordre des noeuds,
216 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);
217 _initEdgeRelationInfo(edge_relation_data, cell_data, edges_infos); // edge-cell relations
218 if (allow_build_face) {
219 _appendEdgeRelationInfo(edge_relation_data, item_data_list[IK_Face], edges_infos); // edge-face relations
220 _appendFaceRelationInfo(item_relation_data_list[IK_Face], edge_data, faces_infos); // face-edge relations
221 }
222 }
223 // Fill Node info 2
224 Integer node_info_size = 1 + nb_node * 2; //New info = Nb_connected_family + for each node : type, uid (no connected family)
225 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);
226 node_lids.resize(item_data_list[m_mesh->nodeFamily()->itemKind()].nbItems());
227 _fillNodeNewInfo(nodes_infos, node_data.itemInfos());
228 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);
229 _initNodeRelationInfo(node_relation_data, cell_data, nodes_infos); // node-cell relations
230 if (allow_build_face)
231 _appendNodeRelationInfo(node_relation_data, item_data_list[IK_Face], nodes_infos); // node-face relations
232 if (hasEdge())
233 _appendNodeRelationInfo(node_relation_data, item_data_list[IK_Edge], nodes_infos); // node-edge relations
234
235 // Launch node, face and edges (not mandatory) and cell creation
236 addItems(item_data_list, item_relation_data_list);
237}
238
239/*---------------------------------------------------------------------------*/
240
241void DynamicMeshIncrementalBuilder::
242addCells2(Integer nb_cell, Int64ConstArrayView cells_infos,
243 Integer sub_domain_id, Int32ArrayView cells,
244 bool allow_build_face)
245{
246 ItemDataList item_data_list;
247 ItemData& cell_data = item_data_list.itemData(Integer(m_mesh->cellFamily()->itemKind()),
248 nb_cell, 0, cells, &mesh()->trueCellFamily(), &mesh()->trueCellFamily(), sub_domain_id);
249 // item info_size cannot be guessed
250 Int64Array& cell_infos2 = cell_data.itemInfos();
251 Int64UniqueArray faces_infos;
252 Int64UniqueArray node_uids;
253 Int32UniqueArray face_lids;
254 Integer nb_face;
255
256 // Fill cell info 2
257 _fillCellInfo2(nb_cell, cells_infos, cell_infos2, nb_face, faces_infos, node_uids, allow_build_face);
258
259 // Fill face info 2
260 if (allow_build_face) {
261 Integer face_infos2_size = faces_infos.size() + 1 + 2 * nb_face; // additive info nb_connected_family + nb_face * (family_id + nb_connected_element)
262 face_lids.resize(nb_face);
263 ItemData& face_data = item_data_list.itemData(Integer(m_mesh->faceFamily()->itemKind()),
264 nb_face, face_infos2_size, face_lids, &mesh()->trueFaceFamily(), &mesh()->trueFaceFamily(), sub_domain_id);
265 Int64ArrayView face_infos2 = face_data.itemInfos().view();
266 _fillFaceInfo2(nb_face, faces_infos, face_infos2, node_uids); // if allow_build_face false, node_uids built in fillCellInfo3
267 }
268
269 // Fill node info 2
270 Integer nb_node_to_add = node_uids.size();
271 Int32UniqueArray node_lids(nb_node_to_add);
272 ItemData& node_data = item_data_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()),
273 nb_node_to_add, 2 * nb_node_to_add + 1, node_lids, &mesh()->trueNodeFamily(), &mesh()->trueNodeFamily(), sub_domain_id);
274 Int64Array& node_infos2 = node_data.itemInfos();
275 _fillNodeNewInfo(node_uids, node_infos2);
276
277 // Launch node and face and cell creation
278 addItems(item_data_list);
279}
280
281/*---------------------------------------------------------------------------*/
282/*---------------------------------------------------------------------------*/
292_fillFaceInfo(Integer& nb_face, Integer nb_cell, Int64Array& faces_infos, Int64ConstArrayView cells_infos, std::map<Int64, Int64SharedArray>& cell_to_face_connectivity_info)
293{
294 faces_infos.reserve(2 * cells_infos.size());
295 Int64UniqueArray work_face_sorted_nodes;
296 Int64UniqueArray work_face_orig_nodes;
297 ItemTypeMng* itm = m_item_type_mng;
298 Integer cells_infos_index = 0;
299 nb_face = 0;
300 NodeInFaceSet face_nodes_set;
301 for (Integer i_cell = 0; i_cell < nb_cell; ++i_cell) {
302 Integer item_type_id = (Integer)cells_infos[cells_infos_index++];
303 Int64 current_cell_unique_id = cells_infos[cells_infos_index++];
304 ItemTypeInfo* it = itm->typeFromId(item_type_id);
305 Integer current_cell_nb_node = it->nbLocalNode();
306 Int64ConstArrayView current_cell_node_uids(current_cell_nb_node, &cells_infos[cells_infos_index]);
307 Integer current_cell_nb_face = it->nbLocalFace();
308 for (Integer face_in_cell_index = 0; face_in_cell_index < current_cell_nb_face; ++face_in_cell_index) {
309 const ItemTypeInfo::LocalFace& current_face = it->localFace(face_in_cell_index);
310 Integer current_face_nb_node = current_face.nbNode();
311 work_face_orig_nodes.resize(current_face_nb_node);
312 work_face_sorted_nodes.resize(current_face_nb_node);
313 Integer i = 0;
314 for (Integer node_in_face_index = 0; node_in_face_index < current_face_nb_node; ++node_in_face_index) {
315 work_face_orig_nodes[i++] = current_cell_node_uids[current_face.node(node_in_face_index)];
316 }
317 mesh_utils::reorderNodesOfFace(work_face_orig_nodes, work_face_sorted_nodes);
318 // get face uid: we shouldn't have to guess, it should be given in arguments...
319 Int64 current_face_uid = _findFaceUniqueId(work_face_sorted_nodes, face_nodes_set);
320 if (current_face_uid == NULL_ITEM_ID) // face not already known add to face info
321 {
322 current_face_uid = m_face_uid_pool++;
323 faces_infos.add(current_face.typeId()); // face info type
324 faces_infos.add(current_face_uid); // face info uid
325 faces_infos.addRange(work_face_sorted_nodes); // face info node uids
326 _addFaceNodes(face_nodes_set, work_face_sorted_nodes, current_face_uid);
327 ++nb_face;
328 }
329 cell_to_face_connectivity_info[current_cell_unique_id].add(current_face_uid);
330 }
331 cells_infos_index += current_cell_nb_node;
332 }
333}
334
335/*---------------------------------------------------------------------------*/
336
337void DynamicMeshIncrementalBuilder::
338_fillEdgeInfo(Integer& nb_edge, Integer nb_face, Int64Array& edges_infos,
339 Int64ConstArrayView faces_infos, std::map<std::pair<Int64, Int64>, Int64>& edge_uid_map)
340{
341 edges_infos.reserve(2 * faces_infos.size());
342 ItemTypeMng* itm = m_item_type_mng;
343 Integer faces_infos_index = 0;
344 nb_edge = 0;
345 for (Integer i_face = 0; i_face < nb_face; ++i_face) {
346 Integer item_type_id = (Integer)faces_infos[faces_infos_index++]; // face type
347 ++faces_infos_index; // face uid (unused)
348 ItemTypeInfo* it = itm->typeFromId(item_type_id);
349 Integer current_face_nb_node = it->nbLocalNode();
350 Int64ConstArrayView current_face_node_uids(current_face_nb_node, &faces_infos[faces_infos_index]);
351 Integer current_face_nb_edge = it->nbLocalEdge();
352 for (Integer edge_in_face_index = 0; edge_in_face_index < current_face_nb_edge; ++edge_in_face_index) {
353 const ItemTypeInfo::LocalEdge& current_edge = it->localEdge(edge_in_face_index);
354 Int64 first_node = current_face_node_uids[current_edge.beginNode()];
355 Int64 second_node = current_face_node_uids[current_edge.endNode()];
356 if (first_node > second_node)
357 std::swap(first_node, second_node);
358 auto edge_it = edge_uid_map.insert(std::make_pair(std::make_pair(first_node, second_node), m_edge_uid_pool));
359 if (edge_it.second) {
360 edges_infos.add(m_edge_uid_pool); // edge uid
361 edges_infos.add(first_node); // first node uid
362 edges_infos.add(second_node); // second node uid
363 ++nb_edge;
365 }
366 }
367 faces_infos_index += current_face_nb_node;
368 }
369}
370
371/*---------------------------------------------------------------------------*/
372
373void DynamicMeshIncrementalBuilder::
374_fillNodeInfo(Integer& nb_node, Integer nb_face, Int64Array& nodes_infos, Int64ConstArrayView faces_infos)
375{
376 nodes_infos.reserve(faces_infos.size());
377 Integer faces_infos_index = 0;
378 std::set<Int64> nodes_set;
379 ItemTypeMng* itm = m_item_type_mng;
380 for (Integer i_face = 0; i_face < nb_face; ++i_face) {
381 Int32 type_id = CheckedConvert::toInt32(faces_infos[faces_infos_index++]);
382 Integer current_face_nb_node = itm->typeFromId(type_id)->nbLocalNode(); // face type
383 ++faces_infos_index; //face_uid (unused)
384 for (auto node_uid : faces_infos.subConstView(faces_infos_index, current_face_nb_node)) {
385 nodes_set.insert(node_uid);
386 }
387 faces_infos_index += current_face_nb_node;
388 }
389 nb_node = CheckedConvert::toInteger(nodes_set.size());
390 for (auto node_uid : nodes_set) {
391 nodes_infos.add(node_uid);
392 }
393}
394
395/*---------------------------------------------------------------------------*/
396
397void DynamicMeshIncrementalBuilder::
398_fillNodeInfoFromEdge(Integer& nb_node, Integer nb_edge, Int64Array& nodes_infos, Int64ConstArrayView edges_infos)
399{
400 nodes_infos.reserve(2 * edges_infos.size());
401 Integer edges_infos_index = 0;
402 std::set<Int64> nodes_set;
403 for (Integer i_edge = 0; i_edge < nb_edge; ++i_edge) {
404 ++edges_infos_index; //edge_uid (unused)
405 nodes_set.insert(edges_infos[edges_infos_index++]);
406 nodes_set.insert(edges_infos[edges_infos_index++]);
407 }
408 nb_node = CheckedConvert::toInteger(nodes_set.size());
409 for (auto node_uid : nodes_set) {
410 nodes_infos.add(node_uid);
411 }
412}
413/*---------------------------------------------------------------------------*/
414
415void DynamicMeshIncrementalBuilder::
416_fillCellNewInfoNew(Integer nb_cell, Int64ConstArrayView cells_infos, Int64Array& cell_infos2,
417 const std::map<Int64, Int64SharedArray>& cell_to_face_connectivity_info, const std::map<std::pair<Int64, Int64>, Int64>& edge_uid_map)
418{
419 Integer cell_infos2_size_approx = 1 + 3 * (cells_infos.size() + 2 * nb_cell); // supposes as many faces as nodes as edges...
420 cell_infos2.reserve(cell_infos2_size_approx);
421 ItemTypeMng* itm = m_item_type_mng;
422 Integer cells_infos_index = 0;
423 Integer nb_connected_families = hasEdge() ? 3 : 2;
424 cell_infos2.add(nb_connected_families); // nb_connected_families (node and face +/- edge)
425 for (Integer i_cell = 0; i_cell < nb_cell; ++i_cell) {
426 Integer item_type_id = (Integer)cells_infos[cells_infos_index];
427 cell_infos2.add(cells_infos[cells_infos_index++]); // cell type
428 Int64 current_cell_uid = cells_infos[cells_infos_index];
429 cell_infos2.add(cells_infos[cells_infos_index++]); // cell uid
430 ItemTypeInfo* it = itm->typeFromId(item_type_id);
431 //--- Cell node connectivity
432 cell_infos2.add(mesh()->nodeFamily()->itemKind()); // connected_family_id: node family
433 Integer current_cell_nb_node = it->nbLocalNode();
434 cell_infos2.add(current_cell_nb_node); // nb_connected_nodes
435 Int64ConstArrayView current_cell_node_uids(current_cell_nb_node, &cells_infos[cells_infos_index]);
436 cell_infos2.addRange(current_cell_node_uids); // node ids
437 //--- Cell face connectivity
438 cell_infos2.add(mesh()->faceFamily()->itemKind()); // connected_family_id: face family
439 Integer current_cell_nb_face = it->nbLocalFace();
440 cell_infos2.add(current_cell_nb_face); // nb_connected_faces
441 Int64ArrayView current_cell_faces = cell_to_face_connectivity_info.find(current_cell_uid)->second.view();
442 if (current_cell_nb_face != current_cell_faces.size())
443 ARCANE_FATAL("Incoherent number of faces for cell {0}. Expected {1} found {2}",
444 current_cell_uid, current_cell_nb_face, current_cell_faces.size());
445 cell_infos2.addRange(current_cell_faces); // face ids
446 //-- Cell edge connectivity
447 if (hasEdge()) {
448 cell_infos2.add(mesh()->edgeFamily()->itemKind()); // connected_family_id: edge family
449 Integer current_cell_nb_edge = it->nbLocalEdge();
450 cell_infos2.add(current_cell_nb_edge); // nb_connected_edges
451 for (int edge_index = 0; edge_index < current_cell_nb_edge; ++edge_index) {
452 Int64 first_node = current_cell_node_uids[it->localEdge(edge_index).beginNode()];
453 Int64 second_node = current_cell_node_uids[it->localEdge(edge_index).endNode()];
454 if (first_node > second_node)
455 std::swap(first_node, second_node); // edge may be oriented negatively in the cell
456 auto edge_it = edge_uid_map.find(std::make_pair(first_node, second_node));
457 if (edge_it == edge_uid_map.end())
458 ARCANE_FATAL("Do not find edge with nodes {0}-{1} in edge uid map. Exiting",
459 current_cell_node_uids[it->localEdge(edge_index).beginNode()],
460 current_cell_node_uids[it->localEdge(edge_index).endNode()]);
461 cell_infos2.add(edge_it->second);
462 }
463 }
464 cells_infos_index += current_cell_nb_node;
465 }
466}
467
468/*---------------------------------------------------------------------------*/
469/*---------------------------------------------------------------------------*/
470
471void DynamicMeshIncrementalBuilder::
472_fillCellInfo2(Integer nb_cell, Int64ConstArrayView cells_infos, Int64Array& cell_infos2,
473 Integer& nb_face, Int64Array& faces_infos, Int64Array& node_uids, bool allow_build_face)
474{
475 Integer cell_infos2_size_approx = 1 + 2 * (cells_infos.size() + 2 * nb_cell); // supposes as many faces as nodes...
476 cell_infos2.reserve(cell_infos2_size_approx);
477 // Fill infos
478 ItemTypeMng* itm = m_item_type_mng;
479 Integer cells_infos_index = 0;
480 cell_infos2.add(2); // nb_connected_families (node and face)
481
482 nb_face = 0;
483 faces_infos.reserve(2 * cells_infos.size());
484 Int64UniqueArray work_face_sorted_nodes;
485 Int64UniqueArray work_face_orig_nodes;
486 NodeInFaceSet face_nodes_set;
487 std::set<Int64> node_uid_set;
488 // Fill face_infos2 from faces_infos
489 for (Integer i_cell = 0; i_cell < nb_cell; ++i_cell) {
490
491 Integer item_type_id = (Integer)cells_infos[cells_infos_index];
492 cell_infos2.add(cells_infos[cells_infos_index++]); // cell type
493 cell_infos2.add(cells_infos[cells_infos_index++]); // cell uid
494 cell_infos2.add(mesh()->nodeFamily()->itemKind()); // connected_family_id: node family
495
496 ItemTypeInfo* it = itm->typeFromId(item_type_id);
497 // Cell node connectivity
498 Integer current_cell_nb_node = it->nbLocalNode();
499 cell_infos2.add(current_cell_nb_node); // nb_connected_nodes
500 Int64ConstArrayView current_cell_node_uids(current_cell_nb_node, &cells_infos[cells_infos_index]);
501 cell_infos2.addRange(current_cell_node_uids); // node ids
502 if (!allow_build_face)
503 node_uid_set.insert(current_cell_node_uids.begin(), current_cell_node_uids.end()); // otherwise node ids will be computed in face info build
504 // cell face connectivity
505 cell_infos2.add(mesh()->faceFamily()->itemKind()); // connected_family_id: face family
506 Integer current_cell_nb_face = it->nbLocalFace();
507 cell_infos2.add(current_cell_nb_face); // nb_connected_faces
508 for (Integer face_in_cell_index = 0; face_in_cell_index < current_cell_nb_face; ++face_in_cell_index) {
509 ItemTypeInfo::LocalFace current_face = it->localFace(face_in_cell_index);
510 Integer current_face_nb_node = current_face.nbNode();
511 work_face_orig_nodes.resize(current_face_nb_node);
512 work_face_sorted_nodes.resize(current_face_nb_node);
513 Integer i = 0;
514 for (Integer node_in_face_index = 0; node_in_face_index < current_face_nb_node; ++node_in_face_index) {
515 work_face_orig_nodes[i++] = current_cell_node_uids[current_face.node(node_in_face_index)];
516 }
517 mesh_utils::reorderNodesOfFace(work_face_orig_nodes, work_face_sorted_nodes);
518 // get face uid: we shouldn't have to guess, it should be given in arguments...
519 Int64 current_face_uid = _findFaceUniqueId(work_face_sorted_nodes, face_nodes_set);
520 if (current_face_uid == NULL_ITEM_ID) // face not already known add to face info
521 {
522 current_face_uid = m_face_uid_pool++;
523 faces_infos.add(current_face.typeId()); // face info type
524 faces_infos.add(current_face_uid); // face info uid
525 faces_infos.addRange(work_face_sorted_nodes); // face info node uids
526 _addFaceNodes(face_nodes_set, work_face_sorted_nodes, current_face_uid);
527 ++nb_face;
528 }
529 cell_infos2.add(current_face_uid); // face ids
530 }
531 cells_infos_index += current_cell_nb_node;
532 }
533 if (!allow_build_face) {
534 node_uids.resize(node_uid_set.size());
535 Integer index = 0;
536 for (Int64 node_uid : node_uid_set)
537 node_uids[index++] = node_uid;
538 }
539}
540
541/*---------------------------------------------------------------------------*/
542/*---------------------------------------------------------------------------*/
552_initFaceRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView faces_info)
553{
554 _fillFaceRelationInfo(source_item_relation_data, target_item_dependencies_data, faces_info, true);
555}
556
557/*---------------------------------------------------------------------------*/
558
559void DynamicMeshIncrementalBuilder::
560_appendFaceRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView faces_info)
561{
562 _fillFaceRelationInfo(source_item_relation_data, target_item_dependencies_data, faces_info, false);
563}
564
565/*---------------------------------------------------------------------------*/
566
567void DynamicMeshIncrementalBuilder::
568_fillFaceRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data,
569 Int64ConstArrayView faces_info, bool is_source_relation_data_empty)
570{
571 // face_infos = [{face_type, face_uid, {face_node_uids}]
572 Int64UniqueArray face_uids_and_types;
573 face_uids_and_types.reserve(2 * source_item_relation_data.nbItems());
574 ItemTypeMng* itm = m_item_type_mng;
575 for (Integer face_info_index = 0; face_info_index < faces_info.size();) {
576 face_uids_and_types.add(faces_info[face_info_index + 1]); // face_uid
577 face_uids_and_types.add(faces_info[face_info_index]); // face_type
578 Integer type_id = CheckedConvert::toInteger(face_uids_and_types.back());
579 face_info_index += (2 + itm->typeFromId(type_id)->nbLocalNode()); // increment and skip info (first & second_node_uid)
580 }
581 _fillItemRelationInfo(source_item_relation_data, target_item_dependencies_data, face_uids_and_types, is_source_relation_data_empty);
582}
583
584/*---------------------------------------------------------------------------*/
585
586void DynamicMeshIncrementalBuilder::
587_initEdgeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView edges_info)
588{
589 _fillEdgeRelationInfo(source_item_relation_data, target_item_dependencies_data, edges_info, true);
590}
591
592/*---------------------------------------------------------------------------*/
593
594void DynamicMeshIncrementalBuilder::
595_appendEdgeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView edges_info)
596{
597 _fillEdgeRelationInfo(source_item_relation_data, target_item_dependencies_data, edges_info, false);
598}
599
600/*---------------------------------------------------------------------------*/
601
602void DynamicMeshIncrementalBuilder::
603_fillEdgeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data,
604 Int64ConstArrayView edges_info, bool is_source_relation_data_empty)
605{
606 // edge_infos = [{edge_uid, first_node_uid, second_node_uid}
607 ARCANE_ASSERT((source_item_relation_data.nbItems() * 3 == edges_info.size()), ("source_item_relation_data and edges_info size incoherent. Exiting."));
608 Int64UniqueArray edge_uids_and_types;
609 edge_uids_and_types.reserve(2 * source_item_relation_data.nbItems());
610 for (Integer edge_info_index = 0; edge_info_index < edges_info.size();) {
611 edge_uids_and_types.add(edges_info[edge_info_index++]); // edge_uid
612 edge_uids_and_types.add(IT_Line2); // edge_type
613 edge_info_index += 2; // skip info (first & second_node_uid)
614 }
615 _fillItemRelationInfo(source_item_relation_data, target_item_dependencies_data, edge_uids_and_types, is_source_relation_data_empty);
616}
617
618/*---------------------------------------------------------------------------*/
619
620void DynamicMeshIncrementalBuilder::
621_initNodeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView nodes_info)
622{
623 _fillNodeRelationInfo(source_item_relation_data, target_item_dependencies_data, nodes_info, true);
624}
625
626/*---------------------------------------------------------------------------*/
627
628void DynamicMeshIncrementalBuilder::
629_appendNodeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView nodes_info)
630{
631 _fillNodeRelationInfo(source_item_relation_data, target_item_dependencies_data, nodes_info, false);
632}
633
634/*---------------------------------------------------------------------------*/
635
636void DynamicMeshIncrementalBuilder::
637_fillNodeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView nodes_info, bool is_source_relation_data_empty)
638{
639 // nodes_info = [node_uids]
640 ARCANE_ASSERT((source_item_relation_data.nbItems() == nodes_info.size()), ("source_item_relation_data and nodes_info size incoherent. Exiting."));
641 Int64UniqueArray node_uids_and_types(2 * nodes_info.size());
642 for (Integer node_index = 0; node_index < nodes_info.size(); ++node_index) {
643 node_uids_and_types[2 * node_index] = nodes_info[node_index];
644 node_uids_and_types[2 * node_index + 1] = IT_Vertex;
645 }
646 _fillItemRelationInfo(source_item_relation_data, target_item_dependencies_data, node_uids_and_types, is_source_relation_data_empty);
647}
648
649/*---------------------------------------------------------------------------*/
650
651void DynamicMeshIncrementalBuilder::
652_fillItemRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data,
653 Int64ConstArrayView source_item_uids_and_types,
654 bool is_source_item_relation_data_empty)
655{
656 ARCANE_ASSERT((source_item_relation_data.nbItems() * 2 == source_item_uids_and_types.size()),
657 ("source item number incoherent between source_item_relation_data and source_item_uids_and_types. Exiting."));
658 // Fill an ItemData containing source to target relations (target to source relations are included in target_item_data)
659 auto& source_relation_info = source_item_relation_data.itemInfos();
660 const auto& target_dependencies_info = target_item_dependencies_data.itemInfos();
661 auto source_family = source_item_relation_data.itemFamily();
662 auto target_family = target_item_dependencies_data.itemFamily();
663 if (!source_family || !target_family)
664 return;
665 std::map<Int64, Int64SharedArray> source_to_target_uids;
666 Integer nb_families_connected_to_target = CheckedConvert::toInteger(target_dependencies_info[0]);
667 Integer target_info_index = 1; // 0 is nb_connected_families
668
669 // Fill map source to target traversing target_item_dependencies_data
670 for (; target_info_index < target_dependencies_info.size();) {
671 target_info_index++; // current target item_type
672 Int64 target_item_uid = target_dependencies_info[target_info_index++]; // current target item uid
673 for (Integer family_connected_to_target = 0; family_connected_to_target < nb_families_connected_to_target; ++family_connected_to_target) {
674 Int64 family_connected_to_target_kind = target_dependencies_info[target_info_index++]; // current target item connected family kind
675 if (family_connected_to_target_kind != source_family->itemKind()) { //this connection info does not concern source family. Skip
676 Integer nb_non_read_values = CheckedConvert::toInteger(target_dependencies_info[target_info_index++]); // nb_connected_item on this other family (/= to source family)
677 target_info_index += nb_non_read_values;
678 continue;
679 }
680 else {
681 Int32 nb_source_item_connected_to_target_item = CheckedConvert::toInt32(target_dependencies_info[target_info_index++]);
682 for (Integer source_item_index = 0; source_item_index < nb_source_item_connected_to_target_item; ++source_item_index) {
683 source_to_target_uids[target_dependencies_info[source_item_index + target_info_index]].add(target_item_uid);
684 }
685 target_info_index += nb_source_item_connected_to_target_item;
686 }
687 }
688 }
689 // Fill or append source_item_relation_data traversing the map source_to_target_connectivity
690 if (is_source_item_relation_data_empty)
691 _initEmptyRelationInfo(source_relation_info, source_to_target_uids, source_item_uids_and_types,
692 target_dependencies_info.size(), target_family);
693 else
694 _appendInitializedRelationInfo(source_relation_info, source_to_target_uids, source_item_uids_and_types,
695 target_dependencies_info.size(), target_family);
696}
697
698/*---------------------------------------------------------------------------*/
699
700void DynamicMeshIncrementalBuilder::
701_initEmptyRelationInfo(Int64Array& source_relation_info, std::map<Int64, Int64SharedArray>& source_to_target_uids, Int64ConstArrayView source_item_uids_and_types,
702 Integer approx_relation_size,
703 IItemFamily const* target_family)
704{
705 if (!source_relation_info.empty())
706 source_relation_info.clear();
707 source_relation_info.reserve(approx_relation_size); // clearly too much elements...but only available info. Do better ?
708 source_relation_info.add(1); // nb_connected_families
709 // Fill source_item_relation_data
710 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) {
711 Int64 source_item_uid = source_item_uids_and_types[source_item_uids_and_types_index];
712 source_relation_info.add(source_item_uids_and_types[source_item_uids_and_types_index + 1]); // item type
713 source_relation_info.add(source_item_uid); // item uid
714 source_relation_info.add(target_family->itemKind()); // connected family kind
715 auto& connected_items = source_to_target_uids[source_item_uid];
716 source_relation_info.add(connected_items.size()); // nb_connected_item
717 source_relation_info.addRange(connected_items.view()); // connected_items uids
718 }
719}
720
721/*---------------------------------------------------------------------------*/
722
723void DynamicMeshIncrementalBuilder::
724_appendInitializedRelationInfo(Int64Array& source_relation_info, std::map<Int64, Int64SharedArray>& source_to_target_uids, Int64ConstArrayView source_item_uids_and_types,
725 Integer approx_relation_size,
726 IItemFamily const* target_family)
727{
728 // Create a working array to build the consolidated info. This array will be copied in to source_relation_info at the end.
729 Int64UniqueArray source_relation_info_wrk_copy;
730 source_relation_info_wrk_copy.reserve(source_relation_info.size() + approx_relation_size);
731 std::set<Int64> treated_items; // To detect eventual source_items not already present in source_relation_info
732 Integer source_relation_info_index = 0;
733 Integer nb_connected_family = CheckedConvert::toInteger(source_relation_info[source_relation_info_index++]);
734 source_relation_info_wrk_copy.add(nb_connected_family + 1); // adding a new connected family
735 for (; source_relation_info_index < source_relation_info.size();) {
736 source_relation_info_wrk_copy.add(source_relation_info[source_relation_info_index++]); // item type
737 Int64 source_item_uid = source_relation_info[source_relation_info_index++]; // get item uid
738 source_relation_info_wrk_copy.add(source_item_uid);
739 treated_items.insert(source_item_uid);
740 for (Integer connected_family_index = 0; connected_family_index < nb_connected_family; ++connected_family_index) {
741 source_relation_info_wrk_copy.add(source_relation_info[source_relation_info_index++]); // family kind
742 Integer nb_connected_elements = CheckedConvert::toInteger(source_relation_info[source_relation_info_index++]); // nb connected elements
743 source_relation_info_wrk_copy.add(nb_connected_elements);
744 source_relation_info_wrk_copy.addRange(source_relation_info.subConstView(source_relation_info_index, nb_connected_elements));
745 source_relation_info_index += nb_connected_elements;
746 }
747 // Add new connection info
748 source_relation_info_wrk_copy.add(target_family->itemKind()); // family kind
749 const auto& connected_items = source_to_target_uids[source_item_uid]; // get connected items
750 source_relation_info_wrk_copy.add(connected_items.size()); // nb connected elements
751 source_relation_info_wrk_copy.addRange(connected_items);
752 }
753 // Find eventual source_items not already present in source_relation_info : todo check this can happen
754 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) {
755 Int64 source_item_uid = source_item_uids_and_types[source_item_uids_and_types_index];
756 if (treated_items.find(source_item_uid) == treated_items.end()) {
757 source_relation_info_wrk_copy.add(source_item_uids_and_types[source_item_uids_and_types_index + 1]); // item type
758 source_relation_info_wrk_copy.add(source_item_uid); // item uid
759 source_relation_info_wrk_copy.add(target_family->itemKind()); // family kind
760 const auto& connected_items = source_to_target_uids[source_item_uid]; // get connected items
761 source_relation_info_wrk_copy.add(connected_items.size()); // nb connected elements
762 source_relation_info_wrk_copy.addRange(connected_items);
763 // Padd this item info with family info : we added only one family, add void values for the other nb_connected_family families
764 for (Integer connected_family_index = 0; connected_family_index < nb_connected_family; ++connected_family_index) {
765 source_relation_info_wrk_copy.add(0); // family id (does not matter)
766 source_relation_info_wrk_copy.add(0); // nb_connected_elements for this family
767 }
768 }
769 }
770 // Copy working array into destination array
771 source_relation_info.resize(source_relation_info_wrk_copy.size());
772 std::copy(source_relation_info_wrk_copy.begin(), source_relation_info_wrk_copy.end(), source_relation_info.begin());
773}
774
775/*---------------------------------------------------------------------------*/
776/*---------------------------------------------------------------------------*/
777
778Int64 DynamicMeshIncrementalBuilder::
779_findFaceUniqueId(Int64ConstArrayView work_face_sorted_nodes, NodeInFaceSet& face_nodes_set)
780{
781 // check if first node exist
782 Integer index = 0;
783 // return _findFaceInFaceNodesSet(face_nodes_set,index,work_face_sorted_nodes,std::make_shared<NodeInFace>(NULL_ITEM_ID));
784 return _findFaceInFaceNodesSet(face_nodes_set, index, work_face_sorted_nodes, NodeInFacePtr(NULL_ITEM_ID));
785}
786
787/*---------------------------------------------------------------------------*/
788
789Int64 DynamicMeshIncrementalBuilder::
790_findFaceInFaceNodesSet(const NodeInFaceSet& face_nodes_set, Integer index, Int64ConstArrayView face_nodes, NodeInFacePtr node)
791{
792 if (index < face_nodes.size()) {
793 auto found_node = std::find(face_nodes_set.begin(), face_nodes_set.end(), NodeInFacePtr(face_nodes[index]));
794 if (found_node == face_nodes_set.end())
795 return node->faceUid();
796 else
797 return _findFaceInFaceNodesSet((*found_node)->nextNodeSet(), ++index, face_nodes, *found_node);
798 }
799 else
800 return node->faceUid();
801}
802
803/*---------------------------------------------------------------------------*/
804
805void DynamicMeshIncrementalBuilder::
806_addFaceNodes(NodeInFaceSet& face_nodes_set, Int64ConstArrayView face_nodes, Int64 face_uid)
807{
808 Integer index = 0;
809 // _addFaceInFaceNodesSet(face_nodes_set, index,face_nodes, std::make_shared<NodeInFace>(NULL_ITEM_ID), face_uid);
810 _addFaceInFaceNodesSet(face_nodes_set, index, face_nodes, NodeInFacePtr(NULL_ITEM_ID), face_uid);
811}
812
813/*---------------------------------------------------------------------------*/
814
815void DynamicMeshIncrementalBuilder::
816_addFaceInFaceNodesSet(NodeInFaceSet& face_nodes_set, Integer index, Int64ConstArrayView face_nodes, NodeInFacePtr node, Int64 face_uid)
817{
818 if (index < face_nodes.size()) {
819 // auto next_node = std::make_shared<NodeInFace>(face_nodes[index]);
820 auto next_node = _insertNode(face_nodes_set, face_nodes[index]);
821 // debug() << "Add node " << face_nodes[index] << " in set " << &face_nodes_set;
822 // debug() << "set size " << face_nodes_set.size();
823 _addFaceInFaceNodesSet(next_node->nextNodeSet(), ++index, face_nodes, next_node, face_uid);
824 // else
825 // _addFaceInFaceNodesSet((*insertion_return.first)->nextNodeSet(),++index,face_nodes,*insertion_return.first,face_uid); // pbe du const. Change from set to map ?
826 }
827 else {
828 node->setFaceUid(face_uid);
829 // debug() << "Set face uid " << face_uid << " for node " << node->m_uid;
830 }
831}
832
834DynamicMeshIncrementalBuilder::_insertNode(NodeInFaceSet& face_nodes_set, Int64 inserted_node_uid)
835{
836 NodeInFacePtr new_node(inserted_node_uid);
837 auto found_node = std::find(face_nodes_set.begin(), face_nodes_set.end(), new_node);
838 if (found_node == face_nodes_set.end()) {
839 face_nodes_set.push_back(std::move(new_node));
840 return face_nodes_set.back();
841 }
842 else
843 return *found_node;
844}
845
846/*---------------------------------------------------------------------------*/
847/*---------------------------------------------------------------------------*/
855addParentCells(const ItemVectorView& items)
856{
857 const Integer nb_cell = items.size();
858
859 for (Integer i_cell = 0; i_cell < nb_cell; ++i_cell) {
860 m_one_mesh_item_adder->addOneParentItem(items[i_cell], IK_Cell);
861 }
862}
863
864/*---------------------------------------------------------------------------*/
865/*---------------------------------------------------------------------------*/
866
876addHChildrenCells(Cell hParent_cell, Integer nb_cell, Int64ConstArrayView cells_infos,
877 Integer sub_domain_id, Int32ArrayView cells,
878 bool allow_build_face)
879{
880 ItemTypeMng* itm = m_item_type_mng;
881 CellFamily& cell_family = m_mesh->trueCellFamily();
882
883 debug() << "[DynamicMeshIncrementalBuilder::addHChildrenCells] ADD CELLS mesh=" << m_mesh->name() << " nb_cell=" << nb_cell;
884 Integer cells_infos_index = 0;
885 bool add_to_cells = cells.size() != 0;
886 if (add_to_cells && nb_cell != cells.size())
887 throw ArgumentException(A_FUNCINFO,
888 "return array 'cells' has to have same size as number of cells");
889 for (Integer i_cell = 0; i_cell < nb_cell; ++i_cell) {
890 debug(Trace::Highest) << "\t\t[DynamicMeshIncrementalBuilder::addHChildrenCells]cell " << i_cell << "/" << nb_cell;
891
892 ItemTypeId item_type_id{ (Int16)cells_infos[cells_infos_index] };
893 debug(Trace::Highest) << "\t\t[DynamicMeshIncrementalBuilder::addHChildrenCells]cells_infos[" << cells_infos_index << "]=" << cells_infos[cells_infos_index] << ", type_id=" << item_type_id;
894 ++cells_infos_index;
895
896 Int64 cell_unique_id = cells_infos[cells_infos_index];
897 debug(Trace::Highest) << "\t\t[DynamicMeshIncrementalBuilder::addHChildrenCells]cells_infos[" << cells_infos_index << "]=" << cells_infos[cells_infos_index] << ", uid=" << cell_unique_id;
898 ++cells_infos_index;
899
900 ItemTypeInfo* it = itm->typeFromId(item_type_id);
901 Integer current_cell_nb_node = it->nbLocalNode();
902 debug(Trace::Highest) << "\t\t[DynamicMeshIncrementalBuilder::addHChildrenCells]DM ADD_CELL uid=" << cell_unique_id << " type_id=" << item_type_id
903 << " nb_node=" << current_cell_nb_node;
904 Int64ConstArrayView current_cell_nodes_uid(current_cell_nb_node, &cells_infos[cells_infos_index]);
905 for (Integer i = 0; i < current_cell_nb_node; ++i)
906 debug(Trace::Highest) << "\t\t\t[DynamicMeshIncrementalBuilder::addHChildrenCells]DM NODE uid=" << current_cell_nodes_uid[i];
907
908 ItemInternal* cell = m_one_mesh_item_adder->addOneCell(item_type_id,
909 cell_unique_id,
910 sub_domain_id,
911 current_cell_nodes_uid,
912 allow_build_face);
913
914 cell_family._addParentCellToCell(cell, hParent_cell);
915 if (add_to_cells)
916 cells[i_cell] = cell->localId();
917 cells_infos_index += current_cell_nb_node;
918 }
919 cell_family._addChildrenCellsToCell(hParent_cell, cells);
920
921 debug() << "[DynamicMeshIncrementalBuilder::addHChildrenCells] done";
922}
923
924/*---------------------------------------------------------------------------*/
925/*---------------------------------------------------------------------------*/
933addParentItems(const ItemVectorView& items, const eItemKind submesh_kind)
934{
935 const Integer nb_item = items.size();
936
937 for (Integer i_item = 0; i_item < nb_item; ++i_item) {
938 m_one_mesh_item_adder->addOneParentItem(items[i_item], submesh_kind, false);
939 }
940}
941
942/*---------------------------------------------------------------------------*/
943/*---------------------------------------------------------------------------*/
952addNodes(Int64ConstArrayView nodes_uid, Integer owner, Int32ArrayView nodes)
953{
954 Integer nb_node_to_add = nodes_uid.size();
955 bool add_to_nodes = nodes.size() != 0;
956 if (add_to_nodes && nb_node_to_add != nodes.size())
957 throw ArgumentException(A_FUNCINFO,
958 "return array 'nodes' has to have same size as number of nodes");
959 for (Integer i_node = 0; i_node < nb_node_to_add; ++i_node) {
960 ItemInternal* node = m_one_mesh_item_adder->addOneNode(nodes_uid[i_node], owner);
961 if (add_to_nodes)
962 nodes[i_node] = node->localId();
963 }
964}
965
966/*---------------------------------------------------------------------------*/
967/*---------------------------------------------------------------------------*/
977{
978 Integer nb_node_to_add = nodes_uid.size();
979 bool add_to_nodes = nodes.size() != 0;
980 if (add_to_nodes && nb_node_to_add != nodes.size())
981 throw ArgumentException(A_FUNCINFO,
982 "return array 'nodes' has to have same size as number of nodes");
983 ItemDataList item_info_list;
984 ItemData& node_data = item_info_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()),
985 nb_node_to_add, 2 * nb_node_to_add + 1, nodes, &mesh()->trueNodeFamily(), &mesh()->trueNodeFamily(), owner);
986 Int64Array& node_infos2 = node_data.itemInfos();
987 // Copy node_info : to decrease the footprint of the copy, use references instead of int64
988 _fillNodeNewInfo(nodes_uid, node_infos2);
989
990 addItems(item_info_list);
991}
992
993/*---------------------------------------------------------------------------*/
994/*---------------------------------------------------------------------------*/
995
996void DynamicMeshIncrementalBuilder::
997_fillNodeNewInfo(Int64ConstArrayView node_uids, Int64ArrayView node_infos2)
998{
999 node_infos2[0] = 0; // nb_connected_families
1000 Integer index = 0;
1001 for (auto node_uid : node_uids) {
1002 node_infos2[2 * index + 1] = IT_Vertex; // type
1003 node_infos2[2 * index + 2] = node_uid; // id
1004 index++;
1005 }
1006}
1007
1008/*---------------------------------------------------------------------------*/
1009/*---------------------------------------------------------------------------*/
1028
1030addItems(ItemDataList& item_info_list)
1031{
1032 // Add items : item construction done from leaves to root
1033 _addItemsOrRelations(item_info_list, IItemFamilyNetwork::InverseTopologicalOrder);
1034}
1035
1036/*---------------------------------------------------------------------------*/
1037
1039addItems(ItemDataList& item_info_list, ItemDataList& item_relation_info_list)
1040{
1041 if (item_info_list.size() == 0 || item_relation_info_list.size() == 0)
1042 return;
1043 addItems(item_info_list);
1044 addRelations(item_relation_info_list);
1045}
1046
1047/*---------------------------------------------------------------------------*/
1048
1049void DynamicMeshIncrementalBuilder::
1050addRelations(ItemDataList& item_relation_list)
1051{
1052 // Add relations : items are already added. Do it from root to leaves
1053 _addItemsOrRelations(item_relation_list, IItemFamilyNetwork::TopologicalOrder);
1054}
1055
1056/*---------------------------------------------------------------------------*/
1057
1058void DynamicMeshIncrementalBuilder::
1059_addItemsOrRelations(ItemDataList& info_list, IItemFamilyNetwork::eSchedulingOrder family_graph_traversal_order)
1060{
1061 // Add relations : items are already added. Do it from root to leaves
1062 if (info_list.size() == 0)
1063 return;
1064 m_mesh->itemFamilyNetwork()->schedule([&](IItemFamily* family) {
1065 ItemData i_infos = info_list[family->itemKind()];
1066 this->addFamilyItems(i_infos);
1067 },
1068 family_graph_traversal_order); // item construction done from leaves to root
1069}
1070
1071/*---------------------------------------------------------------------------*/
1072/*---------------------------------------------------------------------------*/
1077
1079addFamilyItems(ItemData& item_data)
1080{
1081 if (item_data.nbItems() == 0)
1082 return;
1083 bool add_to_items = item_data.itemLids().size() != 0;
1084 if (add_to_items && item_data.nbItems() != item_data.itemLids().size())
1085 throw ArgumentException(A_FUNCINFO,
1086 "return array containing item lids has to have be of size number of items");
1087 // Prepare info and call OneMeshItemAdder->addOneItem
1088 Int64 item_uid;
1089 Int64ConstArrayView item_infos = item_data.itemInfos();
1090 Integer nb_connected_family = CheckedConvert::toInteger(item_infos[0]);
1091 if (nb_connected_family == 0)
1092 return;
1093 Int64UniqueArray connectivity_info;
1094 Integer nb_item_info = 0;
1095 Integer item_index = 0;
1096 for (Integer info_index = 1; info_index < item_data.itemInfos().size();) {
1097 ItemTypeId item_type_id{ (Int16)item_infos[info_index++] }; // item_type
1098 item_uid = item_infos[info_index++]; // item_uid
1099 Integer item_info_begin_index = info_index;
1100 for (Integer connected_family_index = 0; connected_family_index < nb_connected_family; ++connected_family_index) {
1101 Integer current_index = CheckedConvert::toInteger(item_infos[info_index + 1]);
1102 Integer nb_item_info_increment = 2 + current_index;
1103 nb_item_info += nb_item_info_increment; // family_id , nb_connected_elements
1104 info_index += nb_item_info_increment; // pointing on next family id
1105 }
1106 ItemInternal* item = m_one_mesh_item_adder->addOneItem2(item_data.itemFamily(),
1107 item_data.itemFamilyModifier(),
1108 item_type_id,
1109 item_uid,
1110 item_data.itemOwners()[item_index],
1111 item_data.subDomainId(),
1112 nb_connected_family,
1113 item_infos.subView(item_info_begin_index, nb_item_info));
1114 if (add_to_items)
1115 item_data.itemLids()[item_index++] = item->localId();
1116 nb_item_info = 0;
1117 }
1118}
1119
1120/*---------------------------------------------------------------------------*/
1121/*---------------------------------------------------------------------------*/
1131addFaces(Integer nb_face, Int64ConstArrayView faces_infos,
1132 Int32 rank, Int32ArrayView faces)
1133{
1134 ItemTypeMng* itm = m_item_type_mng;
1135
1136 bool add_to_faces = faces.size() != 0;
1137 if (add_to_faces && nb_face != faces.size())
1138 throw ArgumentException(A_FUNCINFO,
1139 "return array 'faces' has to have same size as number of faces");
1140
1141 Integer faces_infos_index = 0;
1142 for (Integer i_face = 0; i_face < nb_face; ++i_face) {
1143
1144 ItemTypeId item_type_id = ItemTypeId::fromInteger(faces_infos[faces_infos_index]);
1145 ++faces_infos_index;
1146 Int64 face_unique_id = faces_infos[faces_infos_index];
1147 ++faces_infos_index;
1148
1149 ItemTypeInfo* it = itm->typeFromId(item_type_id);
1150
1151 Integer current_face_nb_node = it->nbLocalNode();
1152 Int64ConstArrayView nodes_uid(current_face_nb_node, &faces_infos[faces_infos_index]);
1153 faces_infos_index += current_face_nb_node;
1154
1155 ItemInternal* face = m_one_mesh_item_adder->addOneFace(item_type_id, face_unique_id, rank, nodes_uid);
1156
1157 if (add_to_faces)
1158 faces[i_face] = face->localId();
1159 }
1160}
1161
1162/*---------------------------------------------------------------------------*/
1163/*---------------------------------------------------------------------------*/
1173addFaces2(Integer nb_face, Int64ConstArrayView faces_infos,
1174 Integer sub_domain_id, Int32ArrayView faces)
1175{
1176 bool add_to_faces = faces.size() != 0;
1177 if (add_to_faces && nb_face != faces.size())
1178 throw ArgumentException(A_FUNCINFO,
1179 "return array 'faces' has to have same size as number of faces");
1180 // Prepare face infos 2
1181 Integer face_infos2_size = faces_infos.size() + 1 + 2 * nb_face; // additive info nb_connected_family + nb_face * (family_id + nb_connected_element)
1182 ItemDataList item_info_list;
1183 ItemData& face_data = item_info_list.itemData(Integer(m_mesh->faceFamily()->itemKind()),
1184 nb_face, face_infos2_size, faces, &mesh()->trueFaceFamily(), &mesh()->trueFaceFamily(), sub_domain_id);
1185
1186 Int64ArrayView face_infos2 = face_data.itemInfos().view();
1187 Int64UniqueArray node_uids;
1188 Int64UniqueArray edge_uids;
1189
1190 _fillFaceInfo2(nb_face, faces_infos, face_infos2, node_uids);
1191
1192 // Prepare edge data if needed
1193 // if (m_has_edge) {
1194 // Integer nb_edge_to_add = edge_uids.size();
1195 // Int32UniqueArray edge_lids(nb_edge_to_add);
1196 // ItemData& edge_data = item_info_list.itemData(Integer(m_mesh->edgeFamily()->itemKind()),
1197 // nb_edge_to_add,2*nb_edge_to_add+1,edge_lids,&mesh()->trueNodeFamily(),&mesh()->trueNodeFamily(),sub_domain_id);
1198 // Int64Array& edge_infos2 = edge_data.itemInfos();
1199 // _fillEdgeInfo2(nb_edge_to_add,edge_uids,edge_infos2);
1200 // }
1201
1202 // Prepare node data (mutualize)
1203 Integer nb_node_to_add = node_uids.size();
1204 Int32UniqueArray node_lids(nb_node_to_add);
1205 ItemData& node_data = item_info_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()),
1206 nb_node_to_add, 2 * nb_node_to_add + 1, node_lids, &mesh()->trueNodeFamily(), &mesh()->trueNodeFamily(), sub_domain_id);
1207 Int64Array& node_infos2 = node_data.itemInfos();
1208 _fillNodeNewInfo(node_uids, node_infos2);
1209
1210 // Launch node and face creation
1211 addItems(item_info_list);
1212}
1213
1214/*---------------------------------------------------------------------------*/
1215
1216void DynamicMeshIncrementalBuilder::
1217addFaces3(Integer nb_face, Int64ConstArrayView faces_infos,
1218 Integer sub_domain_id, Int32ArrayView faces)
1219{
1220 bool add_to_faces = faces.size() != 0;
1221 if (add_to_faces && nb_face != faces.size())
1222 throw ArgumentException(A_FUNCINFO,
1223 "return array 'faces' has to have same size as number of faces");
1224 ItemDataList item_data_list;
1225 ItemDataList item_relation_data_list;
1226 // item info_size cannot be guessed
1227 Int64UniqueArray edges_infos;
1228 Int64UniqueArray nodes_infos;
1229 Int64UniqueArray node_uids;
1230 Int32UniqueArray edge_lids;
1231 Int32UniqueArray node_lids;
1232 Integer nb_edge = 0;
1233 Integer nb_node = 0;
1234 std::map<std::pair<Int64, Int64>, Int64> edge_uid_map;
1235
1236 // Fill classical info
1237 _fillEdgeInfo(nb_edge, nb_face, edges_infos, faces_infos, edge_uid_map);
1238 _fillNodeInfo(nb_node, nb_face, nodes_infos, faces_infos);
1239
1240 // Face info New
1241 ItemData& face_data = item_data_list.itemData(Integer(m_mesh->faceFamily()->itemKind()), nb_face, 0, faces, &mesh()->trueFaceFamily(), &mesh()->trueFaceFamily(), sub_domain_id);
1242 _fillFaceNewInfoNew(nb_face, faces_infos, face_data.itemInfos(), edge_uid_map);
1243
1244 // Edge info New
1245 if (hasEdge()) {
1246 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
1247 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);
1248 edge_lids.resize(item_data_list[m_mesh->edgeFamily()->itemKind()].nbItems());
1249 _fillEdgeNewInfoNew(nb_edge, edges_infos, edge_data.itemInfos()); // reprendre fillEdgeInfo et voir l'appel depuis add Edges + attention ordre des noeuds,
1250 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);
1251 _initEdgeRelationInfo(edge_relation_data, face_data, edges_infos); // edge-face relation
1252 }
1253
1254 // Node info New
1255 Integer node_info_size = 1 + nb_node * 2; //New info = Nb_connected_family + for each node : type, uid (no connected family)
1256 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);
1257 node_lids.resize(item_data_list[m_mesh->nodeFamily()->itemKind()].nbItems());
1258 _fillNodeNewInfo(nodes_infos, node_data.itemInfos());
1259 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);
1260 _initNodeRelationInfo(node_relation_data, face_data, nodes_infos); // node-face relation
1261
1262 // Launch node, face and edges (not compulsory) creation
1263 addItems(item_data_list, item_relation_data_list);
1264}
1265
1266/*---------------------------------------------------------------------------*/
1267/*---------------------------------------------------------------------------*/
1268
1269void DynamicMeshIncrementalBuilder::
1270_fillFaceNewInfoNew(Integer nb_face, Int64ConstArrayView faces_infos, Int64Array& face_infos2, const std::map<std::pair<Int64, Int64>, Int64>& edge_uid_map)
1271{
1272 ItemTypeMng* itm = m_item_type_mng;
1273 Integer nb_connected_family = hasEdge() ? 2 : 1;
1274 Integer face_infos2_size_approx = 1 + 2 * (faces_infos.size() + 2 * nb_face); // supposes as many faces as edges...
1275 face_infos2.reserve(face_infos2_size_approx);
1276 Int64UniqueArray work_face_sorted_nodes;
1277 Int64UniqueArray work_face_orig_nodes;
1278 Integer faces_infos_index = 0;
1279 // Integer face_infos2_index = 0;
1280 std::set<Int64> node_uids_set;
1281 face_infos2.add(nb_connected_family); // nb_connected_families nodes +/- Edges !!
1282 // Fill face_infos2 from faces_infos
1283 for (Integer i_face = 0; i_face < nb_face; ++i_face) {
1284 Integer current_face_type = (Integer)faces_infos[faces_infos_index++];
1285 Integer current_face_uid = (Integer)faces_infos[faces_infos_index++];
1286 face_infos2.add(current_face_type); // type
1287 face_infos2.add(current_face_uid); // uid
1288 //--Node connectivity
1289 face_infos2.add(mesh()->nodeFamily()->itemKind()); // connected_family_id
1290 ItemTypeInfo* it = itm->typeFromId(current_face_type);
1291 Integer current_face_nb_node = it->nbLocalNode();
1292 face_infos2.add(current_face_nb_node); // nb_connected_nodes
1293 // Nodes are not necessarily sorted (if caller is addFaces...)
1294 Int64ConstArrayView current_face_node_uids(current_face_nb_node, &faces_infos[faces_infos_index]);
1295 work_face_orig_nodes.resize(current_face_nb_node);
1296 work_face_sorted_nodes.resize(current_face_nb_node);
1297 work_face_orig_nodes.copy(current_face_node_uids);
1298 mesh_utils::reorderNodesOfFace(work_face_orig_nodes, work_face_sorted_nodes);
1299 face_infos2.addRange(work_face_sorted_nodes); // connected node uids
1300 faces_infos_index += current_face_nb_node;
1301 //--Edge Connectivity
1302 if (hasEdge()) {
1303 face_infos2.add(mesh()->edgeFamily()->itemKind());
1304 face_infos2.add(it->nbLocalEdge()); // nb_connected_edges
1305 for (int edge_index = 0; edge_index < it->nbLocalEdge(); ++edge_index) {
1306 Int64 first_node = work_face_sorted_nodes[it->localEdge(edge_index).beginNode()];
1307 Int64 second_node = work_face_sorted_nodes[it->localEdge(edge_index).endNode()];
1308 if (first_node > second_node)
1309 std::swap(first_node, second_node); // edge may be oriented negatively in the face
1310 auto edge_it = edge_uid_map.find(std::make_pair(first_node, second_node));
1311 if (edge_it == edge_uid_map.end())
1312 ARCANE_FATAL("Do not find edge with nodes {0}-{1} in edge uid map. Exiting",
1313 work_face_sorted_nodes[it->localEdge(edge_index).beginNode()],
1314 work_face_sorted_nodes[it->localEdge(edge_index).endNode()]);
1315 face_infos2.add(edge_it->second); // connected edge uid
1316 }
1317 }
1318 }
1319}
1320
1321/*---------------------------------------------------------------------------*/
1322
1323void DynamicMeshIncrementalBuilder::
1324_fillFaceInfo2(Integer nb_face, Int64ConstArrayView faces_infos, Int64ArrayView face_infos2, Int64Array& node_uids)
1325{
1326 ItemTypeMng* itm = m_item_type_mng;
1327 Integer faces_infos_index = 0;
1328 Integer face_infos2_index = 0;
1329 face_infos2[face_infos2_index++] = 1; // nb_connected_families (node only)
1330 Int64UniqueArray work_face_sorted_nodes;
1331 Int64UniqueArray work_face_orig_nodes;
1332 std::set<Int64> node_uids_set;
1333 // Fill face_infos2 from faces_infos
1334 for (Integer i_face = 0; i_face < nb_face; ++i_face) {
1335
1336 Integer item_type_id = (Integer)faces_infos[faces_infos_index];
1337 face_infos2[face_infos2_index++] = faces_infos[faces_infos_index++]; // type
1338 face_infos2[face_infos2_index++] = faces_infos[faces_infos_index++]; // uid
1339 face_infos2[face_infos2_index++] = mesh()->nodeFamily()->itemKind(); // connected_family_id
1340
1341 ItemTypeInfo* it = itm->typeFromId(item_type_id);
1342 Integer current_face_nb_node = it->nbLocalNode();
1343 face_infos2[face_infos2_index++] = current_face_nb_node; // nb_connected_items
1344 Int64ConstArrayView current_face_node_uids(current_face_nb_node, &faces_infos[faces_infos_index]);
1345 work_face_orig_nodes.resize(current_face_nb_node);
1346 work_face_sorted_nodes.resize(current_face_nb_node);
1347 work_face_orig_nodes.copy(current_face_node_uids);
1348 mesh_utils::reorderNodesOfFace(work_face_orig_nodes, work_face_sorted_nodes);
1349 face_infos2.subView(face_infos2_index, current_face_nb_node).copy(work_face_sorted_nodes); // connected node uids
1350 faces_infos_index += current_face_nb_node;
1351 face_infos2_index += current_face_nb_node;
1352 node_uids_set.insert(current_face_node_uids.begin(), current_face_node_uids.end());
1353 }
1354 node_uids.resize(node_uids_set.size());
1355 Integer index = 0;
1356 for (Int64 node_uid : node_uids_set)
1357 node_uids[index++] = node_uid;
1358}
1359
1360/*---------------------------------------------------------------------------*/
1361/*---------------------------------------------------------------------------*/
1371addEdges(Integer nb_edge, Int64ConstArrayView edge_infos,
1372 Integer sub_domain_id, Int32ArrayView edges)
1373{
1374 bool add_to_edges = edges.size() != 0;
1375 if (add_to_edges && nb_edge != edges.size())
1376 throw ArgumentException(A_FUNCINFO,
1377 "return array 'edges' has to have same size as number of edges");
1378
1379 Integer edge_info_index = 0;
1380 for (Integer i_edge = 0; i_edge < nb_edge; ++i_edge) {
1381
1382 Int64 edge_unique_id = edge_infos[edge_info_index];
1383 ++edge_info_index;
1384
1385 Int64ConstArrayView nodes_uid(2, &edge_infos[edge_info_index]);
1386 edge_info_index += 2;
1387
1388 ItemInternal* edge = m_one_mesh_item_adder->addOneEdge(edge_unique_id, sub_domain_id, nodes_uid);
1389
1390 if (add_to_edges)
1391 edges[i_edge] = edge->localId();
1392 }
1393}
1394
1395/*---------------------------------------------------------------------------*/
1396/*---------------------------------------------------------------------------*/
1406addEdges2(Integer nb_edge, Int64ConstArrayView edge_infos,
1407 Integer sub_domain_id, Int32ArrayView edges)
1408{
1409 bool add_to_edges = edges.size() != 0;
1410 if (add_to_edges && nb_edge != edges.size())
1411 throw ArgumentException(A_FUNCINFO,
1412 "return array 'edges' has to have same size as number of edges");
1413
1414 // Prepare face infos 2
1415 Integer edge_infos2_size = edge_infos.size() + 1 + 2 * nb_edge; // additive info nb_connected_family + nb_face * (family_id + nb_connected_element)
1416 ItemDataList item_info_list;
1417 ItemData& edge_data = item_info_list.itemData(Integer(m_mesh->edgeFamily()->itemKind()),
1418 nb_edge, edge_infos2_size, edges, &mesh()->trueEdgeFamily(), &mesh()->trueEdgeFamily(), sub_domain_id);
1419
1420 Int64ArrayView edge_infos2 = edge_data.itemInfos().view();
1421 Int64UniqueArray node_uids;
1422
1423 _fillEdgeInfo2(nb_edge, edge_infos, edge_infos2, node_uids);
1424
1425 // Prepare node data (mutualize)
1426 Integer nb_node_to_add = node_uids.size();
1427 Int32UniqueArray node_lids(nb_node_to_add);
1428 ItemData& node_data = item_info_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()),
1429 nb_node_to_add, 2 * nb_node_to_add + 1, node_lids, &mesh()->trueNodeFamily(), &mesh()->trueNodeFamily(), sub_domain_id);
1430 Int64Array& node_infos2 = node_data.itemInfos();
1431 _fillNodeNewInfo(node_uids, node_infos2);
1432
1433 // Launch node and face creation
1434 addItems(item_info_list);
1435}
1436
1437void DynamicMeshIncrementalBuilder::
1438addEdges3(Integer nb_edge, Int64ConstArrayView edges_infos,
1439 Integer sub_domain_id, Int32ArrayView edges)
1440{
1441 bool add_to_edges = edges.size() != 0;
1442 if (add_to_edges && nb_edge != edges.size())
1443 throw ArgumentException(A_FUNCINFO,
1444 "return array 'edges' has to have same size as number of edges");
1445 ItemDataList item_data_list;
1446 ItemDataList item_relation_data_list;
1447 // item info_size cannot be guessed
1448 Int64UniqueArray nodes_infos;
1449 Int32UniqueArray node_lids;
1450 Integer nb_node = 0;
1451
1452 // Fill classical info
1453 _fillNodeInfoFromEdge(nb_node, nb_edge, nodes_infos, edges_infos);
1454
1455 // Edge new info : edge data stores edge uids and dependency connectivities
1456 ItemData& edge_data = item_data_list.itemData(Integer(m_mesh->edgeFamily()->itemKind()), nb_edge, 0, edges, &mesh()->trueEdgeFamily(), &mesh()->trueEdgeFamily(), sub_domain_id);
1457 _fillEdgeNewInfoNew(nb_edge, edges_infos, edge_data.itemInfos());
1458
1459 // Node new info & relationsm
1460 ItemData& node_data = item_data_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()), nb_node, 0, node_lids, &mesh()->trueNodeFamily(), &mesh()->trueNodeFamily(), sub_domain_id);
1461 node_lids.resize(nb_node);
1462 _fillNodeNewInfo(nodes_infos, node_data.itemInfos());
1463 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);
1464 _initNodeRelationInfo(node_relations_data, edge_data, nodes_infos); // node-edge relation
1465
1466 // Launch node and edges creation
1467 addItems(item_data_list, item_relation_data_list);
1468}
1469
1470/*---------------------------------------------------------------------------*/
1471/*---------------------------------------------------------------------------*/
1472
1473void DynamicMeshIncrementalBuilder::
1474_fillEdgeInfo2(Integer nb_edge, Int64ConstArrayView edges_infos, Int64ArrayView edge_infos2, Int64Array& node_uids)
1475{
1476 Integer edges_infos_index = 0;
1477 Integer edge_infos2_index = 0;
1478 std::set<Int64> node_uids_set;
1479
1480 // Fill edge_infos2 from edges_infos
1481 edge_infos2[edge_infos2_index++] = 1; // nb_connected_families (node only)
1482
1483 for (Integer i_edge = 0; i_edge < nb_edge; ++i_edge) {
1484 edge_infos2[edge_infos2_index++] = IT_Line2; // type
1485 edge_infos2[edge_infos2_index++] = edges_infos[edges_infos_index++]; // uid
1486 edge_infos2[edge_infos2_index++] = mesh()->nodeFamily()->itemKind(); // connected_family_id
1487 edge_infos2[edge_infos2_index++] = 2; // nb_connected_items Attention : ordre des noeuds !! TODO
1488 edge_infos2[edge_infos2_index++] = edges_infos[edges_infos_index]; // first connected node uid
1489 node_uids_set.insert(edges_infos[edges_infos_index++]);
1490 edge_infos2[edge_infos2_index++] = edges_infos[edges_infos_index]; // second connected node uid
1491 node_uids_set.insert(edges_infos[edges_infos_index++]);
1492 }
1493 node_uids.resize(node_uids_set.size());
1494 Integer index = 0;
1495 for (Int64 node_uid : node_uids_set)
1496 node_uids[index++] = node_uid;
1497}
1498
1499void DynamicMeshIncrementalBuilder::
1500_fillEdgeNewInfoNew(Integer nb_edge, Int64ConstArrayView edges_infos, Int64ArrayView edges_new_infos)
1501{
1502 Integer edges_infos_index = 0;
1503 Integer edges_new_infos_index = 0;
1504
1505 // Fill edge_infos2 from edges_infos
1506 edges_new_infos[edges_new_infos_index++] = 1; // nb_connected_families (node only)
1507
1508 for (Integer i_edge = 0; i_edge < nb_edge; ++i_edge) {
1509 edges_new_infos[edges_new_infos_index++] = IT_Line2; // type
1510 edges_new_infos[edges_new_infos_index++] = edges_infos[edges_infos_index++]; // uid
1511 edges_new_infos[edges_new_infos_index++] = mesh()->nodeFamily()->itemKind(); // connected_family_id
1512 edges_new_infos[edges_new_infos_index++] = 2; // nb_connected_items
1513 Int64 first_node = edges_infos[edges_infos_index++];
1514 Int64 second_node = edges_infos[edges_infos_index++];
1515 if (first_node > second_node)
1516 std::swap(first_node, second_node);
1517 edges_new_infos[edges_new_infos_index++] = first_node; // first connected node uid
1518 edges_new_infos[edges_new_infos_index++] = second_node; // second connected node uid
1519 }
1520}
1521
1522/*---------------------------------------------------------------------------*/
1523/*---------------------------------------------------------------------------*/
1524
1525void DynamicMeshIncrementalBuilder::
1526readFromDump()
1527{
1528 // Recalculate the max uniqueId() of faces to know what value
1529 // to use in case of face creation.
1530 ItemInternalMap& faces_map = m_mesh->facesMap();
1531 Int64 max_uid = -1;
1532 faces_map.eachItem([&](Item face) {
1533 if (face.uniqueId() > max_uid)
1534 max_uid = face.uniqueId();
1535 });
1536 m_one_mesh_item_adder->setNextFaceUid(max_uid + 1);
1537
1538 if (m_has_edge) {
1539 ItemInternalMap& edges_map = m_mesh->edgesMap();
1540 Int64 max_uid = -1;
1541 edges_map.eachItem([&](Item edge) {
1542 if (edge.uniqueId() > max_uid)
1543 max_uid = edge.uniqueId();
1544 });
1545 m_one_mesh_item_adder->setNextEdgeUid(max_uid + 1);
1546 }
1547
1548 info(5) << "NEXT FACE UID mesh=" << m_mesh->name() << " Next=" << m_one_mesh_item_adder->nextFaceUid();
1549 info(5) << "NEXT EDGE UID mesh=" << m_mesh->name() << " Next=" << m_one_mesh_item_adder->nextEdgeUid();
1550}
1551
1552/*---------------------------------------------------------------------------*/
1553/*---------------------------------------------------------------------------*/
1554
1555void DynamicMeshIncrementalBuilder::
1556printInfos()
1557{
1558 info() << "-- Mesh information (Arcane2):";
1559 info() << "Number of nodes " << m_one_mesh_item_adder->nbNode();
1560 info() << "Number of edges " << m_one_mesh_item_adder->nbEdge();
1561 info() << "Number of faces " << m_one_mesh_item_adder->nbFace();
1562 info() << "Number of cells " << m_one_mesh_item_adder->nbCell();
1563 info() << "-- Graph information (Arcane2):";
1564}
1565
1566/*---------------------------------------------------------------------------*/
1567/*---------------------------------------------------------------------------*/
1568
1569void DynamicMeshIncrementalBuilder::
1570printStats(Int32 level)
1571{
1572 info(level) << "-- -- Statistics";
1573 info(level) << "Number of nodes after addition &: " << m_one_mesh_item_adder->nbNode()
1574 << " hashmap=" << m_mesh->nodesMap().count();
1575 info(level) << "Number of edges after addition : " << m_one_mesh_item_adder->nbEdge()
1576 << " hashmap=" << m_mesh->edgesMap().count();
1577 info(level) << "Number of faces after addition : " << m_one_mesh_item_adder->nbFace()
1578 << " hashmap=" << m_mesh->facesMap().count();
1579 info(level) << "Number of cells after addition : " << m_one_mesh_item_adder->nbCell()
1580 << " hashmap=" << m_mesh->cellsMap().count();
1581 info(level) << "--";
1582}
1583
1584/*---------------------------------------------------------------------------*/
1585/*---------------------------------------------------------------------------*/
1607{
1608 if (!m_face_unique_id_builder)
1609 m_face_unique_id_builder = new FaceUniqueIdBuilder(this);
1610 m_face_unique_id_builder->computeFacesUniqueIds();
1611
1612 if (m_has_edge) {
1613 if (!m_edge_unique_id_builder)
1614 m_edge_unique_id_builder = new EdgeUniqueIdBuilder(this);
1615 m_edge_unique_id_builder->computeEdgesUniqueIds();
1616 }
1617}
1618
1619/*---------------------------------------------------------------------------*/
1620/*---------------------------------------------------------------------------*/
1621
1622void DynamicMeshIncrementalBuilder::
1623addGhostLayers(bool is_allocate)
1624{
1625 debug() << "Add one ghost layer";
1628 m_ghost_layer_builder->addGhostLayers(is_allocate);
1629}
1630
1631/*---------------------------------------------------------------------------*/
1632/*---------------------------------------------------------------------------*/
1633
1636addGhostChildFromParent(Array<Int64>& ghost_cell_to_refine)
1637{
1638 debug() << "Add one ghost layer";
1641 m_ghost_layer_builder->addGhostChildFromParent2(ghost_cell_to_refine);
1642}
1643
1644/*---------------------------------------------------------------------------*/
1645/*---------------------------------------------------------------------------*/
1646
1647void DynamicMeshIncrementalBuilder::
1648_removeNeedRemoveMarkedItems(ItemInternalMap& map, UniqueArray<Int32>& items_local_id)
1649{
1650 // Removal of links
1651 SharedArray<ItemInternal*> items_to_remove;
1652 items_to_remove.reserve(1000);
1653
1654 map.eachItem([&](Item item) {
1655 impl::MutableItemBase mb_item = item.mutableItemBase();
1656 Integer f = mb_item.flags();
1657 if (f & ItemFlags::II_NeedRemove) {
1658 f &= ~ItemFlags::II_NeedRemove;
1659 mb_item.setFlags(f);
1660 items_local_id.add(item.localId());
1661 }
1662 });
1663}
1664
1665/*---------------------------------------------------------------------------*/
1666/*---------------------------------------------------------------------------*/
1667
1678{
1679 if (!m_mesh->useMeshItemFamilyDependencies()) {
1680
1681 IItemFamily* links_family = m_mesh->findItemFamily(IK_DoF, GraphDoFs::linkFamilyName(), false, false);
1682 if (links_family) {
1683 info() << "Remove Items for family : " << links_family->name();
1684 links_family->removeNeedRemoveMarkedItems();
1685 }
1686
1687 for (IItemFamily* family : m_mesh->itemFamilies()) {
1688 if (family->itemKind() != IK_DoF || family->name() == GraphDoFs::linkFamilyName())
1689 continue;
1690 info() << "Remove Items for family : " << family->name();
1691 family->removeNeedRemoveMarkedItems();
1692 }
1693 // Suppression of particles from the Particle family
1694
1695 for (IItemFamilyCollection::Enumerator i(m_mesh->itemFamilies()); ++i;) {
1696 IItemFamily* family = *i;
1697 if (family->itemKind() == IK_Particle) {
1698 ParticleFamily* particle_family = dynamic_cast<ParticleFamily*>(family);
1699 ARCANE_CHECK_POINTER(particle_family);
1700 if (particle_family && particle_family->getEnableGhostItems() == true) {
1701 UniqueArray<Integer> lids_to_remove;
1702 lids_to_remove.reserve(1000);
1703
1704 ItemInternalMap& particle_map = particle_family->itemsMap();
1705 particle_map.eachItem([&](Item item) {
1706 impl::MutableItemBase mb_item = item.mutableItemBase();
1707 Integer f = mb_item.flags();
1708 if (f & ItemFlags::II_NeedRemove) {
1709 f &= ~ItemFlags::II_NeedRemove;
1710 mb_item.setFlags(f);
1711 lids_to_remove.add(item.localId());
1712 }
1713 });
1714
1715 info() << "Number of particles of family " << family->name() << " to remove: " << lids_to_remove.size();
1716 if (lids_to_remove.size() > 0)
1717 particle_family->removeParticles(lids_to_remove);
1718 }
1719 }
1720 }
1721
1722 // Suppression of cells
1723 CellFamily& cell_family = m_mesh->trueCellFamily();
1724 UniqueArray<Int32> cells_to_remove;
1725 cells_to_remove.reserve(1000);
1726 _removeNeedRemoveMarkedItems(cell_family.itemsMap(), cells_to_remove);
1727
1728 info() << "Number of cells to remove: " << cells_to_remove.size();
1729
1730#ifdef ARCANE_DEBUG_DYNAMIC_MESH
1731 for (Integer i = 0, is = cells_to_remove.size(); i < is; ++i)
1732 info() << "remove cell with uid=" << cells_to_remove[i]->uniqueId()
1733 << ",lid=" << cells_to_remove[i]->localId()
1734 << ",owner=" << cells_to_remove[i]->owner();
1735#endif /* ARCANE_DEBUG_DYNAMIC_MESH */
1736
1737 cell_family.removeCells(cells_to_remove);
1738 }
1739 // With ItemFamilyNetwork
1740 else {
1741 // handle families already in the network
1742 m_mesh->itemFamilyNetwork()->schedule([](IItemFamily* family) {
1744 // Remove items from family graph leaves to root
1745 },
1746 IItemFamilyNetwork::InverseTopologicalOrder);
1747 for (auto family : m_mesh->itemFamilies()) {
1748 // handle remaining families (particles, links, dual nodes & dof).
1749 // Will have no effect on the families already handled in the graph (since NeedRemove flag is reset)
1751 }
1752 }
1753}
1754
1755/*---------------------------------------------------------------------------*/
1756/*---------------------------------------------------------------------------*/
1757
1759setConnectivity(const Integer connectivity)
1760{
1761 if (connectivity == 0)
1762 ARCANE_FATAL("Undefined connectivity !");
1763 if (m_connectivity != 0)
1764 ARCANE_FATAL("Connectivity already set: cannot redefine it");
1765 m_connectivity = connectivity;
1766 m_has_edge = Connectivity::hasConnectivity(connectivity, Connectivity::CT_HasEdge);
1767}
1768
1769/*---------------------------------------------------------------------------*/
1770/*---------------------------------------------------------------------------*/
1771
1774{
1775 m_face_uid_pool = 0;
1776 m_edge_uid_pool = 0;
1777 m_one_mesh_item_adder->resetAfterDeallocate();
1778}
1779
1780/*---------------------------------------------------------------------------*/
1781/*---------------------------------------------------------------------------*/
1782
1783} // End namespace Arcane::mesh
1784
1785/*---------------------------------------------------------------------------*/
1786/*---------------------------------------------------------------------------*/
#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.
Integer size() const
Number of elements in the vector.
constexpr Integer size() const noexcept
Returns the size of the array.
Base class for 1D data vectors.
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.
void add(ConstReferenceType val)
Adds element val to the end of the array.
T & back()
Last element of the array.
void reserve(Int64 new_capacity)
Reserves memory for new_capacity 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.
Template class for converting a type.
Face of a cell.
Definition Item.h:1032
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 typeId() const
Type of the face entity.
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.
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.
1D vector of data with reference semantics.
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).
void removeCells(ConstArrayView< Int32 > cells_local_id)
Removes the cells whose local numbers are cells_local_id.
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 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 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.
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.
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.
Construction of ghost layers.
Construction of ghost layers.
Construction of ghost layers.
Associative array of ItemInternal.
void eachItem(const Lambda &lambda)
Template function to iterate over the instance's entities.
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.