47#ifdef __MPI_PARALLEL_MODE
59#ifndef __MPI_PARALLEL_MODE
61LoadBalancer :: LoadBalancer(
Domain *d) : wtpList()
66void LoadBalancer::migrateLoad(Domain *d) {}
67void LoadBalancer::printStatistics()
const {}
68void LoadBalancer::initializeFrom(InputRecord &ir) { }
69void LoadBalancerMonitor::initializeFrom(InputRecord &ir) { }
97 for (
int iwtp: wtp ) {
98 std :: unique_ptr< WorkTransferPlugin > plugin;
100 plugin = std::make_unique<NonlocalMaterialWTP>(
this);
105 wtpList.push_back(std :: move( plugin ));
130 com.
packAllData(
this, d, & LoadBalancer :: packMigratingData);
141 com.
unpackAllData(
this, d, & LoadBalancer :: unpackMigratingData);
147#ifdef LoadBalancer_debug_print
150 fprintf(stderr,
"\n[%d] Nodal Table\n", myrank);
151 for (
int i = 1; i <= nnodes; i++ ) {
156 for (
int j = 1; j <= d->
giveDofManager(i)->givePartitionList()->giveSize(); j++ ) {
160 fprintf(stderr,
"\n");
164 fprintf(stderr,
"\n[%d] Element Table\n", myrank);
165 for (
int i = 1; i <= nelems; i++ ) {
166 fprintf(stderr,
"%5d {", i);
167 for (
int j = 1; j <= d->
giveElement(i)->giveNumberOfDofManagers(); j++ ) {
171 fprintf(stderr,
"}\n");
187#ifdef LoadBalancer_debug_print
191 fprintf(stderr,
"LB Debug print (after wtp update):\n");
192 fprintf(stderr,
"\n[%d] Nodal Table\n", myrank);
193 for (
int i = 1; i <= nnodes; i++ ) {
198 for (
int j = 1; j <= d->
giveDofManager(i)->givePartitionList()->giveSize(); j++ ) {
202 fprintf(stderr,
"\n");
206 fprintf(stderr,
"\n[%d] Element Table\n", myrank);
207 for (
int i = 1; i <= nelems; i++ ) {
209 for (
int j = 1; j <= d->
giveElement(i)->giveNumberOfDofManagers(); j++ ) {
213 fprintf(stderr,
"}\n");
221 int nelem =
domain->giveNumberOfElements();
222 int nnode =
domain->giveNumberOfDofManagers();
223 int lnode = 0, lelem = 0;
225 for (
int i = 1; i <= nnode; i++ ) {
231 for (
int i = 1; i <= nelem; i++ ) {
237 OOFEM_LOG_RELEVANT(
"[%d] LB Statistics: local elem=%d local node=%d\n", myrank, lelem, lnode);
251 if ( iproc == myrank ) {
259 for (
int idofman = 1; idofman <= ndofman; idofman++ ) {
285 for (
int ielem = 1; ielem <= nelem; ielem++ ) {
288 ( this->giveElementPartition(ielem) == iproc ) ) {
301 OOFEM_LOG_RELEVANT(
"[%d] LoadBalancer:: sending %d migrating elements to %d\n", myrank, nsend, iproc);
321 IntArray _partitions, local_partitions;
330 if ( iproc == myrank ) {
339 if ( !pcbuff->
read(_type) ) {
342 if ( _type.size() == 0 ) {
347 case LoadBalancer :: DM_Remote:
349 pcbuff->
read(_globnum);
359 dofman =
classFactory.createDofManager(_type.c_str(), 0, d).release();
376 case LoadBalancer :: DM_Shared:
379 pcbuff->
read(_globnum);
389 dofman =
classFactory.createDofManager(_type.c_str(), 0, d).release();
398#ifdef __VERBOSE_PARALLEL
399 fprintf(stderr,
"[%d] received Shared new dofman [%d]\n", myrank, _globnum);
410 OOFEM_ERROR(
"unexpected dof manager mode (%d)", _mode);
419 if ( _type.size() == 0 ) {
423 elem =
classFactory.createElement(_type.c_str(), 0, d).release();
431 OOFEM_LOG_RELEVANT(
"[%d] LoadBalancer:: receiving %d migrating elements from %d\n", myrank, nrecv, iproc);
442LoadBalancer :: deleteRemoteDofManagers(
Domain *d)
446 LoadBalancer :: DofManMode dmode;
452 for (
int i = 1; i <= ndofman; i++ ) {
454 if ( dmode == LoadBalancer :: DM_Remote ) {
460 }
else if ( dmode == LoadBalancer :: DM_NULL ) {
465 }
else if ( dmode == LoadBalancer :: DM_Shared ) {
475 }
else if ( dmode == LoadBalancer :: DM_Local ) {
491LoadBalancer :: deleteRemoteElements(
Domain *d)
501 for (
int i = 1; i <= nelem; i++ ) {
517LoadBalancer :: printStatistics()
const
521 int lelem = 0, lnode = 0;
524 nelem =
domain->giveNumberOfElements();
525 nnode =
domain->giveNumberOfDofManagers();
527 for (
int i = 1; i <= nnode; i++ ) {
533 for (
int i = 1; i <= nelem; i++ ) {
539 double mySolutionWTime = emodel->
giveTimer()->
getWtime(EngngModelTimer :: EMTT_AnalysisTimer);
540 double mySolutionUTime = emodel->
giveTimer()->
getUtime(EngngModelTimer :: EMTT_AnalysisTimer);
543 mySolutionWTime, mySolutionUTime, lelem, lnode);
550 int nproc =
emodel->giveNumberOfProcesses();
551 int nodeWeightMode = 0;
554 for (
int i = 0; i < nproc; i++ ) {
559 if ( nodeWeightMode == 0 ) {
561 }
else if ( nodeWeightMode == 1 ) {
563 }
else if ( nodeWeightMode == 2 ) {
566 OOFEM_ERROR(
"nodeWeights size not equal to number of processors");
571 OOFEM_ERROR(
"unsupported node weight type, using default value");
int unpackAllData(T *ptr, int(T ::*unpackFunc)(ProcessCommunicator &))
int initExchange(int tag)
int packAllData(T *ptr, int(T ::*packFunc)(ProcessCommunicator &))
void setPartitionList(const IntArray *_p)
int giveGlobalNumber() const
const char * giveInputRecordName() const override
void saveContext(DataStream &stream, ContextMode mode) override
void restoreContext(DataStream &stream, ContextMode mode) override
const IntArray * givePartitionList()
void setGlobalNumber(int newNumber)
dofManagerParallelMode giveParallelMode() const
void setParallelMode(dofManagerParallelMode _mode)
int addDofManTransaction(DomainTransactionType, int, DofManager *)
int addElementTransaction(DomainTransactionType, int, Element *)
DomainTransactionManager * giveTransactionManager()
int commitTransactions(DomainTransactionManager *tm)
void initGlobalElementMap(bool forceinit=false)
void initGlobalDofManMap(bool forceinit=false)
int giveNumberOfElements() const
Returns number of elements in domain.
int giveNumberOfDofManagers() const
Returns number of dof managers in domain.
DofManager * giveDofManager(int n)
Element * giveElement(int n)
EngngModel * giveEngngModel()
int giveGlobalNumber() const
void saveContext(DataStream &stream, ContextMode mode) override
elementParallelMode giveParallelMode() const
virtual void initForNewStep()
DofManager * giveDofManager(int i) const
void restoreContext(DataStream &stream, ContextMode mode) override
double getUtime(EngngModelTimerType t)
Returns total user time elapsed.
double getWtime(EngngModelTimerType t)
Returns elapsed wall clock time.
int giveNumberOfProcesses() const
Returns the number of collaborating processes.
int giveRank() const
Returns domain rank in a group of collaborating processes (0..groupSize-1).
EngngModelTimer * giveTimer()
Returns reference to receiver timer (EngngModelTimer).
virtual const char * giveInputRecordName() const =0
contextIOResultType restoreYourself(DataStream &stream)
int findFirstIndexOf(int value) const
bool staticNodeWeightFlag
virtual IntArray * giveDofManPartitions(int idofman)=0
Returns the partition list of given dofmanager after load balancing.
void initializeWtp(IntArray &wtp)
virtual DofManMode giveDofManState(int idofman)=0
Returns the label of dofmanager after load balancing.
virtual int giveElementPartition(int ielem)=0
Returns the new partition number assigned to local element after LB.
void deleteRemoteDofManagers(Domain *)
std ::vector< std ::unique_ptr< WorkTransferPlugin > > wtpList
List of work transfer plugins.
void deleteRemoteElements(Domain *)
int read(int *data, std::size_t count) override
Reads count integer values into array pointed by data.
int write(const int *data, std::size_t count) override
Writes count integer values from array pointed by data.
ProcessCommunicatorBuff * giveProcessCommunicatorBuff()
Returns communication buffer.
#define CM_UnknownDictState
#define CM_DefinitionGlobal
#define _IFT_LoadBalancer_wtp
#define _IFT_LoadBalancerMonitor_initialnodeweights
#define _IFT_LoadBalancerMonitor_nodeWeightMode
#define OOFEM_LOG_RELEVANT(...)
@ Element_local
Element is local, there are no contributions from other domains to this element.
ClassFactory & classFactory