Changeset 2711
- Timestamp:
- 12/09/09 07:37:38 (15 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 23 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 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 532 #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 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 555 #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 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 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 711 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 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 864 865 866 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 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 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 1524 #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 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 1565 #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 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 1619 #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 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 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 1884 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 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 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 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 2214 #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 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 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 2328 #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 2353 #ifdef _ISSM_DEBUG_ 2301 2354 printf("Element id %i Jacobian determinant: %lf\n",GetId(),Jdet); 2302 2303 2304 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 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 2612 2613 2614 2615 2616 2617 2618 2619 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 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 2698 #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 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 2780 #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 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 2866 #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 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 2975 #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 3163 3164 3165 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 3491 3492 3493 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 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 3902 3903 3904 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 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.