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