Changeset 4219
- Timestamp:
- 06/24/10 19:44:31 (15 years ago)
- Location:
- issm/trunk/src/c
- Files:
-
- 1 deleted
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk/src/c/DataSet/Constraints.cpp
r4217 r4219 42 42 /*}}}*/ 43 43 44 /*Object management*/ 44 /*Numerics: */ 45 /*FUNCTION Constraints::NumberOfLocalRgbs{{{1*/ 46 int Constraints::NumberOfLocalRgbs(int analysis_type){ 47 48 int i; 49 int count=0; 50 51 for(i=0;i<this->Size();i++){ 52 53 Object* object=(Object*)this->GetObjectByOffset(i); 54 55 /*Check this is a single point constraint (spc): */ 56 if (object->Enum()==RgbEnum){ 57 58 Rgb* rgb=(Rgb*)object; 59 if(rgb->InAnalysis(analysis_type))count++; 60 } 61 } 62 63 return count; 64 } 65 /*}}}*/ 66 -
issm/trunk/src/c/DataSet/DataSet.cpp
r4218 r4219 590 590 } 591 591 592 }593 /*}}}*/594 /*FUNCTION DataSet::CreatePartitioningVector{{{1*/595 void DataSet::CreatePartitioningVector(Vec* ppartition,int numberofobjects){596 597 /*output: */598 Vec partition=NULL;599 vector<Object*>::iterator object;600 DofObject* dofobject=NULL;601 602 /*Create partition vector: */603 partition=NewVec(numberofobjects);604 605 /*Go through all objects, and ask each object to plug its doflist in606 * partition: */607 608 for ( object=objects.begin() ; object < objects.end(); object++ ){609 610 dofobject=dynamic_cast<DofObject*>(*object);611 dofobject->CreatePartition(partition);612 }613 614 /*Assemble the petsc vector: */615 VecAssemblyBegin(partition);616 VecAssemblyEnd(partition);617 618 /*Assign output pointers: */619 *ppartition=partition;620 }621 /*}}}*/622 /*FUNCTION DataSet::DistributeDofs{{{1*/623 void DataSet::DistributeDofs(int numberofobjects,int numberofdofsperobject){624 625 extern int num_procs;626 extern int my_rank;627 628 int i;629 630 int dofcount=0;631 int* alldofcount=NULL;632 int* truedofs=NULL;633 int* alltruedofs=NULL;634 vector<Object*>::iterator object;635 DofObject* dofobject=NULL;636 637 /*Go through objects, and distribute dofs locally, from 0 to numberofdofsperobject: */638 for ( object=objects.begin() ; object < objects.end(); object++ ){639 640 dofobject=dynamic_cast<DofObject*>(*object);641 dofobject->DistributeDofs(&dofcount);642 643 }644 645 /*Ok, now every object has distributed dofs, but locally, and with a dof count starting from646 *0. This means the dofs between all the cpus are not synchronized! We need to synchronize all647 *dof on all cpus, and use those to update the dofs of every object: */648 649 alldofcount=(int*)xmalloc(num_procs*sizeof(int));650 MPI_Gather(&dofcount,1,MPI_INT,alldofcount,1,MPI_INT,0,MPI_COMM_WORLD);651 MPI_Bcast(alldofcount,num_procs,MPI_INT,0,MPI_COMM_WORLD);652 653 /*Ok, now every cpu should start its own dof count at the end of the dofcount654 * from cpu-1. : */655 dofcount=0;656 if(my_rank==0){657 dofcount=0;658 }659 else{660 for(i=0;i<my_rank;i++){661 dofcount+=alldofcount[i];662 }663 }664 665 666 /*Ok, now every cpu knows where his dofs should start. Update the dof count: */667 for ( object=objects.begin() ; object < objects.end(); object++ ){668 669 dofobject=dynamic_cast<DofObject*>(*object);670 dofobject->OffsetDofs(dofcount);671 672 }673 674 /*Finally, remember that cpus may have skipped some objects, because they were clones. For every675 * object that is not a clone, tell them to show their dofs, so that later on, they can get picked676 * up by their clones: */677 truedofs=(int*)xcalloc(numberofobjects*numberofdofsperobject,sizeof(int));678 alltruedofs=(int*)xcalloc(numberofobjects*numberofdofsperobject,sizeof(int));679 680 for ( object=objects.begin() ; object < objects.end(); object++ ){681 682 /*Ok, let this object show its true dofs, if is is a true dof: */683 dofobject=dynamic_cast<DofObject*>(*object);684 dofobject->ShowTrueDofs(truedofs);685 }686 687 MPI_Allreduce ( (void*)truedofs,(void*)alltruedofs,numberofobjects*numberofdofsperobject,MPI_INT,MPI_MAX,MPI_COMM_WORLD);688 689 /*Ok, now every cpu knows the true dofs of everyone else that is not a clone. Let the clones recover those true dofs: */690 for ( object=objects.begin() ; object < objects.end(); object++ ){691 692 dofobject=dynamic_cast<DofObject*>(*object);693 dofobject->UpdateCloneDofs(alltruedofs);694 695 }696 697 /* Free ressources: */698 xfree((void**)&alldofcount);699 xfree((void**)&truedofs);700 xfree((void**)&alltruedofs);701 702 }703 /*}}}*/704 /*FUNCTION DataSet::FlagClones{{{1*/705 void DataSet::FlagClones(int numberofobjects){706 707 int i;708 extern int num_procs;709 710 int* ranks=NULL;711 int* minranks=NULL;712 713 vector<Object*>::iterator object;714 DofObject* dofobject=NULL;715 716 /*Allocate ranks: */717 ranks=(int*)xmalloc(numberofobjects*sizeof(int));718 minranks=(int*)xmalloc(numberofobjects*sizeof(int));719 720 for(i=0;i<numberofobjects;i++)ranks[i]=num_procs; //no cpu can have rank num_procs. This is the maximum limit.721 722 /*Now go through all our objects and ask them to report to who they belong (which rank): */723 Ranks(ranks);724 725 /*We need to take the minimum rank for each vertex, and every cpu needs to get that result. That way,726 * when we start building the dof list for all vertexs, a cpu can check whether its vertex already has been727 * dealt with by another cpu. We take the minimum because we are going to manage dof assignment in increasing728 * order of cpu rank. This is also why we initialized this array to num_procs.*/729 MPI_Allreduce ( (void*)ranks,(void*)minranks,numberofobjects,MPI_INT,MPI_MIN,MPI_COMM_WORLD);730 731 /*Now go through all objects, and use minranks to flag which objects are cloned: */732 for ( object=objects.begin() ; object < objects.end(); object++ ){733 734 /*For this object, decide whether it is a clone: */735 dofobject=dynamic_cast<DofObject*>(*object);736 dofobject->SetClone(minranks);737 }738 739 /*Free ressources: */740 xfree((void**)&ranks);741 xfree((void**)&minranks);742 743 }744 /*}}}*/745 /*FUNCTION DataSet::FlagNodeSets{{{1*/746 void DataSet::FlagNodeSets(Vec pv_g, Vec pv_m, Vec pv_n, Vec pv_f, Vec pv_s,int analysis_type){747 748 vector<Object*>::iterator object;749 Node* node=NULL;750 751 for ( object=objects.begin() ; object < objects.end(); object++ ){752 753 /*Check this is a single point constraint (spc): */754 if((*object)->Enum()==NodeEnum){755 756 node=(Node*)(*object);757 758 if (node->InAnalysis(analysis_type)){759 760 /*Plug set values intp our 4 set vectors: */761 node->CreateVecSets(pv_g,pv_m,pv_n,pv_f,pv_s);762 763 }764 765 }766 }767 768 /*Assemble: */769 VecAssemblyBegin(pv_g);770 VecAssemblyEnd(pv_g);771 772 VecAssemblyBegin(pv_m);773 VecAssemblyEnd(pv_m);774 775 VecAssemblyBegin(pv_n);776 VecAssemblyEnd(pv_n);777 778 VecAssemblyBegin(pv_f);779 VecAssemblyEnd(pv_f);780 781 VecAssemblyBegin(pv_s);782 VecAssemblyEnd(pv_s);783 784 }785 /*}}}*/786 /*FUNCTION DataSet::MeltingIsPresent{{{1*/787 int DataSet::MeltingIsPresent(){788 789 int found=0;790 int mpi_found=0;791 792 vector<Object*>::iterator object;793 794 for ( object=objects.begin() ; object < objects.end(); object++ ){795 796 if((*object)->Enum()==PengridEnum){797 found=1;798 break;799 }800 }801 802 #ifdef _PARALLEL_803 MPI_Reduce (&found,&mpi_found,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD );804 MPI_Bcast(&mpi_found,1,MPI_INT,0,MPI_COMM_WORLD);805 found=mpi_found;806 #endif807 808 return found;809 }810 /*}}}*/811 /*FUNCTION DataSet::MeltingConstraints{{{1*/812 void DataSet::MeltingConstraints(int* pconverged, int* pnum_unstable_constraints){813 814 /* generic object pointer: */815 vector<Object*>::iterator object;816 Pengrid* pengrid=NULL;817 818 int unstable=0;819 int num_unstable_constraints=0;820 int converged=0;821 int sum_num_unstable_constraints=0;822 823 num_unstable_constraints=0;824 825 /*Enforce constraints: */826 for ( object=objects.begin() ; object < objects.end(); object++ ){827 828 if((*object)->Enum()==PengridEnum){829 830 pengrid=(Pengrid*)(*object);831 832 pengrid->PenaltyConstrain(&unstable);833 834 num_unstable_constraints+=unstable;835 }836 }837 838 #ifdef _PARALLEL_839 MPI_Reduce (&num_unstable_constraints,&sum_num_unstable_constraints,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD );840 MPI_Bcast(&sum_num_unstable_constraints,1,MPI_INT,0,MPI_COMM_WORLD);841 num_unstable_constraints=sum_num_unstable_constraints;842 #endif843 844 /*Have we converged? : */845 if (num_unstable_constraints==0) converged=1;846 else converged=0;847 848 /*Assign output pointers: */849 *pconverged=converged;850 *pnum_unstable_constraints=num_unstable_constraints;851 }852 /*}}}*/853 /*FUNCTION DataSet::NumberOfDofs(int analysis_type){{{1*/854 int DataSet::NumberOfDofs(int analysis_type){855 856 857 vector<Object*>::iterator object;858 Node* node=NULL;859 int numdofs=0;860 int allnumdofs;861 862 /*Now go through all nodes, and get how many dofs they own, unless they are clone nodes: */863 for ( object=objects.begin() ; object < objects.end(); object++ ){864 865 /*Check this is a node: */866 if((*object)->Enum()==NodeEnum){867 868 node=(Node*)(*object);869 870 /*Check that this node corresponds to our analysis currently being carried out: */871 872 /*Ok, this object is a node, ask it to plug values into partition: */873 if (!node->IsClone()){874 875 numdofs+=node->GetNumberOfDofs();876 877 }878 }879 }880 881 /*Gather from all cpus: */882 MPI_Allreduce ( (void*)&numdofs,(void*)&allnumdofs,1,MPI_INT,MPI_SUM,MPI_COMM_WORLD);883 884 return allnumdofs;885 }886 /*}}}*/887 /*FUNCTION DataSet::NumberOfLocalRgbs{{{1*/888 int DataSet::NumberOfLocalRgbs(int analysis_type){889 890 vector<Object*>::iterator object;891 Rgb* rgb=NULL;892 int count=0;893 894 for ( object=objects.begin() ; object < objects.end(); object++ ){895 896 /*Check this is a single point constraint (spc): */897 if((*object)->Enum()==RgbEnum){ //we assume uniqueness of all Rgbs, no error checking here.898 899 rgb=(Rgb*)(*object);900 if(rgb->InAnalysis(analysis_type))count++;901 }902 }903 904 return count;905 }906 /*}}}*/907 /*FUNCTION DataSet::NumberOfNodes{{{1*/908 int DataSet::NumberOfNodes(void){909 910 vector<Object*>::iterator object;911 int max_sid=0;912 int sid;913 int node_max_sid;914 915 for ( object=objects.begin() ; object < objects.end(); object++ ){916 917 if((*object)->Enum()==NodeEnum){918 919 Node* node=(Node*)(*object);920 sid=node->Sid();921 if (sid>max_sid)max_sid=sid;922 }923 }924 925 #ifdef _PARALLEL_926 MPI_Reduce (&max_sid,&node_max_sid,1,MPI_INT,MPI_MAX,0,MPI_COMM_WORLD );927 MPI_Bcast(&node_max_sid,1,MPI_INT,0,MPI_COMM_WORLD);928 max_sid=node_max_sid;929 #endif930 931 /*sid starts at 0*/932 max_sid++;933 934 /*return*/935 return max_sid;936 592 } 937 593 /*}}}*/ -
issm/trunk/src/c/DataSet/DataSet.h
r4218 r4219 59 59 Object* FindParamObject(char* name); 60 60 void Ranks(int* ranks); 61 void DistributeDofs(int numberofnodes,int numdofspernode);62 void CreatePartitioningVector(Vec* ppartition,int numobjects);63 void FlagClones(int numberofnodes);64 int NumberOfDofs(int analysis_type);65 int NumberOfLocalRgbs(int analysis_type);66 61 int NumberOfVertices(void); 67 int NumberOfNodes(void);68 62 int NumberOfLoads(void); 69 63 int NumberOfConstraints(void); 70 64 void SetupSpcs(DataSet* nodes,Vec yg,int analysis_type); 71 65 void SetupMpcs(Mat Rmg,DataSet* nodes,int analysis_type); 72 void FlagNodeSets(Vec pv_g, Vec pv_m, Vec pv_n, Vec pv_f, Vec pv_s,int analysis_type);73 66 void clear(); 74 67 void Configure(Elements* elements,Loads* loads, DataSet* nodes, Vertices* vertices, Materials* materials,Parameters* parameters); … … 79 72 void Sort(); 80 73 int RiftIsPresent(); 81 int MeltingIsPresent();82 void MeltingConstraints(int* pconverged, int* pnum_unstable_constraints);83 74 DataSet* Copy(void); 84 75 int DeleteObject(Object* object); … … 150 141 /*}}}*/ 151 142 /*numerics: {{{1*/ 143 void DistributeDofs(int numberofnodes,int numdofspernode); 144 void FlagClones(int numberofnodes); 145 void FlagNodeSets(Vec pv_g, Vec pv_m, Vec pv_n, Vec pv_f, Vec pv_s,int analysis_type); 146 int NumberOfDofs(int analysis_type); 147 int NumberOfNodes(void); 152 148 /*}}}*/ 153 149 … … 167 163 /*}}}*/ 168 164 /*numerics: {{{1*/ 165 void CreatePartitioningVector(Vec* ppartition,int numobjects); 166 void DistributeDofs(int numberofnodes,int numdofspernode); 167 void FlagClones(int numberofnodes); 169 168 /*}}}*/ 170 169 … … 184 183 /*}}}*/ 185 184 /*numerics: {{{1*/ 185 int MeltingIsPresent(); 186 void MeltingConstraints(int* pconverged, int* pnum_unstable_constraints); 186 187 /*}}}*/ 187 188 … … 216 217 /*}}}*/ 217 218 /*numerics: {{{1*/ 219 int NumberOfLocalRgbs(int analysis_type); 218 220 /*}}}*/ 219 221 -
issm/trunk/src/c/DataSet/Loads.cpp
r4214 r4219 42 42 /*}}}*/ 43 43 44 /*Object management*/ 44 /*Numerics:*/ 45 /*FUNCTION Loads::MeltingIsPresent{{{1*/ 46 int Loads::MeltingIsPresent(){ 47 48 int i; 49 int found=0; 50 int mpi_found=0; 51 52 for(i=0;i<this->Size();i++){ 53 Object* object=(Object*)this->GetObjectByOffset(i); 54 if (object->Enum()==PengridEnum){ 55 found=1; 56 break; 57 } 58 } 59 60 #ifdef _PARALLEL_ 61 MPI_Reduce (&found,&mpi_found,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD ); 62 MPI_Bcast(&mpi_found,1,MPI_INT,0,MPI_COMM_WORLD); 63 found=mpi_found; 64 #endif 65 66 return found; 67 } 68 /*}}}*/ 69 /*FUNCTION Loads::MeltingConstraints{{{1*/ 70 void Loads::MeltingConstraints(int* pconverged, int* pnum_unstable_constraints){ 71 72 int i; 73 74 int unstable=0; 75 int num_unstable_constraints=0; 76 int converged=0; 77 int sum_num_unstable_constraints=0; 78 79 num_unstable_constraints=0; 80 81 /*Enforce constraints: */ 82 for(i=0;i<this->Size();i++){ 83 Object* object=(Object*)this->GetObjectByOffset(i); 84 if(object->Enum()==PengridEnum){ 85 86 Pengrid* pengrid=(Pengrid*)object; 87 pengrid->PenaltyConstrain(&unstable); 88 num_unstable_constraints+=unstable; 89 } 90 } 91 92 #ifdef _PARALLEL_ 93 MPI_Reduce (&num_unstable_constraints,&sum_num_unstable_constraints,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD ); 94 MPI_Bcast(&sum_num_unstable_constraints,1,MPI_INT,0,MPI_COMM_WORLD); 95 num_unstable_constraints=sum_num_unstable_constraints; 96 #endif 97 98 /*Have we converged? : */ 99 if (num_unstable_constraints==0) converged=1; 100 else converged=0; 101 102 /*Assign output pointers: */ 103 *pconverged=converged; 104 *pnum_unstable_constraints=num_unstable_constraints; 105 } 106 /*}}}*/ -
issm/trunk/src/c/DataSet/Nodes.cpp
r4211 r4219 42 42 /*}}}*/ 43 43 44 /*Object management*/ 44 /*Numerics*/ 45 /*FUNCTION Nodes::DistributeDofs{{{1*/ 46 void Nodes::DistributeDofs(int numberofobjects,int numberofdofsperobject){ 47 48 extern int num_procs; 49 extern int my_rank; 50 51 int i; 52 53 int dofcount=0; 54 int* alldofcount=NULL; 55 int* truedofs=NULL; 56 int* alltruedofs=NULL; 57 58 /*Go through objects, and distribute dofs locally, from 0 to numberofdofsperobject: */ 59 for (i=0;i<this->Size();i++){ 60 Node* node=(Node*)this->GetObjectByOffset(i); 61 node->DistributeDofs(&dofcount); 62 } 63 64 /*Ok, now every object has distributed dofs, but locally, and with a dof count starting from 65 *0. This means the dofs between all the cpus are not synchronized! We need to synchronize all 66 *dof on all cpus, and use those to update the dofs of every object: */ 67 68 alldofcount=(int*)xmalloc(num_procs*sizeof(int)); 69 MPI_Gather(&dofcount,1,MPI_INT,alldofcount,1,MPI_INT,0,MPI_COMM_WORLD); 70 MPI_Bcast(alldofcount,num_procs,MPI_INT,0,MPI_COMM_WORLD); 71 72 /*Ok, now every cpu should start its own dof count at the end of the dofcount 73 * from cpu-1. : */ 74 dofcount=0; 75 if(my_rank==0){ 76 dofcount=0; 77 } 78 else{ 79 for(i=0;i<my_rank;i++){ 80 dofcount+=alldofcount[i]; 81 } 82 } 83 84 85 /*Ok, now every cpu knows where his dofs should start. Update the dof count: */ 86 for (i=0;i<this->Size();i++){ 87 Node* node=(Node*)this->GetObjectByOffset(i); 88 node->OffsetDofs(dofcount); 89 } 90 91 /*Finally, remember that cpus may have skipped some objects, because they were clones. For every 92 * object that is not a clone, tell them to show their dofs, so that later on, they can get picked 93 * up by their clones: */ 94 truedofs=(int*)xcalloc(numberofobjects*numberofdofsperobject,sizeof(int)); 95 alltruedofs=(int*)xcalloc(numberofobjects*numberofdofsperobject,sizeof(int)); 96 97 for (i=0;i<this->Size();i++){ 98 Node* node=(Node*)this->GetObjectByOffset(i); 99 node->ShowTrueDofs(truedofs); 100 } 101 102 MPI_Allreduce ( (void*)truedofs,(void*)alltruedofs,numberofobjects*numberofdofsperobject,MPI_INT,MPI_MAX,MPI_COMM_WORLD); 103 104 /*Ok, now every cpu knows the true dofs of everyone else that is not a clone. Let the clones recover those true dofs: */ 105 for (i=0;i<this->Size();i++){ 106 Node* node=(Node*)this->GetObjectByOffset(i); 107 node->UpdateCloneDofs(alltruedofs); 108 } 109 110 /* Free ressources: */ 111 xfree((void**)&alldofcount); 112 xfree((void**)&truedofs); 113 xfree((void**)&alltruedofs); 114 115 } 116 /*}}}*/ 117 /*FUNCTION Nodes::FlagClones{{{1*/ 118 void Nodes::FlagClones(int numberofobjects){ 119 120 int i; 121 extern int num_procs; 122 123 int* ranks=NULL; 124 int* minranks=NULL; 125 126 /*Allocate ranks: */ 127 ranks=(int*)xmalloc(numberofobjects*sizeof(int)); 128 minranks=(int*)xmalloc(numberofobjects*sizeof(int)); 129 130 for(i=0;i<numberofobjects;i++)ranks[i]=num_procs; //no cpu can have rank num_procs. This is the maximum limit. 131 132 /*Now go through all our objects and ask them to report to who they belong (which rank): */ 133 Ranks(ranks); 134 135 /*We need to take the minimum rank for each vertex, and every cpu needs to get that result. That way, 136 * when we start building the dof list for all vertexs, a cpu can check whether its vertex already has been 137 * dealt with by another cpu. We take the minimum because we are going to manage dof assignment in increasing 138 * order of cpu rank. This is also why we initialized this array to num_procs.*/ 139 MPI_Allreduce ( (void*)ranks,(void*)minranks,numberofobjects,MPI_INT,MPI_MIN,MPI_COMM_WORLD); 140 141 /*Now go through all objects, and use minranks to flag which objects are cloned: */ 142 for(i=0;i<this->Size();i++){ 143 /*For this object, decide whether it is a clone: */ 144 Node* node=(Node*)this->GetObjectByOffset(i); 145 node->SetClone(minranks); 146 } 147 148 /*Free ressources: */ 149 xfree((void**)&ranks); 150 xfree((void**)&minranks); 151 152 } 153 /*}}}*/ 154 /*FUNCTION Nodes::FlagNodeSets{{{1*/ 155 void Nodes::FlagNodeSets(Vec pv_g, Vec pv_m, Vec pv_n, Vec pv_f, Vec pv_s,int analysis_type){ 156 157 int i; 158 159 for(i=0;i<this->Size();i++){ 160 Node* node=(Node*)this->GetObjectByOffset(i); 161 162 if (node->InAnalysis(analysis_type)){ 163 /*Plug set values intp our 4 set vectors: */ 164 node->CreateVecSets(pv_g,pv_m,pv_n,pv_f,pv_s); 165 } 166 } 167 168 /*Assemble: */ 169 VecAssemblyBegin(pv_g); 170 VecAssemblyEnd(pv_g); 171 172 VecAssemblyBegin(pv_m); 173 VecAssemblyEnd(pv_m); 174 175 VecAssemblyBegin(pv_n); 176 VecAssemblyEnd(pv_n); 177 178 VecAssemblyBegin(pv_f); 179 VecAssemblyEnd(pv_f); 180 181 VecAssemblyBegin(pv_s); 182 VecAssemblyEnd(pv_s); 183 184 } 185 /*}}}*/ 186 /*FUNCTION Nodes::NumberOfDofs(int analysis_type){{{1*/ 187 int Nodes::NumberOfDofs(int analysis_type){ 188 189 int i; 190 191 int numdofs=0; 192 int allnumdofs; 193 194 /*Now go through all nodes, and get how many dofs they own, unless they are clone nodes: */ 195 for(i=0;i<this->Size();i++){ 196 197 Node* node=(Node*)this->GetObjectByOffset(i); 198 199 /*Check that this node corresponds to our analysis currently being carried out: */ 200 if (node->InAnalysis(analysis_type)){ 201 202 /*Ok, this object is a node, ask it to plug values into partition: */ 203 if (!node->IsClone()){ 204 205 numdofs+=node->GetNumberOfDofs(); 206 207 } 208 } 209 } 210 211 /*Gather from all cpus: */ 212 MPI_Allreduce ( (void*)&numdofs,(void*)&allnumdofs,1,MPI_INT,MPI_SUM,MPI_COMM_WORLD); 213 214 return allnumdofs; 215 } 216 /*}}}*/ 217 /*FUNCTION Nodes::NumberOfNodes{{{1*/ 218 int Nodes::NumberOfNodes(void){ 219 220 int i; 221 222 int max_sid=0; 223 int sid; 224 int node_max_sid; 225 226 for(i=0;i<this->Size();i++){ 227 228 Node* node=(Node*)this->GetObjectByOffset(i); 229 sid=node->Sid(); 230 if (sid>max_sid)max_sid=sid; 231 } 232 233 #ifdef _PARALLEL_ 234 MPI_Reduce (&max_sid,&node_max_sid,1,MPI_INT,MPI_MAX,0,MPI_COMM_WORLD ); 235 MPI_Bcast(&node_max_sid,1,MPI_INT,0,MPI_COMM_WORLD); 236 max_sid=node_max_sid; 237 #endif 238 239 /*sid starts at 0*/ 240 max_sid++; 241 242 /*return*/ 243 return max_sid; 244 } 245 /*}}}*/ 246 -
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 /*}}}*/ -
issm/trunk/src/c/objects/Node.h
r4213 r4219 9 9 /*{{{1*/ 10 10 #include "./Object.h" 11 #include "./DofObject.h"12 11 #include "../shared/shared.h" 13 12 class Inputs; … … 19 18 /*}}}*/ 20 19 21 class Node: public Object ,public DofObject{20 class Node: public Object{ 22 21 23 22 private: -
issm/trunk/src/c/objects/Vertex.cpp
r4170 r4219 321 321 /*}}}*/ 322 322 /*}}}*/ 323 -
issm/trunk/src/c/objects/Vertex.h
r4140 r4219 9 9 /*{{{1*/ 10 10 #include "./Object.h" 11 #include "./DofObject.h"12 11 class IoModel; 13 12 #include "../shared/Exceptions/exceptions.h" 13 #include "../toolkits/toolkits.h" 14 14 #include "../include/include.h" 15 15 … … 17 17 18 18 19 class Vertex: public Object ,public DofObject{19 class Vertex: public Object{ 20 20 21 21 public: -
issm/trunk/src/c/solvers/solver_diagnostic_nonlinear.cpp
r4214 r4219 30 30 int num_unstable_constraints; 31 31 int count; 32 int numberofnodes;33 32 int min_mechanical_constraints; 34 33 int max_nonlinear_iterations; … … 42 41 /*Recover parameters: */ 43 42 kflag=1; pflag=1; 44 numberofnodes=femmodel->nodes->NumberOfNodes();45 43 femmodel->parameters->FindParam(&solver_string,SolverStringEnum); 46 44 femmodel->parameters->FindParam(&dim,DimEnum); -
issm/trunk/src/c/solvers/solver_thermal_nonlinear.cpp
r4185 r4219 29 29 int num_unstable_constraints; 30 30 int count; 31 int numberofnodes;32 31 int min_thermal_constraints; 33 32 bool reset_penalties; … … 42 41 kflag=1; pflag=1; 43 42 44 numberofnodes=fem->nodes->NumberOfNodes();45 43 fem->parameters->FindParam(&solver_string,SolverStringEnum); 46 44 fem->parameters->FindParam(&verbose,VerboseEnum);
Note:
See TracChangeset
for help on using the changeset viewer.