Changeset 2711
- Timestamp:
 - 12/09/09 07:37:38 (16 years ago)
 - Location:
 - issm/trunk/src/c/objects
 - Files:
 - 
      
- 2 edited
 
 
Legend:
- Unmodified
 - Added
 - Removed
 
- 
      
issm/trunk/src/c/objects/Penta.cpp
r2671 r2711 16 16 #include "../include/typedefs.h" 17 17 18 /*FUNCTION Penta constructor {{{1*/ 18 19 Penta::Penta(){ 19 20 return; 20 21 } 22 /*}}}*/ 23 /*FUNCTION Penta creation {{{1*/ 21 24 Penta::Penta( int penta_id, int penta_mid, int penta_mparid, int penta_numparid, int penta_node_ids[6], double penta_h[6], double penta_s[6], double penta_b[6], double penta_k[6], int penta_friction_type, 22 double penta_p, double penta_q, int penta_shelf, int penta_onbed, int penta_onsurface, int penta_collapse, double penta_melting[6], double penta_accumulation[6], double penta_geothermalflux[6],23 int penta_thermal_steadystate,bool penta_onwater){24 25 double penta_p, double penta_q, int penta_shelf, int penta_onbed, int penta_onsurface, int penta_collapse, double penta_melting[6], double penta_accumulation[6], double penta_geothermalflux[6], 26 int penta_thermal_steadystate,bool penta_onwater){ 27 25 28 int i; 26 29 … … 61 64 return; 62 65 } 63 66 /*}}}*/ 67 /*FUNCTION Penta destructor {{{1*/ 64 68 Penta::~Penta(){ 65 69 return; 66 70 } 71 /*}}}*/ 72 /*FUNCTION Penta Echo {{{1*/ 67 73 void Penta::Echo(void){ 68 74 … … 82 88 printf(" b=[%g,%g,%g,%g,%g,%g]\n",b[0],b[1],b[2],b[3],b[4],b[5]); 83 89 printf(" k=[%g,%g,%g,%g,%g,%g]\n",k[0],k[1],k[2],k[3],k[4],k[5]); 84 90 85 91 printf(" friction_type: %i\n",friction_type); 86 92 printf(" p: %g\n",p); … … 91 97 printf(" onsurface: %i\n",onsurface); 92 98 printf(" collapse: %i\n",collapse); 93 99 94 100 printf(" melting=[%g,%g,%g,%g,%g,%g]\n",melting[0],melting[1],melting[2],melting[3],melting[4],melting[5]); 95 101 printf(" accumulation=[%g,%g,%g,%g,%g,%g]\n",accumulation[0],accumulation[1],accumulation[2],accumulation[3],accumulation[4],accumulation[5]); … … 98 104 return; 99 105 } 106 /*}}}*/ 107 /*FUNCTION Penta DeepEcho {{{1*/ 100 108 void Penta::DeepEcho(void){ 101 109 … … 115 123 printf(" b=[%i,%i,%i,%i,%i,%i]\n",b[0],b[1],b[2],b[3],b[4],b[5]); 116 124 printf(" k=[%i,%i,%i,%i,%i,%i]\n",k[0],k[1],k[2],k[3],k[4],k[5]); 117 125 118 126 printf(" friction_type: %i\n",friction_type); 119 127 printf(" p: %g\n",p); … … 124 132 printf(" onsurface: %i\n",onsurface); 125 133 printf(" collapse: %i\n",collapse); 126 134 127 135 printf(" melting=[%i,%i,%i,%i,%i,%i]\n",melting[0],melting[1],melting[2],melting[3],melting[4],melting[5]); 128 136 printf(" accumulation=[%i,%i,%i,%i,%i,%i]\n",accumulation[0],accumulation[1],accumulation[2],accumulation[3],accumulation[4],accumulation[5]); … … 131 139 return; 132 140 } 141 /*}}}*/ 142 /*FUNCTION Penta Marshall {{{1*/ 133 143 void Penta::Marshall(char** pmarshalled_dataset){ 134 144 … … 141 151 /*get enum type of Penta: */ 142 152 enum_type=PentaEnum(); 143 153 144 154 /*marshall enum: */ 145 155 memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type); 146 156 147 157 /*marshall Penta data: */ 148 158 memcpy(marshalled_dataset,&id,sizeof(id));marshalled_dataset+=sizeof(id); … … 175 185 memcpy(marshalled_dataset,&geothermalflux,sizeof(geothermalflux));marshalled_dataset+=sizeof(geothermalflux); 176 186 memcpy(marshalled_dataset,&thermal_steadystate,sizeof(thermal_steadystate));marshalled_dataset+=sizeof(thermal_steadystate); 177 187 178 188 *pmarshalled_dataset=marshalled_dataset; 179 189 return; 180 190 } 181 191 /*}}}*/ 192 /*FUNCTION Penta MarshallSize {{{1*/ 182 193 int Penta::MarshallSize(){ 183 194 184 195 return sizeof(id)+ 185 sizeof(mid)+ 186 sizeof(mparid)+ 187 sizeof(node_ids)+ 188 sizeof(nodes)+ 189 sizeof(node_offsets)+ 190 sizeof(matice)+ 191 sizeof(matice_offset)+ 192 sizeof(matpar)+ 193 sizeof(matpar_offset)+ 194 +sizeof(numparid)+ 195 +sizeof(numpar)+ 196 +sizeof(numpar_offset)+ 197 sizeof(h)+ 198 sizeof(s)+ 199 sizeof(b)+ 200 sizeof(k)+ 201 sizeof(friction_type)+ 202 sizeof(p)+ 203 sizeof(q)+ 204 sizeof(shelf)+ 205 sizeof(onbed)+ 206 sizeof(onwater)+ 207 sizeof(onsurface)+ 208 sizeof(collapse)+ 209 sizeof(melting)+ 210 sizeof(accumulation)+ 211 sizeof(geothermalflux)+ 212 sizeof(thermal_steadystate) + 213 sizeof(int); //sizeof(int) for enum type 214 } 215 196 sizeof(mid)+ 197 sizeof(mparid)+ 198 sizeof(node_ids)+ 199 sizeof(nodes)+ 200 sizeof(node_offsets)+ 201 sizeof(matice)+ 202 sizeof(matice_offset)+ 203 sizeof(matpar)+ 204 sizeof(matpar_offset)+ 205 +sizeof(numparid)+ 206 +sizeof(numpar)+ 207 +sizeof(numpar_offset)+ 208 sizeof(h)+ 209 sizeof(s)+ 210 sizeof(b)+ 211 sizeof(k)+ 212 sizeof(friction_type)+ 213 sizeof(p)+ 214 sizeof(q)+ 215 sizeof(shelf)+ 216 sizeof(onbed)+ 217 sizeof(onwater)+ 218 sizeof(onsurface)+ 219 sizeof(collapse)+ 220 sizeof(melting)+ 221 sizeof(accumulation)+ 222 sizeof(geothermalflux)+ 223 sizeof(thermal_steadystate) + 224 sizeof(int); //sizeof(int) for enum type 225 } 226 /*}}}*/ 227 /*FUNCTION Penta GetName {{{1*/ 216 228 char* Penta::GetName(void){ 217 229 return "penta"; 218 230 } 219 231 /*}}}*/ 232 /*FUNCTION Penta Demarshall {{{1*/ 220 233 void Penta::Demarshall(char** pmarshalled_dataset){ 221 234 … … 269 282 return; 270 283 } 284 /*}}}*/ 285 /*FUNCTION Penta Enum {{{1*/ 271 286 int Penta::Enum(void){ 272 287 … … 274 289 275 290 } 276 int Penta::GetId(void){ return id; } 277 291 /*}}}*/ 292 /*FUNCTION Penta GetId {{{1*/ 293 int Penta::GetId(void){ 294 return id; 295 } 296 /*}}}*/ 297 /*FUNCTION Penta MyRank {{{1*/ 278 298 int Penta::MyRank(void){ 279 299 extern int my_rank; 280 300 return my_rank; 281 301 } 282 283 284 #undef __FU NCT__302 /*}}}*/ 303 /*FUNCTION Penta Configure {{{1*/ 304 #undef __FUConfigure NCT__ 285 305 #define __FUNCT__ "Penta::Configure" 286 306 void Penta::Configure(void* ploadsin,void* pnodesin,void* pmaterialsin,void* pparametersin){ 287 307 288 308 int i; 289 309 290 310 DataSet* loadsin=NULL; 291 311 DataSet* nodesin=NULL; … … 301 321 /*Link this element with its nodes, ie find pointers to the nodes in the nodes dataset.: */ 302 322 ResolvePointers((Object**)nodes,node_ids,node_offsets,6,nodesin); 303 323 304 324 /*Same for materials: */ 305 325 ResolvePointers((Object**)&matice,&mid,&matice_offset,1,materialsin); … … 310 330 311 331 } 312 332 /*}}}*/ 333 /*FUNCTION Penta CreateKMatrix {{{1*/ 313 334 #undef __FUNCT__ 314 335 #define __FUNCT__ "Penta::CreateKMatrix" … … 323 344 } 324 345 else if (analysis_type==DiagnosticAnalysisEnum()){ 325 346 326 347 if (sub_analysis_type==HorizAnalysisEnum()){ 327 348 328 349 CreateKMatrixDiagnosticHoriz( Kgg,inputs,analysis_type,sub_analysis_type); 329 350 } 330 351 else if (sub_analysis_type==VertAnalysisEnum()){ 331 352 332 353 CreateKMatrixDiagnosticVert( Kgg,inputs,analysis_type,sub_analysis_type); 333 354 } 334 355 else if (sub_analysis_type==StokesAnalysisEnum()){ 335 356 336 357 CreateKMatrixDiagnosticStokes( Kgg,inputs,analysis_type,sub_analysis_type); 337 358 338 359 } 339 360 else throw ErrorException(__FUNCT__,exprintf("%s%i%s\n","sub_analysis: ",sub_analysis_type," not supported yet")); 340 361 } 341 362 else if (analysis_type==SlopeComputeAnalysisEnum()){ 342 363 343 364 CreateKMatrixSlopeCompute( Kgg,inputs,analysis_type,sub_analysis_type); 344 365 } 345 366 else if (analysis_type==PrognosticAnalysisEnum()){ 346 367 347 368 CreateKMatrixPrognostic( Kgg,inputs,analysis_type,sub_analysis_type); 348 369 } 349 370 else if (analysis_type==ThermalAnalysisEnum()){ 350 371 351 372 CreateKMatrixThermal( Kgg,inputs,analysis_type,sub_analysis_type); 352 373 } 353 374 else if (analysis_type==MeltingAnalysisEnum()){ 354 375 355 376 CreateKMatrixMelting( Kgg,inputs,analysis_type,sub_analysis_type); 356 377 } … … 360 381 361 382 } 362 383 /*}}}*/ 384 /*FUNCTION Penta CreateKMatrixDiagnosticHoriz {{{1*/ 363 385 #undef __FUNCT__ 364 386 #define __FUNCT__ "Penta:CreateKMatrixDiagnosticHoriz" … … 375 397 int doflist[numdof]; 376 398 int numberofdofspernode; 377 378 399 400 379 401 /* 3d gaussian points: */ 380 402 int num_gauss,ig; … … 392 414 int num_area_gauss; 393 415 double gauss_weight; 394 416 395 417 /* 2d gaussian point: */ 396 418 int num_gauss2d; … … 424 446 double Ke_gg_drag_gaussian[numdof][numdof]; //stiffness matrix contribution from drag 425 447 double Jdet; 426 448 427 449 /*slope: */ 428 450 double slope[2]={0.0,0.0}; … … 491 513 } 492 514 493 #ifdef _DEBUGELEMENTS_515 #ifdef _DEBUGELEMENTS_ 494 516 if(my_rank==RANK && id==ELID){ 495 517 printf("El id %i Rank %i PentaElement input list before gaussian loop: \n",ELID,RANK); … … 508 530 printf(" temperature_average [%g %g %g %g %g %g]\n",temperature_average_list[0],temperature_average_list[1],temperature_average_list[2],temperature_average_list[3],temperature_average_list[4],temperature_average_list[5]); 509 531 } 510 #endif532 #endif 511 533 512 534 /*Get gaussian points and weights. Penta is an extrusion of a Tria, we therefore … … 521 543 GaussPenta( &num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights, &fourth_gauss_vert_coord,&vert_gauss_weights,order_area_gauss,num_vert_gauss); 522 544 523 #ifdef _DEBUGGAUSS_545 #ifdef _DEBUGGAUSS_ 524 546 if(my_rank==RANK && id==ELID){ 525 547 printf("El id %i Rank %i PentaElement gauss points\n",ELID,RANK); … … 531 553 } 532 554 } 533 #endif555 #endif 534 556 /* Start looping on the number of gaussian points: */ 535 557 for (ig1=0; ig1<num_area_gauss; ig1++){ 536 558 for (ig2=0; ig2<num_vert_gauss; ig2++){ 537 559 538 560 /*Pick up the gaussian point: */ 539 561 gauss_weight1=*(area_gauss_weights+ig1); 540 562 gauss_weight2=*(vert_gauss_weights+ig2); 541 563 gauss_weight=gauss_weight1*gauss_weight2; 542 543 564 565 544 566 gauss_l1l2l3l4[0]=*(first_gauss_area_coord+ig1); 545 567 gauss_l1l2l3l4[1]=*(second_gauss_area_coord+ig1); … … 551 573 GetStrainRate(&epsilon[0],&vxvy_list[0][0],&xyz_list[0][0],gauss_l1l2l3l4); 552 574 GetStrainRate(&oldepsilon[0],&oldvxvy_list[0][0],&xyz_list[0][0],gauss_l1l2l3l4); 553 575 554 576 /*Get viscosity: */ 555 577 matice->GetViscosity3d(&viscosity, &epsilon[0]); … … 562 584 /* Get Jacobian determinant: */ 563 585 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss_l1l2l3l4); 564 586 565 587 /*Build the D matrix: we plug the gaussian weight, the thickness, the viscosity, and the jacobian determinant 566 588 onto this scalar matrix, so that we win some computational time: */ 567 589 568 590 newviscosity=viscosity+numpar->viscosity_overshoot*(viscosity-oldviscosity); 569 591 D_scalar=newviscosity*gauss_weight*Jdet; … … 571 593 D[i][i]=D_scalar; 572 594 } 573 595 574 596 /* Do the triple product tB*D*Bprime: */ 575 597 TripleMultiply( &B[0][0],5,numdof,1, 576 &D[0][0],5,5,0,577 &Bprime[0][0],5,numdof,0,578 &Ke_gg_gaussian[0][0],0);598 &D[0][0],5,5,0, 599 &Bprime[0][0],5,numdof,0, 600 &Ke_gg_gaussian[0][0],0); 579 601 580 602 /* Add the Ke_gg_gaussian, and optionally Ke_gg_gaussian onto Ke_gg: */ … … 586 608 } //for (ig2=0; ig2<num_vert_gauss; ig2++) 587 609 } //for (ig1=0; ig1<num_area_gauss; ig1++) 588 610 589 611 590 612 /*Add Ke_gg to global matrix Kgg: */ 591 613 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES); 592 614 593 615 //Deal with 2d friction at the bedrock interface 594 616 if((onbed && !shelf)){ … … 605 627 } 606 628 607 cleanup_and_return:629 cleanup_and_return: 608 630 xfree((void**)&first_gauss_area_coord); 609 631 xfree((void**)&second_gauss_area_coord); … … 618 640 619 641 } 620 642 /*}}}*/ 643 /*FUNCTION Penta CreateKMatrixDiagnosticVert {{{1*/ 621 644 #undef __FUNCT__ 622 645 #define __FUNCT__ "Penta:CreateKMatrixDiagnosticVert" … … 668 691 /*recover pointers: */ 669 692 inputs=(ParameterInputs*)vinputs; 670 693 671 694 672 695 /*If this element is on the surface, we have a dynamic boundary condition that applies, as a stiffness … … 701 724 702 725 GaussPenta( &num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights, &fourth_gauss_vert_coord,&vert_gauss_weights,order_area_gauss,num_vert_gauss); 703 #ifdef _ISSM_DEBUG_726 #ifdef _ISSM_DEBUG_ 704 727 for (i=0;i<num_area_gauss;i++){ 705 728 printf("Area Gauss coord %i: %lf %lf %lf Weight: %lf\n",i,*(first_gauss_area_coord+i),*(second_gauss_area_coord+i),*(third_gauss_area_coord+i),*(area_gauss_weights+i)); … … 708 731 printf("Vert Gauss coord %i: %lf Weight: %lf\n",i,*(fourth_gauss_vert_coord+i),*(vert_gauss_weights+i)); 709 732 } 710 #endif711 733 #endif 734 712 735 /* Start looping on the number of gaussian points: */ 713 736 for (ig1=0; ig1<num_area_gauss; ig1++){ 714 737 for (ig2=0; ig2<num_vert_gauss; ig2++){ 715 738 716 739 /*Pick up the gaussian point: */ 717 740 gauss_weight1=*(area_gauss_weights+ig1); 718 741 gauss_weight2=*(vert_gauss_weights+ig2); 719 742 gauss_weight=gauss_weight1*gauss_weight2; 720 743 721 744 gauss_l1l2l3l4[0]=*(first_gauss_area_coord+ig1); 722 745 gauss_l1l2l3l4[1]=*(second_gauss_area_coord+ig1); … … 734 757 /* Do the triple product tB*D*Bprime: */ 735 758 TripleMultiply( &B[0][0],1,numgrids,1, 736 &DL_scalar,1,1,0,737 &Bprime[0][0],1,numgrids,0,738 &Ke_gg_gaussian[0][0],0);759 &DL_scalar,1,1,0, 760 &Bprime[0][0],1,numgrids,0, 761 &Ke_gg_gaussian[0][0],0); 739 762 740 763 /* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */ … … 749 772 /*Add Ke_gg to global matrix Kgg: */ 750 773 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES); 751 752 cleanup_and_return:774 775 cleanup_and_return: 753 776 xfree((void**)&first_gauss_area_coord); 754 777 xfree((void**)&second_gauss_area_coord); … … 758 781 xfree((void**)&vert_gauss_weights); 759 782 } 760 783 /*}}}*/ 784 /*FUNCTION Penta CreateKMatrixDiagnosticStokes {{{1*/ 761 785 #undef __FUNCT__ 762 786 #define __FUNCT__ "Penta:CreateKMatrixDiagnosticStokes" … … 786 810 /*Grid data: */ 787 811 double xyz_list[numgrids][3]; 788 812 789 813 /*parameters: */ 790 814 double xyz_list_tria[numgrids2d][3]; … … 810 834 double DLStokes[14][14]={0.0}; 811 835 double tLDStokes[numdof2d][14]; 812 836 813 837 /* gaussian points: */ 814 838 int num_area_gauss; … … 832 856 double alpha2_list[numgrids2d]; 833 857 double alpha2_gauss; 834 858 835 859 ParameterInputs* inputs=NULL; 836 860 … … 847 871 } 848 872 } 849 873 850 874 /*recovre material parameters: */ 851 875 rho_water=matpar->GetRhoWater(); … … 861 885 862 886 /* Get gaussian points and weights. Penta is an extrusion of a Tria, we therefore 863 get tria gaussian points as well as segment gaussian points. For tria gaussian864 points, order of integration is 2, because we need to integrate the product tB*D*B'865 which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian866 points, same deal, which yields 3 gaussian points.*/887 get tria gaussian points as well as segment gaussian points. For tria gaussian 888 points, order of integration is 2, because we need to integrate the product tB*D*B' 889 which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian 890 points, same deal, which yields 3 gaussian points.*/ 867 891 868 892 area_order=5; … … 888 912 /*Compute strain rate: */ 889 913 GetStrainRateStokes(&epsilon[0],&vxvyvz_list[0][0],&xyz_list[0][0],gauss_coord); 890 914 891 915 /*Get viscosity: */ 892 916 matice->GetViscosity3dStokes(&viscosity,&epsilon[0]); … … 926 950 /*Build alpha2_list used by drag stiffness matrix*/ 927 951 Friction* friction=NewFriction(); 928 952 929 953 /*Initialize all fields: */ 930 954 friction->element_type=(char*)xmalloc((strlen("2d")+1)*sizeof(char)); 931 955 strcpy(friction->element_type,"2d"); 932 956 933 957 friction->gravity=matpar->GetG(); 934 958 friction->rho_ice=matpar->GetRhoIce(); … … 953 977 } 954 978 } 955 979 956 980 xfree((void**)&first_gauss_area_coord); xfree((void**)&second_gauss_area_coord); xfree((void**)&third_gauss_area_coord); xfree((void**)&area_gauss_weights); 957 981 GaussTria (&num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights, 2); … … 964 988 gauss_coord[2]=*(third_gauss_area_coord+igarea); 965 989 gauss_coord[3]=-1; 966 990 967 991 gauss_coord_tria[0]=*(first_gauss_area_coord+igarea); 968 992 gauss_coord_tria[1]=*(second_gauss_area_coord+igarea); 969 993 gauss_coord_tria[2]=*(third_gauss_area_coord+igarea); 970 994 971 995 /*Get the Jacobian determinant */ 972 996 tria->GetJacobianDeterminant3d(&Jdet2d, &xyz_list_tria[0][0], gauss_coord_tria); 973 997 974 998 /*Get L matrix if viscous basal drag present: */ 975 999 GetLStokes(&LStokes[0][0], gauss_coord_tria); 976 1000 GetLprimeStokes(&LprimeStokes[0][0], &xyz_list[0][0], gauss_coord_tria, gauss_coord); 977 1001 978 1002 /*Compute strain rate: */ 979 1003 GetStrainRateStokes(&epsilon[0],&vxvyvz_list[0][0],&xyz_list[0][0],gauss_coord); 980 1004 981 1005 /*Get viscosity at last iteration: */ 982 1006 matice->GetViscosity3dStokes(&viscosity,&epsilon[0]); 983 1007 984 1008 /*Get normal vecyor to the bed */ 985 1009 SurfaceNormal(&surface_normal[0],xyz_list_tria); 986 1010 987 1011 bed_normal[0]=-surface_normal[0]; //Program is for surface, so the normal to the bed is the opposite of the result 988 1012 bed_normal[1]=-surface_normal[1]; … … 1018 1042 } 1019 1043 } //if ( (onbed==1) && (shelf==0)) 1020 1044 1021 1045 /*Reduce the matrix */ 1022 1046 ReduceMatrixStokes(&Ke_reduced[0][0], &Ke_temp[0][0]); … … 1030 1054 /*Add Ke_gg to global matrix Kgg: */ 1031 1055 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)K_terms,ADD_VALUES); 1032 1033 cleanup_and_return:1034 1056 1057 cleanup_and_return: 1058 1035 1059 /*Free ressources:*/ 1036 1060 xfree((void**)&first_gauss_area_coord); … … 1043 1067 return; 1044 1068 } 1045 1069 /*}}}*/ 1070 /*FUNCTION Penta CreatePVector {{{1*/ 1046 1071 #undef __FUNCT__ 1047 1072 #define __FUNCT__ "Penta::CreatePVector" … … 1050 1075 /*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */ 1051 1076 if (analysis_type==ControlAnalysisEnum()){ 1052 1077 1053 1078 CreatePVectorDiagnosticHoriz( pg,inputs,analysis_type,sub_analysis_type); 1054 1079 } 1055 1080 else if (analysis_type==DiagnosticAnalysisEnum()){ 1056 1081 1057 1082 if (sub_analysis_type==HorizAnalysisEnum()){ 1058 1083 … … 1060 1085 } 1061 1086 else if (sub_analysis_type==VertAnalysisEnum()){ 1062 1087 1063 1088 CreatePVectorDiagnosticVert( pg,inputs,analysis_type,sub_analysis_type); 1064 1089 } 1065 1090 else if (sub_analysis_type==StokesAnalysisEnum()){ 1066 1091 1067 1092 CreatePVectorDiagnosticStokes( pg,inputs,analysis_type,sub_analysis_type); 1068 1093 } … … 1070 1095 } 1071 1096 else if (analysis_type==SlopeComputeAnalysisEnum()){ 1072 1097 1073 1098 CreatePVectorSlopeCompute( pg,inputs,analysis_type,sub_analysis_type); 1074 1099 } 1075 1100 else if (analysis_type==PrognosticAnalysisEnum()){ 1076 1101 1077 1102 CreatePVectorPrognostic( pg,inputs,analysis_type,sub_analysis_type); 1078 1103 } 1079 1104 else if (analysis_type==ThermalAnalysisEnum()){ 1080 1105 1081 1106 CreatePVectorThermal( pg,inputs,analysis_type,sub_analysis_type); 1082 1107 } 1083 1108 else if (analysis_type==MeltingAnalysisEnum()){ 1084 1109 1085 1110 CreatePVectorMelting( pg,inputs,analysis_type,sub_analysis_type); 1086 1111 } … … 1090 1115 1091 1116 } 1117 /*}}}*/ 1118 /*FUNCTION Penta UpdateFromInputs {{{1*/ 1092 1119 #undef __FUNCT__ 1093 1120 #define __FUNCT__ "Penta::UpdateFromInputs" … … 1126 1153 } 1127 1154 } 1128 1155 1129 1156 if(inputs->Recover("temperature_average",&temperature_list[0],1,dofs,6,(void**)nodes)){ 1130 1157 if(matice && collapse){ … … 1136 1163 } 1137 1164 } 1138 1165 1139 1166 if(inputs->Recover("B",&B_list[0],1,dofs,6,(void**)nodes)){ 1140 1167 if(matice){ … … 1145 1172 1146 1173 } 1147 1174 /*}}}*/ 1175 /*FUNCTION Penta GetMatPar {{{1*/ 1148 1176 void* Penta::GetMatPar(){ 1149 1177 return matpar; 1150 1178 } 1151 1179 /*}}}*/ 1180 /*FUNCTION Penta GetShelf {{{1*/ 1152 1181 int Penta::GetShelf(){ 1153 1182 return shelf; 1154 1183 } 1155 1156 1184 /*}}}*/ 1185 /*FUNCTION Penta GetNodes {{{1*/ 1157 1186 void Penta::GetNodes(void** vpnodes){ 1158 1187 int i; … … 1163 1192 } 1164 1193 } 1165 1194 /*}}}*/ 1195 /*FUNCTION Penta GetOnBed {{{1*/ 1166 1196 int Penta::GetOnBed(){ 1167 1197 return onbed; 1168 1198 } 1169 1170 void Penta::GetThicknessList(double* thickness_list){ 1199 /*}}}*/ 1200 /*FUNCTION Penta GetThicknessList {{{1*/ 1201 void Penta::GetThicknessList(double* thickness_list){ 1171 1202 1172 1203 int i; 1173 1204 for(i=0;i<6;i++)thickness_list[i]=h[i]; 1174 1205 } 1175 void Penta::GetBedList(double* bed_list){ 1176 1206 /*}}}*/ 1207 /*FUNCTION Penta GetBedList {{{1*/ 1208 void Penta::GetBedList(double* bed_list){ 1209 1177 1210 int i; 1178 1211 for(i=0;i<6;i++)bed_list[i]=b[i]; 1179 1212 1180 1213 } 1181 1214 /*}}}*/ 1215 /*FUNCTION Penta copy {{{1*/ 1182 1216 Object* Penta::copy() { 1183 1217 return new Penta(*this); 1184 1218 } 1185 1219 /*}}}*/ 1220 /*FUNCTION Penta Du {{{1*/ 1186 1221 #undef __FUNCT__ 1187 1222 #define __FUNCT__ "Penta::Du" … … 1193 1228 /*If on water, skip: */ 1194 1229 if(onwater)return; 1195 1230 1196 1231 /*Bail out if this element if: 1197 1232 * -> Non collapsed and not on the surface … … 1210 1245 } 1211 1246 else{ 1212 1247 1213 1248 tria=(Tria*)SpawnTria(3,4,5); //grids 3, 4 and 5 make the new tria (upper face). 1214 1249 tria->Du(du_g,inputs,analysis_type,sub_analysis_type); … … 1217 1252 } 1218 1253 } 1219 1254 /*}}}*/ 1255 /*FUNCTION Penta Gradj {{{1*/ 1220 1256 #undef __FUNCT__ 1221 1257 #define __FUNCT__ "Penta::Gradj" 1222 1258 void Penta::Gradj(Vec grad_g,void* inputs,int analysis_type,int sub_analysis_type,char* control_type){ 1223 1259 1224 1260 /*If on water, skip grad (=0): */ 1225 1261 if(onwater)return; … … 1233 1269 else throw ErrorException(__FUNCT__,exprintf("%s%s","control type not supported yet: ",control_type)); 1234 1270 } 1235 1271 /*}}}*/ 1272 /*FUNCTION Penta GradjDrag {{{1*/ 1236 1273 #undef __FUNCT__ 1237 1274 #define __FUNCT__ "Penta::GradjDrag" 1238 1275 void Penta::GradjDrag(Vec grad_g,void* inputs,int analysis_type,int sub_analysis_type){ 1239 1276 1240 1277 Tria* tria=NULL; 1241 1278 … … 1267 1304 else throw ErrorException(__FUNCT__,exprintf("%s%i%s\n","sub_analysis: ",sub_analysis_type," not supported yet")); 1268 1305 } 1269 1306 /*}}}*/ 1307 /*FUNCTION Penta GradjB {{{1*/ 1270 1308 #undef __FUNCT__ 1271 1309 #define __FUNCT__ "Penta::GradjB" … … 1296 1334 } 1297 1335 } 1298 1336 /*}}}*/ 1337 /*FUNCTION Penta Misfit {{{1*/ 1299 1338 #undef __FUNCT__ 1300 1339 #define __FUNCT__ "Penta::Misfit" 1301 1340 double Penta::Misfit(void* inputs,int analysis_type,int sub_analysis_type){ 1302 1341 1303 1342 double J; 1304 1343 Tria* tria=NULL; 1305 1344 1306 1345 /*If on water, return 0: */ 1307 1346 if(onwater)return 0; … … 1330 1369 } 1331 1370 } 1332 1371 /*}}}*/ 1372 /*FUNCTION Penta SpawnTria {{{1*/ 1333 1373 #undef __FUNCT__ 1334 1374 #define __FUNCT__ "Penta::SpawnTria" … … 1345 1385 double tria_accumulation[3]; 1346 1386 double tria_geothermalflux[3]; 1347 1387 1348 1388 /*configuration: */ 1349 1389 int tria_node_ids[3]; … … 1370 1410 tria_melting[1]=melting[g1]; 1371 1411 tria_melting[2]=melting[g2]; 1372 1412 1373 1413 tria_accumulation[0]=accumulation[g0]; 1374 1414 tria_accumulation[1]=accumulation[g1]; … … 1401 1441 1402 1442 } 1403 1404 1443 /*}}}*/ 1444 /*FUNCTION Penta GetDofList {{{1*/ 1405 1445 void Penta::GetDofList(int* doflist,int* pnumberofdofspernode){ 1406 1446 … … 1408 1448 int doflist_per_node[MAXDOFSPERNODE]; 1409 1449 int numberofdofspernode; 1410 1450 1411 1451 for(i=0;i<6;i++){ 1412 1452 nodes[i]->GetDofList(&doflist_per_node[0],&numberofdofspernode); … … 1420 1460 1421 1461 } 1422 1462 /*}}}*/ 1463 /*FUNCTION Penta GetDofList1 {{{1*/ 1423 1464 void Penta::GetDofList1(int* doflist){ 1424 1465 … … 1429 1470 1430 1471 } 1472 /*}}}*/ 1473 /*FUNCTION Penta GetStrainRate {{{1*/ 1431 1474 #undef __FUNCT__ 1432 1475 #define __FUNCT__ "Penta::GetStrainRate" … … 1442 1485 GetB(&B[0][0], xyz_list, gauss_l1l2l3l4); 1443 1486 1444 #ifdef _ISSM_DEBUG_1487 #ifdef _ISSM_DEBUG_ 1445 1488 printf("B for grid1 : [ %lf %lf \n",B[0][0],B[0][1]); 1446 1489 printf(" [ %lf %lf \n",B[1][0],B[1][1]); … … 1448 1491 printf(" [ %lf %lf ]\n",B[3][0],B[3][1]); 1449 1492 printf(" [ %lf %lf ]\n",B[4][0],B[4][1]); 1450 1493 1451 1494 printf("B for grid2 : [ %lf %lf \n",B[0][2],B[0][3]); 1452 1495 printf(" [ %lf %lf \n",B[1][2],B[1][3]); … … 1454 1497 printf(" [ %lf %lf ]\n",B[3][2],B[3][3]); 1455 1498 printf(" [ %lf %lf ]\n",B[4][2],B[4][3]); 1456 1499 1457 1500 printf("B for grid3 : [ %lf %lf \n", B[0][4],B[0][5]); 1458 1501 printf(" [ %lf %lf \n", B[1][4],B[1][5]); … … 1460 1503 printf(" [ %lf %lf ]\n",B[3][4],B[3][5]); 1461 1504 printf(" [ %lf %lf ]\n",B[4][4],B[4][5]); 1462 1505 1463 1506 printf("B for grid4 : [ %lf %lf \n", B[0][6],B[0][7]); 1464 1507 printf(" [ %lf %lf \n", B[1][6],B[1][7]); … … 1466 1509 printf(" [ %lf %lf ]\n",B[3][6],B[3][7]); 1467 1510 printf(" [ %lf %lf ]\n",B[4][6],B[4][7]); 1468 1511 1469 1512 printf("B for grid5 : [ %lf %lf \n", B[0][8],B[0][9]); 1470 1513 printf(" [ %lf %lf \n", B[1][8],B[1][9]); … … 1479 1522 printf(" [ %lf %lf ]\n",B[4][10],B[4][11]); 1480 1523 1481 #endif1524 #endif 1482 1525 1483 1526 /*Multiply B by velocity, to get strain rate: */ 1484 1527 MatrixMultiply( &B[0][0],5,NDOF2*numgrids,0, 1485 velocity,NDOF2*numgrids,1,0, 1486 epsilon,0); 1487 1488 } 1489 1528 velocity,NDOF2*numgrids,1,0, 1529 epsilon,0); 1530 1531 } 1532 /*}}}*/ 1533 /*FUNCTION Penta GetB {{{1*/ 1490 1534 #undef __FUNCT__ 1491 1535 #define __FUNCT__ "Penta::GetB" … … 1504 1548 * We assume B has been allocated already, of size: 5x(NDOF2*numgrids) 1505 1549 */ 1506 1550 1507 1551 int i; 1508 1552 const int numgrids=6; … … 1515 1559 GetNodalFunctionsDerivativesBasic(&dh1dh2dh3dh4dh5dh6_basic[0][0],xyz_list, gauss_l1l2l3l4); 1516 1560 1517 #ifdef _ISSM_DEBUG_1561 #ifdef _ISSM_DEBUG_ 1518 1562 for (i=0;i<numgrids;i++){ 1519 1563 printf("Node %i dh/dx=%lf dh/dy=%lf dh/dz=%lf\n",i,dh1dh2dh3dh4dh5dh6_basic[0][i],dh1dh2dh3dh4dh5dh6_basic[1][i],dh1dh2dh3dh4dh5dh6_basic[2][i]); 1520 1564 } 1521 #endif1565 #endif 1522 1566 1523 1567 /*Build B: */ … … 1534 1578 *(B+NDOF2*numgrids*3+NDOF2*i)=(float).5*dh1dh2dh3dh4dh5dh6_basic[2][i]; 1535 1579 *(B+NDOF2*numgrids*3+NDOF2*i+1)=0.0; 1536 1580 1537 1581 *(B+NDOF2*numgrids*4+NDOF2*i)=0.0; 1538 1582 *(B+NDOF2*numgrids*4+NDOF2*i+1)=(float).5*dh1dh2dh3dh4dh5dh6_basic[2][i]; … … 1540 1584 1541 1585 } 1542 1543 1586 /*}}}*/ 1587 /*FUNCTION Penta GetBPrime {{{1*/ 1544 1588 #undef __FUNCT__ 1545 1589 #define __FUNCT__ "Penta::GetBPrime" … … 1558 1602 * We assume B has been allocated already, of size: 5x(NDOF2*numgrids) 1559 1603 */ 1560 1604 1561 1605 int i; 1562 1606 const int NDOF3=3; … … 1569 1613 GetNodalFunctionsDerivativesBasic(&dh1dh2dh3dh4dh5dh6_basic[0][0],xyz_list, gauss_l1l2l3l4); 1570 1614 1571 #ifdef _ISSM_DEBUG_1615 #ifdef _ISSM_DEBUG_ 1572 1616 for (i=0;i<numgrids;i++){ 1573 1617 printf("Node %i dh/dx=%lf dh/dy=%lf dh/dz=%lf\n",i,dh1dh2dh3dh4dh5dh6_basic[0][i],dh1dh2dh3dh4dh5dh6_basic[1][i],dh1dh2dh3dh4dh5dh6_basic[2][i]); 1574 1618 } 1575 #endif1619 #endif 1576 1620 1577 1621 /*Build BPrime: */ … … 1588 1632 *(B+NDOF2*numgrids*3+NDOF2*i)=dh1dh2dh3dh4dh5dh6_basic[2][i]; 1589 1633 *(B+NDOF2*numgrids*3+NDOF2*i+1)=0.0; 1590 1634 1591 1635 *(B+NDOF2*numgrids*4+NDOF2*i)=0.0; 1592 1636 *(B+NDOF2*numgrids*4+NDOF2*i+1)=dh1dh2dh3dh4dh5dh6_basic[2][i]; 1593 1637 } 1594 1638 } 1595 1639 /*}}}*/ 1640 /*FUNCTION Penta GetJacobianDeterminant {{{1*/ 1596 1641 #undef __FUNCT__ 1597 1642 #define __FUNCT__ "Penta::GetJacobianDeterminant" … … 1601 1646 * the determinant of it: */ 1602 1647 const int NDOF3=3; 1603 1648 1604 1649 double J[NDOF3][NDOF3]; 1605 1650 … … 1611 1656 } 1612 1657 } 1613 1658 /*}}}*/ 1659 /*FUNCTION Penta GetNodalFunctionsDerivativesBasic {{{1*/ 1614 1660 #undef __FUNCT__ 1615 1661 #define __FUNCT__ "Penta::GetNodalFunctionsDerivativesBasic" 1616 1662 void Penta::GetNodalFunctionsDerivativesBasic(double* dh1dh2dh3dh4dh5dh6_basic,double* xyz_list, double* gauss_l1l2l3l4){ 1617 1663 1618 1664 /*This routine returns the values of the nodal functions derivatives (with respect to the basic coordinate system: */ 1619 1665 1620 1666 1621 1667 int i; 1622 1668 const int NDOF3=3; … … 1646 1692 1647 1693 } 1648 1694 /*}}}*/ 1695 /*FUNCTION Penta GetJacobian {{{1*/ 1649 1696 #undef __FUNCT__ 1650 1697 #define __FUNCT__ "Penta::GetJacobian" … … 1653 1700 const int NDOF3=3; 1654 1701 int i,j; 1655 1702 1656 1703 /*The Jacobian is constant over the element, discard the gaussian points. 1657 1704 * J is assumed to have been allocated of size NDOF2xNDOF2.*/ … … 1663 1710 double y1,y2,y3,y4,y5,y6; 1664 1711 double z1,z2,z3,z4,z5,z6; 1665 1712 1666 1713 double sqrt3=sqrt(3.0); 1667 1714 1668 1715 /*Figure out xi,eta and zi (parametric coordinates), for this gaussian point: */ 1669 1716 A1=gauss_l1l2l3l4[0]; … … 1681 1728 x5=*(xyz_list+3*4+0); 1682 1729 x6=*(xyz_list+3*5+0); 1683 1730 1684 1731 y1=*(xyz_list+3*0+1); 1685 1732 y2=*(xyz_list+3*1+1); … … 1709 1756 *(J+NDOF3*2+2)=sqrt3/12.0*(z1+z2-2*z3-z4-z5+2*z6)*eta+1.0/4.0*(z1-z2-z4+z5)*xi+1.0/4.0*(-z1+z5-z2+z4); 1710 1757 1711 #ifdef _ISSM_DEBUG_1758 #ifdef _ISSM_DEBUG_ 1712 1759 for(i=0;i<3;i++){ 1713 1760 for (j=0;j<3;j++){ … … 1716 1763 printf("\n"); 1717 1764 } 1718 #endif 1719 } 1720 1765 #endif 1766 } 1767 /*}}}*/ 1768 /*FUNCTION Penta GetNodalFunctionsDerivativesParams {{{1*/ 1721 1769 #undef __FUNCT__ 1722 1770 #define __FUNCT__ "Penta::GetNodalFunctionsDerivativesParams" 1723 1771 void Penta::GetNodalFunctionsDerivativesParams(double* dl1dl2dl3dl4dl5dl6,double* gauss_l1l2l3l4){ 1724 1772 1725 1773 /*This routine returns the values of the nodal functions derivatives (with respect to the 1726 1774 * natural coordinate system) at the gaussian point. Those values vary along xi,eta,z */ … … 1729 1777 double A1,A2,A3,z; 1730 1778 double sqrt3=sqrt(3.0); 1731 1779 1732 1780 A1=gauss_l1l2l3l4[0]; //first area coordinate value. In term of xi and eta: A1=(1-xi)/2-eta/(2*sqrt(3)); 1733 1781 A2=gauss_l1l2l3l4[1]; //second area coordinate value In term of xi and eta: A2=(1+xi)/2-eta/(2*sqrt(3)); … … 1766 1814 *(dl1dl2dl3dl4dl5dl6+numgrids*2+5)=1.0/2.0*A3; 1767 1815 } 1768 1816 /*}}}*/ 1817 /*FUNCTION Penta GetJacobianInvert {{{1*/ 1769 1818 #undef __FUNCT__ 1770 1819 #define __FUNCT__ "Penta::GetJacobianInvert" … … 1780 1829 MatrixInverse(Jinv,NDOF3,NDOF3,NULL,0,&Jdet); 1781 1830 } 1782 1783 1784 1831 /*}}}*/ 1832 /*FUNCTION Penta CreatePVectorDiagnosticHoriz {{{1*/ 1785 1833 #undef __FUNCT__ 1786 1834 #define __FUNCT__ "Penta::CreatePVectorDiagnosticHoriz" … … 1796 1844 int doflist[numdof]; 1797 1845 int numberofdofspernode; 1798 1846 1799 1847 /* parameters: */ 1800 1848 double slope[NDOF2]; … … 1874 1922 1875 1923 GaussPenta( &num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights, &fourth_gauss_vert_coord,&vert_gauss_weights,order_area_gauss,num_vert_gauss); 1876 #ifdef _ISSM_DEBUG_1924 #ifdef _ISSM_DEBUG_ 1877 1925 for (i=0;i<num_area_gauss;i++){ 1878 1926 printf("Area Gauss coord %i: %lf %lf %lf Weight: %lf\n",i,*(first_gauss_area_coord+i),*(second_gauss_area_coord+i),*(third_gauss_area_coord+i),*(area_gauss_weights+i)); … … 1881 1929 printf("Vert Gauss coord %i: %lf Weight: %lf\n",i,*(fourth_gauss_vert_coord+i),*(vert_gauss_weights+i)); 1882 1930 } 1883 #endif1884 1931 #endif 1932 1885 1933 /* Start looping on the number of gaussian points: */ 1886 1934 for (ig1=0; ig1<num_area_gauss; ig1++){ 1887 1935 for (ig2=0; ig2<num_vert_gauss; ig2++){ 1888 1936 1889 1937 /*Pick up the gaussian point: */ 1890 1938 gauss_weight1=*(area_gauss_weights+ig1); 1891 1939 gauss_weight2=*(vert_gauss_weights+ig2); 1892 1940 gauss_weight=gauss_weight1*gauss_weight2; 1893 1941 1894 1942 gauss_l1l2l3l4[0]=*(first_gauss_area_coord+ig1); 1895 1943 gauss_l1l2l3l4[1]=*(second_gauss_area_coord+ig1); 1896 1944 gauss_l1l2l3l4[2]=*(third_gauss_area_coord+ig1); 1897 1945 gauss_l1l2l3l4[3]=*(fourth_gauss_vert_coord+ig2); 1898 1946 1899 1947 /*Compute thickness at gaussian point: */ 1900 1948 GetParameterValue(&thickness, &h[0],gauss_l1l2l3l4); … … 1905 1953 /* Get Jacobian determinant: */ 1906 1954 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss_l1l2l3l4); 1907 1908 /*Get nodal functions: */1955 1956 /*Get nodal functions: */ 1909 1957 GetNodalFunctions(l1l2l3l4l5l6, gauss_l1l2l3l4); 1910 1958 … … 1930 1978 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES); 1931 1979 1932 cleanup_and_return:1980 cleanup_and_return: 1933 1981 xfree((void**)&first_gauss_area_coord); 1934 1982 xfree((void**)&second_gauss_area_coord); … … 1939 1987 1940 1988 } 1941 1942 1989 /*}}}*/ 1990 /*FUNCTION Penta GetParameterValue {{{1*/ 1943 1991 #undef __FUNCT__ 1944 1992 #define __FUNCT__ "Penta::GetParameterValue" 1945 1993 void Penta::GetParameterValue(double* pvalue, double* v_list,double* gauss_l1l2l3l4){ 1946 1994 1947 1995 const int numgrids=6; 1948 1996 double l1l2l3l4l5l6[numgrids]; … … 1952 2000 *pvalue=l1l2l3l4l5l6[0]*v_list[0]+l1l2l3l4l5l6[1]*v_list[1]+l1l2l3l4l5l6[2]*v_list[2]+l1l2l3l4l5l6[3]*v_list[3]+l1l2l3l4l5l6[4]*v_list[4]+l1l2l3l4l5l6[5]*v_list[5]; 1953 2001 } 1954 2002 /*}}}*/ 2003 /*FUNCTION Penta GetParameterDerivativeValue {{{1*/ 1955 2004 #undef __FUNCT__ 1956 2005 #define __FUNCT__ "Penta::GetParameterDerivativeValue" 1957 2006 void Penta::GetParameterDerivativeValue(double* p, double* p_list,double* xyz_list, double* gauss_l1l2l3l4){ 1958 2007 1959 2008 /*From grid values of parameter p (p_list[0], p_list[1], p_list[2], p_list[3], p_list[4] and p_list[4]), return parameter derivative value at gaussian point specified by gauss_l1l2l3l4: 1960 2009 * dp/dx=p_list[0]*dh1/dx+p_list[1]*dh2/dx+p_list[2]*dh3/dx+p_list[3]*dh4/dx+p_list[4]*dh5/dx+p_list[5]*dh6/dx; … … 1971 2020 /*Get dh1dh2dh3dh4dh5dh6_basic in basic coordinate system: */ 1972 2021 GetNodalFunctionsDerivativesBasic(&dh1dh2dh3dh4dh5dh6_basic[0][0],xyz_list, gauss_l1l2l3l4); 1973 2022 1974 2023 *(p+0)=p_list[0]*dh1dh2dh3dh4dh5dh6_basic[0][0]+p_list[1]*dh1dh2dh3dh4dh5dh6_basic[0][1]+p_list[2]*dh1dh2dh3dh4dh5dh6_basic[0][2]+p_list[3]*dh1dh2dh3dh4dh5dh6_basic[0][3]+p_list[4]*dh1dh2dh3dh4dh5dh6_basic[0][4]+p_list[5]*dh1dh2dh3dh4dh5dh6_basic[0][5]; 1975 ;2024 ; 1976 2025 *(p+1)=p_list[0]*dh1dh2dh3dh4dh5dh6_basic[1][0]+p_list[1]*dh1dh2dh3dh4dh5dh6_basic[1][1]+p_list[2]*dh1dh2dh3dh4dh5dh6_basic[1][2]+p_list[3]*dh1dh2dh3dh4dh5dh6_basic[1][3]+p_list[4]*dh1dh2dh3dh4dh5dh6_basic[1][4]+p_list[5]*dh1dh2dh3dh4dh5dh6_basic[1][5]; 1977 2026 … … 1979 2028 1980 2029 } 1981 2030 /*}}}*/ 2031 /*FUNCTION Penta GetNodalFunctions {{{1*/ 1982 2032 #undef __FUNCT__ 1983 2033 #define __FUNCT__ "Penta::GetNodalFunctions" 1984 2034 void Penta::GetNodalFunctions(double* l1l2l3l4l5l6, double* gauss_l1l2l3l4){ 1985 2035 1986 2036 /*This routine returns the values of the nodal functions at the gaussian point.*/ 1987 2037 … … 1989 2039 1990 2040 l1l2l3l4l5l6[1]=gauss_l1l2l3l4[1]*(1-gauss_l1l2l3l4[3])/2.0; 1991 2041 1992 2042 l1l2l3l4l5l6[2]=gauss_l1l2l3l4[2]*(1-gauss_l1l2l3l4[3])/2.0; 1993 2043 … … 1995 2045 1996 2046 l1l2l3l4l5l6[4]=gauss_l1l2l3l4[1]*(1+gauss_l1l2l3l4[3])/2.0; 1997 2047 1998 2048 l1l2l3l4l5l6[5]=gauss_l1l2l3l4[2]*(1+gauss_l1l2l3l4[3])/2.0; 1999 2049 2000 2050 } 2001 2051 /*}}}*/ 2052 /*FUNCTION Penta FieldExtrude {{{1*/ 2002 2053 #undef __FUNCT__ 2003 2054 #define __FUNCT__ "Penta::FieldExtrude" 2004 2055 void Penta::FieldExtrude(Vec field,double* field_serial,char* field_name, int iscollapsed){ 2005 2056 2006 2057 /* node data: */ 2007 2058 const int numgrids=6; … … 2044 2095 * inserting the same field value into field, until we reach the surface: */ 2045 2096 for(i=0;i<3;i++){ 2046 2097 2047 2098 node=nodes[i]; //base nodes 2048 2099 2049 2100 /*get field for this base node: */ 2050 2101 fieldel[0]=field_serial[doflist[numberofdofspernode*i+0]]; … … 2096 2147 } 2097 2148 else if ( 2098 (strcmp(field_name,"thickness")==0) ||2099 (strcmp(field_name,"surface")==0) ||2100 (strcmp(field_name,"bed")==0) ||2101 (strcmp(field_name,"slopex")==0) ||2102 (strcmp(field_name,"slopey")==0)2103 ){2149 (strcmp(field_name,"thickness")==0) || 2150 (strcmp(field_name,"surface")==0) || 2151 (strcmp(field_name,"bed")==0) || 2152 (strcmp(field_name,"slopex")==0) || 2153 (strcmp(field_name,"slopey")==0) 2154 ){ 2104 2155 2105 2156 /* node data: */ … … 2108 2159 int nodedofs; 2109 2160 double fieldel; 2110 2161 2111 2162 GetDofList(&doflist[0],&numberofdofspernode); 2112 2163 … … 2115 2166 * inserting the same thickness value into tg, until we reach the surface: */ 2116 2167 for(i=0;i<3;i++){ 2117 2168 2118 2169 node=nodes[i]; //base nodes 2119 2170 2120 2171 /*get velocity for this base node: */ 2121 2172 fieldel=field_serial[doflist[numberofdofspernode*i+0]]; … … 2139 2190 } //if (extrude) 2140 2191 } 2141 2192 /*}}}*/ 2193 /*FUNCTION Penta GetB_vert {{{1*/ 2142 2194 #undef __FUNCT__ 2143 2195 #define __FUNCT__ "Penta:GetB_vert" … … 2146 2198 2147 2199 /* Compute B matrix. B=[dh1/dz dh2/dz dh3/dz dh4/dz dh5/dz dh6/dz]; 2148 where hi is the interpolation function for grid i.*/2200 where hi is the interpolation function for grid i.*/ 2149 2201 2150 2202 int i; … … 2156 2208 GetNodalFunctionsDerivativesBasic(&dh1dh2dh3dh4dh5dh6_basic[0][0],xyz_list, gauss_l1l2l3l4); 2157 2209 2158 #ifdef _ISSM_DEBUG_2210 #ifdef _ISSM_DEBUG_ 2159 2211 for (i=0;i<numgrids;i++){ 2160 2212 printf("Node %i dh/dx=%lf dh/dy=%lf dh/dz=%lf\n",i,dh1dh2dh3dh4dh5dh6_basic[0][i],dh1dh2dh3dh4dh5dh6_basic[1][i],dh1dh2dh3dh4dh5dh6_basic[2][i]); 2161 2213 } 2162 #endif2214 #endif 2163 2215 2164 2216 /*Build B: */ … … 2166 2218 B[i]=dh1dh2dh3dh4dh5dh6_basic[2][i]; 2167 2219 } 2168 2169 } 2170 2171 2220 2221 } 2222 /*}}}*/ 2223 /*FUNCTION Penta GetBPrime_vert {{{1*/ 2172 2224 #undef __FUNCT__ 2173 2225 #define __FUNCT__ "Penta:GetBPrime_vert" … … 2177 2229 2178 2230 int i; 2179 2231 2180 2232 GetNodalFunctions(B, gauss_l1l2l3l4); 2181 2233 2182 2234 } 2183 2235 /*}}}*/ 2236 /*FUNCTION Penta CreatePVectorDiagnosticVert {{{1*/ 2184 2237 #undef __FUNCT__ 2185 2238 #define __FUNCT__ "Penta:CreatePVectorDiagnosticVert" … … 2196 2249 int doflist[numdof]; 2197 2250 int numberofdofspernode; 2198 2251 2199 2252 /* gaussian points: */ 2200 2253 int num_gauss,ig; … … 2259 2312 /* recover input parameters: */ 2260 2313 if(!inputs->Recover("velocity",&vx_list[0],1,dofs1,numgrids,(void**)nodes))throw ErrorException(__FUNCT__," cannot compute vertical velocity without horizontal velocity!"); 2261 inputs->Recover("velocity",&vy_list[0],1,dofs2,numgrids,(void**)nodes);2314 inputs->Recover("velocity",&vy_list[0],1,dofs2,numgrids,(void**)nodes); 2262 2315 2263 2316 /*Get gaussian points and weights :*/ … … 2266 2319 2267 2320 GaussPenta( &num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights, &fourth_gauss_vert_coord,&vert_gauss_weights,order_area_gauss,num_vert_gauss); 2268 #ifdef _ISSM_DEBUG_2321 #ifdef _ISSM_DEBUG_ 2269 2322 for (i=0;i<num_area_gauss;i++){ 2270 2323 printf("Area Gauss coord %i: %lf %lf %lf Weight: %lf\n",i,*(first_gauss_area_coord+i),*(second_gauss_area_coord+i),*(third_gauss_area_coord+i),*(area_gauss_weights+i)); … … 2273 2326 printf("Vert Gauss coord %i: %lf Weight: %lf\n",i,*(fourth_gauss_vert_coord+i),*(vert_gauss_weights+i)); 2274 2327 } 2275 #endif2328 #endif 2276 2329 2277 2330 /* Start looping on the number of gaussian points: */ 2278 2331 for (ig1=0; ig1<num_area_gauss; ig1++){ 2279 2332 for (ig2=0; ig2<num_vert_gauss; ig2++){ 2280 2333 2281 2334 /*Pick up the gaussian point: */ 2282 2335 gauss_weight1=*(area_gauss_weights+ig1); 2283 2336 gauss_weight2=*(vert_gauss_weights+ig2); 2284 2337 gauss_weight=gauss_weight1*gauss_weight2; 2285 2338 2286 2339 gauss_l1l2l3l4[0]=*(first_gauss_area_coord+ig1); 2287 2340 gauss_l1l2l3l4[1]=*(second_gauss_area_coord+ig1); 2288 2341 gauss_l1l2l3l4[2]=*(third_gauss_area_coord+ig1); 2289 2342 gauss_l1l2l3l4[3]=*(fourth_gauss_vert_coord+ig2); 2290 2343 2291 2344 /*Get velocity derivative, with respect to x and y: */ 2292 2345 GetParameterDerivativeValue(&du[0], &vx_list[0],&xyz_list[0][0], gauss_l1l2l3l4); … … 2294 2347 dudx=du[0]; 2295 2348 dvdy=dv[1]; 2296 2349 2297 2350 2298 2351 /* Get Jacobian determinant: */ 2299 2352 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss_l1l2l3l4); 2300 #ifdef _ISSM_DEBUG_2353 #ifdef _ISSM_DEBUG_ 2301 2354 printf("Element id %i Jacobian determinant: %lf\n",GetId(),Jdet); 2302 #endif2303 2304 /*Get nodal functions: */2355 #endif 2356 2357 /*Get nodal functions: */ 2305 2358 GetNodalFunctions(l1l2l3l4l5l6, gauss_l1l2l3l4); 2306 2359 … … 2319 2372 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES); 2320 2373 2321 cleanup_and_return:2374 cleanup_and_return: 2322 2375 xfree((void**)&first_gauss_area_coord); 2323 2376 xfree((void**)&second_gauss_area_coord); … … 2326 2379 xfree((void**)&area_gauss_weights); 2327 2380 xfree((void**)&vert_gauss_weights); 2328 2329 2330 } 2331 2381 } 2382 /*}}}*/ 2383 /*FUNCTION Penta ComputePressure {{{1*/ 2332 2384 #undef __FUNCT__ 2333 2385 #define __FUNCT__ "Penta::ComputePressure" … … 2343 2395 /*If on water, skip: */ 2344 2396 if(onwater)return; 2345 2397 2346 2398 /*Get node data: */ 2347 2399 GetElementNodeData( &xyz_list[0][0], nodes, numgrids); 2348 2400 2349 2401 /*pressure is lithostatic: */ 2350 2402 //md.pressure=md.rho_ice*md.g*(md.surface-md.z); a la matlab … … 2359 2411 pressure[i]=rho_ice*g*(s[i]-xyz_list[i][2]); 2360 2412 } 2361 2413 2362 2414 /*plug local pressure values into global pressure vector: */ 2363 2415 VecSetValues(pg,numgrids,doflist,(const double*)pressure,INSERT_VALUES); 2364 2416 2365 2417 } 2366 2367 2418 /*}}}*/ 2419 /*FUNCTION Penta CreateKMatrixSlopeCompute {{{1*/ 2368 2420 #undef __FUNCT__ 2369 2421 #define __FUNCT__ "Penta::CreateKMatrixSlopeCompute" … … 2376 2428 /*If on water, skip: */ 2377 2429 if(onwater)return; 2378 2430 2379 2431 /*Is this element on the bed? :*/ 2380 2432 if(!onbed)return; … … 2387 2439 2388 2440 } 2389 2441 /*}}}*/ 2442 /*FUNCTION Penta CreatePVectorSlopeCompute {{{1*/ 2390 2443 #undef __FUNCT__ 2391 2444 #define __FUNCT__ "Penta::CreatePVectorSlopeCompute" 2392 2445 2393 2446 void Penta::CreatePVectorSlopeCompute( Vec pg, void* inputs, int analysis_type,int sub_analysis_type){ 2394 2447 2395 2448 /*Collapsed formulation: */ 2396 2449 Tria* tria=NULL; … … 2398 2451 /*If on water, skip: */ 2399 2452 if(onwater)return; 2400 2453 2401 2454 /*Is this element on the bed? :*/ 2402 2455 if(!onbed)return; … … 2408 2461 return; 2409 2462 } 2410 2463 /*}}}*/ 2464 /*FUNCTION Penta CreateKMatrixPrognostic {{{1*/ 2411 2465 #undef __FUNCT__ 2412 2466 #define __FUNCT__ "Penta::CreateKMatrixPrognostic" … … 2419 2473 /*If on water, skip: */ 2420 2474 if(onwater)return; 2421 2475 2422 2476 /*Is this element on the bed? :*/ 2423 2477 if(!onbed)return; … … 2430 2484 2431 2485 } 2432 2486 /*}}}*/ 2487 /*FUNCTION Penta CreatePVectorPrognostic {{{1*/ 2433 2488 #undef __FUNCT__ 2434 2489 #define __FUNCT__ "Penta::CreatePVectorPrognostic" 2435 2490 2436 2491 void Penta::CreatePVectorPrognostic( Vec pg, void* inputs, int analysis_type,int sub_analysis_type){ 2437 2492 2438 2493 /*Collapsed formulation: */ 2439 2494 Tria* tria=NULL; … … 2441 2496 /*If on water, skip: */ 2442 2497 if(onwater)return; 2443 2498 2444 2499 /*Is this element on the bed? :*/ 2445 2500 if(!onbed)return; … … 2451 2506 return; 2452 2507 } 2453 2508 /*}}}*/ 2509 /*FUNCTION Penta ReduceMatrixStokes {{{1*/ 2454 2510 #undef __FUNCT__ 2455 2511 #define __FUNCT__ "ReduceMatrixStokes" 2456 2512 void Penta::ReduceMatrixStokes(double* Ke_reduced, double* Ke_temp){ 2457 2513 2458 2514 int i,j; 2459 2515 … … 2497 2553 } 2498 2554 } 2499 2500 2501 } 2502 2555 } 2556 /*}}}*/ 2557 /*FUNCTION Penta GetMatrixInvert {{{1*/ 2503 2558 #undef __FUNCT__ 2504 2559 #define __FUNCT__ "GetMatrixInvert" … … 2509 2564 double det; 2510 2565 int calculationdof=3; 2511 2566 2512 2567 /*Take the matrix components: */ 2513 2568 a=*(Ke+calculationdof*0+0); … … 2522 2577 2523 2578 det=a*(e*i-f*h)-b*(d*i-f*g)+c*(d*h-e*g); 2524 2579 2525 2580 *(Ke_invert+calculationdof*0+0)=(e*i-f*h)/det; 2526 2581 *(Ke_invert+calculationdof*0+1)=(c*h-b*i)/det; … … 2534 2589 2535 2590 } 2536 2591 /*}}}*/ 2592 /*FUNCTION Penta SurfaceNormal {{{1*/ 2537 2593 #undef __FUNCT__ 2538 2594 #define __FUNCT__ "Penta::SurfaceNormal" 2539 2540 2595 void Penta::SurfaceNormal(double* surface_normal, double xyz_list[3][3]){ 2541 2596 … … 2562 2617 2563 2618 } 2564 2619 /*}}}*/ 2620 /*FUNCTION Penta GetStrainRateStokes {{{1*/ 2565 2621 #undef __FUNCT__ 2566 2622 #define __FUNCT__ "Penta::GetStrainRateStokes" … … 2601 2657 MatrixMultiply( &B_reduced[0][0],6,DOFVELOCITY*numgrids, 0, velocity,DOFVELOCITY*numgrids,1,0,epsilon, 0); 2602 2658 } 2603 2659 /*}}}*/ 2660 /*FUNCTION Penta GetBStokes {{{1*/ 2604 2661 #undef __FUNCT__ 2605 2662 #define __FUNCT__ "Penta::GetBStokes" … … 2609 2666 * For grid i, Bi can be expressed in the basic coordinate system 2610 2667 * by: Bi_basic=[ dh/dx 0 0 0 ] 2611 * [ 0 dh/dy 0 0 ]2612 * [ 0 0 dh/dy 0 ]2613 * [ 1/2*dh/dy 1/2*dh/dx 0 0 ]2614 * [ 1/2*dh/dz 0 1/2*dh/dx 0 ]2615 * [ 0 1/2*dh/dz 1/2*dh/dy 0 ]2616 * [ 0 0 0 h ]2617 * [ dh/dx dh/dy dh/dz 0 ]2618 * where h is the interpolation function for grid i.2619 * Same thing for Bb except the last column that does not exist.2620 */2621 2668 * [ 0 dh/dy 0 0 ] 2669 * [ 0 0 dh/dy 0 ] 2670 * [ 1/2*dh/dy 1/2*dh/dx 0 0 ] 2671 * [ 1/2*dh/dz 0 1/2*dh/dx 0 ] 2672 * [ 0 1/2*dh/dz 1/2*dh/dy 0 ] 2673 * [ 0 0 0 h ] 2674 * [ dh/dx dh/dy dh/dz 0 ] 2675 * where h is the interpolation function for grid i. 2676 * Same thing for Bb except the last column that does not exist. 2677 */ 2678 2622 2679 int i; 2623 2680 const int calculationdof=3; … … 2633 2690 2634 2691 GetNodalFunctions(l1l6, gauss_coord); 2635 2636 #ifdef _ISSM_DEBUG_2692 2693 #ifdef _ISSM_DEBUG_ 2637 2694 for (i=0;i<7;i++){ 2638 2695 printf("Node %i dh/dx=%lf dh/dy=%lf dh/dz=%lf \n",i,dh1dh7_basic[0][i],dh1dh7_basic[1][i],dh1dh7_basic[2][i]); 2639 2696 } 2640 2697 2641 #endif2698 #endif 2642 2699 2643 2700 /*Build B: */ … … 2681 2738 2682 2739 } 2683 2740 /*}}}*/ 2741 /*FUNCTION Penta GetBprimeStokes {{{1*/ 2684 2742 #undef __FUNCT__ 2685 2743 #define __FUNCT__ "Penta::GetBprimeStokes" … … 2687 2745 2688 2746 /* Compute B' matrix. B'=[B1' B2' B3' B4' B5' B6' Bb'] where Bi' is of size 3*NDOF2. 2689 * For grid i, Bi' can be expressed in the basic coordinate system2690 * by:2691 * Bi_basic'=[ dh/dx 0 0 0]2692 * [ 0 dh/dy 0 0]2693 * [ 0 0 dh/dz 0]2694 * [ dh/dy dh/dx 0 0]2695 * [ dh/dz 0 dh/dx 0]2696 * [ 0 dh/dz dh/dy 0]2697 * [ dh/dx dh/dy dh/dz 0]2698 * [ 0 0 0 h]2699 * where h is the interpolation function for grid i.2700 *2701 * Same thing for the bubble fonction except that there is no fourth column2702 */2747 * For grid i, Bi' can be expressed in the basic coordinate system 2748 * by: 2749 * Bi_basic'=[ dh/dx 0 0 0] 2750 * [ 0 dh/dy 0 0] 2751 * [ 0 0 dh/dz 0] 2752 * [ dh/dy dh/dx 0 0] 2753 * [ dh/dz 0 dh/dx 0] 2754 * [ 0 dh/dz dh/dy 0] 2755 * [ dh/dx dh/dy dh/dz 0] 2756 * [ 0 0 0 h] 2757 * where h is the interpolation function for grid i. 2758 * 2759 * Same thing for the bubble fonction except that there is no fourth column 2760 */ 2703 2761 2704 2762 int i; … … 2710 2768 double l1l6[numgrids]; 2711 2769 2712 2713 2770 /*Get dh1dh7 in basic coordinate system: */ 2714 2771 GetNodalFunctionsDerivativesBasicStokes(&dh1dh7_basic[0][0],xyz_list, gauss_coord); 2715 2772 2716 2773 GetNodalFunctions(l1l6, gauss_coord); 2717 2718 #ifdef _ISSM_DEBUG_2774 2775 #ifdef _ISSM_DEBUG_ 2719 2776 for (i=0;i<6;i++){ 2720 2777 printf("Node %i dh/dx=%lf dh/dy=%lf dh/dz=%lf \n",i,dh1dh7_basic[0][i],dh1dh7_basic[1][i]); 2721 2778 } 2722 2779 2723 #endif2780 #endif 2724 2781 2725 2782 /*B_primeuild B_prime: */ … … 2763 2820 2764 2821 } 2822 /*}}}*/ 2823 /*FUNCTION Penta GetLStokes {{{1*/ 2765 2824 #undef __FUNCT__ 2766 2825 #define __FUNCT__ "Penta::GetLStokes" … … 2768 2827 2769 2828 /* 2770 * Compute L matrix. L=[L1 L2 L3] where Li is square and of size numdof.2771 * For grid i, Li can be expressed in the basic coordinate system2772 * by:2773 * Li_basic=[ h 0 0 0]2774 * [ 0 h 0 0]2775 * [ 0 0 h 0]2776 * [ 0 0 h 0]2777 * [ h 0 0 0]2778 * [ 0 h 0 0]2779 * [ h 0 0 0]2780 * [ 0 h 0 0]2781 * [ 0 0 h 0]2782 * [ 0 0 h 0]2783 * [ 0 0 h 0]2784 * [ h 0 0 0]2785 * [ 0 h 0 0]2786 * [ 0 0 h 0]2787 * where h is the interpolation function for grid i.2788 */2829 * Compute L matrix. L=[L1 L2 L3] where Li is square and of size numdof. 2830 * For grid i, Li can be expressed in the basic coordinate system 2831 * by: 2832 * Li_basic=[ h 0 0 0] 2833 * [ 0 h 0 0] 2834 * [ 0 0 h 0] 2835 * [ 0 0 h 0] 2836 * [ h 0 0 0] 2837 * [ 0 h 0 0] 2838 * [ h 0 0 0] 2839 * [ 0 h 0 0] 2840 * [ 0 0 h 0] 2841 * [ 0 0 h 0] 2842 * [ 0 0 h 0] 2843 * [ h 0 0 0] 2844 * [ 0 h 0 0] 2845 * [ 0 0 h 0] 2846 * where h is the interpolation function for grid i. 2847 */ 2789 2848 2790 2849 int i; … … 2799 2858 l1l2l3[1]=gauss_coord_tria[1]; 2800 2859 l1l2l3[2]=gauss_coord_tria[2]; 2801 2802 2803 #ifdef _DELUG_2860 2861 2862 #ifdef _DELUG_ 2804 2863 for (i=0;i<3;i++){ 2805 2864 printf("Node %i h=%lf \n",i,l1l2l3[i]); 2806 2865 } 2807 #endif2866 #endif 2808 2867 2809 2868 /*Build LStokes: */ … … 2865 2924 *(LStokes+num_dof*numgrids2d*13+num_dof*i+2)=l1l2l3[i]; 2866 2925 *(LStokes+num_dof*numgrids2d*13+num_dof*i+3)=0; 2867 2868 } 2869 } 2870 2871 2926 2927 } 2928 } 2929 /*}}}*/ 2930 /*FUNCTION Penta GetLprimeStokes {{{1*/ 2872 2931 #undef __FUNCT__ 2873 2932 #define __FUNCT__ "Penta::GetLprimeStokes" … … 2875 2934 2876 2935 /* 2877 * Compute Lprime matrix. Lprime=[Lp1 Lp2 Lp3] where Lpi is square and of size numdof.2878 * For grid i, Lpi can be expressed in the basic coordinate system2879 * by:2880 * Lpi_basic=[ h 0 0 0]2881 * [ 0 h 0 0]2882 * [ h 0 0 0]2883 * [ 0 h 0 0]2884 * [ 0 0 h 0]2885 * [ 0 0 h 0]2886 * [ 0 0 dh/dz 0]2887 * [ 0 0 dh/dz 0]2888 * [ 0 0 dh/dz 0]2889 * [dh/dz 0 dh/dx 0]2890 * [ 0 dh/dz dh/dy 0]2891 * [ 0 0 0 h]2892 * [ 0 0 0 h]2893 * [ 0 0 0 h]2894 * where h is the interpolation function for grid i.2895 */2936 * Compute Lprime matrix. Lprime=[Lp1 Lp2 Lp3] where Lpi is square and of size numdof. 2937 * For grid i, Lpi can be expressed in the basic coordinate system 2938 * by: 2939 * Lpi_basic=[ h 0 0 0] 2940 * [ 0 h 0 0] 2941 * [ h 0 0 0] 2942 * [ 0 h 0 0] 2943 * [ 0 0 h 0] 2944 * [ 0 0 h 0] 2945 * [ 0 0 dh/dz 0] 2946 * [ 0 0 dh/dz 0] 2947 * [ 0 0 dh/dz 0] 2948 * [dh/dz 0 dh/dx 0] 2949 * [ 0 dh/dz dh/dy 0] 2950 * [ 0 0 0 h] 2951 * [ 0 0 0 h] 2952 * [ 0 0 0 h] 2953 * where h is the interpolation function for grid i. 2954 */ 2896 2955 2897 2956 int i; … … 2907 2966 l1l2l3[1]=gauss_coord_tria[1]; 2908 2967 l1l2l3[2]=gauss_coord_tria[2]; 2909 2968 2910 2969 GetNodalFunctionsDerivativesBasic(&dh1dh6_basic[0][0],xyz_list,gauss_coord); 2911 2970 2912 #ifdef _DELUG_2971 #ifdef _DELUG_ 2913 2972 for (i=0;i<3;i++){ 2914 2973 printf("Node %i h=%lf \n",i,l1l2l3[i]); 2915 2974 } 2916 #endif2975 #endif 2917 2976 2918 2977 /*Build LprimeStokes: */ … … 2974 3033 *(LprimeStokes+num_dof*numgrids2d*13+num_dof*i+2)=0; 2975 3034 *(LprimeStokes+num_dof*numgrids2d*13+num_dof*i+3)=l1l2l3[i]; 2976 2977 } 2978 2979 } 2980 3035 3036 } 3037 } 3038 /*}}}*/ 3039 /*FUNCTION Penta GetNodalFunctionsDerivativesBasicStokes {{{1*/ 2981 3040 #undef __FUNCT__ 2982 3041 #define __FUNCT__ "Penta::GetNodalFunctionsDerivativesBasicStokes" 2983 3042 void Penta::GetNodalFunctionsDerivativesBasicStokes(double* dh1dh7_basic,double* xyz_list, double* gauss_coord){ 2984 3043 2985 3044 /*This routine returns the values of the nodal functions derivatives (with respect to the 2986 3045 * basic coordinate system: */ … … 3013 3072 3014 3073 } 3015 3016 3074 /*}}}*/ 3075 /*FUNCTION Penta GetNodalFunctionsDerivativesParamsStokes {{{1*/ 3017 3076 #undef __FUNCT__ 3018 3077 #define __FUNCT__ "Penta::GetNodalFunctionsDerivativesParamsStokes" 3019 3078 void Penta::GetNodalFunctionsDerivativesParamsStokes(double* dl1dl7,double* gauss_coord){ 3020 3079 3021 3080 /*This routine returns the values of the nodal functions derivatives (with respect to the 3022 3081 * natural coordinate system) at the gaussian point. */ … … 3065 3124 3066 3125 } 3067 3126 /*}}}*/ 3127 /*FUNCTION Penta CreatePVectorDiagnosticStokes {{{1*/ 3068 3128 #undef __FUNCT__ 3069 3129 #define __FUNCT__ "Penta::CreatePVectorDiagnosticStokes" … … 3109 3169 int area_order=5; 3110 3170 int num_vert_gauss=5; 3111 3171 3112 3172 double epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/ 3113 3173 double viscosity; … … 3132 3192 double tBD[27][8]; 3133 3193 double P_terms[numdof]; 3134 3194 3135 3195 ParameterInputs* inputs=NULL; 3136 3196 Tria* tria=NULL; … … 3160 3220 3161 3221 /* Get gaussian points and weights. Penta is an extrusion of a Tria, we therefore 3162 get tria gaussian points as well as segment gaussian points. For tria gaussian3163 points, order of integration is 2, because we need to integrate the product tB*D*B'3164 which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian3165 points, same deal, which yields 3 gaussian points.*/3222 get tria gaussian points as well as segment gaussian points. For tria gaussian 3223 points, order of integration is 2, because we need to integrate the product tB*D*B' 3224 which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian 3225 points, same deal, which yields 3 gaussian points.*/ 3166 3226 3167 3227 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ … … 3183 3243 GetStrainRateStokes(&epsilon[0],&vxvyvz_list[0][0],&xyz_list[0][0],gauss_coord); 3184 3244 matice->GetViscosity3dStokes(&viscosity,&epsilon[0]); 3185 3245 3186 3246 /* Get Jacobian determinant: */ 3187 3247 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss_coord); … … 3203 3263 GetBStokes(&B[0][0],&xyz_list[0][0],gauss_coord); 3204 3264 GetBprimeStokes(&B_prime[0][0],&xyz_list[0][0], gauss_coord); 3205 3265 3206 3266 /*Get bubble part of Bprime */ 3207 3267 for(i=0;i<8;i++){ … … 3242 3302 } 3243 3303 } 3244 3304 3245 3305 xfree((void**)&first_gauss_area_coord); xfree((void**)&second_gauss_area_coord); xfree((void**)&third_gauss_area_coord); xfree((void**)&area_gauss_weights); 3246 3306 GaussTria (&num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights, 2); … … 3253 3313 gauss_coord[2]=*(third_gauss_area_coord+igarea); 3254 3314 gauss_coord[3]=-1; 3255 3315 3256 3316 gauss_coord_tria[0]=*(first_gauss_area_coord+igarea); 3257 3317 gauss_coord_tria[1]=*(second_gauss_area_coord+igarea); … … 3260 3320 /*Get the Jacobian determinant */ 3261 3321 tria->GetJacobianDeterminant3d(&Jdet2d, &xyz_list_tria[0][0], gauss_coord_tria); 3262 3322 3263 3323 /* Get bed at gaussian point */ 3264 3324 GetParameterValue(&bed,&b[0],gauss_coord); … … 3266 3326 /*Get L matrix : */ 3267 3327 tria->GetL(&L[0], &xyz_list[0][0], gauss_coord_tria,1); 3268 3328 3269 3329 /*Get water_pressure at gaussian point */ 3270 3330 water_pressure=gravity*rho_water*bed; … … 3272 3332 /*Get normal vecyor to the bed */ 3273 3333 SurfaceNormal(&surface_normal[0],xyz_list_tria); 3274 3334 3275 3335 bed_normal[0]=-surface_normal[0]; //Program is for surface, so the normal to the bed is the opposite of the result 3276 3336 bed_normal[1]=-surface_normal[1]; … … 3284 3344 } 3285 3345 } //if ( (onbed==1) && (shelf==1)) 3286 3346 3287 3347 /*Reduce the matrix */ 3288 3348 ReduceVectorStokes(&Pe_reduced[0], &Ke_temp[0][0], &Pe_temp[0]); … … 3304 3364 3305 3365 } 3306 3366 /*}}}*/ 3367 /*FUNCTION Penta ReduceVectorStokes {{{1*/ 3307 3368 #undef __FUNCT__ 3308 3369 #define __FUNCT__ "Penta::ReduceVectorStokes" 3309 3370 void Penta::ReduceVectorStokes(double* Pe_reduced, double* Ke_temp, double* Pe_temp){ 3310 3371 3311 3372 int i,j; 3312 3373 … … 3347 3408 } 3348 3409 } 3349 3410 /*}}}*/ 3411 /*FUNCTION Penta GetNodalFunctionsStokes {{{1*/ 3350 3412 #undef __FUNCT__ 3351 3413 #define __FUNCT__ "Penta::GetNodalFunctionsStokes" 3352 3414 void Penta::GetNodalFunctionsStokes(double* l1l7, double* gauss_coord){ 3353 3415 3354 3416 /*This routine returns the values of the nodal functions at the gaussian point.*/ 3355 3417 … … 3376 3438 3377 3439 } 3378 3440 /*}}}*/ 3441 /*FUNCTION Penta CreateKMatrixThermal {{{1*/ 3379 3442 #undef __FUNCT__ 3380 3443 #define __FUNCT__ "Penta::CreateKMatrixThermal" 3381 3444 void Penta::CreateKMatrixThermal(Mat Kgg,void* vinputs,int analysis_type,int sub_analysis_type){ 3382 3445 3383 3446 /* local declarations */ 3384 3447 int i,j; … … 3466 3529 GetElementNodeData( &xyz_list[0][0], nodes, numgrids); 3467 3530 GetDofList(&doflist[0],&numberofdofspernode); 3468 3531 3469 3532 // /*recovre material parameters: */ 3470 3533 rho_water=matpar->GetRhoWater(); … … 3473 3536 heatcapacity=matpar->GetHeatCapacity(); 3474 3537 thermalconductivity=matpar->GetThermalConductivity(); 3475 3538 3476 3539 /*recover extra inputs from users, dt and velocity: */ 3477 3540 found=inputs->Recover("velocity",&vxvyvz_list[0][0],3,dofs,numgrids,(void**)nodes); … … 3488 3551 3489 3552 /* Get gaussian points and weights. Penta is an extrusion of a Tria, we therefore 3490 get tria gaussian points as well as segment gaussian points. For tria gaussian3491 points, order of integration is 2, because we need to integrate the product tB*D*B'3492 which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian3493 points, same deal, which yields 3 gaussian points.: */3494 3553 get tria gaussian points as well as segment gaussian points. For tria gaussian 3554 points, order of integration is 2, because we need to integrate the product tB*D*B' 3555 which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian 3556 points, same deal, which yields 3 gaussian points.: */ 3557 3495 3558 /*Get gaussian points: */ 3496 3559 area_order=2; … … 3601 3664 } 3602 3665 } 3603 3666 3604 3667 /*Add Ke_gaussian to pKe: */ 3605 3668 for(i=0;i<numdof;i++){ … … 3615 3678 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)K_terms,ADD_VALUES); 3616 3679 3617 cleanup_and_return:3680 cleanup_and_return: 3618 3681 xfree((void**)&first_gauss_area_coord); 3619 3682 xfree((void**)&second_gauss_area_coord); … … 3622 3685 xfree((void**)&vert_gauss_weights); 3623 3686 xfree((void**)&vert_gauss_coord); 3624 3687 3625 3688 //Ice/ocean heat exchange flux on ice shelf base 3626 3689 if(onbed && shelf){ … … 3631 3694 } 3632 3695 } 3633 3696 /*}}}*/ 3697 /*FUNCTION Penta GetB_conduct {{{1*/ 3634 3698 #undef __FUNCT__ 3635 3699 #define __FUNCT__ "Penta::GetB_conduct" … … 3646 3710 * We assume B has been allocated already, of size: 3x(DOFPERGRID*numgrids) 3647 3711 */ 3648 3712 3649 3713 int i; 3650 3714 const int calculationdof=3; … … 3665 3729 } 3666 3730 } 3667 3731 /*}}}*/ 3732 /*FUNCTION Penta GetB_artdiff {{{1*/ 3668 3733 #undef __FUNCT__ 3669 3734 #define __FUNCT__ "Penta::GetB_artdiff" … … 3697 3762 } 3698 3763 } 3699 3764 /*}}}*/ 3765 /*FUNCTION Penta GetB_advec {{{1*/ 3700 3766 #undef __FUNCT__ 3701 3767 #define __FUNCT__ "Penta::GetB_advec" … … 3712 3778 * We assume B has been allocated already, of size: 3x(DOFPERGRID*numgrids) 3713 3779 */ 3714 3780 3715 3781 int i; 3716 3782 int calculationdof=3; … … 3731 3797 } 3732 3798 } 3733 3799 /*}}}*/ 3800 /*FUNCTION Penta GetBprime_advec {{{1*/ 3734 3801 #undef __FUNCT__ 3735 3802 #define __FUNCT__ "Penta::GetBprime_advec" … … 3747 3814 * We assume B has been allocated already, of size: 3x(DOFPERGRID*numgrids) 3748 3815 */ 3749 3816 3750 3817 int i; 3751 3818 const int calculationdof=3; … … 3766 3833 } 3767 3834 } 3768 3835 /*}}}*/ 3836 /*FUNCTION Penta CreateKMatrixMelting {{{1*/ 3769 3837 #undef __FUNCT__ 3770 3838 #define __FUNCT__ "Penta::CreateKMatrixMelting" 3771 3839 void Penta::CreateKMatrixMelting(Mat Kgg,void* inputs,int analysis_type,int sub_analysis_type){ 3772 3840 3773 3841 Tria* tria=NULL; 3774 3842 3775 3843 /*If on water, skip: */ 3776 3844 if(onwater)return; … … 3780 3848 } 3781 3849 else{ 3782 3850 3783 3851 tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria. 3784 3852 tria->CreateKMatrixMelting(Kgg,inputs, analysis_type,sub_analysis_type); … … 3787 3855 } 3788 3856 } 3789 3857 /*}}}*/ 3858 /*FUNCTION Penta CreatePVectorThermal {{{1*/ 3790 3859 #undef __FUNCT__ 3791 3860 #define __FUNCT__ "Penta::CreatePVectorThermal" … … 3805 3874 /*Grid data: */ 3806 3875 double xyz_list[numgrids][3]; 3807 3876 3808 3877 /* gaussian points: */ 3809 3878 int num_area_gauss,igarea,igvert; … … 3818 3887 int area_order=2; 3819 3888 int num_vert_gauss=3; 3820 3889 3821 3890 double dt; 3822 3891 double vx_list[numgrids]; … … 3834 3903 /* element parameters: */ 3835 3904 int friction_type; 3836 3905 3837 3906 int dofs[3]={0,1,2}; 3838 3907 int dofs1[1]={0}; … … 3872 3941 GetElementNodeData( &xyz_list[0][0], nodes, numgrids); 3873 3942 GetDofList(&doflist[0],&numberofdofspernode); 3874 3943 3875 3944 /*recovre material parameters: */ 3876 3945 rho_water=matpar->GetRhoWater(); … … 3891 3960 if(!found)throw ErrorException(__FUNCT__," could not find temperature in inputs!"); 3892 3961 } 3893 3962 3894 3963 for(i=0;i<numgrids;i++){ 3895 3964 vx_list[i]=vxvyvz_list[i][0]; … … 3899 3968 3900 3969 /* Get gaussian points and weights. Penta is an extrusion of a Tria, we therefore 3901 get tria gaussian points as well as segment gaussian points. For tria gaussian3902 points, order of integration is 2, because we need to integrate the product tB*D*B'3903 which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian3904 points, same deal, which yields 3 gaussian points.: */3905 3970 get tria gaussian points as well as segment gaussian points. For tria gaussian 3971 points, order of integration is 2, because we need to integrate the product tB*D*B' 3972 which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian 3973 points, same deal, which yields 3 gaussian points.: */ 3974 3906 3975 /*Get gaussian points: */ 3907 3976 GaussPenta( &num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights,&vert_gauss_coord, &vert_gauss_weights, area_order, num_vert_gauss); … … 3918 3987 gauss_coord[2]=*(third_gauss_area_coord+igarea); 3919 3988 gauss_coord[3]=*(vert_gauss_coord+igvert); 3920 3989 3921 3990 /*Compute strain rate and viscosity: */ 3922 3991 GetStrainRateStokes(&epsilon[0],&vxvyvz_list[0][0],&xyz_list[0][0],gauss_coord); … … 3973 4042 extern int my_rank; 3974 4043 3975 cleanup_and_return:4044 cleanup_and_return: 3976 4045 xfree((void**)&first_gauss_area_coord); 3977 4046 xfree((void**)&second_gauss_area_coord); … … 3982 4051 3983 4052 } 3984 4053 /*}}}*/ 4054 /*FUNCTION Penta CreatePVectorMelting {{{1*/ 3985 4055 #undef __FUNCT__ 3986 4056 #define __FUNCT__ "Penta::CreatePVectorMelting" … … 3988 4058 return; 3989 4059 } 3990 4060 /*}}}*/ 4061 /*FUNCTION Penta GetPhi {{{1*/ 3991 4062 #undef __FUNCT__ 3992 4063 #define __FUNCT__ "Penta::GetPhi" … … 4023 4094 *phi=2*pow(epsilon_eff,2.0)*viscosity; 4024 4095 } 4025 4026 4096 /*}}}*/ 4097 /*FUNCTION Penta MassFlux {{{1*/ 4027 4098 #undef __FUNCT__ 4028 4099 #define __FUNCT__ "Penta::MassFlux" … … 4030 4101 throw ErrorException(__FUNCT__," not supported yet!"); 4031 4102 } 4103 /*}}}*/  - 
      
