Changeset 5808
- Timestamp:
- 09/14/10 16:08:56 (15 years ago)
- Location:
- issm/trunk/src/c
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk/src/c/objects/Elements/Penta.cpp
r5806 r5808 4300 4300 } 4301 4301 /*}}}*/ 4302 /*FUNCTION Penta::GetZcoord {{{1*/ 4303 double Penta::GetZcoord(GaussPenta* gauss){ 4304 4305 int i; 4306 double xyz_list[NUMVERTICES][3]; 4307 double z_list[NUMVERTICES]; 4308 double z; 4309 4310 GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES); 4311 for(i=0;i<NUMVERTICES;i++){ 4312 z_list[i]=xyz_list[i][2]; 4313 } 4314 PentaRef::GetParameterValue(&z,z_list,gauss); 4315 4316 return z; 4317 } 4318 /*}}}*/ 4302 4319 /*FUNCTION Penta::GradjB {{{1*/ 4303 4320 void Penta::GradjB(Vec gradient){ -
issm/trunk/src/c/objects/Elements/Penta.h
r5772 r5808 80 80 int GetNodeIndex(Node* node); 81 81 void GetSolutionFromInputs(Vec solution); 82 double GetZcoord(GaussPenta* gauss); 82 83 void GetVectorFromInputs(Vec vector,int NameEnum); 83 84 void Gradj(Vec gradient,int control_type); … … 146 147 void GetDofList(int** pdoflist,int approximation_enum,int setenum); 147 148 void GetDofList1(int* doflist); 148 int 149 void 150 void 151 void 149 int GetElementType(void); 150 void GetParameterListOnVertices(double* pvalue,int enumtype); 151 void GetParameterListOnVertices(double* pvalue,int enumtype,double defaultvalue); 152 void GetParameterValue(double* pvalue,Node* node,int enumtype); 152 153 void GetPhi(double* phi, double* epsilon, double viscosity); 153 154 void GetSolutionFromInputsDiagnosticHoriz(Vec solutiong); -
issm/trunk/src/c/objects/Elements/PentaRef.cpp
r5745 r5808 723 723 z3=*(xyz_list+3*2+2); 724 724 725 /*Jdet = norm( AB ^ AC ) / (2 * area of the reference triangle), with areaRef=sqrt(3) */ 725 726 *Jdet=SQRT3/6.0*pow(pow(((y2-y1)*(z3-z1)-(z2-z1)*(y3-y1)),2.0)+pow(((z2-z1)*(x3-x1)-(x2-x1)*(z3-z1)),2.0)+pow(((x2-x1)*(y3-y1)-(y2-y1)*(x3-x1)),2.0),0.5); 726 727 if(*Jdet<0) ISSMERROR("negative jacobian determinant!"); … … 935 936 *(dl1dl6+NUMNODESP1*1+5)=1.0/SQRT3*(1.0+z)/2.0; 936 937 *(dl1dl6+NUMNODESP1*2+5)=0.5*A3; 938 } 939 /*}}}*/ 940 /*FUNCTION PentaRef::GetQuadNodalFunctions {{{1*/ 941 void PentaRef::GetQuadNodalFunctions(double* l1l4,GaussPenta* gauss,int index1,int index2,int index3,int index4){ 942 /*This routine returns the values of the nodal functions at the gaussian point.*/ 943 944 double BasisFunctions[6]; 945 946 GetNodalFunctionsP1(&BasisFunctions[0],gauss); 947 948 ISSMASSERT(index1>=0 && index1<6); 949 ISSMASSERT(index2>=0 && index2<6); 950 ISSMASSERT(index3>=0 && index3<6); 951 ISSMASSERT(index4>=0 && index4<6); 952 953 l1l4[0]=BasisFunctions[index1]; 954 l1l4[1]=BasisFunctions[index2]; 955 l1l4[2]=BasisFunctions[index3]; 956 l1l4[3]=BasisFunctions[index4]; 957 958 } 959 /*}}}*/ 960 /*FUNCTION PentaRef::GetQuadJacobianDeterminant{{{1*/ 961 void PentaRef::GetQuadJacobianDeterminant(double* Jdet,double xyz_list[4][3],GaussPenta* gauss){ 962 /*This routine returns the values of the nodal functions at the gaussian point.*/ 963 964 double x1,x2,x3,x4,y1,y2,y3,y4,z1,z2,z3,z4; 965 966 x1=xyz_list[0][0]; 967 y1=xyz_list[0][1]; 968 z1=xyz_list[0][2]; 969 x2=xyz_list[1][0]; 970 y2=xyz_list[1][1]; 971 z2=xyz_list[1][2]; 972 x3=xyz_list[2][0]; 973 y3=xyz_list[2][1]; 974 z3=xyz_list[2][2]; 975 x4=xyz_list[3][0]; 976 y4=xyz_list[3][1]; 977 z4=xyz_list[3][2]; 978 979 /*Jdet = (Area of the trapezoid)/(Area trapezoid ref) with AreaRef = 4*/ 980 /*Area of a trabezoid = altitude * (base1 + base2)/2 */ 981 *Jdet= pow(pow(x2-x1,2.) + pow(y2-y1,2.),0.5) * (z4-z1 + z3-z2)/8; 982 if(*Jdet<0) ISSMERROR("negative jacobian determinant!"); 983 937 984 } 938 985 /*}}}*/ -
issm/trunk/src/c/objects/Elements/PentaRef.h
r5743 r5808 29 29 void GetNodalFunctionsP1DerivativesReference(double* dl1dl6,GaussPenta* gauss); 30 30 void GetNodalFunctionsMINIDerivativesReference(double* dl1dl7,GaussPenta* gauss); 31 void GetQuadNodalFunctions(double* l1l4,GaussPenta* gauss,int index1,int index2,int index3,int index4); 32 void GetQuadJacobianDeterminant(double* Jdet, double xyz_list[4][3],GaussPenta* gauss); 31 33 void GetJacobian(double* J, double* xyz_list,GaussPenta* gauss); 32 34 void GetJacobianDeterminant(double* Jdet, double* xyz_list,GaussPenta* gauss); -
issm/trunk/src/c/objects/Elements/TriaRef.cpp
r5745 r5808 265 265 } 266 266 /*}}}*/ 267 /*FUNCTION TriaRef::GetSegmentJacobian{{{1*/ 268 void TriaRef::GetSegmentJacobian(double* J, double* xyz_list,GaussTria* gauss){ 269 /*The Jacobian is constant over the element, discard the gaussian points. 270 * J is assumed to have been allocated.*/ 271 267 /*FUNCTION TriaRef::GetSegmentJacobianDeterminant{{{1*/ 268 void TriaRef::GetSegmentJacobianDeterminant(double* Jdet, double* xyz_list,GaussTria* gauss){ 269 /*The Jacobian determinant is constant over the element, discard the gaussian points. 270 * J is assumed to have been allocated*/ 272 271 double x1,y1,x2,y2; 273 272 … … 277 276 y2=*(xyz_list+3*1+1); 278 277 279 *J=1.0/2.0*sqrt(pow(x2-x1,2.) + pow(y2-y1,2.)); 280 } 281 /*}}}*/ 282 /*FUNCTION TriaRef::GetSegmentJacobianDeterminant{{{1*/ 283 void TriaRef::GetSegmentJacobianDeterminant(double* Jdet, double* xyz_list,GaussTria* gauss){ 284 /*The Jacobian determinant is constant over the element, discard the gaussian points. 285 * J is assumed to have been allocated*/ 286 287 GetSegmentJacobian(Jdet,xyz_list,gauss); 278 *Jdet=1.0/2.0*sqrt(pow(x2-x1,2.) + pow(y2-y1,2.)); 288 279 if(*Jdet<0) ISSMERROR("negative jacobian determinant!"); 289 280 -
issm/trunk/src/c/objects/Elements/TriaRef.h
r5743 r5808 31 31 void GetL(double* L, double* xyz_list,GaussTria* gauss,int numdof); 32 32 void GetJacobian(double* J, double* xyz_list,GaussTria* gauss); 33 void GetSegmentJacobian(double* J, double* xyz_list,GaussTria* gauss);34 33 void GetSegmentJacobianDeterminant(double* Jdet, double* xyz_list,GaussTria* gauss); 35 34 void GetJacobianDeterminant2d(double* Jdet, double* xyz_list,GaussTria* gauss); -
issm/trunk/src/c/objects/Gauss/GaussPenta.cpp
r5797 r5808 179 179 180 180 /*Quads: get the gauss points using the product of two line rules */ 181 if(index1==0 && index2==1 && index3== 3 && index4==4){181 if(index1==0 && index2==1 && index3==4 && index4==3){ 182 182 for(i=0;i<order_horiz;i++){ 183 183 for(j=0;j<order_vert;j++){ 184 coords1[i*order_ horiz+j]= 0.5*(1-seg_horiz_coords[i]);185 coords2[i*order_ horiz+j]=1-0.5*(1-seg_horiz_coords[i]);186 coords3[i*order_ horiz+j]=0.0;187 coords4[i*order_ horiz+j]=seg_vert_coords[j];188 weights[i*order_ horiz+j]=seg_horiz_weights[i]*seg_vert_weights[j];184 coords1[i*order_vert+j]= 0.5*(1-seg_horiz_coords[i]); 185 coords2[i*order_vert+j]=1-0.5*(1-seg_horiz_coords[i]); 186 coords3[i*order_vert+j]=0.0; 187 coords4[i*order_vert+j]=seg_vert_coords[j]; 188 weights[i*order_vert+j]=seg_horiz_weights[i]*seg_vert_weights[j]; 189 189 } 190 190 } 191 191 } 192 else if(index1==1 && index2==2 && index3== 4 && index4==5){192 else if(index1==1 && index2==2 && index3==5 && index4==4){ 193 193 for(i=0;i<order_horiz;i++){ 194 194 for(j=0;j<order_vert;j++){ 195 coords1[i*order_ horiz+j]=0.0;196 coords2[i*order_ horiz+j]= 0.5*(1-seg_horiz_coords[i]);197 coords3[i*order_ horiz+j]=1-0.5*(1-seg_horiz_coords[i]);198 coords4[i*order_ horiz+j]=seg_vert_coords[j];199 weights[i*order_ horiz+j]=seg_horiz_weights[i]*seg_vert_weights[j];195 coords1[i*order_vert+j]=0.0; 196 coords2[i*order_vert+j]= 0.5*(1-seg_horiz_coords[i]); 197 coords3[i*order_vert+j]=1-0.5*(1-seg_horiz_coords[i]); 198 coords4[i*order_vert+j]=seg_vert_coords[j]; 199 weights[i*order_vert+j]=seg_horiz_weights[i]*seg_vert_weights[j]; 200 200 } 201 201 } 202 202 } 203 else if(index1==2 && index2==0 && index3== 5 && index4==3){203 else if(index1==2 && index2==0 && index3==3 && index4==5){ 204 204 for(i=0;i<order_horiz;i++){ 205 205 for(j=0;j<order_vert;j++){ 206 coords1[i*order_ horiz+j]=1-0.5*(1-seg_horiz_coords[i]);207 coords2[i*order_ horiz+j]=0.0;208 coords3[i*order_ horiz+j]= 0.5*(1-seg_horiz_coords[i]);209 coords4[i*order_ horiz+j]=seg_vert_coords[j];210 weights[i*order_ horiz+j]=seg_horiz_weights[i]*seg_vert_weights[j];206 coords1[i*order_vert+j]=1-0.5*(1-seg_horiz_coords[i]); 207 coords2[i*order_vert+j]=0.0; 208 coords3[i*order_vert+j]= 0.5*(1-seg_horiz_coords[i]); 209 coords4[i*order_vert+j]=seg_vert_coords[j]; 210 weights[i*order_vert+j]=seg_horiz_weights[i]*seg_vert_weights[j]; 211 211 } 212 212 } … … 216 216 } 217 217 218 /*clean-up*/ 219 xfree((void**)&seg_horiz_coords); 220 xfree((void**)&seg_horiz_weights); 221 xfree((void**)&seg_vert_coords); 222 xfree((void**)&seg_vert_weights); 218 223 } 219 224 /*}}}*/ -
issm/trunk/src/c/objects/Loads/Icefront.cpp
r5772 r5808 457 457 gravity =matpar->GetG(); 458 458 459 Get Normal(&normal[0],xyz_list);459 GetSegmentNormal(&normal[0],xyz_list); 460 460 461 461 index1=tria->GetNodeIndex(nodes[0]); … … 542 542 void Icefront::CreatePVectorDiagnosticPattyn( Vec pg){ 543 543 544 int i,j; 545 546 const int numnodes=NUMVERTICESQUA; 547 const int numdofs=numnodes*NDOF2; 548 int* doflist=NULL; 549 550 double xyz_list[numnodes][3]; 551 double xyz_list_quad[numnodes+1][3]; //center node 552 553 double thickness_list[6]; //from penta element 554 double thickness_list_quad[6]; //selection of 4 thickness from penta elements 555 556 double bed_list[6]; //from penta element 557 double bed_list_quad[6]; //selection of 4 beds from penta elements 558 559 /*Objects: */ 560 double pe_g[numdofs]={0.0}; 561 int element_type; 562 563 /*quad grids: */ 564 int grid1,grid2,grid3,grid4; 565 566 /*normals: */ 567 double normal1[3]; 568 double normal2[3]; 569 double normal3[3]; 570 double normal4[3]; 571 double normal_norm; 572 double v15[3]; 573 double v25[3]; 574 double v35[3]; 575 double v45[3]; 576 577 578 element_type=element->Enum(); 579 580 /*check icefront is associated to a pentaelem: */ 581 if(element_type!=PentaEnum){ 582 ISSMERROR(" quad icefront is associated to a TriaElem!"); 583 } 544 /*Constants*/ 545 const int numdofs = NUMVERTICESQUA *NDOF2; 546 547 /*Intermediaries*/ 548 int i,j,ig,index1,index2,index3,index4; 549 int fill; 550 double surface,pressure,ice_pressure,rho_water,rho_ice,gravity; 551 double water_pressure,air_pressure; 552 double Jdet,z_g; 553 double xyz_list[NUMVERTICESQUA][3]; 554 double normal[3]; 555 double pe_g[numdofs] = {0.0}; 556 double l1l4[4]; 557 int *doflist = NULL; 558 GaussPenta *gauss = NULL; 559 Penta *penta = NULL; 584 560 585 561 /* Get dof list and node coordinates: */ 562 penta=(Penta*)element; 586 563 GetDofList(&doflist,PattynApproximationEnum,GsetEnum); 587 GetVerticesCoordinates(&xyz_list[0][0], nodes, numnodes); 588 589 //Identify which grids are comprised in the quad: 590 grid1=element->GetNodeIndex(nodes[0]); 591 grid2=element->GetNodeIndex(nodes[1]); 592 grid3=element->GetNodeIndex(nodes[2]); 593 grid4=element->GetNodeIndex(nodes[3]); 594 595 /*Build new xyz, bed and thickness lists for grids 1 to 4: */ 596 for(i=0;i<4;i++){ 597 for(j=0;j<3;j++){ 598 xyz_list_quad[i][j]=xyz_list[i][j]; 599 } 600 } 601 602 element->GetParameterListOnVertices(&thickness_list[0],ThicknessEnum); 603 element->GetParameterListOnVertices(&bed_list[0],BedEnum); 604 605 thickness_list_quad[0]=thickness_list[grid1]; 606 thickness_list_quad[1]=thickness_list[grid2]; 607 thickness_list_quad[2]=thickness_list[grid3]; 608 thickness_list_quad[3]=thickness_list[grid4]; 609 610 bed_list_quad[0]=bed_list[grid1]; 611 bed_list_quad[1]=bed_list[grid2]; 612 bed_list_quad[2]=bed_list[grid3]; 613 bed_list_quad[3]=bed_list[grid4]; 614 615 //Create a new grid in the midle of the quad and add it at the end of the list 616 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; 617 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; 618 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; 619 620 //Compute four normals (the quad is divided into four triangles) 621 v15[0]=xyz_list_quad[0][0]-xyz_list_quad[4][0]; 622 v15[1]=xyz_list_quad[0][1]-xyz_list_quad[4][1]; 623 v15[2]=xyz_list_quad[0][2]-xyz_list_quad[4][2]; 624 625 v25[0]=xyz_list_quad[1][0]-xyz_list_quad[4][0]; 626 v25[1]=xyz_list_quad[1][1]-xyz_list_quad[4][1]; 627 v25[2]=xyz_list_quad[1][2]-xyz_list_quad[4][2]; 628 629 v35[0]=xyz_list_quad[2][0]-xyz_list_quad[4][0]; 630 v35[1]=xyz_list_quad[2][1]-xyz_list_quad[4][1]; 631 v35[2]=xyz_list_quad[2][2]-xyz_list_quad[4][2]; 632 633 v45[0]=xyz_list_quad[3][0]-xyz_list_quad[4][0]; 634 v45[1]=xyz_list_quad[3][1]-xyz_list_quad[4][1]; 635 v45[2]=xyz_list_quad[3][2]-xyz_list_quad[4][2]; 636 637 cross(normal1,v15,v25); 638 cross(normal2,v25,v35); 639 cross(normal3,v35,v45); 640 cross(normal4,v45,v15); 641 642 normal_norm=norm(normal1);normal1[0]=normal1[0]/normal_norm;normal1[1]=normal1[1]/normal_norm;normal1[2]=normal1[2]/normal_norm; 643 normal_norm=norm(normal2);normal2[0]=normal2[0]/normal_norm;normal2[1]=normal2[1]/normal_norm;normal2[2]=normal2[2]/normal_norm; 644 normal_norm=norm(normal3);normal3[0]=normal3[0]/normal_norm;normal3[1]=normal3[1]/normal_norm;normal3[2]=normal3[2]/normal_norm; 645 normal_norm=norm(normal4);normal4[0]=normal4[0]/normal_norm;normal4[1]=normal4[1]/normal_norm;normal4[2]=normal4[2]/normal_norm; 646 647 //Compute load contribution for this quad: 648 QuadPressureLoad(pe_g,matpar->GetRhoWater(),matpar->GetRhoIce(),matpar->GetG(),thickness_list_quad,bed_list_quad,normal1,normal2,normal3,normal4,&xyz_list_quad[0][0]); 649 650 /*Plug pe_g into vector: */ 564 GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICESQUA); 565 566 /*Recover inputs and parameters */ 567 Input* surface_input =penta->inputs->GetInput(SurfaceEnum); ISSMASSERT(surface_input); 568 inputs->GetParameterValue(&fill,FillEnum); 569 rho_water=matpar->GetRhoWater(); 570 rho_ice =matpar->GetRhoIce(); 571 gravity =matpar->GetG(); 572 GetQuadNormal(&normal[0],xyz_list); 573 574 /*Identify which nodes are in the quad: */ 575 index1=element->GetNodeIndex(nodes[0]); 576 index2=element->GetNodeIndex(nodes[1]); 577 index3=element->GetNodeIndex(nodes[2]); 578 index4=element->GetNodeIndex(nodes[3]); 579 580 /* Start looping on the number of gaussian points: */ 581 double zmax=xyz_list[0][2]; for(i=1;i<NUMVERTICESQUA;i++) if(xyz_list[i][2]>zmax) zmax=xyz_list[i][2]; 582 double zmin=xyz_list[0][2]; for(i=1;i<NUMVERTICESQUA;i++) if(xyz_list[i][2]<zmin) zmin=xyz_list[i][2]; 583 if(zmax>0 && zmin<0) gauss=new GaussPenta(index1,index2,index3,index4,3,10); //refined in vertical because of the sea level discontinuity 584 else gauss=new GaussPenta(index1,index2,index3,index4,3,3); 585 for(ig=gauss->begin();ig<gauss->end();ig++){ 586 587 gauss->GaussPoint(ig); 588 589 penta->GetQuadNodalFunctions(l1l4,gauss,index1,index2,index3,index4); 590 penta->GetQuadJacobianDeterminant(&Jdet,xyz_list,gauss); 591 z_g=penta->GetZcoord(gauss); 592 surface_input->GetParameterValue(&surface,gauss); 593 594 switch(fill){ 595 case WaterEnum: 596 water_pressure=rho_water*gravity*min(0,z_g);//0 if the gaussian point is above water level 597 break; 598 case AirEnum: 599 water_pressure=0; 600 break; 601 default: 602 ISSMERROR("fill type %s not supported yet",EnumToString(fill)); 603 } 604 ice_pressure=rho_ice*gravity*(surface-z_g); 605 air_pressure=0; 606 pressure = ice_pressure + water_pressure + air_pressure; 607 608 for(i=0;i<NUMVERTICESQUA;i++){ 609 for(j=0;j<NDOF2;j++){ 610 pe_g[i*NDOF2+j]+=Jdet*gauss->weight*pressure*l1l4[i]*normal[j]; 611 } 612 } 613 } 614 651 615 VecSetValues(pg,numdofs,doflist,pe_g,ADD_VALUES); 652 616 653 617 /*Free ressources:*/ 618 delete gauss; 654 619 xfree((void**)&doflist); 655 656 } 657 /*}}}*/ 658 /*FUNCTION Icefront::CreatePVectorDiagnosticStokes {{{1*/ 620 } 621 /*}}}*/ 622 /*FUNCTION Icefront::CreatePVectorDiagnosticStokes{{{1*/ 659 623 void Icefront::CreatePVectorDiagnosticStokes( Vec pg){ 660 624 661 int i,j; 662 663 const int numnodes=4; 664 const int numdofs=numnodes*NDOF4; 665 int* doflist=NULL; 666 667 double xyz_list[numnodes][3]; 668 double xyz_list_quad[numnodes+1][3]; //center node 669 670 double thickness_list[6]; //from penta element 671 double thickness_list_quad[6]; //selection of 4 thickness from penta elements 672 673 double bed_list[6]; //from penta element 674 double bed_list_quad[6]; //selection of 4 beds from penta elements 675 676 /*Objects: */ 677 double pe_g[numdofs]={0.0}; 678 Penta* penta=NULL; 679 680 /*quad grids: */ 681 int grid1,grid2,grid3,grid4; 682 683 /*normals: */ 684 double normal1[3]; 685 double normal2[3]; 686 double normal3[3]; 687 double normal4[3]; 688 double normal_norm; 689 double v15[3]; 690 double v25[3]; 691 double v35[3]; 692 double v45[3]; 693 int approximation; 694 695 /*check icefront is associated to a pentaelem: */ 696 if(element->Enum()!=PentaEnum) ISSMERROR("Only Penta supported yet"); 625 /*Constants*/ 626 const int numdofs = NUMVERTICESQUA *NDOF4; 627 628 /*Intermediaries*/ 629 int i,j,ig,index1,index2,index3,index4; 630 int fill; 631 double pressure,rho_water,gravity; 632 double water_pressure,air_pressure; 633 double Jdet,z_g; 634 double xyz_list[NUMVERTICESQUA][3]; 635 double normal[3]; 636 double pe_g[numdofs] = {0.0}; 637 double l1l4[4]; 638 int *doflist = NULL; 639 GaussPenta *gauss = NULL; 640 Penta *penta = NULL; 641 642 /* Get dof list and node coordinates: */ 697 643 penta=(Penta*)element; 698 699 /*If not Stokes, return*/700 penta->inputs->GetParameterValue(&approximation,ApproximationEnum);701 if(approximation!=StokesApproximationEnum) return;702 703 /* Get dof list and node coordinates: */704 644 GetDofList(&doflist,StokesApproximationEnum,GsetEnum); 705 GetVerticesCoordinates(&xyz_list[0][0], nodes, numnodes); 706 707 //Identify which grids are comprised in the quad: 708 grid1=element->GetNodeIndex(nodes[0]); 709 grid2=element->GetNodeIndex(nodes[1]); 710 grid3=element->GetNodeIndex(nodes[2]); 711 grid4=element->GetNodeIndex(nodes[3]); 712 713 /*Build new xyz, bed and thickness lists for grids 1 to 4: */ 714 for(i=0;i<4;i++){ 715 for(j=0;j<3;j++){ 716 xyz_list_quad[i][j]=xyz_list[i][j]; 717 } 718 } 719 720 element->GetParameterListOnVertices(&thickness_list[0],ThicknessEnum); 721 element->GetParameterListOnVertices(&bed_list[0],BedEnum); 722 723 thickness_list_quad[0]=thickness_list[grid1]; 724 thickness_list_quad[1]=thickness_list[grid2]; 725 thickness_list_quad[2]=thickness_list[grid3]; 726 thickness_list_quad[3]=thickness_list[grid4]; 727 728 bed_list_quad[0]=bed_list[grid1]; 729 bed_list_quad[1]=bed_list[grid2]; 730 bed_list_quad[2]=bed_list[grid3]; 731 bed_list_quad[3]=bed_list[grid4]; 732 733 //Create a new grid in the midle of the quad and add it at the end of the list 734 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; 735 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; 736 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; 737 738 //Compute four normals (the quad is divided into four triangles) 739 v15[0]=xyz_list_quad[0][0]-xyz_list_quad[4][0]; 740 v15[1]=xyz_list_quad[0][1]-xyz_list_quad[4][1]; 741 v15[2]=xyz_list_quad[0][2]-xyz_list_quad[4][2]; 742 743 v25[0]=xyz_list_quad[1][0]-xyz_list_quad[4][0]; 744 v25[1]=xyz_list_quad[1][1]-xyz_list_quad[4][1]; 745 v25[2]=xyz_list_quad[1][2]-xyz_list_quad[4][2]; 746 747 v35[0]=xyz_list_quad[2][0]-xyz_list_quad[4][0]; 748 v35[1]=xyz_list_quad[2][1]-xyz_list_quad[4][1]; 749 v35[2]=xyz_list_quad[2][2]-xyz_list_quad[4][2]; 750 751 v45[0]=xyz_list_quad[3][0]-xyz_list_quad[4][0]; 752 v45[1]=xyz_list_quad[3][1]-xyz_list_quad[4][1]; 753 v45[2]=xyz_list_quad[3][2]-xyz_list_quad[4][2]; 754 755 cross(normal1,v15,v25); 756 cross(normal2,v25,v35); 757 cross(normal3,v35,v45); 758 cross(normal4,v45,v15); 759 760 normal_norm=norm(normal1);normal1[0]=normal1[0]/normal_norm;normal1[1]=normal1[1]/normal_norm;normal1[2]=normal1[2]/normal_norm; 761 normal_norm=norm(normal2);normal2[0]=normal2[0]/normal_norm;normal2[1]=normal2[1]/normal_norm;normal2[2]=normal2[2]/normal_norm; 762 normal_norm=norm(normal3);normal3[0]=normal3[0]/normal_norm;normal3[1]=normal3[1]/normal_norm;normal3[2]=normal3[2]/normal_norm; 763 normal_norm=norm(normal4);normal4[0]=normal4[0]/normal_norm;normal4[1]=normal4[1]/normal_norm;normal4[2]=normal4[2]/normal_norm; 764 765 766 //Compute load contribution for this quad: 767 QuadPressureLoadStokes(pe_g,matpar->GetRhoWater(),matpar->GetRhoIce(),matpar->GetG(),thickness_list_quad,bed_list_quad,normal1,normal2,normal3,normal4,&xyz_list_quad[0][0]); 768 769 /*Plug pe_g into vector: */ 645 GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICESQUA); 646 647 /*Recover inputs and parameters */ 648 inputs->GetParameterValue(&fill,FillEnum); 649 rho_water=matpar->GetRhoWater(); 650 gravity =matpar->GetG(); 651 GetQuadNormal(&normal[0],xyz_list); 652 653 /*Identify which nodes are in the quad: */ 654 index1=element->GetNodeIndex(nodes[0]); 655 index2=element->GetNodeIndex(nodes[1]); 656 index3=element->GetNodeIndex(nodes[2]); 657 index4=element->GetNodeIndex(nodes[3]); 658 659 /* Start looping on the number of gaussian points: */ 660 double zmax=xyz_list[0][2]; for(i=1;i<NUMVERTICESQUA;i++) if(xyz_list[i][2]>zmax) zmax=xyz_list[i][2]; 661 double zmin=xyz_list[0][2]; for(i=1;i<NUMVERTICESQUA;i++) if(xyz_list[i][2]<zmin) zmin=xyz_list[i][2]; 662 if(zmax>0 && zmin<0) gauss=new GaussPenta(index1,index2,index3,index4,3,30); //refined in vertical because of the sea level discontinuity 663 else gauss=new GaussPenta(index1,index2,index3,index4,3,3); 664 for(ig=gauss->begin();ig<gauss->end();ig++){ 665 666 gauss->GaussPoint(ig); 667 668 penta->GetQuadNodalFunctions(l1l4,gauss,index1,index2,index3,index4); 669 penta->GetQuadJacobianDeterminant(&Jdet,xyz_list,gauss); 670 z_g=penta->GetZcoord(gauss); 671 672 switch(fill){ 673 case WaterEnum: 674 water_pressure=rho_water*gravity*min(0,z_g);//0 if the gaussian point is above water level 675 break; 676 case AirEnum: 677 water_pressure=0; 678 break; 679 default: 680 ISSMERROR("fill type %s not supported yet",EnumToString(fill)); 681 } 682 air_pressure=0; 683 pressure = water_pressure + air_pressure; //no ice pressure fore Stokes 684 685 for(i=0;i<NUMVERTICESQUA;i++){ 686 for(j=0;j<NDOF4;j++){ 687 if(j<3) pe_g[i*NDOF4+j]+=Jdet*gauss->weight*pressure*l1l4[i]*normal[j]; 688 else pe_g[i*NDOF4+j]+=0; //pressure term 689 } 690 } 691 } 692 770 693 VecSetValues(pg,numdofs,doflist,pe_g,ADD_VALUES); 771 694 772 695 /*Free ressources:*/ 696 delete gauss; 773 697 xfree((void**)&doflist); 774 775 698 } 776 699 /*}}}*/ … … 949 872 } 950 873 /*}}}*/ 951 /*FUNCTION Icefront::QuadPressureLoad {{{1*/ 952 void Icefront::QuadPressureLoad(double* pe_g,double rho_water,double rho_ice,double gravity, double* thickness_list, double* bed_list, 953 double* normal1,double* normal2,double* normal3,double* normal4,double* xyz_list){ 954 955 956 //The quad is divided into four triangles tria1 tria2 tria3 and tria4 as follows 957 // 958 // grid 4 +-----------------+ grid 3 959 // |\2 1 /| 960 // |1\ tria3 /2| 961 // | \ / | 962 // | \ / | 963 // | \ / | 964 // | \ / | 965 // | \ 3 / | 966 // |tria4 \ / 3 | 967 // | 3 \grid5 | 968 // | / \ | 969 // | / 3 \ tria2| 970 // | / \ | 971 // | / \ | 972 // | / \ | 973 // | / tria1 \ | 974 // |2/1 2\1| 975 // grid1 +-----------------+ grid 2 976 // 977 // 978 979 int i,j; 980 981 double nx[4]; 982 double ny[4]; 983 984 /* gaussian points: */ 985 int ig; 986 GaussTria *gauss=NULL; 987 988 double surface_list[5]; 989 double x[5]; 990 double y[5]; 991 double z[5]; 992 double l12,l14,l15,l23,l25,l34,l35,l45; 993 double cos_theta_triangle1,cos_theta_triangle2,cos_theta_triangle3,cos_theta_triangle4; 994 995 double xyz_tria[12][2]; 996 double l1l2l3_tria[3]; 997 double r_tria,s_tria; 998 double r_quad[4]; 999 double s_quad[4]; 1000 double l1l4_tria[4][4]; 1001 1002 double J[4]; 1003 double z_g[4]; 1004 double ice_pressure_tria[4]; 1005 double air_pressure_tria; 1006 double water_level_above_g_tria; 1007 double water_pressure_tria; 1008 double pressure_tria[4]; 1009 int fill; 1010 1011 1012 /*To use tria functionalities: */ 1013 Tria* tria=NULL; 1014 1015 /*Recover inputs: */ 1016 inputs->GetParameterValue(&fill,FillEnum); 1017 1018 /*Initialize fake tria: */ 1019 tria=new Tria(); 1020 1021 //Build the four normal vectors 1022 nx[0]=normal1[0]; nx[1]=normal2[0]; nx[2]=normal3[0]; nx[3]=normal4[0]; 1023 ny[0]=normal1[1]; ny[1]=normal2[1]; ny[2]=normal3[1]; ny[3]=normal4[1]; 1024 1025 //Recover the surface of the four nodes 1026 for(i=0;i<4;i++){ 1027 surface_list[i]=thickness_list[i]+bed_list[i]; 1028 } 1029 //Add surface sor the fifth point (average of the surfaces) 1030 surface_list[4]=(surface_list[0]+surface_list[1]+surface_list[2]+surface_list[3])/4.0; 1031 1032 //Recover grid coordinates 1033 for(i=0;i<5;i++){ 1034 x[i]=*(xyz_list+3*i+0); 1035 y[i]=*(xyz_list+3*i+1); 1036 z[i]=*(xyz_list+3*i+2); 1037 } 1038 1039 //Build triangles in a 2D plan before using reference elements 1040 l12=pow((x[1]-x[0]),2)+pow((y[1]-y[0]),2)+pow((z[1]-z[0]),2); 1041 l14=pow((x[3]-x[0]),2)+pow((y[3]-y[0]),2)+pow((z[3]-z[0]),2); 1042 l15=pow((x[4]-x[0]),2)+pow((y[4]-y[0]),2)+pow((z[4]-z[0]),2); 1043 l23=pow((x[2]-x[1]),2)+pow((y[2]-y[1]),2)+pow((z[2]-z[1]),2); 1044 l25=pow((x[4]-x[1]),2)+pow((y[4]-y[1]),2)+pow((z[4]-z[1]),2); 1045 l34=pow((x[3]-x[2]),2)+pow((y[3]-y[2]),2)+pow((z[3]-z[2]),2); 1046 l35=pow((x[4]-x[2]),2)+pow((y[4]-y[2]),2)+pow((z[4]-z[2]),2); 1047 l45=pow((x[4]-x[3]),2)+pow((y[4]-y[3]),2)+pow((z[4]-z[3]),2); 1048 1049 cos_theta_triangle1=(l15+l12-l25)/(2*sqrt(l12*l15)); 1050 cos_theta_triangle2=(l25+l23-l35)/(2*sqrt(l23*l25)); 1051 cos_theta_triangle3=(l35+l34-l45)/(2*sqrt(l34*l35)); 1052 cos_theta_triangle4=(l45+l14-l15)/(2*sqrt(l14*l45)); 1053 1054 //First triangle : nodes 1, 2 and 5 1055 xyz_tria[0][0]=0; 1056 xyz_tria[0][1]=0; 1057 xyz_tria[1][0]=sqrt(l12); 1058 xyz_tria[1][1]=0; 1059 xyz_tria[2][0]=cos_theta_triangle1*sqrt(l15); 1060 xyz_tria[2][1]=sqrt(1-pow(cos_theta_triangle1,2))*sqrt(l15); 1061 1062 //Second triangle : nodes 2, 3 and 5 1063 xyz_tria[3][0]=0; 1064 xyz_tria[3][1]=0; 1065 xyz_tria[4][0]=sqrt(l23); 1066 xyz_tria[4][1]=0; 1067 xyz_tria[5][0]=cos_theta_triangle2*sqrt(l25); 1068 xyz_tria[5][1]=sqrt(1-pow(cos_theta_triangle2,2))*sqrt(l25); 1069 1070 //Third triangle : nodes 3, 4 and 5 1071 xyz_tria[6][0]=0; 1072 xyz_tria[6][1]=0; 1073 xyz_tria[7][0]=sqrt(l34); 1074 xyz_tria[7][1]=0; 1075 xyz_tria[8][0]=cos_theta_triangle3*sqrt(l35); 1076 xyz_tria[8][1]=sqrt(1-pow(cos_theta_triangle3,2))*sqrt(l35); 1077 1078 //Fourth triangle : nodes 4, 1 and 5 1079 xyz_tria[9][0]=0; 1080 xyz_tria[9][1]=0; 1081 xyz_tria[10][0]=sqrt(l14); 1082 xyz_tria[10][1]=0; 1083 xyz_tria[11][0]=cos_theta_triangle4*sqrt(l45); 1084 xyz_tria[11][1]=sqrt(1-pow(cos_theta_triangle4,2))*sqrt(l45); 1085 1086 /* Start looping on the number of gaussian points: */ 1087 gauss=new GaussTria(2); 1088 for(ig=gauss->begin();ig<gauss->end();ig++){ 1089 1090 gauss->GaussPoint(ig); 1091 1092 tria->GetNodalFunctions(l1l2l3_tria,gauss); 1093 1094 //Get the coordinates of gauss point for each triangle in penta/quad 1095 r_tria=gauss->coord2-gauss->coord1; 1096 s_tria=-3/sqrt((double)3)*(gauss->coord1+gauss->coord2-2/3); 1097 1098 //Coordinates of gauss points in the reference triangle 1099 r_quad[0]=r_tria; 1100 s_quad[0]=1/sqrt((double)3)*s_tria-2/3; 1101 r_quad[1]=-1/sqrt((double)3)*s_tria+2/3; 1102 s_quad[1]=r_tria; 1103 r_quad[2]=-r_tria; 1104 s_quad[2]=-1/sqrt((double)3)*s_tria+2/3; 1105 r_quad[3]=1/sqrt((double)3)*s_tria-2/3; 1106 s_quad[3]=-r_tria; 1107 1108 //Get the nodal function of the quad for the gauss points of each triangle 1109 for(i=0;i<4;i++){ 1110 l1l4_tria[i][0]=1.0/4.0*( 1111 (r_quad[i]-1.0)*(s_quad[i]-1.0) 1112 ); 1113 1114 l1l4_tria[i][1]=1.0/4.0*( 1115 -(r_quad[i]+1.0)*(s_quad[i]-1.0) 1116 ); 1117 1118 l1l4_tria[i][2]=1.0/4.0*( 1119 (r_quad[i]+1.0)*(s_quad[i]+1.0) 1120 ); 1121 1122 l1l4_tria[i][3]=1.0/4.0*( 1123 -(r_quad[i]-1.0)*(s_quad[i]+1.0) 1124 ); 1125 1126 } //for(i=0;i<4;i++) 1127 1128 1129 //Compute jacobian of each triangle 1130 for (i=0;i<4;i++){ 1131 double complete_list[3][3]; //a third coordinate is needed for the jacobian determinant calculation, here it is zero 1132 for(j=0;j<3;j++){ 1133 complete_list[j][0]=xyz_tria[3*i+j][0]; 1134 complete_list[j][1]=xyz_tria[3*i+j][1]; 1135 complete_list[j][2]=0; 1136 } 1137 tria->GetJacobianDeterminant2d(&J[i],&complete_list[0][0],gauss); 1138 } 1139 1140 //Calculation of the z coordinate for the gaussian point ig for each triangle 1141 z_g[0]=z[0]*l1l2l3_tria[0]+z[1]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2]; 1142 z_g[1]=z[1]*l1l2l3_tria[0]+z[2]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2]; 1143 z_g[2]=z[2]*l1l2l3_tria[0]+z[3]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2]; 1144 z_g[3]=z[3]*l1l2l3_tria[0]+z[0]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2]; 1145 1146 //Loop on the triangles 1147 for(i=0;i<4;i++){ 1148 1149 //Loop on the grids of the quad 1150 //Calculate the ice pressure 1151 for(j=0;j<4;j++){ 1152 ice_pressure_tria[j]=gravity*rho_ice*(surface_list[j]-z_g[i]); 1153 } 1154 air_pressure_tria=0; 1155 1156 //Now deal with water pressure: 1157 if(fill==WaterEnum){ //icefront ends in water 1158 water_level_above_g_tria=min(0,z_g[i]);//0 if the gaussian point is above water level 1159 water_pressure_tria=rho_water*gravity*water_level_above_g_tria; 1160 } 1161 else if(fill==AirEnum){ 1162 water_pressure_tria=0; 1163 } 1164 else{ 1165 ISSMERROR("QuadPressureLoad error message: unknow fill type for icefront boundary condition"); 1166 } 1167 1168 //Add pressure from triangle i 1169 //Loop on the grids of the quad 1170 for(j=0;j<4;j++){ 1171 pressure_tria[j] = ice_pressure_tria[j] + water_pressure_tria + air_pressure_tria; 1172 } 1173 1174 1175 pe_g[0]+= J[i]*gauss->weight* pressure_tria[0]*l1l4_tria[i][0]*nx[i]; 1176 pe_g[1]+= J[i]*gauss->weight* pressure_tria[0]*l1l4_tria[i][0]*ny[i]; 1177 pe_g[2]+= J[i]*gauss->weight* pressure_tria[1]*l1l4_tria[i][1]*nx[i]; 1178 pe_g[3]+= J[i]*gauss->weight* pressure_tria[1]*l1l4_tria[i][1]*ny[i]; 1179 pe_g[4]+= J[i]*gauss->weight* pressure_tria[2]*l1l4_tria[i][2]*nx[i]; 1180 pe_g[5]+= J[i]*gauss->weight* pressure_tria[2]*l1l4_tria[i][2]*ny[i]; 1181 pe_g[6]+= J[i]*gauss->weight* pressure_tria[3]*l1l4_tria[i][3]*nx[i]; 1182 pe_g[7]+= J[i]*gauss->weight* pressure_tria[3]*l1l4_tria[i][3]*ny[i]; 1183 1184 1185 1186 } //for(i=0;i<4;i++) 1187 } 1188 1189 delete tria; 1190 delete gauss; 1191 } 1192 /*}}}*/ 1193 /*FUNCTION Icefront::QuadPressureLoadStokes {{{1*/ 1194 void Icefront::QuadPressureLoadStokes(double* pe_g,double rho_water,double rho_ice,double gravity, double* thickness_list, double* bed_list, 1195 double* normal1,double* normal2,double* normal3,double* normal4,double* xyz_list){ 1196 1197 1198 //The quad is divided into four triangles tria1 tria2 tria3 and tria4 as follows 1199 // 1200 // grid 4 +-----------------+ grid 3 1201 // |\2 1 /| 1202 // |1\ tria3 /2| 1203 // | \ / | 1204 // | \ / | 1205 // | \ / | 1206 // | \ / | 1207 // | \ 3 / | 1208 // |tria4 \ / 3 | 1209 // | 3 \grid5 | 1210 // | / \ | 1211 // | / 3 \ tria2| 1212 // | / \ | 1213 // | / \ | 1214 // | / \ | 1215 // | / tria1 \ | 1216 // |2/1 2\1| 1217 // grid1 +-----------------+ grid 2 1218 // 1219 // 1220 1221 int i,j; 1222 1223 double nx[4]; 1224 double ny[4]; 1225 double nz[4]; 1226 1227 /* gaussian points: */ 1228 int ig; 1229 GaussTria* gauss=NULL; 1230 1231 double surface_list[5]; 1232 double x[5]; 1233 double y[5]; 1234 double z[5]; 1235 double l12,l14,l15,l23,l25,l34,l35,l45; 1236 double cos_theta_triangle1,cos_theta_triangle2,cos_theta_triangle3,cos_theta_triangle4; 1237 1238 double xyz_tria[12][2]; 1239 double l1l2l3_tria[3]; 1240 double r_tria,s_tria; 1241 double r_quad[4]; 1242 double s_quad[4]; 1243 double l1l4_tria[4][4]; 1244 1245 double J[4]; 1246 double z_g[4]; 1247 double air_pressure_tria; 1248 double water_level_above_g_tria; 1249 double water_pressure_tria; 1250 double pressure_tria; 1251 int fill; 1252 1253 /*To use tria functionalities: */ 1254 Tria* tria=NULL; 1255 1256 /*Recover inputs: */ 1257 inputs->GetParameterValue(&fill,FillEnum); 1258 1259 /*Initialize fake tria: */ 1260 tria=new Tria(); 1261 1262 //Build the four normal vectors 1263 nx[0]=normal1[0]; nx[1]=normal2[0]; nx[2]=normal3[0]; nx[3]=normal4[0]; 1264 ny[0]=normal1[1]; ny[1]=normal2[1]; ny[2]=normal3[1]; ny[3]=normal4[1]; 1265 nz[0]=normal1[2]; nz[1]=normal2[2]; nz[2]=normal3[2]; nz[3]=normal4[2]; 1266 1267 //Recover the surface of the four nodes 1268 for(i=0;i<4;i++){ 1269 surface_list[i]=thickness_list[i]+bed_list[i]; 1270 } 1271 //Add surface sor the fifth point (average of the surfaces) 1272 surface_list[4]=(surface_list[0]+surface_list[1]+surface_list[2]+surface_list[3])/4.0; 1273 1274 //Recover grid coordinates 1275 for(i=0;i<5;i++){ 1276 x[i]=*(xyz_list+3*i+0); 1277 y[i]=*(xyz_list+3*i+1); 1278 z[i]=*(xyz_list+3*i+2); 1279 } 1280 1281 //Build triangles in a 2D plan before using reference elements 1282 l12=pow((x[1]-x[0]),2)+pow((y[1]-y[0]),2)+pow((z[1]-z[0]),2); 1283 l14=pow((x[3]-x[0]),2)+pow((y[3]-y[0]),2)+pow((z[3]-z[0]),2); 1284 l15=pow((x[4]-x[0]),2)+pow((y[4]-y[0]),2)+pow((z[4]-z[0]),2); 1285 l23=pow((x[2]-x[1]),2)+pow((y[2]-y[1]),2)+pow((z[2]-z[1]),2); 1286 l25=pow((x[4]-x[1]),2)+pow((y[4]-y[1]),2)+pow((z[4]-z[1]),2); 1287 l34=pow((x[3]-x[2]),2)+pow((y[3]-y[2]),2)+pow((z[3]-z[2]),2); 1288 l35=pow((x[4]-x[2]),2)+pow((y[4]-y[2]),2)+pow((z[4]-z[2]),2); 1289 l45=pow((x[4]-x[3]),2)+pow((y[4]-y[3]),2)+pow((z[4]-z[3]),2); 1290 1291 cos_theta_triangle1=(l15+l12-l25)/(2*sqrt(l12*l15)); 1292 cos_theta_triangle2=(l25+l23-l35)/(2*sqrt(l23*l25)); 1293 cos_theta_triangle3=(l35+l34-l45)/(2*sqrt(l34*l35)); 1294 cos_theta_triangle4=(l45+l14-l15)/(2*sqrt(l14*l45)); 1295 1296 //First triangle : nodes 1, 2 and 5 1297 xyz_tria[0][0]=0; 1298 xyz_tria[0][1]=0; 1299 xyz_tria[1][0]=sqrt(l12); 1300 xyz_tria[1][1]=0; 1301 xyz_tria[2][0]=cos_theta_triangle1*sqrt(l15); 1302 xyz_tria[2][1]=sqrt(1-pow(cos_theta_triangle1,2))*sqrt(l15); 1303 1304 //Second triangle : nodes 2, 3 and 5 1305 xyz_tria[3][0]=0; 1306 xyz_tria[3][1]=0; 1307 xyz_tria[4][0]=sqrt(l23); 1308 xyz_tria[4][1]=0; 1309 xyz_tria[5][0]=cos_theta_triangle2*sqrt(l25); 1310 xyz_tria[5][1]=sqrt(1-pow(cos_theta_triangle2,2))*sqrt(l25); 1311 1312 //Third triangle : nodes 3, 4 and 5 1313 xyz_tria[6][0]=0; 1314 xyz_tria[6][1]=0; 1315 xyz_tria[7][0]=sqrt(l34); 1316 xyz_tria[7][1]=0; 1317 xyz_tria[8][0]=cos_theta_triangle3*sqrt(l35); 1318 xyz_tria[8][1]=sqrt(1-pow(cos_theta_triangle3,2))*sqrt(l35); 1319 1320 //Fourth triangle : nodes 4, 1 and 5 1321 xyz_tria[9][0]=0; 1322 xyz_tria[9][1]=0; 1323 xyz_tria[10][0]=sqrt(l14); 1324 xyz_tria[10][1]=0; 1325 xyz_tria[11][0]=cos_theta_triangle4*sqrt(l45); 1326 xyz_tria[11][1]=sqrt(1-pow(cos_theta_triangle4,2))*sqrt(l45); 1327 1328 /* Start looping on the number of gaussian points: */ 1329 gauss=new GaussTria(2); 1330 for(ig=gauss->begin();ig<gauss->end();ig++){ 1331 1332 gauss->GaussPoint(ig); 1333 1334 tria->GetNodalFunctions(l1l2l3_tria,gauss); 1335 1336 //Get the coordinates of gauss point for each triangle in penta/quad 1337 r_tria=gauss->coord2-gauss->coord1; 1338 s_tria=-3/sqrt((double)3)*(gauss->coord1+gauss->coord2-2/3); 1339 1340 //Coordinates of gauss points in the reference triangle 1341 r_quad[0]=r_tria; 1342 s_quad[0]=1/sqrt((double)3)*s_tria-2/3; 1343 r_quad[1]=-1/sqrt((double)3)*s_tria+2/3; 1344 s_quad[1]=r_tria; 1345 r_quad[2]=-r_tria; 1346 s_quad[2]=-1/sqrt((double)3)*s_tria+2/3; 1347 r_quad[3]=1/sqrt((double)3)*s_tria-2/3; 1348 s_quad[3]=-r_tria; 1349 1350 //Get the nodal function of the quad for the gauss points of each triangle 1351 for(i=0;i<4;i++){ 1352 l1l4_tria[i][0]=1.0/4.0*( 1353 (r_quad[i]-1.0)*(s_quad[i]-1.0) 1354 ); 1355 1356 l1l4_tria[i][1]=1.0/4.0*( 1357 -(r_quad[i]+1.0)*(s_quad[i]-1.0) 1358 ); 1359 1360 l1l4_tria[i][2]=1.0/4.0*( 1361 (r_quad[i]+1.0)*(s_quad[i]+1.0) 1362 ); 1363 1364 l1l4_tria[i][3]=1.0/4.0*( 1365 -(r_quad[i]-1.0)*(s_quad[i]+1.0) 1366 ); 1367 1368 } //for(i=0;i<4;i++) 1369 1370 1371 //Compute jacobian of each triangle 1372 for (i=0;i<4;i++){ 1373 double complete_list[3][3]; //a third coordinate is needed for the jacobian determinant calculation, here it is zero 1374 for(j=0;j<3;j++){ 1375 complete_list[j][0]=xyz_tria[3*i+j][0]; 1376 complete_list[j][1]=xyz_tria[3*i+j][1]; 1377 complete_list[j][2]=0; 1378 } 1379 tria->GetJacobianDeterminant2d(&J[i],&complete_list[0][0],gauss); 1380 } 1381 1382 //Calculation of the z coordinate for the gaussian point ig for each triangle 1383 z_g[0]=z[0]*l1l2l3_tria[0]+z[1]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2]; 1384 z_g[1]=z[1]*l1l2l3_tria[0]+z[2]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2]; 1385 z_g[2]=z[2]*l1l2l3_tria[0]+z[3]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2]; 1386 z_g[3]=z[3]*l1l2l3_tria[0]+z[0]*l1l2l3_tria[1]+z[4]*l1l2l3_tria[2]; 1387 1388 //Loop on the triangles 1389 for(i=0;i<4;i++){ 1390 1391 //Loop on the grids of the quad 1392 //Calculate the ice pressure 1393 air_pressure_tria=0; 1394 1395 //Now deal with water pressure: 1396 if(fill==WaterEnum){ //icefront ends in water 1397 water_level_above_g_tria=min(0,z_g[i]);//0 if the gaussian point is above water level 1398 water_pressure_tria=rho_water*gravity*water_level_above_g_tria; 1399 } 1400 else if(fill==AirEnum){ 1401 water_pressure_tria=0; 1402 } 1403 else{ 1404 ISSMERROR("QuadPressureLoadStokes error message: unknow fill type for icefront boundary condition"); 1405 } 1406 1407 //Add pressure 1408 pressure_tria = water_pressure_tria + air_pressure_tria; 1409 1410 pe_g[0]+= J[i]*gauss->weight* pressure_tria*l1l4_tria[i][0]*nx[i]; 1411 pe_g[1]+= J[i]*gauss->weight* pressure_tria*l1l4_tria[i][0]*ny[i]; 1412 pe_g[2]+= J[i]*gauss->weight* pressure_tria*l1l4_tria[i][0]*nz[i]; 1413 pe_g[3]+= 0; 1414 pe_g[4]+= J[i]*gauss->weight* pressure_tria*l1l4_tria[i][1]*nx[i]; 1415 pe_g[5]+= J[i]*gauss->weight* pressure_tria*l1l4_tria[i][1]*ny[i]; 1416 pe_g[6]+= J[i]*gauss->weight* pressure_tria*l1l4_tria[i][1]*nz[i]; 1417 pe_g[7]+= 0; 1418 pe_g[8]+= J[i]*gauss->weight* pressure_tria*l1l4_tria[i][2]*nx[i]; 1419 pe_g[9]+= J[i]*gauss->weight* pressure_tria*l1l4_tria[i][2]*ny[i]; 1420 pe_g[10]+= J[i]*gauss->weight* pressure_tria*l1l4_tria[i][2]*nz[i]; 1421 pe_g[11]+= 0; 1422 pe_g[12]+= J[i]*gauss->weight* pressure_tria*l1l4_tria[i][3]*nx[i]; 1423 pe_g[13]+= J[i]*gauss->weight* pressure_tria*l1l4_tria[i][3]*ny[i]; 1424 pe_g[14]+= J[i]*gauss->weight* pressure_tria*l1l4_tria[i][3]*nz[i]; 1425 pe_g[15]+= 0; 1426 1427 } //for(i=0;i<4;i++) 1428 } 1429 1430 delete tria; 1431 delete gauss; 1432 } 1433 /*}}}*/ 1434 /*FUNCTION Icefront::GetNormal {{{1*/ 1435 void Icefront:: GetNormal(double* normal,double xyz_list[2][3]){ 874 /*FUNCTION Icefront::GetSegmentNormal {{{1*/ 875 void Icefront:: GetSegmentNormal(double* normal,double xyz_list[4][3]){ 1436 876 1437 877 /*Build unit outward pointing vector*/ … … 1447 887 normal[0]= + vector[1]/norm; 1448 888 normal[1]= - vector[0]/norm; 889 } 890 /*}}}*/ 891 /*FUNCTION Icefront::GetQuadNormal {{{1*/ 892 void Icefront:: GetQuadNormal(double* normal,double xyz_list[4][3]){ 893 894 /*Build unit outward pointing vector*/ 895 double AB[3]; 896 double AC[3]; 897 double norm; 898 899 AB[0]=xyz_list[1][0] - xyz_list[0][0]; 900 AB[1]=xyz_list[1][1] - xyz_list[0][1]; 901 AB[2]=xyz_list[1][2] - xyz_list[0][2]; 902 AC[0]=xyz_list[2][0] - xyz_list[0][0]; 903 AC[1]=xyz_list[2][1] - xyz_list[0][1]; 904 AC[2]=xyz_list[2][2] - xyz_list[0][2]; 905 906 cross(normal,AB,AC); 907 norm=sqrt(pow(normal[0],2.0)+pow(normal[1],2.0)+pow(normal[2],2.0)); 908 909 for(int i=0;i<3;i++) normal[i]=normal[i]/norm; 1449 910 } 1450 911 /*}}}*/ -
issm/trunk/src/c/objects/Loads/Icefront.h
r5772 r5808 85 85 int* GetExternalDofList(int approximation_enum,int setenum); 86 86 int GetNumberOfDofs(int approximation_enum,int setenum); 87 void QuadPressureLoad(double* pe_g,double rho_water,double rho_ice,double gravity, double* thickness_list, double* bed_list, 88 double* normal1,double* normal2,double* normal3,double* normal4,double* xyz_list); 89 void QuadPressureLoadStokes(double* pe_g,double rho_water,double rho_ice,double gravity, double* thickness_list, double* bed_list, 90 double* normal1,double* normal2,double* normal3,double* normal4,double* xyz_list); 91 void GetNormal(double* normal,double xyz_list[2][3]); 87 void GetSegmentNormal(double* normal,double xyz_list[2][3]); 88 void GetQuadNormal(double* normal,double xyz_list[4][3]); 92 89 ElementVector* NewElementVector(int approximation); 93 90 /*}}}*/ -
issm/trunk/src/c/shared/Numerics/GaussPoints.cpp
r5744 r5808 1720 1720 GaussLegendreLinear(pzgaus, pzwgt, nkgaus); 1721 1721 }/*}}}1*/ 1722 /*FUNCTION gaussPenta{{{1*/1723 void gaussPenta( int* pngaus, double** pl1, double** pl2, double** pl3, double** pwgt, double** pzgaus, double** pzwgt, int iord, int nkgaus ) {1724 /*Gauss quadrature points for the pentahedron.*/1725 1726 /* get the gauss points using the product of triangular and line rules */1727 GaussLegendreTria(pngaus, pl1, pl2, pl3, pwgt, iord);1728 GaussLegendreLinear(pzgaus, pzwgt, nkgaus);1729 1730 }/*}}}1*/ -
issm/trunk/src/c/shared/Numerics/GaussPoints.h
r5744 r5808 19 19 void gaussQuad( double** pxgaus, double** pxwgt, double** pegaus, double** pewgt, int nigaus, int njgaus ); 20 20 void gaussHexa( double** pxgaus, double** pxwgt, double** pegaus, double** pewgt, double** pzgaus, double** pzwgt, int nigaus, int njgaus, int nkgaus ); 21 void gaussPenta( int* pngaus, double** pl1, double** pl2, double** pl3, double** pwgt, double** pzgaus, double** pzwgt, int iord, int nkgaus );22 21 23 22 #endif
Note:
See TracChangeset
for help on using the changeset viewer.