14#include "arcane/utils/PlatformUtils.h"
15#include "arcane/utils/NotImplementedException.h"
16#include "arcane/utils/ITraceMng.h"
18#include "arcane/core/IParallelMng.h"
19#include "arcane/core/IPrimaryMesh.h"
20#include "arcane/core/IMeshUtilities.h"
21#include "arcane/core/IMeshPartitioner.h"
22#include "arcane/core/IItemFamily.h"
23#include "arcane/core/ItemVector.h"
26#include "arcane/core/IMeshPartitionConstraintMng.h"
27#include "arcane/impl/ArcaneGeometricMeshPartitionerService_axl.h"
70 const int nb_value = 3;
76 for (
int i = (nb_value - 1); i >= 0; --i) {
86 _deflateMatrix(matrix, result.eigen_value, result.eigen_vector);
97 void _deflateMatrix(
Real3x3& matrix,
double eigenvalue,
Real3 eigenvector)
99 for (
int i = 0; i < 3; ++i) {
100 for (
int j = 0; j < 3; ++j) {
101 matrix[i][j] -= eigenvalue * eigenvector[i] * eigenvector[j];
107 PowerResult _applyPowerIteration(
const Real3x3& matrix)
109 int max_iteration = 1000;
110 Real tolerance = 1e-16;
111 Real eigenvalue = 0.0;
114 Real3 b{ 1.0, 1.0, 1.0 };
118 for (
int iter = 0; iter < max_iteration; ++iter) {
122 eigenvalue = b_next.normL2();
123 b_next = b_next / eigenvalue;
127 if (diff < tolerance) {
134 return { eigenvalue, b_next };
190class ArcaneGeometricMeshPartitionerService
196 explicit ArcaneGeometricMeshPartitionerService(
const ServiceBuildInfo& sbi);
200 IMesh*
mesh()
const override {
return BasicService::mesh(); }
205 _partitionMesh(initial_partition, nb_part);
213 Real maximumComputationTime()
const override {
return m_max_computation_time; }
225 m_cells_weight = weights;
226 m_nb_weight = nb_weight;
241 Real m_imbalance = 0.0;
242 Real m_max_imbalance = 0.0;
243 Real m_max_computation_time = 0.0;
244 Int32 m_nb_weight = 0;
245 ArrayView<float> m_cells_weight;
246 UniqueArray<Real> m_computation_times;
252 Real3x3 _computeInertiaTensor(Real3 center,
const VariableCellReal3& cells_center,
254 Real3 _findPrincipalAxis(Real3x3 tensor);
255 void _partitionMesh2();
256 void _partitionMesh(
bool initial_partition, Int32 nb_part);
260 Real3 _computeEigenValuesAndVectors(ITraceMng* tm, Real3x3 tensor, Real3x3& eigen_vectors, Real3& eigen_values);
266ArcaneGeometricMeshPartitionerService::
276Real3 ArcaneGeometricMeshPartitionerService::
282 center += cells_center[icell];
284 Int64 local_nb_cell = cells.size();
287 Real3 global_center = sum_center /
static_cast<Real>(total_nb_cell);
288 return global_center;
296Real3x3 ArcaneGeometricMeshPartitionerService::
304 Real3 cell_coord = cells_center[icell];
305 double dx = cell_coord.x - center.x;
306 double dy = cell_coord.y - center.y;
307 double dz = cell_coord.z - center.z;
309 tensor[0][0] += dy * dy + dz * dz;
310 tensor[1][1] += dx * dx + dz * dz;
311 tensor[2][2] += dx * dx + dy * dy;
312 tensor[0][1] -= dx * dy;
313 tensor[0][2] -= dx * dz;
314 tensor[1][2] -= dy * dz;
319 sum_tensor[1][0] = sum_tensor[0][1];
320 sum_tensor[2][0] = sum_tensor[0][2];
321 sum_tensor[2][1] = sum_tensor[1][2];
331Real3 ArcaneGeometricMeshPartitionerService::
332_findPrincipalAxis(
Real3x3 tensor)
334 info() <<
"Tensor=" << tensor;
336 EigenValuesAndVectorComputer eigen_computer;
337 eigen_computer.computeForMatrix(tensor);
338 info() <<
"EigenValues = " << eigen_computer.eigenValues();
339 info() <<
"EigenVectors = " << eigen_computer.eigenVectors();
340 Real3 v4 = eigen_computer.eigenVectors()[0];
341 info() <<
"V4=" << v4;
349void ArcaneGeometricMeshPartitionerService::
355 CellVector cells_vector(cell_family, cell_family->allItems().own().view().localIds());
358 info() <<
"** ** DO_PARTITION_MESH2 nb_cell=" << cells.size();
365 for (NodeLocalId n : icell->nodeIds())
366 c += nodes_coordinates[n];
367 cells_center[icell] = c / icell->nbNode();
371 Int32 partition_index = 0;
373 _partitionMeshRecursive(cells_center, cells, partition_index, part_id);
379bool ArcaneGeometricMeshPartitionerService::
383 Int32 part0_partition_index = partition_index;
384 Int32 part1_partition_index = partition_index + 1;
387 info() <<
"Doing partition partition_index=" << partition_index <<
" total_nb_cell=" << total_nb_cell;
388 if (part1_partition_index >= m_nb_part)
391 info() <<
"Doing partition really partition_index=" << partition_index;
396 Real3 center = _computeBarycenter(cells_center, cells);
397 info() <<
"GlobalCenter=" << center;
400 Real3x3 tensor = _computeInertiaTensor(center, cells_center, cells);
403 Real3 eigenvector = _findPrincipalAxis(tensor);
404 info() <<
"EigenVector=" << eigenvector;
406 const Int32 nb_cell = cells.size();
407 UniqueArray<Int32> part0_cells;
408 part0_cells.reserve(nb_cell);
409 UniqueArray<Int32> part1_cells;
410 part1_cells.reserve(nb_cell);
416 info() <<
"Doing partition setting partition=" << part0_partition_index <<
" " << part1_partition_index;
418 const Real3 cell_coord = cells_center[icell];
420 Real projection = 0.0;
421 projection += (cell_coord.x - center.x) * eigenvector.x;
422 projection += (cell_coord.y - center.y) * eigenvector.y;
423 projection += (cell_coord.z - center.z) * eigenvector.z;
425 if (projection < 0.0) {
426 part0_cells.add(icell.itemLocalId());
429 part1_cells.add(icell.itemLocalId());
441 if (_partitionMeshRecursive(cells_center, part0, (2 * partition_index) + 1, part_id)) {
442 info() <<
"Filling left part part_index=" << part_id <<
" nb_cell=" << part0.size();
444 cells_new_owner[icell] = part_id;
448 if (_partitionMeshRecursive(cells_center, part1, (2 * partition_index) + 2, part_id)) {
449 info() <<
"Filling right part part_index=" << part_id <<
" nb_cell=" << part1.size();
451 cells_new_owner[icell] = part_id;
461void ArcaneGeometricMeshPartitionerService::
462_partitionMesh([[maybe_unused]]
bool initial_partition,
Int32 nb_part)
468 info() <<
"Doing mesh partition with ArcaneGeometricMeshPartitionerService nb_part=" << nb_part;
469 IParallelMng* pm =
mesh->parallelMng();
470 Int32 nb_rank = pm->commSize();
479 cells_new_owner.synchronize();
480 if (
mesh->partitionConstraintMng()) {
482 mesh->partitionConstraintMng()->computeAndApplyConstraints();
484 mesh->utilities()->changeOwnersFromCells();
490void ArcaneGeometricMeshPartitionerService::
495 for (
Int32 i = 0; i < m_nb_part; ++i) {
498 if (cells_new_owner[icell] == i)
511 _partitionMesh(initial_partition,
mesh()->parallelMng()->commSize());
517ARCANE_REGISTER_SERVICE_ARCANEGEOMETRICMESHPARTITIONERSERVICE(ArcaneGeometricMeshPartitioner,
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
Fonctions mathématiques diverses.
Generation de la classe de base du Service.
ArcaneArcaneGeometricMeshPartitionerServiceObject(const Arcane::ServiceBuildInfo &sbi)
Constructeur.
Service de partitionnement géométrique de maillage.
void setImbalance(Real v) override
Positionne le déséquilibre de temps de calcul.
void setComputationTimes(RealConstArrayView v) override
Temps de calcul de se sous-domaine. Le premier élément indique le temps de calcul du sous-domaine cor...
void setMaxImbalance(Real v) override
Positionne le déséquilibre maximal autorisé
void build() override
Construction de niveau build du service.
void notifyEndPartition() override
Notification lors de la fin d'un re-partitionnement (après échange des entités)
IMesh * mesh() const override
Maillage associé au partitionneur.
Real imbalance() const override
Déséquilibre de temps de calcul.
void partitionMesh(bool initial_partition) override
void setILoadBalanceMng(ILoadBalanceMng *) override
Change le ILoadBalanceMng à utiliser.
Real maxImbalance() const override
Déséquilibre maximal autorisé
void setCellsWeight(ArrayView< float > weights, Integer nb_weight) override
Permet de définir les poids des objets à partitionner : on doit utiliser le ILoadBalanceMng maintenan...
void setMaximumComputationTime(Real v) override
Positionne la proportion du temps de calcul.
Vue modifiable d'un tableau d'un type T.
Classe pour calculer les valeurs et vecteurs propres d'une matrice.
Real3 m_eigen_values
Valeurs propres.
void computeForMatrix(const Real3x3 &orig_matrix)
Calcule les valeurs et vecteurs propres de orig_matrix.
Real3x3 m_eigen_vectors
Vecteurs propres.
Real3 eigenValues() const
Retourne les valeurs propres de la matrice par ordre croissant.
Real3x3 eigenVectors() const
Retourne les vecteurs propres de la matrice par ordre croissant.
Interface d'enregistrement des variables pour l'equilibrage de charge.
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
Interface d'un partitionneur de maillage.
virtual VariableNodeReal3 & nodesCoordinates()=0
Coordonnées des noeuds.
virtual IParallelMng * parallelMng()=0
Gestionnaire de parallèlisme.
virtual IPrimaryMesh * toPrimaryMesh()=0
Retourne l'instance sous la forme d'un IPrimaryMesh.
virtual char reduce(eReduceType rt, char v)=0
Effectue la réduction de type rt sur le réel v et retourne la valeur.
virtual VariableItemInt32 & itemsNewOwner(eItemKind kind)=0
Variable contenant l'identifiant du sous-domaine propriétaire.
CellGroup ownCells() const
Retourne le groupe contenant toutes les mailles propres à ce domaine.
Exception lorsqu'une fonction n'est pas implémentée.
Classe gérant un vecteur de réel de dimension 3.
Classe gérant une matrice de réel de dimension 3x3.
Structure contenant les informations pour créer un service.
TraceMessage info() const
Flot pour un message d'information.
ItemVectorT< Cell > CellVector
Vecteur de mailles.
ItemVectorViewT< Cell > CellVectorView
Vue sur un vecteur de mailles.
MeshVariableScalarRefT< Cell, Real3 > VariableCellReal3
Grandeur au centre des mailles de type coordonnées.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
ItemVariableScalarRefT< Int32 > VariableItemInt32
Grandeur de type entier 32 bits.
@ ReduceSum
Somme des valeurs.
constexpr __host__ __device__ Real squareNormL2(const Real2 &v)
Retourne la norme au carré du couple .
__host__ __device__ Real3 multiply(const Real3x3 &m, Real3 v)
Produit matrice 3x3 . vecteur.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
@ IK_Cell
Entité de maillage de genre maille.
double Real
Type représentant un réel.
@ Cell
Le maillage est AMR par maille.
std::int32_t Int32
Type entier signé sur 32 bits.
ConstArrayView< Real > RealConstArrayView
Equivalent C d'un tableau à une dimension de réels.
Résultat de l'application de la méthode de la puissance.