issm/trunk/src/c/objects/Tria.cpp
r2705 r2711 1973 1973 *(J+NDOF2*1+1)=sqrt3/6.0*(2*y3-y1-y2); 1974 1974 } 1975 1975 /*}}}*/ 1976 /*FUNCTION GetMatPar {{{1*/ 1976 1977 void* Tria::GetMatPar(){ 1977 1978 return matpar; 1978 1979 } 1979 1980 /*}}}*/ 1981 /*FUNCTION GetShelf {{{1*/ 1980 1982 int Tria::GetShelf(){ 1981 1983 return shelf; 1982 1984 } 1983 1984 1985 /*}}}*/ 1986 /*FUNCTION GetNodes {{{1*/ 1985 1987 void Tria::GetNodes(void** vpnodes){ 1986 1988 int i; … … 1991 1993 } 1992 1994 } 1993 1994 1995 /*}}}*/ 1996 /*FUNCTION GetOnBed {{{1*/ 1995 1997 int Tria::GetOnBed(){ 1996 1998 return onbed; 1997 1999 } 1998 1999 void Tria::GetThicknessList(double* thickness_list){ 2000 /*}}}*/ 2001 /*FUNCTION GetThicknessList {{{1*/ 2002 void Tria::GetThicknessList(double* thickness_list){ 2000 2003 2001 2004 int i; 2002 2005 for(i=0;i<3;i++)thickness_list[i]=h[i]; 2003 2006 } 2004 void Tria::GetBedList(double* bed_list){ 2007 /*}}}*/ 2008 /*FUNCTION GetBedList {{{1*/ 2009 void Tria::GetBedList(double* bed_list){ 2005 2010 2006 2011 int i; … … 2008 2013 2009 2014 } 2010 2011 2015 /*}}}*/ 2016 /*FUNCTION copy {{{1*/ 2012 2017 Object* Tria::copy() { 2013 2018  
  Note:
 See   TracChangeset
 for help on using the changeset viewer.
  ![(please configure the [header_logo] section in trac.ini)](/trac/issm/chrome/common/trac_banner.png)