14#include "arcane/utils/PlatformUtils.h"
15#include "arcane/utils/Convert.h"
16#include "arcane/utils/CheckedConvert.h"
17#include "arcane/utils/Array.h"
18#include "arcane/utils/StringBuilder.h"
19#include "arcane/utils/Iostream.h"
20#include "arcane/utils/ScopedPtr.h"
21#include "arcane/utils/NotImplementedException.h"
22#include "arcane/utils/ArgumentException.h"
24#include "arcane/core/ISubDomain.h"
25#include "arcane/core/IParallelMng.h"
27#include "arcane/core/IMeshSubMeshTransition.h"
28#include "arcane/core/ItemGroup.h"
29#include "arcane/core/Service.h"
30#include "arcane/core/Timer.h"
31#include "arcane/core/FactoryService.h"
32#include "arcane/core/ItemPrinter.h"
33#include "arcane/core/IItemFamily.h"
34#include "arcane/core/MeshVariable.h"
35#include "arcane/core/VariableBuildInfo.h"
36#include "arcane/core/CommonVariables.h"
37#include "arcane/utils/HashTableMap.h"
39#include "arcane_internal_config.h"
42#define MPICH_SKIP_MPICXX
43#define OMPI_SKIP_MPICXX
46#include "arcane/std/MeshPartitionerBase.h"
47#include "arcane/std/ZoltanMeshPartitioner_axl.h"
56#define ARCANE_DEBUG_ZOLTAN
73 ZOLTAN_GRAPH = (1<<1),
86 ZoltanInfo(
MeshPartitionerBase* basePartitionner,ostream* ofile,
int model=1,
const Real edgeWeightMultiplier = 1.)
88 , m_mesh_partitionner_base(basePartitionner)
94 , m_edge_weight_multiplier(edgeWeightMultiplier)
96 m_own_cells = m_mesh_partitionner_base->mesh()->ownCells();
107 Real m_edge_weight_multiplier;
108 std::set<std::pair<Int64, Int64> > m_weight_set;
112 info() <<
"ZoltanInfo::build()";
113 if (m_model & ZOLTAN_GEOM)
116 Integer nbOwnCells = m_own_cells.size();
119 if (m_model & ZOLTAN_HG) {
120 nbOwnEdges += nbOwnCells;
122 if (m_model & ZOLTAN_GRAPH) {
124 nbOwnEdges += nbOwnCells * 6;
128 IParallelMng* pm = m_mesh_partitionner_base->mesh()->parallelMng();
131 scanouille[pm->
commRank()] = nbOwnEdges;
134 for (
int i = 0 ; i < pm->
commRank() ; ++i) {
135 m_edgeGIDStart += scanouille[i];
142 if (!m_mesh_partitionner_base->cellUsedWithConstraints(*iCell))
145 int nbNgb = m_mesh_partitionner_base->nbNeighbourCellsWithConstraints(*iCell);
146 if (m_model & ZOLTAN_HG) {
148 m_nbPins += nbNgb + 1;
150 if (m_model & ZOLTAN_GRAPH) {
152 m_nbPins += (nbNgb*2);
156 info() <<
"nbEdges=" << m_nbEdges <<
" ; nbPins=" << m_nbPins;
158 if(m_mesh_partitionner_base->haveWeakConstraints())
161 ENUMERATE_FACE(iface,m_mesh_partitionner_base->mesh()->ownFaces())
163 const Face& face = *iface;
164 const Cell& bCell = iface->backCell();
165 const Cell& fCell = iface->frontCell();
168 if(weak_constraint[face]==2)
179 static int getHgNumVertices(
void *data,
int *ierr)
183 ZoltanInfo* zi = (ZoltanInfo*)data;
194 return zi->m_mesh_partitionner_base->nbOwnCellsWithConstraints();
197 static void getHgVerticesAndWeights(
void *data,
int num_gid_entries,
198 int num_lid_entries, ZOLTAN_ID_PTR gids, ZOLTAN_ID_PTR lids,
199 int wgt_dim,
float *obj_weights,
int *ierr)
201 ARCANE_UNUSED(num_gid_entries);
202 ARCANE_UNUSED(num_lid_entries);
204 ZoltanInfo* zi = (ZoltanInfo*)data;
217 if (zi->m_mesh_partitionner_base->nbCellWeight() <= wgt_dim) {
218 cells_weights = zi->m_mesh_partitionner_base->cellsWeightsWithConstraints(wgt_dim);
222 cells_weights = zi->m_mesh_partitionner_base->cellsSizeWithConstraints();
225 view_weights.
copy(cells_weights);
231 if (!zi->m_mesh_partitionner_base->cellUsedWithConstraints(*icell))
234 gids[index] = (*icell).uniqueId().asInt32();
235 lids[index] = zi->m_mesh_partitionner_base->localIdWithConstraints(*icell);
238 for(
int j=0; j< wgt_dim; ++j ){
239 float weight = cells_weights[lids[index]*wgt_dim+j];
240 *obj_weights++ = weight;
242 (*zi->m_ofile) <<
" Weight uid=" << gids[index] <<
" w=" << weight <<
'\n';
250 static void getHgSizeAndFormat(
void *data,
int *num_lists,
int *num_pins,
int *format,
int *ierr)
252 ZoltanInfo* zi = (ZoltanInfo*)data;
254 zi->
info() <<
" ZoltanInfo::getHgSizeAndFormat() ";
263 *format = ZOLTAN_COMPRESSED_EDGE;
264 *num_pins = zi->m_nbPins;
265 *num_lists = zi->m_nbEdges;
270 zi->
info() <<
" ZoltanInfo::getHgSizeAndFormat() " <<
" num_list= " << *num_lists <<
" num_pins= " << *num_pins;
274 static void getHg(
void *data,
int num_gid_entries,
275 int nrowcol,
int npins,
int format,
276 ZOLTAN_ID_PTR z_vtxedge_GID,
int *z_vtxedge_ptr, ZOLTAN_ID_PTR z_pin_GID,
int *ierr)
278 ZoltanInfo* zi = (ZoltanInfo*)data;
280 zi->
info() <<
" ZoltanInfo::getHg() "
281 <<
" num_gid_entries= " << num_gid_entries
282 <<
" nrowcol= " << nrowcol
283 <<
" npins= " << npins
284 <<
" format= " << format;
291 int gid = zi->m_edgeGIDStart;
292 z_vtxedge_ptr[0] = 0;
294 const Cell& item = *i_item;
296 if (!zi->m_mesh_partitionner_base->cellUsedWithConstraints(item))
299 neighbour_cells.
resize(0);
300 zi->m_mesh_partitionner_base->getNeighbourCellsUidWithConstraints(item,
303 if (zi->m_model & ZOLTAN_HG)
306 z_pin_GID[indexPin++] = CheckedConvert::toInteger(neighbour_cells[z]);
307 z_pin_GID[indexPin++] = item.
uniqueId().asInt32();
308 z_vtxedge_GID[indexEdge] = gid++;
310 z_vtxedge_ptr[indexEdge+1] = z_vtxedge_ptr[indexEdge] + neighbour_cells.
size() + 1;
314 if (zi->m_model & ZOLTAN_GRAPH)
318 for(
Integer z=0; z<neighbour_cells.
size(); ++z ) {
319 z_pin_GID[indexPin++] = CheckedConvert::toInteger(neighbour_cells[z]);
320 z_pin_GID[indexPin++] = (item.
uniqueId().asInt32());
321 z_vtxedge_GID[indexEdge] = gid++;
322 z_vtxedge_ptr[indexEdge+1] = z_vtxedge_ptr[indexEdge] + 2;
328 for (
int i = 0 ; i < nrowcol ; ++i) {
329 (*zi->m_ofile) <<
"*topo GID " << z_vtxedge_GID[i]
330 <<
" : " << z_vtxedge_ptr[i+1] - z_vtxedge_ptr[i];
331 for (
int j = z_vtxedge_ptr[i] ; j < z_vtxedge_ptr[i+1] ; ++j) {
332 (*zi->m_ofile) <<
'\t' << z_pin_GID[j];
334 (*zi->m_ofile) <<
'\n';
347 static void getHgVertexSizes (
void *data,
int num_gid_entries,
int num_lid_entries,
348 int num_ids, ZOLTAN_ID_PTR global_ids, ZOLTAN_ID_PTR local_ids,
349 int *sizes,
int *ierr)
351 ARCANE_UNUSED(num_gid_entries);
352 ARCANE_UNUSED(num_lid_entries);
353 ARCANE_UNUSED(global_ids);
355 ZoltanInfo* zi = (ZoltanInfo*)data;
357 SharedArray<float> cellSizes = zi->m_mesh_partitionner_base->cellsSizeWithConstraints();
359 for (
int i = 0 ; i < num_ids ; ++i)
367 static void getHgEdgeWeightSize(
void *data,
int *num_edges,
int *ierr)
369 ZoltanInfo* zi = (ZoltanInfo*)data;
380 *num_edges = zi->m_nbEdges;
384 static void getHgEdgeWeights(
void *data,
int num_gid_entries,
385 int num_lid_entries,
int nedges,
int edge_weight_dim,
386 ZOLTAN_ID_PTR edge_GID, ZOLTAN_ID_PTR edge_LID,
float *edge_weight,
int *ierr)
388 ARCANE_UNUSED(num_lid_entries);
390 ZoltanInfo* zi = (ZoltanInfo*)data;
396 zi->
info() <<
" ZoltanInfo::getHgEdgeWeights() "
397 <<
" num_gid_entries= " << num_gid_entries
398 <<
" nedges= " << nedges
399 <<
" edge_weight_dim= " << edge_weight_dim;
404 connectivityWeights.
reserve(6);
410 if (!zi->m_mesh_partitionner_base->cellUsedWithConstraints(item))
413 connectivityWeights.
resize(0);
414 neighbour_cells.
resize(0);
415 bool hg_model=(zi->m_model & ZOLTAN_HG);
418 zi->m_mesh_partitionner_base->getNeighbourCellsUidWithConstraints(item,
419 neighbour_cells, &connectivityWeights, hg_model);
421 if (zi->m_model & ZOLTAN_HG) {
422 if (!(zi->m_model & ZOLTAN_GRAPH)) {
424 for(
Integer z=0; z<neighbour_cells.
size(); ++z ) {
425 he_weight += connectivityWeights[z];
428 edge_GID[indexEdge] = indexEdge + zi->m_edgeGIDStart;
429 edge_LID[indexEdge] = indexEdge;
430 edge_weight[indexEdge++] = (float)he_weight;
433 if (zi->m_model & ZOLTAN_GRAPH) {
437 edge_GID[indexEdge] = indexEdge + zi->m_edgeGIDStart;
438 edge_LID[indexEdge] = indexEdge;
439 Real w = connectivityWeights[z];
440 edge_weight[indexEdge] = (float)w;
441 if (zi->m_mesh_partitionner_base->haveWeakConstraints()){
442 std::pair<Int64,Int64> items(item.
uniqueId(), neighbour_cells[z]);
443 if(zi->m_mesh_partitionner_base->cellUsedWithWeakConstraints(items)){
444 edge_weight[indexEdge] *= (float)zi->m_edge_weight_multiplier;
455 static int get_num_geometry(
void *data,
int *ierr)
463 static void get_geometry_list(
void *data,
int sizeGID,
int sizeLID,
465 ZOLTAN_ID_PTR global_ids, ZOLTAN_ID_PTR local_ids,
466 int num_dim,
double *geom_vec,
int *ierr)
468 ARCANE_UNUSED(global_ids);
469 ARCANE_UNUSED(local_ids);
471 ZoltanInfo* zi = (ZoltanInfo*)data;
473 if ( (sizeGID != 1) || (sizeLID != 1) || (num_dim > 3)){
474 *ierr = ZOLTAN_FATAL;
483 if (!zi->m_mesh_partitionner_base->cellUsedWithConstraints(*icell))
490 for(
Integer z=0, zs = (*icell).nbNode(); z<zs; ++z ){
491 const Node& node = (*icell).node(z);
496 geom_vec[num_dim*i ] = bar.x;
497 geom_vec[num_dim*i+1] = bar.y;
498 geom_vec[num_dim*i+2] = bar.z;
503 if (!s.
null() && (s ==
"MYGEOM")) {
504 for (
int i = 0 ; i < num_obj ; ++i) {
505 geom_vec[num_dim*i+num_dim-1] = 0.0;
519class ZoltanMeshPartitioner
543ZoltanMeshPartitioner::
544ZoltanMeshPartitioner(
const ServiceBuildInfo& sbi)
545 : ArcaneZoltanMeshPartitionerObject(sbi)
555 Int32 nb_part =
mesh()->parallelMng()->commSize();
565 info() <<
"Load balancing with Zoltan\n";
569 int rc = ::Zoltan_Initialize(0,0,&ver);
570 Zoltan_Memory_Debug(2);
572 fatal() <<
"Can not initialize zoltan (r=" << rc <<
")";
581 warning() <<
"Unable to test load balancing on a single sub-domain";
585 Integer nb_weight = nbCellWeight();
587 struct Zoltan_Struct *zz;
592 ZOLTAN_ID_PTR importGlobalIds;
593 ZOLTAN_ID_PTR importLocalIds;
597 ZOLTAN_ID_PTR exportGlobalIds;
608 zz = Zoltan_Create(*(MPI_Comm*)getCommunicator());
610 Zoltan_Set_Param(zz,
"RCB_REUSE",
"1");
619 if (!s.null() &&
options()->model.isPresent())
620 fatal() <<
"Conflicting configuration between ZOLTAN_MODEL environment variable and user data set";
621 usePHG =
options()->useHypergraphe();
626 }
else if (s.null()) {
632 if (subDomain()->commonVariables().globalIteration() <= 2)
638 String algo =
"HYPERGRAPH";
639 if (s ==
"MYHG" || s ==
"OLDHG" || s ==
"DUALHG" || s ==
"GRAPH") {
642 }
else if (s ==
"RIB" || s==
"HSFC") {
645 }
else if (s ==
"RCB" || s ==
"MYGEOM") {
649 fatal() <<
"Undefined zoltan model '" << s <<
"'";
652 int model = ZOLTAN_HG;
653 if (usePHG ==
false) {
658 model |= ZOLTAN_GRAPH;
659 }
else if (s ==
"GRAPH") {
660 model = ZOLTAN_GRAPH;
667 Real edgeWeightMultiplier = 1;
668 Integer repartitionFrequency = 10;
669 Real imbalanceTol = 1.05;
670 Real phgRepartMultiplier = 10;
676 edgeWeightMultiplier =
options()->edgeWeightMultiplier();
677 repartitionFrequency =
options()->repartFrequency();
678 imbalanceTol =
options()->imbalanceTol();
679 phgRepartMultiplier =
options()->phgRepartMultiplier();
680 phgOutputLevel =
options()->phgOutputLevel();
681 debugLevel =
options()->debugLevel();
685 info() <<
"Zoltan: utilise un repartitionnement " << algo <<
" (" << s <<
").";
686 Zoltan_Set_Param(zz,
"LB_METHOD", algo.localstr());
687 Zoltan_Set_Param(zz,
"HYPERGRAPH_PACKAGE",
"PHG");
689 if(
mesh->subDomain()->commonVariables().globalIteration()==1)
691 Zoltan_Set_Param(zz,
"LB_APPROACH",
"PARTITION");
692 info() <<
"Zoltan: Partition";
694 else if(
mesh->subDomain()->commonVariables().globalIteration()%repartitionFrequency==0 && repartitionFrequency!=-1)
696 Zoltan_Set_Param(zz,
"LB_APPROACH",
"REPARTITION");
697 info() <<
"Zoltan: Repartition";
701 Zoltan_Set_Param(zz,
"LB_APPROACH",
"REFINE");
702 info() <<
"Zoltan: Refine";
705 String s_imbalaceTol(String::fromNumber(imbalanceTol));
706 Zoltan_Set_Param(zz,
"IMBALANCE_TOL", s_imbalaceTol.localstr());
708 String s_nb_part(String::fromNumber(nb_part));
709 Zoltan_Set_Param(zz,
"NUM_GLOBAL_PARTS", s_nb_part.localstr());
711 Zoltan_Set_Param(zz,
"NUM_GID_ENTRIES",
"1");
712 Zoltan_Set_Param(zz,
"NUM_LID_ENTRIES",
"1");
713 Zoltan_Set_Param(zz,
"RETURN_LISTS",
"EXPORT");
714 String s_nb_weight(String::fromNumber(nb_weight));
716 Zoltan_Set_Param(zz,
"OBJ_WEIGHT_DIM", s_nb_weight.localstr());
719 Zoltan_Set_Param(zz,
"ADD_OBJ_WEIGHT",
"NONE");
723 Zoltan_Set_Param(zz,
"FINAL_OUTPUT",
"0");
724 Zoltan_Set_Param(zz,
"PHG_USE_TIMERS",
"1");
726 String s_phgOutputLevel(String::fromNumber(phgOutputLevel));
727 Zoltan_Set_Param(zz,
"PHG_OUTPUT_LEVEL", s_phgOutputLevel.localstr());
730 Zoltan_Set_Param(zz,
"CHECK_HYPERGRAPH",
"0");
731 String s_debugLevel(String::fromNumber(debugLevel));
732 Zoltan_Set_Param(zz,
"DEBUG_LEVEL", s_debugLevel.localstr());
737 Zoltan_Set_Param(zz,
"PHG_COARSENING_METHOD",
"IPM");
741 Zoltan_Set_Param(zz,
"EDGE_WEIGHT_DIM",
"1");
742 Zoltan_Set_Param(zz,
"PHG_EDGE_WEIGHT_OPERATION",
"add");
744 if(!initial_partition)
748 String s_phgRepartMultiplier(String::fromNumber(phgRepartMultiplier));
749 Zoltan_Set_Param(zz,
"PHG_REPART_MULTIPLIER", s_phgRepartMultiplier.localstr());
754 Zoltan_Set_Param(zz,
"KEEP_CUTS",
"0");
755 Zoltan_Set_Param(zz,
"RCB_OUTPUT_LEVEL",
"0");
756 Zoltan_Set_Param(zz,
"RCB_RECTILINEAR_BLOCKS",
"0");
759 Zoltan_Set_Param(zz,
"OBJ_WEIGHTS_COMPARABLE",
"0");
763 Zoltan_Set_Param(zz,
"RCB_MULTICRITERIA_NORM",
"3");
764 Zoltan_Set_Param(zz,
"RCB_MAX_ASPECT_RATIO",
"10");
767 bool dump_infos =
false;
773 Integer iteration =
mesh->subDomain()->commonVariables().globalIteration();
779 ofile.open(f.localstr());
791 ScopedPtrT<ZoltanInfo> zoltan_info(
new ZoltanInfo(
this,zofile, model, edgeWeightMultiplier));
792 Zoltan_Set_Num_Obj_Fn(zz,&ZoltanInfo::getHgNumVertices, zoltan_info.get());
793 Zoltan_Set_Obj_List_Fn(zz, &ZoltanInfo::getHgVerticesAndWeights, zoltan_info.get());
794 if (!initial_partition) {
795 Zoltan_Set_Obj_Size_Multi_Fn(zz, &ZoltanInfo::getHgVertexSizes,
799 info() <<
"Setting up HG Callbacks";
800 Zoltan_Set_HG_Size_CS_Fn(zz, &ZoltanInfo::getHgSizeAndFormat, zoltan_info.get());
801 Zoltan_Set_HG_CS_Fn(zz, &ZoltanInfo::getHg, zoltan_info.get());
802 Zoltan_Set_HG_Size_Edge_Weights_Fn(zz, &ZoltanInfo::getHgEdgeWeightSize, zoltan_info.get());
803 Zoltan_Set_HG_Edge_Weights_Fn(zz, &ZoltanInfo::getHgEdgeWeights, zoltan_info.get());
807 info() <<
"Setting up Geom Callbacks";
808 Zoltan_Set_Num_Geom_Fn(zz, ZoltanInfo::get_num_geometry, zoltan_info.get());
809 Zoltan_Set_Geom_Multi_Fn(zz, ZoltanInfo::get_geometry_list, zoltan_info.get());
814 int* export_partitions = 0;
815 ZOLTAN_ID_PTR export_local_ids = 0;
817 info() <<
"Doing partition";
818 rc = Zoltan_LB_Partition(zz, &changes, &numGidEntries, &numLidEntries,
819 &numImport, &importGlobalIds, &importLocalIds,
820 &importProcs, &importToPart,
821 &numExport, &exportGlobalIds, &export_local_ids,
822 &exportProcs, &export_partitions);
827 cells_new_owner[icell] = (*icell).owner();
830 invertArrayLid2LidCompacted();
833 CellInfoListView items_internal(m_cell_family);
835 info() <<
"numExport = "<<numExport;
836 for(
Integer i=0; i<nb_export; ++i ){
837 Item item = items_internal[ localIdWithConstraints(export_local_ids[i]) ];
839 changeCellOwner(item, cells_new_owner, export_partitions[i]);
841 ofile <<
"EXPORT: uid=" << ItemPrinter(item) <<
" OLD=" << item.owner()
842 <<
" NEW=" << cells_new_owner[item] <<
" PROC=" << exportProcs[i] <<
'\n';
856 MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
859 Zoltan_LB_Free_Part(&exportGlobalIds, &export_local_ids,
860 &exportProcs, &export_partitions);
867 cells_new_owner.synchronize();
888#if ARCANE_DEFAULT_PARTITIONER == ZOLTAN_DEFAULT_PARTITIONER
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro pour déclarer une interface lors de l'enregistrement d'un service.
Integer size() const
Nombre d'éléments du vecteur.
CaseOptionsZoltanMeshPartitioner * options() const
Options du jeu de données du service.
ArcaneZoltanMeshPartitionerObject(const Arcane::ServiceBuildInfo &sbi)
Constructeur.
Exception lorsqu'un argument est invalide.
Vue modifiable d'un tableau d'un type T.
void copy(const U ©_array)
Recopie le tableau copy_array dans l'instance.
void fill(const DataType &data)
Remplissage du tableau.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
Cell frontCell() const
Maille devant la face (maille nulle si aucune)
Cell backCell() const
Maille derrière la face (maille nulle si aucune)
virtual ITraceMng * traceMng()=0
Gestionnaire de message associé
Interface d'un partitionneur de maillage.
Interface d'un partitionneur de maillage.
virtual IMesh * mesh() const =0
Maillage associé au partitionneur.
virtual VariableNodeReal3 & nodesCoordinates()=0
Coordonnées des noeuds.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual void scan(eReduceType rt, ArrayView< char > v)=0
Applique un algorithme de prefix-um sur les valeurs de v via l'opération rt.
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
virtual void barrier()=0
Effectue une barière.
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
constexpr bool null() const
true si l'entité est nul (i.e. non connecté au maillage)
Classe de base d'un service d'équilibrage de charge.
IMesh * mesh() const override
Maillage associé au partitionneur.
virtual void changeOwnersFromCells()
Positionne les nouveaux propriétaires des noeuds, arêtes et faces à partir des mailles.
Variable scalaire sur un type d'entité du maillage.
Classe gérant un vecteur de réel de dimension 3.
Structure contenant les informations pour créer un service.
Propriétés de création d'un service.
Vecteur 1D de données avec sémantique par référence.
Chaîne de caractères unicode.
bool null() const
Retourne true si la chaîne est nulle.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessage fatal() const
Flot pour un message d'erreur fatale.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage warning() const
Flot pour un message d'avertissement.
Vecteur 1D de données avec sémantique par valeur (style STL).
Paramètres nécessaires à la construction d'une variable.
Partitioneur de maillage utilisant la bibliotheque Zoltan.
virtual void notifyEndPartition()
Notification lors de la fin d'un re-partitionnement (après échange des entités)
virtual void build()
Construction de niveau build du service.
virtual void partitionMesh(bool initial_partition)
ItemGroupT< Cell > CellGroup
Groupe de mailles.
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro pour enregistrer un service.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
ItemVariableScalarRefT< Int32 > VariableItemInt32
Grandeur de type entier 32 bits.
Integer toInteger(Real r)
Converti un Real en Integer.
double toDouble(Real r)
Converti un Real en double.
@ ReduceSum
Somme des valeurs.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Int32 Integer
Type représentant un entier.
@ ST_SubDomain
Le service s'utilise au niveau du sous-domaine.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
@ IK_Cell
Entité de maillage de genre maille.
double Real
Type représentant un réel.
std::int32_t Int32
Type entier signé sur 32 bits.