Changeset 93
- Timestamp:
- 04/28/09 15:18:46 (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk/src/c/objects/Icefront.cpp
r66 r93 67 67 printf(" matpar_offset: %i\n",matpar_offset); 68 68 printf(" matpar: \n"); 69 if(matpar)matpar->Echo();70 69 71 70 printf(" element_type: %i\n",element_type); … … 73 72 printf(" element_offset: %i\n",eid); 74 73 printf(" element\n"); 75 if(element)element->Echo();76 74 77 75 if (strcmp(type,"segment")==0){ … … 319 317 } 320 318 } 321 322 319 /* Set pe_g to 0: */ 323 320 for(i=0;i<numdofs;i++) pe_g[i]=0.0; … … 327 324 if(element_type==PentaEnum())element_nodes=(Node**)xmalloc(6*sizeof(Node*)); 328 325 element->GetNodes(element_nodes); 329 326 330 327 /*go through first 3 grids (all grids for tria, bed grids for penta) and identify 1st and 2nd grid: */ 331 328 for(i=0;i<3;i++){ … … 341 338 element->GetThicknessList(&thickness_list_element[0]); 342 339 element->GetBedList(&bed_list_element[0]); 343 340 344 341 /*Build thickness_list and bed_list: */ 345 342 thickness_list[0]=thickness_list_element[grid1]; … … 394 391 void Icefront::CreatePVectorDiagnosticHorizQuad( Vec pg,ParameterInputs* inputs, int analysis_type){ 395 392 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 398 548 399 549 #undef __FUNCT__ … … 428 578 } 429 579 } 580 430 581 431 582 /*Assign output pointers:*/ … … 521 672 } 522 673 674 675 #undef __FUNCT__ 676 #define __FUNCT__ "Icefront::QuadPressureLoad" 677 void 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.