Changeset 394
- Timestamp:
- 05/13/09 15:01:35 (16 years ago)
- Location:
- issm/trunk/src
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk/src/c/ModelProcessorx/DiagnosticStokes/CreateConstraintsDiagnosticStokes.cpp
r377 r394 91 91 /*Free data: */ 92 92 xfree((void**)&gridonstokes); 93 93 94 94 /*Assign output pointer: */ 95 95 *pconstraints=constraints; -
issm/trunk/src/c/ModelProcessorx/DiagnosticStokes/CreateElementsNodesAndMaterialsDiagnosticStokes.cpp
r387 r394 514 514 xfree((void**)&model->gridonstokes); 515 515 xfree((void**)&model->borderstokes); 516 516 517 517 cleanup_and_return: 518 518 -
issm/trunk/src/c/ModelProcessorx/DiagnosticStokes/CreateLoadsDiagnosticStokes.cpp
r387 r394 51 51 int numberofsegs_diag_stokes; 52 52 int count; 53 53 54 54 55 /*Create loads: */ … … 134 135 #endif 135 136 136 if ((model->gridonbed[i]) && (model->gridonicesheet[i]) && (model->gridonstokes[i])) 137 if ((model->gridonbed[i]) && (model->gridonicesheet[i]) && (model->gridonstokes[i])){ 137 138 138 pengrid_id=count+1; //matlab indexing139 pengrid_node_id=i+1;140 pengrid_dof=1;141 pengrid_penalty_offset=model->penalty_offset;139 pengrid_id=count+1; //matlab indexing 140 pengrid_node_id=i+1; 141 pengrid_dof=1; 142 pengrid_penalty_offset=model->penalty_offset; 142 143 143 pengrid= new Pengrid(pengrid_id, pengrid_node_id,pengrid_dof, pengrid_active, pengrid_penalty_offset,pengrid_thermal_steadystate); 144 145 loads->AddObject(icefront); 146 count++; 144 pengrid= new Pengrid(pengrid_id, pengrid_node_id,pengrid_dof, pengrid_active, pengrid_penalty_offset,pengrid_thermal_steadystate); 145 146 loads->AddObject(icefront); 147 count++; 148 } 147 149 #ifdef _PARALLEL_ 148 150 } //if((model->my_grids[i]==1)) -
issm/trunk/src/c/ModelProcessorx/Model.cpp
r388 r394 307 307 ModelFetchData((void**)&model->ishutter,NULL,NULL,model_handle,"ishutter","Integer",NULL); 308 308 ModelFetchData((void**)&model->ismacayealpattyn,NULL,NULL,model_handle,"ismacayealpattyn","Integer",NULL); 309 ModelFetchData((void**)&model->isstokes,NULL,NULL,model_handle,"isstokes","Integer",NULL); 309 310 310 311 /*!Get drag_type, drag and p,q: */ -
issm/trunk/src/c/objects/Friction.cpp
r1 r394 35 35 friction->p=UNDEF; 36 36 friction->q=UNDEF; 37 friction->analysis_type=UNDEF; 37 38 38 39 return 1; -
issm/trunk/src/c/objects/Friction.h
r1 r394 19 19 double p; 20 20 double q; 21 int analysis_type; 21 22 22 23 }; -
issm/trunk/src/c/objects/Matice.cpp
r312 r394 306 306 } 307 307 308 #undef __FUNCT__ 309 #define __FUNCT__ "MatIce::GetViscosity3dStokes" 310 void Matice::GetViscosity3dStokes(double* pviscosity3d, double* epsilon){ 311 312 /*Return viscosity accounting for steady state power law creep [Thomas and MacAyeal, 1982]: 313 * 314 * 2*B 315 * viscosity3d= ------------------------------------------------------------------- 316 * 2[ exx^2+eyy^2+exx*eyy+exy^2+exz^2+eyz^2 ]^[(n-1)/2n] 317 * 318 * where mu is the viscotiy, B the flow law parameter , (u,v) the velocity 319 * vector, and n the flow law exponent. 320 * 321 * If epsilon is NULL, it means this is the first time Emg is being run, and we 322 * return g, initial viscosity. 323 */ 324 325 /*output: */ 326 double viscosity3d; 327 328 /*input strain rate: */ 329 double exx,eyy,exy,exz,eyz,ezz; 330 331 /*Intermediary value A and exponent e: */ 332 double A,e; 333 double eps0; 334 335 eps0=10^-27; 336 337 if (n==1){ 338 /*Viscous behaviour! viscosity3d=B: */ 339 viscosity3d=B; 340 } 341 else{ 342 if((epsilon[0]==0) && (epsilon[1]==0) && (epsilon[2]==0) && 343 (epsilon[3]==0) && (epsilon[4]==0) && (epsilon[5]==0)){ 344 viscosity3d=pow(10,14); 345 } 346 else{ 347 348 /*Retrive strain rate components: */ 349 exx=*(epsilon+0); 350 eyy=*(epsilon+1); 351 ezz=*(epsilon+2); //not used 352 exy=*(epsilon+3); 353 exz=*(epsilon+4); 354 eyz=*(epsilon+5); 355 356 /*Build viscosity: viscosity3d=2*B/(2*A^e) */ 357 A=pow(exx,2)+pow(eyy,2)+pow(exy,2)+pow(exz,2)+pow(eyz,2)+exx*eyy+pow(eps0,2); 358 if(A==0){ 359 /*Maxiviscosity3dm viscosity for 0 shear areas: */ 360 viscosity3d=4.5*pow(10,17); 361 } 362 else{ 363 e=(n-1)/2/n; 364 365 viscosity3d=2*B/(2*pow(A,e)); 366 } 367 } 368 } 369 #ifdef _DEBUG_ 370 _printf_("Viscosity %lf\n",viscosity3d); 371 #endif 372 373 /*Assign output pointers:*/ 374 *pviscosity3d=viscosity3d; 375 } 308 376 double Matice::GetB(){ 309 377 return B; -
issm/trunk/src/c/objects/Matice.h
r308 r394 35 35 void GetViscosity2(double* pviscosity2, double* pepsilon); 36 36 void GetViscosity3d(double* pviscosity3d, double* pepsilon); 37 void GetViscosity3dStokes(double* pviscosity3d, double* epsilon); 37 38 Object* copy(); 38 39 double GetB(); -
issm/trunk/src/c/objects/Pengrid.cpp
r387 r394 136 136 return my_rank; 137 137 } 138 void Pengrid::DistributeNumDofs(int* numdof spernode,int analysis_type){return;}138 void Pengrid::DistributeNumDofs(int* numdofpernode,int analysis_type){return;} 139 139 140 140 #undef __FUNCT__ … … 181 181 #define __FUNCT__ "Pengrid::PenaltyCreateKMatrix" 182 182 void Pengrid::PenaltyCreateKMatrix(Mat Kgg,void* inputs,double kmax,int analysis_type){ 183 throw ErrorException(__FUNCT__," not implemented yet!"); 184 } 185 183 184 if ((analysis_type==DiagnosticStokesAnalysisEnum())){ 185 186 PenaltyCreateKMatrixDiagnosticStokes( Kgg,inputs,kmax,analysis_type); 187 188 } 189 else{ 190 throw ErrorException(__FUNCT__,exprintf("%s%i%s\n","analysis: ",analysis_type," not supported yet")); 191 } 192 193 } 194 195 #undef __FUNCT__ 196 #define __FUNCT__ "Pengrid::PenaltyCreateKMatrixDiagnosticStokes" 197 void Pengrid::PenaltyCreateKMatrixDiagnosticStokes(Mat Kgg,void* vinputs,double kmax,int analysis_type){ 198 199 const int numgrids=1; 200 const int NDOF3=3; 201 const int numdof=numgrids*NDOF3; 202 int doflist[numdof]; 203 int numberofdofspernode; 204 205 int dofs1=0; 206 int dofs2=1; 207 double slope[2]; 208 int found=0; 209 double Ke[4][4]={{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}; 210 211 ParameterInputs* inputs=NULL; 212 213 214 /*recover pointers: */ 215 inputs=(ParameterInputs*)vinputs; 216 217 /*Get dof list: */ 218 GetDofList(&doflist[0],&numberofdofspernode); 219 220 /*recover slope: */ 221 found=inputs->Recover("bedslopex",&slope[0],1,&dofs1,numgrids,(void**)&node); 222 if(!found)throw ErrorException(__FUNCT__," bedslopex needed in inputs!"); 223 found=inputs->Recover("bedslopey",&slope[1],1,&dofs2,numgrids,(void**)&node); 224 if(!found)throw ErrorException(__FUNCT__," bedslopey needed in inputs!"); 225 226 //Create elementary matrix: add penalty to contrain wb (wb=ub*db/dx+vb*db/dy) 227 Ke[0][0]=-slope[0]*kmax*pow(10.0,penalty_offset); 228 Ke[1][1]=-slope[1]*kmax*pow(10.0,penalty_offset); 229 Ke[2][2]=kmax*pow(10,penalty_offset); 230 231 232 /*Add Ke to global matrix Kgg: */ 233 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke,ADD_VALUES); 234 } 235 186 236 #undef __FUNCT__ 187 237 #define __FUNCT__ "Pengrid::PenaltyCreatePVector" … … 194 244 } 195 245 246 247 void Pengrid::GetDofList(int* doflist,int* pnumberofdofspernode){ 248 249 int j; 250 int doflist_per_node[MAXDOFSPERNODE]; 251 int numberofdofspernode; 252 253 node->GetDofList(&doflist_per_node[0],&numberofdofspernode); 254 for(j=0;j<numberofdofspernode;j++){ 255 doflist[j]=doflist_per_node[j]; 256 } 257 258 /*Assign output pointers:*/ 259 *pnumberofdofspernode=numberofdofspernode; 260 } -
issm/trunk/src/c/objects/Pengrid.h
r387 r394 46 46 void PenaltyCreateKMatrix(Mat Kgg,void* inputs,double kmax,int analysis_type); 47 47 void PenaltyCreatePVector(Vec pg,void* inputs,double kmax,int analysis_type); 48 void PenaltyCreateKMatrixDiagnosticStokes(Mat Kgg,void* inputs,double kmax,int analysis_type); 49 void GetDofList(int* doflist,int* pnumberofdofspernode); 48 50 Object* copy(); 49 51 -
issm/trunk/src/c/objects/Penta.cpp
r387 r394 297 297 298 298 } 299 else if ((analysis_type==DiagnosticStokesAnalysisEnum())){ 300 301 CreateKMatrixDiagnosticStokes( Kgg,inputs,analysis_type); 302 303 } 299 304 else if ( 300 305 (analysis_type==SurfaceSlopeComputeXAnalysisEnum()) || … … 323 328 /* node data: */ 324 329 const int numgrids=6; 325 const int numdof s=2*numgrids;330 const int numdof=2*numgrids; 326 331 double xyz_list[numgrids][3]; 327 int doflist[numdof s];332 int doflist[numdof]; 328 333 int numberofdofspernode; 329 334 … … 363 368 364 369 /* matrices: */ 365 double B[5][numdof s];366 double Bprime[5][numdof s];367 double L[2][numdof s];370 double B[5][numdof]; 371 double Bprime[5][numdof]; 372 double L[2][numdof]; 368 373 double D[5][5]={{ 0,0,0,0,0 },{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0}}; // material matrix, simple scalar matrix. 369 374 double D_scalar; … … 372 377 373 378 /* local element matrices: */ 374 double Ke_gg[numdof s][numdofs]; //local element stiffness matrix375 double Ke_gg_gaussian[numdof s][numdofs]; //stiffness matrix evaluated at the gaussian point.376 double Ke_gg_drag_gaussian[numdof s][numdofs]; //stiffness matrix contribution from drag379 double Ke_gg[numdof][numdof]; //local element stiffness matrix 380 double Ke_gg_gaussian[numdof][numdof]; //stiffness matrix evaluated at the gaussian point. 381 double Ke_gg_drag_gaussian[numdof][numdof]; //stiffness matrix contribution from drag 377 382 double Jdet; 378 383 … … 433 438 434 439 /* Set Ke_gg to 0: */ 435 for(i=0;i<numdof s;i++){436 for(j=0;j<numdof s;j++){440 for(i=0;i<numdof;i++){ 441 for(j=0;j<numdof;j++){ 437 442 Ke_gg[i][j]=0.0; 438 443 } … … 521 526 522 527 /* Do the triple product tB*D*Bprime: */ 523 TripleMultiply( &B[0][0],5,numdof s,1,528 TripleMultiply( &B[0][0],5,numdof,1, 524 529 &D[0][0],5,5,0, 525 &Bprime[0][0],5,numdof s,0,530 &Bprime[0][0],5,numdof,0, 526 531 &Ke_gg_gaussian[0][0],0); 527 532 528 533 /* Add the Ke_gg_gaussian, and optionally Ke_gg_gaussian onto Ke_gg: */ 529 for( i=0; i<numdof s; i++){530 for(j=0;j<numdof s;j++){534 for( i=0; i<numdof; i++){ 535 for(j=0;j<numdof;j++){ 531 536 Ke_gg[i][j]+=Ke_gg_gaussian[i][j]; 532 537 } … … 537 542 538 543 /*Add Ke_gg to global matrix Kgg: */ 539 MatSetValues(Kgg,numdof s,doflist,numdofs,doflist,(const double*)Ke_gg,ADD_VALUES);544 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES); 540 545 541 546 //Deal with 2d friction at the bedrock interface … … 576 581 const int numgrids=6; 577 582 const int NDOF1=1; 578 const int numdof s=NDOF1*numgrids;583 const int numdof=NDOF1*numgrids; 579 584 double xyz_list[numgrids][3]; 580 int doflist[numdof s];585 int doflist[numdof]; 581 586 int numberofdofspernode; 582 587 … … 598 603 599 604 /* matrices: */ 600 double Ke_gg[numdof s][numdofs];601 double Ke_gg_gaussian[numdof s][numdofs];605 double Ke_gg[numdof][numdof]; 606 double Ke_gg_gaussian[numdof][numdof]; 602 607 double Jdet; 603 608 double B[NDOF1][numgrids]; … … 629 634 630 635 /* Set Ke_gg to 0: */ 631 for(i=0;i<numdof s;i++){632 for(j=0;j<numdof s;j++){636 for(i=0;i<numdof;i++){ 637 for(j=0;j<numdof;j++){ 633 638 Ke_gg[i][j]=0.0; 634 639 } … … 684 689 685 690 /* Add the Ke_gg_gaussian, and optionally Ke_gg_drag_gaussian onto Ke_gg: */ 686 for( i=0; i<numdof s; i++){687 for(j=0;j<numdof s;j++){691 for( i=0; i<numdof; i++){ 692 for(j=0;j<numdof;j++){ 688 693 Ke_gg[i][j]+=Ke_gg_gaussian[i][j]; 689 694 } … … 693 698 694 699 /*Add Ke_gg to global matrix Kgg: */ 695 MatSetValues(Kgg,numdof s,doflist,numdofs,doflist,(const double*)Ke_gg,ADD_VALUES);700 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)Ke_gg,ADD_VALUES); 696 701 697 702 cleanup_and_return: … … 705 710 706 711 #undef __FUNCT__ 712 #define __FUNCT__ "Penta:CreateKMatrixDiagnosticStokes" 713 void Penta::CreateKMatrixDiagnosticStokes( Mat Kgg, void* vinputs, int analysis_type){ 714 715 int i,j; 716 717 int numgrids=6; 718 int DOFPERGRID=4; 719 int numdof=numgrids*DOFPERGRID; 720 int doflist[numdof]; 721 int numberofdofspernode; 722 723 int numgrids2d=3; 724 int numdof2d=numgrids2d*DOFPERGRID; 725 726 int dofs[3]={0,1,2}; 727 728 double K_terms[numdof][numdof]; 729 730 /*Material properties: */ 731 double gravity,rho_ice,rho_water; 732 733 734 /*Collapsed formulation: */ 735 Tria* tria=NULL; 736 737 /*Grid data: */ 738 double xyz_list[numgrids][3]; 739 740 /*parameters: */ 741 double xyz_list_tria[numgrids2d][3]; 742 double surface_normal[3]; 743 double bed_normal[3]; 744 double vxvyvz_list[numgrids][3]; 745 double thickness; 746 747 /*matrices: */ 748 double Ke_temp[27][27]; //for the six nodes and the bubble 749 double Ke_reduced[numdof][numdof]; //for the six nodes only 750 double Ke_gaussian[27][27]; 751 double Ke_drag_gaussian[numdof2d][numdof2d]; 752 double B[8][27]; 753 double B_prime[8][27]; 754 double LStokes[14][numdof2d]; 755 double LprimeStokes[14][numdof2d]; 756 double Jdet; 757 double Jdet2d; 758 double D[8][8]={{ 0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0 }}; 759 double D_scalar; 760 double tBD[numdof][8]; 761 double DLStokes[14][14]; 762 double tLDStokes[numdof2d][14]; 763 764 /* gaussian points: */ 765 int num_area_gauss; 766 int igarea,igvert; 767 double* first_gauss_area_coord = NULL; 768 double* second_gauss_area_coord = NULL; 769 double* third_gauss_area_coord = NULL; 770 double* vert_gauss_coord = NULL; 771 double* area_gauss_weights = NULL; 772 double* vert_gauss_weights = NULL; 773 774 /* specific gaussian point: */ 775 double gauss_weight,area_gauss_weight,vert_gauss_weight; 776 double gauss_coord[4]; 777 double gauss_coord_tria[3]; 778 int area_order=5; 779 int num_vert_gauss=5; 780 781 double epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/ 782 double viscosity; 783 double alpha2_list[numgrids2d]; 784 double alpha2_gauss; 785 786 ParameterInputs* inputs=NULL; 787 788 /*recover pointers: */ 789 inputs=(ParameterInputs*)vinputs; 790 791 /* Set K_terms to 0: */ 792 for(i=0;i<numdof;i++){ 793 for(j=0;j<numdof;j++){ 794 K_terms[i][j]=0.0; 795 } 796 } 797 798 /*recovre material parameters: */ 799 rho_water=matpar->GetRhoWater(); 800 rho_ice=matpar->GetRhoIce(); 801 gravity=matpar->GetG(); 802 803 804 /* Get node coordinates and dof list: */ 805 GetElementNodeData( &xyz_list[0][0], nodes, numgrids); 806 GetDofList(&doflist[0],&numberofdofspernode); 807 808 /*recover extra inputs from users, at current convergence iteration: */ 809 inputs->Recover("velocity",&vxvyvz_list[0][0],3,dofs,numgrids,(void**)nodes); 810 811 /*Initialize Ke_temp to zero befor adding terms */ 812 for (i=0;i<27;i++){ 813 for (j=0;j<27;j++){ 814 Ke_temp[i][j]=0; 815 } 816 } 817 818 /* Get gaussian points and weights. Penta is an extrusion of a Tria, we therefore 819 get tria gaussian points as well as segment gaussian points. For tria gaussian 820 points, order of integration is 2, because we need to integrate the product tB*D*B' 821 which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian 822 points, same deal, which yields 3 gaussian points.*/ 823 824 825 area_order=5; 826 num_vert_gauss=5; 827 828 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ 829 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); 830 831 /* Start looping on the number of gaussian points: */ 832 for (igarea=0; igarea<num_area_gauss; igarea++){ 833 for (igvert=0; igvert<num_vert_gauss; igvert++){ 834 /*Pick up the gaussian point: */ 835 area_gauss_weight=*(area_gauss_weights+igarea); 836 vert_gauss_weight=*(vert_gauss_weights+igvert); 837 gauss_weight=area_gauss_weight*vert_gauss_weight; 838 gauss_coord[0]=*(first_gauss_area_coord+igarea); 839 gauss_coord[1]=*(second_gauss_area_coord+igarea); 840 gauss_coord[2]=*(third_gauss_area_coord+igarea); 841 gauss_coord[3]=*(vert_gauss_coord+igvert); 842 843 844 /*Compute thickness: */ 845 GetParameterValue(&thickness, &h[0],gauss_coord); 846 847 /*Compute strain rate: */ 848 GetStrainRateStokes(&epsilon[0],&vxvyvz_list[0][0],&xyz_list[0][0],gauss_coord); 849 850 /*Get viscosity: */ 851 matice->GetViscosity3dStokes(&viscosity,&epsilon[0]); 852 853 /*Get B and Bprime matrices: */ 854 GetBStokes(&B[0][0],&xyz_list[0][0],gauss_coord); 855 GetBprimeStokes(&B_prime[0][0],&xyz_list[0][0], gauss_coord); 856 857 /* Get Jacobian determinant: */ 858 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],&gauss_coord[0]); 859 860 /* Build the D matrix: we plug the gaussian weight, the thickness, the viscosity, and the jacobian determinant 861 * onto this scalar matrix, so that we win some computational time: */ 862 D_scalar=gauss_weight*Jdet; 863 for (i=0;i<6;i++){ 864 D[i][i]=D_scalar*viscosity; 865 } 866 for (i=6;i<8;i++){ 867 D[i][i]=-D_scalar*stokesreconditioning; 868 } 869 870 871 /* Do the triple product tB*D*Bprime: */ 872 MatrixMultiply(&B[0][0],8,27,1,&D[0][0],8,8,0,&tBD[0][0],0); 873 MatrixMultiply(&tBD[0][0],27,8,0,&B_prime[0][0],8,27,0,&Ke_gaussian[0][0],0); 874 875 /*Add Ke_gaussian and Ke_gaussian to terms in pKe. Watch out for column orientation from matlab: */ 876 for(i=0;i<27;i++){ 877 for(j=0;j<27;j++){ 878 Ke_temp[i][j]+=Ke_gaussian[i][j]; 879 } 880 } 881 } 882 } 883 884 if((onbed==1) && (shelf==0)){ 885 886 887 /*Build alpha2_list used by drag stiffness matrix*/ 888 Friction* friction=NewFriction(); 889 890 /*Initialize all fields: */ 891 friction->element_type=(char*)xmalloc((strlen("2d")+1)*sizeof(char)); 892 strcpy(friction->element_type,"2d"); 893 894 friction->gravity=matpar->GetG(); 895 friction->rho_ice=matpar->GetRhoIce(); 896 friction->rho_water=matpar->GetRhoWater(); 897 friction->K=&k[0]; 898 friction->bed=&b[0]; 899 friction->thickness=&h[0]; 900 friction->velocities=&vxvyvz_list[0][0]; 901 friction->p=p; 902 friction->q=q; 903 friction->analysis_type=analysis_type; 904 905 /*Compute alpha2_list: */ 906 FrictionGetAlpha2(&alpha2_list[0],friction); 907 908 /*Erase friction object: */ 909 DeleteFriction(&friction); 910 911 for(i=0;i<numgrids2d;i++){ 912 for(j=0;j<3;j++){ 913 xyz_list_tria[i][j]=xyz_list[i][j]; 914 } 915 } 916 917 918 GaussTria (&num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights, 2); 919 920 /* Start looping on the number of gauss 2d (nodes on the bedrock) */ 921 for (igarea=0; igarea<num_area_gauss; igarea++){ 922 gauss_weight=*(area_gauss_weights+igarea); 923 gauss_coord[0]=*(first_gauss_area_coord+igarea); 924 gauss_coord[1]=*(second_gauss_area_coord+igarea); 925 gauss_coord[2]=*(third_gauss_area_coord+igarea); 926 gauss_coord[3]=-1; 927 928 gauss_coord_tria[0]=*(first_gauss_area_coord+igarea); 929 gauss_coord_tria[1]=*(second_gauss_area_coord+igarea); 930 gauss_coord_tria[2]=*(third_gauss_area_coord+igarea); 931 932 /*Get the Jacobian determinant */ 933 tria->GetJacobianDeterminant3d(&Jdet2d, &xyz_list_tria[0][0], gauss_coord_tria); 934 935 /*Get L matrix if viscous basal drag present: */ 936 GetLStokes(&LStokes[0][0], gauss_coord_tria); 937 GetLprimeStokes(&LprimeStokes[0][0], &xyz_list[0][0], gauss_coord_tria, gauss_coord); 938 939 /*Compute strain rate: */ 940 GetStrainRateStokes(&epsilon[0],&vxvyvz_list[0][0],&xyz_list[0][0],gauss_coord); 941 942 /*Get viscosity at last iteration: */ 943 matice->GetViscosity3dStokes(&viscosity,&epsilon[0]); 944 945 /*Get normal vecyor to the bed */ 946 SurfaceNormal(&surface_normal[0],xyz_list_tria); 947 948 bed_normal[0]=-surface_normal[0]; //Program is for surface, so the normal to the bed is the opposite of the result 949 bed_normal[1]=-surface_normal[1]; 950 bed_normal[2]=-surface_normal[2]; 951 952 /*Calculate DL on gauss point */ 953 tria->GetParameterValue(&alpha2_gauss,&alpha2_list[0],gauss_coord_tria); 954 955 DLStokes[0][0]=alpha2_gauss*gauss_weight*Jdet2d; 956 DLStokes[1][1]=alpha2_gauss*gauss_weight*Jdet2d; 957 DLStokes[2][2]=-alpha2_gauss*gauss_weight*Jdet2d*bed_normal[0]*bed_normal[2]; 958 DLStokes[3][3]=-alpha2_gauss*gauss_weight*Jdet2d*bed_normal[1]*bed_normal[2]; 959 DLStokes[4][4]=-alpha2_gauss*gauss_weight*Jdet2d*bed_normal[0]*bed_normal[2]; 960 DLStokes[5][5]=-alpha2_gauss*gauss_weight*Jdet2d*bed_normal[1]*bed_normal[2]; 961 DLStokes[6][6]=-viscosity*gauss_weight*Jdet2d*bed_normal[0]; 962 DLStokes[7][7]=-viscosity*gauss_weight*Jdet2d*bed_normal[1]; 963 DLStokes[8][8]=-viscosity*gauss_weight*Jdet2d*bed_normal[2]; 964 DLStokes[9][8]=-viscosity*gauss_weight*Jdet2d*bed_normal[0]/2.0; 965 DLStokes[10][10]=-viscosity*gauss_weight*Jdet2d*bed_normal[1]/2.0; 966 DLStokes[11][11]=stokesreconditioning*gauss_weight*Jdet2d*bed_normal[0]; 967 DLStokes[12][12]=stokesreconditioning*gauss_weight*Jdet2d*bed_normal[1]; 968 DLStokes[13][13]=stokesreconditioning*gauss_weight*Jdet2d*bed_normal[2]; 969 970 /* Do the triple product tL*D*L: */ 971 MatrixMultiply(&LStokes[0][0],14,numdof2d,1,&DLStokes[0][0],14,14,0,&tLDStokes[0][0],0); 972 MatrixMultiply(&tLDStokes[0][0],numdof2d,14,0,&LprimeStokes[0][0],14,numdof2d,0,&Ke_drag_gaussian[0][0],0); 973 974 for(i=0;i<numdof2d;i++){ 975 for(j=0;j<numdof2d;j++){ 976 K_terms[i][j]+=Ke_drag_gaussian[i][j]; 977 } 978 } 979 } 980 } //if ( (onbed==1) && (shelf==0)) 981 982 /*Reduce the matrix */ 983 ReduceMatrixStokes(&Ke_reduced[0][0], &Ke_temp[0][0]); 984 985 for(i=0;i<numdof;i++){ 986 for(j=0;j<numdof;j++){ 987 K_terms[i][j]+=Ke_reduced[i][j]; 988 } 989 } 990 991 /*Add Ke_gg to global matrix Kgg: */ 992 MatSetValues(Kgg,numdof,doflist,numdof,doflist,(const double*)K_terms,ADD_VALUES); 993 994 cleanup_and_return: 995 996 997 return; 998 } 999 1000 #undef __FUNCT__ 707 1001 #define __FUNCT__ "Penta::CreatePVector" 708 1002 void Penta::CreatePVector(Vec pg, void* inputs, int analysis_type){ … … 716 1010 717 1011 CreatePVectorDiagnosticVert( pg,inputs,analysis_type); 1012 } 1013 else if ((analysis_type==DiagnosticStokesAnalysisEnum())){ 1014 1015 CreatePVectorDiagnosticStokes( pg,inputs,analysis_type); 718 1016 } 719 1017 else if ( … … 1344 1642 const int numgrids=6; 1345 1643 const int NDOF2=2; 1346 const int numdof s=NDOF2*numgrids;1644 const int numdof=NDOF2*numgrids; 1347 1645 double xyz_list[numgrids][3]; 1348 int doflist[numdof s];1646 int doflist[numdof]; 1349 1647 int numberofdofspernode; 1350 1648 … … 1377 1675 1378 1676 /*element vector at the gaussian points: */ 1379 double pe_g[numdof s];1380 double pe_g_gaussian[numdof s];1677 double pe_g[numdof]; 1678 double pe_g_gaussian[numdof]; 1381 1679 1382 1680 ParameterInputs* inputs=NULL; … … 1416 1714 1417 1715 /* Set pe_g to 0: */ 1418 for(i=0;i<numdof s;i++) pe_g[i]=0.0;1716 for(i=0;i<numdof;i++) pe_g[i]=0.0; 1419 1717 1420 1718 /*Get gaussian points and weights :*/ … … 1469 1767 1470 1768 /*Add pe_g_gaussian vector to pe_g: */ 1471 for( i=0; i<numdof s; i++)pe_g[i]+=pe_g_gaussian[i];1769 for( i=0; i<numdof; i++)pe_g[i]+=pe_g_gaussian[i]; 1472 1770 1473 1771 } //for (ig2=0; ig2<num_vert_gauss; ig2++) … … 1477 1775 1478 1776 /*Add pe_g to global vector pg: */ 1479 VecSetValues(pg,numdof s,doflist,(const double*)pe_g,ADD_VALUES);1777 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES); 1480 1778 1481 1779 cleanup_and_return: … … 1488 1786 1489 1787 } 1788 1490 1789 1491 1790 #undef __FUNCT__ … … 1554 1853 /* node data: */ 1555 1854 const int numgrids=6; 1556 const int numdof s=2*numgrids;1557 int doflist[numdof s];1855 const int numdof=2*numgrids; 1856 int doflist[numdof]; 1558 1857 int nodedofs[2]; 1559 1858 int numberofdofspernode; … … 1604 1903 const int numgrids=6; 1605 1904 const int NDOF1=1; 1606 const int numdof s=NDOF1*numgrids;1607 int doflist[numdof s];1905 const int numdof=NDOF1*numgrids; 1906 int doflist[numdof]; 1608 1907 int nodedof; 1609 1908 int numberofdofspernode; … … 1700 1999 const int numgrids=6; 1701 2000 const int NDOF1=1; 1702 const int numdof s=NDOF1*numgrids;2001 const int numdof=NDOF1*numgrids; 1703 2002 double xyz_list[numgrids][3]; 1704 int doflist[numdof s];2003 int doflist[numdof]; 1705 2004 int numberofdofspernode; 1706 2005 … … 1725 2024 1726 2025 /*element vector at the gaussian points: */ 1727 double pe_g[numdof s];1728 double pe_g_gaussian[numdof s];2026 double pe_g[numdof]; 2027 double pe_g_gaussian[numdof]; 1729 2028 double l1l2l3l4l5l6[6]; 1730 2029 … … 1760 2059 1761 2060 /* Set pe_g to 0: */ 1762 for(i=0;i<numdof s;i++) pe_g[i]=0.0;2061 for(i=0;i<numdof;i++) pe_g[i]=0.0; 1763 2062 1764 2063 /* recover input parameters: */ … … 1816 2115 1817 2116 /*Add pe_g_gaussian vector to pe_g: */ 1818 for( i=0; i<numdof s; i++)pe_g[i]+=pe_g_gaussian[i];2117 for( i=0; i<numdof; i++)pe_g[i]+=pe_g_gaussian[i]; 1819 2118 1820 2119 } //for (ig2=0; ig2<num_vert_gauss; ig2++) … … 1822 2121 1823 2122 /*Add pe_g to global vector pg: */ 1824 VecSetValues(pg,numdof s,doflist,(const double*)pe_g,ADD_VALUES);2123 VecSetValues(pg,numdof,doflist,(const double*)pe_g,ADD_VALUES); 1825 2124 1826 2125 cleanup_and_return: … … 1905 2204 } 1906 2205 2206 #undef __FUNCT__ 2207 #define __FUNCT__ "ReduceMatrixStokes" 2208 void Penta::ReduceMatrixStokes(double* Ke_reduced, double* Ke_temp){ 2209 2210 int i,j; 2211 2212 double Kii[24][24]; 2213 double Kib[24][3]; 2214 double Kbb[3][3]; 2215 double Kbi[3][24]; 2216 double Kbbinv[3][3]; 2217 double KibKbbinv[24][3]; 2218 double Kright[24][24]; 2219 2220 /*Create the four matrices used for reduction */ 2221 for(i=0;i<24;i++){ 2222 for(j=0;j<24;j++){ 2223 Kii[i][j]=*(Ke_temp+27*i+j); 2224 } 2225 for(j=0;j<3;j++){ 2226 Kib[i][j]=*(Ke_temp+27*i+j+24); 2227 } 2228 } 2229 for(i=0;i<3;i++){ 2230 for(j=0;j<24;j++){ 2231 Kbi[i][j]=*(Ke_temp+27*(i+24)+j); 2232 } 2233 for(j=0;j<3;j++){ 2234 Kbb[i][j]=*(Ke_temp+27*(i+24)+j+24); 2235 } 2236 } 2237 2238 /*Inverse the matrix corresponding to bubble part Kbb */ 2239 GetMatrixInvert(&Kbbinv[0][0], &Kbb[0][0]); 2240 2241 /*Multiply matrices to create the reduce matrix Ke_reduced */ 2242 MatrixMultiply(&Kib[0][0],24,3,0,&Kbbinv[0][0],3,3,0,&KibKbbinv[0][0],0); 2243 MatrixMultiply(&KibKbbinv[0][0],24,3,0,&Kbi[0][0],3,24,0,&Kright[0][0],0); 2244 2245 /*Affect value to the reduced matrix */ 2246 for(i=0;i<24;i++){ 2247 for(j=0;j<24;j++){ 2248 *(Ke_reduced+24*i+j)=Kii[i][j]-Kright[i][j]; 2249 } 2250 } 2251 2252 2253 } 2254 2255 #undef __FUNCT__ 2256 #define __FUNCT__ "GetMatrixInvert" 2257 void Penta::GetMatrixInvert(double* Ke_invert, double* Ke){ 2258 /*Inverse a 3 by 3 matrix only */ 2259 2260 double a,b,c,d,e,f,g,h,i; 2261 double det; 2262 int calculationdof=3; 2263 2264 /*Take the matrix components: */ 2265 a=*(Ke+calculationdof*0+0); 2266 b=*(Ke+calculationdof*0+1); 2267 c=*(Ke+calculationdof*0+2); 2268 d=*(Ke+calculationdof*1+0); 2269 e=*(Ke+calculationdof*1+1); 2270 f=*(Ke+calculationdof*1+2); 2271 g=*(Ke+calculationdof*2+0); 2272 h=*(Ke+calculationdof*2+1); 2273 i=*(Ke+calculationdof*2+2); 2274 2275 det=a*(e*i-f*h)-b*(d*i-f*g)+c*(d*h-e*g); 2276 2277 *(Ke_invert+calculationdof*0+0)=(e*i-f*h)/det; 2278 *(Ke_invert+calculationdof*0+1)=(c*h-b*i)/det; 2279 *(Ke_invert+calculationdof*0+2)=(b*f-c*e)/det; 2280 *(Ke_invert+calculationdof*1+0)=(f*g-d*i)/det; 2281 *(Ke_invert+calculationdof*1+1)=(a*i-c*g)/det; 2282 *(Ke_invert+calculationdof*1+2)=(c*d-a*f)/det; 2283 *(Ke_invert+calculationdof*2+0)=(d*h-e*g)/det; 2284 *(Ke_invert+calculationdof*2+1)=(b*g-a*h)/det; 2285 *(Ke_invert+calculationdof*2+2)=(a*e-b*d)/det; 2286 2287 } 2288 2289 #undef __FUNCT__ 2290 #define __FUNCT__ "Penta::SurfaceNormal" 2291 2292 void Penta::SurfaceNormal(double* surface_normal, double xyz_list[3][3]){ 2293 2294 int i; 2295 double v13[3]; 2296 double v23[3]; 2297 double normal[3]; 2298 double normal_norm; 2299 2300 for (i=0;i<3;i++){ 2301 v13[i]=xyz_list[0][i]-xyz_list[2][i]; 2302 v23[i]=xyz_list[1][i]-xyz_list[2][i]; 2303 } 2304 2305 normal[0]=v13[1]*v23[2]-v13[2]*v23[1]; 2306 normal[1]=v13[2]*v23[0]-v13[0]*v23[2]; 2307 normal[2]=v13[0]*v23[1]-v13[1]*v23[0]; 2308 2309 normal_norm=sqrt( pow(normal[0],2)+pow(normal[1],2)+pow(normal[2],2) ); 2310 2311 *(surface_normal)=normal[0]/normal_norm; 2312 *(surface_normal+1)=normal[1]/normal_norm; 2313 *(surface_normal+2)=normal[2]/normal_norm; 2314 2315 } 2316 2317 #undef __FUNCT__ 2318 #define __FUNCT__ "Penta::GetStrainRateStokes" 2319 void Penta::GetStrainRateStokes(double* epsilon, double* velocity, double* xyz_list, double* gauss_coord){ 2320 2321 int i,j; 2322 2323 int numgrids=6; 2324 int DOFVELOCITY=3; 2325 double B[8][27]; 2326 double B_reduced[numgrids][DOFVELOCITY*numgrids]; 2327 2328 /*Get B matrix: */ 2329 GetBStokes(&B[0][0], xyz_list, gauss_coord); 2330 2331 /*Create a reduced matrix of B to get rid of pressure */ 2332 for (i=0;i<6;i++){ 2333 for (j=0;j<3;j++){ 2334 B_reduced[i][j]=B[i][j]; 2335 } 2336 for (j=4;j<7;j++){ 2337 B_reduced[i][j-1]=B[i][j]; 2338 } 2339 for (j=8;j<11;j++){ 2340 B_reduced[i][j-2]=B[i][j]; 2341 } 2342 for (j=12;j<15;j++){ 2343 B_reduced[i][j-3]=B[i][j]; 2344 } 2345 for (j=16;j<19;j++){ 2346 B_reduced[i][j-4]=B[i][j]; 2347 } 2348 for (j=20;j<23;j++){ 2349 B_reduced[i][j-5]=B[i][j]; 2350 } 2351 } 2352 /*Multiply B by velocity, to get strain rate: */ 2353 MatrixMultiply( &B_reduced[0][0],6,DOFVELOCITY*numgrids, 0, velocity,DOFVELOCITY*numgrids,1,0,epsilon, 0); 2354 } 2355 2356 #undef __FUNCT__ 2357 #define __FUNCT__ "Penta::GetBStokes" 2358 void Penta::GetBStokes(double* B, double* xyz_list, double* gauss_coord){ 2359 2360 /*Compute B matrix. B=[B1 B2 B3 B4 B5 B6] where Bi is of size 3*DOFPERGRID. 2361 * For grid i, Bi can be expressed in the basic coordinate system 2362 * by: Bi_basic=[ dh/dx 0 0 0 ] 2363 * [ 0 dh/dy 0 0 ] 2364 * [ 0 0 dh/dy 0 ] 2365 * [ 1/2*dh/dy 1/2*dh/dx 0 0 ] 2366 * [ 1/2*dh/dz 0 1/2*dh/dx 0 ] 2367 * [ 0 1/2*dh/dz 1/2*dh/dy 0 ] 2368 * [ 0 0 0 h ] 2369 * [ dh/dx dh/dy dh/dz 0 ] 2370 * where h is the interpolation function for grid i. 2371 * Same thing for Bb except the last column that does not exist. 2372 */ 2373 2374 int i; 2375 int calculationdof=3; 2376 int numgrids=6; 2377 int DOFPERGRID=4; 2378 2379 double dh1dh7_basic[calculationdof][numgrids+1]; 2380 double l1l6[numgrids]; 2381 2382 2383 /*Get dh1dh7 in basic coordinate system: */ 2384 GetNodalFunctionsDerivativesBasicStokes(&dh1dh7_basic[0][0],xyz_list, gauss_coord); 2385 2386 GetNodalFunctions(l1l6, gauss_coord); 2387 2388 #ifdef _DEBUG_ 2389 for (i=0;i<6;i++){ 2390 printf("Node %i dh/dx=%lf dh/dy=%lf dh/dz=%lf \n",i,dh1dh7_basic[0][i],dh1dh7_basic[1][i]); 2391 } 2392 2393 #endif 2394 2395 /*Build B: */ 2396 for (i=0;i<numgrids+1;i++){ 2397 *(B+(DOFPERGRID*numgrids+3)*0+DOFPERGRID*i)=dh1dh7_basic[0][i]; //B[0][DOFPERGRID*i]=dh1dh6_basic[0][i]; 2398 *(B+(DOFPERGRID*numgrids+3)*0+DOFPERGRID*i+1)=0; 2399 *(B+(DOFPERGRID*numgrids+3)*0+DOFPERGRID*i+2)=0; 2400 *(B+(DOFPERGRID*numgrids+3)*1+DOFPERGRID*i)=0; 2401 *(B+(DOFPERGRID*numgrids+3)*1+DOFPERGRID*i+1)=dh1dh7_basic[1][i]; 2402 *(B+(DOFPERGRID*numgrids+3)*1+DOFPERGRID*i+2)=0; 2403 *(B+(DOFPERGRID*numgrids+3)*2+DOFPERGRID*i)=0; 2404 *(B+(DOFPERGRID*numgrids+3)*2+DOFPERGRID*i+1)=0; 2405 *(B+(DOFPERGRID*numgrids+3)*2+DOFPERGRID*i+2)=dh1dh7_basic[2][i]; 2406 *(B+(DOFPERGRID*numgrids+3)*3+DOFPERGRID*i)=(float).5*dh1dh7_basic[1][i]; 2407 *(B+(DOFPERGRID*numgrids+3)*3+DOFPERGRID*i+1)=(float).5*dh1dh7_basic[0][i]; 2408 *(B+(DOFPERGRID*numgrids+3)*3+DOFPERGRID*i+2)=0; 2409 *(B+(DOFPERGRID*numgrids+3)*4+DOFPERGRID*i)=(float).5*dh1dh7_basic[2][i]; 2410 *(B+(DOFPERGRID*numgrids+3)*4+DOFPERGRID*i+1)=0; 2411 *(B+(DOFPERGRID*numgrids+3)*4+DOFPERGRID*i+2)=(float).5*dh1dh7_basic[0][i]; 2412 *(B+(DOFPERGRID*numgrids+3)*5+DOFPERGRID*i)=0; 2413 *(B+(DOFPERGRID*numgrids+3)*5+DOFPERGRID*i+1)=(float).5*dh1dh7_basic[2][i]; 2414 *(B+(DOFPERGRID*numgrids+3)*5+DOFPERGRID*i+2)=(float).5*dh1dh7_basic[1][i]; 2415 *(B+(DOFPERGRID*numgrids+3)*6+DOFPERGRID*i)=0; 2416 *(B+(DOFPERGRID*numgrids+3)*6+DOFPERGRID*i+1)=0; 2417 *(B+(DOFPERGRID*numgrids+3)*6+DOFPERGRID*i+2)=0; 2418 *(B+(DOFPERGRID*numgrids+3)*7+DOFPERGRID*i)=dh1dh7_basic[0][i]; 2419 *(B+(DOFPERGRID*numgrids+3)*7+DOFPERGRID*i+1)=dh1dh7_basic[1][i]; 2420 *(B+(DOFPERGRID*numgrids+3)*7+DOFPERGRID*i+2)=dh1dh7_basic[2][i]; 2421 } 2422 2423 for (i=0;i<numgrids;i++){ //last column not for the bubble function 2424 *(B+(DOFPERGRID*numgrids+3)*0+DOFPERGRID*i+3)=0; 2425 *(B+(DOFPERGRID*numgrids+3)*1+DOFPERGRID*i+3)=0; 2426 *(B+(DOFPERGRID*numgrids+3)*2+DOFPERGRID*i+3)=0; 2427 *(B+(DOFPERGRID*numgrids+3)*3+DOFPERGRID*i+3)=0; 2428 *(B+(DOFPERGRID*numgrids+3)*4+DOFPERGRID*i+3)=0; 2429 *(B+(DOFPERGRID*numgrids+3)*5+DOFPERGRID*i+3)=0; 2430 *(B+(DOFPERGRID*numgrids+3)*6+DOFPERGRID*i+3)=l1l6[i]; 2431 *(B+(DOFPERGRID*numgrids+3)*7+DOFPERGRID*i+3)=0; 2432 } 2433 2434 } 2435 2436 #undef __FUNCT__ 2437 #define __FUNCT__ "Penta::GetBprimeStokes" 2438 void Penta::GetBprimeStokes(double* B_prime, double* xyz_list, double* gauss_coord){ 2439 2440 /* Compute B' matrix. B'=[B1' B2' B3' B4' B5' B6' Bb'] where Bi' is of size 3*NDOF2. 2441 * For grid i, Bi' can be expressed in the basic coordinate system 2442 * by: 2443 * Bi_basic'=[ dh/dx 0 0 0] 2444 * [ 0 dh/dy 0 0] 2445 * [ 0 0 dh/dz 0] 2446 * [ dh/dy dh/dx 0 0] 2447 * [ dh/dz 0 dh/dx 0] 2448 * [ 0 dh/dz dh/dy 0] 2449 * [ dh/dx dh/dy dh/dz 0] 2450 * [ 0 0 0 h] 2451 * where h is the interpolation function for grid i. 2452 * 2453 * Same thing for the bubble fonction except that there is no fourth column 2454 */ 2455 2456 int i; 2457 int calculationdof=3; 2458 int numgrids=6; 2459 int DOFPERGRID=4; 2460 2461 double dh1dh7_basic[calculationdof][numgrids+1]; 2462 double l1l6[numgrids]; 2463 2464 2465 /*Get dh1dh7 in basic coordinate system: */ 2466 GetNodalFunctionsDerivativesBasicStokes(&dh1dh7_basic[0][0],xyz_list, gauss_coord); 2467 2468 GetNodalFunctions(l1l6, gauss_coord); 2469 2470 #ifdef _DEBUG_ 2471 for (i=0;i<6;i++){ 2472 printf("Node %i dh/dx=%lf dh/dy=%lf dh/dz=%lf \n",i,dh1dh7_basic[0][i],dh1dh7_basic[1][i]); 2473 } 2474 2475 #endif 2476 2477 /*B_primeuild B_prime: */ 2478 for (i=0;i<numgrids+1;i++){ 2479 *(B_prime+(DOFPERGRID*numgrids+3)*0+DOFPERGRID*i)=dh1dh7_basic[0][i]; //B_prime[0][DOFPERGRID*i]=dh1dh6_basic[0][i]; 2480 *(B_prime+(DOFPERGRID*numgrids+3)*0+DOFPERGRID*i+1)=0; 2481 *(B_prime+(DOFPERGRID*numgrids+3)*0+DOFPERGRID*i+2)=0; 2482 *(B_prime+(DOFPERGRID*numgrids+3)*1+DOFPERGRID*i)=0; 2483 *(B_prime+(DOFPERGRID*numgrids+3)*1+DOFPERGRID*i+1)=dh1dh7_basic[1][i]; 2484 *(B_prime+(DOFPERGRID*numgrids+3)*1+DOFPERGRID*i+2)=0; 2485 *(B_prime+(DOFPERGRID*numgrids+3)*2+DOFPERGRID*i)=0; 2486 *(B_prime+(DOFPERGRID*numgrids+3)*2+DOFPERGRID*i+1)=0; 2487 *(B_prime+(DOFPERGRID*numgrids+3)*2+DOFPERGRID*i+2)=dh1dh7_basic[2][i]; 2488 *(B_prime+(DOFPERGRID*numgrids+3)*3+DOFPERGRID*i)=dh1dh7_basic[1][i]; 2489 *(B_prime+(DOFPERGRID*numgrids+3)*3+DOFPERGRID*i+1)=dh1dh7_basic[0][i]; 2490 *(B_prime+(DOFPERGRID*numgrids+3)*3+DOFPERGRID*i+2)=0; 2491 *(B_prime+(DOFPERGRID*numgrids+3)*4+DOFPERGRID*i)=dh1dh7_basic[2][i]; 2492 *(B_prime+(DOFPERGRID*numgrids+3)*4+DOFPERGRID*i+1)=0; 2493 *(B_prime+(DOFPERGRID*numgrids+3)*4+DOFPERGRID*i+2)=dh1dh7_basic[0][i]; 2494 *(B_prime+(DOFPERGRID*numgrids+3)*5+DOFPERGRID*i)=0; 2495 *(B_prime+(DOFPERGRID*numgrids+3)*5+DOFPERGRID*i+1)=dh1dh7_basic[2][i]; 2496 *(B_prime+(DOFPERGRID*numgrids+3)*5+DOFPERGRID*i+2)=dh1dh7_basic[1][i]; 2497 *(B_prime+(DOFPERGRID*numgrids+3)*6+DOFPERGRID*i)=dh1dh7_basic[0][i]; 2498 *(B_prime+(DOFPERGRID*numgrids+3)*6+DOFPERGRID*i+1)=dh1dh7_basic[1][i]; 2499 *(B_prime+(DOFPERGRID*numgrids+3)*6+DOFPERGRID*i+2)=dh1dh7_basic[2][i]; 2500 *(B_prime+(DOFPERGRID*numgrids+3)*7+DOFPERGRID*i)=0; 2501 *(B_prime+(DOFPERGRID*numgrids+3)*7+DOFPERGRID*i+1)=0; 2502 *(B_prime+(DOFPERGRID*numgrids+3)*7+DOFPERGRID*i+2)=0; 2503 } 2504 2505 for (i=0;i<numgrids;i++){ //last column not for the bubble function 2506 *(B_prime+(DOFPERGRID*numgrids+3)*0+DOFPERGRID*i+3)=0; 2507 *(B_prime+(DOFPERGRID*numgrids+3)*1+DOFPERGRID*i+3)=0; 2508 *(B_prime+(DOFPERGRID*numgrids+3)*2+DOFPERGRID*i+3)=0; 2509 *(B_prime+(DOFPERGRID*numgrids+3)*3+DOFPERGRID*i+3)=0; 2510 *(B_prime+(DOFPERGRID*numgrids+3)*4+DOFPERGRID*i+3)=0; 2511 *(B_prime+(DOFPERGRID*numgrids+3)*5+DOFPERGRID*i+3)=0; 2512 *(B_prime+(DOFPERGRID*numgrids+3)*6+DOFPERGRID*i+3)=0; 2513 *(B_prime+(DOFPERGRID*numgrids+3)*7+DOFPERGRID*i+3)=l1l6[i]; 2514 } 2515 2516 } 2517 #undef __FUNCT__ 2518 #define __FUNCT__ "Penta::GetLStokes" 2519 void Penta::GetLStokes(double* LStokes, double* gauss_coord_tria){ 2520 2521 /* 2522 * Compute L matrix. L=[L1 L2 L3] where Li is square and of size numdof. 2523 * For grid i, Li can be expressed in the basic coordinate system 2524 * by: 2525 * Li_basic=[ h 0 0 0] 2526 * [ 0 h 0 0] 2527 * [ 0 0 h 0] 2528 * [ 0 0 h 0] 2529 * [ h 0 0 0] 2530 * [ 0 h 0 0] 2531 * [ h 0 0 0] 2532 * [ 0 h 0 0] 2533 * [ 0 0 h 0] 2534 * [ 0 0 h 0] 2535 * [ 0 0 h 0] 2536 * [ h 0 0 0] 2537 * [ 0 h 0 0] 2538 * [ 0 0 h 0] 2539 * where h is the interpolation function for grid i. 2540 */ 2541 2542 int i; 2543 int numgrids2d=3; 2544 int num_dof=4; 2545 2546 double l1l2l3[numgrids2d]; 2547 2548 2549 /*Get l1l2l3 in basic coordinate system: */ 2550 l1l2l3[0]=gauss_coord_tria[0]; 2551 l1l2l3[1]=gauss_coord_tria[1]; 2552 l1l2l3[2]=gauss_coord_tria[2]; 2553 2554 2555 #ifdef _DELUG_ 2556 for (i=0;i<3;i++){ 2557 printf("Node %i h=%lf \n",i,l1l2l3[i]); 2558 } 2559 #endif 2560 2561 /*Build LStokes: */ 2562 for (i=0;i<3;i++){ 2563 *(LStokes+num_dof*numgrids2d*0+num_dof*i)=l1l2l3[i]; //LStokes[0][NDOF2*i]=dh1dh2dh3_basic[0][i]; 2564 *(LStokes+num_dof*numgrids2d*0+num_dof*i+1)=0; 2565 *(LStokes+num_dof*numgrids2d*0+num_dof*i+2)=0; 2566 *(LStokes+num_dof*numgrids2d*0+num_dof*i+3)=0; 2567 *(LStokes+num_dof*numgrids2d*1+num_dof*i)=0; 2568 *(LStokes+num_dof*numgrids2d*1+num_dof*i+1)=l1l2l3[i]; 2569 *(LStokes+num_dof*numgrids2d*1+num_dof*i+2)=0; 2570 *(LStokes+num_dof*numgrids2d*1+num_dof*i+3)=0; 2571 *(LStokes+num_dof*numgrids2d*2+num_dof*i)=0; 2572 *(LStokes+num_dof*numgrids2d*2+num_dof*i+1)=0; 2573 *(LStokes+num_dof*numgrids2d*2+num_dof*i+2)=l1l2l3[i]; 2574 *(LStokes+num_dof*numgrids2d*2+num_dof*i+3)=0; 2575 *(LStokes+num_dof*numgrids2d*3+num_dof*i)=0; 2576 *(LStokes+num_dof*numgrids2d*3+num_dof*i+1)=0; 2577 *(LStokes+num_dof*numgrids2d*3+num_dof*i+2)=l1l2l3[i]; 2578 *(LStokes+num_dof*numgrids2d*3+num_dof*i+3)=0; 2579 *(LStokes+num_dof*numgrids2d*4+num_dof*i)=l1l2l3[i]; 2580 *(LStokes+num_dof*numgrids2d*4+num_dof*i+1)=0; 2581 *(LStokes+num_dof*numgrids2d*4+num_dof*i+2)=0; 2582 *(LStokes+num_dof*numgrids2d*4+num_dof*i+3)=0; 2583 *(LStokes+num_dof*numgrids2d*5+num_dof*i)=0; 2584 *(LStokes+num_dof*numgrids2d*5+num_dof*i+1)=l1l2l3[i]; 2585 *(LStokes+num_dof*numgrids2d*5+num_dof*i+2)=0; 2586 *(LStokes+num_dof*numgrids2d*5+num_dof*i+3)=0; 2587 *(LStokes+num_dof*numgrids2d*6+num_dof*i)=l1l2l3[i]; 2588 *(LStokes+num_dof*numgrids2d*6+num_dof*i+1)=0; 2589 *(LStokes+num_dof*numgrids2d*6+num_dof*i+2)=0; 2590 *(LStokes+num_dof*numgrids2d*6+num_dof*i+3)=0; 2591 *(LStokes+num_dof*numgrids2d*7+num_dof*i)=0; 2592 *(LStokes+num_dof*numgrids2d*7+num_dof*i+1)=l1l2l3[i]; 2593 *(LStokes+num_dof*numgrids2d*7+num_dof*i+2)=0; 2594 *(LStokes+num_dof*numgrids2d*7+num_dof*i+3)=0; 2595 *(LStokes+num_dof*numgrids2d*8+num_dof*i)=0; 2596 *(LStokes+num_dof*numgrids2d*8+num_dof*i+1)=0; 2597 *(LStokes+num_dof*numgrids2d*8+num_dof*i+2)=l1l2l3[i]; 2598 *(LStokes+num_dof*numgrids2d*8+num_dof*i+3)=0; 2599 *(LStokes+num_dof*numgrids2d*9+num_dof*i)=0; 2600 *(LStokes+num_dof*numgrids2d*9+num_dof*i+1)=0; 2601 *(LStokes+num_dof*numgrids2d*9+num_dof*i+2)=l1l2l3[i]; 2602 *(LStokes+num_dof*numgrids2d*9+num_dof*i+3)=0; 2603 *(LStokes+num_dof*numgrids2d*10+num_dof*i)=0; 2604 *(LStokes+num_dof*numgrids2d*10+num_dof*i+1)=0; 2605 *(LStokes+num_dof*numgrids2d*10+num_dof*i+2)=l1l2l3[i]; 2606 *(LStokes+num_dof*numgrids2d*10+num_dof*i+3)=0; 2607 *(LStokes+num_dof*numgrids2d*11+num_dof*i)=l1l2l3[i]; 2608 *(LStokes+num_dof*numgrids2d*11+num_dof*i+1)=0; 2609 *(LStokes+num_dof*numgrids2d*11+num_dof*i+2)=0; 2610 *(LStokes+num_dof*numgrids2d*11+num_dof*i+3)=0; 2611 *(LStokes+num_dof*numgrids2d*12+num_dof*i)=0; 2612 *(LStokes+num_dof*numgrids2d*12+num_dof*i+1)=l1l2l3[i]; 2613 *(LStokes+num_dof*numgrids2d*12+num_dof*i+2)=0; 2614 *(LStokes+num_dof*numgrids2d*12+num_dof*i+3)=0; 2615 *(LStokes+num_dof*numgrids2d*13+num_dof*i)=0; 2616 *(LStokes+num_dof*numgrids2d*13+num_dof*i+1)=0; 2617 *(LStokes+num_dof*numgrids2d*13+num_dof*i+2)=l1l2l3[i]; 2618 *(LStokes+num_dof*numgrids2d*13+num_dof*i+3)=0; 2619 2620 } 2621 } 2622 2623 2624 #undef __FUNCT__ 2625 #define __FUNCT__ "Penta::GetLprimeStokes" 2626 void Penta::GetLprimeStokes(double* LprimeStokes, double* xyz_list, double* gauss_coord_tria, double* gauss_coord){ 2627 2628 /* 2629 * Compute Lprime matrix. Lprime=[Lp1 Lp2 Lp3] where Lpi is square and of size numdof. 2630 * For grid i, Lpi can be expressed in the basic coordinate system 2631 * by: 2632 * Lpi_basic=[ h 0 0 0] 2633 * [ 0 h 0 0] 2634 * [ h 0 0 0] 2635 * [ 0 h 0 0] 2636 * [ 0 0 h 0] 2637 * [ 0 0 h 0] 2638 * [ 0 0 dh/dz 0] 2639 * [ 0 0 dh/dz 0] 2640 * [ 0 0 dh/dz 0] 2641 * [dh/dz 0 dh/dx 0] 2642 * [ 0 dh/dz dh/dy 0] 2643 * [ 0 0 0 h] 2644 * [ 0 0 0 h] 2645 * [ 0 0 0 h] 2646 * where h is the interpolation function for grid i. 2647 */ 2648 2649 int i; 2650 int numgrids2d=3; 2651 int num_dof=4; 2652 2653 double l1l2l3[numgrids2d]; 2654 double dh1dh6_basic[3][6]; 2655 2656 2657 /*Get l1l2l3 in basic coordinate system: */ 2658 l1l2l3[0]=gauss_coord_tria[0]; 2659 l1l2l3[1]=gauss_coord_tria[1]; 2660 l1l2l3[2]=gauss_coord_tria[2]; 2661 2662 GetNodalFunctionsDerivativesBasic(&dh1dh6_basic[0][0],xyz_list,gauss_coord); 2663 2664 #ifdef _DELUG_ 2665 for (i=0;i<3;i++){ 2666 printf("Node %i h=%lf \n",i,l1l2l3[i]); 2667 } 2668 #endif 2669 2670 /*Build LprimeStokes: */ 2671 for (i=0;i<3;i++){ 2672 *(LprimeStokes+num_dof*numgrids2d*0+num_dof*i)=l1l2l3[i]; //LprimeStokes[0][NDOF2*i]=dh1dh2dh3_basic[0][i]; 2673 *(LprimeStokes+num_dof*numgrids2d*0+num_dof*i+1)=0; 2674 *(LprimeStokes+num_dof*numgrids2d*0+num_dof*i+2)=0; 2675 *(LprimeStokes+num_dof*numgrids2d*0+num_dof*i+3)=0; 2676 *(LprimeStokes+num_dof*numgrids2d*1+num_dof*i)=0; 2677 *(LprimeStokes+num_dof*numgrids2d*1+num_dof*i+1)=l1l2l3[i]; 2678 *(LprimeStokes+num_dof*numgrids2d*1+num_dof*i+2)=0; 2679 *(LprimeStokes+num_dof*numgrids2d*1+num_dof*i+3)=0; 2680 *(LprimeStokes+num_dof*numgrids2d*2+num_dof*i)=l1l2l3[i]; 2681 *(LprimeStokes+num_dof*numgrids2d*2+num_dof*i+1)=0; 2682 *(LprimeStokes+num_dof*numgrids2d*2+num_dof*i+2)=0; 2683 *(LprimeStokes+num_dof*numgrids2d*2+num_dof*i+3)=0; 2684 *(LprimeStokes+num_dof*numgrids2d*3+num_dof*i)=0; 2685 *(LprimeStokes+num_dof*numgrids2d*3+num_dof*i+1)=l1l2l3[i]; 2686 *(LprimeStokes+num_dof*numgrids2d*3+num_dof*i+2)=0; 2687 *(LprimeStokes+num_dof*numgrids2d*3+num_dof*i+3)=0; 2688 *(LprimeStokes+num_dof*numgrids2d*4+num_dof*i)=0; 2689 *(LprimeStokes+num_dof*numgrids2d*4+num_dof*i+1)=0; 2690 *(LprimeStokes+num_dof*numgrids2d*4+num_dof*i+2)=l1l2l3[i]; 2691 *(LprimeStokes+num_dof*numgrids2d*4+num_dof*i+3)=0; 2692 *(LprimeStokes+num_dof*numgrids2d*5+num_dof*i)=0; 2693 *(LprimeStokes+num_dof*numgrids2d*5+num_dof*i+1)=0; 2694 *(LprimeStokes+num_dof*numgrids2d*5+num_dof*i+2)=l1l2l3[i]; 2695 *(LprimeStokes+num_dof*numgrids2d*5+num_dof*i+3)=0; 2696 *(LprimeStokes+num_dof*numgrids2d*6+num_dof*i)=0; 2697 *(LprimeStokes+num_dof*numgrids2d*6+num_dof*i+1)=0; 2698 *(LprimeStokes+num_dof*numgrids2d*6+num_dof*i+2)=dh1dh6_basic[2][i]; 2699 *(LprimeStokes+num_dof*numgrids2d*6+num_dof*i+3)=0; 2700 *(LprimeStokes+num_dof*numgrids2d*7+num_dof*i)=0; 2701 *(LprimeStokes+num_dof*numgrids2d*7+num_dof*i+1)=0; 2702 *(LprimeStokes+num_dof*numgrids2d*7+num_dof*i+2)=dh1dh6_basic[2][i]; 2703 *(LprimeStokes+num_dof*numgrids2d*7+num_dof*i+3)=0; 2704 *(LprimeStokes+num_dof*numgrids2d*8+num_dof*i)=0; 2705 *(LprimeStokes+num_dof*numgrids2d*8+num_dof*i+1)=0; 2706 *(LprimeStokes+num_dof*numgrids2d*8+num_dof*i+2)=dh1dh6_basic[2][i]; 2707 *(LprimeStokes+num_dof*numgrids2d*8+num_dof*i+3)=0; 2708 *(LprimeStokes+num_dof*numgrids2d*9+num_dof*i)=dh1dh6_basic[2][i]; 2709 *(LprimeStokes+num_dof*numgrids2d*9+num_dof*i+1)=0; 2710 *(LprimeStokes+num_dof*numgrids2d*9+num_dof*i+2)=dh1dh6_basic[0][i]; 2711 *(LprimeStokes+num_dof*numgrids2d*9+num_dof*i+3)=0; 2712 *(LprimeStokes+num_dof*numgrids2d*10+num_dof*i)=0; 2713 *(LprimeStokes+num_dof*numgrids2d*10+num_dof*i+1)=dh1dh6_basic[2][i]; 2714 *(LprimeStokes+num_dof*numgrids2d*10+num_dof*i+2)=dh1dh6_basic[1][i]; 2715 *(LprimeStokes+num_dof*numgrids2d*10+num_dof*i+3)=0; 2716 *(LprimeStokes+num_dof*numgrids2d*11+num_dof*i)=0; 2717 *(LprimeStokes+num_dof*numgrids2d*11+num_dof*i+1)=0; 2718 *(LprimeStokes+num_dof*numgrids2d*11+num_dof*i+2)=0; 2719 *(LprimeStokes+num_dof*numgrids2d*11+num_dof*i+3)=l1l2l3[i]; 2720 *(LprimeStokes+num_dof*numgrids2d*12+num_dof*i)=0; 2721 *(LprimeStokes+num_dof*numgrids2d*12+num_dof*i+1)=0; 2722 *(LprimeStokes+num_dof*numgrids2d*12+num_dof*i+2)=0; 2723 *(LprimeStokes+num_dof*numgrids2d*12+num_dof*i+3)=l1l2l3[i]; 2724 *(LprimeStokes+num_dof*numgrids2d*13+num_dof*i)=0; 2725 *(LprimeStokes+num_dof*numgrids2d*13+num_dof*i+1)=0; 2726 *(LprimeStokes+num_dof*numgrids2d*13+num_dof*i+2)=0; 2727 *(LprimeStokes+num_dof*numgrids2d*13+num_dof*i+3)=l1l2l3[i]; 2728 2729 } 2730 2731 } 2732 2733 #undef __FUNCT__ 2734 #define __FUNCT__ "Penta::GetNodalFunctionsDerivativesBasicStokes" 2735 void Penta::GetNodalFunctionsDerivativesBasicStokes(double* dh1dh7_basic,double* xyz_list, double* gauss_coord){ 2736 2737 /*This routine returns the values of the nodal functions derivatives (with respect to the 2738 * basic coordinate system: */ 2739 2740 int i; 2741 2742 int numgrids=7; 2743 double dh1dh7_param[3][numgrids]; 2744 double Jinv[3][3]; 2745 2746 2747 /*Get derivative values with respect to parametric coordinate system: */ 2748 GetNodalFunctionsDerivativesParamsStokes(&dh1dh7_param[0][0], gauss_coord); 2749 2750 /*Get Jacobian invert: */ 2751 GetJacobianInvert(&Jinv[0][0], xyz_list, gauss_coord); 2752 2753 /*Build dh1dh6_basic: 2754 * 2755 * [dhi/dx]= Jinv'*[dhi/dr] 2756 * [dhi/dy] [dhi/ds] 2757 * [dhi/dz] [dhi/dzeta] 2758 */ 2759 2760 for (i=0;i<numgrids;i++){ 2761 *(dh1dh7_basic+numgrids*0+i)=Jinv[0][0]*dh1dh7_param[0][i]+Jinv[1][0]*dh1dh7_param[1][i]+Jinv[2][0]*dh1dh7_param[2][i]; 2762 *(dh1dh7_basic+numgrids*1+i)=Jinv[0][1]*dh1dh7_param[0][i]+Jinv[1][1]*dh1dh7_param[1][i]+Jinv[2][1]*dh1dh7_param[2][i]; 2763 *(dh1dh7_basic+numgrids*2+i)=Jinv[0][2]*dh1dh7_param[0][i]+Jinv[1][2]*dh1dh7_param[1][i]+Jinv[2][2]*dh1dh7_param[2][i]; 2764 } 2765 2766 } 2767 2768 2769 #undef __FUNCT__ 2770 #define __FUNCT__ "Penta::GetNodalFunctionsDerivativesParamsStokes" 2771 void Penta::GetNodalFunctionsDerivativesParamsStokes(double* dl1dl7,double* gauss_coord){ 2772 2773 /*This routine returns the values of the nodal functions derivatives (with respect to the 2774 * natural coordinate system) at the gaussian point. */ 2775 2776 double sqrt3=sqrt(3.0); 2777 int numgrids=7; //six plus bubble grids 2778 2779 double r=gauss_coord[1]-gauss_coord[0]; 2780 double s=-3.0/sqrt3*(gauss_coord[0]+gauss_coord[1]-2.0/3.0); 2781 double zeta=gauss_coord[3]; 2782 2783 /*First nodal function: */ 2784 *(dl1dl7+numgrids*0+0)=-1.0/2.0*(1.0-zeta)/2.0; 2785 *(dl1dl7+numgrids*1+0)=-sqrt3/6.0*(1.0-zeta)/2.0; 2786 *(dl1dl7+numgrids*2+0)=-1.0/2.0*(-1.0/2.0*r-sqrt3/6.0*s+1.0/3.0); 2787 2788 /*Second nodal function: */ 2789 *(dl1dl7+numgrids*0+1)=1.0/2.0*(1.0-zeta)/2.0; 2790 *(dl1dl7+numgrids*1+1)=-sqrt3/6.0*(1.0-zeta)/2.0; 2791 *(dl1dl7+numgrids*2+1)=-1.0/2.0*(1.0/2.0*r-sqrt3/6.0*s+1.0/3.0); 2792 2793 /*Third nodal function: */ 2794 *(dl1dl7+numgrids*0+2)=0; 2795 *(dl1dl7+numgrids*1+2)=sqrt3/3.0*(1.0-zeta)/2.0; 2796 *(dl1dl7+numgrids*2+2)=-1.0/2.0*(sqrt3/3.0*s+1.0/3.0); 2797 2798 /*Fourth nodal function: */ 2799 *(dl1dl7+numgrids*0+3)=-1.0/2.0*(1.0+zeta)/2.0; 2800 *(dl1dl7+numgrids*1+3)=-sqrt3/6.0*(1.0+zeta)/2.0; 2801 *(dl1dl7+numgrids*2+3)=1.0/2.0*(-1.0/2.0*r-sqrt3/6.0*s+1.0/3.0); 2802 2803 /*Fith nodal function: */ 2804 *(dl1dl7+numgrids*0+4)=1.0/2.0*(1.0+zeta)/2.0; 2805 *(dl1dl7+numgrids*1+4)=-sqrt3/6.0*(1.0+zeta)/2.0; 2806 *(dl1dl7+numgrids*2+4)=1.0/2.0*(1.0/2.0*r-sqrt3/6.0*s+1.0/3.0); 2807 2808 /*Sixth nodal function: */ 2809 *(dl1dl7+numgrids*0+5)=0; 2810 *(dl1dl7+numgrids*1+5)=sqrt3/3.0*(1.0+zeta)/2.0; 2811 *(dl1dl7+numgrids*2+5)=1.0/2.0*(sqrt3/3.0*s+1.0/3.0); 2812 2813 /*Seventh nodal function: */ 2814 *(dl1dl7+numgrids*0+6)=9.0/2.0*r*(1.0+zeta)*(zeta-1.0)*(sqrt3*s+1.0); 2815 *(dl1dl7+numgrids*1+6)=9.0/4.0*(1+zeta)*(1-zeta)*(sqrt3*pow(s,2.0)-2.0*s-sqrt3*pow(r,2.0)); 2816 *(dl1dl7+numgrids*2+6)=27*gauss_coord[0]*gauss_coord[1]*gauss_coord[2]*(-2.0*zeta); 2817 2818 } 2819 2820 #undef __FUNCT__ 2821 #define __FUNCT__ "Penta::CreatePVectorDiagnosticStokes" 2822 void Penta::CreatePVectorDiagnosticStokes( Vec pg, void* vinputs,int analysis_type){ 2823 2824 2825 /*indexing: */ 2826 int i,j; 2827 2828 int numgrids=6; 2829 int DOFPERGRID=4; 2830 int numdof=numgrids*DOFPERGRID; 2831 int numgrids2d=3; 2832 int numdof2d=numgrids2d*DOFPERGRID; 2833 int doflist[numdof]; 2834 int numberofdofspernode; 2835 2836 /*Material properties: */ 2837 double gravity,rho_ice,rho_water; 2838 2839 /*parameters: */ 2840 double xyz_list_tria[numgrids2d][3]; 2841 double xyz_list[numgrids][3]; 2842 double surface_normal[3]; 2843 double bed_normal[3]; 2844 double bed; 2845 double vxvyvz_list[numgrids][3]; 2846 2847 /* gaussian points: */ 2848 int num_area_gauss; 2849 int igarea,igvert; 2850 double* first_gauss_area_coord = NULL; 2851 double* second_gauss_area_coord = NULL; 2852 double* third_gauss_area_coord = NULL; 2853 double* vert_gauss_coord = NULL; 2854 double* area_gauss_weights = NULL; 2855 double* vert_gauss_weights = NULL; 2856 2857 /* specific gaussian point: */ 2858 double gauss_weight,area_gauss_weight,vert_gauss_weight; 2859 double gauss_coord[4]; 2860 double gauss_coord_tria[3]; 2861 2862 int area_order=5; 2863 int num_vert_gauss=5; 2864 2865 double epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/ 2866 double viscosity; 2867 double water_pressure; 2868 int dofs[3]={0,1,2}; 2869 2870 /*matrices: */ 2871 double Pe_temp[27]; //for the six nodes and the bubble 2872 double Pe_gaussian[27]; //for the six nodes and the bubble 2873 double Ke_temp[27][3]; //for the six nodes and the bubble 2874 double Pe_reduced[numdof]; //for the six nodes only 2875 double Ke_gaussian[27][3]; 2876 double L[3]; //for the three nodes of the bed 2877 double l1l7[7]; //for the six nodes and the bubble 2878 double B[8][27]; 2879 double B_prime[8][27]; 2880 double B_prime_bubble[8][3]; 2881 double Jdet; 2882 double Jdet2d; 2883 double D[8][8]={{ 0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0 }}; 2884 double D_scalar; 2885 double tBD[27][8]; 2886 double P_terms[numdof]; 2887 2888 ParameterInputs* inputs=NULL; 2889 Tria* tria=NULL; 2890 2891 /*recover pointers: */ 2892 inputs=(ParameterInputs*)vinputs; 2893 2894 /* Set P_terms to 0: */ 2895 for(i=0;i<numdof;i++){ 2896 P_terms[i]=0; 2897 } 2898 2899 /*recovre material parameters: */ 2900 rho_water=matpar->GetRhoWater(); 2901 rho_ice=matpar->GetRhoIce(); 2902 gravity=matpar->GetG(); 2903 2904 /*recover extra inputs from users, at current convergence iteration: */ 2905 inputs->Recover("velocity",&vxvyvz_list[0][0],3,dofs,numgrids,(void**)nodes); 2906 2907 /* Get node coordinates and dof list: */ 2908 GetElementNodeData( &xyz_list[0][0], nodes, numgrids); 2909 GetDofList(&doflist[0],&numberofdofspernode); 2910 2911 /*Initialize Ke_temp to zero befor adding terms */ 2912 for (i=0;i<27;i++){ 2913 Pe_temp[i]=0; 2914 for (j=0;j<3;j++){ 2915 Ke_temp[i][j]=0; 2916 } 2917 } 2918 2919 2920 2921 /* Get gaussian points and weights. Penta is an extrusion of a Tria, we therefore 2922 get tria gaussian points as well as segment gaussian points. For tria gaussian 2923 points, order of integration is 2, because we need to integrate the product tB*D*B' 2924 which is a polynomial of degree 3 (see GaussTria for more details). For segment gaussian 2925 points, same deal, which yields 3 gaussian points.*/ 2926 2927 2928 2929 /* Get gaussian points and weights (make this a statically initialized list of points? fstd): */ 2930 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); 2931 2932 /* Start looping on the number of gaussian points: */ 2933 for (igarea=0; igarea<num_area_gauss; igarea++){ 2934 for (igvert=0; igvert<num_vert_gauss; igvert++){ 2935 /*Pick up the gaussian point: */ 2936 area_gauss_weight=*(area_gauss_weights+igarea); 2937 vert_gauss_weight=*(vert_gauss_weights+igvert); 2938 gauss_weight=area_gauss_weight*vert_gauss_weight; 2939 gauss_coord[0]=*(first_gauss_area_coord+igarea); 2940 gauss_coord[1]=*(second_gauss_area_coord+igarea); 2941 gauss_coord[2]=*(third_gauss_area_coord+igarea); 2942 gauss_coord[3]=*(vert_gauss_coord+igvert); 2943 2944 /*Compute strain rate and viscosity: */ 2945 GetStrainRateStokes(&epsilon[0],&vxvyvz_list[0][0],&xyz_list[0][0],gauss_coord); 2946 matice->GetViscosity3dStokes(&viscosity,&epsilon[0]); 2947 2948 /* Get Jacobian determinant: */ 2949 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss_coord); 2950 2951 /* Get nodal functions */ 2952 GetNodalFunctionsStokes(&l1l7[0], gauss_coord); 2953 2954 /* Build gaussian vector */ 2955 for(i=0;i<numgrids+1;i++){ 2956 Pe_gaussian[i*DOFPERGRID+2]=-rho_ice*gravity*Jdet*gauss_weight*l1l7[i]; 2957 } 2958 2959 /*Add Pe_gaussian to terms in Pe_temp. Watch out for column orientation from matlab: */ 2960 for(i=0;i<27;i++){ 2961 Pe_temp[i]+=Pe_gaussian[i]; 2962 } 2963 2964 /*Get B and Bprime matrices: */ 2965 GetBStokes(&B[0][0],&xyz_list[0][0],gauss_coord); 2966 GetBprimeStokes(&B_prime[0][0],&xyz_list[0][0], gauss_coord); 2967 2968 /*Get bubble part of Bprime */ 2969 for(i=0;i<8;i++){ 2970 for(j=0;j<3;j++){ 2971 B_prime_bubble[i][j]=B_prime[i][j+24]; 2972 } 2973 } 2974 2975 /* Build the D matrix: we plug the gaussian weight, the thickness, the viscosity, and the jacobian determinant 2976 * onto this scalar matrix, so that we win some computational time: */ 2977 D_scalar=gauss_weight*Jdet; 2978 for (i=0;i<6;i++){ 2979 D[i][i]=D_scalar*viscosity; 2980 } 2981 for (i=6;i<8;i++){ 2982 D[i][i]=-D_scalar*stokesreconditioning; 2983 } 2984 2985 /* Do the triple product tB*D*Bprime: */ 2986 MatrixMultiply(&B[0][0],8,27,1,&D[0][0],8,8,0,&tBD[0][0],0); 2987 MatrixMultiply(&tBD[0][0],27,8,0,&B_prime_bubble[0][0],8,3,0,&Ke_gaussian[0][0],0); 2988 2989 /*Add Ke_gaussian and Ke_gaussian to terms in pKe. Watch out for column orientation from matlab: */ 2990 for(i=0;i<27;i++){ 2991 for(j=0;j<3;j++){ 2992 Ke_temp[i][j]+=Ke_gaussian[i][j]; 2993 } 2994 } 2995 } 2996 } 2997 2998 2999 /*Deal with 2d friction at the bedrock interface: */ 3000 if ( (onbed==1) && (shelf==1)){ 3001 3002 for(i=0;i<numgrids2d;i++){ 3003 for(j=0;j<3;j++){ 3004 xyz_list_tria[i][j]=xyz_list[i][j]; 3005 } 3006 } 3007 3008 GaussTria (&num_area_gauss, &first_gauss_area_coord, &second_gauss_area_coord, &third_gauss_area_coord, &area_gauss_weights, 2); 3009 3010 /* Start looping on the number of gauss 2d (nodes on the bedrock) */ 3011 for (igarea=0; igarea<num_area_gauss; igarea++){ 3012 gauss_weight=*(area_gauss_weights+igarea); 3013 gauss_coord[0]=*(first_gauss_area_coord+igarea); 3014 gauss_coord[1]=*(second_gauss_area_coord+igarea); 3015 gauss_coord[2]=*(third_gauss_area_coord+igarea); 3016 gauss_coord[3]=-1; 3017 3018 gauss_coord_tria[0]=*(first_gauss_area_coord+igarea); 3019 gauss_coord_tria[1]=*(second_gauss_area_coord+igarea); 3020 gauss_coord_tria[2]=*(third_gauss_area_coord+igarea); 3021 3022 3023 /*Get the Jacobian determinant */ 3024 tria->GetJacobianDeterminant3d(&Jdet2d, &xyz_list_tria[0][0], gauss_coord_tria); 3025 3026 /* Get bed at gaussian point */ 3027 GetParameterValue(&bed,&b[0],gauss_coord); 3028 3029 /*Get L matrix : */ 3030 tria->GetL(&L[0], &xyz_list[0][0], gauss_coord_tria,1); 3031 3032 /*Get water_pressure at gaussian point */ 3033 water_pressure=gravity*rho_water*bed; 3034 3035 /*Get normal vecyor to the bed */ 3036 SurfaceNormal(&surface_normal[0],xyz_list_tria); 3037 3038 bed_normal[0]=-surface_normal[0]; //Program is for surface, so the normal to the bed is the opposite of the result 3039 bed_normal[1]=-surface_normal[1]; 3040 bed_normal[2]=-surface_normal[2]; 3041 3042 for(i=0;i<numgrids2d;i++){ 3043 for(j=0;j<3;j++){ 3044 Pe_temp[i*DOFPERGRID+j]+=water_pressure*gauss_weight*Jdet2d*L[i]*bed_normal[j]; 3045 } 3046 } 3047 } 3048 } //if ( (onbed==1) && (shelf==1)) 3049 3050 /*Reduce the matrix */ 3051 ReduceVectorStokes(&Pe_reduced[0], &Ke_temp[0][0], &Pe_temp[0]); 3052 3053 for(i=0;i<numdof;i++){ 3054 P_terms[i]+=Pe_reduced[i]; 3055 } 3056 3057 3058 /*Add P_terms to global vector pg: */ 3059 VecSetValues(pg,numdof,doflist,(const double*)P_terms,ADD_VALUES); 3060 3061 } 3062 3063 #undef __FUNCT__ 3064 #define __FUNCT__ "Penta::ReduceVectorStokes" 3065 void Penta::ReduceVectorStokes(double* Pe_reduced, double* Ke_temp, double* Pe_temp){ 3066 3067 int i,j; 3068 3069 double Pi[24]; 3070 double Pb[3]; 3071 double Kbb[3][3]; 3072 double Kib[24][3]; 3073 double Kbbinv[3][3]; 3074 double KibKbbinv[24][3]; 3075 double Pright[24]; 3076 3077 /*Create the four matrices used for reduction */ 3078 for(i=0;i<24;i++){ 3079 Pi[i]=*(Pe_temp+i); 3080 } 3081 for(i=0;i<3;i++){ 3082 Pb[i]=*(Pe_temp+i+24); 3083 } 3084 for(j=0;j<3;j++){ 3085 for(i=0;i<24;i++){ 3086 Kib[i][j]=*(Ke_temp+3*i+j); 3087 } 3088 for(i=0;i<3;i++){ 3089 Kbb[i][j]=*(Ke_temp+3*(i+24)+j); 3090 } 3091 } 3092 3093 /*Inverse the matrix corresponding to bubble part Kbb */ 3094 GetMatrixInvert(&Kbbinv[0][0], &Kbb[0][0]); 3095 3096 /*Multiply matrices to create the reduce matrix Ke_reduced */ 3097 MatrixMultiply(&Kib[0][0],24,3,0,&Kbbinv[0][0],3,3,0,&KibKbbinv[0][0],0); 3098 MatrixMultiply(&KibKbbinv[0][0],24,3,0,&Pb[0],3,1,0,&Pright[0],0); 3099 3100 /*Affect value to the reduced matrix */ 3101 for(i=0;i<24;i++){ 3102 *(Pe_reduced+i)=Pi[i]-Pright[i]; 3103 } 3104 } 3105 3106 #undef __FUNCT__ 3107 #define __FUNCT__ "Penta::GetNodalFunctionsStokes" 3108 void Penta::GetNodalFunctionsStokes(double* l1l7, double* gauss_coord){ 3109 3110 /*This routine returns the values of the nodal functions at the gaussian point.*/ 3111 3112 /*First nodal function: */ 3113 l1l7[0]=gauss_coord[0]*(1.0-gauss_coord[3])/2.0; 3114 3115 /*Second nodal function: */ 3116 l1l7[1]=gauss_coord[1]*(1.0-gauss_coord[3])/2.0; 3117 3118 /*Third nodal function: */ 3119 l1l7[2]=gauss_coord[2]*(1.0-gauss_coord[3])/2.0; 3120 3121 /*Fourth nodal function: */ 3122 l1l7[3]=gauss_coord[0]*(1.0+gauss_coord[3])/2.0; 3123 3124 /*Fifth nodal function: */ 3125 l1l7[4]=gauss_coord[1]*(1.0+gauss_coord[3])/2.0; 3126 3127 /*Sixth nodal function: */ 3128 l1l7[5]=gauss_coord[2]*(1.0+gauss_coord[3])/2.0; 3129 3130 /*Seventh nodal function: */ 3131 l1l7[6]=27*gauss_coord[0]*gauss_coord[1]*gauss_coord[2]*(1.0+gauss_coord[3])*(1.0-gauss_coord[3]); 3132 3133 } -
issm/trunk/src/c/objects/Penta.h
r387 r394 116 116 void CreatePVectorSlopeCompute( Vec pg, void* vinputs, int analysis_type); 117 117 118 void CreateKMatrixDiagnosticStokes( Mat Kgg, void* vinputs, int analysis_type); 119 void CreatePVectorDiagnosticStokes( Vec pg, void* vinputs,int analysis_type); 120 void ReduceMatrixStokes(double* Ke_reduced, double* Ke_temp); 121 void GetMatrixInvert(double* Ke_invert, double* Ke); 122 void SurfaceNormal(double* surface_normal, double xyz_list[3][3]); 123 void GetStrainRateStokes(double* epsilon, double* velocity, double* xyz_list, double* gauss_coord); 124 void GetBStokes(double* B, double* xyz_list, double* gauss_coord); 125 void GetBprimeStokes(double* B_prime, double* xyz_list, double* gauss_coord); 126 void GetLStokes(double* LStokes, double* gauss_coord_tria); 127 void GetLprimeStokes(double* LprimeStokes, double* xyz_list, double* gauss_coord_tria, double* gauss_coord); 128 void GetNodalFunctionsDerivativesBasicStokes(double* dh1dh7_basic,double* xyz_list, double* gauss_coord); 129 void GetNodalFunctionsDerivativesParamsStokes(double* dl1dl7,double* gauss_coord); 130 void ReduceVectorStokes(double* Pe_reduced, double* Ke_temp, double* Pe_temp); 131 void GetNodalFunctionsStokes(double* l1l7, double* gauss_coord); 132 118 133 119 134 }; -
issm/trunk/src/m/solutions/cielo/diagnostic_core.m
r387 r394 42 42 43 43 end 44 44 45 45 if ismacayealpattyn, 46 46 … … 83 83 inputs=add(inputs,'bedslopey',slopey,'doublevec',m_sl.parameters.numberofdofspernode,m_sl.parameters.numberofnodes); 84 84 85 inputs=add(inputs,'velocity',u_g,'doublevec',m_dh.parameters.numberofdofspernode,m_dh.parameters.numberofnodes); 86 inputs=add(inputs,'pressure',p_g,'doublevec',1,m_dh.parameters.numberofnodes); 85 %recombine u_g and p_g: 86 u_g_stokes=zeros(m_ds.nodesets.gsize,1); 87 u_g_stokes(dofsetgen([1,2,3],4,m_ds.nodesets.gsize))=u_g; 88 u_g_stokes(dofsetgen([4],4,m_ds.nodesets.gsize))=p_g; 89 90 inputs=add(inputs,'velocity',u_g_stokes,'doublevec',4,m_ds.parameters.numberofnodes); 87 91 88 92 displaystring(debug,'\n%s',['update boundary conditions for stokes using velocities previously computed...']); 89 m_ds.y_g(dofsetgen([1,2],4,m_ds.parameters.gsize))=u_g; 90 m_ds.y_g(dofsetgen([3],4,m_ds.parameters.gsize))=u_g_vert; 93 m_ds.y_g(dofsetgen([1,2,3],4,m_ds.nodesets.gsize))=u_g; 91 94 [m_ds.ys m_ds.ys0]=Reducevectorgtos(m_ds.y_g,m_ds.nodesets); 92 95 -
issm/trunk/src/m/solutions/cielo/diagnostic_core_nonlinear.m
r370 r394 12 12 converged=0; 13 13 14 soln(count).u_g=get(inputs,'velocity',[1 1 (m.parameters.numberofdofspernode>=3) ]); %only keep vz if running with more than 3 dofs per node14 soln(count).u_g=get(inputs,'velocity',[1 1 (m.parameters.numberofdofspernode>=3) (m.parameters.numberofdofspernode>=3)]); %only keep vz if running with more than 3 dofs per node 15 15 soln(count).u_f=[]; 16 16 -
issm/trunk/src/mex/ModelProcessor/ModelProcessor.cpp
r209 r394 39 39 /*Create loads: */ 40 40 CreateLoads(&loads,model,MODEL); 41 42 41 /*Create parameters: */ 43 42 CreateParameters(¶meters,model,MODEL);
Note:
See TracChangeset
for help on using the changeset viewer.