Changeset 511
- Timestamp:
- 05/20/09 07:46:55 (16 years ago)
- Location:
- issm/trunk/src/c/objects
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk/src/c/objects/Penta.cpp
r503 r511 4 4 5 5 #ifdef HAVE_CONFIG_H 6 6 #include "config.h" 7 7 #else 8 8 #error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!" … … 20 20 } 21 21 Penta::Penta( int penta_id, int penta_mid, int penta_mparid, 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 22 double penta_p, double penta_q, int penta_shelf, int penta_onbed, int penta_onsurface, double penta_meanvel,double penta_epsvel, 23 int penta_collapse, double penta_melting[6], double penta_accumulation[6], double penta_geothermalflux[6], 24 int penta_artdiff, int penta_thermal_steadystate,double penta_viscosity_overshoot,double penta_stokesreconditioning){ 25 26 26 int i; 27 27 … … 83 83 printf(" b=[%i,%i,%i,%i,%i,%i]\n",b[0],b[1],b[2],b[3],b[4],b[5]); 84 84 printf(" k=[%i,%i,%i,%i,%i,%i]\n",k[0],k[1],k[2],k[3],k[4],k[5]); 85 85 86 86 printf(" friction_type: %i\n",friction_type); 87 87 printf(" p: %g\n",p); … … 93 93 printf(" epsvel: %g\n",epsvel); 94 94 printf(" collapse: %i\n",collapse); 95 95 96 96 printf(" melting=[%i,%i,%i,%i,%i,%i]\n",melting[0],melting[1],melting[2],melting[3],melting[4],melting[5]); 97 97 printf(" accumulation=[%i,%i,%i,%i,%i,%i]\n",accumulation[0],accumulation[1],accumulation[2],accumulation[3],accumulation[4],accumulation[5]); … … 114 114 /*get enum type of Penta: */ 115 115 enum_type=PentaEnum(); 116 116 117 117 /*marshall enum: */ 118 118 memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type); 119 119 120 120 /*marshall Penta data: */ 121 121 memcpy(marshalled_dataset,&id,sizeof(id));marshalled_dataset+=sizeof(id); … … 149 149 memcpy(marshalled_dataset,&viscosity_overshoot,sizeof(viscosity_overshoot));marshalled_dataset+=sizeof(viscosity_overshoot); 150 150 memcpy(marshalled_dataset,&stokesreconditioning,sizeof(stokesreconditioning));marshalled_dataset+=sizeof(stokesreconditioning); 151 151 152 152 *pmarshalled_dataset=marshalled_dataset; 153 153 return; 154 154 } 155 155 156 156 int Penta::MarshallSize(){ 157 157 158 158 return sizeof(id)+ 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 159 sizeof(mid)+ 160 sizeof(mparid)+ 161 sizeof(node_ids)+ 162 sizeof(nodes)+ 163 sizeof(node_offsets)+ 164 sizeof(matice)+ 165 sizeof(matice_offset)+ 166 sizeof(matpar)+ 167 sizeof(matpar_offset)+ 168 sizeof(h)+ 169 sizeof(s)+ 170 sizeof(b)+ 171 sizeof(k)+ 172 sizeof(friction_type)+ 173 sizeof(p)+ 174 sizeof(q)+ 175 sizeof(shelf)+ 176 sizeof(onbed)+ 177 sizeof(onsurface)+ 178 sizeof(meanvel)+ 179 sizeof(epsvel)+ 180 sizeof(collapse)+ 181 sizeof(melting)+ 182 sizeof(accumulation)+ 183 sizeof(geothermalflux)+ 184 sizeof(artdiff)+ 185 sizeof(thermal_steadystate) + 186 sizeof(viscosity_overshoot) + 187 sizeof(stokesreconditioning) + 188 sizeof(int); //sizeof(int) for enum type 189 189 } 190 190 … … 262 262 263 263 int i; 264 264 265 265 DataSet* loadsin=NULL; 266 266 DataSet* nodesin=NULL; … … 274 274 /*Link this element with its nodes, ie find pointers to the nodes in the nodes dataset.: */ 275 275 ResolvePointers((Object**)nodes,node_ids,node_offsets,6,nodesin); 276 276 277 277 /*Same for materials: */ 278 278 ResolvePointers((Object**)&matice,&mid,&matice_offset,1,materialsin); … … 293 293 } 294 294 else if (analysis_type==DiagnosticAnalysisEnum()){ 295 295 296 296 if (sub_analysis_type==HorizAnalysisEnum()){ 297 297 298 298 CreateKMatrixDiagnosticHoriz( Kgg,inputs,analysis_type,sub_analysis_type); 299 299 } 300 300 else if (sub_analysis_type==VertAnalysisEnum()){ 301 301 302 302 CreateKMatrixDiagnosticVert( Kgg,inputs,analysis_type,sub_analysis_type); 303 303 } 304 304 else if (sub_analysis_type==StokesAnalysisEnum()){ 305 305 306 306 CreateKMatrixDiagnosticStokes( Kgg,inputs,analysis_type,sub_analysis_type); 307 307 308 308 } 309 309 else throw ErrorException(__FUNCT__,exprintf("%s%i%s\n","sub_analysis: ",sub_analysis_type," not supported yet")); 310 310 } 311 311 else if (analysis_type==SlopeComputeAnalysisEnum()){ 312 312 313 313 CreateKMatrixSlopeCompute( Kgg,inputs,analysis_type,sub_analysis_type); 314 314 } 315 315 else if (analysis_type==ThermalAnalysisEnum()){ 316 316 317 317 CreateKMatrixThermal( Kgg,inputs,analysis_type,sub_analysis_type); 318 318 } 319 319 else if (analysis_type==MeltingAnalysisEnum()){ 320 320 321 321 CreateKMatrixMelting( Kgg,inputs,analysis_type,sub_analysis_type); 322 322 } … … 342 342 int doflist[numdof]; 343 343 int numberofdofspernode; 344 345 344 345 346 346 /* 3d gaussian points: */ 347 347 int num_gauss,ig; … … 359 359 int num_area_gauss; 360 360 double gauss_weight; 361 361 362 362 /* 2d gaussian point: */ 363 363 int num_gauss2d; … … 391 391 double Ke_gg_drag_gaussian[numdof][numdof]; //stiffness matrix contribution from drag 392 392 double Jdet; 393 393 394 394 /*slope: */ 395 395 double slope[2]={0.0,0.0}; … … 454 454 } 455 455 456 456 #ifdef _DEBUGELEMENTS_ 457 457 if(my_rank==RANK && id==ELID){ 458 458 printf("El id %i Rank %i PentaElement input list before gaussian loop: \n",ELID,RANK); … … 471 471 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]); 472 472 } 473 473 #endif 474 474 475 475 /*Get gaussian points and weights. Penta is an extrusion of a Tria, we therefore … … 484 484 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); 485 485 486 486 #ifdef _DEBUGGAUSS_ 487 487 if(my_rank==RANK && id==ELID){ 488 488 printf("El id %i Rank %i PentaElement gauss points\n",ELID,RANK); … … 494 494 } 495 495 } 496 496 #endif 497 497 /* Start looping on the number of gaussian points: */ 498 498 for (ig1=0; ig1<num_area_gauss; ig1++){ 499 499 for (ig2=0; ig2<num_vert_gauss; ig2++){ 500 500 501 501 /*Pick up the gaussian point: */ 502 502 gauss_weight1=*(area_gauss_weights+ig1); 503 503 gauss_weight2=*(vert_gauss_weights+ig2); 504 504 gauss_weight=gauss_weight1*gauss_weight2; 505 506 505 506 507 507 gauss_l1l2l3l4[0]=*(first_gauss_area_coord+ig1); 508 508 gauss_l1l2l3l4[1]=*(second_gauss_area_coord+ig1); … … 514 514 GetStrainRate(&epsilon[0],&vxvy_list[0][0],&xyz_list[0][0],gauss_l1l2l3l4); 515 515 GetStrainRate(&oldepsilon[0],&oldvxvy_list[0][0],&xyz_list[0][0],gauss_l1l2l3l4); 516 516 517 517 /*Get viscosity: */ 518 518 matice->GetViscosity3d(&viscosity, &epsilon[0]); … … 525 525 /* Get Jacobian determinant: */ 526 526 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss_l1l2l3l4); 527 527 528 528 /*Build the D matrix: we plug the gaussian weight, the thickness, the viscosity, and the jacobian determinant 529 529 onto this scalar matrix, so that we win some computational time: */ 530 530 531 531 newviscosity=viscosity+viscosity_overshoot*(viscosity-oldviscosity); 532 532 D_scalar=newviscosity*gauss_weight*Jdet; … … 534 534 D[i][i]=D_scalar; 535 535 } 536 536 537 537 /* Do the triple product tB*D*Bprime: */ 538 538 TripleMultiply( &B[0][0],5,numdof,1, 539 &D[0][0],5,5,0,540 &Bprime[0][0],5,numdof,0,541 &Ke_gg_gaussian[0][0],0);539 &D[0][0],5,5,0, 540 &Bprime[0][0],5,numdof,0, 541 &Ke_gg_gaussian[0][0],0); 542 542 543 543 /* Add the Ke_gg_gaussian, and optionally Ke_gg_gaussian onto Ke_gg: */ … … 549 549 } //for (ig2=0; ig2<num_vert_gauss; ig2++) 550 550 } //for (ig1=0; ig1<num_area_gauss; ig1++) 551 551 552 552 553 553 /*Add Ke_gg to global matrix Kgg: */ 554 554 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES); 555 555 556 556 //Deal with 2d friction at the bedrock interface 557 557 if((onbed && !shelf)){ … … 567 567 568 568 } 569 570 569 570 cleanup_and_return: 571 571 xfree((void**)&first_gauss_area_coord); 572 572 xfree((void**)&second_gauss_area_coord); … … 627 627 /*recover pointers: */ 628 628 inputs=(ParameterInputs*)vinputs; 629 629 630 630 631 631 /*If this element is on the surface, we have a dynamic boundary condition that applies, as a stiffness … … 660 660 661 661 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); 662 662 #ifdef _DEBUG_ 663 663 for (i=0;i<num_area_gauss;i++){ 664 664 _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)); … … 667 667 _printf_("Vert Gauss coord %i: %lf Weight: %lf\n",i,*(fourth_gauss_vert_coord+i),*(vert_gauss_weights+i)); 668 668 } 669 670 669 #endif 670 671 671 /* Start looping on the number of gaussian points: */ 672 672 for (ig1=0; ig1<num_area_gauss; ig1++){ 673 673 for (ig2=0; ig2<num_vert_gauss; ig2++){ 674 674 675 675 /*Pick up the gaussian point: */ 676 676 gauss_weight1=*(area_gauss_weights+ig1); 677 677 gauss_weight2=*(vert_gauss_weights+ig2); 678 678 gauss_weight=gauss_weight1*gauss_weight2; 679 679 680 680 gauss_l1l2l3l4[0]=*(first_gauss_area_coord+ig1); 681 681 gauss_l1l2l3l4[1]=*(second_gauss_area_coord+ig1); … … 693 693 /* Do the triple product tB*D*Bprime: */ 694 694 TripleMultiply( &B[0][0],1,numgrids,1, 695 &DL_scalar,1,1,0,696 &Bprime[0][0],1,numgrids,0,697 &Ke_gg_gaussian[0][0],0);695 &DL_scalar,1,1,0, 696 &Bprime[0][0],1,numgrids,0, 697 &Ke_gg_gaussian[0][0],0); 698 698 699 699 /* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */ … … 708 708 /*Add Ke_gg to global matrix Kgg: */ 709 709 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES); 710 711 710 711 cleanup_and_return: 712 712 xfree((void**)&first_gauss_area_coord); 713 713 xfree((void**)&second_gauss_area_coord); … … 740 740 double gravity,rho_ice,rho_water; 741 741 742 742 743 743 /*Collapsed formulation: */ 744 744 Tria* tria=NULL; … … 746 746 /*Grid data: */ 747 747 double xyz_list[numgrids][3]; 748 748 749 749 /*parameters: */ 750 750 double xyz_list_tria[numgrids2d][3]; … … 770 770 double DLStokes[14][14]={0.0}; 771 771 double tLDStokes[numdof2d][14]; 772 772 773 773 /* gaussian points: */ 774 774 int num_area_gauss; … … 792 792 double alpha2_list[numgrids2d]; 793 793 double alpha2_gauss; 794 794 795 795 ParameterInputs* inputs=NULL; 796 796 … … 804 804 } 805 805 } 806 806 807 807 /*recovre material parameters: */ 808 808 rho_water=matpar->GetRhoWater(); … … 818 818 819 819 /* Get gaussian points and weights. Penta is an extrusion of a Tria, we therefore 820 821 822 823 820 get tria gaussian points as well as segment gaussian points. For tria gaussian 821 points, order of integration is 2, because we need to integrate the product tB*D*B' 822 which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian 823 points, same deal, which yields 3 gaussian points.*/ 824 824 825 825 area_order=5; … … 845 845 /*Compute strain rate: */ 846 846 GetStrainRateStokes(&epsilon[0],&vxvyvz_list[0][0],&xyz_list[0][0],gauss_coord); 847 847 848 848 /*Get viscosity: */ 849 849 matice->GetViscosity3dStokes(&viscosity,&epsilon[0]); … … 883 883 /*Build alpha2_list used by drag stiffness matrix*/ 884 884 Friction* friction=NewFriction(); 885 885 886 886 /*Initialize all fields: */ 887 887 friction->element_type=(char*)xmalloc((strlen("2d")+1)*sizeof(char)); 888 888 strcpy(friction->element_type,"2d"); 889 889 890 890 friction->gravity=matpar->GetG(); 891 891 friction->rho_ice=matpar->GetRhoIce(); … … 910 910 } 911 911 } 912 912 913 913 GaussTria (&num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights, 2); 914 914 … … 920 920 gauss_coord[2]=*(third_gauss_area_coord+igarea); 921 921 gauss_coord[3]=-1; 922 922 923 923 gauss_coord_tria[0]=*(first_gauss_area_coord+igarea); 924 924 gauss_coord_tria[1]=*(second_gauss_area_coord+igarea); 925 925 gauss_coord_tria[2]=*(third_gauss_area_coord+igarea); 926 926 927 927 /*Get the Jacobian determinant */ 928 928 tria->GetJacobianDeterminant3d(&Jdet2d, &xyz_list_tria[0][0], gauss_coord_tria); 929 929 930 930 /*Get L matrix if viscous basal drag present: */ 931 931 GetLStokes(&LStokes[0][0], gauss_coord_tria); 932 932 GetLprimeStokes(&LprimeStokes[0][0], &xyz_list[0][0], gauss_coord_tria, gauss_coord); 933 933 934 934 /*Compute strain rate: */ 935 935 GetStrainRateStokes(&epsilon[0],&vxvyvz_list[0][0],&xyz_list[0][0],gauss_coord); 936 936 937 937 /*Get viscosity at last iteration: */ 938 938 matice->GetViscosity3dStokes(&viscosity,&epsilon[0]); 939 939 940 940 /*Get normal vecyor to the bed */ 941 941 SurfaceNormal(&surface_normal[0],xyz_list_tria); 942 942 943 943 bed_normal[0]=-surface_normal[0]; //Program is for surface, so the normal to the bed is the opposite of the result 944 944 bed_normal[1]=-surface_normal[1]; … … 974 974 } 975 975 } //if ( (onbed==1) && (shelf==0)) 976 976 977 977 /*Reduce the matrix */ 978 978 ReduceMatrixStokes(&Ke_reduced[0][0], &Ke_temp[0][0]); … … 986 986 /*Add Ke_gg to global matrix Kgg: */ 987 987 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)K_terms,ADD_VALUES); 988 989 988 989 cleanup_and_return: 990 990 991 991 return; … … 998 998 /*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */ 999 999 if (analysis_type==ControlAnalysisEnum()){ 1000 1000 1001 1001 CreatePVectorDiagnosticHoriz( pg,inputs,analysis_type,sub_analysis_type); 1002 1002 } 1003 1003 else if (analysis_type==DiagnosticAnalysisEnum()){ 1004 1004 1005 1005 if (sub_analysis_type==HorizAnalysisEnum()){ 1006 1006 … … 1008 1008 } 1009 1009 else if (sub_analysis_type==VertAnalysisEnum()){ 1010 1010 1011 1011 CreatePVectorDiagnosticVert( pg,inputs,analysis_type,sub_analysis_type); 1012 1012 } 1013 1013 else if (sub_analysis_type==StokesAnalysisEnum()){ 1014 1014 1015 1015 CreatePVectorDiagnosticStokes( pg,inputs,analysis_type,sub_analysis_type); 1016 1016 } … … 1018 1018 } 1019 1019 else if (analysis_type==SlopeComputeAnalysisEnum()){ 1020 1020 1021 1021 CreatePVectorSlopeCompute( pg,inputs,analysis_type,sub_analysis_type); 1022 1022 } 1023 1023 else if (analysis_type==ThermalAnalysisEnum()){ 1024 1024 1025 1025 CreatePVectorThermal( pg,inputs,analysis_type,sub_analysis_type); 1026 1026 } 1027 1027 else if (analysis_type==MeltingAnalysisEnum()){ 1028 1028 1029 1029 CreatePVectorMelting( pg,inputs,analysis_type,sub_analysis_type); 1030 1030 } … … 1056 1056 inputs->Recover("melting",&melting[0],1,dofs,6,(void**)nodes); 1057 1057 inputs->Recover("accumulation_param",&accumulation[0],1,dofs,6,(void**)nodes); 1058 1058 1059 1059 //Update material if necessary 1060 1060 if(inputs->Recover("temperature_average",&temperature_list[0],1,dofs,6,(void**)nodes)){ … … 1063 1063 matice->SetB(B_average); 1064 1064 } 1065 1065 1066 1066 if(inputs->Recover("B",&B_list[0],1,dofs,6,(void**)nodes)){ 1067 1067 B_average=(B_list[0]+B_list[1]+B_list[2]+B_list[3]+B_list[4]+B_list[5])/6.0; … … 1088 1088 } 1089 1089 } 1090 1090 1091 1091 int Penta::GetOnBed(){ 1092 1092 return onbed; … … 1099 1099 } 1100 1100 void Penta::GetBedList(double* bed_list){ 1101 1101 1102 1102 int i; 1103 1103 for(i=0;i<6;i++)bed_list[i]=b[i]; … … 1115 1115 int i; 1116 1116 Tria* tria=NULL; 1117 1117 1118 1118 /*Bail out if this element if: 1119 1119 * -> Non collapsed and not on the surface … … 1132 1132 } 1133 1133 else{ 1134 1134 1135 1135 tria=(Tria*)SpawnTria(3,4,5); //grids 3, 4 and 5 make the new tria (upper face). 1136 1136 tria->Du(du_g,u_g,u_g_obs,inputs,analysis_type,sub_analysis_type); … … 1156 1156 #define __FUNCT__ "Penta::GradjDrag" 1157 1157 void Penta::GradjDrag(Vec grad_g,double* u_g,double* lambda_g,void* inputs,int analysis_type,int sub_analysis_type){ 1158 1159 1158 1159 1160 1160 Tria* tria=NULL; 1161 1161 1162 1162 /*Bail out if this element does not touch the bedrock: */ 1163 1163 if (!onbed){ … … 1165 1165 } 1166 1166 else{ 1167 1167 1168 1168 tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria. 1169 1169 tria->GradjDrag( grad_g,u_g,lambda_g,inputs,analysis_type,sub_analysis_type); … … 1178 1178 throw ErrorException(__FUNCT__," not supported yet!"); 1179 1179 } 1180 1180 1181 1181 #undef __FUNCT__ 1182 1182 #define __FUNCT__ "Penta::Misfit" 1183 1183 double Penta::Misfit(double* velocity,double* obs_velocity,void* inputs,int analysis_type,int sub_analysis_type){ 1184 1184 1185 1185 double J; 1186 1186 Tria* tria=NULL; 1187 1187 1188 1188 /*Bail out if this element if: 1189 1189 * -> Non collapsed and not on the surface … … 1209 1209 } 1210 1210 } 1211 1211 1212 1212 #undef __FUNCT__ 1213 1213 #define __FUNCT__ "Penta::SpawnTria" … … 1224 1224 double tria_accumulation[3]; 1225 1225 double tria_geothermalflux[3]; 1226 1226 1227 1227 /*configuration: */ 1228 1228 int tria_node_ids[3]; … … 1249 1249 tria_melting[1]=melting[g1]; 1250 1250 tria_melting[2]=melting[g2]; 1251 1251 1252 1252 tria_accumulation[0]=accumulation[g0]; 1253 1253 tria_accumulation[1]=accumulation[g1]; … … 1286 1286 int doflist_per_node[MAXDOFSPERNODE]; 1287 1287 int numberofdofspernode; 1288 1288 1289 1289 for(i=0;i<6;i++){ 1290 1290 nodes[i]->GetDofList(&doflist_per_node[0],&numberofdofspernode); … … 1320 1320 GetB(&B[0][0], xyz_list, gauss_l1l2l3l4); 1321 1321 1322 1322 #ifdef _DEBUG_ 1323 1323 _printf_("B for grid1 : [ %lf %lf \n",B[0][0],B[0][1]); 1324 1324 _printf_(" [ %lf %lf \n",B[1][0],B[1][1]); … … 1326 1326 _printf_(" [ %lf %lf ]\n",B[3][0],B[3][1]); 1327 1327 _printf_(" [ %lf %lf ]\n",B[4][0],B[4][1]); 1328 1328 1329 1329 _printf_("B for grid2 : [ %lf %lf \n",B[0][2],B[0][3]); 1330 1330 _printf_(" [ %lf %lf \n",B[1][2],B[1][3]); … … 1332 1332 _printf_(" [ %lf %lf ]\n",B[3][2],B[3][3]); 1333 1333 _printf_(" [ %lf %lf ]\n",B[4][2],B[4][3]); 1334 1334 1335 1335 _printf_("B for grid3 : [ %lf %lf \n", B[0][4],B[0][5]); 1336 1336 _printf_(" [ %lf %lf \n", B[1][4],B[1][5]); … … 1338 1338 _printf_(" [ %lf %lf ]\n",B[3][4],B[3][5]); 1339 1339 _printf_(" [ %lf %lf ]\n",B[4][4],B[4][5]); 1340 1340 1341 1341 _printf_("B for grid4 : [ %lf %lf \n", B[0][6],B[0][7]); 1342 1342 _printf_(" [ %lf %lf \n", B[1][6],B[1][7]); … … 1344 1344 _printf_(" [ %lf %lf ]\n",B[3][6],B[3][7]); 1345 1345 _printf_(" [ %lf %lf ]\n",B[4][6],B[4][7]); 1346 1346 1347 1347 _printf_("B for grid5 : [ %lf %lf \n", B[0][8],B[0][9]); 1348 1348 _printf_(" [ %lf %lf \n", B[1][8],B[1][9]); … … 1360 1360 _printf_("Velocity for grid %i %lf %lf\n",i,*(vxvy_list+2*i+0),*(vxvy_list+2*i+1)); 1361 1361 } 1362 1362 #endif 1363 1363 1364 1364 /*Multiply B by velocity, to get strain rate: */ 1365 1365 MatrixMultiply( &B[0][0],5,NDOF2*numgrids,0, 1366 1367 1366 velocity,NDOF2*numgrids,1,0, 1367 epsilon,0); 1368 1368 1369 1369 } … … 1385 1385 * We assume B has been allocated already, of size: 5x(NDOF2*numgrids) 1386 1386 */ 1387 1387 1388 1388 int i; 1389 1389 const int numgrids=6; … … 1396 1396 GetNodalFunctionsDerivativesBasic(&dh1dh2dh3dh4dh5dh6_basic[0][0],xyz_list, gauss_l1l2l3l4); 1397 1397 1398 1398 #ifdef _DEBUG_ 1399 1399 for (i=0;i<numgrids;i++){ 1400 1400 _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]); 1401 1401 } 1402 1402 #endif 1403 1403 1404 1404 /*Build B: */ … … 1415 1415 *(B+NDOF2*numgrids*3+NDOF2*i)=(float).5*dh1dh2dh3dh4dh5dh6_basic[2][i]; 1416 1416 *(B+NDOF2*numgrids*3+NDOF2*i+1)=0.0; 1417 1417 1418 1418 *(B+NDOF2*numgrids*4+NDOF2*i)=0.0; 1419 1419 *(B+NDOF2*numgrids*4+NDOF2*i+1)=(float).5*dh1dh2dh3dh4dh5dh6_basic[2][i]; … … 1439 1439 * We assume B has been allocated already, of size: 5x(NDOF2*numgrids) 1440 1440 */ 1441 1441 1442 1442 int i; 1443 1443 const int NDOF3=3; … … 1450 1450 GetNodalFunctionsDerivativesBasic(&dh1dh2dh3dh4dh5dh6_basic[0][0],xyz_list, gauss_l1l2l3l4); 1451 1451 1452 1452 #ifdef _DEBUG_ 1453 1453 for (i=0;i<numgrids;i++){ 1454 1454 _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]); 1455 1455 } 1456 1456 #endif 1457 1457 1458 1458 /*Build BPrime: */ … … 1469 1469 *(B+NDOF2*numgrids*3+NDOF2*i)=dh1dh2dh3dh4dh5dh6_basic[2][i]; 1470 1470 *(B+NDOF2*numgrids*3+NDOF2*i+1)=0.0; 1471 1471 1472 1472 *(B+NDOF2*numgrids*4+NDOF2*i)=0.0; 1473 1473 *(B+NDOF2*numgrids*4+NDOF2*i+1)=dh1dh2dh3dh4dh5dh6_basic[2][i]; … … 1482 1482 * the determinant of it: */ 1483 1483 const int NDOF3=3; 1484 1484 1485 1485 double J[NDOF3][NDOF3]; 1486 1486 … … 1496 1496 #define __FUNCT__ "Penta::GetNodalFunctionsDerivativesBasic" 1497 1497 void Penta::GetNodalFunctionsDerivativesBasic(double* dh1dh2dh3dh4dh5dh6_basic,double* xyz_list, double* gauss_l1l2l3l4){ 1498 1498 1499 1499 /*This routine returns the values of the nodal functions derivatives (with respect to the basic coordinate system: */ 1500 1500 1501 1501 1502 1502 int i; 1503 1503 const int NDOF3=3; … … 1534 1534 const int NDOF3=3; 1535 1535 int i,j; 1536 1536 1537 1537 /*The Jacobian is constant over the element, discard the gaussian points. 1538 1538 * J is assumed to have been allocated of size NDOF2xNDOF2.*/ … … 1544 1544 double y1,y2,y3,y4,y5,y6; 1545 1545 double z1,z2,z3,z4,z5,z6; 1546 1546 1547 1547 double sqrt3=sqrt(3.0); 1548 1548 1549 1549 /*Figure out xi,eta and zi (parametric coordinates), for this gaussian point: */ 1550 1550 A1=gauss_l1l2l3l4[0]; … … 1562 1562 x5=*(xyz_list+3*4+0); 1563 1563 x6=*(xyz_list+3*5+0); 1564 1564 1565 1565 y1=*(xyz_list+3*0+1); 1566 1566 y2=*(xyz_list+3*1+1); … … 1590 1590 *(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); 1591 1591 1592 1592 #ifdef _DEBUG_ 1593 1593 for(i=0;i<3;i++){ 1594 1594 for (j=0;j<3;j++){ … … 1597 1597 printf("\n"); 1598 1598 } 1599 1599 #endif 1600 1600 } 1601 1601 … … 1603 1603 #define __FUNCT__ "Penta::GetNodalFunctionsDerivativesParams" 1604 1604 void Penta::GetNodalFunctionsDerivativesParams(double* dl1dl2dl3dl4dl5dl6,double* gauss_l1l2l3l4){ 1605 1605 1606 1606 /*This routine returns the values of the nodal functions derivatives (with respect to the 1607 1607 * natural coordinate system) at the gaussian point. Those values vary along xi,eta,z */ … … 1610 1610 double A1,A2,A3,z; 1611 1611 double sqrt3=sqrt(3.0); 1612 1612 1613 1613 A1=gauss_l1l2l3l4[0]; //first area coordinate value. In term of xi and eta: A1=(1-xi)/2-eta/(2*sqrt(3)); 1614 1614 A2=gauss_l1l2l3l4[1]; //second area coordinate value In term of xi and eta: A2=(1+xi)/2-eta/(2*sqrt(3)); … … 1677 1677 int doflist[numdof]; 1678 1678 int numberofdofspernode; 1679 1679 1680 1680 /* parameters: */ 1681 1681 double slope[NDOF2]; … … 1752 1752 1753 1753 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); 1754 1754 #ifdef _DEBUG_ 1755 1755 for (i=0;i<num_area_gauss;i++){ 1756 1756 _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)); … … 1759 1759 _printf_("Vert Gauss coord %i: %lf Weight: %lf\n",i,*(fourth_gauss_vert_coord+i),*(vert_gauss_weights+i)); 1760 1760 } 1761 1762 1761 #endif 1762 1763 1763 /* Start looping on the number of gaussian points: */ 1764 1764 for (ig1=0; ig1<num_area_gauss; ig1++){ 1765 1765 for (ig2=0; ig2<num_vert_gauss; ig2++){ 1766 1766 1767 1767 /*Pick up the gaussian point: */ 1768 1768 gauss_weight1=*(area_gauss_weights+ig1); 1769 1769 gauss_weight2=*(vert_gauss_weights+ig2); 1770 1770 gauss_weight=gauss_weight1*gauss_weight2; 1771 1771 1772 1772 gauss_l1l2l3l4[0]=*(first_gauss_area_coord+ig1); 1773 1773 gauss_l1l2l3l4[1]=*(second_gauss_area_coord+ig1); 1774 1774 gauss_l1l2l3l4[2]=*(third_gauss_area_coord+ig1); 1775 1775 gauss_l1l2l3l4[3]=*(fourth_gauss_vert_coord+ig2); 1776 1776 1777 1777 /*Compute thickness at gaussian point: */ 1778 1778 GetParameterValue(&thickness, &h[0],gauss_l1l2l3l4); … … 1783 1783 /* Get Jacobian determinant: */ 1784 1784 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss_l1l2l3l4); 1785 1786 1785 1786 /*Get nodal functions: */ 1787 1787 GetNodalFunctions(l1l2l3l4l5l6, gauss_l1l2l3l4); 1788 1788 … … 1808 1808 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES); 1809 1809 1810 1810 cleanup_and_return: 1811 1811 xfree((void**)&first_gauss_area_coord); 1812 1812 xfree((void**)&second_gauss_area_coord); … … 1822 1822 #define __FUNCT__ "Penta::CreateKMatrix" 1823 1823 void Penta::GetParameterValue(double* pvalue, double* v_list,double* gauss_l1l2l3l4){ 1824 1824 1825 1825 const int numgrids=6; 1826 1826 double l1l2l3l4l5l6[numgrids]; … … 1834 1834 #define __FUNCT__ "Penta::GetParameterDerivativeValue" 1835 1835 void Penta::GetParameterDerivativeValue(double* p, double* p_list,double* xyz_list, double* gauss_l1l2l3l4){ 1836 1836 1837 1837 /*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: 1838 1838 * 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; … … 1849 1849 /*Get dh1dh2dh3dh4dh5dh6_basic in basic coordinate system: */ 1850 1850 GetNodalFunctionsDerivativesBasic(&dh1dh2dh3dh4dh5dh6_basic[0][0],xyz_list, gauss_l1l2l3l4); 1851 1851 1852 1852 *(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]; 1853 ;1853 ; 1854 1854 *(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]; 1855 1855 … … 1861 1861 #define __FUNCT__ "Penta::GetNodalFunctions" 1862 1862 void Penta::GetNodalFunctions(double* l1l2l3l4l5l6, double* gauss_l1l2l3l4){ 1863 1863 1864 1864 /*This routine returns the values of the nodal functions at the gaussian point.*/ 1865 1865 … … 1867 1867 1868 1868 l1l2l3l4l5l6[1]=gauss_l1l2l3l4[1]*(1-gauss_l1l2l3l4[3])/2.0; 1869 1869 1870 1870 l1l2l3l4l5l6[2]=gauss_l1l2l3l4[2]*(1-gauss_l1l2l3l4[3])/2.0; 1871 1871 … … 1873 1873 1874 1874 l1l2l3l4l5l6[4]=gauss_l1l2l3l4[1]*(1+gauss_l1l2l3l4[3])/2.0; 1875 1875 1876 1876 l1l2l3l4l5l6[5]=gauss_l1l2l3l4[2]*(1+gauss_l1l2l3l4[3])/2.0; 1877 1877 … … 1888 1888 int nodedofs[2]; 1889 1889 int numberofdofspernode; 1890 1890 1891 1891 Node* node=NULL; 1892 1892 int i; 1893 1893 double velocity[2]; 1894 1894 1895 1895 1896 1896 if((collapse==1) && (onbed==1)){ 1897 1897 1898 1898 GetDofList(&doflist[0],&numberofdofspernode); 1899 1899 … … 1902 1902 * inserting the same velocity value into ug, until we reach the surface: */ 1903 1903 for(i=0;i<3;i++){ 1904 1904 1905 1905 node=nodes[i]; //base nodes 1906 1906 1907 1907 /*get velocity for this base node: */ 1908 1908 velocity[0]=ug_serial[doflist[numberofdofspernode*i+0]]; … … 1938 1938 int nodedof; 1939 1939 int numberofdofspernode; 1940 1940 1941 1941 Node* node=NULL; 1942 1942 int i; 1943 1943 double slope; 1944 1944 1945 1945 1946 1946 if(onbed==1){ 1947 1947 1948 1948 GetDofList(&doflist[0],&numberofdofspernode); 1949 1949 … … 1952 1952 /*For each node on the base of this penta, we grab the slope. Once we know the slope, we follow the upper nodes, 1953 1953 * inserting the same slope value into sg, until we reach the surface: */ 1954 1954 1955 1955 for(i=0;i<3;i++){ 1956 1956 1957 1957 node=nodes[i]; //base nodes 1958 1958 1959 1959 /*get velocity for this base node: */ 1960 1960 slope=sg_serial[doflist[i]]; … … 1984 1984 1985 1985 /* Compute B matrix. B=[dh1/dz dh2/dz dh3/dz dh4/dz dh5/dz dh6/dz]; 1986 where hi is the interpolation function for grid i.*/1986 where hi is the interpolation function for grid i.*/ 1987 1987 1988 1988 int i; … … 1994 1994 GetNodalFunctionsDerivativesBasic(&dh1dh2dh3dh4dh5dh6_basic[0][0],xyz_list, gauss_l1l2l3l4); 1995 1995 1996 1996 #ifdef _DEBUG_ 1997 1997 for (i=0;i<numgrids;i++){ 1998 1998 _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]); 1999 1999 } 2000 2000 #endif 2001 2001 2002 2002 /*Build B: */ … … 2004 2004 B[i]=dh1dh2dh3dh4dh5dh6_basic[2][i]; 2005 2005 } 2006 2006 2007 2007 } 2008 2008 … … 2015 2015 2016 2016 int i; 2017 2017 2018 2018 GetNodalFunctions(B, gauss_l1l2l3l4); 2019 2019 … … 2034 2034 int doflist[numdof]; 2035 2035 int numberofdofspernode; 2036 2036 2037 2037 /* gaussian points: */ 2038 2038 int num_gauss,ig; … … 2094 2094 /* recover input parameters: */ 2095 2095 if(!inputs->Recover("velocity",&vx_list[0],1,dofs1,numgrids,(void**)nodes))throw ErrorException(__FUNCT__," cannot compute vertical velocity without horizontal velocity!"); 2096 2096 inputs->Recover("velocity",&vy_list[0],1,dofs2,numgrids,(void**)nodes); 2097 2097 2098 2098 /*Get gaussian points and weights :*/ … … 2101 2101 2102 2102 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); 2103 2103 #ifdef _DEBUG_ 2104 2104 for (i=0;i<num_area_gauss;i++){ 2105 2105 _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)); … … 2108 2108 _printf_("Vert Gauss coord %i: %lf Weight: %lf\n",i,*(fourth_gauss_vert_coord+i),*(vert_gauss_weights+i)); 2109 2109 } 2110 2110 #endif 2111 2111 2112 2112 /* Start looping on the number of gaussian points: */ 2113 2113 for (ig1=0; ig1<num_area_gauss; ig1++){ 2114 2114 for (ig2=0; ig2<num_vert_gauss; ig2++){ 2115 2115 2116 2116 /*Pick up the gaussian point: */ 2117 2117 gauss_weight1=*(area_gauss_weights+ig1); 2118 2118 gauss_weight2=*(vert_gauss_weights+ig2); 2119 2119 gauss_weight=gauss_weight1*gauss_weight2; 2120 2120 2121 2121 gauss_l1l2l3l4[0]=*(first_gauss_area_coord+ig1); 2122 2122 gauss_l1l2l3l4[1]=*(second_gauss_area_coord+ig1); 2123 2123 gauss_l1l2l3l4[2]=*(third_gauss_area_coord+ig1); 2124 2124 gauss_l1l2l3l4[3]=*(fourth_gauss_vert_coord+ig2); 2125 2125 2126 2126 /*Get velocity derivative, with respect to x and y: */ 2127 2127 GetParameterDerivativeValue(&du[0], &vx_list[0],&xyz_list[0][0], gauss_l1l2l3l4); … … 2129 2129 dudx=du[0]; 2130 2130 dvdy=dv[1]; 2131 2131 2132 2132 2133 2133 /* Get Jacobian determinant: */ 2134 2134 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss_l1l2l3l4); 2135 2135 #ifdef _DEBUG_ 2136 2136 _printf_("Element id %i Jacobian determinant: %lf\n",PentaElementGetID(this),Jdet); 2137 2138 2139 2137 #endif 2138 2139 /*Get nodal functions: */ 2140 2140 GetNodalFunctions(l1l2l3l4l5l6, gauss_l1l2l3l4); 2141 2141 … … 2154 2154 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES); 2155 2155 2156 2156 cleanup_and_return: 2157 2157 xfree((void**)&first_gauss_area_coord); 2158 2158 xfree((void**)&second_gauss_area_coord); … … 2175 2175 double rho_ice,g; 2176 2176 double xyz_list[numgrids][3]; 2177 2177 2178 2178 /*Get node data: */ 2179 2179 GetElementNodeData( &xyz_list[0][0], nodes, numgrids); 2180 2180 2181 2181 /*pressure is lithostatic: */ 2182 2182 //md.pressure=md.rho_ice*md.g*(md.surface-md.z); a la matlab … … 2191 2191 pressure[i]=rho_ice*g*(s[i]-xyz_list[i][2]); 2192 2192 } 2193 2193 2194 2194 /*plug local pressure values into global pressure vector: */ 2195 2195 VecSetValues(pg,numgrids,doflist,(const double*)pressure,INSERT_VALUES); … … 2205 2205 /*Collapsed formulation: */ 2206 2206 Tria* tria=NULL; 2207 2207 2208 2208 /*Is this element on the bed? :*/ 2209 2209 if(!onbed)return; … … 2221 2221 2222 2222 void Penta::CreatePVectorSlopeCompute( Vec pg, void* inputs, int analysis_type,int sub_analysis_type){ 2223 2223 2224 2224 /*Collapsed formulation: */ 2225 2225 Tria* tria=NULL; 2226 2226 2227 2227 /*Is this element on the bed? :*/ 2228 2228 if(!onbed)return; … … 2238 2238 #define __FUNCT__ "ReduceMatrixStokes" 2239 2239 void Penta::ReduceMatrixStokes(double* Ke_reduced, double* Ke_temp){ 2240 2240 2241 2241 int i,j; 2242 2242 … … 2292 2292 double det; 2293 2293 int calculationdof=3; 2294 2294 2295 2295 /*Take the matrix components: */ 2296 2296 a=*(Ke+calculationdof*0+0); … … 2305 2305 2306 2306 det=a*(e*i-f*h)-b*(d*i-f*g)+c*(d*h-e*g); 2307 2307 2308 2308 *(Ke_invert+calculationdof*0+0)=(e*i-f*h)/det; 2309 2309 *(Ke_invert+calculationdof*0+1)=(c*h-b*i)/det; … … 2392 2392 * For grid i, Bi can be expressed in the basic coordinate system 2393 2393 * by: Bi_basic=[ dh/dx 0 0 0 ] 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2394 * [ 0 dh/dy 0 0 ] 2395 * [ 0 0 dh/dy 0 ] 2396 * [ 1/2*dh/dy 1/2*dh/dx 0 0 ] 2397 * [ 1/2*dh/dz 0 1/2*dh/dx 0 ] 2398 * [ 0 1/2*dh/dz 1/2*dh/dy 0 ] 2399 * [ 0 0 0 h ] 2400 * [ dh/dx dh/dy dh/dz 0 ] 2401 * where h is the interpolation function for grid i. 2402 * Same thing for Bb except the last column that does not exist. 2403 */ 2404 2405 2405 int i; 2406 2406 int calculationdof=3; … … 2416 2416 2417 2417 GetNodalFunctions(l1l6, gauss_coord); 2418 2419 2418 2419 #ifdef _DEBUG_ 2420 2420 for (i=0;i<7;i++){ 2421 2421 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]); 2422 2422 } 2423 2423 2424 2424 #endif 2425 2425 2426 2426 /*Build B: */ … … 2470 2470 2471 2471 /* Compute B' matrix. B'=[B1' B2' B3' B4' B5' B6' Bb'] where Bi' is of size 3*NDOF2. 2472 * For grid i, Bi' can be expressed in the basic coordinate system2473 * by:2474 * Bi_basic'=[ dh/dx 0 0 0]2475 * [ 0 dh/dy 0 0]2476 * [ 0 0 dh/dz 0]2477 * [ dh/dy dh/dx 0 0]2478 * [ dh/dz 0 dh/dx 0]2479 * [ 0 dh/dz dh/dy 0]2480 * [ dh/dx dh/dy dh/dz 0]2481 * [ 0 0 0 h]2482 * where h is the interpolation function for grid i.2483 *2484 * Same thing for the bubble fonction except that there is no fourth column2485 */2472 * For grid i, Bi' can be expressed in the basic coordinate system 2473 * by: 2474 * Bi_basic'=[ dh/dx 0 0 0] 2475 * [ 0 dh/dy 0 0] 2476 * [ 0 0 dh/dz 0] 2477 * [ dh/dy dh/dx 0 0] 2478 * [ dh/dz 0 dh/dx 0] 2479 * [ 0 dh/dz dh/dy 0] 2480 * [ dh/dx dh/dy dh/dz 0] 2481 * [ 0 0 0 h] 2482 * where h is the interpolation function for grid i. 2483 * 2484 * Same thing for the bubble fonction except that there is no fourth column 2485 */ 2486 2486 2487 2487 int i; … … 2498 2498 2499 2499 GetNodalFunctions(l1l6, gauss_coord); 2500 2501 2500 2501 #ifdef _DEBUG_ 2502 2502 for (i=0;i<6;i++){ 2503 2503 printf("Node %i dh/dx=%lf dh/dy=%lf dh/dz=%lf \n",i,dh1dh7_basic[0][i],dh1dh7_basic[1][i]); 2504 2504 } 2505 2505 2506 2506 #endif 2507 2507 2508 2508 /*B_primeuild B_prime: */ … … 2551 2551 2552 2552 /* 2553 * Compute L matrix. L=[L1 L2 L3] where Li is square and of size numdof.2554 * For grid i, Li can be expressed in the basic coordinate system2555 * by:2556 * Li_basic=[ h 0 0 0]2557 * [ 0 h 0 0]2558 * [ 0 0 h 0]2559 * [ 0 0 h 0]2560 * [ h 0 0 0]2561 * [ 0 h 0 0]2562 * [ h 0 0 0]2563 * [ 0 h 0 0]2564 * [ 0 0 h 0]2565 * [ 0 0 h 0]2566 * [ 0 0 h 0]2567 * [ h 0 0 0]2568 * [ 0 h 0 0]2569 * [ 0 0 h 0]2570 * where h is the interpolation function for grid i.2571 */2553 * Compute L matrix. L=[L1 L2 L3] where Li is square and of size numdof. 2554 * For grid i, Li can be expressed in the basic coordinate system 2555 * by: 2556 * Li_basic=[ h 0 0 0] 2557 * [ 0 h 0 0] 2558 * [ 0 0 h 0] 2559 * [ 0 0 h 0] 2560 * [ h 0 0 0] 2561 * [ 0 h 0 0] 2562 * [ h 0 0 0] 2563 * [ 0 h 0 0] 2564 * [ 0 0 h 0] 2565 * [ 0 0 h 0] 2566 * [ 0 0 h 0] 2567 * [ h 0 0 0] 2568 * [ 0 h 0 0] 2569 * [ 0 0 h 0] 2570 * where h is the interpolation function for grid i. 2571 */ 2572 2572 2573 2573 int i; … … 2582 2582 l1l2l3[1]=gauss_coord_tria[1]; 2583 2583 l1l2l3[2]=gauss_coord_tria[2]; 2584 2585 2586 2584 2585 2586 #ifdef _DELUG_ 2587 2587 for (i=0;i<3;i++){ 2588 2588 printf("Node %i h=%lf \n",i,l1l2l3[i]); 2589 2589 } 2590 2590 #endif 2591 2591 2592 2592 /*Build LStokes: */ … … 2648 2648 *(LStokes+num_dof*numgrids2d*13+num_dof*i+2)=l1l2l3[i]; 2649 2649 *(LStokes+num_dof*numgrids2d*13+num_dof*i+3)=0; 2650 2650 2651 2651 } 2652 2652 } … … 2658 2658 2659 2659 /* 2660 * Compute Lprime matrix. Lprime=[Lp1 Lp2 Lp3] where Lpi is square and of size numdof.2661 * For grid i, Lpi can be expressed in the basic coordinate system2662 * by:2663 * Lpi_basic=[ h 0 0 0]2664 * [ 0 h 0 0]2665 * [ h 0 0 0]2666 * [ 0 h 0 0]2667 * [ 0 0 h 0]2668 * [ 0 0 h 0]2669 * [ 0 0 dh/dz 0]2670 * [ 0 0 dh/dz 0]2671 * [ 0 0 dh/dz 0]2672 * [dh/dz 0 dh/dx 0]2673 * [ 0 dh/dz dh/dy 0]2674 * [ 0 0 0 h]2675 * [ 0 0 0 h]2676 * [ 0 0 0 h]2677 * where h is the interpolation function for grid i.2678 */2660 * Compute Lprime matrix. Lprime=[Lp1 Lp2 Lp3] where Lpi is square and of size numdof. 2661 * For grid i, Lpi can be expressed in the basic coordinate system 2662 * by: 2663 * Lpi_basic=[ h 0 0 0] 2664 * [ 0 h 0 0] 2665 * [ h 0 0 0] 2666 * [ 0 h 0 0] 2667 * [ 0 0 h 0] 2668 * [ 0 0 h 0] 2669 * [ 0 0 dh/dz 0] 2670 * [ 0 0 dh/dz 0] 2671 * [ 0 0 dh/dz 0] 2672 * [dh/dz 0 dh/dx 0] 2673 * [ 0 dh/dz dh/dy 0] 2674 * [ 0 0 0 h] 2675 * [ 0 0 0 h] 2676 * [ 0 0 0 h] 2677 * where h is the interpolation function for grid i. 2678 */ 2679 2679 2680 2680 int i; … … 2690 2690 l1l2l3[1]=gauss_coord_tria[1]; 2691 2691 l1l2l3[2]=gauss_coord_tria[2]; 2692 2692 2693 2693 GetNodalFunctionsDerivativesBasic(&dh1dh6_basic[0][0],xyz_list,gauss_coord); 2694 2694 2695 2695 #ifdef _DELUG_ 2696 2696 for (i=0;i<3;i++){ 2697 2697 printf("Node %i h=%lf \n",i,l1l2l3[i]); 2698 2698 } 2699 2699 #endif 2700 2700 2701 2701 /*Build LprimeStokes: */ … … 2757 2757 *(LprimeStokes+num_dof*numgrids2d*13+num_dof*i+2)=0; 2758 2758 *(LprimeStokes+num_dof*numgrids2d*13+num_dof*i+3)=l1l2l3[i]; 2759 2760 } 2761 2759 2760 } 2761 2762 2762 } 2763 2763 … … 2765 2765 #define __FUNCT__ "Penta::GetNodalFunctionsDerivativesBasicStokes" 2766 2766 void Penta::GetNodalFunctionsDerivativesBasicStokes(double* dh1dh7_basic,double* xyz_list, double* gauss_coord){ 2767 2767 2768 2768 /*This routine returns the values of the nodal functions derivatives (with respect to the 2769 2769 * basic coordinate system: */ … … 2801 2801 #define __FUNCT__ "Penta::GetNodalFunctionsDerivativesParamsStokes" 2802 2802 void Penta::GetNodalFunctionsDerivativesParamsStokes(double* dl1dl7,double* gauss_coord){ 2803 2803 2804 2804 /*This routine returns the values of the nodal functions derivatives (with respect to the 2805 2805 * natural coordinate system) at the gaussian point. */ … … 2893 2893 int area_order=5; 2894 2894 int num_vert_gauss=5; 2895 2895 2896 2896 double epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/ 2897 2897 double viscosity; … … 2916 2916 double tBD[27][8]; 2917 2917 double P_terms[numdof]; 2918 2918 2919 2919 ParameterInputs* inputs=NULL; 2920 2920 Tria* tria=NULL; … … 2941 2941 2942 2942 /* Get gaussian points and weights. Penta is an extrusion of a Tria, we therefore 2943 2944 2945 2946 2943 get tria gaussian points as well as segment gaussian points. For tria gaussian 2944 points, order of integration is 2, because we need to integrate the product tB*D*B' 2945 which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian 2946 points, same deal, which yields 3 gaussian points.*/ 2947 2947 2948 2948 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ … … 2964 2964 GetStrainRateStokes(&epsilon[0],&vxvyvz_list[0][0],&xyz_list[0][0],gauss_coord); 2965 2965 matice->GetViscosity3dStokes(&viscosity,&epsilon[0]); 2966 2966 2967 2967 /* Get Jacobian determinant: */ 2968 2968 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss_coord); … … 2984 2984 GetBStokes(&B[0][0],&xyz_list[0][0],gauss_coord); 2985 2985 GetBprimeStokes(&B_prime[0][0],&xyz_list[0][0], gauss_coord); 2986 2986 2987 2987 /*Get bubble part of Bprime */ 2988 2988 for(i=0;i<8;i++){ … … 3033 3033 gauss_coord[2]=*(third_gauss_area_coord+igarea); 3034 3034 gauss_coord[3]=-1; 3035 3035 3036 3036 gauss_coord_tria[0]=*(first_gauss_area_coord+igarea); 3037 3037 gauss_coord_tria[1]=*(second_gauss_area_coord+igarea); … … 3040 3040 /*Get the Jacobian determinant */ 3041 3041 tria->GetJacobianDeterminant3d(&Jdet2d, &xyz_list_tria[0][0], gauss_coord_tria); 3042 3042 3043 3043 /* Get bed at gaussian point */ 3044 3044 GetParameterValue(&bed,&b[0],gauss_coord); … … 3046 3046 /*Get L matrix : */ 3047 3047 tria->GetL(&L[0], &xyz_list[0][0], gauss_coord_tria,1); 3048 3048 3049 3049 /*Get water_pressure at gaussian point */ 3050 3050 water_pressure=gravity*rho_water*bed; … … 3052 3052 /*Get normal vecyor to the bed */ 3053 3053 SurfaceNormal(&surface_normal[0],xyz_list_tria); 3054 3054 3055 3055 bed_normal[0]=-surface_normal[0]; //Program is for surface, so the normal to the bed is the opposite of the result 3056 3056 bed_normal[1]=-surface_normal[1]; … … 3064 3064 } 3065 3065 } //if ( (onbed==1) && (shelf==1)) 3066 3066 3067 3067 /*Reduce the matrix */ 3068 3068 ReduceVectorStokes(&Pe_reduced[0], &Ke_temp[0][0], &Pe_temp[0]); … … 3080 3080 #define __FUNCT__ "Penta::ReduceVectorStokes" 3081 3081 void Penta::ReduceVectorStokes(double* Pe_reduced, double* Ke_temp, double* Pe_temp){ 3082 3082 3083 3083 int i,j; 3084 3084 … … 3123 3123 #define __FUNCT__ "Penta::GetNodalFunctionsStokes" 3124 3124 void Penta::GetNodalFunctionsStokes(double* l1l7, double* gauss_coord){ 3125 3125 3126 3126 /*This routine returns the values of the nodal functions at the gaussian point.*/ 3127 3127 … … 3161 3161 const int NDOF1=1; 3162 3162 const int numdof=NDOF1*numgrids; 3163 double 3164 int 3165 int 3163 double xyz_list[numgrids][3]; 3164 int doflist[numdof]; 3165 int numberofdofspernode; 3166 3166 3167 3167 /* gaussian points: */ … … 3177 3177 3178 3178 int area_order=5; 3179 int num_vert_gauss=5; 3180 3181 int dofs[3]={0,1,2}; 3182 double dt; 3183 int dt_exists; 3184 3185 double vxvyvz_list[numgrids][3]; 3186 double vx_list[numgrids]; 3187 int vx_list_exists; 3188 double u; 3189 double vy_list[numgrids]; 3190 int vy_list_exists; 3191 double v; 3192 double vz_list[numgrids]; 3193 int vz_list_exists; 3194 double w; 3195 3196 /* element parameters: */ 3197 int onbed; 3198 int shelf; 3199 int steady_state; 3179 int num_vert_gauss=5; 3180 3181 int dofs[3]={0,1,2}; 3182 double dt; 3183 int dt_exists; 3184 3185 double vxvyvz_list[numgrids][3]; 3186 double vx_list[numgrids]; 3187 int vx_list_exists; 3188 double u; 3189 double vy_list[numgrids]; 3190 int vy_list_exists; 3191 double v; 3192 double vz_list[numgrids]; 3193 int vz_list_exists; 3194 double w; 3200 3195 3201 3196 /*matrices: */ 3202 double 3203 double 3204 double 3205 double 3206 double 3207 double 3208 double 3209 double 3210 double 3211 double 3212 double 3213 double 3214 double 3215 double 3216 double 3217 double 3218 double 3219 double 3220 3221 double 3197 double K_terms[numdof][numdof]={0.0}; 3198 double Ke_gaussian_conduct[numdof][numdof]; 3199 double Ke_gaussian_advec[numdof][numdof]; 3200 double Ke_gaussian_transient[numdof][numdof]; 3201 double B[3][numdof]; 3202 double Bprime[3][numdof]; 3203 double B_conduct[3][numdof]; 3204 double B_advec[3][numdof]; 3205 double Bprime_advec[3][numdof]; 3206 double L[numdof]; 3207 double D_scalar; 3208 double D[3][3]; 3209 double l1l2l3[3]; 3210 double tl1l2l3D[3]; 3211 double tBD[3][numdof]; 3212 double tBD_conduct[3][numdof]; 3213 double tBD_advec[3][numdof]; 3214 double tLD[numdof]; 3215 3216 double Jdet; 3222 3217 3223 3218 /*Material properties: */ 3224 double 3225 double 3226 double 3219 double gravity,rho_ice,rho_water; 3220 double heatcapacity,thermalconductivity; 3221 double mixed_layer_capacity,thermal_exchange_velocity; 3227 3222 3228 3223 /*Collapsed formulation: */ … … 3237 3232 GetDofList(&doflist[0],&numberofdofspernode); 3238 3233 3239 / / /*recovre material parameters: */3234 /*recovre material parameters: */ 3240 3235 rho_water=matpar->GetRhoWater(); 3241 3236 rho_ice=matpar->GetRhoIce(); … … 3243 3238 heatcapacity=matpar->GetHeatCapacity(); 3244 3239 thermalconductivity=matpar->GetThermalConductivity(); 3245 3246 3240 3247 3241 /*recover extra inputs from users, dt and velocity: */ … … 3300 3294 D[2][0]=0; D[2][1]=0; D[2][2]=D_scalar; 3301 3295 3302 3303 3296 /* Do the triple product B'*D*B: */ 3304 3297 MatrixMultiply(&B_conduct[0][0],3,numdof,1,&D[0][0],3,3,0,&tBD_conduct[0][0],0); … … 3310 3303 GetB_advec(&B_advec[0][0],&xyz_list[0][0],gauss_coord); 3311 3304 GetBprime_advec(&Bprime_advec[0][0],&xyz_list[0][0],gauss_coord); 3312 3313 3305 3314 3306 //Build the D matrix … … 3330 3322 MatrixMultiply(&B_advec[0][0],3,numdof,1,&D[0][0],3,3,0,&tBD_advec[0][0],0); 3331 3323 MatrixMultiply(&tBD_advec[0][0],numdof,3,0,&Bprime_advec[0][0],3,numdof,0,&Ke_gaussian_advec[0][0],0); 3332 3333 3324 3334 3325 /*Transient: */ … … 3359 3350 } 3360 3351 } 3361 3362 //Ice/ocean heat exchange flux on ice shelf base3363 3364 if(onbed && shelf){3365 3366 tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria.3367 tria->CreateKMatrixThermal(Kgg,inputs, analysis_type,sub_analysis_type);3368 delete tria;3369 return;3370 }3371 3352 3372 3353 /*Add Ke_gg to global matrix Kgg: */ … … 3381 3362 xfree((void**)&vert_gauss_coord); 3382 3363 3364 //Ice/ocean heat exchange flux on ice shelf base 3365 if(onbed && shelf){ 3366 3367 tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria. 3368 tria->CreateKMatrixThermal(Kgg,inputs, analysis_type,sub_analysis_type); 3369 delete tria; 3370 } 3383 3371 } 3384 3372 … … 3397 3385 * We assume B has been allocated already, of size: 3x(DOFPERGRID*numgrids) 3398 3386 */ 3399 3387 3400 3388 int i; 3401 3389 int calculationdof=3; … … 3431 3419 * We assume B has been allocated already, of size: 3x(DOFPERGRID*numgrids) 3432 3420 */ 3433 3421 3434 3422 int i; 3435 3423 int calculationdof=3; … … 3466 3454 * We assume B has been allocated already, of size: 3x(DOFPERGRID*numgrids) 3467 3455 */ 3468 3456 3469 3457 int i; 3470 3458 int calculationdof=3; … … 3489 3477 #define __FUNCT__ "Penta::CreateKMatrixMelting" 3490 3478 void Penta::CreateKMatrixMelting(Mat Kgg,void* inputs,int analysis_type,int sub_analysis_type){ 3491 3479 3492 3480 Tria* tria=NULL; 3493 3481 if (!onbed){ … … 3495 3483 } 3496 3484 else{ 3497 3485 3498 3486 tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria. 3499 3487 tria->CreateKMatrixMelting(Kgg,inputs, analysis_type,sub_analysis_type); … … 3520 3508 /*Grid data: */ 3521 3509 double xyz_list[numgrids][3]; 3522 3510 3523 3511 /* gaussian points: */ 3524 3512 int num_area_gauss,igarea,igvert; … … 3533 3521 int area_order=2; 3534 3522 int num_vert_gauss=3; 3535 3523 3536 3524 double dt; 3537 3525 double vx_list[numgrids]; … … 3549 3537 /* element parameters: */ 3550 3538 int friction_type; 3551 3539 3552 3540 int dofs[3]={0,1,2}; 3553 3541 int dofs1[1]={0}; … … 3584 3572 GetElementNodeData( &xyz_list[0][0], nodes, numgrids); 3585 3573 GetDofList(&doflist[0],&numberofdofspernode); 3586 3574 3587 3575 // /*recovre material parameters: */ 3588 3576 rho_water=matpar->GetRhoWater(); … … 3604 3592 if(!found)throw ErrorException(__FUNCT__," could not find temperature in inputs!"); 3605 3593 } 3606 3594 3607 3595 for(i=0;i<numgrids;i++){ 3608 3596 vx_list[i]=vxvyvz_list[i][0]; … … 3612 3600 3613 3601 /* Get gaussian points and weights. Penta is an extrusion of a Tria, we therefore 3614 3615 3616 3617 3618 3602 get tria gaussian points as well as segment gaussian points. For tria gaussian 3603 points, order of integration is 2, because we need to integrate the product tB*D*B' 3604 which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian 3605 points, same deal, which yields 3 gaussian points.: */ 3606 3619 3607 /*Get gaussian points: */ 3620 3608 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); … … 3631 3619 gauss_coord[2]=*(third_gauss_area_coord+igarea); 3632 3620 gauss_coord[3]=*(vert_gauss_coord+igvert); 3633 3621 3634 3622 /*Compute strain rate and viscosity: */ 3635 3623 GetStrainRateStokes(&epsilon[0],&vxvyvz_list[0][0],&xyz_list[0][0],gauss_coord); … … 3673 3661 /* Ice/ocean heat exchange flux on ice shelf base */ 3674 3662 if(onbed && shelf){ 3675 3676 3663 3677 3664 tria=(Tria*)SpawnTria(0,1,2); //grids 0, 1 and 2 make the new tria. -
issm/trunk/src/c/objects/Tria.cpp
r503 r511 16 16 #include "../DataSet/DataSet.h" 17 17 #include "../include/typedefs.h" 18 19 18 20 19 /*For debugging purposes: */ … … 51 50 melting[i]=tria_melting[i]; 52 51 accumulation[i]=tria_accumulation[i]; 53 geothermalflux[i]=tria_geothermalflux[i]; } 52 geothermalflux[i]=tria_geothermalflux[i]; 53 } 54 54 matice=NULL; 55 55 matice_offset=UNDEF; … … 242 242 } 243 243 244 245 244 #undef __FUNCT__ 246 245 #define __FUNCT__ "Tria::Configure" … … 294 293 throw ErrorException(__FUNCT__,exprintf("%s%i%s\n","analysis: ",analysis_type," not supported yet")); 295 294 } 296 297 } 298 295 } 299 296 300 297 #undef __FUNCT__ … … 302 299 303 300 void Tria::CreateKMatrixDiagnosticHoriz(Mat Kgg,void* vinputs,int analysis_type,int sub_analysis_type){ 304 305 301 306 302 /* local declarations */
Note:
See TracChangeset
for help on using the changeset viewer.