Changeset 93


Ignore:
Timestamp:
04/28/09 15:18:46 (16 years ago)
Author:
Eric.Larour
Message:

New quad pressure

File:
1 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk/src/c/objects/Icefront.cpp

    r66 r93  
    6767        printf("   matpar_offset: %i\n",matpar_offset);
    6868        printf("   matpar: \n");
    69         if(matpar)matpar->Echo();
    7069       
    7170        printf("   element_type: %i\n",element_type);
     
    7372        printf("   element_offset: %i\n",eid);
    7473        printf("   element\n");
    75         if(element)element->Echo();
    7674               
    7775        if (strcmp(type,"segment")==0){
     
    319317                }
    320318        }
    321 
    322319        /* Set pe_g to 0: */
    323320        for(i=0;i<numdofs;i++) pe_g[i]=0.0;
     
    327324        if(element_type==PentaEnum())element_nodes=(Node**)xmalloc(6*sizeof(Node*));
    328325        element->GetNodes(element_nodes);
    329                
     326
    330327        /*go through first 3 grids (all grids for tria, bed grids for penta) and identify 1st and 2nd grid: */
    331328        for(i=0;i<3;i++){
     
    341338        element->GetThicknessList(&thickness_list_element[0]);
    342339        element->GetBedList(&bed_list_element[0]);
    343        
     340               
    344341        /*Build thickness_list and bed_list: */
    345342        thickness_list[0]=thickness_list_element[grid1];
     
    394391void Icefront::CreatePVectorDiagnosticHorizQuad( Vec pg,ParameterInputs* inputs, int analysis_type){
    395392
    396         throw ErrorException(__FUNCT__," not implemented yet!");
    397 }
     393        int i,j;
     394
     395        const int numgrids=4;
     396        const int NDOF2=2;
     397        const int numdofs=numgrids*NDOF2;
     398        int   numberofdofspernode;
     399        int   doflist[numdofs];
     400
     401        int    fill;
     402        double xyz_list[numgrids][3];
     403        double xyz_list_quad[numgrids+1][3]; //center node
     404
     405        double thickness_list[6]; //from penta element
     406        double thickness_list_quad[6]; //selection of 4 thickness from penta elements
     407
     408        double bed_list[6]; //from penta element
     409        double bed_list_quad[6]; //selection of 4 beds from penta elements
     410
     411        /*Objects: */
     412        double  pe_g[numdofs];
     413        Matpar* matpar=NULL;
     414        Node**  element_nodes=NULL;
     415
     416        /*quad grids: */
     417        int grid1,grid2,grid3,grid4;
     418
     419        /*normals: */
     420        double normal1[3];
     421        double normal2[3];
     422        double normal3[3];
     423        double normal4[3];
     424        double normal_norm;
     425        double v15[3];
     426        double v25[3];
     427        double v35[3];
     428        double v45[3];
     429               
     430
     431        /*check icefront is associated to a pentaelem: */
     432        if(element_type!=PentaEnum()){
     433                throw ErrorException(__FUNCT__," quad icefront is associated to a TriaElem!");
     434        }
     435        /*Recover material and fill parameters: */
     436        matpar=element->GetMatPar();
     437        fill=element->GetShelf();
     438
     439        /* Set pe_g to 0: */
     440        for(i=0;i<numdofs;i++) pe_g[i]=0.0;
     441
     442        /* Get dof list and node coordinates: */
     443        GetDofList(&doflist[0],&numberofdofspernode);
     444        GetElementNodeData( &xyz_list[0][0], nodes, numgrids);
     445       
     446        //Identify which grids are comprised in the quad:
     447        if(element_type==PentaEnum())element_nodes=(Node**)xmalloc(6*sizeof(Node*));
     448        element->GetNodes(element_nodes);
     449
     450        grid1=-1; grid2=-1; grid3=-1; grid4=-1;
     451        for(i=0;i<6;i++){
     452                if (nodes[0]==element_nodes[i])grid1=i;
     453                if (nodes[1]==element_nodes[i])grid2=i;
     454                if (nodes[2]==element_nodes[i])grid3=i;
     455                if (nodes[3]==element_nodes[i])grid4=i;
     456        }
     457       
     458        if((grid1==-1) || (grid2==-1)|| (grid3==-1)||(grid4==-1)){
     459                throw ErrorException(__FUNCT__,"could not find element grids corresponding to quad icefront!");
     460        }
     461
     462        /*Build new xyz, bed and thickness lists for grids 1 to 4: */
     463        for(i=0;i<4;i++){
     464                for(j=0;j<3;j++){
     465                        xyz_list_quad[i][j]=xyz_list[i][j];
     466                }
     467        }
     468
     469        element->GetThicknessList(&thickness_list[0]);
     470        element->GetBedList(&bed_list[0]);
     471
     472        thickness_list_quad[0]=thickness_list[grid1];
     473        thickness_list_quad[1]=thickness_list[grid2];
     474        thickness_list_quad[2]=thickness_list[grid3];
     475        thickness_list_quad[3]=thickness_list[grid4];
     476
     477        bed_list_quad[0]=bed_list[grid1];
     478        bed_list_quad[1]=bed_list[grid2];
     479        bed_list_quad[2]=bed_list[grid3];
     480        bed_list_quad[3]=bed_list[grid4];
     481
     482        //Create a new grid in the midle of the quad and add it at the end of the list
     483        xyz_list_quad[4][0] = (xyz_list_quad[0][0]+xyz_list_quad[1][0]+xyz_list_quad[2][0]+xyz_list_quad[3][0])/4.0;
     484        xyz_list_quad[4][1] = (xyz_list_quad[0][1]+xyz_list_quad[1][1]+xyz_list_quad[2][1]+xyz_list_quad[3][1])/4.0;
     485        xyz_list_quad[4][2] = (xyz_list_quad[0][2]+xyz_list_quad[1][2]+xyz_list_quad[2][2]+xyz_list_quad[3][2])/4.0;
     486
     487        //Compute four normals (the quad is divided into four triangles)
     488        v15[0]=xyz_list_quad[0][0]-xyz_list_quad[4][0];
     489        v15[1]=xyz_list_quad[0][1]-xyz_list_quad[4][1];
     490        v15[2]=xyz_list_quad[0][2]-xyz_list_quad[4][2];
     491       
     492        v25[0]=xyz_list_quad[1][0]-xyz_list_quad[4][0];
     493        v25[1]=xyz_list_quad[1][1]-xyz_list_quad[4][1];
     494        v25[2]=xyz_list_quad[1][2]-xyz_list_quad[4][2];
     495       
     496        v35[0]=xyz_list_quad[2][0]-xyz_list_quad[4][0];
     497        v35[1]=xyz_list_quad[2][1]-xyz_list_quad[4][1];
     498        v35[2]=xyz_list_quad[2][2]-xyz_list_quad[4][2];
     499       
     500        v45[0]=xyz_list_quad[3][0]-xyz_list_quad[4][0];
     501        v45[1]=xyz_list_quad[3][1]-xyz_list_quad[4][1];
     502        v45[2]=xyz_list_quad[3][2]-xyz_list_quad[4][2];
     503
     504        cross(normal1,v15,v25);
     505        cross(normal2,v25,v35);
     506        cross(normal3,v35,v45);
     507        cross(normal4,v45,v15);
     508
     509        normal_norm=norm(normal1);normal1[0]=normal1[0]/normal_norm;normal1[1]=normal1[1]/normal_norm;normal1[2]=normal1[2]/normal_norm;
     510        normal_norm=norm(normal2);normal2[0]=normal2[0]/normal_norm;normal2[1]=normal2[1]/normal_norm;normal2[2]=normal2[2]/normal_norm;
     511        normal_norm=norm(normal3);normal3[0]=normal3[0]/normal_norm;normal3[1]=normal3[1]/normal_norm;normal3[2]=normal3[2]/normal_norm;
     512        normal_norm=norm(normal4);normal4[0]=normal4[0]/normal_norm;normal4[1]=normal4[1]/normal_norm;normal4[2]=normal4[2]/normal_norm;
     513
     514
     515        //Compute load contribution for this quad:
     516        QuadPressureLoad(pe_g,matpar->GetRhoWater(),matpar->GetRhoIce(),matpar->GetG(),thickness_list_quad,bed_list_quad,normal1,normal2,normal3,normal4,&xyz_list_quad[0][0],fill);
     517
     518
     519        #ifdef _DEBUGELEMENTS_
     520        if(my_rank==RANK && eid==ELID){
     521                printf("\nicefront load\n");
     522                printf("grids %i %i %i %i\n",grid1,grid2,grid3,grid4);
     523                printf("rho_water %g\n",rho_water);
     524                printf("rho_ice %g\n",rho_ice);
     525                printf("gravity %g\n",gravity);
     526                printf("thickness_list (%g,%g,%g,%g)\n",thickness_list[0],thickness_list[1],thickness_list[2],thickness_list[3]);
     527                printf("bed_list (%g,%g,%g,%g)\n",bed_list[0],bed_list[1],bed_list[2],bed_list[3]);
     528                printf("normal1 (%g,%g,%g)\n",normal1[0],normal1[1],normal1[2]);
     529                printf("normal2 (%g,%g,%g)\n",normal2[0],normal2[1],normal2[2]);
     530                printf("normal3 (%g,%g,%g)\n",normal3[0],normal3[1],normal3[2]);
     531                printf("normal4 (%g,%g,%g)\n",normal4[0],normal4[1],normal4[2]);
     532                printf("fill %i\n",fill);
     533                printf("pe_g->terms\n");
     534                for(i=0;i<numgridsload*NDOF2;i++){
     535                        printf("%g ",*(pe_g->terms+i));
     536                }
     537        }
     538        #endif
     539
     540        /*Plug pe_g into vector: */
     541        VecSetValues(pg,numdofs,doflist,pe_g,ADD_VALUES);
     542
     543        /*Free ressources:*/
     544        xfree((void**)&element_nodes);
     545
     546}
     547
    398548
    399549#undef __FUNCT__
     
    428578                }
    429579        }
     580
    430581
    431582        /*Assign output pointers:*/
     
    521672}
    522673
     674
     675#undef __FUNCT__
     676#define __FUNCT__ "Icefront::QuadPressureLoad"
     677void Icefront::QuadPressureLoad(double* pe_g,double rho_water,double rho_ice,double gravity, double* thickness_list, double* bed_list,
     678                                              double* normal1,double* normal2,double* normal3,double* normal4,double* xyz_list, int fill){
     679       
     680       
     681        //The quad is divided into four triangles tria1 tria2 tria3 and tria4 as follows
     682        //
     683        //   grid 4 +-----------------+ grid 3
     684        //          |\2            1 /|
     685        //          |1\    tria3    /2|
     686        //          |  \           /  |
     687        //          |   \         /   |
     688        //          |    \       /    |
     689        //          |     \     /     |
     690        //          |      \ 3 /      |
     691        //          |tria4  \ / 3     |
     692        //          |      3 \grid5   |
     693        //          |       / \       |
     694        //          |      / 3 \ tria2|
     695        //          |     /     \     |
     696        //          |    /       \    |
     697        //          |   /         \   |
     698        //          |  /   tria1   \  |
     699        //          |2/1           2\1|
     700        //   grid1  +-----------------+ grid 2
     701        //
     702        //
     703
     704        int      i,j;
     705
     706        double nx[4];
     707        double ny[4];
     708
     709        /* gaussian points: */
     710        int     num_gauss,ig;
     711        double* first_gauss_area_coord  =  NULL;
     712        double* second_gauss_area_coord =  NULL;
     713        double* third_gauss_area_coord  =  NULL;
     714        double* gauss_weights           =  NULL;
     715        double  gauss_weight;
     716        double  gauss_coord[3];
     717
     718        double  surface_list[5];
     719        double  x[5];
     720        double  y[5];
     721        double  z[5];
     722        double l12,l14,l15,l23,l25,l34,l35,l45;
     723        double cos_theta_triangle1,cos_theta_triangle2,cos_theta_triangle3,cos_theta_triangle4;
     724
     725        double xyz_tria[12][2];
     726        double l1l2l3_tria[3];
     727        double r_tria,s_tria;
     728        double r_quad[4];
     729        double s_quad[4];
     730        double l1l4_tria[4][4];
     731
     732        double J[4];
     733        double z_g[4];
     734        double ice_pressure_tria[4];
     735        double air_pressure_tria;
     736        double water_level_above_g_tria;
     737        double water_pressure_tria;
     738        double pressure_tria[4];
     739
     740        /*To use tria functionalities: */
     741        Tria* tria=NULL;
     742
     743        /*Initialize fake tria: */
     744        tria=new Tria();
     745
     746        //Build the four normal vectors
     747        nx[0]=normal1[0]; nx[1]=normal2[0]; nx[2]=normal3[0]; nx[3]=normal4[0];
     748        ny[0]=normal1[1]; ny[1]=normal2[1]; ny[2]=normal3[1]; ny[3]=normal4[1];
     749
     750        /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */
     751        GaussTria( &num_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &gauss_weights, 2);
     752       
     753        //Recover the surface of the four nodes
     754        for(i=0;i<4;i++){
     755                surface_list[i]=thickness_list[i]+bed_list[i];
     756        }
     757        //Add surface sor the fifth point (average of the surfaces)
     758        surface_list[4]=(surface_list[0]+surface_list[1]+surface_list[2]+surface_list[3])/4.0;
     759
     760        //Recover grid coordinates
     761        for(i=0;i<5;i++){
     762                x[i]=*(xyz_list+3*i+0);
     763                y[i]=*(xyz_list+3*i+1);
     764                z[i]=*(xyz_list+3*i+2);
     765        }
     766       
     767        //Build triangles in a 2D plan before using reference elements
     768        l12=pow((x[1]-x[0]),2)+pow((y[1]-y[0]),2)+pow((z[1]-z[0]),2);
     769        l14=pow((x[3]-x[0]),2)+pow((y[3]-y[0]),2)+pow((z[3]-z[0]),2);
     770        l15=pow((x[4]-x[0]),2)+pow((y[4]-y[0]),2)+pow((z[4]-z[0]),2);
     771        l23=pow((x[2]-x[1]),2)+pow((y[2]-y[1]),2)+pow((z[2]-z[1]),2);
     772        l25=pow((x[4]-x[1]),2)+pow((y[4]-y[1]),2)+pow((z[4]-z[1]),2);
     773        l34=pow((x[3]-x[2]),2)+pow((y[3]-y[2]),2)+pow((z[3]-z[2]),2);
     774        l35=pow((x[4]-x[2]),2)+pow((y[4]-y[2]),2)+pow((z[4]-z[2]),2);
     775        l45=pow((x[4]-x[3]),2)+pow((y[4]-y[3]),2)+pow((z[4]-z[3]),2);
     776
     777        cos_theta_triangle1=(l15+l12-l25)/(2*sqrt(l12*l15));
     778        cos_theta_triangle2=(l25+l23-l35)/(2*sqrt(l23*l25));
     779        cos_theta_triangle3=(l35+l34-l45)/(2*sqrt(l34*l35));
     780        cos_theta_triangle4=(l45+l14-l15)/(2*sqrt(l14*l45));
     781
     782        //First triangle : nodes 1, 2 and 5
     783        xyz_tria[0][0]=0;
     784        xyz_tria[0][1]=0;
     785        xyz_tria[1][0]=sqrt(l12);
     786        xyz_tria[1][1]=0;
     787        xyz_tria[2][0]=cos_theta_triangle1*sqrt(l15);
     788        xyz_tria[2][1]=sqrt(1-pow(cos_theta_triangle1,2))*sqrt(l15);
     789
     790        //Second triangle : nodes 2, 3 and 5
     791        xyz_tria[3][0]=0;
     792        xyz_tria[3][1]=0;
     793        xyz_tria[4][0]=sqrt(l23);
     794        xyz_tria[4][1]=0;
     795        xyz_tria[5][0]=cos_theta_triangle2*sqrt(l25);
     796        xyz_tria[5][1]=sqrt(1-pow(cos_theta_triangle2,2))*sqrt(l25);
     797       
     798        //Third triangle : nodes 3, 4 and 5
     799        xyz_tria[6][0]=0;
     800        xyz_tria[6][1]=0;
     801        xyz_tria[7][0]=sqrt(l34);
     802        xyz_tria[7][1]=0;
     803        xyz_tria[8][0]=cos_theta_triangle3*sqrt(l35);
     804        xyz_tria[8][1]=sqrt(1-pow(cos_theta_triangle3,2))*sqrt(l35);
     805
     806        //Fourth triangle : nodes 4, 1 and 5
     807        xyz_tria[9][0]=0;
     808        xyz_tria[9][1]=0;
     809        xyz_tria[10][0]=sqrt(l14);
     810        xyz_tria[10][1]=0;
     811        xyz_tria[11][0]=cos_theta_triangle4*sqrt(l45);
     812        xyz_tria[11][1]=sqrt(1-pow(cos_theta_triangle4,2))*sqrt(l45);
     813
     814       
     815
     816        //Start  looping on the triangle's gaussian points:
     817        for(ig=0;ig<num_gauss;ig++){
     818
     819                /*Pick up the gaussian point: */
     820                gauss_weight=*(gauss_weights+ig);
     821                gauss_coord[0]=*(first_gauss_area_coord+ig);
     822                gauss_coord[1]=*(second_gauss_area_coord+ig);
     823                gauss_coord[2]=*(third_gauss_area_coord+ig);
     824       
     825                tria->GetNodalFunctions(l1l2l3_tria,gauss_coord);
     826
     827                //Get the coordinates of gauss point for each triangle in penta/quad
     828                r_tria=gauss_coord[1]-gauss_coord[0];
     829                s_tria=-3/sqrt(3)*(gauss_coord[0]+gauss_coord[1]-2/3);
     830
     831                //Coordinates of gauss points in the reference triangle
     832                r_quad[0]=r_tria;
     833                s_quad[0]=1/sqrt(3)*s_tria-2/3;
     834                r_quad[1]=-1/sqrt(3)*s_tria+2/3;
     835                s_quad[1]=r_tria;
     836                r_quad[2]=-r_tria;
     837                s_quad[2]=-1/sqrt(3)*s_tria+2/3;
     838                r_quad[3]=1/sqrt(3)*s_tria-2/3;
     839                s_quad[3]=-r_tria;
     840
     841                //Get the nodal function of the quad for the gauss points of each triangle
     842                for(i=0;i<4;i++){
     843                        l1l4_tria[i][0]=1.0/4.0*(
     844                                        (r_quad[i]-1.0)*(s_quad[i]-1.0)
     845                                        );
     846                       
     847                        l1l4_tria[i][1]=1.0/4.0*(
     848                                         -(r_quad[i]+1.0)*(s_quad[i]-1.0)
     849                                        );
     850
     851                        l1l4_tria[i][2]=1.0/4.0*(
     852                                        (r_quad[i]+1.0)*(s_quad[i]+1.0)
     853                                        );
     854                       
     855                        l1l4_tria[i][3]=1.0/4.0*(
     856                                         -(r_quad[i]-1.0)*(s_quad[i]+1.0)
     857                                        );
     858
     859                } //for(i=0;i<4;i++)
     860               
     861               
     862                //Compute jacobian of each triangle
     863                for (i=0;i<4;i++){
     864                        double complete_list[3][3]; //a third coordinate is needed for the jacobian determinant calculation, here it is zero
     865                        for(j=0;j<3;j++){
     866                                complete_list[j][0]=xyz_tria[3*i+j][0];
     867                                complete_list[j][1]=xyz_tria[3*i+j][1];
     868                                complete_list[j][2]=0;
     869                        }
     870                        tria->GetJacobianDeterminant(&J[i],&complete_list[0][0],l1l2l3_tria);
     871                }
     872
     873                //Calculation of the z coordinate for the gaussian point ig for each triangle
     874                z_g[0]=z[0]*l1l2l3_tria[0]+z[1]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2];
     875                z_g[1]=z[1]*l1l2l3_tria[0]+z[2]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2];
     876                z_g[2]=z[2]*l1l2l3_tria[0]+z[3]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2];
     877                z_g[3]=z[3]*l1l2l3_tria[0]+z[0]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2];
     878               
     879                //Loop on the triangles
     880                for(i=0;i<4;i++){
     881
     882                        //Loop on the grids of the quad
     883                        //Calculate the ice pressure
     884                        for(j=0;j<4;j++){
     885                                ice_pressure_tria[j]=gravity*rho_ice*(surface_list[j]-z_g[i]);
     886                        }
     887                        air_pressure_tria=0;
     888
     889                        //Now deal with water pressure:
     890                        if(fill==1){ //icefront ends in water
     891                                water_level_above_g_tria=min(0,z_g[i]);//0 if the gaussian point is above water level
     892                                water_pressure_tria=rho_water*gravity*water_level_above_g_tria;
     893                        }
     894                        else if(fill==0){
     895                                water_pressure_tria=0;
     896                        }
     897                        else{
     898                                throw ErrorException(__FUNCT__,"QuadPressureLoad error message: unknow fill type for icefront boundary condition");
     899                        }
     900
     901                        //Add pressure from triangle i
     902                        //Loop on the grids of the quad
     903                        for(j=0;j<4;j++){
     904                                pressure_tria[j] = ice_pressure_tria[j] + water_pressure_tria + air_pressure_tria;
     905                        }
     906
     907
     908                        pe_g[0]+= J[i]*gauss_weight* pressure_tria[0]*l1l4_tria[i][0]*nx[i];
     909                        pe_g[1]+= J[i]*gauss_weight* pressure_tria[0]*l1l4_tria[i][0]*ny[i];
     910                        pe_g[2]+= J[i]*gauss_weight* pressure_tria[1]*l1l4_tria[i][1]*nx[i];
     911                        pe_g[3]+= J[i]*gauss_weight* pressure_tria[1]*l1l4_tria[i][1]*ny[i];
     912                        pe_g[4]+= J[i]*gauss_weight* pressure_tria[2]*l1l4_tria[i][2]*nx[i];
     913                        pe_g[5]+= J[i]*gauss_weight* pressure_tria[2]*l1l4_tria[i][2]*ny[i];
     914                        pe_g[6]+= J[i]*gauss_weight* pressure_tria[3]*l1l4_tria[i][3]*nx[i];
     915                        pe_g[7]+= J[i]*gauss_weight* pressure_tria[3]*l1l4_tria[i][3]*ny[i];
     916
     917                       
     918
     919                } //for(i=0;i<4;i++)
     920        } //for(ig=0;ig<num_gauss;ig++)
     921
     922        /*Delete fake tria: */
     923        delete tria;
     924}
Note: See TracChangeset for help on using the changeset viewer.