74ParmetisLoadBalancer :: calculateLoadTransfer()
76 idx_t *eind, *eptr, *xadj, *adjncy, *vwgt, *vsize;
78 int i, nlocalelems, eind_size, nelem =
domain->giveNumberOfElements();
79 int ndofman, idofman, numflag, ncommonnodes, options [ 4 ], ie, nproc;
80 int edgecut, wgtflag, ncon;
81 real_t ubvec [ 1 ], itr;
83 MPI_Comm communicator = MPI_COMM_WORLD;
86 nproc =
domain->giveEngngModel()->giveNumberOfProcesses();
93 for ( i = 1; i <= nelem; i++ ) {
94 ielem =
domain->giveElement(i);
102 eind =
new idx_t [ eind_size ];
103 eptr =
new idx_t [ nlocalelems + 1 ];
104 if ( ( eind == NULL ) || ( eptr == NULL ) ) {
105 OOFEM_ERROR(
"failed to allocate eind and eptr arrays");
109 int eind_pos = 0, eptr_pos = 0;
110 for ( i = 1; i <= nelem; i++ ) {
111 ielem =
domain->giveElement(i);
113 eptr [ eptr_pos ] = eind_pos;
115 for ( idofman = 1; idofman <= ndofman; idofman++ ) {
124 eptr [ nlocalelems ] = eind_pos;
131 ParMETIS_V3_Mesh2Dual(
elmdist, eptr, eind, & numflag, & ncommonnodes, & xadj, & adjncy, & communicator);
133 #ifdef ParmetisLoadBalancer_DEBUG_PRINT
134 int myrank =
domain->giveEngngModel()->giveRank();
136 fprintf(stderr,
"[%d] xadj:", myrank);
137 for ( i = 0; i <= nlocalelems; i++ ) {
138 fprintf(stderr,
" %d", xadj [ i ]);
141 fprintf(stderr,
"\n[%d] adjncy:", myrank);
142 for ( i = 0; i < xadj [ nlocalelems ]; i++ ) {
143 fprintf(stderr,
" %d", adjncy [ i ]);
146 fprintf(stderr,
"\n");
162 if ( (
tpwgts =
new real_t [ nproc ] ) == NULL ) {
167 for ( i = 0; i < nproc; i++ ) {
168 tpwgts [ i ] = _procweights(i);
179 if ( ( vwgt =
new idx_t [ nlocalelems ] ) == NULL ) {
183 if ( ( vsize =
new idx_t [ nlocalelems ] ) == NULL ) {
187 for ( ie = 0, i = 0; i < nelem; i++ ) {
188 ielem =
domain->giveElement(i + 1);
198 if ( ( part =
new idx_t [ nlocalelems ] ) == NULL ) {
203 ParMETIS_V3_AdaptiveRepart(
elmdist, xadj, adjncy, vwgt, vsize, NULL, & wgtflag, & numflag, & ncon, & nproc,
204 tpwgts, ubvec, & itr, options, & edgecut, part, & communicator);
211 for ( i = 1; i <= nelem; i++ ) {
212 ielem =
domain->giveElement(i);
226 #ifdef ParmetisLoadBalancer_DEBUG_PRINT
228 fprintf(stderr,
"[%d] edgecut: %d elementPart:", myrank, edgecut);
229 for ( i = 1; i <= nelem; i++ ) {
233 fprintf(stderr,
"\n");
248ParmetisLoadBalancer :: initGlobalParmetisElementNumbering()
250 int nproc =
domain->giveEngngModel()->giveNumberOfProcesses();
251 int myrank =
domain->giveEngngModel()->giveRank();
256 elmdist =
new idx_t [ nproc + 1 ];
263 int i, nlocelem = 0, nelem =
domain->giveNumberOfElements();
266 for ( i = 1; i <= nelem; i++ ) {
272 procElementCounts(myrank) = nlocelem;
274 MPI_Allgather(& nlocelem, 1, MPI_INT, procElementCounts.
givePointer(), 1, MPI_INT, MPI_COMM_WORLD);
276 for ( i = 0; i < nproc; i++ ) {
283 for ( i = 0; i < myrank; i++ ) {
294 for ( i = 1; i <= nelem; i++ ) {
306ParmetisLoadBalancer :: labelDofManagers()
308 int idofman, ndofman =
domain->giveNumberOfDofManagers();
314 std :: set< int, std :: less< int > >__dmanpartitions;
315 int myrank =
domain->giveEngngModel()->giveRank();
316 int nproc =
domain->giveEngngModel()->giveNumberOfProcesses();
326 #ifdef ParmetisLoadBalancer_DEBUG_PRINT
328 fprintf(stderr,
"[%d] DofManager labels:\n", myrank);
332 for ( idofman = 1; idofman <= ndofman; idofman++ ) {
333 dofman =
domain->giveDofManager(idofman);
337 __dmanpartitions.
clear();
338 for ( ie = 1; ie <= dofmanconntable->
giveSize(); ie++ ) {
339 ielem =
domain->giveElement( dofmanconntable->
at(ie) );
347 npart = __dmanpartitions.size();
350 for (
auto &dm: __dmanpartitions ) {
363 com.
packAllData(
this, & ParmetisLoadBalancer :: packSharedDmanPartitions);
365 com.
unpackAllData(
this, & ParmetisLoadBalancer :: unpackSharedDmanPartitions);
369 for ( idofman = 1; idofman <= ndofman; idofman++ ) {
370 dofman =
domain->giveDofManager(idofman);
382 #ifdef ParmetisLoadBalancer_DEBUG_PRINT
383 for ( idofman = 1; idofman <= ndofman; idofman++ ) {
384 fprintf(stderr,
" | %d: ", idofman);
386 fprintf(stderr,
"NULL ");
388 fprintf(stderr,
"Local ");
390 fprintf(stderr,
"Shared");
392 fprintf(stderr,
"Remote");
394 fprintf(stderr,
"Unknown");
401 if ( ( ( ++_cols % 4 ) == 0 ) || ( idofman == ndofman ) ) {
402 fprintf(stderr,
"\n");
565void ParmetisLoadBalancer :: handleMasterSlaveDofManLinks()
567 int idofman, ndofman =
domain->giveNumberOfDofManagers();
570 int __i, __j, __partition, _master;
584 for ( idofman = 1; idofman <= ndofman; idofman++ ) {
585 dofman =
domain->giveDofManager(idofman);
591 for ( __i = 1; __i <= slaveMastersDofMans.
giveSize(); __i++ ) {
593 _master = slaveMastersDofMans.
at(__i);
596 for ( __j = 1; __j <=
dofManPartitions [ idofman - 1 ].giveSize(); __j++ ) {