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 #include "config.h"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 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 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 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 type159 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 #ifdef _DEBUGELEMENTS_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 #endif473 #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 #ifdef _DEBUGGAUSS_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 #endif496 #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 cleanup_and_return: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 #ifdef _DEBUG_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 #endif670 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 cleanup_and_return: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 get tria gaussian points as well as segment gaussian points. For tria gaussian821 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 gaussian823 points, same deal, which yields 3 gaussian points.*/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 cleanup_and_return: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 #ifdef _DEBUG_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 #endif1362 #endif 1363 1363 1364 1364 /*Multiply B by velocity, to get strain rate: */ 1365 1365 MatrixMultiply( &B[0][0],5,NDOF2*numgrids,0, 1366 velocity,NDOF2*numgrids,1,0,1367 epsilon,0);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 #ifdef _DEBUG_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 #endif1402 #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 #ifdef _DEBUG_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 #endif1456 #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 #ifdef _DEBUG_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 #endif1599 #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 #ifdef _DEBUG_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 #endif1762 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 /*Get nodal functions: */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 cleanup_and_return: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 #ifdef _DEBUG_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 #endif2000 #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 inputs->Recover("velocity",&vy_list[0],1,dofs2,numgrids,(void**)nodes);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 #ifdef _DEBUG_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 #endif2110 #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 #ifdef _DEBUG_2135 #ifdef _DEBUG_ 2136 2136 _printf_("Element id %i Jacobian determinant: %lf\n",PentaElementGetID(this),Jdet); 2137 #endif2138 2139 /*Get nodal functions: */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 cleanup_and_return: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 * [ 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 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 #ifdef _DEBUG_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 #endif2424 #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 #ifdef _DEBUG_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 #endif2506 #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 #ifdef _DELUG_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 #endif2590 #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 #ifdef _DELUG_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 #endif2699 #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 get tria gaussian points as well as segment gaussian points. For tria gaussian2944 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 gaussian2946 points, same deal, which yields 3 gaussian points.*/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 xyz_list[numgrids][3];3164 int doflist[numdof];3165 int numberofdofspernode;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 K_terms[numdof][numdof]={0.0};3203 double Ke_gaussian_conduct[numdof][numdof];3204 double Ke_gaussian_advec[numdof][numdof];3205 double Ke_gaussian_transient[numdof][numdof];3206 double B[3][numdof];3207 double Bprime[3][numdof];3208 double B_conduct[3][numdof];3209 double B_advec[3][numdof];3210 double Bprime_advec[3][numdof];3211 double L[numdof];3212 double D_scalar;3213 double D[3][3];3214 double l1l2l3[3];3215 double tl1l2l3D[3];3216 double tBD[3][numdof];3217 double tBD_conduct[3][numdof];3218 double tBD_advec[3][numdof];3219 double tLD[numdof];3220 3221 double Jdet;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 gravity,rho_ice,rho_water;3225 double heatcapacity,thermalconductivity;3226 double mixed_layer_capacity,thermal_exchange_velocity;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 get tria gaussian points as well as segment gaussian points. For tria gaussian3615 points, order of integration is 2, because we need to integrate the product tB*D*B'3616 which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian3617 points, same deal, which yields 3 gaussian points.: */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.
![(please configure the [header_logo] section in trac.ini)](/trac/issm/chrome/common/trac_banner.png)