Arcane  v3.15.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-2025 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/* 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())
65, m_one_mesh_item_adder(new OneMeshItemAdder(this))
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() ){
95 if (face.backCell()==cell){
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] };
138 Int64 cell_unique_id = cells_infos[cells_infos_index];
140
141 ItemTypeInfo* it = itm->typeFromId(item_type_id);
142 Integer current_cell_nb_node = it->nbLocalNode();
144
147
148 if (add_to_cells)
149 cells[i_cell] = cell->localId();
151 }
152}
153
154/*---------------------------------------------------------------------------*/
155/*---------------------------------------------------------------------------*/
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
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)_appendNodeRelationInfo(node_relation_data, item_data_list[IK_Face], nodes_infos); // node-face relations
223 if (hasEdge())_appendNodeRelationInfo(node_relation_data, item_data_list[IK_Edge], nodes_infos); // node-edge relations
224
225 // Launch node, face and edges (not mandatory) and cell creation
227
228}
229
230/*---------------------------------------------------------------------------*/
231
232void DynamicMeshIncrementalBuilder::
233addCells2(Integer nb_cell,Int64ConstArrayView cells_infos,
234 Integer sub_domain_id,Int32ArrayView cells,
235 bool allow_build_face)
236{
238 ItemData& cell_data = item_data_list.itemData(Integer(m_mesh->cellFamily()->itemKind()),
239 nb_cell,0,cells,&mesh()->trueCellFamily(),&mesh()->trueCellFamily(),sub_domain_id);
240 // item info_size cannot be guessed
241 Int64Array& cell_infos2 = cell_data.itemInfos();
242 Int64UniqueArray faces_infos;
245 Integer nb_face;
246
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
253 {
254 Integer face_infos2_size = faces_infos.size()+ 1 + 2 * nb_face; // additive info nb_connected_family + nb_face * (family_id + nb_connected_element)
255 face_lids.resize(nb_face);
256 ItemData& face_data = item_data_list.itemData(Integer(m_mesh->faceFamily()->itemKind()),
257 nb_face,face_infos2_size,face_lids,&mesh()->trueFaceFamily(),&mesh()->trueFaceFamily(),sub_domain_id);
258 Int64ArrayView face_infos2 = face_data.itemInfos().view();
259 _fillFaceInfo2(nb_face,faces_infos,face_infos2,node_uids); // if allow_build_face false, node_uids built in fillCellInfo3
260 }
261
262 // Fill node info 2
263 Integer nb_node_to_add = node_uids.size();
265 ItemData& node_data = item_data_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()),
266 nb_node_to_add,2*nb_node_to_add+1,node_lids,&mesh()->trueNodeFamily(),&mesh()->trueNodeFamily(),sub_domain_id);
267 Int64Array& node_infos2 = node_data.itemInfos();
268 _fillNodeNewInfo(node_uids,node_infos2);
269
270 // Launch node and face and cell creation
272
273}
274
275/*---------------------------------------------------------------------------*/
276/*---------------------------------------------------------------------------*/
277
278void DynamicMeshIncrementalBuilder::
279_fillFaceInfo(Integer& nb_face, Integer nb_cell,Int64Array& faces_infos, Int64ConstArrayView cells_infos, std::map<Int64,Int64SharedArray>& cell_to_face_connectivity_info)
280{
281 faces_infos.reserve(2*cells_infos.size());
282 Int64UniqueArray work_face_sorted_nodes;
283 Int64UniqueArray work_face_orig_nodes;
284 ItemTypeMng* itm = m_item_type_mng;
285 Integer cells_infos_index = 0;
286 nb_face = 0;
287 NodeInFaceSet face_nodes_set;
288 for (Integer i_cell = 0; i_cell < nb_cell; ++i_cell) {
289 Integer item_type_id = (Integer)cells_infos[cells_infos_index++];
290 Int64 current_cell_unique_id = cells_infos[cells_infos_index++];
291 ItemTypeInfo* it = itm->typeFromId(item_type_id);
292 Integer current_cell_nb_node = it->nbLocalNode();
293 Int64ConstArrayView current_cell_node_uids(current_cell_nb_node,&cells_infos[cells_infos_index]);
294 Integer current_cell_nb_face = it->nbLocalFace();
295 for (Integer face_in_cell_index = 0; face_in_cell_index < current_cell_nb_face; ++face_in_cell_index)
296 {
297 const ItemTypeInfo::LocalFace& current_face = it->localFace(face_in_cell_index);
298 Integer current_face_nb_node = current_face.nbNode();
299 work_face_orig_nodes.resize(current_face_nb_node);
300 work_face_sorted_nodes.resize(current_face_nb_node);
301 Integer i = 0;
302 for (Integer node_in_face_index = 0; node_in_face_index < current_face_nb_node; ++node_in_face_index)
303 {
304 work_face_orig_nodes[i++] = current_cell_node_uids[current_face.node(node_in_face_index)];
305 }
306 mesh_utils::reorderNodesOfFace(work_face_orig_nodes,work_face_sorted_nodes);
307 // get face uid: we shouldn't have to guess, it should be given in arguments...
308 Int64 current_face_uid = _findFaceUniqueId(work_face_sorted_nodes,face_nodes_set);
309 if (current_face_uid == NULL_ITEM_ID) // face not already known add to face info
310 {
311 current_face_uid = m_face_uid_pool++;
312 faces_infos.add(current_face.typeId()); // face info type
313 faces_infos.add(current_face_uid); // face info uid
314 faces_infos.addRange(work_face_sorted_nodes); // face info node uids
315 _addFaceNodes(face_nodes_set,work_face_sorted_nodes,current_face_uid);
316 ++nb_face;
317 }
318 cell_to_face_connectivity_info[current_cell_unique_id].add(current_face_uid);
319 }
320 cells_infos_index += current_cell_nb_node;
321 }
322}
323
324/*---------------------------------------------------------------------------*/
325
326void DynamicMeshIncrementalBuilder::
327_fillEdgeInfo(Integer& nb_edge, Integer nb_face,Int64Array& edges_infos,
328 Int64ConstArrayView faces_infos,std::map<std::pair<Int64,Int64>, Int64>& edge_uid_map)
329{
330 edges_infos.reserve(2*faces_infos.size());
331 ItemTypeMng* itm = m_item_type_mng;
332 Integer faces_infos_index = 0;
333 nb_edge = 0;
334 for (Integer i_face = 0; i_face < nb_face; ++i_face) {
335 Integer item_type_id = (Integer)faces_infos[faces_infos_index++]; // face type
336 ++faces_infos_index;// face uid (unused)
337 ItemTypeInfo* it = itm->typeFromId(item_type_id);
338 Integer current_face_nb_node = it->nbLocalNode();
339 Int64ConstArrayView current_face_node_uids(current_face_nb_node,&faces_infos[faces_infos_index]);
340 Integer current_face_nb_edge = it->nbLocalEdge();
341 for (Integer edge_in_face_index = 0; edge_in_face_index < current_face_nb_edge; ++edge_in_face_index)
342 {
343 const ItemTypeInfo::LocalEdge& current_edge = it->localEdge(edge_in_face_index);
344 Int64 first_node = current_face_node_uids[current_edge.beginNode()];
345 Int64 second_node = current_face_node_uids[current_edge.endNode()];
346 if (first_node > second_node) std::swap(first_node,second_node);
347 auto edge_it = edge_uid_map.insert(std::make_pair(std::make_pair(first_node,second_node), m_edge_uid_pool));
348 if (edge_it.second)
349 {
350 edges_infos.add(m_edge_uid_pool); // edge uid
351 edges_infos.add(first_node); // first node uid
352 edges_infos.add(second_node); // second node uid
353 ++nb_edge;
355 }
356 }
357 faces_infos_index += current_face_nb_node;
358 }
359}
360
361/*---------------------------------------------------------------------------*/
362
363void DynamicMeshIncrementalBuilder::
364_fillNodeInfo(Integer& nb_node, Integer nb_face,Int64Array& nodes_infos, Int64ConstArrayView faces_infos)
365{
366 nodes_infos.reserve(faces_infos.size());
367 Integer faces_infos_index = 0;
368 std::set<Int64> nodes_set;
369 ItemTypeMng* itm = m_item_type_mng;
370 for (Integer i_face = 0; i_face < nb_face; ++i_face) {
371 Int32 type_id = CheckedConvert::toInt32(faces_infos[faces_infos_index++]);
372 Integer current_face_nb_node = itm->typeFromId(type_id)->nbLocalNode(); // face type
373 ++faces_infos_index;//face_uid (unused)
374 for (auto node_uid : faces_infos.subConstView(faces_infos_index,current_face_nb_node)) {
375 nodes_set.insert(node_uid);
376 }
377 faces_infos_index+=current_face_nb_node;
378 }
379 nb_node = CheckedConvert::toInteger(nodes_set.size());
380 for (auto node_uid : nodes_set) {
381 nodes_infos.add(node_uid);
382 }
383}
384
385/*---------------------------------------------------------------------------*/
386
387void DynamicMeshIncrementalBuilder::
388_fillNodeInfoFromEdge(Integer& nb_node, Integer nb_edge, Int64Array& nodes_infos, Int64ConstArrayView edges_infos)
389{
390 nodes_infos.reserve(2*edges_infos.size());
391 Integer edges_infos_index = 0;
392 std::set<Int64> nodes_set;
393 for (Integer i_edge = 0; i_edge < nb_edge; ++i_edge) {
394 ++edges_infos_index;//edge_uid (unused)
395 nodes_set.insert(edges_infos[edges_infos_index++]);
396 nodes_set.insert(edges_infos[edges_infos_index++]);
397 }
398 nb_node = CheckedConvert::toInteger(nodes_set.size());
399 for (auto node_uid : nodes_set) {
400 nodes_infos.add(node_uid);
401 }
402}
403/*---------------------------------------------------------------------------*/
404
405void DynamicMeshIncrementalBuilder::
406_fillCellNewInfoNew(Integer nb_cell,Int64ConstArrayView cells_infos,Int64Array& cell_infos2,
407 const std::map<Int64,Int64SharedArray>& cell_to_face_connectivity_info, const std::map<std::pair<Int64,Int64>, Int64>& edge_uid_map)
408{
409 Integer cell_infos2_size_approx = 1 + 3 * (cells_infos.size()+ 2*nb_cell); // supposes as many faces as nodes as edges...
410 cell_infos2.reserve(cell_infos2_size_approx);
411 ItemTypeMng* itm = m_item_type_mng;
412 Integer cells_infos_index = 0;
413 Integer nb_connected_families = hasEdge() ? 3 : 2;
414 cell_infos2.add(nb_connected_families); // nb_connected_families (node and face +/- edge)
415 for (Integer i_cell = 0; i_cell < nb_cell; ++i_cell) {
416 Integer item_type_id = (Integer)cells_infos[cells_infos_index];
417 cell_infos2.add(cells_infos[cells_infos_index++]); // cell type
418 Int64 current_cell_uid = cells_infos[cells_infos_index];
419 cell_infos2.add(cells_infos[cells_infos_index++]); // cell uid
420 ItemTypeInfo* it = itm->typeFromId(item_type_id);
421 //--- Cell node connectivity
422 cell_infos2.add(mesh()->nodeFamily()->itemKind()); // connected_family_id: node family
423 Integer current_cell_nb_node = it->nbLocalNode();
424 cell_infos2.add(current_cell_nb_node); // nb_connected_nodes
425 Int64ConstArrayView current_cell_node_uids(current_cell_nb_node,&cells_infos[cells_infos_index]);
426 cell_infos2.addRange(current_cell_node_uids); // node ids
427 //--- Cell face connectivity
428 cell_infos2.add(mesh()->faceFamily()->itemKind()); // connected_family_id: face family
429 Integer current_cell_nb_face = it->nbLocalFace();
430 cell_infos2.add(current_cell_nb_face); // nb_connected_faces
431 Int64ArrayView current_cell_faces = cell_to_face_connectivity_info.find(current_cell_uid)->second.view();
432 if (current_cell_nb_face != current_cell_faces.size())
433 ARCANE_FATAL("Incoherent number of faces for cell {0}. Expected {1} found {2}",
434 current_cell_uid,current_cell_nb_face,current_cell_faces.size());
435 cell_infos2.addRange(current_cell_faces); // face ids
436 //-- Cell edge connectivity
437 if (hasEdge())
438 {
439 cell_infos2.add(mesh()->edgeFamily()->itemKind()); // connected_family_id: edge family
440 Integer current_cell_nb_edge = it->nbLocalEdge();
441 cell_infos2.add(current_cell_nb_edge); // nb_connected_edges
442 for (int edge_index = 0; edge_index < current_cell_nb_edge; ++edge_index) {
443 Int64 first_node = current_cell_node_uids[it->localEdge(edge_index).beginNode()];
444 Int64 second_node = current_cell_node_uids[it->localEdge(edge_index).endNode()];
445 if (first_node > second_node) std::swap(first_node,second_node);// edge may be oriented negatively in the cell
446 auto edge_it = edge_uid_map.find(std::make_pair(first_node,second_node));
447 if (edge_it == edge_uid_map.end())
448 ARCANE_FATAL("Do not find edge with nodes {0}-{1} in edge uid map. Exiting",
449 current_cell_node_uids[it->localEdge(edge_index).beginNode()],
450 current_cell_node_uids[it->localEdge(edge_index).endNode()]);
451 cell_infos2.add(edge_it->second);
452 }
453 }
454 cells_infos_index += current_cell_nb_node;
455 }
456}
457
458
459/*---------------------------------------------------------------------------*/
460/*---------------------------------------------------------------------------*/
461
462void DynamicMeshIncrementalBuilder::
463_fillCellInfo2(Integer nb_cell,Int64ConstArrayView cells_infos,Int64Array& cell_infos2,
464 Integer& nb_face, Int64Array& faces_infos, Int64Array& node_uids, bool allow_build_face)
465{
466 Integer cell_infos2_size_approx = 1 + 2 * (cells_infos.size()+ 2*nb_cell); // supposes as many faces as nodes...
467 cell_infos2.reserve(cell_infos2_size_approx);
468 // Fill infos
469 ItemTypeMng* itm = m_item_type_mng;
470 Integer cells_infos_index = 0;
471 cell_infos2.add(2); // nb_connected_families (node and face)
472
473 nb_face = 0;
474 faces_infos.reserve(2*cells_infos.size());
475 Int64UniqueArray work_face_sorted_nodes;
476 Int64UniqueArray work_face_orig_nodes;
477 NodeInFaceSet face_nodes_set;
478 std::set<Int64> node_uid_set;
479 // Fill face_infos2 from faces_infos
480 for (Integer i_cell = 0; i_cell < nb_cell; ++i_cell) {
481
482 Integer item_type_id = (Integer)cells_infos[cells_infos_index];
483 cell_infos2.add(cells_infos[cells_infos_index++]); // cell type
484 cell_infos2.add(cells_infos[cells_infos_index++]); // cell uid
485 cell_infos2.add(mesh()->nodeFamily()->itemKind()); // connected_family_id: node family
486
487 ItemTypeInfo* it = itm->typeFromId(item_type_id);
488 // Cell node connectivity
489 Integer current_cell_nb_node = it->nbLocalNode();
490 cell_infos2.add(current_cell_nb_node); // nb_connected_nodes
491 Int64ConstArrayView current_cell_node_uids(current_cell_nb_node,&cells_infos[cells_infos_index]);
492 cell_infos2.addRange(current_cell_node_uids); // node ids
493 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
494 // cell face connectivity
495 cell_infos2.add(mesh()->faceFamily()->itemKind()); // connected_family_id: face family
496 Integer current_cell_nb_face = it->nbLocalFace();
497 cell_infos2.add(current_cell_nb_face); // nb_connected_faces
498 for (Integer face_in_cell_index = 0; face_in_cell_index < current_cell_nb_face; ++face_in_cell_index)
499 {
500 ItemTypeInfo::LocalFace current_face = it->localFace(face_in_cell_index);
501 Integer current_face_nb_node = current_face.nbNode();
502 work_face_orig_nodes.resize(current_face_nb_node);
503 work_face_sorted_nodes.resize(current_face_nb_node);
504 Integer i = 0;
505 for (Integer node_in_face_index = 0; node_in_face_index < current_face_nb_node; ++node_in_face_index)
506 {
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 {
527 node_uids.resize(node_uid_set.size());
528 Integer index = 0;
529 for (Int64 node_uid : node_uid_set) node_uids[index++] = node_uid;
530 }
531}
532
533/*---------------------------------------------------------------------------*/
534
535void DynamicMeshIncrementalBuilder::
536_initFaceRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView faces_info)
537{
538 _fillFaceRelationInfo(source_item_relation_data,target_item_dependencies_data,faces_info,true);
539}
540
541
542/*---------------------------------------------------------------------------*/
543
544void DynamicMeshIncrementalBuilder::
545_appendFaceRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView faces_info)
546{
547 _fillFaceRelationInfo(source_item_relation_data,target_item_dependencies_data,faces_info,false);
548}
549
550/*---------------------------------------------------------------------------*/
551
552void DynamicMeshIncrementalBuilder::
553_fillFaceRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data,
554 Int64ConstArrayView faces_info, bool is_source_relation_data_empty)
555{
556 // face_infos = [{face_type, face_uid, {face_node_uids}]
557 Int64UniqueArray face_uids_and_types;
558 face_uids_and_types.reserve(2*source_item_relation_data.nbItems());
559 ItemTypeMng* itm = m_item_type_mng;
560 for (Integer face_info_index = 0; face_info_index < faces_info.size();) {
561 face_uids_and_types.add(faces_info[face_info_index+1]); // face_uid
562 face_uids_and_types.add(faces_info[face_info_index]); // face_type
563 Integer type_id = CheckedConvert::toInteger(face_uids_and_types.back());
564 face_info_index += (2+itm->typeFromId(type_id)->nbLocalNode());// increment and skip info (first & second_node_uid)
565 }
566 _fillItemRelationInfo(source_item_relation_data,target_item_dependencies_data,face_uids_and_types, is_source_relation_data_empty);
567}
568
569/*---------------------------------------------------------------------------*/
570
571void DynamicMeshIncrementalBuilder::
572_initEdgeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView edges_info)
573{
574 _fillEdgeRelationInfo(source_item_relation_data,target_item_dependencies_data,edges_info,true);
575}
576
577
578/*---------------------------------------------------------------------------*/
579
580void DynamicMeshIncrementalBuilder::
581_appendEdgeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView edges_info)
582{
583 _fillEdgeRelationInfo(source_item_relation_data,target_item_dependencies_data,edges_info,false);
584}
585
586
587/*---------------------------------------------------------------------------*/
588
589void DynamicMeshIncrementalBuilder::
590_fillEdgeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data,
591 Int64ConstArrayView edges_info, bool is_source_relation_data_empty)
592{
593 // edge_infos = [{edge_uid, first_node_uid, second_node_uid}
594 ARCANE_ASSERT((source_item_relation_data.nbItems()*3 == edges_info.size()),("source_item_relation_data and edges_info size incoherent. Exiting."));
595 Int64UniqueArray edge_uids_and_types;
596 edge_uids_and_types.reserve(2*source_item_relation_data.nbItems());
597 for (Integer edge_info_index = 0; edge_info_index < edges_info.size();) {
598 edge_uids_and_types.add(edges_info[edge_info_index++]); // edge_uid
599 edge_uids_and_types.add(IT_Line2); // edge_type
600 edge_info_index+=2;// skip info (first & second_node_uid)
601 }
602 _fillItemRelationInfo(source_item_relation_data,target_item_dependencies_data,edge_uids_and_types, is_source_relation_data_empty);
603}
604
605/*---------------------------------------------------------------------------*/
606
607void DynamicMeshIncrementalBuilder::
608_initNodeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView nodes_info)
609{
610 _fillNodeRelationInfo(source_item_relation_data,target_item_dependencies_data,nodes_info,true);
611}
612
613
614/*---------------------------------------------------------------------------*/
615
616void DynamicMeshIncrementalBuilder::
617_appendNodeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView nodes_info)
618{
619 _fillNodeRelationInfo(source_item_relation_data,target_item_dependencies_data,nodes_info,false);
620}
621
622/*---------------------------------------------------------------------------*/
623
624void DynamicMeshIncrementalBuilder::
625_fillNodeRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data, Int64ConstArrayView nodes_info, bool is_source_relation_data_empty){
626 // nodes_info = [node_uids]
627 ARCANE_ASSERT((source_item_relation_data.nbItems() == nodes_info.size()),("source_item_relation_data and nodes_info size incoherent. Exiting."));
628 Int64UniqueArray node_uids_and_types(2*nodes_info.size());
629 for (Integer node_index = 0; node_index < nodes_info.size(); ++node_index) {
630 node_uids_and_types[2*node_index] = nodes_info[node_index];
631 node_uids_and_types[2*node_index+1] = IT_Vertex;
632 }
633 _fillItemRelationInfo(source_item_relation_data,target_item_dependencies_data,node_uids_and_types, is_source_relation_data_empty);
634}
635
636
637/*---------------------------------------------------------------------------*/
638
639void DynamicMeshIncrementalBuilder::
640_fillItemRelationInfo(ItemData& source_item_relation_data, const ItemData& target_item_dependencies_data,
641 Int64ConstArrayView source_item_uids_and_types,
642 bool is_source_item_relation_data_empty)
643{
644 ARCANE_ASSERT((source_item_relation_data.nbItems()*2 == source_item_uids_and_types.size()),
645 ("source item number incoherent between source_item_relation_data and source_item_uids_and_types. Exiting."));
646 // Fill an ItemData containing source to target relations (target to source relations are included in target_item_data)
647 auto & source_relation_info = source_item_relation_data.itemInfos();
648 const auto & target_dependencies_info = target_item_dependencies_data.itemInfos();
649 auto source_family = source_item_relation_data.itemFamily();
650 auto target_family = target_item_dependencies_data.itemFamily();
651 if (! source_family || !target_family) return;
652 std::map<Int64, Int64SharedArray> source_to_target_uids;
653 Integer nb_families_connected_to_target = CheckedConvert::toInteger(target_dependencies_info[0]);
654 Integer target_info_index = 1; // 0 is nb_connected_families
655
656 // Fill map source to target traversing target_item_dependencies_data
657 for (; target_info_index < target_dependencies_info.size();) {
658 target_info_index++; // current target item_type
659 Int64 target_item_uid = target_dependencies_info[target_info_index++];// current target item uid
660 for (Integer family_connected_to_target = 0; family_connected_to_target < nb_families_connected_to_target; ++family_connected_to_target) {
661 Int64 family_connected_to_target_kind = target_dependencies_info[target_info_index++];// current target item connected family kind
662 if (family_connected_to_target_kind != source_family->itemKind()) {//this connection info does not concern source family. Skip
663 Integer nb_non_read_values = CheckedConvert::toInteger(target_dependencies_info[target_info_index++]); // nb_connected_item on this other family (/= to source family)
664 target_info_index+= nb_non_read_values;
665 continue;
666 }
667 else {
668 Int32 nb_source_item_connected_to_target_item = CheckedConvert::toInt32(target_dependencies_info[target_info_index++]);
669 for (Integer source_item_index = 0; source_item_index < nb_source_item_connected_to_target_item; ++source_item_index) {
670 source_to_target_uids[target_dependencies_info[source_item_index+target_info_index]].add(target_item_uid);
671 }
672 target_info_index += nb_source_item_connected_to_target_item;
673 }
674 }
675 }
676 // Fill or append source_item_relation_data traversing the map source_to_target_connectivity
677 if (is_source_item_relation_data_empty) _initEmptyRelationInfo(source_relation_info, source_to_target_uids, source_item_uids_and_types,
678 target_dependencies_info.size(), target_family);
679 else _appendInitializedRelationInfo(source_relation_info, source_to_target_uids, source_item_uids_and_types,
680 target_dependencies_info.size(), target_family);
681
682}
683
684/*---------------------------------------------------------------------------*/
685
686void DynamicMeshIncrementalBuilder::
687_initEmptyRelationInfo(Int64Array& source_relation_info, std::map<Int64, Int64SharedArray>& source_to_target_uids, Int64ConstArrayView source_item_uids_and_types,
688 Integer approx_relation_size,
689 IItemFamily const * target_family)
690{
691 if (! source_relation_info.empty()) source_relation_info.clear();
692 source_relation_info.reserve(approx_relation_size); // clearly too much elements...but only available info. Do better ?
693 source_relation_info.add(1);// nb_connected_families
694 // Fill source_item_relation_data
695 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) {
696 Int64 source_item_uid = source_item_uids_and_types[source_item_uids_and_types_index];
697 source_relation_info.add(source_item_uids_and_types[source_item_uids_and_types_index+1]); // item type
698 source_relation_info.add(source_item_uid); // item uid
699 source_relation_info.add(target_family->itemKind());// connected family kind
700 auto & connected_items = source_to_target_uids[source_item_uid];
701 source_relation_info.add(connected_items.size());// nb_connected_item
702 source_relation_info.addRange(connected_items.view()); // connected_items uids
703 }
704}
705
706/*---------------------------------------------------------------------------*/
707
708void DynamicMeshIncrementalBuilder::
709_appendInitializedRelationInfo(Int64Array& source_relation_info, std::map<Int64, Int64SharedArray>& source_to_target_uids, Int64ConstArrayView source_item_uids_and_types,
710 Integer approx_relation_size,
711 IItemFamily const * target_family)
712{
713 // Create a working array to build the consolidated info. This array will be copied in to source_relation_info at the end.
714 Int64UniqueArray source_relation_info_wrk_copy;
715 source_relation_info_wrk_copy.reserve(source_relation_info.size()+approx_relation_size);
716 std::set<Int64> treated_items;// To detect eventual source_items not already present in source_relation_info
717 Integer source_relation_info_index = 0;
718 Integer nb_connected_family = CheckedConvert::toInteger(source_relation_info[source_relation_info_index++]);
719 source_relation_info_wrk_copy.add(nb_connected_family+1); // adding a new connected family
720 for(; source_relation_info_index < source_relation_info.size() ;){
721 source_relation_info_wrk_copy.add(source_relation_info[source_relation_info_index++]); // item type
722 Int64 source_item_uid = source_relation_info[source_relation_info_index++]; // get item uid
723 source_relation_info_wrk_copy.add(source_item_uid);
724 treated_items.insert(source_item_uid);
725 for (Integer connected_family_index = 0; connected_family_index < nb_connected_family; ++connected_family_index) {
726 source_relation_info_wrk_copy.add(source_relation_info[source_relation_info_index++]); // family kind
727 Integer nb_connected_elements = CheckedConvert::toInteger(source_relation_info[source_relation_info_index++]); // nb connected elements
728 source_relation_info_wrk_copy.add(nb_connected_elements);
729 source_relation_info_wrk_copy.addRange(source_relation_info.subConstView(source_relation_info_index,nb_connected_elements));
730 source_relation_info_index += nb_connected_elements;
731 }
732 // Add new connection info
733 source_relation_info_wrk_copy.add(target_family->itemKind()); // family kind
734 const auto& connected_items = source_to_target_uids[source_item_uid]; // get connected items
735 source_relation_info_wrk_copy.add(connected_items.size()); // nb connected elements
736 source_relation_info_wrk_copy.addRange(connected_items);
737 }
738 // Find eventual source_items not already present in source_relation_info : todo check this can happen
739 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) {
740 Int64 source_item_uid = source_item_uids_and_types[source_item_uids_and_types_index];
741 if (treated_items.find(source_item_uid) == treated_items.end()){
742 source_relation_info_wrk_copy.add(source_item_uids_and_types[source_item_uids_and_types_index+1]); // item type
743 source_relation_info_wrk_copy.add(source_item_uid); // item uid
744 source_relation_info_wrk_copy.add(target_family->itemKind()); // family kind
745 const auto& connected_items = source_to_target_uids[source_item_uid]; // get connected items
746 source_relation_info_wrk_copy.add(connected_items.size()); // nb connected elements
747 source_relation_info_wrk_copy.addRange(connected_items);
748 // Padd this item info with family info : we added only one family, add void values for the other nb_connected_family families
749 for (Integer connected_family_index = 0; connected_family_index < nb_connected_family; ++connected_family_index) {
750 source_relation_info_wrk_copy.add(0); // family id (does not matter)
751 source_relation_info_wrk_copy.add(0); // nb_connected_elements for this family
752 }
753 }
754 }
755 // Copy working array into destination array
756 source_relation_info.resize(source_relation_info_wrk_copy.size());
757 std::copy(source_relation_info_wrk_copy.begin(), source_relation_info_wrk_copy.end(), source_relation_info.begin());
758}
759
760/*---------------------------------------------------------------------------*/
761/*---------------------------------------------------------------------------*/
762
763Int64 DynamicMeshIncrementalBuilder::
764_findFaceUniqueId(Int64ConstArrayView work_face_sorted_nodes, NodeInFaceSet& face_nodes_set)
765{
766 // check if first node exist
767 Integer index = 0;
768// return _findFaceInFaceNodesSet(face_nodes_set,index,work_face_sorted_nodes,std::make_shared<NodeInFace>(NULL_ITEM_ID));
769 return _findFaceInFaceNodesSet(face_nodes_set,index,work_face_sorted_nodes,NodeInFacePtr(NULL_ITEM_ID));
770}
771
772/*---------------------------------------------------------------------------*/
773
774Int64 DynamicMeshIncrementalBuilder::
775_findFaceInFaceNodesSet(const NodeInFaceSet& face_nodes_set,Integer index,Int64ConstArrayView face_nodes, NodeInFacePtr node)
776{
777 if (index < face_nodes.size())
778 {
779 auto found_node = std::find(face_nodes_set.begin(),face_nodes_set.end(),NodeInFacePtr(face_nodes[index]));
780 if (found_node == face_nodes_set.end()) return node->faceUid();
781 else return _findFaceInFaceNodesSet((*found_node)->nextNodeSet(),++index,face_nodes,*found_node);
782 }
783 else return node->faceUid();
784}
785
786/*---------------------------------------------------------------------------*/
787
788void DynamicMeshIncrementalBuilder::
789_addFaceNodes(NodeInFaceSet& face_nodes_set, Int64ConstArrayView face_nodes, Int64 face_uid)
790{
791 Integer index = 0;
792// _addFaceInFaceNodesSet(face_nodes_set, index,face_nodes, std::make_shared<NodeInFace>(NULL_ITEM_ID), face_uid);
793 _addFaceInFaceNodesSet(face_nodes_set, index,face_nodes, NodeInFacePtr(NULL_ITEM_ID), face_uid);
794}
795
796/*---------------------------------------------------------------------------*/
797
798void DynamicMeshIncrementalBuilder::
799_addFaceInFaceNodesSet(NodeInFaceSet& face_nodes_set,Integer index,Int64ConstArrayView face_nodes, NodeInFacePtr node, Int64 face_uid)
800{
801 if (index < face_nodes.size())
802 {
803// auto next_node = std::make_shared<NodeInFace>(face_nodes[index]);
804 auto next_node = _insertNode(face_nodes_set,face_nodes[index]);
805// debug() << "Add node " << face_nodes[index] << " in set " << &face_nodes_set;
806// debug() << "set size " << face_nodes_set.size();
807 _addFaceInFaceNodesSet(next_node->nextNodeSet(),++index,face_nodes,next_node,face_uid);
808// else
809// _addFaceInFaceNodesSet((*insertion_return.first)->nextNodeSet(),++index,face_nodes,*insertion_return.first,face_uid); // pbe du const. Change from set to map ?
810 }
811 else
812 {
813 node->setFaceUid(face_uid);
814// debug() << "Set face uid " << face_uid << " for node " << node->m_uid;
815 }
816}
817
818DynamicMeshIncrementalBuilder::NodeInFacePtr&
819DynamicMeshIncrementalBuilder::_insertNode(NodeInFaceSet& face_nodes_set, Int64 inserted_node_uid)
820{
821 NodeInFacePtr new_node(inserted_node_uid);
822 auto found_node = std::find(face_nodes_set.begin(),face_nodes_set.end(),new_node);
823 if (found_node == face_nodes_set.end()) {
824 face_nodes_set.push_back(std::move(new_node));
825 return face_nodes_set.back();
826 }
827 else return *found_node;
828}
829
830/*---------------------------------------------------------------------------*/
831/*---------------------------------------------------------------------------*/
839addParentCells(const ItemVectorView & items)
840{
841 const Integer nb_cell = items.size();
842
843 for( Integer i_cell=0; i_cell<nb_cell; ++i_cell ){
845 }
846}
847
848/*---------------------------------------------------------------------------*/
849/*---------------------------------------------------------------------------*/
850
861 Integer sub_domain_id,Int32ArrayView cells,
862 bool allow_build_face)
863{
864 ItemTypeMng* itm = m_item_type_mng;
865 CellFamily& cell_family = m_mesh->trueCellFamily();
866
867 debug() << "[DynamicMeshIncrementalBuilder::addHChildrenCells] ADD CELLS mesh=" << m_mesh->name() << " nb_cell=" << nb_cell;
868 Integer cells_infos_index = 0;
869 bool add_to_cells = cells.size()!=0;
870 if (add_to_cells && nb_cell!=cells.size())
871 throw ArgumentException(A_FUNCINFO,
872 "return array 'cells' has to have same size as number of cells");
873 for( Integer i_cell=0; i_cell<nb_cell; ++i_cell ){
874 debug(Trace::Highest)<<"\t\t[DynamicMeshIncrementalBuilder::addHChildrenCells]cell "<<i_cell<<"/"<<nb_cell;
875
876 ItemTypeId item_type_id { (Int16)cells_infos[cells_infos_index] };
877 debug(Trace::Highest)<<"\t\t[DynamicMeshIncrementalBuilder::addHChildrenCells]cells_infos["<<cells_infos_index<<"]="<<cells_infos[cells_infos_index]<<", type_id="<<item_type_id;
879
880 Int64 cell_unique_id = cells_infos[cells_infos_index];
881 debug(Trace::Highest)<<"\t\t[DynamicMeshIncrementalBuilder::addHChildrenCells]cells_infos["<<cells_infos_index<<"]="<<cells_infos[cells_infos_index]<<", uid="<<cell_unique_id;
883
884 ItemTypeInfo* it = itm->typeFromId(item_type_id);
885 Integer current_cell_nb_node = it->nbLocalNode();
886 debug(Trace::Highest) << "\t\t[DynamicMeshIncrementalBuilder::addHChildrenCells]DM ADD_CELL uid=" << cell_unique_id << " type_id=" << item_type_id
887 << " nb_node=" << current_cell_nb_node;
889 for( Integer i=0; i<current_cell_nb_node; ++i )
890 debug(Trace::Highest) << "\t\t\t[DynamicMeshIncrementalBuilder::addHChildrenCells]DM NODE uid=" << current_cell_nodes_uid[i];
891
897
898 cell_family._addParentCellToCell(cell,hParent_cell);
899 if (add_to_cells)
900 cells[i_cell] = cell->localId();
902 }
903 cell_family._addChildrenCellsToCell(hParent_cell,cells);
904
905 debug() << "[DynamicMeshIncrementalBuilder::addHChildrenCells] done";
906}
907
908/*---------------------------------------------------------------------------*/
909/*---------------------------------------------------------------------------*/
918{
919 const Integer nb_item = items.size();
920
921 for( Integer i_item=0; i_item<nb_item; ++i_item ) {
923 }
924}
925
926/*---------------------------------------------------------------------------*/
927/*---------------------------------------------------------------------------*/
937{
938 Integer nb_node_to_add = nodes_uid.size();
939 bool add_to_nodes = nodes.size()!=0;
940 if (add_to_nodes && nb_node_to_add!=nodes.size())
941 throw ArgumentException(A_FUNCINFO,
942 "return array 'nodes' has to have same size as number of nodes");
943 for( Integer i_node=0; i_node<nb_node_to_add; ++i_node ){
944 ItemInternal* node = m_one_mesh_item_adder->addOneNode(nodes_uid[i_node],owner);
945 if (add_to_nodes)
946 nodes[i_node] = node->localId();
947 }
948}
949
950/*---------------------------------------------------------------------------*/
951/*---------------------------------------------------------------------------*/
961{
962 Integer nb_node_to_add = nodes_uid.size();
963 bool add_to_nodes = nodes.size()!=0;
964 if (add_to_nodes && nb_node_to_add!=nodes.size())
965 throw ArgumentException(A_FUNCINFO,
966 "return array 'nodes' has to have same size as number of nodes");
968 ItemData& node_data = item_info_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()),
969 nb_node_to_add,2*nb_node_to_add+1,nodes,&mesh()->trueNodeFamily(),&mesh()->trueNodeFamily(),owner);
970 Int64Array& node_infos2 = node_data.itemInfos();
971 // Copy node_info : to decrease the footprint of the copy, use references instead of int64
972 _fillNodeNewInfo(nodes_uid,node_infos2);
973
975 }
976
977/*---------------------------------------------------------------------------*/
978/*---------------------------------------------------------------------------*/
979
980void DynamicMeshIncrementalBuilder::
982{
983 node_infos2[0] = 0; // nb_connected_families
984 Integer index = 0;
985 for (auto node_uid : node_uids)
986 {
987 node_infos2[2*index+1] = IT_Vertex; // type
988 node_infos2[2*index+2] = node_uid; // id
989 index++;
990 }
991}
992
993/*---------------------------------------------------------------------------*/
994/*---------------------------------------------------------------------------*/
1016{
1017 // Add items : item construction done from leaves to root
1018 _addItemsOrRelations(item_info_list,IItemFamilyNetwork::InverseTopologicalOrder);
1019}
1020
1021/*---------------------------------------------------------------------------*/
1022
1025{
1026 if (item_info_list.size() == 0 || item_relation_info_list.size() == 0) return;
1028 addRelations(item_relation_info_list);
1029}
1030
1031/*---------------------------------------------------------------------------*/
1032
1033void DynamicMeshIncrementalBuilder::
1034addRelations(ItemDataList& item_relation_list)
1035{
1036 // Add relations : items are already added. Do it from root to leaves
1037 _addItemsOrRelations(item_relation_list,IItemFamilyNetwork::TopologicalOrder);
1038}
1039
1040/*---------------------------------------------------------------------------*/
1041
1042void DynamicMeshIncrementalBuilder::
1043_addItemsOrRelations(ItemDataList& info_list, IItemFamilyNetwork::eSchedulingOrder family_graph_traversal_order)
1044{
1045 // Add relations : items are already added. Do it from root to leaves
1046 if (info_list.size() == 0) return;
1047 m_mesh->itemFamilyNetwork()->schedule([&](IItemFamily* family){
1048 ItemData i_infos = info_list[family->itemKind()];
1049 this->addFamilyItems(i_infos);
1050 },
1051 family_graph_traversal_order); // item construction done from leaves to root
1052}
1053
1054/*---------------------------------------------------------------------------*/
1055/*---------------------------------------------------------------------------*/
1063{
1064 if (item_data.nbItems() == 0) return;
1065 bool add_to_items = item_data.itemLids().size()!=0;
1066 if (add_to_items && item_data.nbItems()!= item_data.itemLids().size())
1067 throw ArgumentException(A_FUNCINFO,
1068 "return array containing item lids has to have be of size number of items");
1069 // Prepare info and call OneMeshItemAdder->addOneItem
1070 Int64 item_uid;
1073 if(nb_connected_family == 0)
1074 return ;
1076 Integer nb_item_info = 0;
1077 Integer item_index = 0;
1078 for (Integer info_index = 1; info_index < item_data.itemInfos().size();){
1079 ItemTypeId item_type_id { (Int16)item_infos[info_index++] }; // item_type
1080 item_uid = item_infos[info_index++]; // item_uid
1085 nb_item_info += nb_item_info_increment; // family_id , nb_connected_elements
1086 info_index+= nb_item_info_increment; // pointing on next family id
1087 }
1088 ItemInternal* item = m_one_mesh_item_adder->addOneItem2(item_data.itemFamily(),
1089 item_data.itemFamilyModifier(),
1091 item_uid,
1092 item_data.itemOwners()[item_index],
1093 item_data.subDomainId(),
1096 if (add_to_items)
1097 item_data.itemLids()[item_index++] = item->localId();
1098 nb_item_info = 0;
1099 }
1100}
1101
1102/*---------------------------------------------------------------------------*/
1103/*---------------------------------------------------------------------------*/
1113addFaces(Integer nb_face,Int64ConstArrayView faces_infos,
1114 Int32 rank, Int32ArrayView faces)
1115{
1116 ItemTypeMng* itm = m_item_type_mng;
1117
1118 bool add_to_faces = faces.size()!=0;
1119 if (add_to_faces && nb_face!=faces.size())
1120 throw ArgumentException(A_FUNCINFO,
1121 "return array 'faces' has to have same size as number of faces");
1122
1123 Integer faces_infos_index = 0;
1124 for(Integer i_face=0; i_face<nb_face; ++i_face ){
1125
1128 Int64 face_unique_id = faces_infos[faces_infos_index];
1130
1131 ItemTypeInfo* it = itm->typeFromId(item_type_id);
1132
1133 Integer current_face_nb_node = it->nbLocalNode();
1136
1138
1139 if (add_to_faces)
1140 faces[i_face] = face->localId();
1141 }
1142}
1143
1144/*---------------------------------------------------------------------------*/
1145/*---------------------------------------------------------------------------*/
1155addFaces2(Integer nb_face,Int64ConstArrayView faces_infos,
1156 Integer sub_domain_id,Int32ArrayView faces)
1157{
1158 bool add_to_faces = faces.size()!=0;
1159 if (add_to_faces && nb_face!=faces.size())
1160 throw ArgumentException(A_FUNCINFO,
1161 "return array 'faces' has to have same size as number of faces");
1162 // Prepare face infos 2
1163 Integer face_infos2_size = faces_infos.size()+ 1 + 2 * nb_face; // additive info nb_connected_family + nb_face * (family_id + nb_connected_element)
1165 ItemData& face_data = item_info_list.itemData(Integer(m_mesh->faceFamily()->itemKind()),
1166 nb_face,face_infos2_size,faces,&mesh()->trueFaceFamily(),&mesh()->trueFaceFamily(),sub_domain_id);
1167
1168 Int64ArrayView face_infos2 = face_data.itemInfos().view();
1171
1172 _fillFaceInfo2(nb_face,faces_infos,face_infos2,node_uids);
1173
1174 // Prepare edge data if needed
1175// if (m_has_edge) {
1176// Integer nb_edge_to_add = edge_uids.size();
1177// Int32UniqueArray edge_lids(nb_edge_to_add);
1178// ItemData& edge_data = item_info_list.itemData(Integer(m_mesh->edgeFamily()->itemKind()),
1179// nb_edge_to_add,2*nb_edge_to_add+1,edge_lids,&mesh()->trueNodeFamily(),&mesh()->trueNodeFamily(),sub_domain_id);
1180// Int64Array& edge_infos2 = edge_data.itemInfos();
1181// _fillEdgeInfo2(nb_edge_to_add,edge_uids,edge_infos2);
1182// }
1183
1184 // Prepare node data (mutualize)
1185 Integer nb_node_to_add = node_uids.size();
1187 ItemData& node_data = item_info_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()),
1188 nb_node_to_add,2*nb_node_to_add+1,node_lids,&mesh()->trueNodeFamily(),&mesh()->trueNodeFamily(),sub_domain_id);
1189 Int64Array& node_infos2 = node_data.itemInfos();
1190 _fillNodeNewInfo(node_uids,node_infos2);
1191
1192 // Launch node and face creation
1194}
1195
1196/*---------------------------------------------------------------------------*/
1197
1198void DynamicMeshIncrementalBuilder::
1199addFaces3(Integer nb_face,Int64ConstArrayView faces_infos,
1200 Integer sub_domain_id,Int32ArrayView faces)
1201{
1202 bool add_to_faces = faces.size()!=0;
1203 if (add_to_faces && nb_face!=faces.size())
1204 throw ArgumentException(A_FUNCINFO,
1205 "return array 'faces' has to have same size as number of faces");
1208 // item info_size cannot be guessed
1214 Integer nb_edge = 0;
1215 Integer nb_node = 0;
1216 std::map<std::pair<Int64,Int64>, Int64> edge_uid_map;
1217
1218 // Fill classical info
1219 _fillEdgeInfo(nb_edge, nb_face, edges_infos, faces_infos, edge_uid_map);
1220 _fillNodeInfo(nb_node, nb_face, nodes_infos, faces_infos);
1221
1222 // Face info New
1223 ItemData& face_data = item_data_list.itemData(Integer(m_mesh->faceFamily()->itemKind()),nb_face,0,faces,&mesh()->trueFaceFamily(),&mesh()->trueFaceFamily(),sub_domain_id);
1224 _fillFaceNewInfoNew(nb_face,faces_infos,face_data.itemInfos(),edge_uid_map);
1225
1226 // Edge info New
1227 if (hasEdge()) {
1228 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
1229 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);
1230 edge_lids.resize(item_data_list[m_mesh->edgeFamily()->itemKind()].nbItems());
1231 _fillEdgeNewInfoNew(nb_edge,edges_infos,edge_data.itemInfos()); // reprendre fillEdgeInfo et voir l'appel depuis add Edges + attention ordre des noeuds,
1232 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);
1233 _initEdgeRelationInfo(edge_relation_data,face_data, edges_infos); // edge-face relation
1234 }
1235
1236 // Node info New
1237 Integer node_info_size = 1 + nb_node*2;//New info = Nb_connected_family + for each node : type, uid (no connected family)
1238 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);
1239 node_lids.resize(item_data_list[m_mesh->nodeFamily()->itemKind()].nbItems());
1240 _fillNodeNewInfo(nodes_infos,node_data.itemInfos());
1241 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);
1242 _initNodeRelationInfo(node_relation_data,face_data, nodes_infos); // node-face relation
1243
1244
1245 // Launch node, face and edges (not compulsory) creation
1247}
1248
1249/*---------------------------------------------------------------------------*/
1250/*---------------------------------------------------------------------------*/
1251
1252void DynamicMeshIncrementalBuilder::
1253_fillFaceNewInfoNew(Integer nb_face,Int64ConstArrayView faces_infos,Int64Array& face_infos2, const std::map<std::pair<Int64,Int64>, Int64>& edge_uid_map)
1254{
1255 ItemTypeMng* itm = m_item_type_mng;
1256 Integer nb_connected_family = hasEdge() ? 2 : 1;
1257 Integer face_infos2_size_approx = 1 + 2 * (faces_infos.size()+ 2*nb_face); // supposes as many faces as edges...
1258 face_infos2.reserve(face_infos2_size_approx);
1259 Int64UniqueArray work_face_sorted_nodes;
1260 Int64UniqueArray work_face_orig_nodes;
1261 Integer faces_infos_index = 0;
1262// Integer face_infos2_index = 0;
1263 std::set<Int64> node_uids_set;
1264 face_infos2.add(nb_connected_family); // nb_connected_families nodes +/- Edges !!
1265 // Fill face_infos2 from faces_infos
1266 for(Integer i_face=0; i_face<nb_face; ++i_face ){
1267 Integer current_face_type = (Integer)faces_infos[faces_infos_index++];
1268 Integer current_face_uid = (Integer)faces_infos[faces_infos_index++];
1269 face_infos2.add(current_face_type); // type
1270 face_infos2.add(current_face_uid); // uid
1271 //--Node connectivity
1272 face_infos2.add(mesh()->nodeFamily()->itemKind()); // connected_family_id
1273 ItemTypeInfo* it = itm->typeFromId(current_face_type);
1274 Integer current_face_nb_node = it->nbLocalNode();
1275 face_infos2.add(current_face_nb_node); // nb_connected_nodes
1276 // Nodes are not necessarily sorted (if caller is addFaces...)
1277 Int64ConstArrayView current_face_node_uids(current_face_nb_node,&faces_infos[faces_infos_index]);
1278 work_face_orig_nodes.resize(current_face_nb_node);
1279 work_face_sorted_nodes.resize(current_face_nb_node);
1280 work_face_orig_nodes.copy(current_face_node_uids);
1281 mesh_utils::reorderNodesOfFace(work_face_orig_nodes,work_face_sorted_nodes);
1282 face_infos2.addRange(work_face_sorted_nodes); // connected node uids
1283 faces_infos_index += current_face_nb_node;
1284 //--Edge Connectivity
1285 if (hasEdge()){
1286 face_infos2.add(mesh()->edgeFamily()->itemKind());
1287 face_infos2.add(it->nbLocalEdge()); // nb_connected_edges
1288 for (int edge_index = 0; edge_index < it->nbLocalEdge(); ++edge_index) {
1289 Int64 first_node = work_face_sorted_nodes[it->localEdge(edge_index).beginNode()];
1290 Int64 second_node = work_face_sorted_nodes[it->localEdge(edge_index).endNode()];
1291 if (first_node > second_node) std::swap(first_node,second_node); // edge may be oriented negatively in the face
1292 auto edge_it = edge_uid_map.find(std::make_pair(first_node,second_node));
1293 if (edge_it == edge_uid_map.end())
1294 ARCANE_FATAL("Do not find edge with nodes {0}-{1} in edge uid map. Exiting",
1295 work_face_sorted_nodes[it->localEdge(edge_index).beginNode()],
1296 work_face_sorted_nodes[it->localEdge(edge_index).endNode()]);
1297 face_infos2.add(edge_it->second); // connected edge uid
1298 }
1299 }
1300 }
1301}
1302
1303/*---------------------------------------------------------------------------*/
1304
1305void DynamicMeshIncrementalBuilder::
1306_fillFaceInfo2(Integer nb_face,Int64ConstArrayView faces_infos,Int64ArrayView face_infos2, Int64Array& node_uids)
1307{
1308 ItemTypeMng* itm = m_item_type_mng;
1309 Integer faces_infos_index = 0;
1310 Integer face_infos2_index = 0;
1311 face_infos2[face_infos2_index++] = 1; // nb_connected_families (node only)
1312 Int64UniqueArray work_face_sorted_nodes;
1313 Int64UniqueArray work_face_orig_nodes;
1314 std::set<Int64> node_uids_set;
1315 // Fill face_infos2 from faces_infos
1316 for(Integer i_face=0; i_face<nb_face; ++i_face ){
1317
1318 Integer item_type_id = (Integer)faces_infos[faces_infos_index];
1319 face_infos2[face_infos2_index++] = faces_infos[faces_infos_index++]; // type
1320 face_infos2[face_infos2_index++] = faces_infos[faces_infos_index++]; // uid
1321 face_infos2[face_infos2_index++] = mesh()->nodeFamily()->itemKind(); // connected_family_id
1322
1323 ItemTypeInfo* it = itm->typeFromId(item_type_id);
1324 Integer current_face_nb_node = it->nbLocalNode();
1325 face_infos2[face_infos2_index++] = current_face_nb_node; // nb_connected_items
1326 Int64ConstArrayView current_face_node_uids(current_face_nb_node,&faces_infos[faces_infos_index]);
1327 work_face_orig_nodes.resize(current_face_nb_node);
1328 work_face_sorted_nodes.resize(current_face_nb_node);
1329 work_face_orig_nodes.copy(current_face_node_uids);
1330 mesh_utils::reorderNodesOfFace(work_face_orig_nodes,work_face_sorted_nodes);
1331 face_infos2.subView(face_infos2_index,current_face_nb_node).copy(work_face_sorted_nodes); // connected node uids
1332 faces_infos_index += current_face_nb_node;
1333 face_infos2_index += current_face_nb_node;
1334 node_uids_set.insert(current_face_node_uids.begin(),current_face_node_uids.end());
1335 }
1336 node_uids.resize(node_uids_set.size());
1337 Integer index = 0;
1338 for (Int64 node_uid : node_uids_set) node_uids[index++] = node_uid;
1339}
1340
1341/*---------------------------------------------------------------------------*/
1342/*---------------------------------------------------------------------------*/
1353 Integer sub_domain_id,Int32ArrayView edges)
1354{
1355 bool add_to_edges = edges.size()!=0;
1356 if (add_to_edges && nb_edge!=edges.size())
1357 throw ArgumentException(A_FUNCINFO,
1358 "return array 'edges' has to have same size as number of edges");
1359
1360 Integer edge_info_index = 0;
1361 for(Integer i_edge=0; i_edge<nb_edge; ++i_edge ){
1362
1365
1367 edge_info_index += 2;
1368
1370
1371 if (add_to_edges)
1372 edges[i_edge] = edge->localId();
1373 }
1374}
1375
1376/*---------------------------------------------------------------------------*/
1377/*---------------------------------------------------------------------------*/
1388 Integer sub_domain_id,Int32ArrayView edges)
1389{
1390 bool add_to_edges = edges.size()!=0;
1391 if (add_to_edges && nb_edge!=edges.size())
1392 throw ArgumentException(A_FUNCINFO,
1393 "return array 'edges' has to have same size as number of edges");
1394
1395 // Prepare face infos 2
1396 Integer edge_infos2_size = edge_infos.size()+ 1 + 2 * nb_edge; // additive info nb_connected_family + nb_face * (family_id + nb_connected_element)
1398 ItemData& edge_data = item_info_list.itemData(Integer(m_mesh->edgeFamily()->itemKind()),
1399 nb_edge,edge_infos2_size,edges,&mesh()->trueEdgeFamily(),&mesh()->trueEdgeFamily(),sub_domain_id);
1400
1401 Int64ArrayView edge_infos2 = edge_data.itemInfos().view();
1403
1404 _fillEdgeInfo2(nb_edge,edge_infos,edge_infos2,node_uids);
1405
1406 // Prepare node data (mutualize)
1407 Integer nb_node_to_add = node_uids.size();
1409 ItemData& node_data = item_info_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()),
1410 nb_node_to_add,2*nb_node_to_add+1,node_lids,&mesh()->trueNodeFamily(),&mesh()->trueNodeFamily(),sub_domain_id);
1411 Int64Array& node_infos2 = node_data.itemInfos();
1412 _fillNodeNewInfo(node_uids,node_infos2);
1413
1414 // Launch node and face creation
1416}
1417
1418void DynamicMeshIncrementalBuilder::
1419addEdges3(Integer nb_edge,Int64ConstArrayView edges_infos,
1420 Integer sub_domain_id,Int32ArrayView edges)
1421{
1422 bool add_to_edges = edges.size()!=0;
1423 if (add_to_edges && nb_edge!=edges.size())
1424 throw ArgumentException(A_FUNCINFO,
1425 "return array 'edges' has to have same size as number of edges");
1428 // item info_size cannot be guessed
1431 Integer nb_node = 0;
1432
1433 // Fill classical info
1434 _fillNodeInfoFromEdge(nb_node, nb_edge, nodes_infos, edges_infos);
1435
1436 // Edge new info : edge data stores edge uids and dependency connectivities
1437 ItemData& edge_data = item_data_list.itemData(Integer(m_mesh->edgeFamily()->itemKind()),nb_edge,0,edges,&mesh()->trueEdgeFamily(),&mesh()->trueEdgeFamily(),sub_domain_id);
1438 _fillEdgeNewInfoNew(nb_edge,edges_infos,edge_data.itemInfos());
1439
1440
1441 // Node new info & relationsm
1442 ItemData& node_data = item_data_list.itemData(Integer(m_mesh->nodeFamily()->itemKind()),nb_node,0,node_lids,&mesh()->trueNodeFamily(),&mesh()->trueNodeFamily(),sub_domain_id);
1443 node_lids.resize(nb_node);
1444 _fillNodeNewInfo(nodes_infos,node_data.itemInfos());
1445 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);
1446 _initNodeRelationInfo(node_relations_data,edge_data, nodes_infos); // node-edge relation
1447
1448
1449 // Launch node and edges creation
1451
1452}
1453
1454/*---------------------------------------------------------------------------*/
1455/*---------------------------------------------------------------------------*/
1456
1457void DynamicMeshIncrementalBuilder::
1459{
1460 Integer edges_infos_index = 0;
1461 Integer edge_infos2_index = 0;
1462 std::set<Int64> node_uids_set;
1463
1464 // Fill edge_infos2 from edges_infos
1465 edge_infos2[edge_infos2_index++] = 1; // nb_connected_families (node only)
1466
1467 for(Integer i_edge=0; i_edge<nb_edge; ++i_edge ){
1468 edge_infos2[edge_infos2_index++] = IT_Line2; // type
1470 edge_infos2[edge_infos2_index++] = mesh()->nodeFamily()->itemKind(); // connected_family_id
1471 edge_infos2[edge_infos2_index++] = 2; // nb_connected_items Attention : ordre des noeuds !! TODO
1472 edge_infos2[edge_infos2_index++] = edges_infos[edges_infos_index]; // first connected node uid
1474 edge_infos2[edge_infos2_index++] = edges_infos[edges_infos_index]; // second connected node uid
1476 }
1477 node_uids.resize(node_uids_set.size());
1478 Integer index = 0;
1479 for (Int64 node_uid : node_uids_set) node_uids[index++] = node_uid;
1480}
1481
1482void DynamicMeshIncrementalBuilder::
1483_fillEdgeNewInfoNew(Integer nb_edge,Int64ConstArrayView edges_infos,Int64ArrayView edges_new_infos)
1484{
1485 Integer edges_infos_index = 0;
1486 Integer edges_new_infos_index = 0;
1487
1488 // Fill edge_infos2 from edges_infos
1489 edges_new_infos[edges_new_infos_index++] = 1; // nb_connected_families (node only)
1490
1491 for(Integer i_edge=0; i_edge<nb_edge; ++i_edge ){
1492 edges_new_infos[edges_new_infos_index++] = IT_Line2; // type
1493 edges_new_infos[edges_new_infos_index++] = edges_infos[edges_infos_index++]; // uid
1494 edges_new_infos[edges_new_infos_index++] = mesh()->nodeFamily()->itemKind(); // connected_family_id
1495 edges_new_infos[edges_new_infos_index++] = 2; // nb_connected_items
1496 Int64 first_node = edges_infos[edges_infos_index++];
1497 Int64 second_node = edges_infos[edges_infos_index++];
1498 if (first_node > second_node) std::swap(first_node,second_node);
1499 edges_new_infos[edges_new_infos_index++] = first_node; // first connected node uid
1500 edges_new_infos[edges_new_infos_index++] = second_node; // second connected node uid
1501 }
1502}
1503
1504/*---------------------------------------------------------------------------*/
1505/*---------------------------------------------------------------------------*/
1506
1507void DynamicMeshIncrementalBuilder::
1508readFromDump()
1509{
1510 // Recalcul le max uniqueId() des faces pour savoir quelle valeur
1511 // utiliser en cas de creation de face.
1512 ItemInternalMap& faces_map = m_mesh->facesMap();
1513 Int64 max_uid = -1;
1514 faces_map.eachItem([&](Item face) {
1515 if (face.uniqueId() > max_uid)
1516 max_uid = face.uniqueId();
1517 });
1518 m_one_mesh_item_adder->setNextFaceUid(max_uid + 1);
1519
1520 if (m_has_edge) {
1521 ItemInternalMap& edges_map = m_mesh->edgesMap();
1522 Int64 max_uid = -1;
1523 edges_map.eachItem([&](Item edge) {
1524 if (edge.uniqueId() > max_uid)
1525 max_uid = edge.uniqueId();
1526 });
1527 m_one_mesh_item_adder->setNextEdgeUid(max_uid + 1);
1528 }
1529
1530 info(5) << "NEXT FACE UID mesh=" << m_mesh->name() << " Next=" << m_one_mesh_item_adder->nextFaceUid();
1531 info(5) << "NEXT EDGE UID mesh=" << m_mesh->name() << " Next=" << m_one_mesh_item_adder->nextEdgeUid();
1532}
1533
1534/*---------------------------------------------------------------------------*/
1535/*---------------------------------------------------------------------------*/
1536
1537void DynamicMeshIncrementalBuilder::
1538printInfos()
1539{
1540 info() << "-- Mesh information (Arcane2):";
1541 info() << "Number of nodes " << m_one_mesh_item_adder->nbNode();
1542 info() << "Number of edges " << m_one_mesh_item_adder->nbEdge();
1543 info() << "Number of faces " << m_one_mesh_item_adder->nbFace();
1544 info() << "Number of cells " << m_one_mesh_item_adder->nbCell();
1545 info() << "-- Graph information (Arcane2):";
1546}
1547
1548/*---------------------------------------------------------------------------*/
1549/*---------------------------------------------------------------------------*/
1550
1551void DynamicMeshIncrementalBuilder::
1552printStats(Int32 level)
1553{
1554 info(level) << "-- -- Statistics";
1555 info(level) << "Number of nodes after addition &: " << m_one_mesh_item_adder->nbNode()
1556 << " hashmap=" << m_mesh->nodesMap().count();
1557 info(level) << "Number of edges after addition : " << m_one_mesh_item_adder->nbEdge()
1558 << " hashmap=" << m_mesh->edgesMap().count();
1559 info(level) << "Number of faces after addition : " << m_one_mesh_item_adder->nbFace()
1560 << " hashmap=" << m_mesh->facesMap().count();
1561 info(level) << "Number of cells after addition : " << m_one_mesh_item_adder->nbCell()
1562 << " hashmap=" << m_mesh->cellsMap().count();
1563 info(level) << "--";
1564}
1565
1566/*---------------------------------------------------------------------------*/
1567/*---------------------------------------------------------------------------*/
1591{
1592 if (!m_face_unique_id_builder)
1593 m_face_unique_id_builder = new FaceUniqueIdBuilder(this);
1594 m_face_unique_id_builder->computeFacesUniqueIds();
1595
1596 if (m_has_edge) {
1597 if (!m_edge_unique_id_builder)
1598 m_edge_unique_id_builder = new EdgeUniqueIdBuilder(this);
1599 m_edge_unique_id_builder->computeEdgesUniqueIds();
1600 }
1601}
1602
1603/*---------------------------------------------------------------------------*/
1604/*---------------------------------------------------------------------------*/
1605
1606void DynamicMeshIncrementalBuilder::
1607addGhostLayers(bool is_allocate)
1608{
1609 debug() << "Add one ghost layer";
1612 m_ghost_layer_builder->addGhostLayers(is_allocate);
1613}
1614
1615/*---------------------------------------------------------------------------*/
1616/*---------------------------------------------------------------------------*/
1617
1627
1628/*---------------------------------------------------------------------------*/
1629/*---------------------------------------------------------------------------*/
1630
1631void DynamicMeshIncrementalBuilder::
1632_removeNeedRemoveMarkedItems(ItemInternalMap& map, UniqueArray<Int32>& items_local_id)
1633{
1634 // Suppression des liaisons
1636 items_to_remove.reserve(1000);
1637
1638 map.eachItem([&](Item item) {
1640 Integer f = mb_item.flags();
1641 if (f & ItemFlags::II_NeedRemove){
1642 f &= ~ItemFlags::II_NeedRemove;
1643 mb_item.setFlags(f);
1644 items_local_id.add(item.localId());
1645 }
1646 });
1647}
1648
1649/*---------------------------------------------------------------------------*/
1650/*---------------------------------------------------------------------------*/
1651
1662{
1664 {
1665
1666 IItemFamily* links_family = m_mesh->findItemFamily(IK_DoF, GraphDoFs::linkFamilyName(), false, false);
1667 if(links_family)
1668 {
1669 info() << "Remove Items for family : "<<links_family->name() ;
1670 links_family->removeNeedRemoveMarkedItems() ;
1671 }
1672
1673 for( IItemFamily* family : m_mesh->itemFamilies() )
1674 {
1675 if (family->itemKind()!=IK_DoF || family->name()==GraphDoFs::linkFamilyName())
1676 continue;
1677 info() << "Remove Items for family : "<<family->name() ;
1678 family->removeNeedRemoveMarkedItems() ;
1679 }
1680 // Supression des particules de la famille Particle
1681
1682 for( IItemFamilyCollection::Enumerator i(m_mesh->itemFamilies()); ++i; ){
1683 IItemFamily* family = *i;
1684 if (family->itemKind()==IK_Particle){
1685 ParticleFamily* particle_family = dynamic_cast<ParticleFamily*>(family) ;
1687 if(particle_family && particle_family->getEnableGhostItems()==true){
1689 lids_to_remove.reserve(1000);
1690
1692 particle_map.eachItem([&](Item item) {
1694 Integer f = mb_item.flags();
1695 if (f & ItemFlags::II_NeedRemove){
1696 f &= ~ItemFlags::II_NeedRemove;
1697 mb_item.setFlags(f);
1698 lids_to_remove.add(item.localId());
1699 }
1700 });
1701
1702 info() << "Number of particles of family "<<family->name()<<" to remove: " << lids_to_remove.size();
1703 if(lids_to_remove.size()>0)
1704 particle_family->removeParticles(lids_to_remove) ;
1705 }
1706 }
1707 }
1708
1709 // Suppression des mailles
1710 CellFamily& cell_family = m_mesh->trueCellFamily();
1712 cells_to_remove.reserve(1000);
1713 _removeNeedRemoveMarkedItems(cell_family.itemsMap(), cells_to_remove);
1714
1715 info() << "Number of cells to remove: " << cells_to_remove.size();
1716
1717#ifdef ARCANE_DEBUG_DYNAMIC_MESH
1718 for( Integer i=0, is=cells_to_remove.size(); i<is; ++i )
1719 info() << "remove cell with uid=" << cells_to_remove[i]->uniqueId()
1720 << ",lid=" << cells_to_remove[i]->localId()
1721 << ",owner=" << cells_to_remove[i]->owner();
1722#endif /* ARCANE_DEBUG_DYNAMIC_MESH */
1723
1724 cell_family.removeCells(cells_to_remove);
1725 }
1726 // With ItemFamilyNetwork
1727 else
1728 {
1729 // handle families already in the network
1732 // Remove items from family graph leaves to root
1733 }, IItemFamilyNetwork::InverseTopologicalOrder);
1734 for (auto family : m_mesh->itemFamilies()) {
1735 // handle remaining families (particles, links, dual nodes & dof).
1736 // Will have no effect on the families already handled in the graph (since NeedRemove flag is reset)
1738 }
1739 }
1740}
1741
1742/*---------------------------------------------------------------------------*/
1743/*---------------------------------------------------------------------------*/
1744
1746setConnectivity(const Integer connectivity)
1747{
1748 if (connectivity == 0)
1749 ARCANE_FATAL("Undefined connectivity !");
1750 if (m_connectivity != 0)
1751 ARCANE_FATAL("Connectivity already set: cannot redefine it");
1752 m_connectivity = connectivity;
1753 m_has_edge = Connectivity::hasConnectivity(connectivity,Connectivity::CT_HasEdge);
1754}
1755
1756/*---------------------------------------------------------------------------*/
1757/*---------------------------------------------------------------------------*/
1758
1766
1767/*---------------------------------------------------------------------------*/
1768/*---------------------------------------------------------------------------*/
1769
1770} // End namespace Arcane::mesh
1771
1772/*---------------------------------------------------------------------------*/
1773/*---------------------------------------------------------------------------*/
#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.
Tableau d'items de types quelconques.
Maille d'un maillage.
Definition Item.h:1191
Face d'une maille.
Definition Item.h:944
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.
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 localId() const
Numéro local (au sous-domaine) de l'entité
Flags pour les caractéristiques des entités.
Definition ItemFlags.h:31
@ II_NeedRemove
L'entité doit être supprimé
Definition ItemFlags.h:55
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.
Gestionnaire des types d'entités de maillage.
Definition ItemTypeMng.h:66
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:374
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:219
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:149
Méthodes permettant de modifier ItemBase.
Famille de mailles.
Definition CellFamily.h:46
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:97
bool useMeshItemFamilyDependencies() const override
check if the network itemFamily dependencies is activated
IItemFamily * nodeFamily() override
Retourne la famille des noeuds.
IItemFamily * cellFamily() override
Retourne la famille des mailles.
String name() const override
Nom du maillage.
IItemFamily * faceFamily() override
Retourne la famille des faces.
IItemFamily * findItemFamily(eItemKind ik, const String &name, bool create_if_needed, bool register_modifier_if_created) override
Retourne la famille de nom name.
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.
Int32 count() const
Nombre d'éléments de la table.
ItemInternal * addOneCell(ItemTypeId type_id, Int64 cell_uid, Int32 sub_domain_id, Int64ConstArrayView nodes_uid, bool allow_build_face)
Ajoute une maille.
void resetAfterDeallocate()
Remise à zéro des structures pour pouvoir faire à nouveau une allocation.
ItemInternal * addOneParentItem(const Item &item, const eItemKind submesh_kind, const bool fatal_on_existing_item=true)
Ajoute d'un item parent.
ItemInternal * addOneFace(ItemTypeId type_id, Int64 face_uid, Int32 owner_rank, Int64ConstArrayView nodes_uid)
Ajoute une face.
Famille de particules.
Integer size() const
Nombre d'éléments du vecteur.
Exception lorsqu'un argument est invalide.
Vue modifiable d'un tableau d'un type T.
constexpr Integer size() const noexcept
Retourne la taille du tableau.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Chaîne de caractères unicode.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
Vecteur 1D de données avec sémantique par valeur (style STL).
Integer toInteger(Real r)
Converti un Int64 en un Integer.
Int32 toInt32(Int64 v)
Converti un Int64 en un Int32.
Array< Int64 > Int64Array
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:215
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:429
ArrayView< Int64 > Int64ArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:541
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.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:570
Int32 Integer
Type représentant un entier.