Arcane  4.2.3.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
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/* Construction d'un maillage de manière incrémentale. */
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 // Pour les types poly, le nombre de noeuds est la première valeur de la connectivité
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)_appendNodeRelationInfo(node_relation_data, item_data_list[IK_Face], nodes_infos); // node-face relations
231 if (hasEdge())_appendNodeRelationInfo(node_relation_data, item_data_list[IK_Edge], nodes_infos); // node-edge relations
232
233 // Launch node, face and edges (not mandatory) and cell creation
234 addItems(item_data_list, item_relation_data_list);
235
236}
237
238/*---------------------------------------------------------------------------*/
239
240void DynamicMeshIncrementalBuilder::
241addCells2(Integer nb_cell,Int64ConstArrayView cells_infos,
242 Integer sub_domain_id,Int32ArrayView cells,
243 bool allow_build_face)
244{
245 ItemDataList item_data_list;
246 ItemData& cell_data = item_data_list.itemData(Integer(m_mesh->cellFamily()->itemKind()),
247 nb_cell,0,cells,&mesh()->trueCellFamily(),&mesh()->trueCellFamily(),sub_domain_id);
248 // item info_size cannot be guessed
249 Int64Array& cell_infos2 = cell_data.itemInfos();
250 Int64UniqueArray faces_infos;
251 Int64UniqueArray node_uids;
252 Int32UniqueArray face_lids;
253 Integer nb_face;
254
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 {
262 Integer face_infos2_size = faces_infos.size()+ 1 + 2 * nb_face; // additive info nb_connected_family + nb_face * (family_id + nb_connected_element)
263 face_lids.resize(nb_face);
264 ItemData& face_data = item_data_list.itemData(Integer(m_mesh->faceFamily()->itemKind()),
265 nb_face,face_infos2_size,face_lids,&mesh()->trueFaceFamily(),&mesh()->trueFaceFamily(),sub_domain_id);
266 Int64ArrayView face_infos2 = face_data.itemInfos().view();
267 _fillFaceInfo2(nb_face,faces_infos,face_infos2,node_uids); // if allow_build_face false, node_uids built in fillCellInfo3
268 }
269
270 // Fill node info 2
271 Integer nb_node_to_add = node_uids.size();
272 Int32UniqueArray node_lids(nb_node_to_add);
273 ItemData& node_data = item_data_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()),
274 nb_node_to_add,2*nb_node_to_add+1,node_lids,&mesh()->trueNodeFamily(),&mesh()->trueNodeFamily(),sub_domain_id);
275 Int64Array& node_infos2 = node_data.itemInfos();
276 _fillNodeNewInfo(node_uids,node_infos2);
277
278 // Launch node and face and cell creation
279 addItems(item_data_list);
280
281}
282
283/*---------------------------------------------------------------------------*/
284/*---------------------------------------------------------------------------*/
285
286void DynamicMeshIncrementalBuilder::
287_fillFaceInfo(Integer& nb_face, Integer nb_cell,Int64Array& faces_infos, Int64ConstArrayView cells_infos, std::map<Int64,Int64SharedArray>& cell_to_face_connectivity_info)
288{
289 faces_infos.reserve(2*cells_infos.size());
290 Int64UniqueArray work_face_sorted_nodes;
291 Int64UniqueArray work_face_orig_nodes;
292 ItemTypeMng* itm = m_item_type_mng;
293 Integer cells_infos_index = 0;
294 nb_face = 0;
295 NodeInFaceSet face_nodes_set;
296 for (Integer i_cell = 0; i_cell < nb_cell; ++i_cell) {
297 Integer item_type_id = (Integer)cells_infos[cells_infos_index++];
298 Int64 current_cell_unique_id = cells_infos[cells_infos_index++];
299 ItemTypeInfo* it = itm->typeFromId(item_type_id);
300 Integer current_cell_nb_node = it->nbLocalNode();
301 Int64ConstArrayView current_cell_node_uids(current_cell_nb_node,&cells_infos[cells_infos_index]);
302 Integer current_cell_nb_face = it->nbLocalFace();
303 for (Integer face_in_cell_index = 0; face_in_cell_index < current_cell_nb_face; ++face_in_cell_index)
304 {
305 const ItemTypeInfo::LocalFace& current_face = it->localFace(face_in_cell_index);
306 Integer current_face_nb_node = current_face.nbNode();
307 work_face_orig_nodes.resize(current_face_nb_node);
308 work_face_sorted_nodes.resize(current_face_nb_node);
309 Integer i = 0;
310 for (Integer node_in_face_index = 0; node_in_face_index < current_face_nb_node; ++node_in_face_index)
311 {
312 work_face_orig_nodes[i++] = current_cell_node_uids[current_face.node(node_in_face_index)];
313 }
314 mesh_utils::reorderNodesOfFace(work_face_orig_nodes,work_face_sorted_nodes);
315 // get face uid: we shouldn't have to guess, it should be given in arguments...
316 Int64 current_face_uid = _findFaceUniqueId(work_face_sorted_nodes,face_nodes_set);
317 if (current_face_uid == NULL_ITEM_ID) // face not already known add to face info
318 {
319 current_face_uid = m_face_uid_pool++;
320 faces_infos.add(current_face.typeId()); // face info type
321 faces_infos.add(current_face_uid); // face info uid
322 faces_infos.addRange(work_face_sorted_nodes); // face info node uids
323 _addFaceNodes(face_nodes_set,work_face_sorted_nodes,current_face_uid);
324 ++nb_face;
325 }
326 cell_to_face_connectivity_info[current_cell_unique_id].add(current_face_uid);
327 }
328 cells_infos_index += current_cell_nb_node;
329 }
330}
331
332/*---------------------------------------------------------------------------*/
333
334void DynamicMeshIncrementalBuilder::
335_fillEdgeInfo(Integer& nb_edge, Integer nb_face,Int64Array& edges_infos,
336 Int64ConstArrayView faces_infos,std::map<std::pair<Int64,Int64>, Int64>& edge_uid_map)
337{
338 edges_infos.reserve(2*faces_infos.size());
339 ItemTypeMng* itm = m_item_type_mng;
340 Integer faces_infos_index = 0;
341 nb_edge = 0;
342 for (Integer i_face = 0; i_face < nb_face; ++i_face) {
343 Integer item_type_id = (Integer)faces_infos[faces_infos_index++]; // face type
344 ++faces_infos_index;// face uid (unused)
345 ItemTypeInfo* it = itm->typeFromId(item_type_id);
346 Integer current_face_nb_node = it->nbLocalNode();
347 Int64ConstArrayView current_face_node_uids(current_face_nb_node,&faces_infos[faces_infos_index]);
348 Integer current_face_nb_edge = it->nbLocalEdge();
349 for (Integer edge_in_face_index = 0; edge_in_face_index < current_face_nb_edge; ++edge_in_face_index)
350 {
351 const ItemTypeInfo::LocalEdge& current_edge = it->localEdge(edge_in_face_index);
352 Int64 first_node = current_face_node_uids[current_edge.beginNode()];
353 Int64 second_node = current_face_node_uids[current_edge.endNode()];
354 if (first_node > second_node) std::swap(first_node,second_node);
355 auto edge_it = edge_uid_map.insert(std::make_pair(std::make_pair(first_node,second_node), m_edge_uid_pool));
356 if (edge_it.second)
357 {
358 edges_infos.add(m_edge_uid_pool); // edge uid
359 edges_infos.add(first_node); // first node uid
360 edges_infos.add(second_node); // second node uid
361 ++nb_edge;
363 }
364 }
365 faces_infos_index += current_face_nb_node;
366 }
367}
368
369/*---------------------------------------------------------------------------*/
370
371void DynamicMeshIncrementalBuilder::
372_fillNodeInfo(Integer& nb_node, Integer nb_face,Int64Array& nodes_infos, Int64ConstArrayView faces_infos)
373{
374 nodes_infos.reserve(faces_infos.size());
375 Integer faces_infos_index = 0;
376 std::set<Int64> nodes_set;
377 ItemTypeMng* itm = m_item_type_mng;
378 for (Integer i_face = 0; i_face < nb_face; ++i_face) {
379 Int32 type_id = CheckedConvert::toInt32(faces_infos[faces_infos_index++]);
380 Integer current_face_nb_node = itm->typeFromId(type_id)->nbLocalNode(); // face type
381 ++faces_infos_index;//face_uid (unused)
382 for (auto node_uid : faces_infos.subConstView(faces_infos_index,current_face_nb_node)) {
383 nodes_set.insert(node_uid);
384 }
385 faces_infos_index+=current_face_nb_node;
386 }
387 nb_node = CheckedConvert::toInteger(nodes_set.size());
388 for (auto node_uid : nodes_set) {
389 nodes_infos.add(node_uid);
390 }
391}
392
393/*---------------------------------------------------------------------------*/
394
395void DynamicMeshIncrementalBuilder::
396_fillNodeInfoFromEdge(Integer& nb_node, Integer nb_edge, Int64Array& nodes_infos, Int64ConstArrayView edges_infos)
397{
398 nodes_infos.reserve(2*edges_infos.size());
399 Integer edges_infos_index = 0;
400 std::set<Int64> nodes_set;
401 for (Integer i_edge = 0; i_edge < nb_edge; ++i_edge) {
402 ++edges_infos_index;//edge_uid (unused)
403 nodes_set.insert(edges_infos[edges_infos_index++]);
404 nodes_set.insert(edges_infos[edges_infos_index++]);
405 }
406 nb_node = CheckedConvert::toInteger(nodes_set.size());
407 for (auto node_uid : nodes_set) {
408 nodes_infos.add(node_uid);
409 }
410}
411/*---------------------------------------------------------------------------*/
412
413void DynamicMeshIncrementalBuilder::
414_fillCellNewInfoNew(Integer nb_cell,Int64ConstArrayView cells_infos,Int64Array& cell_infos2,
415 const std::map<Int64,Int64SharedArray>& cell_to_face_connectivity_info, const std::map<std::pair<Int64,Int64>, Int64>& edge_uid_map)
416{
417 Integer cell_infos2_size_approx = 1 + 3 * (cells_infos.size()+ 2*nb_cell); // supposes as many faces as nodes as edges...
418 cell_infos2.reserve(cell_infos2_size_approx);
419 ItemTypeMng* itm = m_item_type_mng;
420 Integer cells_infos_index = 0;
421 Integer nb_connected_families = hasEdge() ? 3 : 2;
422 cell_infos2.add(nb_connected_families); // nb_connected_families (node and face +/- edge)
423 for (Integer i_cell = 0; i_cell < nb_cell; ++i_cell) {
424 Integer item_type_id = (Integer)cells_infos[cells_infos_index];
425 cell_infos2.add(cells_infos[cells_infos_index++]); // cell type
426 Int64 current_cell_uid = cells_infos[cells_infos_index];
427 cell_infos2.add(cells_infos[cells_infos_index++]); // cell uid
428 ItemTypeInfo* it = itm->typeFromId(item_type_id);
429 //--- Cell node connectivity
430 cell_infos2.add(mesh()->nodeFamily()->itemKind()); // connected_family_id: node family
431 Integer current_cell_nb_node = it->nbLocalNode();
432 cell_infos2.add(current_cell_nb_node); // nb_connected_nodes
433 Int64ConstArrayView current_cell_node_uids(current_cell_nb_node,&cells_infos[cells_infos_index]);
434 cell_infos2.addRange(current_cell_node_uids); // node ids
435 //--- Cell face connectivity
436 cell_infos2.add(mesh()->faceFamily()->itemKind()); // connected_family_id: face family
437 Integer current_cell_nb_face = it->nbLocalFace();
438 cell_infos2.add(current_cell_nb_face); // nb_connected_faces
439 Int64ArrayView current_cell_faces = cell_to_face_connectivity_info.find(current_cell_uid)->second.view();
440 if (current_cell_nb_face != current_cell_faces.size())
441 ARCANE_FATAL("Incoherent number of faces for cell {0}. Expected {1} found {2}",
442 current_cell_uid,current_cell_nb_face,current_cell_faces.size());
443 cell_infos2.addRange(current_cell_faces); // face ids
444 //-- Cell edge connectivity
445 if (hasEdge())
446 {
447 cell_infos2.add(mesh()->edgeFamily()->itemKind()); // connected_family_id: edge family
448 Integer current_cell_nb_edge = it->nbLocalEdge();
449 cell_infos2.add(current_cell_nb_edge); // nb_connected_edges
450 for (int edge_index = 0; edge_index < current_cell_nb_edge; ++edge_index) {
451 Int64 first_node = current_cell_node_uids[it->localEdge(edge_index).beginNode()];
452 Int64 second_node = current_cell_node_uids[it->localEdge(edge_index).endNode()];
453 if (first_node > second_node) std::swap(first_node,second_node);// edge may be oriented negatively in the cell
454 auto edge_it = edge_uid_map.find(std::make_pair(first_node,second_node));
455 if (edge_it == edge_uid_map.end())
456 ARCANE_FATAL("Do not find edge with nodes {0}-{1} in edge uid map. Exiting",
457 current_cell_node_uids[it->localEdge(edge_index).beginNode()],
458 current_cell_node_uids[it->localEdge(edge_index).endNode()]);
459 cell_infos2.add(edge_it->second);
460 }
461 }
462 cells_infos_index += current_cell_nb_node;
463 }
464}
465
466
467/*---------------------------------------------------------------------------*/
468/*---------------------------------------------------------------------------*/
469
470void DynamicMeshIncrementalBuilder::
471_fillCellInfo2(Integer nb_cell,Int64ConstArrayView cells_infos,Int64Array& cell_infos2,
472 Integer& nb_face, Int64Array& faces_infos, Int64Array& node_uids, bool allow_build_face)
473{
474 Integer cell_infos2_size_approx = 1 + 2 * (cells_infos.size()+ 2*nb_cell); // supposes as many faces as nodes...
475 cell_infos2.reserve(cell_infos2_size_approx);
476 // Fill infos
477 ItemTypeMng* itm = m_item_type_mng;
478 Integer cells_infos_index = 0;
479 cell_infos2.add(2); // nb_connected_families (node and face)
480
481 nb_face = 0;
482 faces_infos.reserve(2*cells_infos.size());
483 Int64UniqueArray work_face_sorted_nodes;
484 Int64UniqueArray work_face_orig_nodes;
485 NodeInFaceSet face_nodes_set;
486 std::set<Int64> node_uid_set;
487 // Fill face_infos2 from faces_infos
488 for (Integer i_cell = 0; i_cell < nb_cell; ++i_cell) {
489
490 Integer item_type_id = (Integer)cells_infos[cells_infos_index];
491 cell_infos2.add(cells_infos[cells_infos_index++]); // cell type
492 cell_infos2.add(cells_infos[cells_infos_index++]); // cell uid
493 cell_infos2.add(mesh()->nodeFamily()->itemKind()); // connected_family_id: node family
494
495 ItemTypeInfo* it = itm->typeFromId(item_type_id);
496 // Cell node connectivity
497 Integer current_cell_nb_node = it->nbLocalNode();
498 cell_infos2.add(current_cell_nb_node); // nb_connected_nodes
499 Int64ConstArrayView current_cell_node_uids(current_cell_nb_node,&cells_infos[cells_infos_index]);
500 cell_infos2.addRange(current_cell_node_uids); // node ids
501 if (!allow_build_face) node_uid_set.insert(current_cell_node_uids.begin(),current_cell_node_uids.end()); // otherwise node ids will be computed in face info build
502 // cell face connectivity
503 cell_infos2.add(mesh()->faceFamily()->itemKind()); // connected_family_id: face family
504 Integer current_cell_nb_face = it->nbLocalFace();
505 cell_infos2.add(current_cell_nb_face); // nb_connected_faces
506 for (Integer face_in_cell_index = 0; face_in_cell_index < current_cell_nb_face; ++face_in_cell_index)
507 {
508 ItemTypeInfo::LocalFace current_face = it->localFace(face_in_cell_index);
509 Integer current_face_nb_node = current_face.nbNode();
510 work_face_orig_nodes.resize(current_face_nb_node);
511 work_face_sorted_nodes.resize(current_face_nb_node);
512 Integer i = 0;
513 for (Integer node_in_face_index = 0; node_in_face_index < current_face_nb_node; ++node_in_face_index)
514 {
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 {
535 node_uids.resize(node_uid_set.size());
536 Integer index = 0;
537 for (Int64 node_uid : node_uid_set) node_uids[index++] = node_uid;
538 }
539}
540
541/*---------------------------------------------------------------------------*/
542
543void DynamicMeshIncrementalBuilder::
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/*---------------------------------------------------------------------------*/
551
552void DynamicMeshIncrementalBuilder::
553_appendFaceRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView faces_info)
554{
555 _fillFaceRelationInfo(source_item_relation_data,target_item_dependencies_data,faces_info,false);
556}
557
558/*---------------------------------------------------------------------------*/
559
560void DynamicMeshIncrementalBuilder::
561_fillFaceRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data,
562 Int64ConstArrayView faces_info, bool is_source_relation_data_empty)
563{
564 // face_infos = [{face_type, face_uid, {face_node_uids}]
565 Int64UniqueArray face_uids_and_types;
566 face_uids_and_types.reserve(2*source_item_relation_data.nbItems());
567 ItemTypeMng* itm = m_item_type_mng;
568 for (Integer face_info_index = 0; face_info_index < faces_info.size();) {
569 face_uids_and_types.add(faces_info[face_info_index+1]); // face_uid
570 face_uids_and_types.add(faces_info[face_info_index]); // face_type
571 Integer type_id = CheckedConvert::toInteger(face_uids_and_types.back());
572 face_info_index += (2+itm->typeFromId(type_id)->nbLocalNode());// increment and skip info (first & second_node_uid)
573 }
574 _fillItemRelationInfo(source_item_relation_data,target_item_dependencies_data,face_uids_and_types, is_source_relation_data_empty);
575}
576
577/*---------------------------------------------------------------------------*/
578
579void DynamicMeshIncrementalBuilder::
580_initEdgeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView edges_info)
581{
582 _fillEdgeRelationInfo(source_item_relation_data,target_item_dependencies_data,edges_info,true);
583}
584
585
586/*---------------------------------------------------------------------------*/
587
588void DynamicMeshIncrementalBuilder::
589_appendEdgeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView edges_info)
590{
591 _fillEdgeRelationInfo(source_item_relation_data,target_item_dependencies_data,edges_info,false);
592}
593
594
595/*---------------------------------------------------------------------------*/
596
597void DynamicMeshIncrementalBuilder::
598_fillEdgeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data,
599 Int64ConstArrayView edges_info, bool is_source_relation_data_empty)
600{
601 // edge_infos = [{edge_uid, first_node_uid, second_node_uid}
602 ARCANE_ASSERT((source_item_relation_data.nbItems()*3 == edges_info.size()),("source_item_relation_data and edges_info size incoherent. Exiting."));
603 Int64UniqueArray edge_uids_and_types;
604 edge_uids_and_types.reserve(2*source_item_relation_data.nbItems());
605 for (Integer edge_info_index = 0; edge_info_index < edges_info.size();) {
606 edge_uids_and_types.add(edges_info[edge_info_index++]); // edge_uid
607 edge_uids_and_types.add(IT_Line2); // edge_type
608 edge_info_index+=2;// skip info (first & second_node_uid)
609 }
610 _fillItemRelationInfo(source_item_relation_data,target_item_dependencies_data,edge_uids_and_types, is_source_relation_data_empty);
611}
612
613/*---------------------------------------------------------------------------*/
614
615void DynamicMeshIncrementalBuilder::
616_initNodeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView nodes_info)
617{
618 _fillNodeRelationInfo(source_item_relation_data,target_item_dependencies_data,nodes_info,true);
619}
620
621
622/*---------------------------------------------------------------------------*/
623
624void DynamicMeshIncrementalBuilder::
625_appendNodeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView nodes_info)
626{
627 _fillNodeRelationInfo(source_item_relation_data,target_item_dependencies_data,nodes_info,false);
628}
629
630/*---------------------------------------------------------------------------*/
631
632void DynamicMeshIncrementalBuilder::
633_fillNodeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView nodes_info, bool is_source_relation_data_empty){
634 // nodes_info = [node_uids]
635 ARCANE_ASSERT((source_item_relation_data.nbItems() == nodes_info.size()),("source_item_relation_data and nodes_info size incoherent. Exiting."));
636 Int64UniqueArray node_uids_and_types(2*nodes_info.size());
637 for (Integer node_index = 0; node_index < nodes_info.size(); ++node_index) {
638 node_uids_and_types[2*node_index] = nodes_info[node_index];
639 node_uids_and_types[2*node_index+1] = IT_Vertex;
640 }
641 _fillItemRelationInfo(source_item_relation_data,target_item_dependencies_data,node_uids_and_types, is_source_relation_data_empty);
642}
643
644
645/*---------------------------------------------------------------------------*/
646
647void DynamicMeshIncrementalBuilder::
648_fillItemRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data,
649 Int64ConstArrayView source_item_uids_and_types,
650 bool is_source_item_relation_data_empty)
651{
652 ARCANE_ASSERT((source_item_relation_data.nbItems()*2 == source_item_uids_and_types.size()),
653 ("source item number incoherent between source_item_relation_data and source_item_uids_and_types. Exiting."));
654 // Fill an ItemData containing source to target relations (target to source relations are included in target_item_data)
655 auto & source_relation_info = source_item_relation_data.itemInfos();
656 const auto & target_dependencies_info = target_item_dependencies_data.itemInfos();
657 auto source_family = source_item_relation_data.itemFamily();
658 auto target_family = target_item_dependencies_data.itemFamily();
659 if (! source_family || !target_family) return;
660 std::map<Int64, Int64SharedArray> source_to_target_uids;
661 Integer nb_families_connected_to_target = CheckedConvert::toInteger(target_dependencies_info[0]);
662 Integer target_info_index = 1; // 0 is nb_connected_families
663
664 // Fill map source to target traversing target_item_dependencies_data
665 for (; target_info_index < target_dependencies_info.size();) {
666 target_info_index++; // current target item_type
667 Int64 target_item_uid = target_dependencies_info[target_info_index++];// current target item uid
668 for (Integer family_connected_to_target = 0; family_connected_to_target < nb_families_connected_to_target; ++family_connected_to_target) {
669 Int64 family_connected_to_target_kind = target_dependencies_info[target_info_index++];// current target item connected family kind
670 if (family_connected_to_target_kind != source_family->itemKind()) {//this connection info does not concern source family. Skip
671 Integer nb_non_read_values = CheckedConvert::toInteger(target_dependencies_info[target_info_index++]); // nb_connected_item on this other family (/= to source family)
672 target_info_index+= nb_non_read_values;
673 continue;
674 }
675 else {
676 Int32 nb_source_item_connected_to_target_item = CheckedConvert::toInt32(target_dependencies_info[target_info_index++]);
677 for (Integer source_item_index = 0; source_item_index < nb_source_item_connected_to_target_item; ++source_item_index) {
678 source_to_target_uids[target_dependencies_info[source_item_index+target_info_index]].add(target_item_uid);
679 }
680 target_info_index += nb_source_item_connected_to_target_item;
681 }
682 }
683 }
684 // Fill or append source_item_relation_data traversing the map source_to_target_connectivity
685 if (is_source_item_relation_data_empty) _initEmptyRelationInfo(source_relation_info, source_to_target_uids, source_item_uids_and_types,
686 target_dependencies_info.size(), target_family);
687 else _appendInitializedRelationInfo(source_relation_info, source_to_target_uids, source_item_uids_and_types,
688 target_dependencies_info.size(), target_family);
689
690}
691
692/*---------------------------------------------------------------------------*/
693
694void DynamicMeshIncrementalBuilder::
695_initEmptyRelationInfo(Int64Array& source_relation_info, std::map<Int64, Int64SharedArray>& source_to_target_uids, Int64ConstArrayView source_item_uids_and_types,
696 Integer approx_relation_size,
697 IItemFamily const * target_family)
698{
699 if (! source_relation_info.empty()) source_relation_info.clear();
700 source_relation_info.reserve(approx_relation_size); // clearly too much elements...but only available info. Do better ?
701 source_relation_info.add(1);// nb_connected_families
702 // Fill source_item_relation_data
703 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) {
704 Int64 source_item_uid = source_item_uids_and_types[source_item_uids_and_types_index];
705 source_relation_info.add(source_item_uids_and_types[source_item_uids_and_types_index+1]); // item type
706 source_relation_info.add(source_item_uid); // item uid
707 source_relation_info.add(target_family->itemKind());// connected family kind
708 auto & connected_items = source_to_target_uids[source_item_uid];
709 source_relation_info.add(connected_items.size());// nb_connected_item
710 source_relation_info.addRange(connected_items.view()); // connected_items uids
711 }
712}
713
714/*---------------------------------------------------------------------------*/
715
716void DynamicMeshIncrementalBuilder::
717_appendInitializedRelationInfo(Int64Array& source_relation_info, std::map<Int64, Int64SharedArray>& source_to_target_uids, Int64ConstArrayView source_item_uids_and_types,
718 Integer approx_relation_size,
719 IItemFamily const * target_family)
720{
721 // Create a working array to build the consolidated info. This array will be copied in to source_relation_info at the end.
722 Int64UniqueArray source_relation_info_wrk_copy;
723 source_relation_info_wrk_copy.reserve(source_relation_info.size()+approx_relation_size);
724 std::set<Int64> treated_items;// To detect eventual source_items not already present in source_relation_info
725 Integer source_relation_info_index = 0;
726 Integer nb_connected_family = CheckedConvert::toInteger(source_relation_info[source_relation_info_index++]);
727 source_relation_info_wrk_copy.add(nb_connected_family+1); // adding a new connected family
728 for(; source_relation_info_index < source_relation_info.size() ;){
729 source_relation_info_wrk_copy.add(source_relation_info[source_relation_info_index++]); // item type
730 Int64 source_item_uid = source_relation_info[source_relation_info_index++]; // get item uid
731 source_relation_info_wrk_copy.add(source_item_uid);
732 treated_items.insert(source_item_uid);
733 for (Integer connected_family_index = 0; connected_family_index < nb_connected_family; ++connected_family_index) {
734 source_relation_info_wrk_copy.add(source_relation_info[source_relation_info_index++]); // family kind
735 Integer nb_connected_elements = CheckedConvert::toInteger(source_relation_info[source_relation_info_index++]); // nb connected elements
736 source_relation_info_wrk_copy.add(nb_connected_elements);
737 source_relation_info_wrk_copy.addRange(source_relation_info.subConstView(source_relation_info_index,nb_connected_elements));
738 source_relation_info_index += nb_connected_elements;
739 }
740 // Add new connection info
741 source_relation_info_wrk_copy.add(target_family->itemKind()); // family kind
742 const auto& connected_items = source_to_target_uids[source_item_uid]; // get connected items
743 source_relation_info_wrk_copy.add(connected_items.size()); // nb connected elements
744 source_relation_info_wrk_copy.addRange(connected_items);
745 }
746 // Find eventual source_items not already present in source_relation_info : todo check this can happen
747 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) {
748 Int64 source_item_uid = source_item_uids_and_types[source_item_uids_and_types_index];
749 if (treated_items.find(source_item_uid) == treated_items.end()){
750 source_relation_info_wrk_copy.add(source_item_uids_and_types[source_item_uids_and_types_index+1]); // item type
751 source_relation_info_wrk_copy.add(source_item_uid); // item uid
752 source_relation_info_wrk_copy.add(target_family->itemKind()); // family kind
753 const auto& connected_items = source_to_target_uids[source_item_uid]; // get connected items
754 source_relation_info_wrk_copy.add(connected_items.size()); // nb connected elements
755 source_relation_info_wrk_copy.addRange(connected_items);
756 // Padd this item info with family info : we added only one family, add void values for the other nb_connected_family families
757 for (Integer connected_family_index = 0; connected_family_index < nb_connected_family; ++connected_family_index) {
758 source_relation_info_wrk_copy.add(0); // family id (does not matter)
759 source_relation_info_wrk_copy.add(0); // nb_connected_elements for this family
760 }
761 }
762 }
763 // Copy working array into destination array
764 source_relation_info.resize(source_relation_info_wrk_copy.size());
765 std::copy(source_relation_info_wrk_copy.begin(), source_relation_info_wrk_copy.end(), source_relation_info.begin());
766}
767
768/*---------------------------------------------------------------------------*/
769/*---------------------------------------------------------------------------*/
770
771Int64 DynamicMeshIncrementalBuilder::
772_findFaceUniqueId(Int64ConstArrayView work_face_sorted_nodes, NodeInFaceSet& face_nodes_set)
773{
774 // check if first node exist
775 Integer index = 0;
776// return _findFaceInFaceNodesSet(face_nodes_set,index,work_face_sorted_nodes,std::make_shared<NodeInFace>(NULL_ITEM_ID));
777 return _findFaceInFaceNodesSet(face_nodes_set,index,work_face_sorted_nodes,NodeInFacePtr(NULL_ITEM_ID));
778}
779
780/*---------------------------------------------------------------------------*/
781
782Int64 DynamicMeshIncrementalBuilder::
783_findFaceInFaceNodesSet(const NodeInFaceSet& face_nodes_set,Integer index,Int64ConstArrayView face_nodes, NodeInFacePtr node)
784{
785 if (index < face_nodes.size())
786 {
787 auto found_node = std::find(face_nodes_set.begin(),face_nodes_set.end(),NodeInFacePtr(face_nodes[index]));
788 if (found_node == face_nodes_set.end()) return node->faceUid();
789 else return _findFaceInFaceNodesSet((*found_node)->nextNodeSet(),++index,face_nodes,*found_node);
790 }
791 else return node->faceUid();
792}
793
794/*---------------------------------------------------------------------------*/
795
796void DynamicMeshIncrementalBuilder::
797_addFaceNodes(NodeInFaceSet& face_nodes_set, Int64ConstArrayView face_nodes, Int64 face_uid)
798{
799 Integer index = 0;
800// _addFaceInFaceNodesSet(face_nodes_set, index,face_nodes, std::make_shared<NodeInFace>(NULL_ITEM_ID), face_uid);
801 _addFaceInFaceNodesSet(face_nodes_set, index,face_nodes, NodeInFacePtr(NULL_ITEM_ID), face_uid);
802}
803
804/*---------------------------------------------------------------------------*/
805
806void DynamicMeshIncrementalBuilder::
807_addFaceInFaceNodesSet(NodeInFaceSet& face_nodes_set,Integer index,Int64ConstArrayView face_nodes, NodeInFacePtr node, Int64 face_uid)
808{
809 if (index < face_nodes.size())
810 {
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 {
821 node->setFaceUid(face_uid);
822// debug() << "Set face uid " << face_uid << " for node " << node->m_uid;
823 }
824}
825
827DynamicMeshIncrementalBuilder::_insertNode(NodeInFaceSet& face_nodes_set, Int64 inserted_node_uid)
828{
829 NodeInFacePtr new_node(inserted_node_uid);
830 auto found_node = std::find(face_nodes_set.begin(),face_nodes_set.end(),new_node);
831 if (found_node == face_nodes_set.end()) {
832 face_nodes_set.push_back(std::move(new_node));
833 return face_nodes_set.back();
834 }
835 else 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/*---------------------------------------------------------------------------*/
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 {
995 node_infos2[2*index+1] = IT_Vertex; // type
996 node_infos2[2*index+2] = node_uid; // id
997 index++;
998 }
999}
1000
1001/*---------------------------------------------------------------------------*/
1002/*---------------------------------------------------------------------------*/
1021
1023addItems(ItemDataList& item_info_list)
1024{
1025 // Add items : item construction done from leaves to root
1026 _addItemsOrRelations(item_info_list,IItemFamilyNetwork::InverseTopologicalOrder);
1027}
1028
1029/*---------------------------------------------------------------------------*/
1030
1032addItems(ItemDataList& item_info_list, ItemDataList& item_relation_info_list)
1033{
1034 if (item_info_list.size() == 0 || item_relation_info_list.size() == 0) 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) return;
1055 m_mesh->itemFamilyNetwork()->schedule([&](IItemFamily* family){
1056 ItemData i_infos = info_list[family->itemKind()];
1057 this->addFamilyItems(i_infos);
1058 },
1059 family_graph_traversal_order); // item construction done from leaves to root
1060}
1061
1062/*---------------------------------------------------------------------------*/
1063/*---------------------------------------------------------------------------*/
1068
1070addFamilyItems(ItemData& item_data)
1071{
1072 if (item_data.nbItems() == 0) return;
1073 bool add_to_items = item_data.itemLids().size()!=0;
1074 if (add_to_items && item_data.nbItems()!= item_data.itemLids().size())
1075 throw ArgumentException(A_FUNCINFO,
1076 "return array containing item lids has to have be of size number of items");
1077 // Prepare info and call OneMeshItemAdder->addOneItem
1078 Int64 item_uid;
1079 Int64ConstArrayView item_infos = item_data.itemInfos();
1080 Integer nb_connected_family = CheckedConvert::toInteger(item_infos[0]);
1081 if(nb_connected_family == 0)
1082 return ;
1083 Int64UniqueArray connectivity_info;
1084 Integer nb_item_info = 0;
1085 Integer item_index = 0;
1086 for (Integer info_index = 1; info_index < item_data.itemInfos().size();){
1087 ItemTypeId item_type_id { (Int16)item_infos[info_index++] }; // item_type
1088 item_uid = item_infos[info_index++]; // item_uid
1089 Integer item_info_begin_index = info_index;
1090 for (Integer connected_family_index = 0;connected_family_index < nb_connected_family; ++connected_family_index) {
1091 Integer current_index = CheckedConvert::toInteger(item_infos[info_index+1]);
1092 Integer nb_item_info_increment = 2 + current_index;
1093 nb_item_info += nb_item_info_increment; // family_id , nb_connected_elements
1094 info_index+= nb_item_info_increment; // pointing on next family id
1095 }
1096 ItemInternal* item = m_one_mesh_item_adder->addOneItem2(item_data.itemFamily(),
1097 item_data.itemFamilyModifier(),
1098 item_type_id,
1099 item_uid,
1100 item_data.itemOwners()[item_index],
1101 item_data.subDomainId(),
1102 nb_connected_family,
1103 item_infos.subView(item_info_begin_index,nb_item_info));
1104 if (add_to_items)
1105 item_data.itemLids()[item_index++] = item->localId();
1106 nb_item_info = 0;
1107 }
1108}
1109
1110/*---------------------------------------------------------------------------*/
1111/*---------------------------------------------------------------------------*/
1121addFaces(Integer nb_face,Int64ConstArrayView faces_infos,
1122 Int32 rank, Int32ArrayView faces)
1123{
1124 ItemTypeMng* itm = m_item_type_mng;
1125
1126 bool add_to_faces = faces.size()!=0;
1127 if (add_to_faces && nb_face!=faces.size())
1128 throw ArgumentException(A_FUNCINFO,
1129 "return array 'faces' has to have same size as number of faces");
1130
1131 Integer faces_infos_index = 0;
1132 for(Integer i_face=0; i_face<nb_face; ++i_face ){
1133
1134 ItemTypeId item_type_id = ItemTypeId::fromInteger(faces_infos[faces_infos_index]);
1135 ++faces_infos_index;
1136 Int64 face_unique_id = faces_infos[faces_infos_index];
1137 ++faces_infos_index;
1138
1139 ItemTypeInfo* it = itm->typeFromId(item_type_id);
1140
1141 Integer current_face_nb_node = it->nbLocalNode();
1142 Int64ConstArrayView nodes_uid(current_face_nb_node,&faces_infos[faces_infos_index]);
1143 faces_infos_index += current_face_nb_node;
1144
1145 ItemInternal* face = m_one_mesh_item_adder->addOneFace(item_type_id, face_unique_id, rank, nodes_uid);
1146
1147 if (add_to_faces)
1148 faces[i_face] = face->localId();
1149 }
1150}
1151
1152/*---------------------------------------------------------------------------*/
1153/*---------------------------------------------------------------------------*/
1163addFaces2(Integer nb_face,Int64ConstArrayView faces_infos,
1164 Integer sub_domain_id,Int32ArrayView faces)
1165{
1166 bool add_to_faces = faces.size()!=0;
1167 if (add_to_faces && nb_face!=faces.size())
1168 throw ArgumentException(A_FUNCINFO,
1169 "return array 'faces' has to have same size as number of faces");
1170 // Prepare face infos 2
1171 Integer face_infos2_size = faces_infos.size()+ 1 + 2 * nb_face; // additive info nb_connected_family + nb_face * (family_id + nb_connected_element)
1172 ItemDataList item_info_list;
1173 ItemData& face_data = item_info_list.itemData(Integer(m_mesh->faceFamily()->itemKind()),
1174 nb_face,face_infos2_size,faces,&mesh()->trueFaceFamily(),&mesh()->trueFaceFamily(),sub_domain_id);
1175
1176 Int64ArrayView face_infos2 = face_data.itemInfos().view();
1177 Int64UniqueArray node_uids;
1178 Int64UniqueArray edge_uids;
1179
1180 _fillFaceInfo2(nb_face,faces_infos,face_infos2,node_uids);
1181
1182 // Prepare edge data if needed
1183// if (m_has_edge) {
1184// Integer nb_edge_to_add = edge_uids.size();
1185// Int32UniqueArray edge_lids(nb_edge_to_add);
1186// ItemData& edge_data = item_info_list.itemData(Integer(m_mesh->edgeFamily()->itemKind()),
1187// nb_edge_to_add,2*nb_edge_to_add+1,edge_lids,&mesh()->trueNodeFamily(),&mesh()->trueNodeFamily(),sub_domain_id);
1188// Int64Array& edge_infos2 = edge_data.itemInfos();
1189// _fillEdgeInfo2(nb_edge_to_add,edge_uids,edge_infos2);
1190// }
1191
1192 // Prepare node data (mutualize)
1193 Integer nb_node_to_add = node_uids.size();
1194 Int32UniqueArray node_lids(nb_node_to_add);
1195 ItemData& node_data = item_info_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()),
1196 nb_node_to_add,2*nb_node_to_add+1,node_lids,&mesh()->trueNodeFamily(),&mesh()->trueNodeFamily(),sub_domain_id);
1197 Int64Array& node_infos2 = node_data.itemInfos();
1198 _fillNodeNewInfo(node_uids,node_infos2);
1199
1200 // Launch node and face creation
1201 addItems(item_info_list);
1202}
1203
1204/*---------------------------------------------------------------------------*/
1205
1206void DynamicMeshIncrementalBuilder::
1207addFaces3(Integer nb_face,Int64ConstArrayView faces_infos,
1208 Integer sub_domain_id,Int32ArrayView faces)
1209{
1210 bool add_to_faces = faces.size()!=0;
1211 if (add_to_faces && nb_face!=faces.size())
1212 throw ArgumentException(A_FUNCINFO,
1213 "return array 'faces' has to have same size as number of faces");
1214 ItemDataList item_data_list;
1215 ItemDataList item_relation_data_list;
1216 // item info_size cannot be guessed
1217 Int64UniqueArray edges_infos;
1218 Int64UniqueArray nodes_infos;
1219 Int64UniqueArray node_uids;
1220 Int32UniqueArray edge_lids;
1221 Int32UniqueArray node_lids;
1222 Integer nb_edge = 0;
1223 Integer nb_node = 0;
1224 std::map<std::pair<Int64,Int64>, Int64> edge_uid_map;
1225
1226 // Fill classical info
1227 _fillEdgeInfo(nb_edge, nb_face, edges_infos, faces_infos, edge_uid_map);
1228 _fillNodeInfo(nb_node, nb_face, nodes_infos, faces_infos);
1229
1230 // Face info New
1231 ItemData& face_data = item_data_list.itemData(Integer(m_mesh->faceFamily()->itemKind()),nb_face,0,faces,&mesh()->trueFaceFamily(),&mesh()->trueFaceFamily(),sub_domain_id);
1232 _fillFaceNewInfoNew(nb_face,faces_infos,face_data.itemInfos(),edge_uid_map);
1233
1234 // Edge info New
1235 if (hasEdge()) {
1236 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
1237 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);
1238 edge_lids.resize(item_data_list[m_mesh->edgeFamily()->itemKind()].nbItems());
1239 _fillEdgeNewInfoNew(nb_edge,edges_infos,edge_data.itemInfos()); // reprendre fillEdgeInfo et voir l'appel depuis add Edges + attention ordre des noeuds,
1240 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);
1241 _initEdgeRelationInfo(edge_relation_data,face_data, edges_infos); // edge-face relation
1242 }
1243
1244 // Node info New
1245 Integer node_info_size = 1 + nb_node*2;//New info = Nb_connected_family + for each node : type, uid (no connected family)
1246 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);
1247 node_lids.resize(item_data_list[m_mesh->nodeFamily()->itemKind()].nbItems());
1248 _fillNodeNewInfo(nodes_infos,node_data.itemInfos());
1249 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);
1250 _initNodeRelationInfo(node_relation_data,face_data, nodes_infos); // node-face relation
1251
1252
1253 // Launch node, face and edges (not compulsory) creation
1254 addItems(item_data_list, item_relation_data_list);
1255}
1256
1257/*---------------------------------------------------------------------------*/
1258/*---------------------------------------------------------------------------*/
1259
1260void DynamicMeshIncrementalBuilder::
1261_fillFaceNewInfoNew(Integer nb_face,Int64ConstArrayView faces_infos,Int64Array& face_infos2, const std::map<std::pair<Int64,Int64>, Int64>& edge_uid_map)
1262{
1263 ItemTypeMng* itm = m_item_type_mng;
1264 Integer nb_connected_family = hasEdge() ? 2 : 1;
1265 Integer face_infos2_size_approx = 1 + 2 * (faces_infos.size()+ 2*nb_face); // supposes as many faces as edges...
1266 face_infos2.reserve(face_infos2_size_approx);
1267 Int64UniqueArray work_face_sorted_nodes;
1268 Int64UniqueArray work_face_orig_nodes;
1269 Integer faces_infos_index = 0;
1270// Integer face_infos2_index = 0;
1271 std::set<Int64> node_uids_set;
1272 face_infos2.add(nb_connected_family); // nb_connected_families nodes +/- Edges !!
1273 // Fill face_infos2 from faces_infos
1274 for(Integer i_face=0; i_face<nb_face; ++i_face ){
1275 Integer current_face_type = (Integer)faces_infos[faces_infos_index++];
1276 Integer current_face_uid = (Integer)faces_infos[faces_infos_index++];
1277 face_infos2.add(current_face_type); // type
1278 face_infos2.add(current_face_uid); // uid
1279 //--Node connectivity
1280 face_infos2.add(mesh()->nodeFamily()->itemKind()); // connected_family_id
1281 ItemTypeInfo* it = itm->typeFromId(current_face_type);
1282 Integer current_face_nb_node = it->nbLocalNode();
1283 face_infos2.add(current_face_nb_node); // nb_connected_nodes
1284 // Nodes are not necessarily sorted (if caller is addFaces...)
1285 Int64ConstArrayView current_face_node_uids(current_face_nb_node,&faces_infos[faces_infos_index]);
1286 work_face_orig_nodes.resize(current_face_nb_node);
1287 work_face_sorted_nodes.resize(current_face_nb_node);
1288 work_face_orig_nodes.copy(current_face_node_uids);
1289 mesh_utils::reorderNodesOfFace(work_face_orig_nodes,work_face_sorted_nodes);
1290 face_infos2.addRange(work_face_sorted_nodes); // connected node uids
1291 faces_infos_index += current_face_nb_node;
1292 //--Edge Connectivity
1293 if (hasEdge()){
1294 face_infos2.add(mesh()->edgeFamily()->itemKind());
1295 face_infos2.add(it->nbLocalEdge()); // nb_connected_edges
1296 for (int edge_index = 0; edge_index < it->nbLocalEdge(); ++edge_index) {
1297 Int64 first_node = work_face_sorted_nodes[it->localEdge(edge_index).beginNode()];
1298 Int64 second_node = work_face_sorted_nodes[it->localEdge(edge_index).endNode()];
1299 if (first_node > second_node) std::swap(first_node,second_node); // edge may be oriented negatively in the face
1300 auto edge_it = edge_uid_map.find(std::make_pair(first_node,second_node));
1301 if (edge_it == edge_uid_map.end())
1302 ARCANE_FATAL("Do not find edge with nodes {0}-{1} in edge uid map. Exiting",
1303 work_face_sorted_nodes[it->localEdge(edge_index).beginNode()],
1304 work_face_sorted_nodes[it->localEdge(edge_index).endNode()]);
1305 face_infos2.add(edge_it->second); // connected edge uid
1306 }
1307 }
1308 }
1309}
1310
1311/*---------------------------------------------------------------------------*/
1312
1313void DynamicMeshIncrementalBuilder::
1314_fillFaceInfo2(Integer nb_face,Int64ConstArrayView faces_infos,Int64ArrayView face_infos2, Int64Array& node_uids)
1315{
1316 ItemTypeMng* itm = m_item_type_mng;
1317 Integer faces_infos_index = 0;
1318 Integer face_infos2_index = 0;
1319 face_infos2[face_infos2_index++] = 1; // nb_connected_families (node only)
1320 Int64UniqueArray work_face_sorted_nodes;
1321 Int64UniqueArray work_face_orig_nodes;
1322 std::set<Int64> node_uids_set;
1323 // Fill face_infos2 from faces_infos
1324 for(Integer i_face=0; i_face<nb_face; ++i_face ){
1325
1326 Integer item_type_id = (Integer)faces_infos[faces_infos_index];
1327 face_infos2[face_infos2_index++] = faces_infos[faces_infos_index++]; // type
1328 face_infos2[face_infos2_index++] = faces_infos[faces_infos_index++]; // uid
1329 face_infos2[face_infos2_index++] = mesh()->nodeFamily()->itemKind(); // connected_family_id
1330
1331 ItemTypeInfo* it = itm->typeFromId(item_type_id);
1332 Integer current_face_nb_node = it->nbLocalNode();
1333 face_infos2[face_infos2_index++] = current_face_nb_node; // nb_connected_items
1334 Int64ConstArrayView current_face_node_uids(current_face_nb_node,&faces_infos[faces_infos_index]);
1335 work_face_orig_nodes.resize(current_face_nb_node);
1336 work_face_sorted_nodes.resize(current_face_nb_node);
1337 work_face_orig_nodes.copy(current_face_node_uids);
1338 mesh_utils::reorderNodesOfFace(work_face_orig_nodes,work_face_sorted_nodes);
1339 face_infos2.subView(face_infos2_index,current_face_nb_node).copy(work_face_sorted_nodes); // connected node uids
1340 faces_infos_index += current_face_nb_node;
1341 face_infos2_index += current_face_nb_node;
1342 node_uids_set.insert(current_face_node_uids.begin(),current_face_node_uids.end());
1343 }
1344 node_uids.resize(node_uids_set.size());
1345 Integer index = 0;
1346 for (Int64 node_uid : node_uids_set) node_uids[index++] = node_uid;
1347}
1348
1349/*---------------------------------------------------------------------------*/
1350/*---------------------------------------------------------------------------*/
1360addEdges(Integer nb_edge,Int64ConstArrayView edge_infos,
1361 Integer sub_domain_id,Int32ArrayView edges)
1362{
1363 bool add_to_edges = edges.size()!=0;
1364 if (add_to_edges && nb_edge!=edges.size())
1365 throw ArgumentException(A_FUNCINFO,
1366 "return array 'edges' has to have same size as number of edges");
1367
1368 Integer edge_info_index = 0;
1369 for(Integer i_edge=0; i_edge<nb_edge; ++i_edge ){
1370
1371 Int64 edge_unique_id = edge_infos[edge_info_index];
1372 ++edge_info_index;
1373
1374 Int64ConstArrayView nodes_uid(2,&edge_infos[edge_info_index]);
1375 edge_info_index += 2;
1376
1377 ItemInternal* edge = m_one_mesh_item_adder->addOneEdge(edge_unique_id, sub_domain_id, nodes_uid);
1378
1379 if (add_to_edges)
1380 edges[i_edge] = edge->localId();
1381 }
1382}
1383
1384/*---------------------------------------------------------------------------*/
1385/*---------------------------------------------------------------------------*/
1395addEdges2(Integer nb_edge,Int64ConstArrayView edge_infos,
1396 Integer sub_domain_id,Int32ArrayView edges)
1397{
1398 bool add_to_edges = edges.size()!=0;
1399 if (add_to_edges && nb_edge!=edges.size())
1400 throw ArgumentException(A_FUNCINFO,
1401 "return array 'edges' has to have same size as number of edges");
1402
1403 // Prepare face infos 2
1404 Integer edge_infos2_size = edge_infos.size()+ 1 + 2 * nb_edge; // additive info nb_connected_family + nb_face * (family_id + nb_connected_element)
1405 ItemDataList item_info_list;
1406 ItemData& edge_data = item_info_list.itemData(Integer(m_mesh->edgeFamily()->itemKind()),
1407 nb_edge,edge_infos2_size,edges,&mesh()->trueEdgeFamily(),&mesh()->trueEdgeFamily(),sub_domain_id);
1408
1409 Int64ArrayView edge_infos2 = edge_data.itemInfos().view();
1410 Int64UniqueArray node_uids;
1411
1412 _fillEdgeInfo2(nb_edge,edge_infos,edge_infos2,node_uids);
1413
1414 // Prepare node data (mutualize)
1415 Integer nb_node_to_add = node_uids.size();
1416 Int32UniqueArray node_lids(nb_node_to_add);
1417 ItemData& node_data = item_info_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()),
1418 nb_node_to_add,2*nb_node_to_add+1,node_lids,&mesh()->trueNodeFamily(),&mesh()->trueNodeFamily(),sub_domain_id);
1419 Int64Array& node_infos2 = node_data.itemInfos();
1420 _fillNodeNewInfo(node_uids,node_infos2);
1421
1422 // Launch node and face creation
1423 addItems(item_info_list);
1424}
1425
1426void DynamicMeshIncrementalBuilder::
1427addEdges3(Integer nb_edge,Int64ConstArrayView edges_infos,
1428 Integer sub_domain_id,Int32ArrayView edges)
1429{
1430 bool add_to_edges = edges.size()!=0;
1431 if (add_to_edges && nb_edge!=edges.size())
1432 throw ArgumentException(A_FUNCINFO,
1433 "return array 'edges' has to have same size as number of edges");
1434 ItemDataList item_data_list;
1435 ItemDataList item_relation_data_list;
1436 // item info_size cannot be guessed
1437 Int64UniqueArray nodes_infos;
1438 Int32UniqueArray node_lids;
1439 Integer nb_node = 0;
1440
1441 // Fill classical info
1442 _fillNodeInfoFromEdge(nb_node, nb_edge, nodes_infos, edges_infos);
1443
1444 // Edge new info : edge data stores edge uids and dependency connectivities
1445 ItemData& edge_data = item_data_list.itemData(Integer(m_mesh->edgeFamily()->itemKind()),nb_edge,0,edges,&mesh()->trueEdgeFamily(),&mesh()->trueEdgeFamily(),sub_domain_id);
1446 _fillEdgeNewInfoNew(nb_edge,edges_infos,edge_data.itemInfos());
1447
1448
1449 // Node new info & relationsm
1450 ItemData& node_data = item_data_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()),nb_node,0,node_lids,&mesh()->trueNodeFamily(),&mesh()->trueNodeFamily(),sub_domain_id);
1451 node_lids.resize(nb_node);
1452 _fillNodeNewInfo(nodes_infos,node_data.itemInfos());
1453 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);
1454 _initNodeRelationInfo(node_relations_data,edge_data, nodes_infos); // node-edge relation
1455
1456
1457 // Launch node and edges creation
1458 addItems(item_data_list, item_relation_data_list);
1459
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) node_uids[index++] = node_uid;
1488}
1489
1490void DynamicMeshIncrementalBuilder::
1491_fillEdgeNewInfoNew(Integer nb_edge,Int64ConstArrayView edges_infos,Int64ArrayView edges_new_infos)
1492{
1493 Integer edges_infos_index = 0;
1494 Integer edges_new_infos_index = 0;
1495
1496 // Fill edge_infos2 from edges_infos
1497 edges_new_infos[edges_new_infos_index++] = 1; // nb_connected_families (node only)
1498
1499 for(Integer i_edge=0; i_edge<nb_edge; ++i_edge ){
1500 edges_new_infos[edges_new_infos_index++] = IT_Line2; // type
1501 edges_new_infos[edges_new_infos_index++] = edges_infos[edges_infos_index++]; // uid
1502 edges_new_infos[edges_new_infos_index++] = mesh()->nodeFamily()->itemKind(); // connected_family_id
1503 edges_new_infos[edges_new_infos_index++] = 2; // nb_connected_items
1504 Int64 first_node = edges_infos[edges_infos_index++];
1505 Int64 second_node = edges_infos[edges_infos_index++];
1506 if (first_node > second_node) std::swap(first_node,second_node);
1507 edges_new_infos[edges_new_infos_index++] = first_node; // first connected node uid
1508 edges_new_infos[edges_new_infos_index++] = second_node; // second connected node uid
1509 }
1510}
1511
1512/*---------------------------------------------------------------------------*/
1513/*---------------------------------------------------------------------------*/
1514
1515void DynamicMeshIncrementalBuilder::
1516readFromDump()
1517{
1518 // Recalcul le max uniqueId() des faces pour savoir quelle valeur
1519 // utiliser en cas de creation de face.
1520 ItemInternalMap& faces_map = m_mesh->facesMap();
1521 Int64 max_uid = -1;
1522 faces_map.eachItem([&](Item face) {
1523 if (face.uniqueId() > max_uid)
1524 max_uid = face.uniqueId();
1525 });
1526 m_one_mesh_item_adder->setNextFaceUid(max_uid + 1);
1527
1528 if (m_has_edge) {
1529 ItemInternalMap& edges_map = m_mesh->edgesMap();
1530 Int64 max_uid = -1;
1531 edges_map.eachItem([&](Item edge) {
1532 if (edge.uniqueId() > max_uid)
1533 max_uid = edge.uniqueId();
1534 });
1535 m_one_mesh_item_adder->setNextEdgeUid(max_uid + 1);
1536 }
1537
1538 info(5) << "NEXT FACE UID mesh=" << m_mesh->name() << " Next=" << m_one_mesh_item_adder->nextFaceUid();
1539 info(5) << "NEXT EDGE UID mesh=" << m_mesh->name() << " Next=" << m_one_mesh_item_adder->nextEdgeUid();
1540}
1541
1542/*---------------------------------------------------------------------------*/
1543/*---------------------------------------------------------------------------*/
1544
1545void DynamicMeshIncrementalBuilder::
1546printInfos()
1547{
1548 info() << "-- Mesh information (Arcane2):";
1549 info() << "Number of nodes " << m_one_mesh_item_adder->nbNode();
1550 info() << "Number of edges " << m_one_mesh_item_adder->nbEdge();
1551 info() << "Number of faces " << m_one_mesh_item_adder->nbFace();
1552 info() << "Number of cells " << m_one_mesh_item_adder->nbCell();
1553 info() << "-- Graph information (Arcane2):";
1554}
1555
1556/*---------------------------------------------------------------------------*/
1557/*---------------------------------------------------------------------------*/
1558
1559void DynamicMeshIncrementalBuilder::
1560printStats(Int32 level)
1561{
1562 info(level) << "-- -- Statistics";
1563 info(level) << "Number of nodes after addition &: " << m_one_mesh_item_adder->nbNode()
1564 << " hashmap=" << m_mesh->nodesMap().count();
1565 info(level) << "Number of edges after addition : " << m_one_mesh_item_adder->nbEdge()
1566 << " hashmap=" << m_mesh->edgesMap().count();
1567 info(level) << "Number of faces after addition : " << m_one_mesh_item_adder->nbFace()
1568 << " hashmap=" << m_mesh->facesMap().count();
1569 info(level) << "Number of cells after addition : " << m_one_mesh_item_adder->nbCell()
1570 << " hashmap=" << m_mesh->cellsMap().count();
1571 info(level) << "--";
1572}
1573
1574/*---------------------------------------------------------------------------*/
1575/*---------------------------------------------------------------------------*/
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 // Suppression des liaisons
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
1674 IItemFamily* links_family = m_mesh->findItemFamily(IK_DoF, GraphDoFs::linkFamilyName(), false, false);
1675 if(links_family)
1676 {
1677 info() << "Remove Items for family : "<<links_family->name() ;
1678 links_family->removeNeedRemoveMarkedItems() ;
1679 }
1680
1681 for( IItemFamily* family : m_mesh->itemFamilies() )
1682 {
1683 if (family->itemKind()!=IK_DoF || family->name()==GraphDoFs::linkFamilyName())
1684 continue;
1685 info() << "Remove Items for family : "<<family->name() ;
1686 family->removeNeedRemoveMarkedItems() ;
1687 }
1688 // Supression des particules de la famille Particle
1689
1690 for( IItemFamilyCollection::Enumerator i(m_mesh->itemFamilies()); ++i; ){
1691 IItemFamily* family = *i;
1692 if (family->itemKind()==IK_Particle){
1693 ParticleFamily* particle_family = dynamic_cast<ParticleFamily*>(family) ;
1694 ARCANE_CHECK_POINTER(particle_family);
1695 if(particle_family && particle_family->getEnableGhostItems()==true){
1696 UniqueArray<Integer> lids_to_remove ;
1697 lids_to_remove.reserve(1000);
1698
1699 ItemInternalMap& particle_map = particle_family->itemsMap();
1700 particle_map.eachItem([&](Item item) {
1701 impl::MutableItemBase mb_item = item.mutableItemBase();
1702 Integer f = mb_item.flags();
1703 if (f & ItemFlags::II_NeedRemove){
1704 f &= ~ItemFlags::II_NeedRemove;
1705 mb_item.setFlags(f);
1706 lids_to_remove.add(item.localId());
1707 }
1708 });
1709
1710 info() << "Number of particles of family "<<family->name()<<" to remove: " << lids_to_remove.size();
1711 if(lids_to_remove.size()>0)
1712 particle_family->removeParticles(lids_to_remove) ;
1713 }
1714 }
1715 }
1716
1717 // Suppression des mailles
1718 CellFamily& cell_family = m_mesh->trueCellFamily();
1719 UniqueArray<Int32> cells_to_remove;
1720 cells_to_remove.reserve(1000);
1721 _removeNeedRemoveMarkedItems(cell_family.itemsMap(), cells_to_remove);
1722
1723 info() << "Number of cells to remove: " << cells_to_remove.size();
1724
1725#ifdef ARCANE_DEBUG_DYNAMIC_MESH
1726 for( Integer i=0, is=cells_to_remove.size(); i<is; ++i )
1727 info() << "remove cell with uid=" << cells_to_remove[i]->uniqueId()
1728 << ",lid=" << cells_to_remove[i]->localId()
1729 << ",owner=" << cells_to_remove[i]->owner();
1730#endif /* ARCANE_DEBUG_DYNAMIC_MESH */
1731
1732 cell_family.removeCells(cells_to_remove);
1733 }
1734 // With ItemFamilyNetwork
1735 else
1736 {
1737 // handle families already in the network
1738 m_mesh->itemFamilyNetwork()->schedule([](IItemFamily* family){
1740 // Remove items from family graph leaves to root
1741 }, IItemFamilyNetwork::InverseTopologicalOrder);
1742 for (auto family : m_mesh->itemFamilies()) {
1743 // handle remaining families (particles, links, dual nodes & dof).
1744 // Will have no effect on the families already handled in the graph (since NeedRemove flag is reset)
1746 }
1747 }
1748}
1749
1750/*---------------------------------------------------------------------------*/
1751/*---------------------------------------------------------------------------*/
1752
1754setConnectivity(const Integer connectivity)
1755{
1756 if (connectivity == 0)
1757 ARCANE_FATAL("Undefined connectivity !");
1758 if (m_connectivity != 0)
1759 ARCANE_FATAL("Connectivity already set: cannot redefine it");
1760 m_connectivity = connectivity;
1761 m_has_edge = Connectivity::hasConnectivity(connectivity,Connectivity::CT_HasEdge);
1762}
1763
1764/*---------------------------------------------------------------------------*/
1765/*---------------------------------------------------------------------------*/
1766
1769{
1770 m_face_uid_pool = 0;
1771 m_edge_uid_pool = 0;
1772 m_one_mesh_item_adder->resetAfterDeallocate();
1773}
1774
1775/*---------------------------------------------------------------------------*/
1776/*---------------------------------------------------------------------------*/
1777
1778} // End namespace Arcane::mesh
1779
1780/*---------------------------------------------------------------------------*/
1781/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fonctions utilitaires sur le maillage.
Integer size() const
Nombre d'éléments du vecteur.
Exception lorsqu'un argument est invalide.
constexpr Integer size() const noexcept
Retourne la taille du tableau.
Tableau d'items de types quelconques.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
ArrayView< T > view() const
Vue mutable sur ce tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Maille d'un maillage.
Definition Item.h:1214
Vue constante d'un tableau de type T.
constexpr ConstArrayView< T > subView(Integer abegin, Integer asize) const noexcept
Sous-vue (constante) à partir de l'élément abegin et contenant asize éléments.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Classe template pour convertir un type.
Face d'une maille.
Definition Item.h:964
virtual void schedule(IItemFamilyNetworkTask task, eSchedulingOrder order=TopologicalOrder)=0
Ordonnance l'exécution d'une tâche, dans l'ordre topologique ou topologique inverse du graphe de dépe...
Interface d'une famille d'entités.
Definition IItemFamily.h:86
virtual void removeNeedRemoveMarkedItems()=0
Supprime des entités et met a jour les connectivites.
virtual String name() const =0
Nom de la famille.
virtual eItemKind itemKind() const =0
Genre des entités.
Int32 flags() const
Flags de l'entité
Int32 localId() const
Numéro local (au sous-domaine) de l'entité
Flags pour les caractéristiques des entités.
Definition ItemFlags.h:38
@ II_NeedRemove
L'entité doit être supprimé
Definition ItemFlags.h:62
Structure interne d'une entité de maillage.
Type d'une entité (Item).
Definition ItemTypeId.h:32
static ItemTypeId fromInteger(Int64 v)
Créé une instance à partir d'un entier.
Infos sur un type d'entité du maillage.
Integer nbLocalNode() const
Nombre de noeuds de l'entité
Gestionnaire des types d'entités d'un maillage.
Definition ItemTypeMng.h:64
ItemTypeInfo * typeFromId(Integer id) const
Type correspondant au numéro id.
Vue sur un vecteur d'entités.
Int32 size() const
Nombre d'éléments du vecteur.
Classe de base d'un élément de maillage.
Definition Item.h:83
impl::MutableItemBase mutableItemBase() const
Partie interne modifiable de l'entité.
Definition Item.h:380
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:219
void setFlags(Int32 f)
Positionne les flags de l'entité
Vecteur 1D de données avec sémantique par référence.
Chaîne de caractères unicode.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
ITraceMng * traceMng() const
Gestionnaire de trace.
Vecteur 1D de données avec sémantique par valeur (style STL).
Famille de mailles.
Definition CellFamily.h:46
void removeCells(ConstArrayView< Int32 > cells_local_id)
Supprime les mailles dont les numéros locaux sont 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()
Calcul les numéros uniques de chaque face.
void setConnectivity(Integer c)
Définit la connectivité active pour le maillage associé
void addParentCells(const ItemVectorView &items)
Ajout au maillage courant d'item venant d'un maillage parent.
void addCells(Integer nb_cell, Int64ConstArrayView cell_infos, Integer sub_domain_id, Int32ArrayView cells, bool allow_build_face=true)
Ajoute des mailles au maillage actuel.
void addParentItems(const ItemVectorView &items, const eItemKind submesh_kind)
Ajout au maillage courant d'item venant d'un maillage parent.
OneMeshItemAdder * m_one_mesh_item_adder
Outils de construction du maillage.
Int64 m_face_uid_pool
Numéro du uniqueId() utilisé pour générer les faces.
void resetAfterDeallocate()
Remise à zéro des structures pour pouvoir faire à nouveau une allocation.
void addGhostChildFromParent(Array< Int64 > &ghost_cell_to_refine)
AMR.
void addEdges2(Integer nb_edge, Int64ConstArrayView edge_infos, Integer sub_domain_id, Int32ArrayView edges)
Ajoute des arêtes au maillage actuel. Utilise l'ajout d'item générique basé sur dépendances entre fam...
Int64 m_edge_uid_pool
Numéro du uniqueId() utilisé pour générer les 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)
Ajoute des arêtes au maillage actuel.
GhostLayerBuilder * m_ghost_layer_builder
Outil pour construire les éléments fantômes.
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 sur la présence d'arête (accèlere l'accès à la connectivité générale).
void addFamilyItems(ItemData &item_info)
Ajout générique d'items d'une famille, décrite par son ItemInfo.
DynamicMeshIncrementalBuilder(DynamicMesh *mesh)
Construit une instance pour le maillage mesh.
void removeNeedRemoveMarkedItems()
Supprime les items fantômes.
void addCells3(Integer nb_cell, Int64ConstArrayView cell_infos, Integer sub_domain_id, Int32ArrayView cells, bool allow_build_face=true)
Ajoute des mailles au maillage actuel. Utilise l'ajout d'item générique basé sur dépendances entre fa...
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
Info de connectivité du maillage courant.
Implémentation d'un maillage.
Definition DynamicMesh.h:98
IItemFamily * nodeFamily() override
Retourne la famille des noeuds.
IItemFamily * cellFamily() override
Retourne la famille des mailles.
IItemFamily * faceFamily() override
Retourne la famille des faces.
IItemFamilyNetwork * itemFamilyNetwork() override
Interface du réseau de familles (familles connectées).
IItemFamily * edgeFamily() override
Retourne la famille des arêtes.
Construction des couches fantômes.
Construction des couches fantômes.
Construction des couches fantômes.
Tableau associatif de ItemInternal.
void eachItem(const Lambda &lambda)
Fonction template pour itérer sur les entités de l'instance.
Famille de particules.
bool getEnableGhostItems() const override
récupère le flag pour gérer les particules ghost de la famille
Array< Int64 > Int64Array
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:119
ArrayView< Int64 > Int64ArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:449
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:337
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:478
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:339
ArrayView< Int32 > Int32ArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:451
eItemKind
Genre d'entité de maillage.
@ IK_Particle
Entité de maillage de genre particule.
@ IK_Cell
Entité de maillage de genre maille.
@ IK_Face
Entité de maillage de genre face.
@ IK_DoF
Entité de maillage de genre degre de liberte.
@ IK_Edge
Entité de maillage de genre arête.
std::int16_t Int16
Type entier signé sur 16 bits.
std::int32_t Int32
Type entier signé sur 32 bits.