Changeset 4219


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 ...

Location:
issm/trunk/src/c
Files:
1 deleted
11 edited

Legend:

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

    r4217 r4219  
    4242/*}}}*/
    4343
    44 /*Object management*/
     44/*Numerics: */
     45/*FUNCTION Constraints::NumberOfLocalRgbs{{{1*/
     46int   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  
    590590        }
    591591
    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 in
    606          * 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 from
    646          *0. This means the dofs between all the cpus are not synchronized! We need to synchronize all
    647          *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 dofcount
    654          * 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 every
    675          * object that is not a clone, tell them to show their dofs, so that later on, they can get picked
    676          * 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 been
    727          * dealt with by another cpu. We take the minimum because we are going to manage dof assignment in increasing
    728          * 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         #endif
    807 
    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         #endif
    843 
    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         #endif
    930 
    931         /*sid starts at 0*/
    932         max_sid++;
    933 
    934         /*return*/
    935         return max_sid;
    936592}
    937593/*}}}*/
  • issm/trunk/src/c/DataSet/DataSet.h

    r4218 r4219  
    5959                Object* FindParamObject(char* name);
    6060                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);
    6661                int   NumberOfVertices(void);
    67                 int   NumberOfNodes(void);
    6862                int   NumberOfLoads(void);
    6963                int   NumberOfConstraints(void);
    7064                void  SetupSpcs(DataSet* nodes,Vec yg,int analysis_type);
    7165                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);
    7366                void  clear();
    7467                void  Configure(Elements* elements,Loads* loads, DataSet* nodes, Vertices* vertices, Materials* materials,Parameters* parameters);
     
    7972                void  Sort();
    8073                int   RiftIsPresent();
    81                 int   MeltingIsPresent();
    82                 void  MeltingConstraints(int* pconverged, int* pnum_unstable_constraints);
    8374                DataSet* Copy(void);
    8475                int   DeleteObject(Object* object);
     
    150141                /*}}}*/
    151142                /*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);
    152148                /*}}}*/
    153149
     
    167163                /*}}}*/
    168164                /*numerics: {{{1*/
     165                void  CreatePartitioningVector(Vec* ppartition,int numobjects);
     166                void  DistributeDofs(int numberofnodes,int numdofspernode);
     167                void  FlagClones(int numberofnodes);
    169168                /*}}}*/
    170169
     
    184183                /*}}}*/
    185184                /*numerics: {{{1*/
     185                int   MeltingIsPresent();
     186                void  MeltingConstraints(int* pconverged, int* pnum_unstable_constraints);
    186187                /*}}}*/
    187188
     
    216217                /*}}}*/
    217218                /*numerics: {{{1*/
     219                int   NumberOfLocalRgbs(int analysis_type);
    218220                /*}}}*/
    219221
  • issm/trunk/src/c/DataSet/Loads.cpp

    r4214 r4219  
    4242/*}}}*/
    4343
    44 /*Object management*/
     44/*Numerics:*/
     45/*FUNCTION Loads::MeltingIsPresent{{{1*/
     46int   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*/
     70void  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  
    4242/*}}}*/
    4343
    44 /*Object management*/
     44/*Numerics*/
     45/*FUNCTION Nodes::DistributeDofs{{{1*/
     46void  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*/
     118void  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*/
     155void 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*/
     187int   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*/
     218int 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  
    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/*}}}*/
  • issm/trunk/src/c/objects/Node.h

    r4213 r4219  
    99/*{{{1*/
    1010#include "./Object.h"
    11 #include "./DofObject.h"
    1211#include "../shared/shared.h"
    1312class  Inputs;
     
    1918/*}}}*/
    2019
    21 class Node: public Object,public DofObject{
     20class Node: public Object{
    2221
    2322        private:
  • issm/trunk/src/c/objects/Vertex.cpp

    r4170 r4219  
    321321/*}}}*/
    322322/*}}}*/
    323 
  • issm/trunk/src/c/objects/Vertex.h

    r4140 r4219  
    99/*{{{1*/
    1010#include "./Object.h"
    11 #include "./DofObject.h"
    1211class IoModel;
    1312#include "../shared/Exceptions/exceptions.h"
     13#include "../toolkits/toolkits.h"
    1414#include "../include/include.h"
    1515
     
    1717
    1818
    19 class Vertex: public Object,public DofObject{
     19class Vertex: public Object{
    2020
    2121        public:
  • issm/trunk/src/c/solvers/solver_diagnostic_nonlinear.cpp

    r4214 r4219  
    3030        int num_unstable_constraints;
    3131        int count;
    32         int numberofnodes;
    3332        int min_mechanical_constraints;
    3433        int max_nonlinear_iterations;
     
    4241        /*Recover parameters: */
    4342        kflag=1; pflag=1;
    44         numberofnodes=femmodel->nodes->NumberOfNodes();
    4543        femmodel->parameters->FindParam(&solver_string,SolverStringEnum);
    4644        femmodel->parameters->FindParam(&dim,DimEnum);
  • issm/trunk/src/c/solvers/solver_thermal_nonlinear.cpp

    r4185 r4219  
    2929        int num_unstable_constraints;
    3030        int count;
    31         int numberofnodes;
    3231        int min_thermal_constraints;
    3332        bool reset_penalties;
     
    4241        kflag=1; pflag=1;
    4342
    44         numberofnodes=fem->nodes->NumberOfNodes();
    4543        fem->parameters->FindParam(&solver_string,SolverStringEnum);
    4644        fem->parameters->FindParam(&verbose,VerboseEnum);
Note: See TracChangeset for help on using the changeset viewer.