Changeset 3424


Ignore:
Timestamp:
04/07/10 15:51:50 (15 years ago)
Author:
seroussi
Message:

added model processor for Prognostic

File:
1 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk/src/c/ModelProcessorx/Prognostic/CreateElementsNodesAndMaterialsPrognostic.cpp

    r3417 r3424  
    22 * CreateElementsNodesAndMaterialsPrognostic.c:
    33 */
    4 
    54
    65#include "../../DataSet/DataSet.h"
     
    1312#include "../IoModel.h"
    1413
    15 
    1614void    CreateElementsNodesAndMaterialsPrognostic(DataSet** pelements,DataSet** pnodes, DataSet** pvertices,DataSet** pmaterials, IoModel* iomodel,ConstDataHandle iomodel_handle){
    17 
    1815
    1916        /*output: int* epart, int* my_grids, double* my_bordergrids*/
    2017
    21 
    2218        int i,j,k,n;
    23         extern int my_rank;
    24         extern int num_procs;
    2519
    2620        /*DataSets: */
     
    3024        DataSet*    materials = NULL;
    3125       
    32         /*Objects: */
    33         Node*       node   = NULL;
    34         Vertex*     vertex = NULL;
    35         Tria*       tria = NULL;
    36         Penta*      penta = NULL;
    37         Matice*     matice  = NULL;
    38         Matpar*     matpar  = NULL;
    39         ElementProperties* tria_properties=NULL;
    40         ElementProperties* penta_properties=NULL;
    41 
    42         /*output: */
    43         int* epart=NULL; //element partitioning.
    44         int* npart=NULL; //node partitioning.
    45         int* my_grids=NULL;
    46         double* my_bordergrids=NULL;
    47 
    48 
    49         /*intermediary: */
    50         int elements_width; //size of elements
    51         double B_avg;
    52                        
    53         /*tria constructor input: */
    54         int tria_id;
    55         int tria_matice_id;
    56         int tria_matpar_id;
    57         int tria_numpar_id;
    58         int tria_node_ids[3];
    59         double tria_h[3];
    60         double tria_s[3];
    61         double tria_b[3];
    62         int    tria_shelf;
    63         bool   tria_onwater;
    64 
    65         /*matice constructor input: */
    66         int    matice_mid;
    67         double matice_B;
    68         double matice_n;
    69        
    70         /*penta constructor input: */
    71 
    72         int penta_id;
    73         int penta_matice_id;
    74         int penta_matpar_id;
    75         int penta_numpar_id;
    76         int penta_node_ids[6];
    77         double penta_h[6];
    78         double penta_s[6];
    79         double penta_b[6];
    80         int penta_shelf;
    81         int penta_onbed;
    82         int penta_onsurface;
    83         int penta_collapse;
    84         bool   penta_onwater;
    85 
    86         /*matpar constructor input: */
    87         int     matpar_mid;
    88         double matpar_rho_ice;
    89         double matpar_rho_water;
    90         double matpar_heatcapacity;
    91         double matpar_thermalconductivity;
    92         double matpar_latentheat;
    93         double matpar_beta;
    94         double matpar_meltingpoint;
    95         double matpar_mixed_layer_capacity;
    96         double matpar_thermal_exchange_velocity;
    97         double matpar_g;
    98 
    99         /* node constructor input: */
    100         int node_id;
    101         int vertex_id;
    102         int node_partitionborder=0;
    103         int node_onbed;
    104         int node_onsurface;
    105         int node_onshelf;
    106         int node_onsheet;
    107         int node_upper_node_id;
    108         int node_numdofs;
    109 
    110                
    111         #ifdef _PARALLEL_
    112         /*Metis partitioning: */
    113         int  range;
    114         Vec  gridborder=NULL;
    115         int  my_numgrids;
    116         int* all_numgrids=NULL;
    117         int  gridcount;
    118         int  count;
    119         #endif
    120         int  first_grid_index;
    121 
    12226        /*First create the elements, nodes and material properties: */
    12327        elements  = new DataSet(ElementsEnum());
     
    12630        materials = new DataSet(MaterialsEnum());
    12731
    128         /*Width of elements: */
    129         if(strcmp(iomodel->meshtype,"2d")==0){
    130                 elements_width=3; //tria elements
    131         }
    132         else{
    133                 elements_width=6; //penta elements
    134         }
    135 
    136         #ifdef _PARALLEL_
    137         /*Determine parallel partitioning of elements: we use Metis for now. First load the data, then partition*/
    138         if(strcmp(iomodel->meshtype,"2d")==0){
    139                 /*load elements: */
    140                 IoModelFetchData(&iomodel->elements,NULL,NULL,iomodel_handle,"elements");
    141         }
    142         else{
    143                 /*load elements2d: */
    144                 IoModelFetchData(&iomodel->elements2d,NULL,NULL,iomodel_handle,"elements2d");
    145         }
    146 
    147 
    148         MeshPartitionx(&epart, &npart,iomodel->numberofelements,iomodel->numberofnodes,iomodel->elements, iomodel->numberofelements2d,iomodel->numberofnodes2d,iomodel->elements2d,iomodel->numlayers,elements_width, iomodel->meshtype,num_procs);
    149 
    150         /*Free elements and elements2d: */
    151         xfree((void**)&iomodel->elements);
    152         xfree((void**)&iomodel->elements2d);
    153 
    154         /*Used later on: */
    155         my_grids=(int*)xcalloc(iomodel->numberofnodes,sizeof(int));
    156         #endif
    157 
    158 
    159 
    160         /*elements created vary if we are dealing with a 2d mesh, or a 3d mesh: */
     32        /*Partition elements and vertices and nodes: */
     33        Partitioning(&iomodel->my_elements, &iomodel->my_vertices, &iomodel->my_nodes, &iomodel->my_bordervertices, iomodel, iomodel_handle);
    16134
    16235        /*2d mesh: */
     
    17346                for (i=0;i<iomodel->numberofelements;i++){
    17447
    175                 #ifdef _PARALLEL_
    176                 /*!All elements have been partitioned above, only create elements for this CPU: */
    177                 if(my_rank==epart[i]){
    178                 #endif
    179                        
    180                        
    181                         /*ids: */
    182                         tria_id=i+1; //matlab indexing.
    183                         tria_matice_id=-1; //no need for materials
    184                         tria_matpar_id=-1; //no need for materials
    185                         tria_numpar_id=1;
     48                        if(iomodel->my_elements[i]){
    18649
    187                         /*vertices offsets: */
    188                         tria_node_ids[0]=(int)*(iomodel->elements+elements_width*i+0);
    189                         tria_node_ids[1]=(int)*(iomodel->elements+elements_width*i+1);
    190                         tria_node_ids[2]=(int)*(iomodel->elements+elements_width*i+2);
     50                                /*Create and add tria element to elements dataset: */
     51                                elements->AddObject(new Tria(i,iomodel));
    19152
    192                         /*thickness,surface and bed:*/
    193                         tria_h[0]= *(iomodel->thickness+ ((int)*(iomodel->elements+elements_width*i+0)-1)); //remember, elements is an index of vertices offsets, in matlab indexing.
    194                         tria_h[1]=*(iomodel->thickness+  ((int)*(iomodel->elements+elements_width*i+1)-1));
    195                         tria_h[2]=*(iomodel->thickness+  ((int)*(iomodel->elements+elements_width*i+2)-1)) ;
    196 
    197                         tria_s[0]=*(iomodel->surface+    ((int)*(iomodel->elements+elements_width*i+0)-1));
    198                         tria_s[1]=*(iomodel->surface+    ((int)*(iomodel->elements+elements_width*i+1)-1));
    199                         tria_s[2]=*(iomodel->surface+    ((int)*(iomodel->elements+elements_width*i+2)-1));
    200 
    201                         tria_b[0]=*(iomodel->bed+        ((int)*(iomodel->elements+elements_width*i+0)-1));
    202                         tria_b[1]=*(iomodel->bed+        ((int)*(iomodel->elements+elements_width*i+1)-1));
    203                         tria_b[2]=*(iomodel->bed+        ((int)*(iomodel->elements+elements_width*i+2)-1));
    204 
    205                         /*element on iceshelf?:*/
    206                         tria_shelf=(int)*(iomodel->elementoniceshelf+i);
    207                         tria_onwater=(bool)*(iomodel->elementonwater+i);
    208 
    209                         /*Create properties: */
    210                         tria_properties=new ElementProperties(3,tria_h, tria_s, tria_b, NULL, NULL, NULL, NULL, UNDEF, UNDEF, UNDEF, tria_shelf, UNDEF, tria_onwater, UNDEF, UNDEF, UNDEF);
    211 
    212                         /*Create tria element using its constructor:*/
    213                         tria=new Tria(tria_id, tria_node_ids, tria_matice_id, tria_matpar_id, tria_numpar_id, tria_properties);
    214 
    215                         /*Delete properties: */
    216                         delete tria_properties;
    217 
    218                         /*Add tria element to elements dataset: */
    219                         elements->AddObject(tria);
    220 
    221                         #ifdef _PARALLEL_
    222                         /*Now that we are here, we can also start building the list of grids belonging to this node partition: we use
    223                          *the  element index to do this. For each element n, we know index[n][0:2] holds the indices (matlab indexing)
    224                          into the grid coordinates. If we start plugging 1 into my_grids for each index[n][i] (i=0:2), then my_grids
    225                          will hold which grids belong to this partition*/
    226                         my_grids[(int)*(iomodel->elements+elements_width*i+0)-1]=1;
    227                         my_grids[(int)*(iomodel->elements+elements_width*i+1)-1]=1;
    228                         my_grids[(int)*(iomodel->elements+elements_width*i+2)-1]=1;
    229                         #endif
    230 
    231                 #ifdef _PARALLEL_
    232                 }//if(my_rank==epart[i])
    233                 #endif
    234 
     53                                /*Create and add material property to materials dataset: */
     54                                materials->AddObject(new Matice(i,iomodel,3));
     55                        }
    23556                }//for (i=0;i<numberofelements;i++)
    23657
     
    25879       
    25980                for (i=0;i<iomodel->numberofelements;i++){
    260                 #ifdef _PARALLEL_
    261                 /*We are using our element partition to decide which elements will be created on this node: */
    262                 if(my_rank==epart[i]){
    263                 #endif
     81                        if(iomodel->my_elements[i]){
     82                                /*Create and add penta element to elements dataset: */
     83                                elements->AddObject(new Penta(i,iomodel));
    26484
    265                        
    266                         /*name and id: */
    267                         penta_id=i+1; //matlab indexing.
    268                         penta_matice_id=-1;
    269                         penta_matpar_id=-1; //no need for materials
    270                         penta_numpar_id=1;
    271 
    272                         /*vertices,thickness,surface,bed and drag: */
    273                         for(j=0;j<6;j++){
    274                                 penta_node_ids[j]=(int)*(iomodel->elements+elements_width*i+j);
    275                                 penta_h[j]=*(iomodel->thickness+    ((int)*(iomodel->elements+elements_width*i+j)-1));
    276                                 penta_s[j]=*(iomodel->surface+    ((int)*(iomodel->elements+elements_width*i+j)-1));
    277                                 penta_b[j]=*(iomodel->bed+    ((int)*(iomodel->elements+elements_width*i+j)-1));
     85                                /*Create and add material property to materials dataset: */
     86                                materials->AddObject(new Matice(i,iomodel,6));
    27887                        }
    279 
    280                         /*diverse: */
    281                         penta_shelf=(int)*(iomodel->elementoniceshelf+i);
    282                         penta_onbed=(int)*(iomodel->elementonbed+i);
    283                         penta_onsurface=(int)*(iomodel->elementonsurface+i);
    284                         penta_collapse=1;
    285                         penta_onwater=(bool)*(iomodel->elementonwater+i);
    286        
    287                         /*Create properties: */
    288                         penta_properties=new ElementProperties(6,penta_h, penta_s, penta_b, NULL, NULL, NULL, NULL, UNDEF, UNDEF, UNDEF, penta_shelf, penta_onbed, penta_onwater, penta_onsurface, penta_collapse, UNDEF);
    289 
    290                         /*Create Penta using its constructor:*/
    291                         penta=new Penta(penta_id, penta_node_ids, penta_matice_id, penta_matpar_id, penta_numpar_id, penta_properties);
    292 
    293                         /*Delete properties: */
    294                         delete penta_properties;
    295 
    296                         /*Add penta element to elements dataset: */
    297                         elements->AddObject(penta);
    298        
    299                         #ifdef _PARALLEL_
    300                         /*Now that we are here, we can also start building the list of grids belonging to this node partition: we use
    301                          *the  element index to do this. For each element n, we know index[n][0:2] holds the indices (matlab indexing)
    302                          into the grid coordinates. If we start plugging 1 into my_grids for each index[n][i] (i=0:2), then my_grids
    303                          will hold which grids belong to this partition*/
    304                         my_grids[(int)*(iomodel->elements+elements_width*i+0)-1]=1;
    305                         my_grids[(int)*(iomodel->elements+elements_width*i+1)-1]=1;
    306                         my_grids[(int)*(iomodel->elements+elements_width*i+2)-1]=1;
    307                         my_grids[(int)*(iomodel->elements+elements_width*i+3)-1]=1;
    308                         my_grids[(int)*(iomodel->elements+elements_width*i+4)-1]=1;
    309                         my_grids[(int)*(iomodel->elements+elements_width*i+5)-1]=1;
    310                         #endif
    311 
    312                 #ifdef _PARALLEL_
    313                 }//if(my_rank==epart[i])
    314                 #endif
    315 
    31688                }//for (i=0;i<numberofelements;i++)
    31789
     
    328100        } //if (strcmp(meshtype,"2d")==0)
    329101
    330         #ifdef _PARALLEL_
    331                 /*From the element partitioning, we can determine which grids are on the inside of this cpu's
    332                  *element partition, and which are on its border with other nodes:*/
    333                 gridborder=NewVec(iomodel->numberofnodes);
    334 
    335                 for (i=0;i<iomodel->numberofnodes;i++){
    336                         if(my_grids[i])VecSetValue(gridborder,i,1,ADD_VALUES);
    337                 }
    338                 VecAssemblyBegin(gridborder);
    339                 VecAssemblyEnd(gridborder);
    340 
    341                 #ifdef _ISSM_DEBUG_
    342                 VecView(gridborder,PETSC_VIEWER_STDOUT_WORLD);
    343                 #endif
    344                
    345                 VecToMPISerial(&my_bordergrids,gridborder);
    346 
    347                 #ifdef _ISSM_DEBUG_
    348                 if(my_rank==0){
    349                         for (i=0;i<iomodel->numberofnodes;i++){
    350                                 printf("Grid id %i Border grid %lf\n",i+1,my_bordergrids[i]);
    351                         }
    352                 }
    353                 #endif
    354         #endif
    355 
    356         /*Add one constant material property to materials: */
    357         matpar_mid=1; //put it at the end of the materials
    358         matpar_g=iomodel->g;
    359         matpar_rho_ice=iomodel->rho_ice;
    360         matpar_rho_water=iomodel->rho_water;
    361         matpar_thermalconductivity=iomodel->thermalconductivity;
    362         matpar_heatcapacity=iomodel->heatcapacity;
    363         matpar_latentheat=iomodel->latentheat;
    364         matpar_beta=iomodel->beta;
    365         matpar_meltingpoint=iomodel->meltingpoint;
    366         matpar_mixed_layer_capacity=iomodel->mixed_layer_capacity;
    367         matpar_thermal_exchange_velocity=iomodel->thermal_exchange_velocity;
    368 
    369         /*Create matpar object using its constructor: */
    370         matpar=new Matpar(matpar_mid,matpar_rho_ice,matpar_rho_water,matpar_heatcapacity,matpar_thermalconductivity,
    371                         matpar_latentheat,matpar_beta,matpar_meltingpoint,matpar_mixed_layer_capacity,
    372                         matpar_thermal_exchange_velocity,matpar_g);
    373                
    374         /*Add to materials datset: */
    375         materials->AddObject(matpar);
    376 
    377         /*Partition penalties in 3d: */
    378         if(strcmp(iomodel->meshtype,"3d")==0){
    379        
    380                 /*Get penalties: */
    381                 IoModelFetchData(&iomodel->penalties,&iomodel->numpenalties,NULL,iomodel_handle,"penalties");
    382 
    383                 if(iomodel->numpenalties){
    384 
    385                         iomodel->penaltypartitioning=(int*)xmalloc(iomodel->numpenalties*sizeof(int));
    386                         #ifdef _SERIAL_
    387                         for(i=0;i<iomodel->numpenalties;i++)iomodel->penaltypartitioning[i]=1;
    388                         #else
    389                         for(i=0;i<iomodel->numpenalties;i++)iomodel->penaltypartitioning[i]=-1;
    390 
    391                         for(i=0;i<iomodel->numpenalties;i++){
    392                                 first_grid_index=(int)(*(iomodel->penalties+i*iomodel->numlayers+0)-1);
    393                                 if((my_grids[first_grid_index]==1) && (my_bordergrids[first_grid_index]<=1.0) ) { //this grid belongs to this node's internal partition  grids
    394                                         /*All grids that are being penalised belong to this node's internal grid partition.:*/
    395                                         iomodel->penaltypartitioning[i]=1;
    396                                 }
    397                                 if(my_bordergrids[first_grid_index]>1.0) { //this grid belongs to a partition border
    398                                         iomodel->penaltypartitioning[i]=0;
    399                                 }
    400                         }
    401                         #endif
    402                 }
    403 
    404                 /*Free penalties: */
    405                 xfree((void**)&iomodel->penalties);
    406         }
    407 
    408         /*Ok, let's summarise. Now, every CPU has the following two arrays: my_grids, and my_bordergrids.
    409          We can therefore determine  which grids are internal to this node's partition
    410          and which ones are shared with other nodes because they are on the border of this node's partition. Knowing
    411          that, go and create the grids*/
    412 
    413         /*Create nodes from x,y,z, as well as the spc values on those grids: */
     102        /*Add new constrant material property to materials, at the end: */
     103        materials->AddObject(new Matpar(iomodel));
    414104               
    415105        /*First fetch data: */
     
    428118        IoModelFetchData(&iomodel->gridoniceshelf,NULL,NULL,iomodel_handle,"gridoniceshelf");
    429119
     120        for (i=0;i<iomodel->numberofvertices;i++){
    430121
    431         /*Get number of dofs per node: */
    432         DistributeNumDofs(&node_numdofs,iomodel->analysis_type,iomodel->sub_analysis_type);
     122                /*vertices and nodes (same number, as we are running continuous galerkin formulation: */
     123                if(iomodel->my_vertices[i]){
    433124
    434         for (i=0;i<iomodel->numberofnodes;i++){
    435         #ifdef _PARALLEL_
    436         /*keep only this partition's nodes:*/
    437         if((my_grids[i]==1)){
    438         #endif
     125                        /*Add vertex to vertices dataset: */
     126                        vertices->AddObject(new Vertex(i,iomodel));
    439127
    440                 /*create vertex: */
    441                 vertex_id=i+1;
    442                 vertex=new Vertex(vertex_id, iomodel->x[i],iomodel->y[i],iomodel->z[i],(iomodel->z[i]-iomodel->bed[i])/(iomodel->thickness[i]));
    443                 vertices->AddObject(vertex);
     128                        /*Add node to nodes dataset: */
     129                        nodes->AddObject(new Node(i,iomodel));
    444130
    445 
    446                 node_id=i+1; //matlab indexing
    447                
    448                 #ifdef _PARALLEL_
    449                 if(my_bordergrids[i]>1.0) { //this grid belongs to a partition border
    450                         node_partitionborder=1;
    451131                }
    452                 else{
    453                         node_partitionborder=0;
    454                 }
    455                 #else
    456                         node_partitionborder=0;
    457                 #endif
    458 
    459                 node_properties.SetProperties(
    460                         (int)iomodel->gridonbed[i],
    461                         (int)iomodel->gridonsurface[i],
    462                         (int)iomodel->gridoniceshelf[i],
    463                         (int)iomodel->gridonicesheet[i]);
    464 
    465        
    466                 if (strcmp(iomodel->meshtype,"3d")==0){
    467                         if (isnan(iomodel->uppernodes[i])){
    468                                 node_upper_node_id=node_id;  //nodes on surface do not have upper nodes, only themselves.
    469                         }
    470                         else{
    471                                 node_upper_node_id=(int)iomodel->uppernodes[i];
    472                         }
    473                 }
    474                 else{
    475                         /*If we are running 2d, upper_node does not mean much. Just point towards itself!:*/
    476                         node_upper_node_id=node_id;
    477                 }
    478 
    479                 /*Create node using its constructor: */
    480                 node=new Node(node_id,vertex_id, node_upper_node_id, node_partitionborder,node_numdofs, &node_properties);   
    481 
    482                 /*set single point constraints.: */
    483                 if (strcmp(iomodel->meshtype,"3d")==0){
    484                         /*On a 3d mesh, we may have collapsed elements, hence dead grids. Freeze them out: */
    485                         if (!iomodel->gridonbed[i]){
    486                                 for(k=1;k<=node_numdofs;k++){
    487                                         node->FreezeDof(k);
    488                                 }
    489                         }
    490                 }
    491                 /*Add node to nodes dataset: */
    492                 nodes->AddObject(node);
    493 
    494         #ifdef _PARALLEL_
    495         } //if((my_grids[i]==1))
    496         #endif
    497132        }
    498 
    499         /*All our datasets are already order by ids. Set presort flag so that later on, when sorting is requested on these
    500          * datasets, it will not be redone: */
    501         elements->Presort();
    502         nodes->Presort();
    503         vertices->Presort();
    504         materials->Presort();
    505133
    506134        /*Clean fetched data: */
     
    517145        xfree((void**)&iomodel->gridoniceshelf);
    518146       
    519 
    520         /*Keep partitioning information into iomodel*/
    521         iomodel->epart=epart;
    522         iomodel->my_grids=my_grids;
    523         iomodel->my_bordergrids=my_bordergrids;
    524 
    525         /*Free ressources:*/
    526         #ifdef _PARALLEL_
    527         xfree((void**)&all_numgrids);
    528         xfree((void**)&npart);
    529         VecFree(&gridborder);
    530         #endif
     147        /*All our datasets are already order by ids. Set presort flag so that later on, when sorting is requested on these
     148         * datasets, it will not be redone: */
     149        elements->Presort();
     150        nodes->Presort();
     151        vertices->Presort();
     152        materials->Presort();
    531153
    532154        cleanup_and_return:
Note: See TracChangeset for help on using the changeset viewer.