Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ParticleFamily.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 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/* ParticleFamily.cc (C) 2000-2024 */
9/* */
10/* Famille de particules. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/mesh/ParticleFamily.h"
15
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/PlatformUtils.h"
18
19#include "arcane/core/ISubDomain.h"
20#include "arcane/core/IMesh.h"
21#include "arcane/core/IVariableMng.h"
22#include "arcane/core/Properties.h"
23#include "arcane/core/ItemPrinter.h"
24
25#include "arcane/mesh/ItemsExchangeInfo2.h"
26#include "arcane/mesh/DynamicMesh.h"
27#include "arcane/mesh/ItemConnectivitySelector.h"
28#include "arcane/mesh/DynamicMeshKindInfos.h"
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33namespace Arcane::mesh
34{
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
39ParticleFamily::
40ParticleFamily(IMesh* mesh, const String& name)
41: ItemFamily(mesh, IK_Particle, name)
42, m_particle_type_info(nullptr)
43, m_particle_shared_info(nullptr)
44, m_sub_domain_id(NULL_SUB_DOMAIN_ID)
45, m_enable_ghost_items(false)
46, m_cell_connectivity(nullptr)
47{
48}
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
52
53ParticleFamily::
54~ParticleFamily()
55{
56}
57
58/*---------------------------------------------------------------------------*/
59/*---------------------------------------------------------------------------*/
60
61void ParticleFamily::
62build()
63{
64 ItemFamily::build();
65 ItemTypeMng* itm = m_mesh->itemTypeMng();
66 m_particle_type_info = itm->typeFromId(IT_NullType);
67 m_sub_domain_id = subDomain()->subDomainId();
68
69 // Temporaire: pour désactiver la table de hashage pour uniqueId
70 if (!platform::getEnvironmentVariable("ARCANE_PARTICLE_NO_UNIQUE_ID_MAP").null()) {
71 pwarning() << "TEMPORARY: suppress particule uniqueId map";
72 setHasUniqueIdMap(false);
73 }
74 else {
75 bool has_unique_id_map = !m_properties->getBool("no-unique-id-map");
76 _setHasUniqueIdMap(has_unique_id_map);
77 }
78
79 m_cell_connectivity = new CellConnectivity(this, mesh()->cellFamily(), "ParticleCell");
80
81 _addConnectivitySelector(m_cell_connectivity);
82
83 _buildConnectivitySelectors();
84
85 // Préalloue une maille par particule.
86 m_cell_connectivity->setPreAllocatedSize(1);
87
88 _setSharedInfo();
89
90 auto network = m_mesh->itemFamilyNetwork();
91 if (network) {
92 network->addDependency(this, mesh()->cellFamily(), m_cell_connectivity->customConnectivity(), false);
93 }
94}
95
96/*---------------------------------------------------------------------------*/
97/*---------------------------------------------------------------------------*/
102inline void ParticleFamily::
103_initializeNewlyAllocatedParticle(ItemInternal* particle, Int64 uid)
104{
105 _allocateInfos(particle, uid, m_particle_shared_info);
106 m_cell_connectivity->addConnectedItem(ItemLocalId(particle), ItemLocalId(NULL_ITEM_LOCAL_ID));
107}
108
109/*---------------------------------------------------------------------------*/
110/*---------------------------------------------------------------------------*/
111
112inline ItemInternal* ParticleFamily::
113_allocParticle(Int64 uid, bool& need_alloc)
114{
115 ItemInternal* ii = _allocOne(uid, need_alloc);
116
117 if (!need_alloc)
118 ii->setUniqueId(uid);
119 else
120 _initializeNewlyAllocatedParticle(ii, uid);
121
122 // Une particule appartient toujours au sous-domaine qui l'a créée
123 ii->setOwner(m_sub_domain_id, m_sub_domain_id);
124 return ii;
125}
126
127/*---------------------------------------------------------------------------*/
128/*---------------------------------------------------------------------------*/
129
130inline ItemInternal* ParticleFamily::
131_findOrAllocParticle(Int64 uid, bool& is_alloc)
132{
133 ItemInternal* ii = ItemFamily::_findOrAllocOne(uid, is_alloc);
134 if (is_alloc)
135 _initializeNewlyAllocatedParticle(ii, uid);
136 return ii;
137}
138
139/*---------------------------------------------------------------------------*/
140/*---------------------------------------------------------------------------*/
141
142ParticleVectorView ParticleFamily::
144{
145 _addItems(unique_ids, items);
146 return view(items);
147}
148
149/*---------------------------------------------------------------------------*/
150/*---------------------------------------------------------------------------*/
151
152ParticleVectorView ParticleFamily::
153addParticles2(Int64ConstArrayView unique_ids,
155 Int32ArrayView items)
156{
157 addItems(unique_ids, owners, items);
158 return view(items);
159}
160
161/*---------------------------------------------------------------------------*/
162/*---------------------------------------------------------------------------*/
163
164void ParticleFamily::
165_setCell(ItemLocalId particle, ItemLocalId cell)
166{
167 m_cell_connectivity->replaceItem(particle, 0, cell);
168}
169
170/*---------------------------------------------------------------------------*/
171/*---------------------------------------------------------------------------*/
172
173ParticleVectorView ParticleFamily::
176 Int32ArrayView items)
177{
178 _addItems(unique_ids, items);
179 Integer n = items.size();
180 for (Integer i = 0; i < n; ++i) {
181 _setCell(ItemLocalId(items[i]), ItemLocalId(cells_local_id[i]));
182 }
183
184 return view(items);
185}
186
187/*---------------------------------------------------------------------------*/
188/*---------------------------------------------------------------------------*/
189
190void ParticleFamily::
191setParticleCell(Particle particle, Cell new_cell)
192{
193 _setCell(particle, new_cell);
194 m_need_prepare_dump = true;
195}
196
197/*---------------------------------------------------------------------------*/
198/*---------------------------------------------------------------------------*/
199
200void ParticleFamily::
202{
205 for (Integer i = 0, n = particle_ids.size(); i < n; ++i)
206 _setCell(ItemLocalId(particle_ids[i]), ItemLocalId(cell_ids[i]));
207 m_need_prepare_dump = true;
208}
209
210/*---------------------------------------------------------------------------*/
211/*---------------------------------------------------------------------------*/
212
213void ParticleFamily::
215{
216 Integer nb_item = unique_ids.size();
217 if (nb_item == 0)
218 return;
219 preAllocate(nb_item);
220
221 bool need_alloc = false;
222 for (Integer i = 0; i < nb_item; ++i) {
223 Int64 uid = unique_ids[i];
224 ItemInternal* ii = _allocParticle(uid, need_alloc);
225 items[i] = ii->localId();
226 }
227
228 m_need_prepare_dump = true;
229 _printInfos(nb_item);
230}
231
232/*---------------------------------------------------------------------------*/
233/*---------------------------------------------------------------------------*/
234
235void ParticleFamily::
236addItems(Int64ConstArrayView unique_ids, Int32ConstArrayView owners, Int32ArrayView items)
237{
238 Integer nb_item = unique_ids.size();
239 if (nb_item == 0)
240 return;
241 preAllocate(nb_item);
242 // La méthode _findOrAlloc nécessite la table de hashage des uniqueId().
243 if (!hasUniqueIdMap())
244 ARCANE_FATAL("Can not add particles with owners when hasUniqueIdMap()==false family={0}",
245 name());
246
247 bool need_alloc = false;
248 for (Integer i = 0; i < nb_item; ++i) {
249 Int64 uid = unique_ids[i];
250 ItemInternal* ii = _findOrAllocParticle(uid, need_alloc);
251 ii->setOwner(owners[i], m_sub_domain_id);
252
253 items[i] = ii->localId();
254 }
255
256 m_need_prepare_dump = true;
257 _printInfos(nb_item);
258}
259
260/*---------------------------------------------------------------------------*/
261/*---------------------------------------------------------------------------*/
262
263void ParticleFamily::
264exchangeParticles()
265{
267 ex.computeExchangeItems();
268 ex.computeExchangeInfos();
269 ex.prepareToSend();
270 ex.processExchange();
271 ex.removeSentItems();
272 ex.readAndAllocItems();
273 notifyItemsOwnerChanged();
274 endUpdate();
275 ex.readGroups();
276 ex.readVariables();
277}
278
279/*---------------------------------------------------------------------------*/
280/*---------------------------------------------------------------------------*/
281
282void ParticleFamily::
283_printInfos(Integer nb_added)
284{
285 ARCANE_UNUSED(nb_added);
286}
287
288/*---------------------------------------------------------------------------*/
289/*---------------------------------------------------------------------------*/
290
291void ParticleFamily::
292internalRemoveItems(Int32ConstArrayView local_ids, bool keep_ghost)
293{
294 ARCANE_UNUSED(keep_ghost);
295
296 InternalConnectivityPolicy policy = mesh()->_connectivityPolicy();
297
298 // A noter que cette boucle n'est pas utile pour le moment si on
299 // n'utilise pas les nouvelles connectivités.
300 // Elle le sera si on souhaite avoir des connectivités inverses
301 // maille->particule.
302 bool want_nullify_cell = (policy != InternalConnectivityPolicy::Legacy);
303 ItemLocalId null_item_lid(NULL_ITEM_LOCAL_ID);
304
305 auto network = m_mesh->itemFamilyNetwork();
306 if (network) {
307 std::set<Int32> remove_lids;
308 if (want_nullify_cell) {
309 for (Integer i = 0, n = local_ids.size(); i < n; ++i) {
311 m_cell_connectivity->replaceItem(lid, 0, null_item_lid);
312 remove_lids.insert(local_ids[i]);
313 }
314 }
315 for (auto parent_connectivity : m_mesh->itemFamilyNetwork()->getParentConnectivities(this)) {
316 //for (auto parent_connectivity : m_mesh->itemFamilyNetwork()->getParentRelations(this)) { // Should be getParentConnectivities, but because legacy connectivity cannot remove a connectivity with a Node as target, we need to restrain to Relations...
317 for (auto source_item : parent_connectivity->sourceFamily()->itemsInternal()) {
318 if (source_item->isSuppressed())
319 continue;
322 if (remove_lids.find(connected_item->localId()) != remove_lids.end()) {
324 }
325 }
326 }
327 }
328 }
329 else {
330 if (want_nullify_cell) {
331 for (Integer i = 0, n = local_ids.size(); i < n; ++i) {
333 m_cell_connectivity->replaceItem(lid, 0, null_item_lid);
334 }
335 }
336 }
337 _removeMany(local_ids);
338
339 m_need_prepare_dump = true;
340}
341
342/*---------------------------------------------------------------------------*/
343/*---------------------------------------------------------------------------*/
344
345void ParticleFamily::
346removeParticles(Int32ConstArrayView items_local_id)
347{
348 internalRemoveItems(items_local_id, false);
349}
350
351/*---------------------------------------------------------------------------*/
352/*---------------------------------------------------------------------------*/
353
354void ParticleFamily::
355prepareForDump()
356{
357 Integer nb_item = nbItem();
358 info(4) << "ParticleFamily::prepareForDump: " << name()
359 << " n=" << nb_item;
360 ItemFamily::prepareForDump();
361}
362
363/*---------------------------------------------------------------------------*/
364/*---------------------------------------------------------------------------*/
365
366void ParticleFamily::
367readFromDump()
368{
369 ItemFamily::readFromDump();
370 // Actualise le shared_info car il peut changer suite à une relecture
371 _setSharedInfo();
372}
373
374/*---------------------------------------------------------------------------*/
375/*---------------------------------------------------------------------------*/
376
377void ParticleFamily::
378preAllocate(Integer nb_item)
379{
380 Integer nb_hash = itemsMap().nbBucket();
381 Integer wanted_size = 2 * (nb_item + nbItem());
382 if (nb_hash < wanted_size)
383 itemsMap().resize(wanted_size, true);
384}
385
386/*---------------------------------------------------------------------------*/
387/*---------------------------------------------------------------------------*/
388
389void ParticleFamily::
390setHasUniqueIdMap(bool v)
391{
392 _setHasUniqueIdMap(v);
393 m_properties->setBool("no-unique-id-map", !v);
394}
395
396/*---------------------------------------------------------------------------*/
397/*---------------------------------------------------------------------------*/
398
399bool ParticleFamily::
400hasUniqueIdMap() const
401{
402 return _infos().hasUniqueIdMap();
403}
404
405/*---------------------------------------------------------------------------*/
406/*---------------------------------------------------------------------------*/
407
408void ParticleFamily::
409_setSharedInfo()
410{
411 m_particle_shared_info = _findSharedInfo(m_particle_type_info);
412}
413
414/*---------------------------------------------------------------------------*/
415/*---------------------------------------------------------------------------*/
416
417void ParticleFamily::
418checkValidConnectivity()
419{
420 ItemFamily::checkValidConnectivity();
421}
422
423/*---------------------------------------------------------------------------*/
424/*---------------------------------------------------------------------------*/
425
426void ParticleFamily::
427removeNeedRemoveMarkedItems()
428{
429 if (getEnableGhostItems()) {
431 lids_to_remove.reserve(1000);
432
433 ItemInternalMap& particle_map = itemsMap();
434 particle_map.eachItem([&](Item item) {
435 Integer f = item.itemBase().flags();
436 if (f & ItemFlags::II_NeedRemove) {
437 f &= ~ItemFlags::II_NeedRemove;
438 item.mutableItemBase().setFlags(f);
439 lids_to_remove.add(item.localId());
440 }
441 });
442
443 info() << "Number of particles of family " << name() << " to remove: " << lids_to_remove.size();
444 if (lids_to_remove.size() > 0)
445 removeParticles(lids_to_remove);
446 }
447}
448
449/*---------------------------------------------------------------------------*/
450/*---------------------------------------------------------------------------*/
451
452} // End namespace Arcane::mesh
453
454/*---------------------------------------------------------------------------*/
455/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_ITEM(name, group)
Enumérateur générique d'un groupe de noeuds.
Maille d'un maillage.
Definition Item.h:1178
Gère la récupération des informations de connectivité.
Flags pour les caractéristiques des entités.
Definition ItemFlags.h:31
Structure interne d'une entité de maillage.
Index d'un Item dans une variable.
Definition ItemLocalId.h:40
Vue sur un tableau typé d'entités.
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:365
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:210
impl::ItemBase itemBase() const
Partie interne de l'entité.
Definition Item.h:354
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Particule.
Definition Item.h:1383
Tableau associatif de ItemInternal.
Informations pour échanger des entités d'une famille donnée et leur caractéristiques.
Vue modifiable d'un tableau d'un type T.
constexpr Integer size() const noexcept
Retourne la taille du tableau.
Vue constante d'un tableau de type T.
@ IK_Particle
Entité de maillage de genre particule.
InternalConnectivityPolicy
Politique d'utilisation des connectivités.
Definition ItemTypes.h:516