Changeset 4219 for issm/trunk/src/c/DataSet/Vertices.cpp
- Timestamp:
- 06/24/10 19:44:31 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk/src/c/DataSet/Vertices.cpp
r4211 r4219 42 42 /*}}}*/ 43 43 44 /*Object management*/ 44 /*Numerics management*/ 45 /*FUNCTION Vertices::CreatePartitioningVector{{{1*/ 46 void 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*/ 73 void 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*/ 145 void 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.