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"
26#include "arcane/accelerator/RunCommandLoop.h"
27#include "arcane/accelerator/Scan.h"
28#include "arcane/accelerator/Reduce.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) {
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 explicit View(ConstituentContainer& c)
101 : nb_components_view(c.m_nb_component_as_array.
view())
102 , component_indexes_view(c.m_component_index_as_array.
view())
103 , component_list_view(c.m_component_list_as_array.
view())
111 Int16 n = nb_components_view[item_lid];
112 Int32 index = component_indexes_view[item_lid];
113 return component_list_view.subPart(index, n);
129 , m_nb_component_as_array(m_nb_component._internalTrueData()->_internalDeprecatedValue())
130 , m_component_index_as_array(m_component_index._internalTrueData()->_internalDeprecatedValue())
131 , m_component_list_as_array(m_component_list._internalTrueData()->_internalDeprecatedValue())
137 void endCreate(
bool is_continue)
140 _resetConnectivities();
145 Int16 n = m_nb_component[item_lid];
146 Int32 index = m_component_index[item_lid];
150 return m_component_list_as_array.
subView(index, n);
153 void checkResize(
Int64 size)
161 void reserve(Int64 capacity)
163 m_nb_component_as_array.
reserve(capacity);
164 m_component_index_as_array.
reserve(capacity);
169 m_nb_component.variable()->compact(new_to_old_ids);
170 m_component_index.variable()->compact(new_to_old_ids);
173 void notifyUpdateConnectivityList()
175 m_component_list.updateFromInternal();
178 void removeAllConnectivities()
180 _resetConnectivities();
200 void _resetConnectivities()
202 m_nb_component.fill(0);
203 m_component_index.fill(0);
205 m_component_list.resize(1);
206 m_component_list[0] = 0;
223 , m_environment_for_materials(environment_for_materials)
229 ARCCORE_HOST_DEVICE
Int16 cellNbMaterial(
Int32 cell_local_id,
Int16 env_id)
const
231 auto mats = m_view.components(cell_local_id);
233 for (
Int16 mat_id : mats) {
234 Int16 current_id = m_environment_for_materials[mat_id];
235 if (current_id == env_id)
256 : m_environment(mesh, var_base_name +
String(
"ComponentEnvironment"))
257 , m_material(mesh, var_base_name +
String(
"ComponentMaterial"))
263 void checkResize(
Int32 lid)
265 Int64 wanted_size = lid + 1;
266 m_environment.checkResize(wanted_size);
267 m_material.checkResize(wanted_size);
272 m_environment.changeLocalIds(new_to_old_ids);
273 m_material.changeLocalIds(new_to_old_ids);
276 void reserve(
Int64 capacity)
278 m_environment.reserve(capacity);
279 m_material.reserve(capacity);
291ConstituentConnectivityList::
292ConstituentConnectivityList(MeshMaterialMng* mm)
295, m_container(new
Container(mm->meshHandle(),
String(
"ComponentEnviroment") + mm->name()))
299 m_is_force_transform_all_constituants = (v.value() != 0);
300 info() <<
"Force transformation in 'ConstituentConnectivityList' v=" << m_is_force_transform_all_constituants;
307ConstituentConnectivityList::
308~ConstituentConnectivityList()
316void ConstituentConnectivityList::
317endCreate(
bool is_continue)
320 const bool always_build_connectivity =
true;
326 m_cell_family = m_material_mng->mesh()->cellFamily();
328 int opt_flag_value = m_material_mng->modificationFlags();
330 if (use_incremental || always_build_connectivity) {
331 m_cell_family->_internalApi()->addSourceConnectivity(
this);
333 info() <<
"Activating incremental material connectivities";
337 Int32 max_local_id = m_cell_family->maxLocalId();
338 m_container->checkResize(max_local_id + 1);
339 m_container->m_environment.endCreate(is_continue);
340 m_container->m_material.endCreate(is_continue);
346 ConstArrayView<MeshMaterial*> materials = m_material_mng->trueMaterials();
347 const Int32 nb_mat = materials.size();
348 auto environment_for_materials = m_environment_for_materials.hostModifier();
349 environment_for_materials.resize(nb_mat);
350 auto local_view = environment_for_materials.view();
351 for (
Int32 i = 0; i < nb_mat; ++i)
352 local_view[i] = materials[i]->trueEnvironment()->componentId();
359void ConstituentConnectivityList::
360_addCells(
Int16 component_id, SmallSpan<const Int32> cells_local_id,
363 const Int32 nb_item = cells_local_id.size();
366 Array<Int16>& nb_component = component.m_nb_component_as_array;
367 Array<Int32>& component_index = component.m_component_index_as_array;
368 Array<Int16>& component_list = component.m_component_list_as_array;
370 SmallSpan<Int16> nb_component_view = component.m_nb_component_as_array.view();
373 NumArray<Int32, MDDim1> new_indexes(nb_item, queue.memoryRessource());
375 NumArray<Int32, MDDim1> new_indexes_to_add(1, eMemoryRessource::HostPinned);
379 Accelerator::GenericScanner scanner(queue);
380 SmallSpan<Int32> new_indexes_view = new_indexes;
381 SmallSpan<Int32> new_indexes_to_add_view = new_indexes_to_add;
382 auto getter = [=] ARCCORE_HOST_DEVICE(
Int32 index) ->
Int32 {
383 return 1 + nb_component_view[cells_local_id[index]];
385 auto setter = [=] ARCCORE_HOST_DEVICE(
Int32 index,
Int32 value) {
386 new_indexes_view[index] = value;
387 if (index == (nb_item - 1))
388 new_indexes_to_add_view[0] = new_indexes_view[index] + nb_component_view[cells_local_id[index]] + 1;
390 Accelerator::ScannerSumOperator<Int32> op;
391 scanner.applyWithIndexExclusive(nb_item, 0, getter, setter, op, A_FUNCINFO);
395 const Int32 nb_indexes_to_add = new_indexes_to_add[0];
396 const Int32 current_list_index = component_list.size();
402 SmallSpan<Int16> nb_component_view = nb_component.view();
403 SmallSpan<Int32> component_index_view = component_index.view();
404 SmallSpan<Int16> component_list_view = component_list.view();
405 SmallSpan<const Int32> new_indexes_view = new_indexes;
409 Int32 cell_id = cells_local_id[i];
410 const Int16 n = nb_component_view[cell_id];
411 Int32 new_pos = current_list_index + new_indexes_view[i];
416 Int32 current_pos = component_index_view[cell_id];
417 SmallSpan<const Int16> current_values(&component_list_view[current_pos], n);
418 SmallSpan<Int16> new_values(&component_list_view[new_pos], n);
419 new_values.copy(current_values);
421 component_index_view[cell_id] = new_pos;
422 component_list_view[new_pos + n] = component_id;
423 ++nb_component_view[cell_id];
427 component.notifyUpdateConnectivityList();
433void ConstituentConnectivityList::
434_removeCells(
Int16 component_id, SmallSpan<const Int32> cells_local_id,
437 SmallSpan<Int16> nb_component = component.m_nb_component_as_array.view();
438 SmallSpan<Int32> component_index = component.m_component_index_as_array.view();
439 SmallSpan<Int16> component_list = component.m_component_list_as_array.view();
441 const Int32 n = cells_local_id.size();
446 Int32 id = cells_local_id[i];
448 CellLocalId cell_id(
id);
449 const Int32 current_pos = component_index[cell_id];
450 const Int32 n = nb_component[cell_id];
451 ArrayView<Int16> current_values(n, &component_list[current_pos]);
453 _removeValueAndKeepOrder(current_values, component_id);
455 current_values[n - 1] = (-1);
456 --nb_component[cell_id];
463void ConstituentConnectivityList::
464addCellsToEnvironment(
Int16 env_id, SmallSpan<const Int32> cell_ids, RunQueue& queue)
466 _addCells(env_id, cell_ids, m_container->m_environment, queue);
472void ConstituentConnectivityList::
473removeCellsToEnvironment(
Int16 env_id, SmallSpan<const Int32> cell_ids, RunQueue& queue)
475 _removeCells(env_id, cell_ids, m_container->m_environment, queue);
481void ConstituentConnectivityList::
482addCellsToMaterial(
Int16 mat_id, SmallSpan<const Int32> cell_ids, RunQueue& queue)
484 _addCells(mat_id, cell_ids, m_container->m_material, queue);
490void ConstituentConnectivityList::
491removeCellsToMaterial(
Int16 mat_id, SmallSpan<const Int32> cell_ids, RunQueue& queue)
493 _removeCells(mat_id, cell_ids, m_container->m_material, queue);
499ConstArrayView<Int16> ConstituentConnectivityList::
500cellsNbEnvironment()
const
502 return m_container->m_environment.m_nb_component_as_array;
508ConstArrayView<Int16> ConstituentConnectivityList::
509cellsNbMaterial()
const
511 return m_container->m_material.m_nb_component_as_array;
520Int16 ConstituentConnectivityList::
521cellNbMaterial(CellLocalId cell_id,
Int16 env_id)
const
523 auto environment_for_materials = m_environment_for_materials.hostView();
525 ArrayView<Int16> mats = m_container->m_material.components(cell_id);
526 for (
Int16 mat_id : mats) {
527 Int16 current_id = environment_for_materials[mat_id];
528 if (current_id == env_id)
537void ConstituentConnectivityList::
538fillCellsNbMaterial(SmallSpan<const Int32> cells_local_id,
Int16 env_id,
539 SmallSpan<Int16> cells_nb_material, RunQueue& queue)
543 auto environment_for_materials = m_environment_for_materials.view(is_device);
544 const Int32 n = cells_local_id.size();
549 Int32 cell_id = cells_local_id[i];
551 SmallSpan<const Int16> mats = materials_container_view.components(cell_id);
552 for (
Int16 mat_id : mats) {
553 Int16 current_id = environment_for_materials[mat_id];
554 if (current_id == env_id)
557 cells_nb_material[i] = nb_mat;
564Int32 ConstituentConnectivityList::
565fillCellsToTransform(SmallSpan<const Int32> cells_local_id,
Int16 env_id,
566 SmallSpan<bool> cells_do_transform,
bool is_add, RunQueue& queue)
569 bool is_device = queue.isAcceleratorPolicy();
570 auto environment_for_materials = m_environment_for_materials.view(is_device);
573 SmallSpan<const Int16> cells_nb_env = cellsNbEnvironment();
574 const Int32 n = cells_local_id.size();
576 Accelerator::ReducerSum2<Int32> sum_transformed(command);
580 Int32 local_id = cells_local_id[i];
581 bool do_transform =
false;
586 const Int16 nb_env = cells_nb_env[local_id];
588 do_transform = (nb_env > 1);
590 do_transform = nb_mat_computer.cellNbMaterial(local_id, env_id) > 1;
593 do_transform = (nb_env == 1);
595 do_transform = nb_mat_computer.cellNbMaterial(local_id, env_id) == 1;
598 cells_do_transform[local_id] = do_transform;
599 sum_transformed.combine(1);
602 return sum_transformed.reducedValue();
608void ConstituentConnectivityList::
609fillCellsIsPartial(SmallSpan<const Int32> cells_local_id,
Int16 env_id,
610 SmallSpan<bool> cells_is_partial, RunQueue& queue)
613 bool is_device = queue.isAcceleratorPolicy();
614 auto environment_for_materials = m_environment_for_materials.view(is_device);
616 SmallSpan<const Int16> cells_nb_env = cellsNbEnvironment();
617 const Int32 n = cells_local_id.size();
623 Int32 local_id = cells_local_id[i];
626 bool is_partial = (cells_nb_env[local_id] > 1 || nb_mat_computer.cellNbMaterial(local_id, env_id) > 1);
627 cells_is_partial[i] = is_partial;
638void ConstituentConnectivityList::
639printConstituents(SmallSpan<const Int32> cells_local_id)
const
644 for (
Int32 i = 0, n = cells_local_id.size(); i < n; ++i) {
645 Int32 lid = cells_local_id[i];
646 info() <<
"Cell index=" << i <<
" lid=" << lid
647 <<
" materials=" << materials_view.components(lid)
648 <<
" environments=" << environments_view.components(lid);
679void ConstituentConnectivityList::
680fillModifiedConstituents(SmallSpan<const Int32> cells_local_id,
681 SmallSpan<bool> is_modified_materials,
682 SmallSpan<bool> is_modified_environments,
683 int modified_mat_id,
bool is_add,
const RunQueue& queue)
685 const Int32 n = cells_local_id.size();
689 bool is_device = queue.isAcceleratorPolicy();
692 auto env_for_mat = m_environment_for_materials.view(is_device);
694 Int16 modified_env_id = m_environment_for_materials.hostView()[modified_mat_id];
695 ConstArrayView<Int16> cells_nb_environment = cellsNbEnvironment();
698 ITraceMng* tm = traceMng();
699 tm->info(4) <<
"FillModifiedConstituents modified_mat=" << modified_mat_id
700 <<
" modified_env=" << modified_env_id <<
" is_add=" << is_add;
701 const bool force_transform = m_is_force_transform_all_constituants;
703 if (force_transform) {
709 const Int32 local_id = cells_local_id[i];
710 SmallSpan<const Int16> cell_envs(environments_view.components(local_id));
711 for (
Int16 x : cell_envs)
712 is_modified_environments[x] =
true;
713 SmallSpan<const Int16> cell_mats(materials_view.components(local_id));
714 for (
Int16 x : cell_mats)
715 is_modified_materials[x] =
true;
723 const Int32 local_id = cells_local_id[i];
724 const Int16 nb_mat_in_modified_env = nb_mat_computer.cellNbMaterial(local_id, modified_env_id);
725 const Int16 nb_env = cells_nb_environment[local_id];
731 SmallSpan<const Int16> cell_envs(environments_view.components(local_id));
732 for (
Int16 x : cell_envs) {
734 if (x == modified_env_id)
736 bool do_transform =
false;
740 do_transform = nb_env == 1;
745 do_transform = nb_env == 2;
749 is_modified_environments[x] =
true;
753 SmallSpan<const Int16> cell_mats(materials_view.components(local_id));
754 for (
Int16 x : cell_mats) {
756 if (x == modified_mat_id)
758 bool do_transform =
false;
759 Int16 my_env_id = env_for_mat[x];
761 Int16 my_mat_nb_env = nb_mat_computer.cellNbMaterial(local_id, my_env_id);
766 if (my_env_id != modified_env_id && (nb_mat_in_modified_env != 0))
768 do_transform = (nb_env == 1) && (my_mat_nb_env == 1);
778 do_transform = (my_env_id == modified_env_id) && (my_mat_nb_env == 2);
782 is_modified_materials[x] =
true;
791void ConstituentConnectivityList::
794 m_container->changeLocalIds(new_to_old_ids);
800void ConstituentConnectivityList::
801notifySourceItemAdded(ItemLocalId item)
803 Int32 lid = item.localId();
804 m_container->checkResize(lid + 1);
806 m_container->m_environment.m_nb_component_as_array[lid] = 0;
807 m_container->m_environment.m_component_index_as_array[lid] = 0;
809 m_container->m_material.m_nb_component_as_array[lid] = 0;
810 m_container->m_material.m_component_index_as_array[lid] = 0;
816void ConstituentConnectivityList::
817reserveMemoryForNbSourceItems(
Int32 n, [[maybe_unused]]
bool pre_alloc_connectivity)
819 info() <<
"Constituent: reserve=" << n;
820 m_container->reserve(n);
826void ConstituentConnectivityList::
834Ref<IIncrementalItemSourceConnectivity> ConstituentConnectivityList::
843void ConstituentConnectivityList::
844removeAllConnectivities()
846 m_container->m_environment.removeAllConnectivities();
847 m_container->m_material.removeAllConnectivities();
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Utility functions for the mesh.
bool checkResizeArray(Array< DataType > &array, Int64 new_size, bool force_resize)
Resizes an array that is indexed by 'ItemLocalId'.
#define RUNCOMMAND_LOOP1(iter_name, x1,...)
1D loop on accelerator with additional arguments.
Modifiable view of an array of type T.
void reserve(Int64 new_capacity)
Reserves memory for new_capacity elements.
ArrayView< T > subView(Int64 abegin, Integer asize)
Sub-view starting from element abegin and containing asize elements.
ArrayView< T > view() const
Mutable view of this array.
Template class for converting a type.
View onto a list of cell constituents.
Container for connectivity data for a constituent type.
Class for calculating the number of materials in an environment.
View of an array of elements of type T.
Unicode character string.
Parameters necessary for building a variable.
void updateFromInternal() override
Updates from the internal part.
Array< DataType > ContainerType
VariableRefArrayT< Int32 > VariableArrayInt32
Array variable of 32-bit integer type.
VariableRefArrayT< Int16 > VariableArrayInt16
Array variable of 16-bit integer type.
RunCommand makeCommand(const RunQueue &run_queue)
Creates a command associated with the queue run_queue.
bool isAcceleratorPolicy(eExecutionPolicy exec_policy)
Indicates if exec_policy corresponds to an accelerator.
Always enables tracing in Arcane parts concerning materials.
@ IncrementalRecompute
Indicates that the incremental version of AllEnvData::forceRecompute() is used.
Int32 checkResizeArrayWithCapacity(Array< DataType > &array, Int64 new_size, bool force_resize)
Resizes an array by adding a memory reserve.
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
std::int16_t Int16
Signed integer type of 16 bits.
std::int32_t Int32
Signed integer type of 32 bits.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.