14#include "arcane/materials/internal/ConstituentConnectivityList.h"
16#include "arcane/core/IItemFamily.h"
18#include "arcane/utils/ITraceMng.h"
20#include "arcane/core/internal/IDataInternal.h"
21#include "arcane/core/internal/IItemFamilyInternal.h"
23#include "arcane/materials/internal/MeshMaterialMng.h"
25#include "arcane/accelerator/core/RunQueue.h"
27#include "arcane/accelerator/Scan.h"
45 template <
typename DataType>
46 ARCCORE_HOST_DEVICE
void _removeValueAndKeepOrder(ArrayView<DataType> values, DataType value_to_remove)
49#ifndef ARCCORE_DEVICE_CODE
51 ARCANE_FATAL(
"Can not remove item lid={0} because list is empty", value_to_remove);
55 if (values[0] == value_to_remove)
60 if (values[n] == value_to_remove)
62 for (Integer i = 0; i < n; ++i) {
63 if (values[i] == value_to_remove) {
64 for (Integer z = i; z < n; ++z)
65 values[z] = values[z + 1];
70#if defined(ARCCORE_DEVICE_CODE)
73# if !defined(__INTEL_LLVM_COMPILER)
77 ARCANE_FATAL(
"No value to remove '{0}' found in list {1}", value_to_remove, values);
100 : nb_components_view(c.m_nb_component_as_array.
view())
101 , component_indexes_view(c.m_component_index_as_array.
view())
102 , component_list_view(c.m_component_list_as_array.
view())
110 Int16 n = nb_components_view[item_lid];
111 Int32 index = component_indexes_view[item_lid];
112 return component_list_view.
subPart(index, n);
128 , m_nb_component_as_array(m_nb_component._internalTrueData()->_internalDeprecatedValue())
129 , m_component_index_as_array(m_component_index._internalTrueData()->_internalDeprecatedValue())
130 , m_component_list_as_array(m_component_list._internalTrueData()->_internalDeprecatedValue())
136 void endCreate(
bool is_continue)
139 _resetConnectivities();
144 Int16 n = m_nb_component[item_lid];
145 Int32 index = m_component_index[item_lid];
149 return m_component_list_as_array.
subView(index, n);
152 void checkResize(Int64 size)
154 if (MeshUtils::checkResizeArray(m_nb_component_as_array, size,
false))
156 if (MeshUtils::checkResizeArray(m_component_index_as_array, size,
false))
160 void reserve(Int64 capacity)
162 m_nb_component_as_array.
reserve(capacity);
163 m_component_index_as_array.
reserve(capacity);
172 void notifyUpdateConnectivityList()
177 void removeAllConnectivities()
179 _resetConnectivities();
199 void _resetConnectivities()
201 m_nb_component.
fill(0);
202 m_component_index.fill(0);
204 m_component_list.resize(1);
205 m_component_list[0] = 0;
221 , m_environment_for_materials(environment_for_materials)
227 ARCCORE_HOST_DEVICE Int16 cellNbMaterial(Int32 cell_local_id, Int16 env_id)
const
229 auto mats = m_view.components(cell_local_id);
231 for (Int16 mat_id : mats) {
232 Int16 current_id = m_environment_for_materials[mat_id];
233 if (current_id == env_id)
254 : m_environment(mesh, var_base_name +
String(
"ComponentEnvironment"))
255 , m_material(mesh, var_base_name +
String(
"ComponentMaterial"))
261 void checkResize(Int32 lid)
263 Int64 wanted_size = lid + 1;
264 m_environment.checkResize(wanted_size);
265 m_material.checkResize(wanted_size);
270 m_environment.changeLocalIds(new_to_old_ids);
271 m_material.changeLocalIds(new_to_old_ids);
274 void reserve(Int64 capacity)
276 m_environment.reserve(capacity);
277 m_material.reserve(capacity);
289ConstituentConnectivityList::
290ConstituentConnectivityList(MeshMaterialMng* mm)
293, m_container(new
Container(mm->meshHandle(),
String(
"ComponentEnviroment") + mm->name()))
297 m_is_force_transform_all_constituants = (v.value() != 0);
298 info() <<
"Force transformation in 'ConstituentConnectivityList' v=" << m_is_force_transform_all_constituants;
305ConstituentConnectivityList::
306~ConstituentConnectivityList()
314void ConstituentConnectivityList::
315endCreate(
bool is_continue)
318 const bool always_build_connectivity =
true;
324 m_cell_family = m_material_mng->mesh()->cellFamily();
326 int opt_flag_value = m_material_mng->modificationFlags();
328 if (use_incremental || always_build_connectivity) {
329 m_cell_family->_internalApi()->addSourceConnectivity(
this);
331 info() <<
"Activating incremental material connectivities";
335 Int32 max_local_id = m_cell_family->maxLocalId();
336 m_container->checkResize(max_local_id + 1);
337 m_container->m_environment.endCreate(is_continue);
338 m_container->m_material.endCreate(is_continue);
344 ConstArrayView<MeshMaterial*> materials = m_material_mng->trueMaterials();
345 const Int32 nb_mat = materials.size();
346 auto environment_for_materials = m_environment_for_materials.hostModifier();
347 environment_for_materials.resize(nb_mat);
348 auto local_view = environment_for_materials.view();
349 for (Int32 i = 0; i < nb_mat; ++i)
350 local_view[i] = materials[i]->trueEnvironment()->componentId();
357void ConstituentConnectivityList::
358_addCells(Int16 component_id, SmallSpan<const Int32> cells_local_id,
359 ConstituentContainer& component, RunQueue& queue)
361 const Int32 nb_item = cells_local_id.size();
364 Array<Int16>& nb_component = component.m_nb_component_as_array;
365 Array<Int32>& component_index = component.m_component_index_as_array;
366 Array<Int16>& component_list = component.m_component_list_as_array;
368 SmallSpan<Int16> nb_component_view = component.m_nb_component_as_array.view();
371 NumArray<Int32, MDDim1> new_indexes(nb_item, queue.memoryRessource());
377 Accelerator::GenericScanner scanner(queue);
378 SmallSpan<Int32> new_indexes_view = new_indexes;
379 SmallSpan<Int32> new_indexes_to_add_view = new_indexes_to_add;
380 auto getter = [=] ARCCORE_HOST_DEVICE(Int32 index) -> Int32 {
381 return 1 + nb_component_view[cells_local_id[index]];
383 auto setter = [=] ARCCORE_HOST_DEVICE(Int32 index, Int32 value) {
384 new_indexes_view[index] = value;
385 if (index == (nb_item - 1))
386 new_indexes_to_add_view[0] = new_indexes_view[index] + nb_component_view[cells_local_id[index]] + 1;
388 Accelerator::ScannerSumOperator<Int32> op;
389 scanner.applyWithIndexExclusive(nb_item, 0, getter, setter, op, A_FUNCINFO);
393 const Int32 nb_indexes_to_add = new_indexes_to_add[0];
394 const Int32 current_list_index = component_list.size();
396 MemoryUtils::checkResizeArrayWithCapacity(component_list, current_list_index + nb_indexes_to_add,
false);
400 SmallSpan<Int16> nb_component_view = nb_component.view();
401 SmallSpan<Int32> component_index_view = component_index.view();
402 SmallSpan<Int16> component_list_view = component_list.view();
403 SmallSpan<const Int32> new_indexes_view = new_indexes;
407 Int32 cell_id = cells_local_id[i];
408 const Int16 n = nb_component_view[cell_id];
409 Int32 new_pos = current_list_index + new_indexes_view[i];
414 Int32 current_pos = component_index_view[cell_id];
415 SmallSpan<const Int16> current_values(&component_list_view[current_pos], n);
416 SmallSpan<Int16> new_values(&component_list_view[new_pos], n);
417 new_values.copy(current_values);
419 component_index_view[cell_id] = new_pos;
420 component_list_view[new_pos + n] = component_id;
421 ++nb_component_view[cell_id];
425 component.notifyUpdateConnectivityList();
431void ConstituentConnectivityList::
432_removeCells(Int16 component_id, SmallSpan<const Int32> cells_local_id,
433 ConstituentContainer& component, RunQueue& queue)
435 SmallSpan<Int16> nb_component = component.m_nb_component_as_array.view();
436 SmallSpan<Int32> component_index = component.m_component_index_as_array.view();
437 SmallSpan<Int16> component_list = component.m_component_list_as_array.view();
439 const Int32 n = cells_local_id.size();
444 Int32
id = cells_local_id[i];
446 CellLocalId cell_id(
id);
447 const Int32 current_pos = component_index[cell_id];
448 const Int32 n = nb_component[cell_id];
449 ArrayView<Int16> current_values(n, &component_list[current_pos]);
451 _removeValueAndKeepOrder(current_values, component_id);
453 current_values[n - 1] = (-1);
454 --nb_component[cell_id];
461void ConstituentConnectivityList::
462addCellsToEnvironment(Int16 env_id, SmallSpan<const Int32> cell_ids, RunQueue& queue)
464 _addCells(env_id, cell_ids, m_container->m_environment, queue);
470void ConstituentConnectivityList::
471removeCellsToEnvironment(Int16 env_id, SmallSpan<const Int32> cell_ids, RunQueue& queue)
473 _removeCells(env_id, cell_ids, m_container->m_environment, queue);
479void ConstituentConnectivityList::
480addCellsToMaterial(Int16 mat_id, SmallSpan<const Int32> cell_ids, RunQueue& queue)
482 _addCells(mat_id, cell_ids, m_container->m_material, queue);
488void ConstituentConnectivityList::
489removeCellsToMaterial(Int16 mat_id, SmallSpan<const Int32> cell_ids, RunQueue& queue)
491 _removeCells(mat_id, cell_ids, m_container->m_material, queue);
497ConstArrayView<Int16> ConstituentConnectivityList::
498cellsNbEnvironment()
const
500 return m_container->m_environment.m_nb_component_as_array;
506ConstArrayView<Int16> ConstituentConnectivityList::
507cellsNbMaterial()
const
509 return m_container->m_material.m_nb_component_as_array;
518Int16 ConstituentConnectivityList::
519cellNbMaterial(CellLocalId cell_id, Int16 env_id)
const
521 auto environment_for_materials = m_environment_for_materials.hostView();
523 ArrayView<Int16> mats = m_container->m_material.components(cell_id);
524 for (Int16 mat_id : mats) {
525 Int16 current_id = environment_for_materials[mat_id];
526 if (current_id == env_id)
535void ConstituentConnectivityList::
536fillCellsNbMaterial(SmallSpan<const Int32> cells_local_id, Int16 env_id,
537 SmallSpan<Int16> cells_nb_material, RunQueue& queue)
539 ConstituentContainer::View materials_container_view(m_container->m_material);
541 auto environment_for_materials = m_environment_for_materials.view(is_device);
542 const Int32 n = cells_local_id.size();
547 Int32 cell_id = cells_local_id[i];
549 SmallSpan<const Int16> mats = materials_container_view.components(cell_id);
550 for (Int16 mat_id : mats) {
551 Int16 current_id = environment_for_materials[mat_id];
552 if (current_id == env_id)
555 cells_nb_material[i] = nb_mat;
562Int32 ConstituentConnectivityList::
563fillCellsToTransform(SmallSpan<const Int32> cells_local_id, Int16 env_id,
564 SmallSpan<bool> cells_do_transform,
bool is_add, RunQueue& queue)
566 ConstituentContainer::View materials_container_view(m_container->m_material);
567 bool is_device = queue.isAcceleratorPolicy();
568 auto environment_for_materials = m_environment_for_materials.view(is_device);
570 NumberOfMaterialComputer nb_mat_computer(materials_container_view, environment_for_materials);
571 SmallSpan<const Int16> cells_nb_env = cellsNbEnvironment();
572 const Int32 n = cells_local_id.size();
574 Accelerator::ReducerSum2<Int32> sum_transformed(command);
578 Int32 local_id = cells_local_id[i];
579 bool do_transform =
false;
584 const Int16 nb_env = cells_nb_env[local_id];
586 do_transform = (nb_env > 1);
588 do_transform = nb_mat_computer.cellNbMaterial(local_id, env_id) > 1;
591 do_transform = (nb_env == 1);
593 do_transform = nb_mat_computer.cellNbMaterial(local_id, env_id) == 1;
596 cells_do_transform[local_id] = do_transform;
597 sum_transformed.combine(1);
600 return sum_transformed.reducedValue();
606void ConstituentConnectivityList::
607fillCellsIsPartial(SmallSpan<const Int32> cells_local_id, Int16 env_id,
608 SmallSpan<bool> cells_is_partial, RunQueue& queue)
610 ConstituentContainer::View materials_container_view(m_container->m_material);
611 bool is_device = queue.isAcceleratorPolicy();
612 auto environment_for_materials = m_environment_for_materials.view(is_device);
613 NumberOfMaterialComputer nb_mat_computer(materials_container_view, environment_for_materials);
614 SmallSpan<const Int16> cells_nb_env = cellsNbEnvironment();
615 const Int32 n = cells_local_id.size();
621 Int32 local_id = cells_local_id[i];
624 bool is_partial = (cells_nb_env[local_id] > 1 || nb_mat_computer.cellNbMaterial(local_id, env_id) > 1);
625 cells_is_partial[i] = is_partial;
635void ConstituentConnectivityList::
636printConstituents(SmallSpan<const Int32> cells_local_id)
const
638 const ConstituentContainer::View materials_view(m_container->m_material);
639 const ConstituentContainer::View environments_view(m_container->m_environment);
641 for (Int32 i = 0, n = cells_local_id.size(); i < n; ++i) {
642 Int32 lid = cells_local_id[i];
643 info() <<
"Cell index=" << i <<
" lid=" << lid
644 <<
" materials=" << materials_view.components(lid)
645 <<
" environments=" << environments_view.components(lid);
676void ConstituentConnectivityList::
677fillModifiedConstituents(SmallSpan<const Int32> cells_local_id,
678 SmallSpan<bool> is_modified_materials,
679 SmallSpan<bool> is_modified_environments,
680 int modified_mat_id,
bool is_add,
const RunQueue& queue)
682 const Int32 n = cells_local_id.size();
686 bool is_device = queue.isAcceleratorPolicy();
687 const ConstituentContainer::View materials_view(m_container->m_material);
688 const ConstituentContainer::View environments_view(m_container->m_environment);
689 auto env_for_mat = m_environment_for_materials.view(is_device);
690 NumberOfMaterialComputer nb_mat_computer(materials_view, m_environment_for_materials.view(is_device));
691 Int16 modified_env_id = m_environment_for_materials.hostView()[modified_mat_id];
692 ConstArrayView<Int16> cells_nb_environment = cellsNbEnvironment();
695 ITraceMng* tm = traceMng();
696 tm->info(4) <<
"FillModifiedConstituents modified_mat=" << modified_mat_id
697 <<
" modified_env=" << modified_env_id <<
" is_add=" << is_add;
698 const bool force_transform = m_is_force_transform_all_constituants;
700 if (force_transform) {
706 const Int32 local_id = cells_local_id[i];
707 SmallSpan<const Int16> cell_envs(environments_view.components(local_id));
708 for (Int16 x : cell_envs)
709 is_modified_environments[x] = true;
710 SmallSpan<const Int16> cell_mats(materials_view.components(local_id));
711 for (Int16 x : cell_mats)
712 is_modified_materials[x] = true;
720 const Int32 local_id = cells_local_id[i];
721 const Int16 nb_mat_in_modified_env = nb_mat_computer.cellNbMaterial(local_id, modified_env_id);
722 const Int16 nb_env = cells_nb_environment[local_id];
728 SmallSpan<const Int16> cell_envs(environments_view.components(local_id));
729 for (Int16 x : cell_envs) {
731 if (x == modified_env_id)
733 bool do_transform =
false;
737 do_transform = nb_env == 1;
742 do_transform = nb_env == 2;
746 is_modified_environments[x] =
true;
750 SmallSpan<const Int16> cell_mats(materials_view.components(local_id));
751 for (Int16 x : cell_mats) {
753 if (x == modified_mat_id)
755 bool do_transform =
false;
756 Int16 my_env_id = env_for_mat[x];
758 Int16 my_mat_nb_env = nb_mat_computer.cellNbMaterial(local_id, my_env_id);
763 if (my_env_id != modified_env_id && (nb_mat_in_modified_env != 0))
765 do_transform = (nb_env == 1) && (my_mat_nb_env == 1);
776 do_transform = (my_env_id == modified_env_id) && (my_mat_nb_env == 2);
780 is_modified_materials[x] =
true;
789void ConstituentConnectivityList::
792 m_container->changeLocalIds(new_to_old_ids);
798void ConstituentConnectivityList::
799notifySourceItemAdded(ItemLocalId item)
801 Int32 lid = item.localId();
802 m_container->checkResize(lid + 1);
804 m_container->m_environment.m_nb_component_as_array[lid] = 0;
805 m_container->m_environment.m_component_index_as_array[lid] = 0;
807 m_container->m_material.m_nb_component_as_array[lid] = 0;
808 m_container->m_material.m_component_index_as_array[lid] = 0;
814void ConstituentConnectivityList::
815reserveMemoryForNbSourceItems(Int32 n, [[maybe_unused]]
bool pre_alloc_connectivity)
817 info() <<
"Constituent: reserve=" << n;
818 m_container->reserve(n);
824void ConstituentConnectivityList::
832Ref<IIncrementalItemSourceConnectivity> ConstituentConnectivityList::
835 return Arccore::makeRef<IIncrementalItemSourceConnectivity>(
this);
841void ConstituentConnectivityList::
842removeAllConnectivities()
844 m_container->m_environment.removeAllConnectivities();
845 m_container->m_material.removeAllConnectivities();
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fonctions utilitaires sur le maillage.
Types et fonctions pour gérer les synchronisations sur les accélérateurs.
Types et macros pour gérer les boucles sur les accélérateurs.
#define RUNCOMMAND_LOOP1(iter_name, x1,...)
Boucle sur accélérateur avec arguments supplémentaires pour les réductions.
virtual void compact(Int32ConstArrayView new_to_old_ids)=0
Compacte les valeurs de la variable.
Vue sur une liste de constituants des mailles.
Conteneur des données de connectivité pour un type de constituant.
Classe pour calculer le nombre de matériaux d'un milieu.
Paramètres nécessaires à la construction d'une variable.
void updateFromInternal() override
Mise à jour à partir de la partie interne.
Array< DataType > ContainerType
Type de la classe gérant la valeur de la variable.
IVariable * variable() const
Variable associée.
Vue modifiable d'un tableau d'un type T.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
ArrayView< T > subView(Int64 abegin, Integer asize)
Sous-vue à partir de l'élément abegin et contenant asize éléments.
ArrayView< T > view() const
Vue mutable sur ce tableau.
void fill(ConstReferenceType value)
Remplit le tableau avec la valeur value.
Vue constante d'un tableau de type T.
Vue d'un tableau d'éléments de type T.
constexpr __host__ __device__ SmallSpan< T, DynExtent > subPart(Int32 abegin, Int32 asize) const
Sous-vue à partir de l'élément abegin et contenant asize éléments.
Chaîne de caractères unicode.
Classe d'accès aux traces.
VariableRefArrayT< Int32 > VariableArrayInt32
Variable tableau de type entier 32 bits.
VariableRefArrayT< Int16 > VariableArrayInt16
Variable tableau de type entier 16 bits.
RunCommand makeCommand(const RunQueue &run_queue)
Créé une commande associée à la file run_queue.
bool isAcceleratorPolicy(eExecutionPolicy exec_policy)
Indique si exec_policy correspond à un accélérateur.
Active toujours les traces dans les parties Arcane concernant les matériaux.
@ IncrementalRecompute
Indique qu'on utilise la version incrémentale de AllEnvData::forceRecompute().
@ HostPinned
Alloue sur l'hôte.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Int32 Integer
Type représentant un entier.