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();
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);
173 void notifyUpdateConnectivityList()
180 _resetConnectivities();
200 void _resetConnectivities()
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) {
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::
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;
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();
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);
502 return m_container->m_environment.m_nb_component_as_array;
511 return m_container->m_material.m_nb_component_as_array;
526 for (
Int16 mat_id : mats) {
527 Int16 current_id = environment_for_materials[mat_id];
528 if (current_id == env_id)
549 Int32 cell_id = cells_local_id[i];
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;
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();
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;
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);
683 int modified_mat_id,
bool is_add,
const RunQueue& queue)
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];
711 for (
Int16 x : cell_envs)
712 is_modified_environments[x] =
true;
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];
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;
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;
794 m_container->changeLocalIds(new_to_old_ids);
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;
819 info() <<
"Constituent: reserve=" << n;
820 m_container->reserve(n);
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.
Class to perform a 'sum' reduction.
Execution queue for an accelerator.
eExecutionPolicy executionPolicy() const
Execution policy of the queue.
bool isAcceleratorPolicy() const
Indicates if the instance is associated with an accelerator.
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.
Constant view of an array of type T.
Template class for converting a type.
virtual ItemVectorView view(Int32ConstArrayView local_ids)=0
View on the entities.
virtual IItemFamilyInternal * _internalApi()=0
Internal Arcane API.
virtual IItemFamily * cellFamily()=0
Returns the cell family.
virtual TraceMessage info()=0
Stream for an information message.
Index of an Item in a variable.
View onto a list of cell constituents.
Container for connectivity data for a constituent type.
VariableArrayInt32 m_component_index
Index in m_component_list (Sized according to the number of cells).
VariableArrayInt16 m_nb_component
Number of environments per cell (sized according to the number of cells).
VariableArrayInt16 m_component_list
List of constituents.
Class for calculating the number of materials in an environment.
SmallSpan< const Int16 > m_environment_for_materials
View indicating the environment associated with the materials.
ConstArrayView< Int16 > cellsNbMaterial() const
Arrays of the total number of materials per cell (indexed by localId()).
void printConstituents(SmallSpan< const Int32 > cells_local_id) const
Displays the constituents of a list of entities.
void fillCellsNbMaterial(SmallSpan< const Int32 > cells_local_id, Int16 env_id, SmallSpan< Int16 > cells_nb_material, RunQueue &queue)
Fills cells_nb_material with the number of materials of environment env_id.
void fillModifiedConstituents(SmallSpan< const Int32 > cells_local_id, SmallSpan< bool > is_modified_materials, SmallSpan< bool > is_modified_environments, int modified_mat_id, bool is_add, const RunQueue &queue)
Fills the constituents affected by a modification.
void notifySourceItemAdded(ItemLocalId item) override
Notifies the connectivity that an entity has been added to the source family.
Int16 cellNbMaterial(CellLocalId cell_id, Int16 env_id)
Number of materials of the cell cell_id for environment index env_id.
ConstArrayView< Int16 > cellsNbEnvironment() const
Arrays of the total number of environments per cell (indexed by localId()).
void notifyReadFromDump() override
Notifies the connectivity that a read has been performed from a dump.
UniqueArray< Int16 > m_environment_for_materials
Index of the environment to which a material belongs.
void notifySourceFamilyLocalIdChanged(Int32ConstArrayView new_to_old_ids) override
Notifies the connectivity that the source family has been compacted.
void removeAllConnectivities()
Removes all connected entities.
Int32 fillCellsToTransform(SmallSpan< const Int32 > cells_local_id, Int16 env_id, SmallSpan< bool > cells_do_transform, bool is_add, RunQueue &queue)
Fills cells_do_transform indicating if the cell transitions from pure to partial.
Ref< IIncrementalItemSourceConnectivity > toSourceReference() override
Returns a reference to the instance.
void reserveMemoryForNbSourceItems(Int32 n, bool pre_alloc_connectivity) override
Reserves memory for n source entities.
void fillCellsIsPartial(SmallSpan< const Int32 > cells_local_id, Int16 env_id, SmallSpan< bool > cells_is_partial, RunQueue &queue)
Fills cells_is_partial indicating if the cell is partial for environment env_id.
Implementation of a material manager.
IMesh * mesh() override
Associated mesh.
int modificationFlags() const override
Flags to parameterize modifications.
Reference to an instance.
View of an array of elements of type T.
constexpr __host__ __device__ SizeType size() const noexcept
Returns the size of the array.
Unicode character string.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage info() const
Flow for an information message.
ITraceMng * traceMng() const
Trace manager.
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.