Ignore:
Timestamp:
06/24/10 19:44:31 (15 years ago)
Author:
Eric.Larour
Message:

Transferred a certain number of functionality from the DataSet to its derivative classes: Nodes, Vertices, Constraints, etc ...

File:
1 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk/src/c/DataSet/Vertices.cpp

    r4211 r4219  
    4242/*}}}*/
    4343
    44 /*Object management*/
     44/*Numerics management*/
     45/*FUNCTION Vertices::CreatePartitioningVector{{{1*/
     46void  Vertices::CreatePartitioningVector(Vec* ppartition,int numberofobjects){
     47
     48        int i;
     49
     50        /*output: */
     51        Vec partition=NULL;
     52
     53        /*Create partition vector: */
     54        partition=NewVec(numberofobjects);
     55
     56        /*Go through all objects, and ask each object to plug its doflist in
     57         * partition: */
     58
     59        for(i=0;i<this->Size();i++){
     60                Vertex* vertex=(Vertex*)this->GetObjectByOffset(i);
     61                vertex->CreatePartition(partition);
     62        }
     63
     64        /*Assemble the petsc vector: */
     65        VecAssemblyBegin(partition);
     66        VecAssemblyEnd(partition);
     67
     68        /*Assign output pointers: */
     69        *ppartition=partition;
     70}
     71/*}}}*/
     72/*FUNCTION Vertices::DistributeDofs{{{1*/
     73void  Vertices::DistributeDofs(int numberofobjects,int numberofdofsperobject){
     74
     75        extern int num_procs;
     76        extern int my_rank;
     77
     78        int  i;
     79       
     80        int  dofcount=0;
     81        int* alldofcount=NULL;
     82        int* truedofs=NULL;
     83        int* alltruedofs=NULL;
     84
     85        /*Go through objects, and distribute dofs locally, from 0 to numberofdofsperobject: */
     86        for (i=0;i<this->Size();i++){
     87                Vertex* vertex=(Vertex*)this->GetObjectByOffset(i);
     88                vertex->DistributeDofs(&dofcount);
     89        }
     90
     91        /*Ok, now every object has distributed dofs, but locally, and with a dof count starting from
     92         *0. This means the dofs between all the cpus are not synchronized! We need to synchronize all
     93         *dof on all cpus, and use those to update the dofs of every object: */
     94
     95        alldofcount=(int*)xmalloc(num_procs*sizeof(int));
     96        MPI_Gather(&dofcount,1,MPI_INT,alldofcount,1,MPI_INT,0,MPI_COMM_WORLD);
     97        MPI_Bcast(alldofcount,num_procs,MPI_INT,0,MPI_COMM_WORLD);
     98
     99        /*Ok, now every cpu should start its own dof count at the end of the dofcount
     100         * from cpu-1. : */
     101        dofcount=0;
     102        if(my_rank==0){
     103                dofcount=0;
     104        }
     105        else{
     106                for(i=0;i<my_rank;i++){
     107                        dofcount+=alldofcount[i];
     108                }
     109        }
     110
     111
     112        /*Ok, now every cpu knows where his dofs should start. Update the dof count: */
     113        for (i=0;i<this->Size();i++){
     114                Vertex* vertex=(Vertex*)this->GetObjectByOffset(i);
     115                vertex->OffsetDofs(dofcount);
     116        }
     117
     118        /*Finally, remember that cpus may have skipped some objects, because they were clones. For every
     119         * object that is not a clone, tell them to show their dofs, so that later on, they can get picked
     120         * up by their clones: */
     121        truedofs=(int*)xcalloc(numberofobjects*numberofdofsperobject,sizeof(int));
     122        alltruedofs=(int*)xcalloc(numberofobjects*numberofdofsperobject,sizeof(int));
     123
     124        for (i=0;i<this->Size();i++){
     125                Vertex* vertex=(Vertex*)this->GetObjectByOffset(i);
     126                vertex->ShowTrueDofs(truedofs);
     127        }
     128       
     129        MPI_Allreduce ( (void*)truedofs,(void*)alltruedofs,numberofobjects*numberofdofsperobject,MPI_INT,MPI_MAX,MPI_COMM_WORLD);
     130
     131        /*Ok, now every cpu knows the true dofs of everyone else that is not a clone. Let the clones recover those true dofs: */
     132        for (i=0;i<this->Size();i++){
     133                Vertex* vertex=(Vertex*)this->GetObjectByOffset(i);
     134                vertex->UpdateCloneDofs(alltruedofs);
     135        }
     136
     137        /* Free ressources: */
     138        xfree((void**)&alldofcount);
     139        xfree((void**)&truedofs);
     140        xfree((void**)&alltruedofs);
     141
     142}
     143/*}}}*/
     144/*FUNCTION Vertices::FlagClones{{{1*/
     145void  Vertices::FlagClones(int numberofobjects){
     146
     147        int i;
     148        extern int num_procs;
     149
     150        int* ranks=NULL;
     151        int* minranks=NULL;
     152
     153        /*Allocate ranks: */
     154        ranks=(int*)xmalloc(numberofobjects*sizeof(int));
     155        minranks=(int*)xmalloc(numberofobjects*sizeof(int));
     156
     157        for(i=0;i<numberofobjects;i++)ranks[i]=num_procs; //no cpu can have rank num_procs. This is the maximum limit.
     158
     159        /*Now go through all our objects and ask them to report to who they belong (which rank): */
     160        Ranks(ranks);
     161
     162        /*We need to take the minimum rank for each vertex, and every cpu needs to get that result. That way,
     163         * when we start building the dof list for all vertexs, a cpu can check whether its vertex already has been
     164         * dealt with by another cpu. We take the minimum because we are going to manage dof assignment in increasing
     165         * order of cpu rank. This is also why we initialized this array to num_procs.*/
     166        MPI_Allreduce ( (void*)ranks,(void*)minranks,numberofobjects,MPI_INT,MPI_MIN,MPI_COMM_WORLD);
     167
     168        /*Now go through all objects, and use minranks to flag which objects are cloned: */
     169        for(i=0;i<this->Size();i++){
     170                /*For this object, decide whether it is a clone: */
     171                Vertex* vertex=(Vertex*)this->GetObjectByOffset(i);
     172                vertex->SetClone(minranks);
     173        }
     174
     175        /*Free ressources: */
     176        xfree((void**)&ranks);
     177        xfree((void**)&minranks);
     178
     179}
     180/*}}}*/
Note: See TracChangeset for help on using the changeset viewer.