Changeset 3425


Ignore:
Timestamp:
04/07/10 15:58:33 (15 years ago)
Author:
seroussi
Message:

added ModelProcessor for SlopeCompute

File:
1 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk/src/c/ModelProcessorx/SlopeCompute/CreateElementsNodesAndMaterialsSlopeCompute.cpp

    r3417 r3425  
    22 * CreateElementsNodesAndMaterialsSlopeCompute.c:
    33 */
    4 
    54
    65#include "../../DataSet/DataSet.h"
     
    1514void    CreateElementsNodesAndMaterialsSlopeCompute(DataSet** pelements,DataSet** pnodes, DataSet** pvertices,DataSet** pmaterials, IoModel* iomodel,ConstDataHandle iomodel_handle){
    1615
    17 
    1816                /*output: int* epart, int* my_grids, double* my_bordergrids*/
    1917
    20 
    2118        int i,j,k,n;
    22         extern int my_rank;
    23         extern int num_procs;
    24 
    2519        /*DataSets: */
    2620        DataSet*    elements  = NULL;
     
    2923        DataSet*    materials = NULL;
    3024       
    31         /*Objects: */
    32         Node*       node   = NULL;
    33         Vertex*     vertex = NULL;
    34         Tria*       tria = NULL;
    35         Penta*      penta = NULL;
    36         ElementProperties* tria_properties=NULL;
    37         ElementProperties* penta_properties=NULL;
    38 
    39         /*output: */
    40         int* epart=NULL; //element partitioning.
    41         int* npart=NULL; //node partitioning.
    42         int* my_grids=NULL;
    43         double* my_bordergrids=NULL;
    44 
    45         /*intermediary: */
    46         int elements_width; //size of elements
    47                        
    48         /*tria constructor input: */
    49         int tria_id;
    50         int tria_matice_id;
    51         int tria_matpar_id;
    52         int tria_numpar_id;
    53         int tria_node_ids[3];
    54         double tria_s[3];
    55         double tria_b[3];
    56         bool   tria_onwater;
    57 
    58         /*penta constructor input: */
    59 
    60         int penta_id;
    61         int penta_matice_id;
    62         int penta_matpar_id;
    63         int penta_numpar_id;
    64         int penta_node_ids[6];
    65         double penta_s[6];
    66         double penta_b[6];
    67         int penta_onbed;
    68         bool   penta_onwater;
    69 
    70         /* node constructor input: */
    71         int node_id;
    72         int vertex_id;
    73         int node_partitionborder=0;
    74         int node_onbed;
    75         int node_onsurface;
    76         int node_onshelf;
    77         int node_onsheet;
    78         int node_upper_node_id;
    79         int node_numdofs;
    80 
    81                
    82         #ifdef _PARALLEL_
    83         /*Metis partitioning: */
    84         int  range;
    85         Vec  gridborder=NULL;
    86         int  my_numgrids;
    87         int* all_numgrids=NULL;
    88         int  gridcount;
    89         int  count;
    90         #endif
    91         int  first_grid_index;
    92 
    9325        /*First create the elements, nodes and material properties: */
    9426        elements  = new DataSet(ElementsEnum());
     
    9729        materials = new DataSet(MaterialsEnum());
    9830
    99         /*Now, is the flag isstokes on? otherwise, do nothing: */
    100         if (!iomodel->isstokes & !iomodel->ishutter)goto cleanup_and_return;
    101 
    102         /*Width of elements: */
    103         if(strcmp(iomodel->meshtype,"2d")==0){
    104                 elements_width=3; //tria elements
    105         }
    106         else{
    107                 elements_width=6; //penta elements
    108         }
    109 
    110         #ifdef _PARALLEL_
    111         /*Determine parallel partitioning of elements: we use Metis for now. First load the data, then partition*/
    112         if(strcmp(iomodel->meshtype,"2d")==0){
    113                 /*load elements: */
    114                 IoModelFetchData(&iomodel->elements,NULL,NULL,iomodel_handle,"elements");
    115         }
    116         else{
    117                 /*load elements2d: */
    118                 IoModelFetchData(&iomodel->elements2d,NULL,NULL,iomodel_handle,"elements2d");
    119         }
    120 
    121 
    122         MeshPartitionx(&epart, &npart,iomodel->numberofelements,iomodel->numberofnodes,iomodel->elements, iomodel->numberofelements2d,iomodel->numberofnodes2d,iomodel->elements2d,iomodel->numlayers,elements_width, iomodel->meshtype,num_procs);
    123 
    124         /*Free elements and elements2d: */
    125         xfree((void**)&iomodel->elements);
    126         xfree((void**)&iomodel->elements2d);
    127 
    128 
    129         /*Used later on: */
    130         my_grids=(int*)xcalloc(iomodel->numberofnodes,sizeof(int));
    131         #endif
    132 
    133 
    134 
    135         /*elements created vary if we are dealing with a 2d mesh, or a 3d mesh: */
     31        /*Partition elements and vertices and nodes: */
     32        Partitioning(&iomodel->my_elements, &iomodel->my_vertices, &iomodel->my_nodes, &iomodel->my_bordervertices, iomodel, iomodel_handle);
    13633
    13734        /*2d mesh: */
     
    14643                for (i=0;i<iomodel->numberofelements;i++){
    14744
    148                 #ifdef _PARALLEL_
    149                 /*!All elements have been partitioned above, only create elements for this CPU: */
    150                 if(my_rank==epart[i]){
    151                 #endif
    152                        
    153                        
    154                         /*ids: */
    155                         tria_id=i+1; //matlab indexing.
    156                         tria_matice_id=-1; //no materials
    157                         tria_matpar_id=-1; //no materials
    158                         tria_numpar_id=1; //no materials
     45                        if(iomodel->my_elements[i]){
     46                               
     47                                /*Create and add tria element to elements dataset: */
     48                                elements->AddObject(new Tria(i,iomodel));
    15949
    160                         /*vertices offsets: */
    161                         tria_node_ids[0]=(int)*(iomodel->elements+elements_width*i+0);
    162                         tria_node_ids[1]=(int)*(iomodel->elements+elements_width*i+1);
    163                         tria_node_ids[2]=(int)*(iomodel->elements+elements_width*i+2);
    164 
    165                         /*surface and bed:*/
    166                         tria_s[0]=*(iomodel->surface+    ((int)*(iomodel->elements+elements_width*i+0)-1));
    167                         tria_s[1]=*(iomodel->surface+    ((int)*(iomodel->elements+elements_width*i+1)-1));
    168                         tria_s[2]=*(iomodel->surface+    ((int)*(iomodel->elements+elements_width*i+2)-1));
    169 
    170                         tria_b[0]=*(iomodel->bed+        ((int)*(iomodel->elements+elements_width*i+0)-1));
    171                         tria_b[1]=*(iomodel->bed+        ((int)*(iomodel->elements+elements_width*i+1)-1));
    172                         tria_b[2]=*(iomodel->bed+        ((int)*(iomodel->elements+elements_width*i+2)-1));
    173                        
    174                         /*element on water? : */
    175                         tria_onwater=(bool)*(iomodel->elementonwater+i);
    176 
    177                         /*Create properties: */
    178                         tria_properties=new ElementProperties(3,NULL, tria_s, tria_b, NULL, NULL, NULL, NULL, UNDEF, UNDEF, UNDEF, UNDEF, UNDEF, tria_onwater, UNDEF, UNDEF, UNDEF);
    179 
    180                         /*Create tria element using its constructor:*/
    181                         tria=new Tria(tria_id, tria_node_ids, tria_matice_id, tria_matpar_id, tria_numpar_id, tria_properties);
    182 
    183                         /*Delete properties: */
    184                         delete tria_properties;
    185 
    186                         /*Add tria element to elements dataset: */
    187                         elements->AddObject(tria);
    188 
    189                         #ifdef _PARALLEL_
    190                         /*Now that we are here, we can also start building the list of grids belonging to this node partition: we use
    191                          *the  element index to do this. For each element n, we know index[n][0:2] holds the indices (matlab indexing)
    192                          into the grid coordinates. If we start plugging 1 into my_grids for each index[n][i] (i=0:2), then my_grids
    193                          will hold which grids belong to this partition*/
    194                         my_grids[(int)*(iomodel->elements+elements_width*i+0)-1]=1;
    195                         my_grids[(int)*(iomodel->elements+elements_width*i+1)-1]=1;
    196                         my_grids[(int)*(iomodel->elements+elements_width*i+2)-1]=1;
    197                         #endif
    198 
    199                 #ifdef _PARALLEL_
    200                 }//if(my_rank==epart[i])
    201                 #endif
     50                                /*Create and add material property to materials dataset: */
     51                                materials->AddObject(new Matice(i,iomodel,3));
     52                        }
    20253
    20354                }//for (i=0;i<numberofelements;i++)
     
    22172       
    22273                for (i=0;i<iomodel->numberofelements;i++){
    223                 #ifdef _PARALLEL_
    224                 /*We are using our element partition to decide which elements will be created on this node: */
    225                 if(my_rank==epart[i]){
    226                 #endif
     74                        if(iomodel->my_elements[i]){
     75                                /*Create and add penta element to elements dataset: */
     76                                elements->AddObject(new Penta(i,iomodel));
    22777
    228                        
    229                         /*name and id: */
    230                         penta_id=i+1; //matlab indexing.
    231                         penta_matice_id=-1; //no materials
    232                         penta_matpar_id=-1; //no materials
    233                         penta_numpar_id=1; //no materials
    234                        
     78                                /*Create and add material property to materials dataset: */
     79                                materials->AddObject(new Matice(i,iomodel,6));
    23580
    236                         /*vertices,thickness,surface,bed and drag: */
    237                         for(j=0;j<6;j++){
    238                                 penta_node_ids[j]=(int)*(iomodel->elements+elements_width*i+j);
    239                                 penta_s[j]=*(iomodel->surface+    ((int)*(iomodel->elements+elements_width*i+j)-1));
    240                                 penta_b[j]=*(iomodel->bed+    ((int)*(iomodel->elements+elements_width*i+j)-1));
    241                         }
    242                        
    243                         /*diverse: */
    244                         penta_onbed=(int)*(iomodel->elementonbed+i);
    245                         penta_onwater=(bool)*(iomodel->elementonwater+i);
    246 
    247                         /*Create properties: */
    248                         penta_properties=new ElementProperties(6,NULL, penta_s, penta_b, NULL, NULL, NULL, NULL, UNDEF, UNDEF, UNDEF,UNDEF,penta_onbed, penta_onwater, UNDEF, UNDEF, UNDEF);
    249                                
    250                         /*Create Penta using its constructor:*/
    251                         penta=new Penta(penta_id, penta_node_ids, penta_matice_id, penta_matpar_id, penta_numpar_id, penta_properties);
    252 
    253                         /*Delete properties: */
    254                         delete penta_properties;
    255 
    256                         /*Add penta element to elements dataset: */
    257                         elements->AddObject(penta);
    258        
    259                         #ifdef _PARALLEL_
    260                         /*Now that we are here, we can also start building the list of grids belonging to this node partition: we use
    261                          *the  element index to do this. For each element n, we know index[n][0:2] holds the indices (matlab indexing)
    262                          into the grid coordinates. If we start plugging 1 into my_grids for each index[n][i] (i=0:2), then my_grids
    263                          will hold which grids belong to this partition*/
    264                         my_grids[(int)*(iomodel->elements+elements_width*i+0)-1]=1;
    265                         my_grids[(int)*(iomodel->elements+elements_width*i+1)-1]=1;
    266                         my_grids[(int)*(iomodel->elements+elements_width*i+2)-1]=1;
    267                         my_grids[(int)*(iomodel->elements+elements_width*i+3)-1]=1;
    268                         my_grids[(int)*(iomodel->elements+elements_width*i+4)-1]=1;
    269                         my_grids[(int)*(iomodel->elements+elements_width*i+5)-1]=1;
    270                         #endif
    271 
    272                 #ifdef _PARALLEL_
    273                 }//if(my_rank==epart[i])
    274                 #endif
    275 
     81                        }//if(my_elements[i])
    27682                }//for (i=0;i<numberofelements;i++)
    27783
     
    28591        } //if (strcmp(meshtype,"2d")==0)
    28692
    287         #ifdef _PARALLEL_
    288                 /*From the element partitioning, we can determine which grids are on the inside of this cpu's
    289                  *element partition, and which are on its border with other nodes:*/
    290                 gridborder=NewVec(iomodel->numberofnodes);
    291 
    292                 for (i=0;i<iomodel->numberofnodes;i++){
    293                         if(my_grids[i])VecSetValue(gridborder,i,1,ADD_VALUES);
    294                 }
    295                 VecAssemblyBegin(gridborder);
    296                 VecAssemblyEnd(gridborder);
    297 
    298                 #ifdef _ISSM_DEBUG_
    299                 VecView(gridborder,PETSC_VIEWER_STDOUT_WORLD);
    300                 #endif
    301                
    302                 VecToMPISerial(&my_bordergrids,gridborder);
    303 
    304                 #ifdef _ISSM_DEBUG_
    305                 if(my_rank==0){
    306                         for (i=0;i<iomodel->numberofnodes;i++){
    307                                 printf("Grid id %i Border grid %lf\n",i+1,my_bordergrids[i]);
    308                         }
    309                 }
    310                 #endif
    311         #endif
    312 
    313         /*Partition penalties in 3d: */
    314         if(strcmp(iomodel->meshtype,"3d")==0){
     93        /*Add new constrant material property tgo materials, at the end: */
     94        materials->AddObject(new Matpar(iomodel));
    31595       
    316                 /*Get penalties: */
    317                 IoModelFetchData(&iomodel->penalties,&iomodel->numpenalties,NULL,iomodel_handle,"penalties");
    318 
    319                 if(iomodel->numpenalties){
    320 
    321                         iomodel->penaltypartitioning=(int*)xmalloc(iomodel->numpenalties*sizeof(int));
    322                         #ifdef _SERIAL_
    323                         for(i=0;i<iomodel->numpenalties;i++)iomodel->penaltypartitioning[i]=1;
    324                         #else
    325                         for(i=0;i<iomodel->numpenalties;i++)iomodel->penaltypartitioning[i]=-1;
    326 
    327                         for(i=0;i<iomodel->numpenalties;i++){
    328                                 first_grid_index=(int)(*(iomodel->penalties+i*iomodel->numlayers+0)-1);
    329                                 if((my_grids[first_grid_index]==1) && (my_bordergrids[first_grid_index]<=1.0) ) { //this grid belongs to this node's internal partition  grids
    330                                         /*All grids that are being penalised belong to this node's internal grid partition.:*/
    331                                         iomodel->penaltypartitioning[i]=1;
    332                                 }
    333                                 if(my_bordergrids[first_grid_index]>1.0) { //this grid belongs to a partition border
    334                                         iomodel->penaltypartitioning[i]=0;
    335                                 }
    336                         }
    337                         #endif
    338                 }
    339 
    340                 /*Free penalties: */
    341                 xfree((void**)&iomodel->penalties);
    342         }
    343 
    344         /*Ok, let's summarise. Now, every CPU has the following two arrays: my_grids, and my_bordergrids.
    345          We can therefore determine  which grids are internal to this node's partition
    346          and which ones are shared with other nodes because they are on the border of this node's partition. Knowing
    347          that, go and create the grids*/
    348 
    349         /*Create nodes from x,y,z, as well as the spc values on those grids: */
    350                
    35196        /*First fetch data: */
    35297        if (strcmp(iomodel->meshtype,"3d")==0){
     
    364109        IoModelFetchData(&iomodel->gridoniceshelf,NULL,NULL,iomodel_handle,"gridoniceshelf");
    365110
     111        for (i=0;i<iomodel->numberofvertices;i++){
    366112
    367         /*Get number of dofs per node: */
    368         DistributeNumDofs(&node_numdofs,iomodel->analysis_type,iomodel->sub_analysis_type);
     113                /*vertices and nodes (same number, as we are running continuous galerkin formulation: */
     114                if(iomodel->my_vertices[i]){
     115                       
     116                        /*Add vertex to vertices dataset: */
     117                        vertices->AddObject(new Vertex(i,iomodel));
    369118
    370         for (i=0;i<iomodel->numberofnodes;i++){
    371         #ifdef _PARALLEL_
    372         /*keep only this partition's nodes:*/
    373         if((my_grids[i]==1)){
    374         #endif
     119                        /*Add node to nodes dataset: */
     120                        nodes->AddObject(new Node(i,iomodel));
    375121
    376                 /*create vertex: */
    377                 vertex_id=i+1;
    378                 vertex=new Vertex(vertex_id, iomodel->x[i],iomodel->y[i],iomodel->z[i],(iomodel->z[i]-iomodel->bed[i])/(iomodel->thickness[i]));
    379                 vertices->AddObject(vertex);
    380 
    381 
    382                 node_id=i+1; //matlab indexing
    383                
    384                 #ifdef _PARALLEL_
    385                 if(my_bordergrids[i]>1.0) { //this grid belongs to a partition border
    386                         node_partitionborder=1;
    387122                }
    388                 else{
    389                         node_partitionborder=0;
    390                 }
    391                 #else
    392                         node_partitionborder=0;
    393                 #endif
    394 
    395                 node_properties.SetProperties(
    396                         (int)iomodel->gridonbed[i],
    397                         (int)iomodel->gridonsurface[i],
    398                         (int)iomodel->gridoniceshelf[i],
    399                         (int)iomodel->gridonicesheet[i]);
    400 
    401                 if (strcmp(iomodel->meshtype,"3d")==0){
    402                         if (isnan(iomodel->uppernodes[i])){
    403                                 node_upper_node_id=node_id;  //nodes on surface do not have upper nodes, only themselves.
    404                         }
    405                         else{
    406                                 node_upper_node_id=(int)iomodel->uppernodes[i];
    407                         }
    408                 }
    409                 else{
    410                         /*If we are running 2d, upper_node does not mean much. Just point towards itself!:*/
    411                         node_upper_node_id=node_id;
    412                 }
    413 
    414                 /*Create node using its constructor: */
    415                 node=new Node(node_id,vertex_id, node_upper_node_id, node_partitionborder,node_numdofs, &node_properties);   
    416 
    417                 /*set single point constraints.: */
    418                 if (strcmp(iomodel->meshtype,"3d")==0){
    419                         /*On a 3d mesh, we may have collapsed elements, hence dead grids. Freeze them out: */
    420                         if (iomodel->gridonbed[i]==0){
    421                                 for(k=1;k<=node_numdofs;k++){
    422                                         node->FreezeDof(k);
    423                                 }
    424                         }
    425                 }
    426                 /*Add node to nodes dataset: */
    427                 nodes->AddObject(node);
    428 
    429         #ifdef _PARALLEL_
    430         } //if((my_grids[i]==1))
    431         #endif
    432123        }
    433 
    434         /*All our datasets are already order by ids. Set presort flag so that later on, when sorting is requested on these
    435          * datasets, it will not be redone: */
    436         elements->Presort();
    437         nodes->Presort();
    438         vertices->Presort();
    439         materials->Presort();
    440124
    441125        /*Clean fetched data: */
     
    452136        xfree((void**)&iomodel->gridoniceshelf);
    453137       
    454 
    455         /*Keep partitioning information into iomodel*/
    456         iomodel->epart=epart;
    457         iomodel->my_grids=my_grids;
    458         iomodel->my_bordergrids=my_bordergrids;
    459 
    460         /*Free ressources:*/
    461         #ifdef _PARALLEL_
    462         xfree((void**)&all_numgrids);
    463         xfree((void**)&npart);
    464         VecFree(&gridborder);
    465         #endif
     138        /*All our datasets are already order by ids. Set presort flag so that later on, when sorting is requested on these
     139         * datasets, it will not be redone: */
     140        elements->Presort();
     141        nodes->Presort();
     142        vertices->Presort();
     143        materials->Presort();
    466144
    467145        cleanup_and_return:
Note: See TracChangeset for help on using the changeset viewer.