Changeset 16993
- Timestamp:
- 12/03/13 10:36:26 (11 years ago)
- Location:
- issm/trunk-jpl/src/c
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/c/analyses/StressbalanceAnalysis.cpp
r16992 r16993 813 813 /*Finite Element Analysis*/ 814 814 ElementMatrix* StressbalanceAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/ 815 _error_("Not implemented"); 815 816 int approximation; 817 element->GetInputValue(&approximation,ApproximationEnum); 818 switch(approximation){ 819 case SSAApproximationEnum: 820 return CreateJacobianMatrixSSA(element); 821 case HOApproximationEnum: 822 return CreateJacobianMatrixHO(element); 823 case FSApproximationEnum: 824 return CreateJacobianMatrixFS(element); 825 case NoneApproximationEnum: 826 return NULL; 827 default: 828 _error_("Approximation "<<EnumToStringx(approximation)<<" not supported"); 829 } 816 830 }/*}}}*/ 817 831 ElementMatrix* StressbalanceAnalysis::CreateKMatrix(Element* element){/*{{{*/ … … 961 975 962 976 /*SSA*/ 977 ElementMatrix* StressbalanceAnalysis::CreateJacobianMatrixSSA(Element* element){/*{{{*/ 978 979 /*Intermediaries*/ 980 int meshtype; 981 Element* basalelement; 982 983 /*Get basal element*/ 984 element->FindParam(&meshtype,MeshTypeEnum); 985 switch(meshtype){ 986 case Mesh2DhorizontalEnum: 987 basalelement = element; 988 break; 989 case Mesh3DEnum: 990 if(!element->IsOnBed()) return NULL; 991 basalelement = element->SpawnBasalElement(); 992 break; 993 default: _error_("mesh "<<EnumToStringx(meshtype)<<" not supported yet"); 994 } 995 996 /*Intermediaries */ 997 IssmDouble Jdet,thickness; 998 IssmDouble eps1dotdphii,eps1dotdphij; 999 IssmDouble eps2dotdphii,eps2dotdphij; 1000 IssmDouble mu_prime; 1001 IssmDouble epsilon[3];/* epsilon=[exx,eyy,exy];*/ 1002 IssmDouble eps1[2],eps2[2]; 1003 IssmDouble *xyz_list = NULL; 1004 1005 /*Fetch number of nodes and dof for this finite element*/ 1006 int numnodes = basalelement->GetNumberOfNodes(); 1007 1008 /*Initialize Element matrix, vectors and Gaussian points*/ 1009 ElementMatrix* Ke=this->CreateKMatrixSSA(element); //Initialize Jacobian with regular SSA (first part of the Gateau derivative) 1010 IssmDouble* dbasis = xNew<IssmDouble>(2*numnodes); 1011 1012 /*Retrieve all inputs and parameters*/ 1013 element->GetVerticesCoordinates(&xyz_list); 1014 Input* thickness_input = basalelement->GetInput(ThicknessEnum);_assert_(thickness_input); 1015 Input* vx_input = basalelement->GetInput(VxEnum); _assert_(vx_input); 1016 Input* vy_input = basalelement->GetInput(VyEnum); _assert_(vy_input); 1017 1018 /* Start looping on the number of gaussian points: */ 1019 Gauss* gauss = basalelement->NewGauss(2); 1020 for(int ig=gauss->begin();ig<gauss->end();ig++){ 1021 gauss->GaussPoint(ig); 1022 1023 basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss); 1024 basalelement->NodalFunctionsDerivatives(dbasis,xyz_list,gauss); 1025 1026 thickness_input->GetInputValue(&thickness, gauss); 1027 basalelement->StrainRateSSA(&epsilon[0],xyz_list,gauss,vx_input,vy_input); 1028 basalelement->ViscositySSADerivativeEpsSquare(&mu_prime,&epsilon[0]); 1029 eps1[0]=2*epsilon[0]+epsilon[1]; eps2[0]=epsilon[2]; 1030 eps1[1]=epsilon[2]; eps2[1]=epsilon[0]+2*epsilon[1]; 1031 1032 for(int i=0;i<numnodes;i++){ 1033 for(int j=0;j<numnodes;j++){ 1034 eps1dotdphii=eps1[0]*dbasis[0*numnodes+i]+eps1[1]*dbasis[1*numnodes+i]; 1035 eps1dotdphij=eps1[0]*dbasis[0*numnodes+j]+eps1[1]*dbasis[1*numnodes+j]; 1036 eps2dotdphii=eps2[0]*dbasis[0*numnodes+i]+eps2[1]*dbasis[1*numnodes+i]; 1037 eps2dotdphij=eps2[0]*dbasis[0*numnodes+j]+eps2[1]*dbasis[1*numnodes+j]; 1038 1039 Ke->values[2*numnodes*(2*i+0)+2*j+0]+=gauss->weight*Jdet*2.*mu_prime*thickness*eps1dotdphij*eps1dotdphii; 1040 Ke->values[2*numnodes*(2*i+0)+2*j+1]+=gauss->weight*Jdet*2.*mu_prime*thickness*eps2dotdphij*eps1dotdphii; 1041 Ke->values[2*numnodes*(2*i+1)+2*j+0]+=gauss->weight*Jdet*2.*mu_prime*thickness*eps1dotdphij*eps2dotdphii; 1042 Ke->values[2*numnodes*(2*i+1)+2*j+1]+=gauss->weight*Jdet*2.*mu_prime*thickness*eps2dotdphij*eps2dotdphii; 1043 } 1044 } 1045 } 1046 1047 /*Transform Coordinate System*/ 1048 basalelement->TransformStiffnessMatrixCoord(Ke,XYEnum); 1049 1050 /*Clean up and return*/ 1051 delete gauss; 1052 xDelete<IssmDouble>(xyz_list); 1053 xDelete<IssmDouble>(dbasis); 1054 1055 /*clean-up and return*/ 1056 if(meshtype!=Mesh2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;}; 1057 return Ke; 1058 1059 }/*}}}*/ 963 1060 ElementMatrix* StressbalanceAnalysis::CreateKMatrixSSA(Element* element){/*{{{*/ 964 1061 … … 1778 1875 1779 1876 /*HO*/ 1877 ElementMatrix* StressbalanceAnalysis::CreateJacobianMatrixHO(Element* element){/*{{{*/ 1878 1879 /*Intermediaries */ 1880 IssmDouble Jdet; 1881 IssmDouble eps1dotdphii,eps1dotdphij; 1882 IssmDouble eps2dotdphii,eps2dotdphij; 1883 IssmDouble mu_prime; 1884 IssmDouble epsilon[5]; /* epsilon=[exx,eyy,exy,exz,eyz];*/ 1885 IssmDouble eps1[3],eps2[3]; 1886 IssmDouble *xyz_list = NULL; 1887 1888 /*Fetch number of nodes and dof for this finite element*/ 1889 int numnodes = element->GetNumberOfNodes(); 1890 1891 /*Initialize Element matrix, vectors and Gaussian points*/ 1892 ElementMatrix* Ke=this->CreateKMatrixHO(element); //Initialize Jacobian with regular HO (first part of the Gateau derivative) 1893 IssmDouble* dbasis = xNew<IssmDouble>(3*numnodes); 1894 1895 /*Retrieve all inputs and parameters*/ 1896 element->GetVerticesCoordinates(&xyz_list); 1897 Input* vx_input = element->GetInput(VxEnum); _assert_(vx_input); 1898 Input* vy_input = element->GetInput(VyEnum); _assert_(vy_input); 1899 1900 /* Start looping on the number of gaussian points: */ 1901 Gauss* gauss = element->NewGauss(5); 1902 for(int ig=gauss->begin();ig<gauss->end();ig++){ 1903 gauss->GaussPoint(ig); 1904 1905 element->JacobianDeterminant(&Jdet,xyz_list,gauss); 1906 element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss); 1907 1908 element->StrainRateHO(&epsilon[0],xyz_list,gauss,vx_input,vy_input); 1909 element->ViscosityHODerivativeEpsSquare(&mu_prime,&epsilon[0]); 1910 eps1[0]=2*epsilon[0]+epsilon[1]; eps2[0]=epsilon[2]; 1911 eps1[1]=epsilon[2]; eps2[1]=epsilon[0]+2*epsilon[1]; 1912 eps1[2]=epsilon[3]; eps2[2]=epsilon[4]; 1913 1914 for(int i=0;i<numnodes;i++){ 1915 for(int j=0;j<numnodes;j++){ 1916 eps1dotdphii=eps1[0]*dbasis[0*numnodes+i]+eps1[1]*dbasis[1*numnodes+i]+eps1[2]*dbasis[2*numnodes+i]; 1917 eps1dotdphij=eps1[0]*dbasis[0*numnodes+j]+eps1[1]*dbasis[1*numnodes+j]+eps1[2]*dbasis[2*numnodes+j]; 1918 eps2dotdphii=eps2[0]*dbasis[0*numnodes+i]+eps2[1]*dbasis[1*numnodes+i]+eps2[2]*dbasis[2*numnodes+i]; 1919 eps2dotdphij=eps2[0]*dbasis[0*numnodes+j]+eps2[1]*dbasis[1*numnodes+j]+eps2[2]*dbasis[2*numnodes+j]; 1920 1921 Ke->values[2*numnodes*(2*i+0)+2*j+0]+=gauss->weight*Jdet*2.*mu_prime*eps1dotdphij*eps1dotdphii; 1922 Ke->values[2*numnodes*(2*i+0)+2*j+1]+=gauss->weight*Jdet*2.*mu_prime*eps2dotdphij*eps1dotdphii; 1923 Ke->values[2*numnodes*(2*i+1)+2*j+0]+=gauss->weight*Jdet*2.*mu_prime*eps1dotdphij*eps2dotdphii; 1924 Ke->values[2*numnodes*(2*i+1)+2*j+1]+=gauss->weight*Jdet*2.*mu_prime*eps2dotdphij*eps2dotdphii; 1925 } 1926 } 1927 } 1928 1929 /*Transform Coordinate System*/ 1930 element->TransformStiffnessMatrixCoord(Ke,XYEnum); 1931 1932 /*Clean up and return*/ 1933 delete gauss; 1934 xDelete<IssmDouble>(xyz_list); 1935 xDelete<IssmDouble>(dbasis); 1936 return Ke; 1937 }/*}}}*/ 1780 1938 ElementMatrix* StressbalanceAnalysis::CreateKMatrixHO(Element* element){/*{{{*/ 1781 1939 … … 2219 2377 2220 2378 /*FS*/ 2379 ElementMatrix* StressbalanceAnalysis::CreateJacobianMatrixFS(Element* element){/*{{{*/ 2380 2381 /*Intermediaries */ 2382 int i,j; 2383 IssmDouble Jdet; 2384 IssmDouble eps1dotdphii,eps1dotdphij; 2385 IssmDouble eps2dotdphii,eps2dotdphij; 2386 IssmDouble eps3dotdphii,eps3dotdphij; 2387 IssmDouble mu_prime; 2388 IssmDouble epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/ 2389 IssmDouble eps1[3],eps2[3],eps3[3]; 2390 IssmDouble *xyz_list = NULL; 2391 2392 /*Fetch number of nodes and dof for this finite element*/ 2393 int vnumnodes = element->GetNumberOfNodesVelocity(); 2394 int pnumnodes = element->GetNumberOfNodesPressure(); 2395 int numdof = vnumnodes*NDOF3 + pnumnodes*NDOF1; 2396 2397 /*Prepare coordinate system list*/ 2398 int* cs_list = xNew<int>(vnumnodes+pnumnodes); 2399 for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum; 2400 for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum; 2401 2402 /*Initialize Element matrix, vectors and Gaussian points*/ 2403 ElementMatrix* Ke=this->CreateKMatrixFS(element); //Initialize Jacobian with regular FS (first part of the Gateau derivative) 2404 IssmDouble* dbasis = xNew<IssmDouble>(3*vnumnodes); 2405 2406 /*Retrieve all inputs and parameters*/ 2407 element->GetVerticesCoordinates(&xyz_list); 2408 Input* vx_input = element->GetInput(VxEnum); _assert_(vx_input); 2409 Input* vy_input = element->GetInput(VyEnum); _assert_(vy_input); 2410 Input* vz_input = element->GetInput(VzEnum); _assert_(vz_input); 2411 2412 /* Start looping on the number of gaussian points: */ 2413 Gauss* gauss = element->NewGauss(5); 2414 for(int ig=gauss->begin();ig<gauss->end();ig++){ 2415 gauss->GaussPoint(ig); 2416 2417 element->JacobianDeterminant(&Jdet,xyz_list,gauss); 2418 element->NodalFunctionsDerivativesVelocity(dbasis,xyz_list,gauss); 2419 2420 //element->StrainRateFS(&epsilon[0],xyz_list,gauss,vx_input,vy_input,vz_input); 2421 //eps1[0]=epsilon[0]; eps2[0]=epsilon[3]; eps3[0]=epsilon[4]; 2422 //eps1[1]=epsilon[3]; eps2[1]=epsilon[1]; eps3[1]=epsilon[5]; 2423 //eps1[2]=epsilon[4]; eps2[2]=epsilon[5]; eps3[2]=epsilon[2]; 2424 element->StrainRateHO(&epsilon[0],xyz_list,gauss,vx_input,vy_input); 2425 eps1[0]=epsilon[0]; eps2[0]=epsilon[2]; eps3[0]=epsilon[3]; 2426 eps1[1]=epsilon[2]; eps2[1]=epsilon[1]; eps3[1]=epsilon[4]; 2427 eps1[2]=epsilon[3]; eps2[2]=epsilon[4]; eps3[2]= -epsilon[0] -epsilon[1]; 2428 element->ViscosityFSDerivativeEpsSquare(&mu_prime,&epsilon[0]); 2429 2430 for(i=0;i<vnumnodes;i++){ 2431 for(j=0;j<vnumnodes;j++){ 2432 eps1dotdphii=eps1[0]*dbasis[0*vnumnodes+i]+eps1[1]*dbasis[1*vnumnodes+i]+eps1[2]*dbasis[2*vnumnodes+i]; 2433 eps1dotdphij=eps1[0]*dbasis[0*vnumnodes+j]+eps1[1]*dbasis[1*vnumnodes+j]+eps1[2]*dbasis[2*vnumnodes+j]; 2434 eps2dotdphii=eps2[0]*dbasis[0*vnumnodes+i]+eps2[1]*dbasis[1*vnumnodes+i]+eps2[2]*dbasis[2*vnumnodes+i]; 2435 eps2dotdphij=eps2[0]*dbasis[0*vnumnodes+j]+eps2[1]*dbasis[1*vnumnodes+j]+eps2[2]*dbasis[2*vnumnodes+j]; 2436 eps3dotdphii=eps3[0]*dbasis[0*vnumnodes+i]+eps3[1]*dbasis[1*vnumnodes+i]+eps3[2]*dbasis[2*vnumnodes+i]; 2437 eps3dotdphij=eps3[0]*dbasis[0*vnumnodes+j]+eps3[1]*dbasis[1*vnumnodes+j]+eps3[2]*dbasis[2*vnumnodes+j]; 2438 2439 Ke->values[numdof*(3*i+0)+3*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps1dotdphii; 2440 Ke->values[numdof*(3*i+0)+3*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps1dotdphii; 2441 Ke->values[numdof*(3*i+0)+3*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps1dotdphii; 2442 2443 Ke->values[numdof*(3*i+1)+3*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps2dotdphii; 2444 Ke->values[numdof*(3*i+1)+3*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps2dotdphii; 2445 Ke->values[numdof*(3*i+1)+3*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps2dotdphii; 2446 2447 Ke->values[numdof*(3*i+2)+3*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps3dotdphii; 2448 Ke->values[numdof*(3*i+2)+3*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps3dotdphii; 2449 Ke->values[numdof*(3*i+2)+3*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps3dotdphii; 2450 } 2451 } 2452 } 2453 2454 /*Transform Coordinate System*/ 2455 element->TransformStiffnessMatrixCoord(Ke,cs_list); 2456 2457 /*Clean up and return*/ 2458 delete gauss; 2459 xDelete<IssmDouble>(xyz_list); 2460 xDelete<IssmDouble>(dbasis); 2461 xDelete<int>(cs_list); 2462 return Ke; 2463 }/*}}}*/ 2221 2464 ElementMatrix* StressbalanceAnalysis::CreateKMatrixFS(Element* element){/*{{{*/ 2222 2465 -
issm/trunk-jpl/src/c/analyses/StressbalanceAnalysis.h
r16992 r16993 29 29 30 30 /*SSA*/ 31 ElementMatrix* CreateJacobianMatrixSSA(Element* element); 31 32 ElementMatrix* CreateKMatrixSSA(Element* element); 32 33 ElementMatrix* CreateKMatrixSSAViscous(Element* element); … … 48 49 void InputUpdateFromSolutionL1L2(IssmDouble* solution,Element* element); 49 50 /*HO*/ 51 ElementMatrix* CreateJacobianMatrixHO(Element* element); 50 52 ElementMatrix* CreateKMatrixHO(Element* element); 51 53 ElementMatrix* CreateKMatrixHOViscous(Element* element); … … 59 61 void InputUpdateFromSolutionHO(IssmDouble* solution,Element* element); 60 62 /*FS*/ 63 ElementMatrix* CreateJacobianMatrixFS(Element* element); 61 64 ElementMatrix* CreateKMatrixFS(Element* element); 62 65 ElementMatrix* CreateKMatrixFSViscous(Element* element); -
issm/trunk-jpl/src/c/classes/Elements/Element.h
r16982 r16993 104 104 virtual void SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Materials* materials,Parameters* parameters)=0; 105 105 virtual void SetwiseNodeConnectivity(int* d_nz,int* o_nz,Node* node,bool* flags,int* flagsindices,int set1_enum,int set2_enum)=0; 106 virtual ElementMatrix* CreateKMatrix(void)=0;107 106 virtual void CreateDVector(Vector<IssmDouble>* df)=0; 108 virtual void CreateJacobianMatrix(Matrix<IssmDouble>* Jff)=0;109 107 virtual void ElementSizes(IssmDouble* phx,IssmDouble* phy,IssmDouble* phz)=0; 110 108 virtual void EnthalpyToThermal(IssmDouble* ptemperature,IssmDouble* pwaterfraction,IssmDouble enthalpy,IssmDouble pressure)=0; -
issm/trunk-jpl/src/c/classes/Elements/Penta.cpp
r16982 r16993 379 379 } 380 380 /*}}}*/ 381 /*FUNCTION Penta::CreateKMatrix(void){{{*/382 ElementMatrix* Penta::CreateKMatrix(void){383 384 /*retrieve parameters: */385 int analysis_type;386 parameters->FindParam(&analysis_type,AnalysisTypeEnum);387 388 /*Checks in debugging {{{*/389 _assert_(this->nodes && this->material && this->matpar && this->verticalneighbors && this->parameters && this->inputs);390 /*}}}*/391 392 /*Skip if water element*/393 if(NoIceInElement()) return NULL;394 395 /*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */396 switch(analysis_type){397 #ifdef _HAVE_STRESSBALANCE_398 case StressbalanceAnalysisEnum:399 return CreateKMatrixStressbalanceHoriz();400 break;401 case AdjointHorizAnalysisEnum:402 return CreateKMatrixAdjointHoriz();403 break;404 case StressbalanceSIAAnalysisEnum:405 return CreateKMatrixStressbalanceSIA();406 break;407 case StressbalanceVerticalAnalysisEnum:408 return CreateKMatrixStressbalanceVert();409 break;410 #endif411 case L2ProjectionBaseAnalysisEnum:412 return CreateBasalMassMatrix();413 break;414 case MasstransportAnalysisEnum:415 return CreateKMatrixMasstransport();416 break;417 case FreeSurfaceTopAnalysisEnum:418 return CreateKMatrixFreeSurfaceTop();419 break;420 case FreeSurfaceBaseAnalysisEnum:421 return CreateKMatrixFreeSurfaceBase();422 break;423 #ifdef _HAVE_BALANCED_424 case BalancethicknessAnalysisEnum:425 return CreateKMatrixBalancethickness();426 break;427 #endif428 #ifdef _HAVE_THERMAL_429 case ThermalAnalysisEnum:430 return CreateKMatrixThermal();431 break;432 case EnthalpyAnalysisEnum:433 return CreateKMatrixEnthalpy();434 break;435 case MeltingAnalysisEnum:436 return CreateKMatrixMelting();437 break;438 #endif439 #ifdef _HAVE_HYDROLOGY_440 case HydrologyDCInefficientAnalysisEnum:441 return CreateKMatrixHydrologyDCInefficient();442 break;443 case HydrologyDCEfficientAnalysisEnum:444 return CreateKMatrixHydrologyDCEfficient();445 break;446 case L2ProjectionEPLAnalysisEnum:447 return CreateEPLDomainMassMatrix();448 break;449 #endif450 default:451 _error_("analysis " << EnumToStringx(analysis_type) << " not supported yet");452 }453 454 /*Make compiler happy*/455 return NULL;456 }457 /*}}}*/458 /*FUNCTION Penta::CreateKMatrixMasstransport {{{*/459 ElementMatrix* Penta::CreateKMatrixMasstransport(void){460 461 if (!IsOnBed()) return NULL;462 463 /*Depth Averaging Vx and Vy*/464 this->InputDepthAverageAtBase(VxEnum,VxAverageEnum);465 this->InputDepthAverageAtBase(VyEnum,VyAverageEnum);466 467 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.468 ElementMatrix* Ke=tria->CreateKMatrixMasstransport();469 delete tria->material; delete tria;470 471 /*Delete Vx and Vy averaged*/472 this->inputs->DeleteInput(VxAverageEnum);473 this->inputs->DeleteInput(VyAverageEnum);474 475 /*clean up and return*/476 return Ke;477 }478 /*}}}*/479 /*FUNCTION Penta::CreateKMatrixFreeSurfaceTop {{{*/480 ElementMatrix* Penta::CreateKMatrixFreeSurfaceTop(void){481 482 if(!IsOnSurface()) return NULL;483 484 Tria* tria=(Tria*)SpawnTria(1); //lower face is 0, upper face is 1.485 ElementMatrix* Ke=tria->CreateKMatrixFreeSurfaceTop();486 delete tria->material; delete tria;487 488 /*clean up and return*/489 return Ke;490 }491 /*}}}*/492 /*FUNCTION Penta::CreateKMatrixFreeSurfaceBase {{{*/493 ElementMatrix* Penta::CreateKMatrixFreeSurfaceBase(void){494 495 if(!IsOnBed()) return NULL;496 497 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.498 ElementMatrix* Ke=tria->CreateKMatrixFreeSurfaceBase();499 delete tria->material; delete tria;500 501 /*clean up and return*/502 return Ke;503 }504 /*}}}*/505 /*FUNCTION Penta::CreateBasalMassMatrix{{{*/506 ElementMatrix* Penta::CreateBasalMassMatrix(void){507 508 if (!IsOnBed()) return NULL;509 510 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.511 ElementMatrix* Ke=tria->CreateMassMatrix();512 delete tria->material; delete tria;513 514 /*clean up and return*/515 return Ke;516 }517 /*}}}*/518 381 /*FUNCTION Penta::CreateDVector {{{*/ 519 382 void Penta::CreateDVector(Vector<IssmDouble>* df){ … … 539 402 De->InsertIntoGlobal(df); 540 403 delete De; 541 }542 }543 /*}}}*/544 /*FUNCTION Penta::CreateJacobianMatrix{{{*/545 void Penta::CreateJacobianMatrix(Matrix<IssmDouble>* Jff){546 547 /*retrieve parameters: */548 ElementMatrix* Ke=NULL;549 int analysis_type;550 parameters->FindParam(&analysis_type,AnalysisTypeEnum);551 552 /*Checks in debugging {{{*/553 _assert_(this->nodes && this->material && this->matpar && this->verticalneighbors && this->parameters && this->inputs);554 /*}}}*/555 556 /*Skip if water element*/557 if(NoIceInElement()) return;558 559 /*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */560 switch(analysis_type){561 #ifdef _HAVE_STRESSBALANCE_562 case StressbalanceAnalysisEnum:563 Ke=CreateJacobianStressbalanceHoriz();564 break;565 #endif566 default:567 _error_("analysis " << analysis_type << " (" << EnumToStringx(analysis_type) << ") not supported yet");568 }569 570 /*Add to global matrix*/571 if(Ke){572 /*Condense if requested*/573 if(this->element_type==MINIcondensedEnum){574 int indices[3]={18,19,20};575 Ke->StaticCondensation(3,&indices[0]);576 }577 else if(this->element_type==P1bubblecondensedEnum){578 int size = nodes[6]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);579 int offset = 0;580 for(int i=0;i<6;i++) offset+=nodes[i]->GetNumberOfDofs(NoneApproximationEnum,GsetEnum);581 int* indices=xNew<int>(size);582 for(int i=0;i<size;i++) indices[i] = offset+i;583 Ke->StaticCondensation(size,indices);584 xDelete<int>(indices);585 }586 587 Ke->AddToGlobal(Jff);588 delete Ke;589 404 } 590 405 } … … 3437 3252 3438 3253 #ifdef _HAVE_THERMAL_ 3439 /*FUNCTION Penta::CreateKMatrixEnthalpy {{{*/3440 ElementMatrix* Penta::CreateKMatrixEnthalpy(void){3441 3442 /*compute all stiffness matrices for this element*/3443 ElementMatrix* Ke1=CreateKMatrixEnthalpyVolume();3444 ElementMatrix* Ke2=CreateKMatrixEnthalpyShelf();3445 ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);3446 3447 /*clean-up and return*/3448 delete Ke1;3449 delete Ke2;3450 return Ke;3451 }3452 /*}}}*/3453 /*FUNCTION Penta::CreateKMatrixEnthalpyVolume {{{*/3454 ElementMatrix* Penta::CreateKMatrixEnthalpyVolume(void){3455 3456 /*Constants*/3457 const int numdof=NDOF1*NUMVERTICES;3458 3459 /*Intermediaries */3460 int stabilization;3461 int i,j;3462 IssmDouble Jdet,u,v,w,um,vm,wm;3463 IssmDouble h,hx,hy,hz,vx,vy,vz,vel;3464 IssmDouble gravity,rho_ice,rho_water;3465 IssmDouble epsvel=2.220446049250313e-16;3466 IssmDouble heatcapacity,thermalconductivity,dt;3467 IssmDouble enthalpy[NUMVERTICES], pressure[NUMVERTICES];3468 IssmDouble latentheat,kappa;3469 IssmDouble tau_parameter,diameter;3470 IssmDouble xyz_list[NUMVERTICES][3];3471 IssmDouble B_conduct[3][numdof];3472 IssmDouble B_advec[3][numdof];3473 IssmDouble Bprime_advec[3][numdof];3474 IssmDouble L[numdof];3475 IssmDouble dbasis[3][6];3476 IssmDouble D_scalar_conduct,D_scalar_advec;3477 IssmDouble D_scalar_trans,D_scalar_stab;3478 IssmDouble D[3][3];3479 IssmDouble K[3][3]={0.0};3480 GaussPenta *gauss=NULL;3481 3482 /*Initialize Element matrix*/3483 ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters,NoneApproximationEnum);3484 3485 /*Retrieve all inputs and parameters*/3486 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);3487 rho_water=matpar->GetRhoWater();3488 rho_ice=matpar->GetRhoIce();3489 gravity=matpar->GetG();3490 heatcapacity=matpar->GetHeatCapacity();3491 latentheat=matpar->GetLatentHeat();3492 thermalconductivity=matpar->GetThermalConductivity();3493 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);3494 this->parameters->FindParam(&stabilization,ThermalStabilizationEnum);3495 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);3496 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);3497 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);3498 Input* vxm_input=inputs->GetInput(VxMeshEnum); _assert_(vxm_input);3499 Input* vym_input=inputs->GetInput(VyMeshEnum); _assert_(vym_input);3500 Input* vzm_input=inputs->GetInput(VzMeshEnum); _assert_(vzm_input);3501 if (stabilization==2) diameter=MinEdgeLength(&xyz_list[0][0]);3502 3503 /* Start looping on the number of gaussian points: */3504 gauss=new GaussPenta(2,2);3505 for(int ig=gauss->begin();ig<gauss->end();ig++){3506 3507 gauss->GaussPoint(ig);3508 3509 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);3510 3511 /*Conduction: */3512 GetBConduct(&B_conduct[0][0],&xyz_list[0][0],gauss);3513 GetInputListOnVertices(&enthalpy[0],EnthalpyPicardEnum);3514 GetInputListOnVertices(&pressure[0],PressureEnum);3515 kappa=matpar->GetEnthalpyDiffusionParameterVolume(NUMVERTICES,enthalpy,pressure); _assert_(kappa>0.);3516 3517 D_scalar_conduct=gauss->weight*Jdet*kappa/rho_ice;3518 if(reCast<bool,IssmDouble>(dt)) D_scalar_conduct=D_scalar_conduct*dt;3519 3520 D[0][0]=D_scalar_conduct; D[0][1]=0; D[0][2]=0;3521 D[1][0]=0; D[1][1]=D_scalar_conduct; D[1][2]=0;3522 D[2][0]=0; D[2][1]=0; D[2][2]=D_scalar_conduct;3523 3524 TripleMultiply(&B_conduct[0][0],3,numdof,1,3525 &D[0][0],3,3,0,3526 &B_conduct[0][0],3,numdof,0,3527 &Ke->values[0],1);3528 3529 /*Advection: */3530 GetBAdvec(&B_advec[0][0],&xyz_list[0][0],gauss);3531 GetBprimeAdvec(&Bprime_advec[0][0],&xyz_list[0][0],gauss);3532 3533 vx_input->GetInputValue(&u, gauss); vxm_input->GetInputValue(&um,gauss); vx=u-um;3534 vy_input->GetInputValue(&v, gauss); vym_input->GetInputValue(&vm,gauss); vy=v-vm;3535 vz_input->GetInputValue(&w, gauss); vzm_input->GetInputValue(&wm,gauss); vz=w-wm;3536 3537 D_scalar_advec=gauss->weight*Jdet;3538 if(reCast<bool,IssmDouble>(dt)) D_scalar_advec=D_scalar_advec*dt;3539 3540 D[0][0]=D_scalar_advec*vx;D[0][1]=0; D[0][2]=0;3541 D[1][0]=0; D[1][1]=D_scalar_advec*vy;D[1][2]=0;3542 D[2][0]=0; D[2][1]=0; D[2][2]=D_scalar_advec*vz;3543 3544 TripleMultiply(&B_advec[0][0],3,numdof,1,3545 &D[0][0],3,3,0,3546 &Bprime_advec[0][0],3,numdof,0,3547 &Ke->values[0],1);3548 3549 /*Transient: */3550 if(reCast<bool,IssmDouble>(dt)){3551 GetNodalFunctionsP1(&L[0], gauss);3552 D_scalar_trans=gauss->weight*Jdet;3553 3554 TripleMultiply(&L[0],numdof,1,0,3555 &D_scalar_trans,1,1,0,3556 &L[0],1,numdof,0,3557 &Ke->values[0],1);3558 }3559 3560 /*Artificial diffusivity*/3561 if(stabilization==1){3562 /*Build K: */3563 ElementSizes(&hx,&hy,&hz);3564 vel=sqrt(vx*vx + vy*vy + vz*vz)+1.e-14;3565 h=sqrt( pow(hx*vx/vel,2) + pow(hy*vy/vel,2) + pow(hz*vz/vel,2));3566 3567 K[0][0]=h/(2*vel)*vx*vx; K[0][1]=h/(2*vel)*vx*vy; K[0][2]=h/(2*vel)*vx*vz;3568 K[1][0]=h/(2*vel)*vy*vx; K[1][1]=h/(2*vel)*vy*vy; K[1][2]=h/(2*vel)*vy*vz;3569 K[2][0]=h/(2*vel)*vz*vx; K[2][1]=h/(2*vel)*vz*vy; K[2][2]=h/(2*vel)*vz*vz;3570 3571 D_scalar_stab=gauss->weight*Jdet;3572 if(reCast<bool,IssmDouble>(dt)) D_scalar_stab=D_scalar_stab*dt;3573 for(i=0;i<3;i++) for(j=0;j<3;j++) K[i][j] = D_scalar_stab*K[i][j];3574 3575 GetBprimeAdvec(&Bprime_advec[0][0],&xyz_list[0][0],gauss);3576 3577 TripleMultiply(&Bprime_advec[0][0],3,numdof,1,3578 &K[0][0],3,3,0,3579 &Bprime_advec[0][0],3,numdof,0,3580 &Ke->values[0],1);3581 }3582 else if(stabilization==2){3583 GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0], gauss);3584 tau_parameter=StabilizationParameter(u-um,v-vm,w-wm,diameter,kappa/rho_ice);3585 3586 for(i=0;i<numdof;i++){3587 for(j=0;j<numdof;j++){3588 Ke->values[i*numdof+j]+=tau_parameter*D_scalar_advec*3589 ((u-um)*dbasis[0][i]+(v-vm)*dbasis[1][i]+(w-wm)*dbasis[2][i])*((u-um)*dbasis[0][j]+(v-vm)*dbasis[1][j]+(w-wm)*dbasis[2][j]);3590 }3591 }3592 if(reCast<bool,IssmDouble>(dt)){3593 for(i=0;i<numdof;i++){3594 for(j=0;j<numdof;j++){3595 Ke->values[i*numdof+j]+=tau_parameter*D_scalar_trans*L[j]*((u-um)*dbasis[0][i]+(v-vm)*dbasis[1][i]+(w-wm)*dbasis[2][i]);3596 }3597 }3598 }3599 }3600 }3601 3602 /*Clean up and return*/3603 delete gauss;3604 return Ke;3605 }3606 /*}}}*/3607 /*FUNCTION Penta::CreateKMatrixEnthalpyShelf {{{*/3608 ElementMatrix* Penta::CreateKMatrixEnthalpyShelf(void){3609 3610 /*Constants*/3611 const int numdof=NDOF1*NUMVERTICES;3612 3613 /*Intermediaries */3614 int i,j;3615 IssmDouble mixed_layer_capacity,thermal_exchange_velocity;3616 IssmDouble rho_ice,rho_water,heatcapacity;3617 IssmDouble Jdet2d,dt;3618 IssmDouble xyz_list[NUMVERTICES][3];3619 IssmDouble xyz_list_tria[NUMVERTICES2D][3];3620 IssmDouble basis[NUMVERTICES];3621 IssmDouble D_scalar;3622 GaussPenta *gauss=NULL;3623 3624 /*Initialize Element matrix and return if necessary*/3625 if (!IsOnBed() || !IsFloating()) return NULL;3626 ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters,NoneApproximationEnum);3627 3628 /*Retrieve all inputs and parameters*/3629 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);3630 mixed_layer_capacity=matpar->GetMixedLayerCapacity();3631 thermal_exchange_velocity=matpar->GetThermalExchangeVelocity();3632 rho_water=matpar->GetRhoWater();3633 rho_ice=matpar->GetRhoIce();3634 heatcapacity=matpar->GetHeatCapacity();3635 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);3636 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];3637 3638 /* Start looping on the number of gauss (nodes on the bedrock) */3639 gauss=new GaussPenta(0,1,2,2);3640 for(int ig=gauss->begin();ig<gauss->end();ig++){3641 3642 gauss->GaussPoint(ig);3643 3644 GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);3645 GetNodalFunctionsP1(&basis[0], gauss);3646 3647 D_scalar=gauss->weight*Jdet2d*rho_water*mixed_layer_capacity*thermal_exchange_velocity/(rho_ice*heatcapacity);3648 if(reCast<bool,IssmDouble>(dt)) D_scalar=dt*D_scalar;3649 3650 TripleMultiply(&basis[0],numdof,1,0,3651 &D_scalar,1,1,0,3652 &basis[0],1,numdof,0,3653 &Ke->values[0],1);3654 }3655 3656 /*Clean up and return*/3657 delete gauss;3658 return Ke;3659 }3660 /*}}}*/3661 /*FUNCTION Penta::CreateKMatrixMelting {{{*/3662 ElementMatrix* Penta::CreateKMatrixMelting(void){3663 3664 if (!IsOnBed()) return NULL;3665 3666 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.3667 ElementMatrix* Ke=tria->CreateKMatrixMelting();3668 3669 delete tria->material; delete tria;3670 return Ke;3671 }3672 /*}}}*/3673 /*FUNCTION Penta::CreateKMatrixThermal {{{*/3674 ElementMatrix* Penta::CreateKMatrixThermal(void){3675 3676 /*compute all stiffness matrices for this element*/3677 ElementMatrix* Ke1=CreateKMatrixThermalVolume();3678 ElementMatrix* Ke2=CreateKMatrixThermalShelf();3679 ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);3680 3681 /*clean-up and return*/3682 delete Ke1;3683 delete Ke2;3684 return Ke;3685 }3686 /*}}}*/3687 /*FUNCTION Penta::CreateKMatrixThermalVolume {{{*/3688 ElementMatrix* Penta::CreateKMatrixThermalVolume(void){3689 3690 /*Constants*/3691 const int numdof=NDOF1*NUMVERTICES;3692 3693 /*Intermediaries */3694 int stabilization;3695 int i,j;3696 IssmDouble Jdet,u,v,w,um,vm,wm,vel;3697 IssmDouble h,hx,hy,hz,vx,vy,vz;3698 IssmDouble gravity,rho_ice,rho_water,kappa;3699 IssmDouble heatcapacity,thermalconductivity,dt;3700 IssmDouble tau_parameter,diameter;3701 IssmDouble xyz_list[NUMVERTICES][3];3702 IssmDouble B_conduct[3][numdof];3703 IssmDouble B_advec[3][numdof];3704 IssmDouble Bprime_advec[3][numdof];3705 IssmDouble L[numdof];3706 IssmDouble dbasis[3][6];3707 IssmDouble D_scalar_conduct,D_scalar_advec;3708 IssmDouble D_scalar_trans,D_scalar_stab;3709 IssmDouble D[3][3];3710 IssmDouble K[3][3]={0.0};3711 GaussPenta *gauss=NULL;3712 3713 /*Initialize Element matrix*/3714 ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters,NoneApproximationEnum);3715 3716 /*Retrieve all inputs and parameters*/3717 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);3718 rho_water=matpar->GetRhoWater();3719 rho_ice=matpar->GetRhoIce();3720 gravity=matpar->GetG();3721 heatcapacity=matpar->GetHeatCapacity();3722 thermalconductivity=matpar->GetThermalConductivity();3723 kappa=thermalconductivity/(rho_ice*heatcapacity);3724 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);3725 this->parameters->FindParam(&stabilization,ThermalStabilizationEnum);3726 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);3727 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);3728 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);3729 Input* vxm_input=inputs->GetInput(VxMeshEnum); _assert_(vxm_input);3730 Input* vym_input=inputs->GetInput(VyMeshEnum); _assert_(vym_input);3731 Input* vzm_input=inputs->GetInput(VzMeshEnum); _assert_(vzm_input);3732 if (stabilization==2) diameter=MinEdgeLength(&xyz_list[0][0]);3733 3734 /* Start looping on the number of gaussian points: */3735 gauss=new GaussPenta(2,2);3736 for(int ig=gauss->begin();ig<gauss->end();ig++){3737 3738 gauss->GaussPoint(ig);3739 3740 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);3741 3742 /*Conduction: */3743 3744 GetBConduct(&B_conduct[0][0],&xyz_list[0][0],gauss);3745 3746 D_scalar_conduct=gauss->weight*Jdet*kappa;3747 if(reCast<bool,IssmDouble>(dt)) D_scalar_conduct=D_scalar_conduct*dt;3748 3749 D[0][0]=D_scalar_conduct; D[0][1]=0; D[0][2]=0;3750 D[1][0]=0; D[1][1]=D_scalar_conduct; D[1][2]=0;3751 D[2][0]=0; D[2][1]=0; D[2][2]=D_scalar_conduct;3752 3753 TripleMultiply(&B_conduct[0][0],3,numdof,1,3754 &D[0][0],3,3,0,3755 &B_conduct[0][0],3,numdof,0,3756 &Ke->values[0],1);3757 3758 /*Advection: */3759 GetBAdvec(&B_advec[0][0],&xyz_list[0][0],gauss);3760 GetBprimeAdvec(&Bprime_advec[0][0],&xyz_list[0][0],gauss);3761 3762 vx_input->GetInputValue(&u, gauss); vxm_input->GetInputValue(&um,gauss); vx=u-um;3763 vy_input->GetInputValue(&v, gauss); vym_input->GetInputValue(&vm,gauss); vy=v-vm;3764 vz_input->GetInputValue(&w, gauss); vzm_input->GetInputValue(&wm,gauss); vz=w-wm;3765 3766 D_scalar_advec=gauss->weight*Jdet;3767 if(reCast<bool,IssmDouble>(dt)) D_scalar_advec=D_scalar_advec*dt;3768 3769 D[0][0]=D_scalar_advec*vx; D[0][1]=0; D[0][2]=0;3770 D[1][0]=0; D[1][1]=D_scalar_advec*vy; D[1][2]=0;3771 D[2][0]=0; D[2][1]=0; D[2][2]=D_scalar_advec*vz;3772 3773 TripleMultiply(&B_advec[0][0],3,numdof,1,3774 &D[0][0],3,3,0,3775 &Bprime_advec[0][0],3,numdof,0,3776 &Ke->values[0],1);3777 3778 /*Transient: */3779 if(reCast<bool,IssmDouble>(dt)){3780 GetNodalFunctionsP1(&L[0], gauss);3781 D_scalar_trans=gauss->weight*Jdet;3782 3783 TripleMultiply(&L[0],numdof,1,0,3784 &D_scalar_trans,1,1,0,3785 &L[0],1,numdof,0,3786 &Ke->values[0],1);3787 }3788 3789 /*Artifficial diffusivity*/3790 if(stabilization==1){3791 /*Build K: */3792 ElementSizes(&hx,&hy,&hz);3793 vel=sqrt(vx*vx + vy*vy + vz*vz)+1.e-14;3794 h=sqrt( pow(hx*vx/vel,2) + pow(hy*vy/vel,2) + pow(hz*vz/vel,2));3795 3796 K[0][0]=h/(2*vel)*fabs(vx*vx); K[0][1]=h/(2*vel)*fabs(vx*vy); K[0][2]=h/(2*vel)*fabs(vx*vz);3797 K[1][0]=h/(2*vel)*fabs(vy*vx); K[1][1]=h/(2*vel)*fabs(vy*vy); K[1][2]=h/(2*vel)*fabs(vy*vz);3798 K[2][0]=h/(2*vel)*fabs(vz*vx); K[2][1]=h/(2*vel)*fabs(vz*vy); K[2][2]=h/(2*vel)*fabs(vz*vz);3799 3800 D_scalar_stab=gauss->weight*Jdet;3801 if(reCast<bool,IssmDouble>(dt)) D_scalar_stab=D_scalar_stab*dt;3802 for(i=0;i<3;i++) for(j=0;j<3;j++) K[i][j] = D_scalar_stab*K[i][j];3803 3804 GetBprimeAdvec(&Bprime_advec[0][0],&xyz_list[0][0],gauss);3805 3806 TripleMultiply(&Bprime_advec[0][0],3,numdof,1,3807 &K[0][0],3,3,0,3808 &Bprime_advec[0][0],3,numdof,0,3809 &Ke->values[0],1);3810 }3811 else if(stabilization==2){3812 GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0], gauss);3813 tau_parameter=StabilizationParameter(u-um,v-vm,w-wm,diameter,kappa);3814 3815 for(i=0;i<numdof;i++){3816 for(j=0;j<numdof;j++){3817 Ke->values[i*numdof+j]+=tau_parameter*D_scalar_advec*3818 ((u-um)*dbasis[0][i]+(v-vm)*dbasis[1][i]+(w-wm)*dbasis[2][i])*((u-um)*dbasis[0][j]+(v-vm)*dbasis[1][j]+(w-wm)*dbasis[2][j]);3819 }3820 }3821 if(reCast<bool,IssmDouble>(dt)){3822 for(i=0;i<numdof;i++){3823 for(j=0;j<numdof;j++){3824 Ke->values[i*numdof+j]+=tau_parameter*D_scalar_trans*L[j]*((u-um)*dbasis[0][i]+(v-vm)*dbasis[1][i]+(w-wm)*dbasis[2][i]);3825 }3826 }3827 }3828 }3829 }3830 3831 /*Clean up and return*/3832 delete gauss;3833 return Ke;3834 }3835 /*}}}*/3836 /*FUNCTION Penta::CreateKMatrixThermalShelf {{{*/3837 ElementMatrix* Penta::CreateKMatrixThermalShelf(void){3838 3839 /*Constants*/3840 const int numdof=NDOF1*NUMVERTICES;3841 3842 /*Intermediaries */3843 int i,j;3844 IssmDouble mixed_layer_capacity,thermal_exchange_velocity;3845 IssmDouble rho_ice,rho_water,heatcapacity;3846 IssmDouble Jdet2d,dt;3847 IssmDouble xyz_list[NUMVERTICES][3];3848 IssmDouble xyz_list_tria[NUMVERTICES2D][3];3849 IssmDouble basis[NUMVERTICES];3850 IssmDouble D_scalar;3851 GaussPenta *gauss=NULL;3852 3853 /*Initialize Element matrix and return if necessary*/3854 if (!IsOnBed() || !IsFloating()) return NULL;3855 ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters,NoneApproximationEnum);3856 3857 /*Retrieve all inputs and parameters*/3858 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);3859 mixed_layer_capacity=matpar->GetMixedLayerCapacity();3860 thermal_exchange_velocity=matpar->GetThermalExchangeVelocity();3861 rho_water=matpar->GetRhoWater();3862 rho_ice=matpar->GetRhoIce();3863 heatcapacity=matpar->GetHeatCapacity();3864 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);3865 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];3866 3867 /* Start looping on the number of gauss (nodes on the bedrock) */3868 gauss=new GaussPenta(0,1,2,2);3869 for(int ig=gauss->begin();ig<gauss->end();ig++){3870 3871 gauss->GaussPoint(ig);3872 3873 GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);3874 GetNodalFunctionsP1(&basis[0], gauss);3875 3876 D_scalar=gauss->weight*Jdet2d*rho_water*mixed_layer_capacity*thermal_exchange_velocity/(heatcapacity*rho_ice);3877 if(reCast<bool,IssmDouble>(dt)) D_scalar=dt*D_scalar;3878 3879 TripleMultiply(&basis[0],numdof,1,0,3880 &D_scalar,1,1,0,3881 &basis[0],1,numdof,0,3882 &Ke->values[0],1);3883 }3884 3885 /*Clean up and return*/3886 delete gauss;3887 return Ke;3888 }3889 /*}}}*/3890 3254 /*FUNCTION Penta::UpdateBasalConstraintsEnthalpy{{{*/ 3891 3255 void Penta::UpdateBasalConstraintsEnthalpy(void){ … … 4282 3646 4283 3647 }/*}}}*/ 4284 /*FUNCTION Penta::CreateKMatrixAdjointHoriz{{{*/4285 ElementMatrix* Penta::CreateKMatrixAdjointHoriz(void){4286 4287 int approximation;4288 inputs->GetInputValue(&approximation,ApproximationEnum);4289 4290 switch(approximation){4291 case SSAApproximationEnum:4292 return CreateKMatrixAdjointSSA2d();4293 case HOApproximationEnum:4294 return CreateKMatrixAdjointHO();4295 case FSApproximationEnum:4296 return CreateKMatrixAdjointFS();4297 case NoneApproximationEnum:4298 return NULL;4299 default:4300 _error_("Approximation " << EnumToStringx(approximation) << " not supported yet");4301 }4302 }4303 /*}}}*/4304 /*FUNCTION Penta::CreateKMatrixAdjointSSA2d{{{*/4305 ElementMatrix* Penta::CreateKMatrixAdjointSSA2d(void){4306 4307 /*Figure out if this penta is collapsed. If so, then bailout, except if it is at the4308 bedrock, in which case we spawn a tria element using the 3 first nodes, and use it to build4309 the stiffness matrix. */4310 if (!IsOnBed()) return NULL;4311 4312 /*Depth average some fields*/4313 switch(this->material->ObjectEnum()){4314 case MaticeEnum:4315 this->InputDepthAverageAtBase(MaterialsRheologyBEnum,MaterialsRheologyBbarEnum,MaterialsEnum);4316 this->InputDepthAverageAtBase(DamageDEnum,DamageDbarEnum,MaterialsEnum);4317 break;4318 default:4319 _error_("material "<<EnumToStringx(this->material->ObjectEnum())<<" not supported");4320 }4321 4322 /*Call Tria function*/4323 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.4324 ElementMatrix* Ke=tria->CreateKMatrixAdjointSSA();4325 delete tria->material; delete tria;4326 4327 /*Delete averaged fields*/4328 this->material->inputs->DeleteInput(MaterialsRheologyBbarEnum);4329 this->material->inputs->DeleteInput(DamageDbarEnum);4330 4331 /*clean up and return*/4332 return Ke;4333 }4334 /*}}}*/4335 /*FUNCTION Penta::CreateKMatrixAdjointHO{{{*/4336 ElementMatrix* Penta::CreateKMatrixAdjointHO(void){4337 4338 /*Intermediaries */4339 int i,j;4340 bool incomplete_adjoint;4341 IssmDouble xyz_list[NUMVERTICES][3];4342 IssmDouble Jdet;4343 IssmDouble eps1dotdphii,eps1dotdphij;4344 IssmDouble eps2dotdphii,eps2dotdphij;4345 IssmDouble mu_prime;4346 IssmDouble epsilon[5]; /* epsilon=[exx,eyy,exy,exz,eyz];*/4347 IssmDouble eps1[3],eps2[3];4348 IssmDouble dphi[3][NUMVERTICES];4349 GaussPenta *gauss=NULL;4350 4351 /*Initialize Jacobian with regular HO (first part of the Gateau derivative)*/4352 parameters->FindParam(&incomplete_adjoint,InversionIncompleteAdjointEnum);4353 ElementMatrix* Ke=CreateKMatrixStressbalanceHO();4354 if(incomplete_adjoint) return Ke;4355 4356 /*Retrieve all inputs and parameters*/4357 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);4358 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);4359 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);4360 4361 /* Start looping on the number of gaussian points: */4362 gauss=new GaussPenta(5,5);4363 for(int ig=gauss->begin();ig<gauss->end();ig++){4364 4365 gauss->GaussPoint(ig);4366 4367 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);4368 GetNodalFunctionsP1Derivatives(&dphi[0][0],&xyz_list[0][0],gauss);4369 4370 this->StrainRateHO(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);4371 material->GetViscosityDerivativeEpsSquare(&mu_prime,&epsilon[0]);4372 eps1[0]=2*epsilon[0]+epsilon[1]; eps2[0]=epsilon[2];4373 eps1[1]=epsilon[2]; eps2[1]=epsilon[0]+2*epsilon[1];4374 eps1[2]=epsilon[3]; eps2[2]=epsilon[4];4375 4376 for(i=0;i<6;i++){4377 for(j=0;j<6;j++){4378 eps1dotdphii=eps1[0]*dphi[0][i]+eps1[1]*dphi[1][i]+eps1[2]*dphi[2][i];4379 eps1dotdphij=eps1[0]*dphi[0][j]+eps1[1]*dphi[1][j]+eps1[2]*dphi[2][j];4380 eps2dotdphii=eps2[0]*dphi[0][i]+eps2[1]*dphi[1][i]+eps2[2]*dphi[2][i];4381 eps2dotdphij=eps2[0]*dphi[0][j]+eps2[1]*dphi[1][j]+eps2[2]*dphi[2][j];4382 4383 Ke->values[12*(2*i+0)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps1dotdphii;4384 Ke->values[12*(2*i+0)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps1dotdphii;4385 Ke->values[12*(2*i+1)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps2dotdphii;4386 Ke->values[12*(2*i+1)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps2dotdphii;4387 }4388 }4389 }4390 4391 /*Transform Coordinate System*/4392 ::TransformStiffnessMatrixCoord(Ke,nodes,NUMVERTICES,XYEnum);4393 4394 /*Clean up and return*/4395 delete gauss;4396 return Ke;4397 }4398 /*}}}*/4399 /*FUNCTION Penta::CreateKMatrixAdjointFS{{{*/4400 ElementMatrix* Penta::CreateKMatrixAdjointFS(void){4401 4402 /*Intermediaries */4403 int i,j;4404 bool incomplete_adjoint;4405 IssmDouble xyz_list[NUMVERTICES][3];4406 IssmDouble Jdet;4407 IssmDouble eps1dotdphii,eps1dotdphij;4408 IssmDouble eps2dotdphii,eps2dotdphij;4409 IssmDouble eps3dotdphii,eps3dotdphij;4410 IssmDouble mu_prime;4411 IssmDouble epsilon[5]; /* epsilon=[exx,eyy,exy,exz,eyz];*/4412 IssmDouble eps1[3],eps2[3],eps3[3];4413 IssmDouble dphi[3][NUMVERTICES];4414 GaussPenta *gauss=NULL;4415 4416 /*Initialize Jacobian with regular FS (first part of the Gateau derivative)*/4417 parameters->FindParam(&incomplete_adjoint,InversionIncompleteAdjointEnum);4418 ElementMatrix* Ke=CreateKMatrixStressbalanceFS();4419 if(incomplete_adjoint) return Ke;4420 4421 /*Fetch number of nodes and dof for this finite element*/4422 int vnumnodes = this->NumberofNodesVelocity();4423 int pnumnodes = this->NumberofNodesPressure();4424 int numdof = vnumnodes*NDOF3 + pnumnodes*NDOF1;4425 4426 /*Retrieve all inputs and parameters*/4427 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);4428 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);4429 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);4430 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);4431 4432 /* Start looping on the number of gaussian points: */4433 gauss=new GaussPenta(5,5);4434 for(int ig=gauss->begin();ig<gauss->end();ig++){4435 4436 gauss->GaussPoint(ig);4437 4438 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);4439 GetNodalFunctionsP1Derivatives(&dphi[0][0],&xyz_list[0][0],gauss);4440 4441 this->StrainRateHO(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);4442 material->GetViscosityDerivativeEpsSquare(&mu_prime,&epsilon[0]);4443 eps1[0]=epsilon[0]; eps2[0]=epsilon[2]; eps3[0]=epsilon[3];4444 eps1[1]=epsilon[2]; eps2[1]=epsilon[1]; eps3[1]=epsilon[4];4445 eps1[2]=epsilon[3]; eps2[2]=epsilon[4]; eps3[2]= -epsilon[0] -epsilon[1];4446 4447 for(i=0;i<6;i++){4448 for(j=0;j<6;j++){4449 eps1dotdphii=eps1[0]*dphi[0][i]+eps1[1]*dphi[1][i]+eps1[2]*dphi[2][i];4450 eps1dotdphij=eps1[0]*dphi[0][j]+eps1[1]*dphi[1][j]+eps1[2]*dphi[2][j];4451 eps2dotdphii=eps2[0]*dphi[0][i]+eps2[1]*dphi[1][i]+eps2[2]*dphi[2][i];4452 eps2dotdphij=eps2[0]*dphi[0][j]+eps2[1]*dphi[1][j]+eps2[2]*dphi[2][j];4453 eps3dotdphii=eps3[0]*dphi[0][i]+eps3[1]*dphi[1][i]+eps3[2]*dphi[2][i];4454 eps3dotdphij=eps3[0]*dphi[0][j]+eps3[1]*dphi[1][j]+eps3[2]*dphi[2][j];4455 4456 Ke->values[numdof*(4*i+0)+4*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps1dotdphii;4457 Ke->values[numdof*(4*i+0)+4*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps1dotdphii;4458 Ke->values[numdof*(4*i+0)+4*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps1dotdphii;4459 4460 Ke->values[numdof*(4*i+1)+4*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps2dotdphii;4461 Ke->values[numdof*(4*i+1)+4*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps2dotdphii;4462 Ke->values[numdof*(4*i+1)+4*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps2dotdphii;4463 4464 Ke->values[numdof*(4*i+2)+4*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps3dotdphii;4465 Ke->values[numdof*(4*i+2)+4*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps3dotdphii;4466 Ke->values[numdof*(4*i+2)+4*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps3dotdphii;4467 }4468 }4469 }4470 4471 /*Transform Coordinate System*/4472 ::TransformStiffnessMatrixCoord(Ke,nodes,NUMVERTICES,XYZEnum);4473 4474 /*Clean up and return*/4475 delete gauss;4476 return Ke;4477 }4478 /*}}}*/4479 3648 /*FUNCTION Penta::GradientIndexing{{{*/ 4480 3649 void Penta::GradientIndexing(int* indexing,int control_index){ … … 5351 4520 } 5352 4521 /*}}}*/ 5353 /*FUNCTION Penta::CreateKMatrixCouplingSSAHO{{{*/5354 ElementMatrix* Penta::CreateKMatrixCouplingSSAHO(void){5355 5356 /*compute all stiffness matrices for this element*/5357 ElementMatrix* Ke1=CreateKMatrixCouplingSSAHOViscous();5358 ElementMatrix* Ke2=CreateKMatrixCouplingSSAHOFriction();5359 ElementMatrix* Ke=new ElementMatrix(Ke1,Ke2);5360 5361 /*clean-up and return*/5362 delete Ke1;5363 delete Ke2;5364 return Ke;5365 }5366 /*}}}*/5367 /*FUNCTION Penta::CreateKMatrixCouplingSSAHOViscous{{{*/5368 ElementMatrix* Penta::CreateKMatrixCouplingSSAHOViscous(void){5369 5370 /*Constants*/5371 const int numnodes = 2 *NUMVERTICES;5372 const int numdofm = NDOF2 *NUMVERTICES2D;5373 const int numdofp = NDOF2 *NUMVERTICES;5374 const int numdoftotal = 2 *NDOF2*NUMVERTICES;5375 5376 /*Intermediaries */5377 int i,j;5378 IssmDouble Jdet;5379 IssmDouble viscosity,oldviscosity,newviscosity,viscosity_overshoot; //viscosity5380 IssmDouble epsilon[5],oldepsilon[5]; /* epsilon=[exx,eyy,exy,exz,eyz];*/5381 IssmDouble xyz_list[NUMVERTICES][3];5382 IssmDouble B[3][numdofp];5383 IssmDouble Bprime[3][numdofm];5384 IssmDouble D[3][3]={0.0}; // material matrix, simple scalar matrix.5385 IssmDouble D_scalar;5386 IssmDouble Ke_gg[numdofp][numdofm]={0.0}; //local element stiffness matrix5387 IssmDouble Ke_gg_gaussian[numdofp][numdofm]; //stiffness matrix evaluated at the gaussian point.5388 GaussPenta *gauss=NULL;5389 GaussTria *gauss_tria=NULL;5390 Node *node_list[numnodes];5391 int cs_list[numnodes];5392 5393 /*Find penta on bed as HO must be coupled to the dofs on the bed: */5394 Penta* pentabase=(Penta*)GetBasalElement();5395 Tria* tria=pentabase->SpawnTria(0); //lower face is 0, upper face is 1.5396 5397 /*prepare node list*/5398 for(i=0;i<NUMVERTICES;i++){5399 node_list[i+0*NUMVERTICES] = pentabase->nodes[i];5400 node_list[i+1*NUMVERTICES] = this->nodes[i];5401 cs_list[i+0*NUMVERTICES] = XYEnum;5402 cs_list[i+1*NUMVERTICES] = XYEnum;5403 }5404 5405 /*Initialize Element matrix*/5406 ElementMatrix* Ke1=new ElementMatrix(pentabase->nodes,NUMVERTICES,this->parameters,SSAApproximationEnum);5407 ElementMatrix* Ke2=new ElementMatrix(this->nodes ,NUMVERTICES,this->parameters,HOApproximationEnum);5408 ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);5409 delete Ke1; delete Ke2;5410 5411 /* Get node coordinates and dof list: */5412 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);5413 this->parameters->FindParam(&viscosity_overshoot,StressbalanceViscosityOvershootEnum);5414 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);5415 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);5416 Input* vxold_input=inputs->GetInput(VxPicardEnum); _assert_(vxold_input);5417 Input* vyold_input=inputs->GetInput(VyPicardEnum); _assert_(vyold_input);5418 5419 /* Start looping on the number of gaussian points: */5420 gauss=new GaussPenta(5,5);5421 gauss_tria=new GaussTria();5422 for(int ig=gauss->begin();ig<gauss->end();ig++){5423 5424 gauss->GaussPoint(ig);5425 gauss->SynchronizeGaussBase(gauss_tria);5426 5427 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);5428 GetBSSAHO(&B[0][0], &xyz_list[0][0], gauss);5429 tria->GetBprimeSSA(&Bprime[0][0], &xyz_list[0][0], gauss_tria);5430 5431 this->StrainRateHO(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);5432 this->StrainRateHO(&oldepsilon[0],&xyz_list[0][0],gauss,vxold_input,vyold_input);5433 material->GetViscosity3d(&viscosity, &epsilon[0]);5434 material->GetViscosity3d(&oldviscosity, &oldepsilon[0]);5435 5436 newviscosity=viscosity+viscosity_overshoot*(viscosity-oldviscosity);5437 D_scalar=2*newviscosity*gauss->weight*Jdet;5438 for (i=0;i<3;i++) D[i][i]=D_scalar;5439 5440 TripleMultiply( &B[0][0],3,numdofp,1,5441 &D[0][0],3,3,0,5442 &Bprime[0][0],3,numdofm,0,5443 &Ke_gg_gaussian[0][0],0);5444 5445 for( i=0; i<numdofp; i++) for(j=0;j<numdofm; j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];5446 }5447 for(i=0;i<numdofp;i++) for(j=0;j<numdofm;j++) Ke->values[(i+2*numdofm)*numdoftotal+j]+=Ke_gg[i][j];5448 for(i=0;i<numdofm;i++) for(j=0;j<numdofp;j++) Ke->values[i*numdoftotal+(j+2*numdofm)]+=Ke_gg[j][i];5449 5450 /*Transform Coordinate System*/5451 ::TransformStiffnessMatrixCoord(Ke,node_list,numnodes,cs_list);5452 5453 /*Clean-up and return*/5454 delete tria->material; delete tria;5455 delete gauss;5456 delete gauss_tria;5457 return Ke;5458 }5459 /*}}}*/5460 /*FUNCTION Penta::CreateKMatrixCouplingSSAHOFriction{{{*/5461 ElementMatrix* Penta::CreateKMatrixCouplingSSAHOFriction(void){5462 5463 /*Constants*/5464 const int numnodes = 2 *NUMVERTICES;5465 const int numdof = NDOF2 *NUMVERTICES;5466 const int numdoftotal = NDOF4 *NUMVERTICES;5467 5468 /*Intermediaries */5469 int i,j,analysis_type;5470 IssmDouble Jdet2d,alpha2;5471 IssmDouble xyz_list[NUMVERTICES][3];5472 IssmDouble xyz_list_tria[NUMVERTICES2D][3]={0.0};5473 IssmDouble L[2][numdof];5474 IssmDouble DL[2][2] ={{ 0,0 },{0,0}}; //for basal drag5475 IssmDouble DL_scalar;5476 IssmDouble Ke_gg[numdof][numdof] ={0.0};5477 IssmDouble Ke_gg_gaussian[numdof][numdof]; //stiffness matrix contribution from drag5478 Friction *friction = NULL;5479 GaussPenta *gauss=NULL;5480 Node *node_list[numnodes];5481 int cs_list[numnodes];5482 5483 /*Initialize Element matrix and return if necessary*/5484 if(IsFloating() || !IsOnBed()) return NULL;5485 ElementMatrix* Ke1=new ElementMatrix(nodes,NUMVERTICES,this->parameters,SSAApproximationEnum);5486 ElementMatrix* Ke2=new ElementMatrix(nodes,NUMVERTICES,this->parameters,HOApproximationEnum);5487 ElementMatrix* Ke=new ElementMatrix(Ke1,Ke2);5488 delete Ke1; delete Ke2;5489 5490 /*Prepare node list*/5491 for(i=0;i<NUMVERTICES;i++){5492 node_list[i+0*NUMVERTICES] = this->nodes[i];5493 node_list[i+1*NUMVERTICES] = this->nodes[i];5494 cs_list[i+0*NUMVERTICES] = XYEnum;5495 cs_list[i+1*NUMVERTICES] = XYEnum;5496 }5497 5498 /*retrieve inputs :*/5499 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);5500 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];5501 parameters->FindParam(&analysis_type,AnalysisTypeEnum);5502 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);5503 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);5504 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);5505 5506 /*build friction object, used later on: */5507 friction=new Friction(this,2);5508 5509 /* Start looping on the number of gaussian points: */5510 gauss=new GaussPenta(0,1,2,2);5511 for(int ig=gauss->begin();ig<gauss->end();ig++){5512 5513 gauss->GaussPoint(ig);5514 5515 /*Friction: */5516 friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);5517 5518 GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0],gauss);5519 GetBHOFriction(&L[0][0],gauss);5520 5521 DL_scalar=alpha2*gauss->weight*Jdet2d;5522 for (i=0;i<2;i++) DL[i][i]=DL_scalar;5523 5524 /* Do the triple producte tL*D*L: */5525 TripleMultiply( &L[0][0],2,numdof,1,5526 &DL[0][0],2,2,0,5527 &L[0][0],2,numdof,0,5528 &Ke_gg_gaussian[0][0],0);5529 5530 for(i=0;i<numdof;i++) for(j=0;j<numdof;j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];5531 }5532 5533 for(i=0;i<numdof;i++) for(j=0;j<numdof;j++) Ke->values[i*numdoftotal+(numdof+j)]+=Ke_gg[i][j];5534 for(i=0;i<numdof;i++) for(j=0;j<numdof;j++) Ke->values[(i+numdof)*numdoftotal+j]+=Ke_gg[i][j];5535 5536 /*Transform Coordinate System*/5537 ::TransformStiffnessMatrixCoord(Ke,node_list,numnodes,cs_list);5538 5539 /*Clean up and return*/5540 delete gauss;5541 delete friction;5542 return Ke;5543 }5544 /*}}}*/5545 /*FUNCTION Penta::CreateKMatrixCouplingSSAFS{{{*/5546 ElementMatrix* Penta::CreateKMatrixCouplingSSAFS(void){5547 5548 /*compute all stiffness matrices for this element*/5549 ElementMatrix* Ke1=CreateKMatrixCouplingSSAFSViscous();5550 ElementMatrix* Ke2=CreateKMatrixCouplingSSAFSFriction();5551 ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);5552 5553 /*clean-up and return*/5554 delete Ke1;5555 delete Ke2;5556 return Ke;5557 }5558 /*}}}*/5559 /*FUNCTION Penta::CreateKMatrixCouplingSSAFSViscous{{{*/5560 ElementMatrix* Penta::CreateKMatrixCouplingSSAFSViscous(void){5561 5562 /*Constants*/5563 const int numdofm = NDOF2 *NUMVERTICES2D;5564 const int numdofs = NDOF4 *NUMVERTICES + NDOF3;5565 const int numdoftotal = 2 *numdofm+numdofs;5566 5567 /*Intermediaries */5568 int i,j;5569 IssmDouble Jdet;5570 IssmDouble viscosity,FSreconditioning; //viscosity5571 IssmDouble epsilon[6]; /* epsilon=[exx,eyy,exy,exz,eyz];*/5572 IssmDouble xyz_list[NUMVERTICES][3];5573 IssmDouble B[4][numdofs];5574 IssmDouble Bprime[4][numdofm];5575 IssmDouble B2[3][numdofm];5576 IssmDouble Bprime2[3][numdofs];5577 IssmDouble D[4][4]={0.0}; // material matrix, simple scalar matrix.5578 IssmDouble D2[3][3]={0.0}; // material matrix, simple scalar matrix.5579 IssmDouble D_scalar;5580 IssmDouble Ke_gg[numdofs][numdofm]={0.0}; //local element stiffness matrix5581 IssmDouble Ke_gg2[numdofm][numdofs]={0.0}; //local element stiffness matrix5582 IssmDouble Ke_gg_gaussian[numdofs][numdofm]; //stiffness matrix evaluated at the gaussian point.5583 IssmDouble Ke_gg_gaussian2[numdofm][numdofs]; //stiffness matrix evaluated at the gaussian point.5584 GaussPenta *gauss=NULL;5585 GaussTria *gauss_tria=NULL;5586 Node *node_list[20];5587 5588 /*Find penta on bed as FS must be coupled to the dofs on the bed: */5589 Penta* pentabase=(Penta*)GetBasalElement();5590 Tria* tria=pentabase->SpawnTria(0); //lower face is 0, upper face is 1.5591 5592 int vnumnodes = this->NumberofNodesVelocity();5593 int pnumnodes = this->NumberofNodesPressure();5594 int numnodes = 2*vnumnodes-1+pnumnodes;5595 5596 /*Prepare node list*/5597 int* cs_list = xNew<int>(2*vnumnodes+pnumnodes);5598 for(i=0;i<vnumnodes-1;i++){5599 node_list[i] = pentabase->nodes[i];5600 cs_list[i] = XYEnum;5601 }5602 for(i=0;i<vnumnodes;i++){5603 node_list[i+vnumnodes-1] = this->nodes[i];5604 cs_list[i+vnumnodes-1] = XYZEnum;5605 }5606 for(i=0;i<pnumnodes;i++){5607 node_list[2*vnumnodes-1+i] = this->nodes[vnumnodes+i];5608 cs_list[2*vnumnodes-1+i] = PressureEnum;5609 }5610 5611 /*Initialize Element matrix and return if necessary*/5612 ElementMatrix* Ke1=new ElementMatrix(pentabase->nodes,NUMVERTICES, this->parameters,SSAApproximationEnum);5613 ElementMatrix* Ke2=new ElementMatrix(this->nodes ,2*NUMVERTICES+1,this->parameters,FSvelocityEnum);5614 ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);5615 delete Ke1; delete Ke2;5616 5617 /* Get node coordinates and dof list: */5618 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);5619 parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);5620 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);5621 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);5622 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);5623 5624 /* Start looping on the number of gaussian points: */5625 gauss=new GaussPenta(5,5);5626 gauss_tria=new GaussTria();5627 for(int ig=gauss->begin();ig<gauss->end();ig++){5628 5629 gauss->GaussPoint(ig);5630 gauss->SynchronizeGaussBase(gauss_tria);5631 5632 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);5633 GetBSSAFS(&B[0][0], &xyz_list[0][0], gauss);5634 tria->GetBprimeSSAFS(&Bprime[0][0], &xyz_list[0][0], gauss_tria);5635 tria->GetBSSAFS(&B2[0][0], &xyz_list[0][0], gauss_tria);5636 GetBprimeSSAFS(&Bprime2[0][0], &xyz_list[0][0], gauss);5637 5638 this->StrainRateFS(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);5639 material->GetViscosity3dFS(&viscosity, &epsilon[0]);5640 5641 D_scalar=2*viscosity*gauss->weight*Jdet;5642 for (i=0;i<3;i++) D[i][i]=D_scalar;5643 D[3][3]=-gauss->weight*Jdet*FSreconditioning;5644 for (i=0;i<3;i++) D2[i][i]=D_scalar;5645 5646 TripleMultiply( &B[0][0],4,numdofs,1,5647 &D[0][0],4,4,0,5648 &Bprime[0][0],4,numdofm,0,5649 &Ke_gg_gaussian[0][0],0);5650 5651 TripleMultiply( &B2[0][0],3,numdofm,1,5652 &D2[0][0],3,3,0,5653 &Bprime2[0][0],3,numdofs,0,5654 &Ke_gg_gaussian2[0][0],0);5655 5656 for( i=0; i<numdofs; i++) for(j=0;j<numdofm; j++) Ke_gg[i][j]+=Ke_gg_gaussian[i][j];5657 for( i=0; i<numdofm; i++) for(j=0;j<numdofs; j++) Ke_gg2[i][j]+=Ke_gg_gaussian2[i][j];5658 }5659 for(i=0;i<numdofs;i++) for(j=0;j<numdofm;j++) Ke->values[(i+2*numdofm)*numdoftotal+j]+=Ke_gg[i][j];5660 for(i=0;i<numdofm;i++) for(j=0;j<numdofs;j++) Ke->values[i*numdoftotal+(j+2*numdofm)]+=Ke_gg2[i][j];5661 5662 /*Transform Coordinate System*/5663 ::TransformStiffnessMatrixCoord(Ke,node_list,numnodes,cs_list);5664 5665 /*Clean-up and return*/5666 xDelete<int>(cs_list);5667 delete tria->material; delete tria;5668 delete gauss;5669 delete gauss_tria;5670 return Ke;5671 }5672 /*}}}*/5673 /*FUNCTION Penta::CreateKMatrixCouplingSSAFSFriction {{{*/5674 ElementMatrix* Penta::CreateKMatrixCouplingSSAFSFriction(void){5675 /*Constants*/5676 const int numdofs = (NUMVERTICES+1)*NDOF3 + NUMVERTICES*NDOF1;5677 const int numdofm = NUMVERTICES *NDOF2;5678 const int numdof2d = NUMVERTICES2D *NDOF3;5679 const int numdof2dm = NUMVERTICES2D *NDOF2;5680 const int numdoftot = NUMVERTICES*2 + (NUMVERTICES+1)*3 +NUMVERTICES; // HO + FS vel + FS Pressure5681 5682 /*Intermediaries */5683 int i,j;5684 int analysis_type,approximation;5685 IssmDouble FSreconditioning;5686 IssmDouble viscosity,alpha2_gauss,Jdet2d;5687 IssmDouble bed_normal[3];5688 IssmDouble epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/5689 IssmDouble xyz_list[NUMVERTICES][3];5690 IssmDouble xyz_list_tria[NUMVERTICES2D][3];5691 IssmDouble LSSAFS[8][numdof2dm];5692 IssmDouble LprimeSSAFS[8][numdofs];5693 IssmDouble DLSSAFS[8][8]={0.0};5694 IssmDouble LFSSSA[4][numdof2d];5695 IssmDouble LprimeFSSSA[4][numdof2dm];5696 IssmDouble DLFSSSA[4][4]={0.0};5697 IssmDouble Ke_drag_gaussian[numdof2dm][numdofs];5698 IssmDouble Ke_drag_gaussian2[numdof2d][numdof2dm];5699 Friction* friction=NULL;5700 GaussPenta *gauss=NULL;5701 Node *node_list[20];5702 5703 /*If on water or not FS, skip stiffness: */5704 inputs->GetInputValue(&approximation,ApproximationEnum);5705 if(IsFloating() || !IsOnBed()) return NULL;5706 5707 int vnumnodes = this->NumberofNodesVelocity();5708 int pnumnodes = this->NumberofNodesPressure();5709 int numnodes = 2*vnumnodes-1+pnumnodes;5710 5711 /*Prepare node list*/5712 int* cs_list = xNew<int>(2*vnumnodes+pnumnodes);5713 for(i=0;i<vnumnodes-1;i++){5714 node_list[i] = this->nodes[i];5715 cs_list[i] = XYEnum;5716 }5717 for(i=0;i<vnumnodes;i++){5718 node_list[i+vnumnodes-1] = this->nodes[i];5719 cs_list[i+vnumnodes-1] = XYZEnum;5720 }5721 for(i=0;i<pnumnodes;i++){5722 node_list[2*vnumnodes-1+i] = this->nodes[vnumnodes+i];5723 cs_list[2*vnumnodes-1+i] = PressureEnum;5724 }5725 5726 ElementMatrix* Ke1=new ElementMatrix(this->nodes,NUMVERTICES, this->parameters,SSAApproximationEnum);5727 ElementMatrix* Ke2=new ElementMatrix(this->nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);5728 ElementMatrix* Ke=new ElementMatrix(Ke1,Ke2);5729 delete Ke1; delete Ke2;5730 5731 /*Retrieve all inputs and parameters*/5732 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);5733 parameters->FindParam(&analysis_type,AnalysisTypeEnum);5734 parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);5735 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);5736 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);5737 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);5738 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];5739 5740 /*build friction object, used later on: */5741 friction=new Friction(this,3);5742 5743 /* Start looping on the number of gaussian points: */5744 gauss=new GaussPenta(0,1,2,2);5745 for(int ig=gauss->begin();ig<gauss->end();ig++){5746 5747 gauss->GaussPoint(ig);5748 5749 GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0],gauss);5750 GetLSSAFS(&LSSAFS[0][0], gauss);5751 GetLprimeSSAFS(&LprimeSSAFS[0][0], &xyz_list[0][0], gauss);5752 GetLFSSSA(&LFSSSA[0][0], gauss);5753 GetLprimeFSSSA(&LprimeFSSSA[0][0], &xyz_list[0][0], gauss);5754 5755 this->StrainRateFS(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);5756 material->GetViscosity3dFS(&viscosity,&epsilon[0]);5757 5758 NormalBase(&bed_normal[0],&xyz_list_tria[0][0]);5759 friction->GetAlpha2(&alpha2_gauss, gauss,vx_input,vy_input,vz_input);5760 5761 DLSSAFS[0][0]=alpha2_gauss*gauss->weight*Jdet2d;5762 DLSSAFS[1][1]=alpha2_gauss*gauss->weight*Jdet2d;5763 DLSSAFS[2][2]=-alpha2_gauss*gauss->weight*Jdet2d*bed_normal[0]*bed_normal[2];5764 DLSSAFS[3][3]=-alpha2_gauss*gauss->weight*Jdet2d*bed_normal[1]*bed_normal[2];5765 DLSSAFS[4][4]=-2*viscosity*gauss->weight*Jdet2d*bed_normal[0];5766 DLSSAFS[5][5]=-2*viscosity*gauss->weight*Jdet2d*bed_normal[1];5767 DLSSAFS[6][6]=FSreconditioning*gauss->weight*Jdet2d*bed_normal[0];5768 DLSSAFS[7][7]=FSreconditioning*gauss->weight*Jdet2d*bed_normal[1];5769 5770 DLFSSSA[0][0]=alpha2_gauss*gauss->weight*Jdet2d;5771 DLFSSSA[1][1]=alpha2_gauss*gauss->weight*Jdet2d;5772 DLFSSSA[2][2]=-alpha2_gauss*gauss->weight*Jdet2d*bed_normal[0]*bed_normal[2];5773 DLFSSSA[3][3]=-alpha2_gauss*gauss->weight*Jdet2d*bed_normal[1]*bed_normal[2];5774 5775 TripleMultiply( &LSSAFS[0][0],8,numdof2dm,1,5776 &DLSSAFS[0][0],8,8,0,5777 &LprimeSSAFS[0][0],8,numdofs,0,5778 &Ke_drag_gaussian[0][0],0);5779 5780 TripleMultiply( &LFSSSA[0][0],4,numdof2d,1,5781 &DLFSSSA[0][0],4,4,0,5782 &LprimeFSSSA[0][0],4,numdof2dm,0,5783 &Ke_drag_gaussian2[0][0],0);5784 for(i=0;i<numdof2dm;i++) for(j=0;j<numdofs;j++) Ke->values[i*numdoftot+j+numdofm]+=Ke_drag_gaussian[i][j];5785 for(i=0;i<numdof2d;i++) for(j=0;j<numdof2dm;j++) Ke->values[(i+numdofm)*numdoftot+j]+=Ke_drag_gaussian2[i][j];5786 }5787 5788 /*Transform Coordinate System*/5789 ::TransformStiffnessMatrixCoord(Ke,node_list,numnodes,cs_list);5790 5791 /*Clean up and return*/5792 xDelete<int>(cs_list);5793 delete gauss;5794 delete friction;5795 return Ke;5796 }5797 /*}}}*/5798 /*FUNCTION Penta::CreateKMatrixCouplingHOFS{{{*/5799 ElementMatrix* Penta::CreateKMatrixCouplingHOFS(void){5800 5801 /*Constants*/5802 const int numnodes = 3 *NUMVERTICES+1;5803 const int numdofp = NDOF2 *NUMVERTICES;5804 const int numdofs = NDOF4 * 6 + NDOF3;5805 const int numdoftotal = (NDOF2+NDOF4) *NUMVERTICES + NDOF3;5806 5807 /*Intermediaries*/5808 int i,j,init;5809 Node *node_list[NUMVERTICES*3+1];5810 int cs_list[NUMVERTICES*3+1];5811 int cs_list2[NUMVERTICES*2+1];5812 5813 /*Some parameters needed*/5814 init=this->element_type;5815 5816 /*prepare node list*/5817 for(i=0;i<NUMVERTICES+1;i++){5818 node_list[i+NUMVERTICES] = this->nodes[i];5819 cs_list[i+NUMVERTICES] = XYZEnum;5820 cs_list2[i] = XYZEnum;5821 }5822 for(i=0;i<NUMVERTICES;i++){5823 node_list[i] = this->nodes[i];5824 node_list[i+2*NUMVERTICES+1] = this->nodes[i+NUMVERTICES+1];5825 cs_list[i] = XYEnum;5826 cs_list[i+2*NUMVERTICES+1] = PressureEnum;5827 cs_list2[i+NUMVERTICES+1] = PressureEnum;5828 }5829 5830 /*compute all stiffness matrices for this element*/5831 ElementMatrix* Ke1=new ElementMatrix(this->nodes,NUMVERTICES,this->parameters,HOApproximationEnum);5832 ElementMatrix* Ke2=new ElementMatrix(this->nodes,2*NUMVERTICES+1,this->parameters,FSvelocityEnum);5833 ElementMatrix* Ke=new ElementMatrix(Ke1,Ke2);5834 delete Ke1; delete Ke2;5835 5836 /*Compute HO Matrix with P1 element type\n");*/5837 this->element_type=P1Enum;5838 Ke1=CreateKMatrixStressbalanceHO(); TransformInvStiffnessMatrixCoord(Ke1,XYEnum);5839 this->element_type=init;5840 /*Compute FS Matrix and condense it \n");*/5841 Ke2=CreateKMatrixStressbalanceFS(); TransformInvStiffnessMatrixCoord(Ke2,node_list,2*NUMVERTICES+1,cs_list2);5842 int indices[3]={18,19,20};5843 Ke2->StaticCondensation(3,&indices[0]);5844 5845 for(i=0;i<numdofs;i++) for(j=0;j<NUMVERTICES;j++){5846 Ke->values[(i+numdofp)*numdoftotal+NDOF2*j+0]+=Ke2->values[i*numdofs+NDOF3*j+0];5847 Ke->values[(i+numdofp)*numdoftotal+NDOF2*j+1]+=Ke2->values[i*numdofs+NDOF3*j+1];5848 }5849 for(i=0;i<numdofp;i++) for(j=0;j<NUMVERTICES;j++){5850 Ke->values[i*numdoftotal+numdofp+NDOF3*j+0]+=Ke1->values[i*numdofp+NDOF2*j+0];5851 Ke->values[i*numdoftotal+numdofp+NDOF3*j+1]+=Ke1->values[i*numdofp+NDOF2*j+1];5852 }5853 5854 /*Transform Coordinate System*/ //Do not transform, already done in the matrices5855 ::TransformStiffnessMatrixCoord(Ke,node_list,numnodes,cs_list);5856 5857 /*clean-up and return*/5858 delete Ke1;5859 delete Ke2;5860 return Ke;5861 }5862 //*}}}*/5863 /*FUNCTION Penta::CreateKMatrixStressbalanceHoriz {{{*/5864 ElementMatrix* Penta::CreateKMatrixStressbalanceHoriz(void){5865 5866 int approximation;5867 inputs->GetInputValue(&approximation,ApproximationEnum);5868 switch(approximation){5869 case SSAApproximationEnum:5870 return CreateKMatrixStressbalanceSSA2d();5871 case L1L2ApproximationEnum:5872 return CreateKMatrixStressbalanceL1L2();5873 case HOApproximationEnum:5874 return CreateKMatrixStressbalanceHO();5875 case FSApproximationEnum:5876 return CreateKMatrixStressbalanceFS();5877 case SIAApproximationEnum:5878 return NULL;5879 case NoneApproximationEnum:5880 return NULL;5881 case SSAHOApproximationEnum:5882 return CreateKMatrixStressbalanceSSAHO();5883 case SSAFSApproximationEnum:5884 return CreateKMatrixStressbalanceSSAFS();5885 case HOFSApproximationEnum:5886 return CreateKMatrixStressbalanceHOFS();5887 default:5888 _error_("Approximation " << EnumToStringx(approximation) << " not supported yet");5889 }5890 }5891 /*}}}*/5892 /*FUNCTION Penta::CreateKMatrixStressbalanceSIA{{{*/5893 ElementMatrix* Penta::CreateKMatrixStressbalanceSIA(void){5894 5895 /*Intermediaries*/5896 IssmDouble connectivity[2];5897 IssmDouble one0,one1;5898 int i,i0,i1,j0,j1;5899 5900 /*Fetch number of nodes and dof for this finite element*/5901 int numnodes = this->NumberofNodes(); _assert_(numnodes==6);5902 int numdof = numnodes*NDOF2;5903 5904 /*Initialize Element matrix*/5905 ElementMatrix* Ke=new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);5906 5907 /*3 vertical edges*/5908 for(i=0;i<3;i++){5909 5910 /*2 dofs of first node*/5911 i0=2*i; i1=2*i+1;5912 /*2 dofs of second node*/5913 j0=2*(i+3); j1=2*(i+3)+1;5914 5915 /*Find connectivity for the two nodes*/5916 connectivity[0]=(IssmDouble)vertices[i]->Connectivity();5917 connectivity[1]=(IssmDouble)vertices[i+3]->Connectivity();5918 one0=1./connectivity[0];5919 one1=1./connectivity[1];5920 5921 /*Create matrix for these two nodes*/5922 if (IsOnBed() && IsOnSurface()){5923 Ke->values[i0*numdof+i0] = +one0;5924 Ke->values[i1*numdof+i1] = +one0;5925 Ke->values[j0*numdof+i0] = -one1;5926 Ke->values[j0*numdof+j0] = +one1;5927 Ke->values[j1*numdof+i1] = -one1;5928 Ke->values[j1*numdof+j1] = +one1;5929 }5930 else if (IsOnBed()){5931 Ke->values[i0*numdof+i0] = one0;5932 Ke->values[i1*numdof+i1] = one0;5933 Ke->values[j0*numdof+i0] = -2.*one1;5934 Ke->values[j0*numdof+j0] = +2.*one1;5935 Ke->values[j1*numdof+i1] = -2.*one1;5936 Ke->values[j1*numdof+j1] = +2.*one1;5937 }5938 else if (IsOnSurface()){5939 Ke->values[j0*numdof+i0] = -one1;5940 Ke->values[j0*numdof+j0] = +one1;5941 Ke->values[j1*numdof+i1] = -one1;5942 Ke->values[j1*numdof+j1] = +one1;5943 }5944 else{ //node is on two horizontal layers and beams include the values only once, so the have to use half of the connectivity5945 Ke->values[j0*numdof+i0] = -2.*one1;5946 Ke->values[j0*numdof+j0] = +2.*one1;5947 Ke->values[j1*numdof+i1] = -2.*one1;5948 Ke->values[j1*numdof+j1] = +2.*one1;5949 }5950 }5951 5952 /*Clean up and return*/5953 return Ke;5954 }/*}}}*/5955 /*FUNCTION Penta::CreateKMatrixStressbalanceSSA2d{{{*/5956 ElementMatrix* Penta::CreateKMatrixStressbalanceSSA2d(void){5957 5958 /*Figure out if this penta is collapsed. If so, then bailout, except if it is at the5959 bedrock, in which case we spawn a tria element using the 3 first nodes, and use it to build5960 the stiffness matrix. */5961 if (!IsOnBed()) return NULL;5962 5963 /*Depth average some fields*/5964 switch(this->material->ObjectEnum()){5965 case MaticeEnum:5966 this->InputDepthAverageAtBase(MaterialsRheologyBEnum,MaterialsRheologyBbarEnum,MaterialsEnum);5967 this->InputDepthAverageAtBase(DamageDEnum,DamageDbarEnum,MaterialsEnum);5968 break;5969 default:5970 _error_("material "<<EnumToStringx(this->material->ObjectEnum())<<" not supported");5971 }5972 5973 /*Call Tria function*/5974 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.5975 ElementMatrix* Ke=tria->CreateKMatrixStressbalanceSSA();5976 delete tria->material; delete tria;5977 5978 /*Delete averaged fields*/5979 this->material->inputs->DeleteInput(MaterialsRheologyBbarEnum);5980 this->material->inputs->DeleteInput(DamageDbarEnum);5981 5982 /*clean up and return*/5983 return Ke;5984 }5985 /*}}}*/5986 /*FUNCTION Penta::CreateKMatrixStressbalanceSSA3d{{{*/5987 ElementMatrix* Penta::CreateKMatrixStressbalanceSSA3d(void){5988 5989 /*compute all stiffness matrices for this element*/5990 ElementMatrix* Ke1=CreateKMatrixStressbalanceSSA3dViscous();5991 ElementMatrix* Ke2=CreateKMatrixStressbalanceSSA3dFriction();5992 ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);5993 5994 /*clean-up and return*/5995 delete Ke1;5996 delete Ke2;5997 return Ke;5998 }5999 /*}}}*/6000 /*FUNCTION Penta::CreateKMatrixStressbalanceSSA3dViscous{{{*/6001 ElementMatrix* Penta::CreateKMatrixStressbalanceSSA3dViscous(void){6002 6003 /*Constants*/6004 const int numdof2d=2*NUMVERTICES2D;6005 6006 /*Intermediaries */6007 int i,j,approximation;6008 IssmDouble Jdet;6009 IssmDouble viscosity , oldviscosity, newviscosity, viscosity_overshoot;6010 IssmDouble epsilon[5],oldepsilon[5]; /* epsilon=[exx,eyy,exy,exz,eyz];*/6011 IssmDouble epsilons[6]; //6 for FS6012 IssmDouble xyz_list[NUMVERTICES][3];6013 IssmDouble B[3][numdof2d];6014 IssmDouble Bprime[3][numdof2d];6015 IssmDouble D[3][3]= {0.0}; // material matrix, simple scalar matrix.6016 IssmDouble D_scalar;6017 IssmDouble Ke_gg_gaussian[numdof2d][numdof2d];6018 Tria *tria = NULL;6019 Penta *pentabase = NULL;6020 GaussPenta *gauss = NULL;6021 GaussTria *gauss_tria = NULL;6022 6023 /*Find penta on bed as this is a SSA elements: */6024 pentabase=(Penta*)GetBasalElement();6025 tria=pentabase->SpawnTria(0); //lower face is 0, upper face is 1.6026 6027 /*Initialize Element matrix*/6028 ElementMatrix* Ke=new ElementMatrix(tria->nodes,NUMVERTICES2D,this->parameters,SSAApproximationEnum);6029 inputs->GetInputValue(&approximation,ApproximationEnum);6030 6031 /*Retrieve all inputs and parameters*/6032 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6033 this->parameters->FindParam(&viscosity_overshoot,StressbalanceViscosityOvershootEnum);6034 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);6035 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);6036 Input* vxold_input=inputs->GetInput(VxPicardEnum); _assert_(vxold_input);6037 Input* vyold_input=inputs->GetInput(VyPicardEnum); _assert_(vyold_input);6038 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);6039 6040 /* Start looping on the number of gaussian points: */6041 gauss=new GaussPenta(5,5);6042 gauss_tria=new GaussTria();6043 for(int ig=gauss->begin();ig<gauss->end();ig++){6044 6045 gauss->GaussPoint(ig);6046 gauss->SynchronizeGaussBase(gauss_tria);6047 6048 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);6049 tria->GetBSSA(&B[0][0], &xyz_list[0][0], gauss_tria);6050 tria->GetBprimeSSA(&Bprime[0][0], &xyz_list[0][0], gauss_tria);6051 6052 if(approximation==SSAHOApproximationEnum){6053 this->StrainRateHO(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);6054 this->StrainRateHO(&oldepsilon[0],&xyz_list[0][0],gauss,vxold_input,vyold_input);6055 material->GetViscosity3d(&viscosity, &epsilon[0]);6056 material->GetViscosity3d(&oldviscosity, &oldepsilon[0]);6057 6058 newviscosity=viscosity+viscosity_overshoot*(viscosity-oldviscosity);6059 }6060 else if (approximation==SSAFSApproximationEnum){6061 this->StrainRateFS(&epsilons[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);6062 material->GetViscosity3dFS(&newviscosity,&epsilons[0]);6063 }6064 else _error_("approximation " << approximation << " (" << EnumToStringx(approximation) << ") not supported yet");6065 6066 D_scalar=2*newviscosity*gauss->weight*Jdet;6067 for (i=0;i<3;i++) D[i][i]=D_scalar;6068 6069 TripleMultiply( &B[0][0],3,numdof2d,1,6070 &D[0][0],3,3,0,6071 &Bprime[0][0],3,numdof2d,0,6072 &Ke_gg_gaussian[0][0],0);6073 6074 for(i=0;i<numdof2d;i++) for(j=0;j<numdof2d;j++) Ke->values[i*numdof2d+j]+=Ke_gg_gaussian[i][j];6075 }6076 6077 /*Transform Coordinate System*/6078 ::TransformStiffnessMatrixCoord(Ke,tria->nodes,NUMVERTICES2D,XYEnum);6079 6080 /*Clean up and return*/6081 delete tria->material;6082 delete tria;6083 delete gauss_tria;6084 delete gauss;6085 return Ke;6086 }6087 /*}}}*/6088 /*FUNCTION Penta::CreateKMatrixStressbalanceSSA3dFriction{{{*/6089 ElementMatrix* Penta::CreateKMatrixStressbalanceSSA3dFriction(void){6090 6091 /*Initialize Element matrix and return if necessary*/6092 if(IsFloating() || !IsOnBed()) return NULL;6093 6094 /*Build a tria element using the 3 nodes of the base of the penta. Then use6095 * the tria functionality to build a friction stiffness matrix on these 36096 * nodes: */6097 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.6098 ElementMatrix* Ke=tria->CreateKMatrixStressbalanceSSAFriction();6099 delete tria->material; delete tria;6100 6101 /*clean-up and return*/6102 return Ke;6103 }6104 /*}}}*/6105 /*FUNCTION Penta::CreateKMatrixStressbalanceSSAHO{{{*/6106 ElementMatrix* Penta::CreateKMatrixStressbalanceSSAHO(void){6107 6108 /*compute all stiffness matrices for this element*/6109 ElementMatrix* Ke1=CreateKMatrixStressbalanceSSA3d();6110 ElementMatrix* Ke2=CreateKMatrixStressbalanceHO();6111 ElementMatrix* Ke3=CreateKMatrixCouplingSSAHO();6112 ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2,Ke3);6113 6114 /*clean-up and return*/6115 delete Ke1;6116 delete Ke2;6117 delete Ke3;6118 return Ke;6119 }6120 /*}}}*/6121 /*FUNCTION Penta::CreateKMatrixStressbalanceSSAFS{{{*/6122 ElementMatrix* Penta::CreateKMatrixStressbalanceSSAFS(void){6123 6124 /*compute all stiffness matrices for this element*/6125 ElementMatrix* Ke1=CreateKMatrixStressbalanceFS();6126 int indices[3]={18,19,20};6127 Ke1->StaticCondensation(3,&indices[0]);6128 int init = this->element_type;6129 this->element_type=P1Enum; //P1 needed for HO6130 ElementMatrix* Ke2=CreateKMatrixStressbalanceSSA3d();6131 this->element_type=init;6132 ElementMatrix* Ke3=CreateKMatrixCouplingSSAFS();6133 ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2,Ke3);6134 6135 /*clean-up and return*/6136 delete Ke1;6137 delete Ke2;6138 delete Ke3;6139 return Ke;6140 }6141 /*}}}*/6142 /*FUNCTION Penta::CreateKMatrixStressbalanceL1L2{{{*/6143 ElementMatrix* Penta::CreateKMatrixStressbalanceL1L2(void){6144 6145 /*compute all stiffness matrices for this element*/6146 ElementMatrix* Ke1=CreateKMatrixStressbalanceL1L2Viscous();6147 ElementMatrix* Ke2=CreateKMatrixStressbalanceL1L2Friction();6148 ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);6149 6150 /*clean-up and return*/6151 delete Ke1;6152 delete Ke2;6153 return Ke;6154 }6155 /*}}}*/6156 /*FUNCTION Penta::CreateKMatrixStressbalanceL1L2Viscous{{{*/6157 ElementMatrix* Penta::CreateKMatrixStressbalanceL1L2Viscous(void){6158 6159 /*Constants*/6160 const int numdof2d=2*NUMVERTICES2D;6161 6162 /*Intermediaries */6163 int i,j;6164 IssmDouble Jdet,viscosity;6165 IssmDouble xyz_list[NUMVERTICES][3];6166 IssmDouble B[3][numdof2d];6167 IssmDouble Bprime[3][numdof2d];6168 IssmDouble Ke_gg_gaussian[numdof2d][numdof2d];6169 IssmDouble D[3][3]= {0.0}; // material matrix, simple scalar matrix.6170 Tria *tria = NULL;6171 Penta *pentabase = NULL;6172 GaussPenta *gauss = NULL;6173 GaussTria *gauss_tria = NULL;6174 6175 /*Find penta on bed as this is a SSA elements: */6176 pentabase=(Penta*)GetBasalElement();6177 tria=pentabase->SpawnTria(0); //lower face is 0, upper face is 1.6178 6179 /*Initialize Element matrix*/6180 ElementMatrix* Ke=new ElementMatrix(tria->nodes,NUMVERTICES2D,this->parameters,L1L2ApproximationEnum);6181 6182 /*Retrieve all inputs and parameters*/6183 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6184 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);6185 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);6186 Input* surf_input=inputs->GetInput(SurfaceEnum); _assert_(surf_input);6187 6188 /* Start looping on the number of gaussian points: */6189 gauss=new GaussPenta(5,5);6190 gauss_tria=new GaussTria();6191 for(int ig=gauss->begin();ig<gauss->end();ig++){6192 6193 gauss->GaussPoint(ig);6194 gauss->SynchronizeGaussBase(gauss_tria);6195 6196 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);6197 tria->GetBSSA(&B[0][0], &xyz_list[0][0], gauss_tria);6198 tria->GetBprimeSSA(&Bprime[0][0], &xyz_list[0][0], gauss_tria);6199 6200 /*Get viscosity for L1L2 model*/6201 ViscosityL1L2(&viscosity,&xyz_list[0][0],gauss,vx_input,vy_input,surf_input);6202 6203 for(i=0;i<3;i++) D[i][i]=2*viscosity*gauss->weight*Jdet;6204 6205 TripleMultiply( &B[0][0],3,numdof2d,1,6206 &D[0][0],3,3,0,6207 &Bprime[0][0],3,numdof2d,0,6208 &Ke_gg_gaussian[0][0],0);6209 for(i=0;i<numdof2d;i++) for(j=0;j<numdof2d;j++) Ke->values[i*numdof2d+j]+=Ke_gg_gaussian[i][j];6210 }6211 6212 /*Transform Coordinate System*/6213 ::TransformStiffnessMatrixCoord(Ke,tria->nodes,NUMVERTICES2D,XYEnum);6214 6215 /*Clean up and return*/6216 delete tria->material;6217 delete tria;6218 delete gauss_tria;6219 delete gauss;6220 return Ke;6221 }6222 /*}}}*/6223 /*FUNCTION Penta::CreateKMatrixStressbalanceL1L2Friction{{{*/6224 ElementMatrix* Penta::CreateKMatrixStressbalanceL1L2Friction(void){6225 6226 /*Initialize Element matrix and return if necessary*/6227 if(IsFloating() || !IsOnBed()) return NULL;6228 6229 /*Build a tria element using the 3 nodes of the base of the penta. Then use6230 * the tria functionality to build a friction stiffness matrix on these 36231 * nodes: */6232 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.6233 ElementMatrix* Ke=tria->CreateKMatrixStressbalanceSSAFriction();6234 delete tria->material; delete tria;6235 6236 /*clean-up and return*/6237 return Ke;6238 }6239 /*}}}*/6240 /*FUNCTION Penta::CreateKMatrixStressbalanceHO{{{*/6241 ElementMatrix* Penta::CreateKMatrixStressbalanceHO(void){6242 6243 /*compute all stiffness matrices for this element*/6244 ElementMatrix* Ke1=CreateKMatrixStressbalanceHOViscous();6245 ElementMatrix* Ke2=CreateKMatrixStressbalanceHOFriction();6246 ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);6247 6248 /*clean-up and return*/6249 delete Ke1;6250 delete Ke2;6251 return Ke;6252 6253 }6254 /*}}}*/6255 /*FUNCTION Penta::CreateKMatrixStressbalanceHOViscous{{{*/6256 ElementMatrix* Penta::CreateKMatrixStressbalanceHOViscous(void){6257 6258 /*Intermediaries */6259 int approximation;6260 IssmDouble xyz_list[NUMVERTICES][3];6261 IssmDouble Jdet;6262 IssmDouble viscosity,oldviscosity,newviscosity,viscosity_overshoot; //viscosity6263 IssmDouble epsilon[5],oldepsilon[5]; /* epsilon=[exx,eyy,exy,exz,eyz];*/6264 IssmDouble D_scalar;6265 GaussPenta *gauss=NULL;6266 6267 /*Fetch number of nodes and dof for this finite element*/6268 int numnodes = this->NumberofNodes();6269 int numdof = numnodes*NDOF2;6270 6271 /*Initialize Element matrix and vectors*/6272 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters,HOApproximationEnum);6273 IssmDouble* B = xNew<IssmDouble>(5*numdof);6274 IssmDouble* Bprime = xNew<IssmDouble>(5*numdof);6275 IssmDouble* D = xNewZeroInit<IssmDouble>(5*5);6276 6277 /*Retrieve all inputs and parameters*/6278 inputs->GetInputValue(&approximation,ApproximationEnum);6279 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6280 this->parameters->FindParam(&viscosity_overshoot,StressbalanceViscosityOvershootEnum);6281 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);6282 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);6283 Input* vxold_input=inputs->GetInput(VxPicardEnum); _assert_(vxold_input);6284 Input* vyold_input=inputs->GetInput(VyPicardEnum); _assert_(vyold_input);6285 6286 /* Start looping on the number of gaussian points: */6287 gauss=new GaussPenta(5,5);6288 for(int ig=gauss->begin();ig<gauss->end();ig++){6289 6290 gauss->GaussPoint(ig);6291 6292 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);6293 GetBHO(&B[0], &xyz_list[0][0], gauss);6294 GetBprimeHO(&Bprime[0], &xyz_list[0][0], gauss);6295 6296 this->StrainRateHO(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);6297 this->StrainRateHO(&oldepsilon[0],&xyz_list[0][0],gauss,vxold_input,vyold_input);6298 material->GetViscosity3d(&viscosity, &epsilon[0]);6299 material->GetViscosity3d(&oldviscosity, &oldepsilon[0]);6300 newviscosity=viscosity+viscosity_overshoot*(viscosity-oldviscosity);6301 6302 D_scalar=2*newviscosity*gauss->weight*Jdet;6303 for(int i=0;i<5;i++) D[i*5+i]=D_scalar;6304 6305 TripleMultiply(B,5,numdof,1,6306 D,5,5,0,6307 Bprime,5,numdof,0,6308 &Ke->values[0],1);6309 }6310 6311 /*Transform Coordinate System*/6312 ::TransformStiffnessMatrixCoord(Ke,nodes,numnodes,XYEnum);6313 6314 /*Clean up and return*/6315 delete gauss;6316 xDelete<IssmDouble>(D);6317 xDelete<IssmDouble>(Bprime);6318 xDelete<IssmDouble>(B);6319 return Ke;6320 }6321 /*}}}*/6322 /*FUNCTION Penta::CreateKMatrixStressbalanceHOFriction{{{*/6323 ElementMatrix* Penta::CreateKMatrixStressbalanceHOFriction(void){6324 6325 /*Intermediaries */6326 bool mainlyfloating;6327 int i,j;6328 int analysis_type,migration_style;6329 int point1;6330 IssmDouble xyz_list[NUMVERTICES][3];6331 IssmDouble xyz_list_tria[NUMVERTICES2D][3];6332 IssmDouble alpha2,Jdet;6333 IssmDouble fraction1,fraction2;6334 IssmDouble gllevelset;6335 IssmDouble phi=1.0;6336 IssmDouble DL_scalar;6337 Friction *friction = NULL;6338 GaussPenta *gauss = NULL;6339 6340 /*Initialize Element matrix and return if necessary*/6341 if(IsFloating() || !IsOnBed()) return NULL;6342 6343 /*Fetch number of nodes and dof for this finite element*/6344 int numnodes = this->NumberofNodes();6345 int numdof = numnodes*NDOF2;6346 6347 /*Initialize Element matrix and vectors*/6348 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters,HOApproximationEnum);6349 IssmDouble* B = xNew<IssmDouble>(2*numdof);6350 IssmDouble* D = xNewZeroInit<IssmDouble>(2*2);6351 6352 /*Retrieve all inputs and parameters*/6353 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6354 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];6355 parameters->FindParam(&migration_style,GroundinglineMigrationEnum);6356 parameters->FindParam(&analysis_type,AnalysisTypeEnum);6357 Input* surface_input=inputs->GetInput(SurfaceEnum); _assert_(surface_input);6358 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);6359 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);6360 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);6361 Input* gllevelset_input=NULL;6362 6363 /*build friction object, used later on: */6364 friction=new Friction(this,2);6365 6366 /*Recover portion of element that is grounded*/6367 if(migration_style==SubelementMigrationEnum) phi=this->GetGroundedPortion(&xyz_list_tria[0][0]);6368 if(migration_style==SubelementMigration2Enum){6369 gllevelset_input=inputs->GetInput(MaskGroundediceLevelsetEnum); _assert_(gllevelset_input);6370 this->GetGroundedPart(&point1,&fraction1,&fraction2,&mainlyfloating);6371 //gauss=new GaussPenta(point1,fraction1,fraction2,mainlyfloating,2);6372 gauss=new GaussPenta(0,1,2,2);6373 }6374 else{6375 gauss=new GaussPenta(0,1,2,2);6376 }6377 6378 /* Start looping on the number of gaussian points: */6379 for(int ig=gauss->begin();ig<gauss->end();ig++){6380 6381 gauss->GaussPoint(ig);6382 6383 GetTriaJacobianDeterminant(&Jdet,&xyz_list_tria[0][0],gauss);6384 GetBHOFriction(&B[0],gauss);6385 6386 friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);6387 if(migration_style==SubelementMigrationEnum) alpha2=phi*alpha2;6388 if(migration_style==SubelementMigration2Enum){6389 gllevelset_input->GetInputValue(&gllevelset, gauss);6390 if(gllevelset<0) alpha2=0;6391 }6392 6393 DL_scalar=alpha2*gauss->weight*Jdet;6394 for (i=0;i<2;i++) D[i*2+i]=DL_scalar;6395 6396 TripleMultiply(B,2,numdof,1,6397 D,2,2,0,6398 B,2,numdof,0,6399 &Ke->values[0],1);6400 }6401 6402 /*Transform Coordinate System*/6403 ::TransformStiffnessMatrixCoord(Ke,nodes,numnodes,XYEnum);6404 6405 /*Clean up and return*/6406 delete gauss;6407 xDelete<IssmDouble>(D);6408 xDelete<IssmDouble>(B);6409 delete friction;6410 return Ke;6411 }6412 /*}}}*/6413 /*FUNCTION Penta::CreateKMatrixStressbalanceHOFS{{{*/6414 ElementMatrix* Penta::CreateKMatrixStressbalanceHOFS(void){6415 6416 /*compute all stiffness matrices for this element*/6417 ElementMatrix* Ke1=CreateKMatrixStressbalanceFS();6418 int indices[3]={18,19,20};6419 Ke1->StaticCondensation(3,&indices[0]);6420 int init = this->element_type;6421 this->element_type=P1Enum; //P1 needed for HO6422 ElementMatrix* Ke2=CreateKMatrixStressbalanceHO();6423 this->element_type=init;6424 ElementMatrix* Ke3=CreateKMatrixCouplingHOFS();6425 ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2,Ke3);6426 6427 /*clean-up and return*/6428 delete Ke1;6429 delete Ke2;6430 delete Ke3;6431 return Ke;6432 }6433 /*}}}*/6434 /*FUNCTION Penta::CreateKMatrixStressbalanceFS{{{*/6435 ElementMatrix* Penta::CreateKMatrixStressbalanceFS(void){6436 6437 ElementMatrix* Ke1 = NULL;6438 ElementMatrix* Ke2 = NULL;6439 ElementMatrix* Ke = NULL;6440 6441 /*compute all stiffness matrices for this element*/6442 Ke1=CreateKMatrixStressbalanceFSViscous();6443 Ke2=CreateKMatrixStressbalanceFSFriction();6444 Ke =new ElementMatrix(Ke1,Ke2);6445 6446 /*clean-up and return*/6447 delete Ke1;6448 delete Ke2;6449 return Ke;6450 6451 }6452 /*}}}*/6453 4522 /*FUNCTION Penta::KMatrixGLSstabilization{{{*/ 6454 4523 void Penta::KMatrixGLSstabilization(ElementMatrix* Ke){ … … 6556 4625 } 6557 4626 /*}}}*/ 6558 /*FUNCTION Penta::CreateKMatrixStressbalanceFSViscous {{{*/6559 ElementMatrix* Penta::CreateKMatrixStressbalanceFSViscous(void){6560 6561 /*Intermediaries */6562 int i,approximation;6563 IssmDouble Jdet,viscosity,FSreconditioning,D_scalar;6564 IssmDouble xyz_list[NUMVERTICES][3];6565 IssmDouble epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/6566 GaussPenta *gauss=NULL;6567 6568 /*If on water or not FS, skip stiffness: */6569 inputs->GetInputValue(&approximation,ApproximationEnum);6570 if(approximation!=FSApproximationEnum && approximation!=SSAFSApproximationEnum && approximation!=HOFSApproximationEnum) return NULL;6571 6572 /*Fetch number of nodes and dof for this finite element*/6573 int vnumnodes = this->NumberofNodesVelocity();6574 int pnumnodes = this->NumberofNodesPressure();6575 int numdof = vnumnodes*NDOF3 + pnumnodes*NDOF1;6576 6577 /*Prepare coordinate system list*/6578 int* cs_list = xNew<int>(vnumnodes+pnumnodes);6579 for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;6580 for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;6581 6582 /*Initialize Element matrix and vectors*/6583 ElementMatrix* Ke = new ElementMatrix(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);6584 IssmDouble* B = xNew<IssmDouble>(8*numdof);6585 IssmDouble* Bprime = xNew<IssmDouble>(8*numdof);6586 IssmDouble* D = xNewZeroInit<IssmDouble>(8*8);6587 6588 /*Retrieve all inputs and parameters*/6589 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6590 parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);6591 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);6592 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);6593 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);6594 6595 /* Start looping on the number of gaussian points: */6596 gauss=new GaussPenta(5,5);6597 for(int ig=gauss->begin();ig<gauss->end();ig++){6598 6599 gauss->GaussPoint(ig);6600 6601 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);6602 GetBFS(B,&xyz_list[0][0],gauss);6603 GetBprimeFS(Bprime,&xyz_list[0][0],gauss);6604 6605 this->StrainRateFS(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);6606 material->GetViscosity3dFS(&viscosity,&epsilon[0]);6607 6608 D_scalar=gauss->weight*Jdet;6609 for(i=0;i<6;i++) D[i*8+i] = +D_scalar*2.*viscosity;6610 for(i=6;i<8;i++) D[i*8+i] = -D_scalar*FSreconditioning;6611 6612 TripleMultiply(B,8,numdof,1,6613 D,8,8,0,6614 Bprime,8,numdof,0,6615 Ke->values,1);6616 }6617 6618 /*Transform Coordinate System*/6619 ::TransformStiffnessMatrixCoord(Ke,nodes,(vnumnodes+pnumnodes),cs_list);6620 6621 /*Clean up and return*/6622 delete gauss;6623 xDelete<int>(cs_list);6624 xDelete<IssmDouble>(B);6625 xDelete<IssmDouble>(Bprime);6626 xDelete<IssmDouble>(D);6627 return Ke;6628 }6629 /*}}}*/6630 /*FUNCTION Penta::CreateKMatrixStressbalanceFSFriction{{{*/6631 ElementMatrix* Penta::CreateKMatrixStressbalanceFSFriction(void){6632 6633 /*Intermediaries */6634 int i,j;6635 int analysis_type,approximation;6636 IssmDouble alpha2,Jdet2d;6637 IssmDouble xyz_list[NUMVERTICES][3];6638 IssmDouble xyz_list_tria[NUMVERTICES2D][3];6639 Friction *friction = NULL;6640 GaussPenta *gauss = NULL;6641 6642 /*Initialize Element matrix and return if necessary*/6643 if(IsFloating() || !IsOnBed()) return NULL;6644 6645 /*If on water or not FS, skip stiffness: */6646 inputs->GetInputValue(&approximation,ApproximationEnum);6647 if(approximation!=FSApproximationEnum && approximation!=SSAFSApproximationEnum && approximation!=HOFSApproximationEnum) return NULL;6648 6649 /*Fetch number of nodes and dof for this finite element*/6650 int vnumnodes = this->NumberofNodesVelocity();6651 int pnumnodes = this->NumberofNodesPressure();6652 int numdof = vnumnodes*NDOF3 + pnumnodes*NDOF1;6653 6654 /*Initialize Element matrix and vectors*/6655 ElementMatrix* Ke = new ElementMatrix(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);6656 IssmDouble* BFriction = xNew<IssmDouble>(2*numdof);6657 IssmDouble* D = xNewZeroInit<IssmDouble>(2*2);6658 6659 /*Retrieve all inputs and parameters*/6660 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6661 parameters->FindParam(&analysis_type,AnalysisTypeEnum);6662 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);6663 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);6664 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);6665 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];6666 6667 /*build friction object, used later on: */6668 friction=new Friction(this,3);6669 6670 /* Start looping on the number of gaussian points: */6671 gauss=new GaussPenta(0,1,2,3);6672 for(int ig=gauss->begin();ig<gauss->end();ig++){6673 6674 gauss->GaussPoint(ig);6675 6676 GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0],gauss);6677 GetLFS(BFriction,gauss);6678 6679 friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);6680 6681 D[0*2+0] = +alpha2*gauss->weight*Jdet2d; //taub_x = -alpha2 vx6682 D[1*2+1] = +alpha2*gauss->weight*Jdet2d; //taub_y = -alpha2 vy6683 6684 TripleMultiply(BFriction,2,numdof,1,6685 D,2,2,0,6686 BFriction,2,numdof,0,6687 Ke->values,1);6688 }6689 6690 /*DO NOT Transform Coordinate System: this stiffness matrix is already expressed in tangential coordinates*/6691 //::TransformStiffnessMatrixCoord(Ke,nodes,NUMVERTICES,XYZEnum);6692 6693 /*Clean up and return*/6694 delete gauss;6695 delete friction;6696 xDelete<IssmDouble>(BFriction);6697 xDelete<IssmDouble>(D);6698 return Ke;6699 }6700 /*}}}*/6701 /*FUNCTION Penta::CreateKMatrixStressbalanceVert {{{*/6702 ElementMatrix* Penta::CreateKMatrixStressbalanceVert(void){6703 6704 /*compute all stiffness matrices for this element*/6705 ElementMatrix* Ke1=CreateKMatrixStressbalanceVertVolume();6706 ElementMatrix* Ke2=CreateKMatrixStressbalanceVertSurface();6707 ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);6708 6709 /*clean-up and return*/6710 delete Ke1;6711 delete Ke2;6712 return Ke;6713 6714 }6715 /*}}}*/6716 /*FUNCTION Penta::CreateKMatrixStressbalanceVertVolume {{{*/6717 ElementMatrix* Penta::CreateKMatrixStressbalanceVertVolume(void){6718 6719 /*Intermediaries */6720 IssmDouble Jdet;6721 IssmDouble xyz_list[NUMVERTICES][3];6722 IssmDouble B[NDOF1][NUMVERTICES];6723 IssmDouble Bprime[NDOF1][NUMVERTICES];6724 IssmDouble DL_scalar;6725 GaussPenta *gauss=NULL;6726 6727 /*Initialize Element matrix*/6728 ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters,NoneApproximationEnum);6729 6730 /*Retrieve all inputs and parameters*/6731 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6732 6733 /* Start looping on the number of gaussian points: */6734 gauss=new GaussPenta(2,2);6735 for(int ig=gauss->begin();ig<gauss->end();ig++){6736 6737 gauss->GaussPoint(ig);6738 6739 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);6740 GetBVert(&B[0][0], &xyz_list[0][0], gauss);6741 GetBprimeVert(&Bprime[0][0], &xyz_list[0][0], gauss);6742 6743 DL_scalar=gauss->weight*Jdet;6744 6745 TripleMultiply( &B[0][0],1,NUMVERTICES,1,6746 &DL_scalar,1,1,0,6747 &Bprime[0][0],1,NUMVERTICES,0,6748 &Ke->values[0],1);6749 }6750 6751 /*Clean up and return*/6752 delete gauss;6753 return Ke;6754 }6755 /*}}}*/6756 /*FUNCTION Penta::CreateKMatrixStressbalanceVertSurface {{{*/6757 ElementMatrix* Penta::CreateKMatrixStressbalanceVertSurface(void){6758 6759 if (!IsOnSurface()) return NULL;6760 6761 /*Constants*/6762 const int numdof=NDOF1*NUMVERTICES;6763 6764 /*Intermediaries */6765 int i,j;6766 IssmDouble xyz_list[NUMVERTICES][3];6767 IssmDouble xyz_list_tria[NUMVERTICES2D][3];6768 IssmDouble surface_normal[3];6769 IssmDouble Jdet2d,DL_scalar;6770 IssmDouble basis[NUMVERTICES];6771 GaussPenta *gauss=NULL;6772 6773 /*Initialize Element matrix*/6774 ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters,NoneApproximationEnum);6775 6776 /*Retrieve all inputs and parameters*/6777 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6778 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i+3][j];6779 NormalTop(&surface_normal[0],&xyz_list_tria[0][0]);6780 6781 /* Start looping on the number of gaussian points: */6782 gauss=new GaussPenta(3,4,5,2);6783 for(int ig=gauss->begin();ig<gauss->end();ig++){6784 6785 gauss->GaussPoint(ig);6786 6787 GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0],gauss);6788 GetNodalFunctionsP1(&basis[0], gauss);6789 6790 DL_scalar= - gauss->weight*Jdet2d*surface_normal[2];6791 6792 TripleMultiply( basis,1,numdof,1,6793 &DL_scalar,1,1,0,6794 basis,1,numdof,0,6795 &Ke->values[0],1);6796 }6797 6798 /*Clean up and return*/6799 delete gauss;6800 return Ke;6801 }6802 /*}}}*/6803 /*FUNCTION Penta::CreateJacobianStressbalanceHoriz{{{*/6804 ElementMatrix* Penta::CreateJacobianStressbalanceHoriz(void){6805 6806 int approximation;6807 inputs->GetInputValue(&approximation,ApproximationEnum);6808 6809 switch(approximation){6810 case SSAApproximationEnum:6811 return CreateJacobianStressbalanceSSA2d();6812 case HOApproximationEnum:6813 return CreateJacobianStressbalanceHO();6814 case FSApproximationEnum:6815 return CreateJacobianStressbalanceFS();6816 case NoneApproximationEnum:6817 return NULL;6818 default:6819 _error_("Approximation " << EnumToStringx(approximation) << " not supported yet");6820 }6821 }6822 /*}}}*/6823 /*FUNCTION Penta::CreateJacobianStressbalanceSSA2d{{{*/6824 ElementMatrix* Penta::CreateJacobianStressbalanceSSA2d(void){6825 6826 /*Figure out if this penta is collapsed. If so, then bailout, except if it is at the6827 bedrock, in which case we spawn a tria element using the 3 first nodes, and use it to build6828 the stiffness matrix. */6829 if (!IsOnBed()) return NULL;6830 6831 /*Depth average some fields*/6832 switch(this->material->ObjectEnum()){6833 case MaticeEnum:6834 this->InputDepthAverageAtBase(MaterialsRheologyBEnum,MaterialsRheologyBbarEnum,MaterialsEnum);6835 this->InputDepthAverageAtBase(DamageDEnum,DamageDbarEnum,MaterialsEnum);6836 break;6837 default:6838 _error_("material "<<EnumToStringx(this->material->ObjectEnum())<<" not supported");6839 }6840 6841 /*Call Tria function*/6842 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.6843 ElementMatrix* Ke=tria->CreateJacobianStressbalanceSSA();6844 delete tria->material; delete tria;6845 6846 /*Delete averaged inputs*/6847 this->material->inputs->DeleteInput(MaterialsRheologyBbarEnum);6848 this->material->inputs->DeleteInput(DamageDbarEnum);6849 6850 /*clean up and return*/6851 return Ke;6852 }6853 /*}}}*/6854 /*FUNCTION Penta::CreateJacobianStressbalanceHO{{{*/6855 ElementMatrix* Penta::CreateJacobianStressbalanceHO(void){6856 6857 /*Intermediaries */6858 int i,j;6859 IssmDouble xyz_list[NUMVERTICES][3];6860 IssmDouble Jdet;6861 IssmDouble eps1dotdphii,eps1dotdphij;6862 IssmDouble eps2dotdphii,eps2dotdphij;6863 IssmDouble mu_prime;6864 IssmDouble epsilon[5]; /* epsilon=[exx,eyy,exy,exz,eyz];*/6865 IssmDouble eps1[3],eps2[3];6866 IssmDouble dphi[3][NUMVERTICES];6867 GaussPenta *gauss=NULL;6868 6869 /*Initialize Jacobian with regular HO (first part of the Gateau derivative)*/6870 ElementMatrix* Ke=CreateKMatrixStressbalanceHO();6871 6872 /*Retrieve all inputs and parameters*/6873 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6874 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);6875 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);6876 6877 /* Start looping on the number of gaussian points: */6878 gauss=new GaussPenta(5,5);6879 for(int ig=gauss->begin();ig<gauss->end();ig++){6880 6881 gauss->GaussPoint(ig);6882 6883 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);6884 GetNodalFunctionsP1Derivatives(&dphi[0][0],&xyz_list[0][0],gauss);6885 6886 this->StrainRateHO(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);6887 material->GetViscosityDerivativeEpsSquare(&mu_prime,&epsilon[0]);6888 eps1[0]=2*epsilon[0]+epsilon[1]; eps2[0]=epsilon[2];6889 eps1[1]=epsilon[2]; eps2[1]=epsilon[0]+2*epsilon[1];6890 eps1[2]=epsilon[3]; eps2[2]=epsilon[4];6891 6892 for(i=0;i<6;i++){6893 for(j=0;j<6;j++){6894 eps1dotdphii=eps1[0]*dphi[0][i]+eps1[1]*dphi[1][i]+eps1[2]*dphi[2][i];6895 eps1dotdphij=eps1[0]*dphi[0][j]+eps1[1]*dphi[1][j]+eps1[2]*dphi[2][j];6896 eps2dotdphii=eps2[0]*dphi[0][i]+eps2[1]*dphi[1][i]+eps2[2]*dphi[2][i];6897 eps2dotdphij=eps2[0]*dphi[0][j]+eps2[1]*dphi[1][j]+eps2[2]*dphi[2][j];6898 6899 Ke->values[12*(2*i+0)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps1dotdphii;6900 Ke->values[12*(2*i+0)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps1dotdphii;6901 Ke->values[12*(2*i+1)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps2dotdphii;6902 Ke->values[12*(2*i+1)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps2dotdphii;6903 }6904 }6905 }6906 6907 /*Transform Coordinate System*/6908 ::TransformStiffnessMatrixCoord(Ke,nodes,NUMVERTICES,XYEnum);6909 6910 /*Clean up and return*/6911 delete gauss;6912 return Ke;6913 }6914 /*}}}*/6915 /*FUNCTION Penta::CreateJacobianStressbalanceFS{{{*/6916 ElementMatrix* Penta::CreateJacobianStressbalanceFS(void){6917 6918 /*Intermediaries */6919 int i,j;6920 IssmDouble xyz_list[NUMVERTICES][3];6921 IssmDouble Jdet;6922 IssmDouble eps1dotdphii,eps1dotdphij;6923 IssmDouble eps2dotdphii,eps2dotdphij;6924 IssmDouble eps3dotdphii,eps3dotdphij;6925 IssmDouble mu_prime;6926 IssmDouble epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/6927 IssmDouble eps1[3],eps2[3],eps3[3];6928 GaussPenta *gauss=NULL;6929 6930 /*If on water or not FS, skip stiffness: */6931 //inputs->GetInputValue(&approximation,ApproximationEnum);6932 //if(approximation!=FSApproximationEnum && approximation!=SSAFSApproximationEnum && approximation!=HOFSApproximationEnum) return NULL;6933 6934 /*Fetch number of nodes and dof for this finite element*/6935 int vnumnodes = this->NumberofNodesVelocity();6936 int pnumnodes = this->NumberofNodesPressure();6937 int numdof = vnumnodes*NDOF3 + pnumnodes*NDOF1;6938 6939 /*Prepare coordinate system list*/6940 int* cs_list = xNew<int>(vnumnodes+pnumnodes);6941 for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum;6942 for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;6943 6944 /*Initialize Jacobian with regular FS (first part of the Gateau derivative)*/6945 ElementMatrix* Ke=CreateKMatrixStressbalanceFS();6946 IssmDouble* dbasis = xNew<IssmDouble>(3*vnumnodes);6947 6948 /*Retrieve all inputs and parameters*/6949 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6950 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);6951 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);6952 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);6953 6954 /* Start looping on the number of gaussian points: */6955 gauss=new GaussPenta(5,5);6956 for(int ig=gauss->begin();ig<gauss->end();ig++){6957 6958 gauss->GaussPoint(ig);6959 6960 GetJacobianDeterminant(&Jdet,&xyz_list[0][0],gauss);6961 GetNodalFunctionsDerivativesVelocity(dbasis,&xyz_list[0][0],gauss);6962 6963 //this->StrainRateFS(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);6964 //material->GetViscosityDerivativeEpsSquareFS(&mu_prime,&epsilon[0]);6965 //eps1[0]=epsilon[0]; eps2[0]=epsilon[3]; eps3[0]=epsilon[4];6966 //eps1[1]=epsilon[3]; eps2[1]=epsilon[1]; eps3[1]=epsilon[5];6967 //eps1[2]=epsilon[4]; eps2[2]=epsilon[5]; eps3[2]=epsilon[2];6968 this->StrainRateHO(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);6969 material->GetViscosityDerivativeEpsSquare(&mu_prime,&epsilon[0]);6970 eps1[0]=epsilon[0]; eps2[0]=epsilon[2]; eps3[0]=epsilon[3];6971 eps1[1]=epsilon[2]; eps2[1]=epsilon[1]; eps3[1]=epsilon[4];6972 eps1[2]=epsilon[3]; eps2[2]=epsilon[4]; eps3[2]= -epsilon[0] -epsilon[1];6973 6974 for(i=0;i<vnumnodes-1;i++){6975 for(j=0;j<vnumnodes-1;j++){6976 eps1dotdphii=eps1[0]*dbasis[0*vnumnodes+i]+eps1[1]*dbasis[1*vnumnodes+i]+eps1[2]*dbasis[2*vnumnodes+i];6977 eps1dotdphij=eps1[0]*dbasis[0*vnumnodes+j]+eps1[1]*dbasis[1*vnumnodes+j]+eps1[2]*dbasis[2*vnumnodes+j];6978 eps2dotdphii=eps2[0]*dbasis[0*vnumnodes+i]+eps2[1]*dbasis[1*vnumnodes+i]+eps2[2]*dbasis[2*vnumnodes+i];6979 eps2dotdphij=eps2[0]*dbasis[0*vnumnodes+j]+eps2[1]*dbasis[1*vnumnodes+j]+eps2[2]*dbasis[2*vnumnodes+j];6980 eps3dotdphii=eps3[0]*dbasis[0*vnumnodes+i]+eps3[1]*dbasis[1*vnumnodes+i]+eps3[2]*dbasis[2*vnumnodes+i];6981 eps3dotdphij=eps3[0]*dbasis[0*vnumnodes+j]+eps3[1]*dbasis[1*vnumnodes+j]+eps3[2]*dbasis[2*vnumnodes+j];6982 6983 Ke->values[numdof*(3*i+0)+3*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps1dotdphii;6984 Ke->values[numdof*(3*i+0)+3*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps1dotdphii;6985 Ke->values[numdof*(3*i+0)+3*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps1dotdphii;6986 6987 Ke->values[numdof*(3*i+1)+3*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps2dotdphii;6988 Ke->values[numdof*(3*i+1)+3*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps2dotdphii;6989 Ke->values[numdof*(3*i+1)+3*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps2dotdphii;6990 6991 Ke->values[numdof*(3*i+2)+3*j+0]+=gauss->weight*Jdet*2*mu_prime*eps1dotdphij*eps3dotdphii;6992 Ke->values[numdof*(3*i+2)+3*j+1]+=gauss->weight*Jdet*2*mu_prime*eps2dotdphij*eps3dotdphii;6993 Ke->values[numdof*(3*i+2)+3*j+2]+=gauss->weight*Jdet*2*mu_prime*eps3dotdphij*eps3dotdphii;6994 }6995 }6996 }6997 6998 /*Transform Coordinate System*/6999 ::TransformStiffnessMatrixCoord(Ke,nodes,(vnumnodes+pnumnodes),cs_list);7000 7001 /*Clean up and return*/7002 xDelete<int>(cs_list);7003 xDelete<IssmDouble>(dbasis);7004 delete gauss;7005 return Ke;7006 }7007 /*}}}*/7008 4627 #endif 7009 4628 7010 #ifdef _HAVE_BALANCED_7011 /*FUNCTION Penta::CreateKMatrixBalancethickness {{{*/7012 ElementMatrix* Penta::CreateKMatrixBalancethickness(void){7013 7014 /*Figure out if this penta is collapsed. If so, then bailout, except if it is at the7015 bedrock, in which case we spawn a tria element using the 3 first nodes, and use it to build7016 the stiffness matrix. */7017 if (!IsOnBed()) return NULL;7018 7019 /*Depth Averaging Vx and Vy*/7020 this->InputDepthAverageAtBase(VxEnum,VxAverageEnum);7021 this->InputDepthAverageAtBase(VyEnum,VyAverageEnum);7022 7023 /*Spawn Tria element from the base of the Penta: */7024 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.7025 ElementMatrix* Ke=tria->CreateKMatrixBalancethickness();7026 delete tria->material; delete tria;7027 7028 /*Delete Vx and Vy averaged*/7029 this->inputs->DeleteInput(VxAverageEnum);7030 this->inputs->DeleteInput(VyAverageEnum);7031 7032 /*clean up and return*/7033 return Ke;7034 }7035 /*}}}*/7036 #endif7037 7038 4629 #ifdef _HAVE_HYDROLOGY_ 7039 /*FUNCTION Penta::CreateKMatrixHydrologyDCInefficient {{{*/7040 ElementMatrix* Penta::CreateKMatrixHydrologyDCInefficient(void){7041 7042 if (!IsOnBed()) return NULL;7043 7044 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.7045 ElementMatrix* Ke=tria->CreateKMatrixHydrologyDCInefficient();7046 delete tria->material; delete tria;7047 7048 /*clean up and return*/7049 return Ke;7050 }7051 /*}}}*/7052 /*FUNCTION Penta::CreateKMatrixHydrologyDCEfficient {{{*/7053 ElementMatrix* Penta::CreateKMatrixHydrologyDCEfficient(void){7054 7055 if (!IsOnBed()) return NULL;7056 7057 Tria* tria=(Tria*)SpawnTria(0); //lower face is 0, upper face is 1.7058 ElementMatrix* Ke=tria->CreateKMatrixHydrologyDCEfficient();7059 delete tria->material; delete tria;7060 7061 /*clean up and return*/7062 return Ke;7063 }7064 /*}}}*/7065 4630 /*FUNCTION Penta::CreateEPLDomainMassMatrix {{{*/ 7066 4631 ElementMatrix* Penta::CreateEPLDomainMassMatrix(void){ -
issm/trunk-jpl/src/c/classes/Elements/Penta.h
r16982 r16993 72 72 void SetwiseNodeConnectivity(int* d_nz,int* o_nz,Node* node,bool* flags,int* flagsindices,int set1_enum,int set2_enum); 73 73 void CreateDVector(Vector<IssmDouble>* df); 74 void CreateJacobianMatrix(Matrix<IssmDouble>* Jff);75 74 void Delta18oParameterization(void); 76 75 void EnthalpyToThermal(IssmDouble* ptemperature,IssmDouble* pwaterfraction,IssmDouble enthalpy,IssmDouble pressure); … … 195 194 void NormalTop(IssmDouble* bed_normal, IssmDouble* xyz_list); 196 195 ElementMatrix* CreateBasalMassMatrix(void); 197 ElementMatrix* CreateKMatrix(void);198 ElementMatrix* CreateKMatrixMasstransport(void);199 ElementMatrix* CreateKMatrixFreeSurfaceTop(void);200 ElementMatrix* CreateKMatrixFreeSurfaceBase(void);201 196 IssmDouble EnthalpyDiffusionParameter(IssmDouble enthalpy,IssmDouble pressure); 202 197 IssmDouble EnthalpyDiffusionParameterVolume(int numvertices,IssmDouble* enthalpy,IssmDouble* pressure); … … 260 255 261 256 #ifdef _HAVE_STRESSBALANCE_ 262 ElementMatrix* CreateKMatrixCouplingSSAHO(void);263 ElementMatrix* CreateKMatrixCouplingSSAHOViscous(void);264 ElementMatrix* CreateKMatrixCouplingSSAHOFriction(void);265 ElementMatrix* CreateKMatrixCouplingSSAFS(void);266 ElementMatrix* CreateKMatrixCouplingSSAFSViscous(void);267 ElementMatrix* CreateKMatrixCouplingSSAFSFriction(void);268 ElementMatrix* CreateKMatrixCouplingHOFS(void);269 ElementMatrix* CreateKMatrixStressbalanceHoriz(void);270 ElementMatrix* CreateKMatrixAdjointHoriz(void);271 257 ElementVector* CreateDVectorStressbalanceHoriz(void); 272 258 ElementVector* CreateDVectorStressbalanceFS(void); 273 ElementMatrix* CreateKMatrixStressbalanceSIA(void);274 ElementMatrix* CreateKMatrixStressbalanceSSA2d(void);275 ElementMatrix* CreateKMatrixStressbalanceSSA3d(void);276 ElementMatrix* CreateKMatrixStressbalanceSSA3dViscous(void);277 ElementMatrix* CreateKMatrixStressbalanceSSA3dFriction(void);278 ElementMatrix* CreateKMatrixStressbalanceSSAHO(void);279 ElementMatrix* CreateKMatrixStressbalanceSSAFS(void);280 ElementMatrix* CreateKMatrixStressbalanceL1L2(void);281 ElementMatrix* CreateKMatrixStressbalanceL1L2Viscous(void);282 ElementMatrix* CreateKMatrixStressbalanceL1L2Friction(void);283 ElementMatrix* CreateKMatrixStressbalanceHO(void);284 ElementMatrix* CreateKMatrixStressbalanceHOViscous(void);285 ElementMatrix* CreateKMatrixStressbalanceHOFriction(void);286 ElementMatrix* CreateKMatrixStressbalanceHOFS(void);287 ElementMatrix* CreateKMatrixStressbalanceFS(void);288 ElementMatrix* CreateKMatrixStressbalanceFSViscous(void);289 259 void KMatrixGLSstabilization(ElementMatrix* Ke); 290 ElementMatrix* CreateKMatrixStressbalanceFSFriction(void);291 ElementMatrix* CreateKMatrixStressbalanceVert(void);292 ElementMatrix* CreateKMatrixStressbalanceVertVolume(void);293 ElementMatrix* CreateKMatrixStressbalanceVertSurface(void);294 ElementMatrix* CreateJacobianStressbalanceHoriz(void);295 ElementMatrix* CreateJacobianStressbalanceSSA2d(void);296 ElementMatrix* CreateJacobianStressbalanceHO(void);297 ElementMatrix* CreateJacobianStressbalanceFS(void);298 #endif299 300 #ifdef _HAVE_CONTROL_301 ElementMatrix* CreateKMatrixAdjointSSA2d(void);302 ElementMatrix* CreateKMatrixAdjointHO(void);303 ElementMatrix* CreateKMatrixAdjointFS(void);304 260 #endif 305 261 306 262 #ifdef _HAVE_HYDROLOGY_ 307 ElementMatrix* CreateKMatrixHydrologyDCInefficient(void);308 ElementMatrix* CreateKMatrixHydrologyDCEfficient(void);309 263 ElementMatrix* CreateEPLDomainMassMatrix(void); 310 264 void GetHydrologyDCInefficientHmax(IssmDouble* ph_max, Node* innode); … … 319 273 void UpdateConstraintsExtrudeFromTop(void){_error_("not implemented yet");}; 320 274 #ifdef _HAVE_THERMAL_ 321 ElementMatrix* CreateKMatrixEnthalpy(void);322 ElementMatrix* CreateKMatrixEnthalpyVolume(void);323 ElementMatrix* CreateKMatrixEnthalpyShelf(void);324 ElementMatrix* CreateKMatrixThermal(void);325 ElementMatrix* CreateKMatrixMelting(void);326 ElementMatrix* CreateKMatrixThermalVolume(void);327 ElementMatrix* CreateKMatrixThermalShelf(void);328 275 void UpdateBasalConstraintsEnthalpy(void); 329 276 void ComputeBasalMeltingrate(void); 330 277 void DrainWaterfraction(IssmDouble* drainrate_element); 331 278 #endif 332 333 #ifdef _HAVE_BALANCED_334 ElementMatrix* CreateKMatrixBalancethickness(void);335 #endif336 279 /*}}}*/ 337 280 }; -
issm/trunk-jpl/src/c/classes/Elements/Seg.cpp
r16982 r16993 138 138 } 139 139 /*}}}*/ 140 /*FUNCTION Seg::CreateKMatrixFreeSurfaceTop {{{*/141 ElementMatrix* Seg::CreateKMatrixFreeSurfaceTop(void){142 143 /*Intermediaries */144 int stabilization;145 IssmDouble Jdet,D_scalar,dt,h;146 IssmDouble vx,vel;147 IssmDouble xyz_list[NUMVERTICES][3];148 149 /*Fetch number of nodes for this finite element*/150 int numnodes = this->NumberofNodes();151 152 /*Initialize Element matrix and vectors*/153 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);154 IssmDouble* basis = xNew<IssmDouble>(numnodes);155 IssmDouble* B = xNew<IssmDouble>(1*numnodes);156 IssmDouble* Bprime = xNew<IssmDouble>(1*numnodes);157 158 /*Retrieve all inputs and parameters*/159 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);160 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);161 this->parameters->FindParam(&stabilization,MasstransportStabilizationEnum);162 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);163 h=this->GetSize();164 165 /* Start looping on the number of gaussian points: */166 GaussSeg *gauss=new GaussSeg(2);167 for(int ig=gauss->begin();ig<gauss->end();ig++){168 169 gauss->GaussPoint(ig);170 171 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);172 GetNodalFunctions(basis,gauss);173 174 vx_input->GetInputValue(&vx,gauss);175 176 D_scalar=gauss->weight*Jdet;177 178 TripleMultiply(basis,1,numnodes,1,179 &D_scalar,1,1,0,180 basis,1,numnodes,0,181 &Ke->values[0],1);182 183 GetNodalFunctions(B,gauss);184 GetBprimeMasstransport(Bprime,&xyz_list[0][0],gauss);185 186 D_scalar=dt*gauss->weight*Jdet*vx;187 TripleMultiply(B,1,numnodes,1,188 &D_scalar,1,1,0,189 Bprime,1,numnodes,0,190 &Ke->values[0],1);191 192 if(stabilization==2){193 /*Streamline upwinding*/194 vel=fabs(vx)+1.e-8;195 D_scalar=dt*gauss->weight*Jdet*h/(2.*vel)*vx;196 }197 else if(stabilization==1){198 /*SSA*/199 vx_input->GetInputAverage(&vx);200 D_scalar=dt*gauss->weight*Jdet*h/2.*fabs(vx);201 }202 if(stabilization==1 || stabilization==2){203 TripleMultiply(Bprime,1,numnodes,1,204 &D_scalar,1,1,0,205 Bprime,1,numnodes,0,206 &Ke->values[0],1);207 }208 }209 210 /*Clean up and return*/211 xDelete<IssmDouble>(basis);212 xDelete<IssmDouble>(B);213 xDelete<IssmDouble>(Bprime);214 delete gauss;215 return Ke;216 }217 /*}}}*/218 /*FUNCTION Seg::CreateKMatrixFreeSurfaceBase {{{*/219 ElementMatrix* Seg::CreateKMatrixFreeSurfaceBase(void){220 221 /*Intermediaries */222 int stabilization;223 IssmDouble Jdet,D_scalar,dt,h;224 IssmDouble vx,vel;225 IssmDouble xyz_list[NUMVERTICES][3];226 227 /*Fetch number of nodes for this finite element*/228 int numnodes = this->NumberofNodes();229 230 /*Initialize Element matrix and vectors*/231 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);232 IssmDouble* basis = xNew<IssmDouble>(numnodes);233 IssmDouble* B = xNew<IssmDouble>(1*numnodes);234 IssmDouble* Bprime = xNew<IssmDouble>(1*numnodes);235 236 /*Retrieve all inputs and parameters*/237 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);238 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);239 this->parameters->FindParam(&stabilization,MasstransportStabilizationEnum);240 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);241 h=this->GetSize();242 243 /* Start looping on the number of gaussian points: */244 GaussSeg *gauss=new GaussSeg(2);245 for(int ig=gauss->begin();ig<gauss->end();ig++){246 247 gauss->GaussPoint(ig);248 249 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);250 GetNodalFunctions(basis,gauss);251 252 vx_input->GetInputValue(&vx,gauss);253 254 D_scalar=gauss->weight*Jdet;255 256 TripleMultiply(basis,1,numnodes,1,257 &D_scalar,1,1,0,258 basis,1,numnodes,0,259 &Ke->values[0],1);260 261 GetNodalFunctions(B,gauss);262 GetBprimeMasstransport(Bprime,&xyz_list[0][0],gauss);263 264 D_scalar=dt*gauss->weight*Jdet*vx;265 TripleMultiply(B,1,numnodes,1,266 &D_scalar,1,1,0,267 Bprime,1,numnodes,0,268 &Ke->values[0],1);269 270 if(stabilization==2){271 /*Streamline upwinding*/272 vel=fabs(vx)+1.e-8;273 D_scalar=dt*gauss->weight*Jdet*h/(2.*vel)*vx;274 }275 else if(stabilization==1){276 /*SSA*/277 vx_input->GetInputAverage(&vx);278 D_scalar=dt*gauss->weight*Jdet*h/2.*fabs(vx);279 }280 if(stabilization==1 || stabilization==2){281 TripleMultiply(Bprime,1,numnodes,1,282 &D_scalar,1,1,0,283 Bprime,1,numnodes,0,284 &Ke->values[0],1);285 }286 }287 288 /*Clean up and return*/289 xDelete<IssmDouble>(basis);290 xDelete<IssmDouble>(B);291 xDelete<IssmDouble>(Bprime);292 delete gauss;293 return Ke;294 }295 /*}}}*/296 /*FUNCTION Seg::CreateMassMatrix {{{*/297 ElementMatrix* Seg::CreateMassMatrix(void){298 299 /* Intermediaries */300 IssmDouble D,Jdet;301 IssmDouble xyz_list[NUMVERTICES][3];302 303 /*Fetch number of nodes and dof for this finite element*/304 int numnodes = this->NumberofNodes();305 306 /*Initialize Element matrix and vectors*/307 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);308 IssmDouble* basis = xNew<IssmDouble>(numnodes);309 310 /*Retrieve all inputs and parameters*/311 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);312 313 /* Start looping on the number of gaussian points: */314 GaussSeg* gauss=new GaussSeg(2);315 for(int ig=gauss->begin();ig<gauss->end();ig++){316 317 gauss->GaussPoint(ig);318 319 GetNodalFunctions(basis,gauss);320 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);321 D=gauss->weight*Jdet;322 323 TripleMultiply(basis,1,numnodes,1,324 &D,1,1,0,325 basis,1,numnodes,0,326 &Ke->values[0],1);327 }328 329 /*Clean up and return*/330 delete gauss;331 xDelete<IssmDouble>(basis);332 return Ke;333 }334 /*}}}*/335 140 /*FUNCTION Seg::GetNumberOfNodes;{{{*/ 336 141 int Seg::GetNumberOfNodes(void){ -
issm/trunk-jpl/src/c/classes/Elements/Seg.h
r16982 r16993 69 69 void SetCurrentConfiguration(Elements* elements,Loads* loads,Nodes* nodes,Materials* materials,Parameters* parameters){_error_("not implemented yet");}; 70 70 void SetwiseNodeConnectivity(int* d_nz,int* o_nz,Node* node,bool* flags,int* flagsindices,int set1_enum,int set2_enum){_error_("not implemented yet");}; 71 ElementMatrix* CreateKMatrix(void){_error_("not implemented yet");};72 71 void CreateDVector(Vector<IssmDouble>* df){_error_("not implemented yet");}; 73 void CreateJacobianMatrix(Matrix<IssmDouble>* Jff){_error_("not implemented yet");};74 72 void Delta18oParameterization(void){_error_("not implemented yet");}; 75 73 void ElementSizes(IssmDouble* hx,IssmDouble* hy,IssmDouble* hz){_error_("not implemented yet");}; … … 257 255 /*}}}*/ 258 256 /*Seg specific routines:*/ 259 ElementMatrix* CreateMassMatrix(void);260 ElementMatrix* CreateKMatrixFreeSurfaceTop(void);261 ElementMatrix* CreateKMatrixFreeSurfaceBase(void);262 257 IssmDouble GetSize(void); 263 258 }; -
issm/trunk-jpl/src/c/classes/Elements/Tria.cpp
r16982 r16993 191 191 } 192 192 /*}}}*/ 193 /*FUNCTION Tria::CreateKMatrix(void) {{{*/194 ElementMatrix* Tria::CreateKMatrix(void){195 196 /*retreive parameters: */197 int analysis_type;198 int meshtype;199 parameters->FindParam(&analysis_type,AnalysisTypeEnum);200 201 /*Checks in debugging mode{{{*/202 _assert_(this->nodes && this->material && this->matpar && this->parameters && this->inputs);203 /*}}}*/204 205 /*Skip if water element*/206 if(NoIceInElement()) return NULL;207 208 /*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */209 switch(analysis_type){210 #ifdef _HAVE_STRESSBALANCE_211 case StressbalanceAnalysisEnum:212 int approximation;213 inputs->GetInputValue(&approximation,ApproximationEnum);214 switch(approximation){215 case SSAApproximationEnum:216 return CreateKMatrixStressbalanceSSA();217 case FSApproximationEnum:218 return CreateKMatrixStressbalanceFS();219 case SIAApproximationEnum:220 return NULL;221 case NoneApproximationEnum:222 return NULL;223 default:224 _error_("Approximation " << EnumToStringx(approximation) << " not supported yet");225 }226 break;227 case StressbalanceSIAAnalysisEnum:228 return CreateKMatrixStressbalanceSIA();229 break;230 #endif231 #ifdef _HAVE_DAMAGE_232 case DamageEvolutionAnalysisEnum:233 return CreateKMatrixDamageEvolution();234 break;235 #endif236 case L2ProjectionBaseAnalysisEnum:237 parameters->FindParam(&meshtype,MeshTypeEnum);238 if(meshtype==Mesh2DverticalEnum){239 return CreateBasalMassMatrix();240 }241 else{242 return CreateMassMatrix();243 }244 break;245 #ifdef _HAVE_MASSTRANSPORT_246 case MasstransportAnalysisEnum:247 return CreateKMatrixMasstransport();248 break;249 case FreeSurfaceTopAnalysisEnum:250 parameters->FindParam(&meshtype,MeshTypeEnum);251 switch(meshtype){252 case Mesh2DverticalEnum:253 return CreateKMatrixFreeSurfaceTop1D();254 case Mesh3DEnum:255 return CreateKMatrixFreeSurfaceTop();256 default:257 _error_("Mesh not supported yet");258 }259 break;260 case FreeSurfaceBaseAnalysisEnum:261 parameters->FindParam(&meshtype,MeshTypeEnum);262 switch(meshtype){263 case Mesh2DverticalEnum:264 return CreateKMatrixFreeSurfaceBase1D();265 case Mesh3DEnum:266 return CreateKMatrixFreeSurfaceBase();267 default:268 _error_("Mesh not supported yet");269 }270 break;271 case ExtrudeFromBaseAnalysisEnum: case ExtrudeFromTopAnalysisEnum:272 return CreateKMatrixExtrusion();273 #endif274 #ifdef _HAVE_HYDROLOGY_275 case HydrologyShreveAnalysisEnum:276 return CreateKMatrixHydrologyShreve();277 break;278 case HydrologyDCInefficientAnalysisEnum:279 return CreateKMatrixHydrologyDCInefficient();280 break;281 case HydrologyDCEfficientAnalysisEnum:282 return CreateKMatrixHydrologyDCEfficient();283 break;284 case L2ProjectionEPLAnalysisEnum:285 return CreateEPLDomainMassMatrix();286 break;287 #endif288 #ifdef _HAVE_BALANCED_289 case BalancethicknessAnalysisEnum:290 return CreateKMatrixBalancethickness();291 break;292 case BalancevelocityAnalysisEnum:293 return CreateKMatrixBalancevelocity();294 break;295 case SmoothedSurfaceSlopeXAnalysisEnum: case SmoothedSurfaceSlopeYAnalysisEnum:296 return CreateKMatrixSmoothedSlope();297 break;298 #endif299 #ifdef _HAVE_CONTROL_300 case AdjointBalancethicknessAnalysisEnum:301 return CreateKMatrixAdjointBalancethickness();302 break;303 case AdjointHorizAnalysisEnum:304 return CreateKMatrixAdjointSSA();305 break;306 #endif307 default:308 _error_("analysis " << analysis_type << " (" << EnumToStringx(analysis_type) << ") not supported yet");309 }310 311 /*Make compiler happy*/312 return NULL;313 }314 /*}}}*/315 /*FUNCTION Tria::CreateMassMatrix {{{*/316 ElementMatrix* Tria::CreateMassMatrix(void){317 318 /* Intermediaries */319 IssmDouble D,Jdet;320 IssmDouble xyz_list[NUMVERTICES][3];321 322 /*Fetch number of nodes and dof for this finite element*/323 int numnodes = this->NumberofNodes();324 325 /*Initialize Element matrix and vectors*/326 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);327 IssmDouble* basis = xNew<IssmDouble>(numnodes);328 329 /*Retrieve all inputs and parameters*/330 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);331 332 /* Start looping on the number of gaussian points: */333 GaussTria* gauss=new GaussTria(2);334 for(int ig=gauss->begin();ig<gauss->end();ig++){335 336 gauss->GaussPoint(ig);337 338 GetNodalFunctions(basis,gauss);339 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);340 D=gauss->weight*Jdet;341 342 TripleMultiply(basis,1,numnodes,1,343 &D,1,1,0,344 basis,1,numnodes,0,345 &Ke->values[0],1);346 }347 348 /*Clean up and return*/349 delete gauss;350 xDelete<IssmDouble>(basis);351 return Ke;352 }353 /*}}}*/354 /*FUNCTION Tria::CreateBasalMassMatrix{{{*/355 ElementMatrix* Tria::CreateBasalMassMatrix(void){356 357 if(!HasEdgeOnBed()) return NULL;358 359 int index1,index2;360 this->EdgeOnBedIndices(&index1,&index2);361 362 Seg* seg=(Seg*)SpawnSeg(index1,index2);363 ElementMatrix* Ke=seg->CreateMassMatrix();364 delete seg->material; delete seg;365 366 /*clean up and return*/367 return Ke;368 }369 /*}}}*/370 193 /*FUNCTION Tria::CreateDVector {{{*/ 371 194 void Tria::CreateDVector(Vector<IssmDouble>* df){ 372 195 373 196 /*Nothing done yet*/ 374 }375 /*}}}*/376 /*FUNCTION Tria::CreateJacobianMatrix{{{*/377 void Tria::CreateJacobianMatrix(Matrix<IssmDouble>* Jff){378 379 /*retrieve parameters: */380 ElementMatrix* Ke=NULL;381 int analysis_type;382 parameters->FindParam(&analysis_type,AnalysisTypeEnum);383 384 /*Checks in debugging {{{*/385 _assert_(this->nodes && this->material && this->matpar && this->parameters && this->inputs);386 /*}}}*/387 388 /*Skip if water element*/389 if(NoIceInElement()) return;390 391 /*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */392 switch(analysis_type){393 #ifdef _HAVE_STRESSBALANCE_394 case StressbalanceAnalysisEnum:395 Ke=CreateJacobianStressbalanceSSA();396 break;397 #endif398 default:399 _error_("analysis " << analysis_type << " (" << EnumToStringx(analysis_type) << ") not supported yet");400 }401 402 /*Add to global matrix*/403 if(Ke){404 Ke->AddToGlobal(Jff);405 delete Ke;406 }407 197 } 408 198 /*}}}*/ … … 3273 3063 3274 3064 #ifdef _HAVE_STRESSBALANCE_ 3275 /*FUNCTION Tria::CreateKMatrixStressbalanceFS{{{*/3276 ElementMatrix* Tria::CreateKMatrixStressbalanceFS(void){3277 3278 ElementMatrix* Ke1 = NULL;3279 ElementMatrix* Ke2 = NULL;3280 ElementMatrix* Ke = NULL;3281 3282 /*compute all stiffness matrices for this element*/3283 Ke1=CreateKMatrixStressbalanceFSViscous();3284 Ke2=CreateKMatrixStressbalanceFSFriction();3285 Ke =new ElementMatrix(Ke1,Ke2);3286 3287 /*clean-up and return*/3288 delete Ke1;3289 delete Ke2;3290 return Ke;3291 3292 }3293 /*}}}*/3294 /*FUNCTION Tria::CreateKMatrixStressbalanceFSViscous {{{*/3295 ElementMatrix* Tria::CreateKMatrixStressbalanceFSViscous(void){3296 3297 /*Intermediaries */3298 int i,approximation;3299 IssmDouble Jdet,viscosity,FSreconditioning,D_scalar;3300 IssmDouble xyz_list[NUMVERTICES][3];3301 IssmDouble epsilon[3]; /* epsilon=[exx,eyy,exy];*/3302 GaussTria *gauss=NULL;3303 3304 /*Fetch number of nodes and dof for this finite element*/3305 int vnumnodes = this->NumberofNodesVelocity();3306 int pnumnodes = this->NumberofNodesPressure();3307 int numdof = vnumnodes*NDOF2 + pnumnodes*NDOF1;3308 3309 /*Prepare coordinate system list*/3310 int* cs_list = xNew<int>(vnumnodes+pnumnodes);3311 for(i=0;i<vnumnodes;i++) cs_list[i] = XYEnum;3312 for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;3313 3314 /*Initialize Element matrix and vectors*/3315 ElementMatrix* Ke = new ElementMatrix(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);3316 IssmDouble* B = xNew<IssmDouble>(5*numdof);3317 IssmDouble* Bprime = xNew<IssmDouble>(5*numdof);3318 IssmDouble* D = xNewZeroInit<IssmDouble>(5*5);3319 3320 /*Retrieve all inputs and parameters*/3321 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);3322 parameters->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum);3323 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);3324 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);3325 3326 /* Start looping on the number of gaussian points: */3327 gauss=new GaussTria(5);3328 for(int ig=gauss->begin();ig<gauss->end();ig++){3329 3330 gauss->GaussPoint(ig);3331 3332 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);3333 GetBFS(B,&xyz_list[0][0],gauss);3334 GetBprimeFS(Bprime,&xyz_list[0][0],gauss);3335 3336 this->StrainRateSSA(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);3337 material->GetViscosity2dvertical(&viscosity,&epsilon[0]);3338 3339 D_scalar=gauss->weight*Jdet;3340 for(i=0;i<3;i++) D[i*5+i] = +D_scalar*2.*viscosity;3341 for(i=3;i<5;i++) D[i*5+i] = -D_scalar*FSreconditioning;3342 3343 TripleMultiply(B,5,numdof,1,3344 D,5,5,0,3345 Bprime,5,numdof,0,3346 Ke->values,1);3347 }3348 3349 /*Transform Coordinate System*/3350 ::TransformStiffnessMatrixCoord(Ke,nodes,(vnumnodes+pnumnodes),cs_list);3351 3352 /*Clean up and return*/3353 delete gauss;3354 xDelete<int>(cs_list);3355 xDelete<IssmDouble>(B);3356 xDelete<IssmDouble>(Bprime);3357 xDelete<IssmDouble>(D);3358 return Ke;3359 }3360 /*}}}*/3361 /*FUNCTION Tria::CreateKMatrixStressbalanceFSFriction{{{*/3362 ElementMatrix* Tria::CreateKMatrixStressbalanceFSFriction(void){3363 3364 /*Intermediaries */3365 int i,j;3366 int analysis_type;3367 int indices[2];3368 IssmDouble alpha2,Jdet;3369 IssmDouble xyz_list[NUMVERTICES][3];3370 IssmDouble xyz_list_seg[NUMVERTICES1D][3];3371 Friction *friction = NULL;3372 3373 /*Initialize Element matrix and return if necessary*/3374 if(IsFloating() || !HasEdgeOnBed()) return NULL;3375 3376 /*Fetch number of nodes and dof for this finite element*/3377 int vnumnodes = this->NumberofNodesVelocity();3378 int pnumnodes = this->NumberofNodesPressure();3379 int numdof = vnumnodes*NDOF2 + pnumnodes*NDOF1;3380 3381 /*Prepare coordinate system list*/3382 int* cs_list = xNew<int>(vnumnodes+pnumnodes);3383 for(i=0;i<vnumnodes;i++) cs_list[i] = XYEnum;3384 for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum;3385 3386 /*Initialize Element matrix and vectors*/3387 ElementMatrix* Ke = new ElementMatrix(nodes,vnumnodes+pnumnodes,this->parameters,FSvelocityEnum);3388 IssmDouble* BFriction = xNew<IssmDouble>(1*numdof);3389 IssmDouble D;3390 3391 /*Retrieve all inputs and parameters*/3392 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);3393 parameters->FindParam(&analysis_type,AnalysisTypeEnum);3394 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);3395 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);3396 3397 /*Get vertex indices that lie on bed*/3398 this->EdgeOnBedIndices(&indices[0],&indices[1]);3399 for(i=0;i<NUMVERTICES1D;i++) for(j=0;j<2;j++) xyz_list_seg[i][j]=xyz_list[indices[i]][j];3400 3401 /*build friction object, used later on: */3402 friction=new Friction(this,1);3403 3404 /* Start looping on the number of gauss 1d (nodes on the bedrock) */3405 GaussTria* gauss=new GaussTria(indices[0],indices[1],3);3406 for(int ig=gauss->begin();ig<gauss->end();ig++){3407 3408 gauss->GaussPoint(ig);3409 3410 GetSegmentJacobianDeterminant(&Jdet,&xyz_list_seg[0][0],gauss);3411 GetLFS(BFriction,gauss);3412 3413 friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,NULL);3414 D = +alpha2*gauss->weight*Jdet; //taub_x = -alpha2 vx3415 3416 TripleMultiply(BFriction,1,numdof,1,3417 &D,1,1,0,3418 BFriction,1,numdof,0,3419 Ke->values,1);3420 }3421 3422 /*DO NOT Transform Coordinate System: this stiffness matrix is already expressed in tangential coordinates*/3423 //::TransformStiffnessMatrixCoord(Ke,nodes,(vnumnodes+pnumnodes),cs_list);3424 3425 /*Clean up and return*/3426 delete gauss;3427 delete friction;3428 xDelete<IssmDouble>(BFriction);3429 xDelete<int>(cs_list);3430 return Ke;3431 }3432 /*}}}*/3433 /*FUNCTION Tria::CreateKMatrixStressbalanceSSA {{{*/3434 ElementMatrix* Tria::CreateKMatrixStressbalanceSSA(void){3435 3436 /*compute all stiffness matrices for this element*/3437 ElementMatrix* Ke1=CreateKMatrixStressbalanceSSAViscous();3438 ElementMatrix* Ke2=CreateKMatrixStressbalanceSSAFriction();3439 ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2);3440 3441 /*clean-up and return*/3442 delete Ke1;3443 delete Ke2;3444 return Ke;3445 }3446 /*}}}*/3447 /*FUNCTION Tria::CreateKMatrixStressbalanceSSAViscous{{{*/3448 ElementMatrix* Tria::CreateKMatrixStressbalanceSSAViscous(void){3449 3450 /*Intermediaries*/3451 IssmDouble xyz_list[NUMVERTICES][3];3452 IssmDouble viscosity,newviscosity,oldviscosity;3453 IssmDouble viscosity_overshoot,thickness,Jdet;3454 IssmDouble epsilon[3],oldepsilon[3]; /* epsilon=[exx,eyy,exy]; */3455 IssmDouble D_scalar;3456 3457 /*Fetch number of nodes and dof for this finite element*/3458 int numnodes = this->NumberofNodes();3459 int numdof = numnodes*NDOF2;3460 3461 /*Initialize Element matrix and vectors*/3462 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters,SSAApproximationEnum);3463 IssmDouble* B = xNew<IssmDouble>(3*numdof);3464 IssmDouble* Bprime = xNew<IssmDouble>(3*numdof);3465 IssmDouble* D = xNewZeroInit<IssmDouble>(3*3);3466 3467 /*Retrieve all inputs and parameters*/3468 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);3469 Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);3470 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);3471 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);3472 Input* vxold_input=inputs->GetInput(VxPicardEnum); _assert_(vxold_input);3473 Input* vyold_input=inputs->GetInput(VyPicardEnum); _assert_(vyold_input);3474 this->parameters->FindParam(&viscosity_overshoot,StressbalanceViscosityOvershootEnum);3475 3476 /* Start looping on the number of gaussian points: */3477 GaussTria* gauss = new GaussTria(2);3478 for(int ig=gauss->begin();ig<gauss->end();ig++){3479 3480 gauss->GaussPoint(ig);3481 3482 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);3483 GetBSSA(&B[0], &xyz_list[0][0], gauss);3484 GetBprimeSSA(&Bprime[0], &xyz_list[0][0], gauss);3485 3486 this->StrainRateSSA(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);3487 this->StrainRateSSA(&oldepsilon[0],&xyz_list[0][0],gauss,vxold_input,vyold_input);3488 material->GetViscosity2d(&viscosity, &epsilon[0]);3489 material->GetViscosity2d(&oldviscosity, &oldepsilon[0]);3490 thickness_input->GetInputValue(&thickness, gauss);3491 3492 newviscosity=viscosity+viscosity_overshoot*(viscosity-oldviscosity);3493 D_scalar=2.*newviscosity*thickness*gauss->weight*Jdet;3494 for(int i=0;i<3;i++) D[i*3+i]=D_scalar;3495 3496 TripleMultiply(B,3,numdof,1,3497 D,3,3,0,3498 Bprime,3,numdof,0,3499 &Ke->values[0],1);3500 }3501 3502 /*Transform Coordinate System*/3503 ::TransformStiffnessMatrixCoord(Ke,nodes,numnodes,XYEnum);3504 3505 /*Clean up and return*/3506 delete gauss;3507 xDelete<IssmDouble>(D);3508 xDelete<IssmDouble>(Bprime);3509 xDelete<IssmDouble>(B);3510 return Ke;3511 }3512 /*}}}*/3513 /*FUNCTION Tria::CreateKMatrixStressbalanceSSAFriction {{{*/3514 ElementMatrix* Tria::CreateKMatrixStressbalanceSSAFriction(void){3515 3516 /*Intermediaries*/3517 bool mainlyfloating;3518 int analysis_type,migration_style;3519 int point1;3520 IssmDouble alpha2,Jdet;3521 IssmDouble fraction1,fraction2;3522 IssmDouble phi=1.0;3523 IssmDouble D_scalar;3524 IssmDouble gllevelset;3525 IssmDouble xyz_list[NUMVERTICES][3];3526 Friction *friction = NULL;3527 GaussTria *gauss = NULL;3528 3529 /*Return if element is inactive*/3530 if(IsFloating()) return NULL;3531 3532 /*Fetch number of nodes and dof for this finite element*/3533 int numnodes = this->NumberofNodes();3534 int numdof = numnodes*NDOF2;3535 3536 /*Initialize Element matrix and vectors*/3537 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters,SSAApproximationEnum);3538 IssmDouble* B = xNew<IssmDouble>(2*numdof);3539 IssmDouble* D = xNewZeroInit<IssmDouble>(2*2);3540 3541 /*Retrieve all inputs and parameters*/3542 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);3543 parameters->FindParam(&migration_style,GroundinglineMigrationEnum);3544 Input* surface_input=inputs->GetInput(SurfaceEnum); _assert_(surface_input);3545 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);3546 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);3547 Input* gllevelset_input=NULL;3548 parameters->FindParam(&analysis_type,AnalysisTypeEnum);3549 3550 /*build friction object, used later on: */3551 friction=new Friction(this,2);3552 3553 /*Recover portion of element that is grounded*/3554 if(migration_style==SubelementMigrationEnum) phi=this->GetGroundedPortion(&xyz_list[0][0]);3555 if(migration_style==SubelementMigration2Enum){3556 gllevelset_input=inputs->GetInput(MaskGroundediceLevelsetEnum); _assert_(gllevelset_input);3557 this->GetGroundedPart(&point1,&fraction1,&fraction2,&mainlyfloating);3558 gauss=new GaussTria(point1,fraction1,fraction2,mainlyfloating,2);3559 }3560 else{3561 gauss=new GaussTria(2);3562 }3563 3564 /* Start looping on the number of gaussian points: */3565 for(int ig=gauss->begin();ig<gauss->end();ig++){3566 3567 gauss->GaussPoint(ig);3568 3569 friction->GetAlpha2(&alpha2, gauss,vx_input,vy_input,NULL);3570 if(migration_style==SubelementMigrationEnum) alpha2=phi*alpha2;3571 if(migration_style==SubelementMigration2Enum){3572 gllevelset_input->GetInputValue(&gllevelset, gauss);3573 if(gllevelset<0) alpha2=0;3574 }3575 3576 GetBSSAFriction(&B[0], &xyz_list[0][0], gauss);3577 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);3578 D_scalar=alpha2*gauss->weight*Jdet;3579 for(int i=0;i<2;i++) D[i*2+i]=D_scalar;3580 3581 TripleMultiply(B,2,numdof,1,3582 D,2,2,0,3583 B,2,numdof,0,3584 &Ke->values[0],1);3585 }3586 3587 /*Transform Coordinate System*/3588 ::TransformStiffnessMatrixCoord(Ke,nodes,numnodes,XYEnum);3589 3590 /*Clean up and return*/3591 delete gauss;3592 delete friction;3593 xDelete<IssmDouble>(D);3594 xDelete<IssmDouble>(B);3595 return Ke;3596 }3597 /*}}}*/3598 /*FUNCTION Tria::CreateKMatrixStressbalanceSIA{{{*/3599 ElementMatrix* Tria::CreateKMatrixStressbalanceSIA(void){3600 3601 /*Intermediaries*/3602 IssmDouble connectivity;3603 3604 /*Fetch number of nodes and dof for this finite element*/3605 int numnodes = this->NumberofNodes(); _assert_(numnodes==3);3606 int numdof = numnodes*NDOF2;3607 3608 /*Initialize Element matrix*/3609 ElementMatrix* Ke=new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);3610 3611 /*Create Element matrix*/3612 for(int i=0;i<numnodes;i++){3613 connectivity=(IssmDouble)vertices[i]->Connectivity();3614 Ke->values[(2*i+0)*numdof+(2*i+0)]=1./connectivity;3615 Ke->values[(2*i+1)*numdof+(2*i+1)]=1./connectivity;3616 }3617 3618 /*Clean up and return*/3619 return Ke;3620 }3621 /*}}}*/3622 /*FUNCTION Tria::CreateJacobianStressbalanceSSA{{{*/3623 ElementMatrix* Tria::CreateJacobianStressbalanceSSA(void){3624 3625 /*Intermediaries */3626 int i,j;3627 IssmDouble xyz_list[NUMVERTICES][3];3628 IssmDouble Jdet,thickness;3629 IssmDouble eps1dotdphii,eps1dotdphij;3630 IssmDouble eps2dotdphii,eps2dotdphij;3631 IssmDouble mu_prime;3632 IssmDouble epsilon[3];/* epsilon=[exx,eyy,exy];*/3633 IssmDouble eps1[2],eps2[2];3634 GaussTria* gauss = NULL;3635 3636 /*Fetch number of nodes and dof for this finite element*/3637 int numnodes = this->NumberofNodes();3638 3639 /*Initialize Element matrix, vectors and Gaussian points*/3640 ElementMatrix* Ke=CreateKMatrixStressbalanceSSA(); //Initialize Jacobian with regular SSA (first part of the Gateau derivative)3641 IssmDouble* dbasis = xNew<IssmDouble>(2*numnodes);3642 3643 /*Retrieve all inputs and parameters*/3644 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);3645 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);3646 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);3647 Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);3648 3649 /* Start looping on the number of gaussian points: */3650 gauss=new GaussTria(2);3651 for(int ig=gauss->begin();ig<gauss->end();ig++){3652 3653 gauss->GaussPoint(ig);3654 3655 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);3656 GetNodalFunctionsDerivatives(dbasis,&xyz_list[0][0],gauss);3657 3658 thickness_input->GetInputValue(&thickness, gauss);3659 this->StrainRateSSA(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);3660 material->GetViscosity2dDerivativeEpsSquare(&mu_prime,&epsilon[0]);3661 eps1[0]=2*epsilon[0]+epsilon[1]; eps2[0]=epsilon[2];3662 eps1[1]=epsilon[2]; eps2[1]=epsilon[0]+2*epsilon[1];3663 3664 for(i=0;i<numnodes;i++){3665 for(j=0;j<numnodes;j++){3666 eps1dotdphii=eps1[0]*dbasis[0*numnodes+i]+eps1[1]*dbasis[1*numnodes+i];3667 eps1dotdphij=eps1[0]*dbasis[0*numnodes+j]+eps1[1]*dbasis[1*numnodes+j];3668 eps2dotdphii=eps2[0]*dbasis[0*numnodes+i]+eps2[1]*dbasis[1*numnodes+i];3669 eps2dotdphij=eps2[0]*dbasis[0*numnodes+j]+eps2[1]*dbasis[1*numnodes+j];3670 3671 Ke->values[2*numnodes*(2*i+0)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*thickness*eps1dotdphij*eps1dotdphii;3672 Ke->values[2*numnodes*(2*i+0)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*thickness*eps2dotdphij*eps1dotdphii;3673 Ke->values[2*numnodes*(2*i+1)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*thickness*eps1dotdphij*eps2dotdphii;3674 Ke->values[2*numnodes*(2*i+1)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*thickness*eps2dotdphij*eps2dotdphii;3675 }3676 }3677 }3678 3679 /*Transform Coordinate System*/3680 ::TransformStiffnessMatrixCoord(Ke,nodes,numnodes,XYEnum);3681 3682 /*Clean up and return*/3683 xDelete<IssmDouble>(dbasis);3684 delete gauss;3685 return Ke;3686 }3687 /*}}}*/3688 3065 /*FUNCTION Tria::GetYcoord {{{*/ 3689 3066 IssmDouble Tria::GetYcoord(GaussTria* gauss){ … … 5037 4414 } 5038 4415 /*}}}*/ 5039 /*FUNCTION Tria::CreateKMatrixAdjointBalancethickness {{{*/5040 ElementMatrix* Tria::CreateKMatrixAdjointBalancethickness(void){5041 5042 ElementMatrix* Ke=NULL;5043 5044 /*Get Element Matrix of the forward model*/5045 switch(GetElementType()){5046 case P1Enum:5047 Ke=CreateKMatrixBalancethickness_CG();5048 break;5049 case P1DGEnum:5050 Ke=CreateKMatrixBalancethickness_DG();5051 break;5052 default:5053 _error_("Element type " << EnumToStringx(GetElementType()) << " not supported yet");5054 }5055 5056 /*Transpose and return Ke*/5057 Ke->Transpose();5058 return Ke;5059 }5060 /*}}}*/5061 /*FUNCTION Tria::CreateKMatrixAdjointSSA{{{*/5062 ElementMatrix* Tria::CreateKMatrixAdjointSSA(void){5063 5064 /*Intermediaries */5065 int i,j;5066 bool incomplete_adjoint;5067 IssmDouble xyz_list[NUMVERTICES][3];5068 IssmDouble Jdet,thickness;5069 IssmDouble eps1dotdphii,eps1dotdphij;5070 IssmDouble eps2dotdphii,eps2dotdphij;5071 IssmDouble mu_prime;5072 IssmDouble epsilon[3];/* epsilon=[exx,eyy,exy];*/5073 IssmDouble eps1[2],eps2[2];5074 GaussTria *gauss=NULL;5075 5076 /*Fetch number of nodes and dof for this finite element*/5077 int numnodes = this->NumberofNodes();5078 5079 /*Initialize Jacobian with regular SSA (first part of the Gateau derivative)*/5080 parameters->FindParam(&incomplete_adjoint,InversionIncompleteAdjointEnum);5081 ElementMatrix* Ke=CreateKMatrixStressbalanceSSA();5082 if(incomplete_adjoint) return Ke;5083 5084 /*Retrieve all inputs and parameters*/5085 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);5086 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);5087 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);5088 Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);5089 5090 /*Allocate dbasis*/5091 IssmDouble* dbasis = xNew<IssmDouble>(2*numnodes);5092 5093 /* Start looping on the number of gaussian points: */5094 gauss=new GaussTria(2);5095 for(int ig=gauss->begin();ig<gauss->end();ig++){5096 5097 gauss->GaussPoint(ig);5098 5099 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);5100 GetNodalFunctionsDerivatives(dbasis,&xyz_list[0][0],gauss);5101 5102 thickness_input->GetInputValue(&thickness, gauss);5103 this->StrainRateSSA(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);5104 material->GetViscosity2dDerivativeEpsSquare(&mu_prime,&epsilon[0]);5105 eps1[0]=2*epsilon[0]+epsilon[1]; eps2[0]=epsilon[2];5106 eps1[1]=epsilon[2]; eps2[1]=epsilon[0]+2*epsilon[1];5107 5108 for(i=0;i<numnodes;i++){5109 for(j=0;j<numnodes;j++){5110 eps1dotdphii=eps1[0]*dbasis[0*numnodes+i]+eps1[1]*dbasis[1*numnodes+i];5111 eps1dotdphij=eps1[0]*dbasis[0*numnodes+j]+eps1[1]*dbasis[1*numnodes+j];5112 eps2dotdphii=eps2[0]*dbasis[0*numnodes+i]+eps2[1]*dbasis[1*numnodes+i];5113 eps2dotdphij=eps2[0]*dbasis[0*numnodes+j]+eps2[1]*dbasis[1*numnodes+j];5114 5115 Ke->values[2*numnodes*(2*i+0)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*thickness*eps1dotdphij*eps1dotdphii;5116 Ke->values[2*numnodes*(2*i+0)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*thickness*eps2dotdphij*eps1dotdphii;5117 Ke->values[2*numnodes*(2*i+1)+2*j+0]+=gauss->weight*Jdet*2*mu_prime*thickness*eps1dotdphij*eps2dotdphii;5118 Ke->values[2*numnodes*(2*i+1)+2*j+1]+=gauss->weight*Jdet*2*mu_prime*thickness*eps2dotdphij*eps2dotdphii;5119 }5120 }5121 }5122 5123 /*Transform Coordinate System*/5124 ::TransformStiffnessMatrixCoord(Ke,nodes,numnodes,XYEnum);5125 5126 /*Clean up and return*/5127 delete gauss;5128 xDelete<IssmDouble>(dbasis);5129 //Ke->Transpose();5130 return Ke;5131 }5132 /*}}}*/5133 4416 /*FUNCTION Tria::GetVectorFromControlInputs{{{*/ 5134 4417 void Tria::GetVectorFromControlInputs(Vector<IssmDouble>* vector,int control_enum,int control_index,const char* data){ … … 5191 4474 5192 4475 ((ControlInput*)input)->SetInput(new_input); 5193 }5194 /*}}}*/5195 #endif5196 5197 #ifdef _HAVE_THERMAL_5198 /*FUNCTION Tria::CreateKMatrixMelting {{{*/5199 ElementMatrix* Tria::CreateKMatrixMelting(void){5200 5201 /*Intermediaries */5202 IssmDouble heatcapacity,latentheat;5203 IssmDouble Jdet,D_scalar;5204 IssmDouble xyz_list[NUMVERTICES][3];5205 5206 /*Fetch number of nodes and dof for this finite element*/5207 int numnodes = this->NumberofNodes();5208 5209 /*Initialize Element vector and vectors*/5210 ElementMatrix* Ke=new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);5211 IssmDouble* basis = xNew<IssmDouble>(numnodes);5212 5213 /*Retrieve all inputs and parameters*/5214 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);5215 latentheat = matpar->GetLatentHeat();5216 heatcapacity = matpar->GetHeatCapacity();5217 5218 /* Start looping on the number of gauss (nodes on the bedrock) */5219 GaussTria* gauss=new GaussTria(2);5220 for(int ig=gauss->begin();ig<gauss->end();ig++){5221 5222 gauss->GaussPoint(ig);5223 5224 GetNodalFunctions(&basis[0],gauss);5225 GetJacobianDeterminant(&Jdet, &xyz_list[0][0], gauss);5226 5227 D_scalar=latentheat/heatcapacity*gauss->weight*Jdet;5228 5229 TripleMultiply(basis,numnodes,1,0,5230 &D_scalar,1,1,0,5231 basis,1,numnodes,0,5232 &Ke->values[0],1);5233 }5234 5235 /*Clean up and return*/5236 xDelete<IssmDouble>(basis);5237 delete gauss;5238 return Ke;5239 4476 } 5240 4477 /*}}}*/ … … 5294 4531 this->inputs->AddInput(new TriaInput(HydrologyWaterVxEnum,vx,P1Enum)); 5295 4532 this->inputs->AddInput(new TriaInput(HydrologyWaterVyEnum,vy,P1Enum)); 5296 }5297 /*}}}*/5298 /*FUNCTION Tria::CreateKMatrixHydrologyShreve{{{*/5299 ElementMatrix* Tria::CreateKMatrixHydrologyShreve(void){5300 5301 /*Intermediaries */5302 IssmDouble diffusivity;5303 IssmDouble Jdet,D_scalar,dt,h;5304 IssmDouble vx,vy,vel,dvxdx,dvydy;5305 IssmDouble dvx[2],dvy[2];5306 IssmDouble xyz_list[NUMVERTICES][3];5307 5308 /*Skip if water or ice shelf element*/5309 if(NoIceInElement() || IsFloating()) return NULL;5310 5311 /*Fetch number of nodes and dof for this finite element*/5312 int numnodes = this->NumberofNodes();5313 5314 /*Initialize Element matrix and vectors*/5315 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);5316 IssmDouble* basis = xNew<IssmDouble>(numnodes);5317 IssmDouble* B = xNew<IssmDouble>(2*numnodes);5318 IssmDouble* Bprime = xNew<IssmDouble>(2*numnodes);5319 IssmDouble D[2][2];5320 5321 /*Create water velocity vx and vy from current inputs*/5322 CreateHydrologyWaterVelocityInput();5323 5324 /*Retrieve all inputs and parameters*/5325 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);5326 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);5327 this->parameters->FindParam(&diffusivity,HydrologyshreveStabilizationEnum);5328 Input* vx_input=inputs->GetInput(HydrologyWaterVxEnum); _assert_(vx_input);5329 Input* vy_input=inputs->GetInput(HydrologyWaterVyEnum); _assert_(vy_input);5330 h=sqrt(2*this->GetArea());5331 5332 /* Start looping on the number of gaussian points: */5333 GaussTria* gauss=new GaussTria(2);5334 for(int ig=gauss->begin();ig<gauss->end();ig++){5335 5336 gauss->GaussPoint(ig);5337 5338 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);5339 GetNodalFunctions(basis,gauss);5340 5341 vx_input->GetInputValue(&vx,gauss);5342 vy_input->GetInputValue(&vy,gauss);5343 vx_input->GetInputDerivativeValue(&dvx[0],&xyz_list[0][0],gauss);5344 vy_input->GetInputDerivativeValue(&dvy[0],&xyz_list[0][0],gauss);5345 5346 D_scalar=gauss->weight*Jdet;5347 5348 TripleMultiply(basis,1,numnodes,1,5349 &D_scalar,1,1,0,5350 basis,1,numnodes,0,5351 Ke->values,1);5352 5353 GetBMasstransport(B,&xyz_list[0][0], gauss);5354 GetBprimeMasstransport(Bprime,&xyz_list[0][0], gauss);5355 5356 dvxdx=dvx[0];5357 dvydy=dvy[1];5358 D_scalar=dt*gauss->weight*Jdet;5359 5360 D[0][0]=D_scalar*dvxdx;5361 D[0][1]=0.;5362 D[1][0]=0.;5363 D[1][1]=D_scalar*dvydy;5364 TripleMultiply(B,2,numnodes,1,5365 &D[0][0],2,2,0,5366 B,2,numnodes,0,5367 &Ke->values[0],1);5368 5369 D[0][0]=D_scalar*vx;5370 D[1][1]=D_scalar*vy;5371 TripleMultiply(B,2,numnodes,1,5372 &D[0][0],2,2,0,5373 Bprime,2,numnodes,0,5374 &Ke->values[0],1);5375 5376 /*Artificial diffusivity*/5377 vel=sqrt(vx*vx+vy*vy);5378 D[0][0]=D_scalar*diffusivity*h/(2*vel)*vx*vx;5379 D[1][0]=D_scalar*diffusivity*h/(2*vel)*vy*vx;5380 D[0][1]=D_scalar*diffusivity*h/(2*vel)*vx*vy;5381 D[1][1]=D_scalar*diffusivity*h/(2*vel)*vy*vy;5382 TripleMultiply(Bprime,2,numnodes,1,5383 &D[0][0],2,2,0,5384 Bprime,2,numnodes,0,5385 &Ke->values[0],1);5386 }5387 5388 /*Clean up and return*/5389 xDelete<IssmDouble>(basis);5390 xDelete<IssmDouble>(B);5391 xDelete<IssmDouble>(Bprime);5392 delete gauss;5393 return Ke;5394 }5395 /*}}}*/5396 /*FUNCTION Tria::CreateKMatrixHydrologyDCInefficient{{{*/5397 ElementMatrix* Tria::CreateKMatrixHydrologyDCInefficient(void){5398 5399 /* Intermediaries */5400 IssmDouble D_scalar,Jdet;5401 IssmDouble sediment_transmitivity,dt;5402 IssmDouble sediment_storing;5403 IssmDouble xyz_list[NUMVERTICES][3];5404 5405 /*Fetch number of nodes and dof for this finite element*/5406 int numnodes = this->NumberofNodes();5407 5408 /*Initialize Element matrix and vectors*/5409 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters);5410 IssmDouble* B = xNew<IssmDouble>(5*numnodes);5411 IssmDouble* basis = xNew<IssmDouble>(numnodes);5412 IssmDouble D[2][2];5413 5414 /*Retrieve all inputs and parameters*/5415 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);5416 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);5417 sediment_storing = matpar->GetSedimentStoring();5418 sediment_transmitivity = matpar->GetSedimentTransmitivity();5419 5420 /* Start looping on the number of gaussian points: */5421 GaussTria* gauss=new GaussTria(2);5422 for(int ig=gauss->begin();ig<gauss->end();ig++){5423 5424 gauss->GaussPoint(ig);5425 5426 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);5427 5428 /*Diffusivity*/5429 D_scalar=sediment_transmitivity*gauss->weight*Jdet;5430 if(reCast<bool,IssmDouble>(dt)) D_scalar=D_scalar*dt;5431 D[0][0]=D_scalar; D[0][1]=0.;5432 D[1][0]=0.; D[1][1]=D_scalar;5433 GetBHydro(B,&xyz_list[0][0],gauss);5434 TripleMultiply(B,2,numnodes,1,5435 &D[0][0],2,2,0,5436 B,2,numnodes,0,5437 &Ke->values[0],1);5438 5439 /*Transient*/5440 if(reCast<bool,IssmDouble>(dt)){5441 GetNodalFunctions(&basis[0],gauss);5442 D_scalar=sediment_storing*gauss->weight*Jdet;5443 5444 TripleMultiply(basis,numnodes,1,0,5445 &D_scalar,1,1,0,5446 basis,1,numnodes,0,5447 &Ke->values[0],1);5448 }5449 }5450 /*Clean up and return*/5451 xDelete<IssmDouble>(basis);5452 xDelete<IssmDouble>(B);5453 delete gauss;5454 return Ke;5455 }5456 /*}}}*/5457 /*FUNCTION Tria::CreateKMatrixHydrologyDCEfficient{{{*/5458 ElementMatrix* Tria::CreateKMatrixHydrologyDCEfficient(void){5459 5460 /* Intermediaries */5461 IssmDouble D_scalar,Jdet,dt;5462 IssmDouble epl_thickness;5463 IssmDouble epl_conductivity;5464 IssmDouble epl_specificstoring;5465 IssmDouble xyz_list[NUMVERTICES][3];5466 5467 /*Check that all nodes are active, else return empty matrix*/5468 if(!this->AllActive()){5469 return NULL;5470 }5471 5472 /*Fetch number of nodes and dof for this finite element*/5473 int numnodes = this->NumberofNodes();5474 5475 /*Initialize Element matrix and vectors*/5476 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters);5477 IssmDouble* B = xNew<IssmDouble>(5*numnodes);5478 IssmDouble* basis = xNew<IssmDouble>(numnodes);5479 IssmDouble D[2][2];5480 5481 /*Retrieve all inputs and parameters*/5482 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);5483 Input* thickness_input=inputs->GetInput(HydrologydcEplThicknessEnum); _assert_(thickness_input);5484 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);5485 epl_specificstoring = matpar->GetEplSpecificStoring();5486 epl_conductivity = matpar->GetEplConductivity();5487 5488 5489 /* Start looping on the number of gaussian points: */5490 GaussTria* gauss=new GaussTria(2);5491 for(int ig=gauss->begin();ig<gauss->end();ig++){5492 5493 5494 gauss->GaussPoint(ig);5495 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);5496 thickness_input->GetInputValue(&epl_thickness,gauss);5497 5498 /*Diffusivity*/5499 D_scalar=epl_conductivity*epl_thickness*gauss->weight*Jdet;5500 if(reCast<bool,IssmDouble>(dt)) D_scalar=D_scalar*dt;5501 D[0][0]=D_scalar; D[0][1]=0.;5502 D[1][0]=0.; D[1][1]=D_scalar;5503 GetBHydro(B,&xyz_list[0][0],gauss);5504 TripleMultiply(B,2,numnodes,1,5505 &D[0][0],2,2,0,5506 B,2,numnodes,0,5507 &Ke->values[0],1);5508 5509 /*Transient*/5510 if(reCast<bool,IssmDouble>(dt)){5511 GetNodalFunctions(basis,gauss);5512 D_scalar=epl_specificstoring*epl_thickness*gauss->weight*Jdet;5513 5514 TripleMultiply(basis,numnodes,1,0,5515 &D_scalar,1,1,0,5516 basis,1,numnodes,0,5517 &Ke->values[0],1);5518 }5519 }5520 5521 /*Clean up and return*/5522 xDelete<IssmDouble>(basis);5523 xDelete<IssmDouble>(B);5524 delete gauss;5525 return Ke;5526 4533 } 5527 4534 /*}}}*/ … … 5898 4905 #endif 5899 4906 5900 #ifdef _HAVE_MASSTRANSPORT_5901 /*FUNCTION Tria::CreateKMatrixExtrusion {{{*/5902 ElementMatrix* Tria::CreateKMatrixExtrusion(void){5903 5904 /*compute all stiffness matrices for this element*/5905 ElementMatrix* Ke1=CreateKMatrixExtrusionVolume();5906 ElementMatrix* Ke2=CreateKMatrixExtrusionSurface();5907 ElementMatrix* Ke3=CreateKMatrixExtrusionBed();5908 ElementMatrix* Ke =new ElementMatrix(Ke1,Ke2,Ke3);5909 5910 /*clean-up and return*/5911 delete Ke1;5912 delete Ke2;5913 delete Ke3;5914 return Ke;5915 5916 }5917 /*}}}*/5918 /*FUNCTION Tria::CreateKMatrixExtrusionVolume {{{*/5919 ElementMatrix* Tria::CreateKMatrixExtrusionVolume(void){5920 5921 /*Intermediaries */5922 IssmDouble Jdet;5923 IssmDouble xyz_list[NUMVERTICES][3];5924 IssmDouble B[NDOF1][NUMVERTICES];5925 IssmDouble Bprime[NDOF1][NUMVERTICES];5926 IssmDouble DL_scalar;5927 GaussTria *gauss=NULL;5928 5929 /*Initialize Element matrix*/5930 ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters,NoneApproximationEnum);5931 5932 /*Retrieve all inputs and parameters*/5933 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);5934 5935 /* Start looping on the number of gaussian points: */5936 gauss=new GaussTria(2);5937 for(int ig=gauss->begin();ig<gauss->end();ig++){5938 5939 gauss->GaussPoint(ig);5940 5941 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);5942 GetBExtrusion(&B[0][0], &xyz_list[0][0], gauss);5943 GetNodalFunctions(&Bprime[0][0],gauss);5944 5945 DL_scalar=gauss->weight*Jdet;5946 5947 TripleMultiply(&B[0][0],1,NUMVERTICES,1,5948 &DL_scalar,1,1,0,5949 &Bprime[0][0],1,NUMVERTICES,0,5950 &Ke->values[0],1);5951 }5952 5953 /*Clean up and return*/5954 delete gauss;5955 return Ke;5956 }5957 /*}}}*/5958 /*FUNCTION Tria::CreateKMatrixExtrusionSurface {{{*/5959 ElementMatrix* Tria::CreateKMatrixExtrusionSurface(void){5960 5961 if (!HasEdgeOnSurface()) return NULL;5962 5963 /*Constants*/5964 const int numdof=NDOF1*NUMVERTICES;5965 5966 /*Intermediaries */5967 int indices[2];5968 IssmDouble xyz_list[NUMVERTICES][3];5969 IssmDouble xyz_list_seg[NUMVERTICES1D][3];5970 IssmDouble normal[3];5971 IssmDouble Jdet,DL_scalar;5972 IssmDouble basis[NUMVERTICES];5973 GaussTria *gauss=NULL;5974 5975 /*Initialize Element matrix*/5976 ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters,NoneApproximationEnum);5977 5978 /*Retrieve all inputs and parameters*/5979 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);5980 5981 /*Get vertex indices that lie on bed*/5982 this->EdgeOnSurfaceIndices(&indices[0],&indices[1]);5983 for(int i=0;i<NUMVERTICES1D;i++) for(int j=0;j<2;j++) xyz_list_seg[i][j]=xyz_list[indices[i]][j];5984 NormalSection(&normal[0],&xyz_list_seg[0][0]);5985 5986 /* Start looping on the number of gaussian points: */5987 gauss=new GaussTria(indices[0],indices[1],2);5988 for(int ig=gauss->begin();ig<gauss->end();ig++){5989 5990 gauss->GaussPoint(ig);5991 5992 GetSegmentJacobianDeterminant(&Jdet,&xyz_list_seg[0][0],gauss);5993 GetNodalFunctions(&basis[0], gauss);5994 5995 DL_scalar= - gauss->weight*Jdet*normal[1];5996 5997 TripleMultiply( basis,1,numdof,1,5998 &DL_scalar,1,1,0,5999 basis,1,numdof,0,6000 &Ke->values[0],1);6001 }6002 6003 /*Clean up and return*/6004 delete gauss;6005 return Ke;6006 }6007 /*}}}*/6008 /*FUNCTION Tria::CreateKMatrixExtrusionBed {{{*/6009 ElementMatrix* Tria::CreateKMatrixExtrusionBed(void){6010 6011 if (!HasEdgeOnBed()) return NULL;6012 6013 /*Constants*/6014 const int numdof=NDOF1*NUMVERTICES;6015 6016 /*Intermediaries */6017 int indices[2];6018 IssmDouble xyz_list[NUMVERTICES][3];6019 IssmDouble xyz_list_seg[NUMVERTICES1D][3];6020 IssmDouble normal[3];6021 IssmDouble Jdet,DL_scalar;6022 IssmDouble basis[NUMVERTICES];6023 GaussTria *gauss=NULL;6024 6025 /*Initialize Element matrix*/6026 ElementMatrix* Ke=new ElementMatrix(nodes,NUMVERTICES,this->parameters,NoneApproximationEnum);6027 6028 /*Retrieve all inputs and parameters*/6029 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6030 6031 /*Get vertex indices that lie on bed*/6032 this->EdgeOnBedIndices(&indices[0],&indices[1]);6033 for(int i=0;i<NUMVERTICES1D;i++) for(int j=0;j<2;j++) xyz_list_seg[i][j]=xyz_list[indices[i]][j];6034 NormalSection(&normal[0],&xyz_list_seg[0][0]);6035 6036 /* Start looping on the number of gaussian points: */6037 gauss=new GaussTria(indices[0],indices[1],2);6038 for(int ig=gauss->begin();ig<gauss->end();ig++){6039 6040 gauss->GaussPoint(ig);6041 6042 GetSegmentJacobianDeterminant(&Jdet,&xyz_list_seg[0][0],gauss);6043 GetNodalFunctions(&basis[0], gauss);6044 6045 DL_scalar= - gauss->weight*Jdet*normal[1];6046 6047 TripleMultiply( basis,1,numdof,1,6048 &DL_scalar,1,1,0,6049 basis,1,numdof,0,6050 &Ke->values[0],1);6051 }6052 6053 /*Clean up and return*/6054 delete gauss;6055 return Ke;6056 }6057 /*}}}*/6058 /*FUNCTION Tria::CreateKMatrixMasstransport {{{*/6059 ElementMatrix* Tria::CreateKMatrixMasstransport(void){6060 6061 switch(GetElementType()){6062 case P1Enum: case P2Enum:6063 return CreateKMatrixMasstransport_CG();6064 case P1DGEnum:6065 return CreateKMatrixMasstransport_DG();6066 default:6067 _error_("Element type " << EnumToStringx(GetElementType()) << " not supported yet");6068 }6069 }6070 /*}}}*/6071 /*FUNCTION Tria::CreateKMatrixMasstransport_CG {{{*/6072 ElementMatrix* Tria::CreateKMatrixMasstransport_CG(void){6073 6074 /*Intermediaries */6075 int stabilization;6076 int meshtype;6077 IssmDouble Jdet,D_scalar,dt,h;6078 IssmDouble vel,vx,vy,dvxdx,dvydy;6079 IssmDouble dvx[2],dvy[2];6080 IssmDouble xyz_list[NUMVERTICES][3];6081 6082 /*Fetch number of nodes for this finite element*/6083 int numnodes = this->NumberofNodes();6084 6085 /*Initialize Element matrix and vectors*/6086 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);6087 IssmDouble* basis = xNew<IssmDouble>(numnodes);6088 IssmDouble* B = xNew<IssmDouble>(2*numnodes);6089 IssmDouble* Bprime = xNew<IssmDouble>(2*numnodes);6090 IssmDouble D[2][2];6091 6092 /*Retrieve all inputs and parameters*/6093 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6094 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);6095 this->parameters->FindParam(&meshtype,MeshTypeEnum);6096 this->parameters->FindParam(&stabilization,MasstransportStabilizationEnum);6097 Input* vxaverage_input=NULL;6098 Input* vyaverage_input=NULL;6099 if(meshtype==Mesh2DhorizontalEnum){6100 vxaverage_input=inputs->GetInput(VxEnum); _assert_(vxaverage_input);6101 vyaverage_input=inputs->GetInput(VyEnum); _assert_(vyaverage_input);6102 }6103 else{6104 vxaverage_input=inputs->GetInput(VxAverageEnum); _assert_(vxaverage_input);6105 vyaverage_input=inputs->GetInput(VyAverageEnum); _assert_(vyaverage_input);6106 }6107 h=sqrt(2*this->GetArea());6108 6109 /* Start looping on the number of gaussian points: */6110 GaussTria *gauss=new GaussTria(2);6111 for(int ig=gauss->begin();ig<gauss->end();ig++){6112 6113 gauss->GaussPoint(ig);6114 6115 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);6116 GetNodalFunctions(basis,gauss);6117 6118 vxaverage_input->GetInputValue(&vx,gauss);6119 vyaverage_input->GetInputValue(&vy,gauss);6120 vxaverage_input->GetInputDerivativeValue(&dvx[0],&xyz_list[0][0],gauss);6121 vyaverage_input->GetInputDerivativeValue(&dvy[0],&xyz_list[0][0],gauss);6122 6123 D_scalar=gauss->weight*Jdet;6124 6125 TripleMultiply(basis,1,numnodes,1,6126 &D_scalar,1,1,0,6127 basis,1,numnodes,0,6128 &Ke->values[0],1);6129 6130 GetBMasstransport(B,&xyz_list[0][0],gauss);6131 GetBprimeMasstransport(Bprime,&xyz_list[0][0],gauss);6132 6133 dvxdx=dvx[0];6134 dvydy=dvy[1];6135 D_scalar=dt*gauss->weight*Jdet;6136 6137 D[0][0]=D_scalar*dvxdx;6138 D[0][1]=0.;6139 D[1][0]=0.;6140 D[1][1]=D_scalar*dvydy;6141 TripleMultiply(B,2,numnodes,1,6142 &D[0][0],2,2,0,6143 B,2,numnodes,0,6144 &Ke->values[0],1);6145 6146 D[0][0]=D_scalar*vx;6147 D[1][1]=D_scalar*vy;6148 TripleMultiply(B,2,numnodes,1,6149 &D[0][0],2,2,0,6150 Bprime,2,numnodes,0,6151 &Ke->values[0],1);6152 6153 if(stabilization==2){6154 /*Streamline upwinding*/6155 vel=sqrt(vx*vx+vy*vy)+1.e-8;6156 D[0][0]=h/(2*vel)*vx*vx;6157 D[1][0]=h/(2*vel)*vy*vx;6158 D[0][1]=h/(2*vel)*vx*vy;6159 D[1][1]=h/(2*vel)*vy*vy;6160 }6161 else if(stabilization==1){6162 /*SSA*/6163 vxaverage_input->GetInputAverage(&vx);6164 vyaverage_input->GetInputAverage(&vy);6165 D[0][0]=h/2.0*fabs(vx);6166 D[0][1]=0.;6167 D[1][0]=0.;6168 D[1][1]=h/2.0*fabs(vy);6169 }6170 if(stabilization==1 || stabilization==2){6171 D[0][0]=D_scalar*D[0][0];6172 D[1][0]=D_scalar*D[1][0];6173 D[0][1]=D_scalar*D[0][1];6174 D[1][1]=D_scalar*D[1][1];6175 TripleMultiply(Bprime,2,numnodes,1,6176 &D[0][0],2,2,0,6177 Bprime,2,numnodes,0,6178 &Ke->values[0],1);6179 }6180 }6181 6182 /*Clean up and return*/6183 xDelete<IssmDouble>(basis);6184 xDelete<IssmDouble>(B);6185 xDelete<IssmDouble>(Bprime);6186 delete gauss;6187 return Ke;6188 }6189 /*}}}*/6190 /*FUNCTION Tria::CreateKMatrixMasstransport_DG {{{*/6191 ElementMatrix* Tria::CreateKMatrixMasstransport_DG(void){6192 6193 /*Intermediaries */6194 int meshtype;6195 IssmDouble xyz_list[NUMVERTICES][3];6196 IssmDouble Jdet,D_scalar,dt,vx,vy;6197 6198 /*Fetch number of nodes for this finite element*/6199 int numnodes = this->NumberofNodes();6200 6201 /*Initialize Element matrix and vectors*/6202 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);6203 IssmDouble* basis = xNew<IssmDouble>(numnodes);6204 IssmDouble* B = xNew<IssmDouble>(2*numnodes);6205 IssmDouble* Bprime = xNew<IssmDouble>(2*numnodes);6206 IssmDouble D[2][2];6207 6208 /*Retrieve all inputs and parameters*/6209 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6210 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);6211 this->parameters->FindParam(&meshtype,MeshTypeEnum);6212 Input* vxaverage_input=NULL;6213 Input* vyaverage_input=NULL;6214 if(meshtype==Mesh2DhorizontalEnum){6215 vxaverage_input=inputs->GetInput(VxEnum); _assert_(vxaverage_input);6216 vyaverage_input=inputs->GetInput(VyEnum); _assert_(vyaverage_input);6217 }6218 else{6219 vxaverage_input=inputs->GetInput(VxAverageEnum); _assert_(vxaverage_input);6220 vyaverage_input=inputs->GetInput(VyAverageEnum); _assert_(vyaverage_input);6221 }6222 6223 /* Start looping on the number of gaussian points: */6224 GaussTria* gauss=new GaussTria(2);6225 for(int ig=gauss->begin();ig<gauss->end();ig++){6226 6227 gauss->GaussPoint(ig);6228 6229 vxaverage_input->GetInputValue(&vx,gauss);6230 vyaverage_input->GetInputValue(&vy,gauss);6231 6232 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);6233 GetNodalFunctions(basis,gauss);6234 6235 D_scalar=gauss->weight*Jdet;6236 6237 TripleMultiply(basis,1,numnodes,1,6238 &D_scalar,1,1,0,6239 basis,1,numnodes,0,6240 &Ke->values[0],1);6241 6242 /*WARNING: B and Bprime are inverted compared to usual masstransport!!!!*/6243 GetBMasstransport(Bprime, &xyz_list[0][0], gauss);6244 GetBprimeMasstransport(B, &xyz_list[0][0], gauss);6245 6246 D_scalar=-dt*gauss->weight*Jdet;6247 D[0][0]=D_scalar*vx;6248 D[0][1]=0.;6249 D[1][0]=0.;6250 D[1][1]=D_scalar*vy;6251 6252 TripleMultiply(B,2,numnodes,1,6253 &D[0][0],2,2,0,6254 Bprime,2,numnodes,0,6255 &Ke->values[0],1);6256 }6257 6258 /*Clean up and return*/6259 xDelete<IssmDouble>(basis);6260 xDelete<IssmDouble>(B);6261 xDelete<IssmDouble>(Bprime);6262 delete gauss;6263 return Ke;6264 }6265 /*}}}*/6266 /*FUNCTION Tria::CreateKMatrixFreeSurfaceTop {{{*/6267 ElementMatrix* Tria::CreateKMatrixFreeSurfaceTop(void){6268 6269 /*Intermediaries */6270 int stabilization;6271 IssmDouble Jdet,D_scalar,dt,h;6272 IssmDouble vel,vx,vy;6273 IssmDouble xyz_list[NUMVERTICES][3];6274 6275 /*Fetch number of nodes for this finite element*/6276 int numnodes = this->NumberofNodes();6277 6278 /*Initialize Element matrix and vectors*/6279 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);6280 IssmDouble* basis = xNew<IssmDouble>(numnodes);6281 IssmDouble* B = xNew<IssmDouble>(2*numnodes);6282 IssmDouble* Bprime = xNew<IssmDouble>(2*numnodes);6283 IssmDouble D[2][2];6284 6285 /*Retrieve all inputs and parameters*/6286 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6287 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);6288 this->parameters->FindParam(&stabilization,MasstransportStabilizationEnum);6289 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);6290 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);6291 h=sqrt(2*this->GetArea());6292 6293 /* Start looping on the number of gaussian points: */6294 GaussTria *gauss=new GaussTria(2);6295 for(int ig=gauss->begin();ig<gauss->end();ig++){6296 6297 gauss->GaussPoint(ig);6298 6299 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);6300 GetNodalFunctions(basis,gauss);6301 6302 vx_input->GetInputValue(&vx,gauss);6303 vy_input->GetInputValue(&vy,gauss);6304 6305 D_scalar=gauss->weight*Jdet;6306 6307 TripleMultiply(basis,1,numnodes,1,6308 &D_scalar,1,1,0,6309 basis,1,numnodes,0,6310 &Ke->values[0],1);6311 6312 GetBMasstransport(B,&xyz_list[0][0],gauss);6313 GetBprimeMasstransport(Bprime,&xyz_list[0][0],gauss);6314 6315 D_scalar=dt*gauss->weight*Jdet;6316 6317 D[0][0]=D_scalar*vx;6318 D[0][1]=0.;6319 D[1][0]=0.;6320 D[1][1]=D_scalar*vy;6321 TripleMultiply(B,2,numnodes,1,6322 &D[0][0],2,2,0,6323 Bprime,2,numnodes,0,6324 &Ke->values[0],1);6325 6326 if(stabilization==2){6327 /*Streamline upwinding*/6328 vel=sqrt(vx*vx+vy*vy)+1.e-8;6329 D[0][0]=h/(2*vel)*vx*vx;6330 D[1][0]=h/(2*vel)*vy*vx;6331 D[0][1]=h/(2*vel)*vx*vy;6332 D[1][1]=h/(2*vel)*vy*vy;6333 }6334 else if(stabilization==1){6335 /*SSA*/6336 vx_input->GetInputAverage(&vx);6337 vy_input->GetInputAverage(&vy);6338 D[0][0]=h/2.0*fabs(vx);6339 D[0][1]=0.;6340 D[1][0]=0.;6341 D[1][1]=h/2.0*fabs(vy);6342 }6343 if(stabilization==1 || stabilization==2){6344 D[0][0]=D_scalar*D[0][0];6345 D[1][0]=D_scalar*D[1][0];6346 D[0][1]=D_scalar*D[0][1];6347 D[1][1]=D_scalar*D[1][1];6348 TripleMultiply(Bprime,2,numnodes,1,6349 &D[0][0],2,2,0,6350 Bprime,2,numnodes,0,6351 &Ke->values[0],1);6352 }6353 }6354 6355 /*Clean up and return*/6356 xDelete<IssmDouble>(basis);6357 xDelete<IssmDouble>(B);6358 xDelete<IssmDouble>(Bprime);6359 delete gauss;6360 return Ke;6361 }6362 /*}}}*/6363 /*FUNCTION Tria::CreateKMatrixFreeSurfaceTop1D {{{*/6364 ElementMatrix* Tria::CreateKMatrixFreeSurfaceTop1D(void){6365 6366 if(!HasEdgeOnSurface()) return NULL;6367 6368 int index1,index2;6369 this->EdgeOnSurfaceIndices(&index1,&index2);6370 6371 Seg* seg=(Seg*)SpawnSeg(index1,index2);6372 ElementMatrix* Ke=seg->CreateKMatrixFreeSurfaceTop();6373 delete seg->material; delete seg;6374 6375 /*clean up and return*/6376 return Ke;6377 }6378 /*}}}*/6379 /*FUNCTION Tria::CreateKMatrixFreeSurfaceBase {{{*/6380 ElementMatrix* Tria::CreateKMatrixFreeSurfaceBase(void){6381 6382 /*Intermediaries */6383 int stabilization;6384 IssmDouble Jdet,D_scalar,dt,h;6385 IssmDouble vel,vx,vy;6386 IssmDouble xyz_list[NUMVERTICES][3];6387 6388 /*Fetch number of nodes for this finite element*/6389 int numnodes = this->NumberofNodes();6390 6391 /*Initialize Element matrix and vectors*/6392 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);6393 IssmDouble* basis = xNew<IssmDouble>(numnodes);6394 IssmDouble* B = xNew<IssmDouble>(2*numnodes);6395 IssmDouble* Bprime = xNew<IssmDouble>(2*numnodes);6396 IssmDouble D[2][2];6397 6398 /*Retrieve all inputs and parameters*/6399 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6400 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);6401 this->parameters->FindParam(&stabilization,MasstransportStabilizationEnum);6402 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);6403 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);6404 h=sqrt(2*this->GetArea());6405 6406 /* Start looping on the number of gaussian points: */6407 GaussTria *gauss=new GaussTria(2);6408 for(int ig=gauss->begin();ig<gauss->end();ig++){6409 6410 gauss->GaussPoint(ig);6411 6412 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);6413 GetNodalFunctions(basis,gauss);6414 6415 vx_input->GetInputValue(&vx,gauss);6416 vy_input->GetInputValue(&vy,gauss);6417 6418 D_scalar=gauss->weight*Jdet;6419 6420 TripleMultiply(basis,1,numnodes,1,6421 &D_scalar,1,1,0,6422 basis,1,numnodes,0,6423 &Ke->values[0],1);6424 6425 GetBMasstransport(B,&xyz_list[0][0],gauss);6426 GetBprimeMasstransport(Bprime,&xyz_list[0][0],gauss);6427 6428 D_scalar=dt*gauss->weight*Jdet;6429 6430 D[0][0]=D_scalar*vx;6431 D[0][1]=0.;6432 D[1][0]=0.;6433 D[1][1]=D_scalar*vy;6434 TripleMultiply(B,2,numnodes,1,6435 &D[0][0],2,2,0,6436 Bprime,2,numnodes,0,6437 &Ke->values[0],1);6438 6439 if(stabilization==2){6440 /*Streamline upwinding*/6441 vel=sqrt(vx*vx+vy*vy)+1.e-8;6442 D[0][0]=h/(2*vel)*vx*vx;6443 D[1][0]=h/(2*vel)*vy*vx;6444 D[0][1]=h/(2*vel)*vx*vy;6445 D[1][1]=h/(2*vel)*vy*vy;6446 }6447 else if(stabilization==1){6448 /*SSA*/6449 vx_input->GetInputAverage(&vx);6450 vy_input->GetInputAverage(&vy);6451 D[0][0]=h/2.0*fabs(vx);6452 D[0][1]=0.;6453 D[1][0]=0.;6454 D[1][1]=h/2.0*fabs(vy);6455 }6456 if(stabilization==1 || stabilization==2){6457 D[0][0]=D_scalar*D[0][0];6458 D[1][0]=D_scalar*D[1][0];6459 D[0][1]=D_scalar*D[0][1];6460 D[1][1]=D_scalar*D[1][1];6461 TripleMultiply(Bprime,2,numnodes,1,6462 &D[0][0],2,2,0,6463 Bprime,2,numnodes,0,6464 &Ke->values[0],1);6465 }6466 }6467 6468 /*Clean up and return*/6469 xDelete<IssmDouble>(basis);6470 xDelete<IssmDouble>(B);6471 xDelete<IssmDouble>(Bprime);6472 delete gauss;6473 return Ke;6474 }6475 /*}}}*/6476 /*FUNCTION Tria::CreateKMatrixFreeSurfaceBase1D {{{*/6477 ElementMatrix* Tria::CreateKMatrixFreeSurfaceBase1D(void){6478 6479 if(!HasEdgeOnBed()) return NULL;6480 6481 int index1,index2;6482 this->EdgeOnBedIndices(&index1,&index2);6483 6484 Seg* seg=(Seg*)SpawnSeg(index1,index2);6485 ElementMatrix* Ke=seg->CreateKMatrixFreeSurfaceBase();6486 delete seg->material; delete seg;6487 6488 /*clean up and return*/6489 return Ke;6490 }6491 /*}}}*/6492 #endif6493 6494 4907 #ifdef _HAVE_DAMAGE_ 6495 /*FUNCTION Tria::CreateKMatrixDamageEvolution {{{*/6496 ElementMatrix* Tria::CreateKMatrixDamageEvolution(void){6497 6498 switch(GetElementType()){6499 case P1Enum: case P2Enum:6500 return CreateKMatrixDamageEvolution_CG();6501 case P1DGEnum:6502 _error_("DG not implemented yet!");break;6503 default:6504 _error_("Element type " << EnumToStringx(GetElementType()) << " not supported yet");6505 }6506 }6507 /*}}}*/6508 /*FUNCTION Tria::CreateKMatrixDamageEvolution_CG {{{*/6509 ElementMatrix* Tria::CreateKMatrixDamageEvolution_CG(void){6510 6511 /*Intermediaries */6512 int stabilization;6513 int meshtype;6514 IssmDouble Jdet,D_scalar,dt,h;6515 IssmDouble vel,vx,vy,dvxdx,dvydy;6516 IssmDouble dvx[2],dvy[2];6517 IssmDouble xyz_list[NUMVERTICES][3];6518 6519 /*Fetch number of nodes for this finite element*/6520 int numnodes = this->NumberofNodes();6521 6522 /*Initialize Element matrix and vectors*/6523 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);6524 IssmDouble* basis = xNew<IssmDouble>(numnodes);6525 IssmDouble* B = xNew<IssmDouble>(2*numnodes);6526 IssmDouble* Bprime = xNew<IssmDouble>(2*numnodes);6527 IssmDouble D[2][2];6528 6529 /*Retrieve all inputs and parameters*/6530 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6531 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);6532 this->parameters->FindParam(&meshtype,MeshTypeEnum);6533 this->parameters->FindParam(&stabilization,DamageStabilizationEnum);6534 Input* vxaverage_input=NULL;6535 Input* vyaverage_input=NULL;6536 if(meshtype==Mesh2DhorizontalEnum){6537 vxaverage_input=inputs->GetInput(VxEnum); _assert_(vxaverage_input);6538 vyaverage_input=inputs->GetInput(VyEnum); _assert_(vyaverage_input);6539 }6540 else{6541 vxaverage_input=inputs->GetInput(VxAverageEnum); _assert_(vxaverage_input);6542 vyaverage_input=inputs->GetInput(VyAverageEnum); _assert_(vyaverage_input);6543 }6544 h=sqrt(2*this->GetArea());6545 6546 /* Start looping on the number of gaussian points: */6547 GaussTria *gauss=new GaussTria(2);6548 for(int ig=gauss->begin();ig<gauss->end();ig++){6549 6550 gauss->GaussPoint(ig);6551 6552 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);6553 GetNodalFunctions(basis,gauss);6554 6555 vxaverage_input->GetInputValue(&vx,gauss);6556 vyaverage_input->GetInputValue(&vy,gauss);6557 vxaverage_input->GetInputDerivativeValue(&dvx[0],&xyz_list[0][0],gauss);6558 vyaverage_input->GetInputDerivativeValue(&dvy[0],&xyz_list[0][0],gauss);6559 6560 D_scalar=gauss->weight*Jdet;6561 6562 TripleMultiply(basis,1,numnodes,1,6563 &D_scalar,1,1,0,6564 basis,1,numnodes,0,6565 &Ke->values[0],1);6566 GetBMasstransport(B,&xyz_list[0][0],gauss);6567 GetBprimeMasstransport(Bprime,&xyz_list[0][0],gauss);6568 6569 dvxdx=dvx[0];6570 dvydy=dvy[1];6571 D_scalar=dt*gauss->weight*Jdet;6572 6573 D[0][0]=D_scalar*dvxdx;6574 D[0][1]=0.;6575 D[1][0]=0.;6576 D[1][1]=D_scalar*dvydy;6577 TripleMultiply(B,2,numnodes,1,6578 &D[0][0],2,2,0,6579 B,2,numnodes,0,6580 &Ke->values[0],1);6581 6582 D[0][0]=D_scalar*vx;6583 D[1][1]=D_scalar*vy;6584 TripleMultiply(B,2,numnodes,1,6585 &D[0][0],2,2,0,6586 Bprime,2,numnodes,0,6587 &Ke->values[0],1);6588 6589 if(stabilization==2){6590 /*Streamline upwinding*/6591 vel=sqrt(vx*vx+vy*vy)+1.e-8;6592 D[0][0]=h/(2*vel)*vx*vx;6593 D[1][0]=h/(2*vel)*vy*vx;6594 D[0][1]=h/(2*vel)*vx*vy;6595 D[1][1]=h/(2*vel)*vy*vy;6596 }6597 else if(stabilization==1){6598 /*SSA*/6599 vxaverage_input->GetInputAverage(&vx);6600 vyaverage_input->GetInputAverage(&vy);6601 D[0][0]=h/2.0*fabs(vx);6602 D[0][1]=0.;6603 D[1][0]=0.;6604 D[1][1]=h/2.0*fabs(vy);6605 }6606 if(stabilization==1 || stabilization==2){6607 D[0][0]=D_scalar*D[0][0];6608 D[1][0]=D_scalar*D[1][0];6609 D[0][1]=D_scalar*D[0][1];6610 D[1][1]=D_scalar*D[1][1];6611 TripleMultiply(Bprime,2,numnodes,1,6612 &D[0][0],2,2,0,6613 Bprime,2,numnodes,0,6614 &Ke->values[0],1);6615 }6616 }6617 6618 /*Clean up and return*/6619 xDelete<IssmDouble>(basis);6620 xDelete<IssmDouble>(B);6621 xDelete<IssmDouble>(Bprime);6622 delete gauss;6623 return Ke;6624 }6625 /*}}}*/6626 4908 /*FUNCTION Tria::DamageEvolutionF{{{*/ 6627 4909 void Tria::DamageEvolutionF(IssmDouble* f){ … … 6819 5101 } 6820 5102 6821 }6822 /*}}}*/6823 #endif6824 6825 #ifdef _HAVE_BALANCED_6826 /*FUNCTION Tria::CreateKMatrixBalancethickness {{{*/6827 ElementMatrix* Tria::CreateKMatrixBalancethickness(void){6828 6829 switch(GetElementType()){6830 case P1Enum:6831 return CreateKMatrixBalancethickness_CG();6832 case P1DGEnum:6833 return CreateKMatrixBalancethickness_DG();6834 default:6835 _error_("Element type " << EnumToStringx(GetElementType()) << " not supported yet");6836 }6837 6838 }6839 /*}}}*/6840 /*FUNCTION Tria::CreateKMatrixBalancethickness_CG {{{*/6841 ElementMatrix* Tria::CreateKMatrixBalancethickness_CG(void){6842 6843 /*Intermediaries */6844 int stabilization,meshtype;6845 IssmDouble Jdet,vx,vy,dvxdx,dvydy,vel,h;6846 IssmDouble D_scalar;6847 IssmDouble dvx[2],dvy[2];6848 IssmDouble xyz_list[NUMVERTICES][3];6849 6850 /*Fetch number of nodes and dof for this finite element*/6851 int numnodes = this->NumberofNodes();6852 6853 /*Initialize Element matrix and vectors*/6854 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);6855 IssmDouble* basis = xNew<IssmDouble>(numnodes);6856 IssmDouble* B = xNew<IssmDouble>(2*numnodes);6857 IssmDouble* Bprime = xNew<IssmDouble>(2*numnodes);6858 IssmDouble D[2][2];6859 6860 /*Retrieve all Inputs and parameters: */6861 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6862 this->parameters->FindParam(&stabilization,BalancethicknessStabilizationEnum);6863 this->parameters->FindParam(&meshtype,MeshTypeEnum);6864 Input* vxaverage_input=NULL;6865 Input* vyaverage_input=NULL;6866 if(meshtype==Mesh2DhorizontalEnum){6867 vxaverage_input=inputs->GetInput(VxEnum); _assert_(vxaverage_input);6868 vyaverage_input=inputs->GetInput(VyEnum); _assert_(vyaverage_input);6869 }6870 else{6871 vxaverage_input=inputs->GetInput(VxAverageEnum); _assert_(vxaverage_input);6872 vyaverage_input=inputs->GetInput(VyAverageEnum); _assert_(vyaverage_input);6873 }6874 h=sqrt(2.*this->GetArea());6875 6876 /*Start looping on the number of gaussian points:*/6877 GaussTria* gauss=new GaussTria(2);6878 for(int ig=gauss->begin();ig<gauss->end();ig++){6879 6880 gauss->GaussPoint(ig);6881 6882 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);6883 GetBMasstransport(B,&xyz_list[0][0],gauss);6884 GetBprimeMasstransport(Bprime,&xyz_list[0][0],gauss);6885 6886 vxaverage_input->GetInputValue(&vx,gauss);6887 vyaverage_input->GetInputValue(&vy,gauss);6888 vxaverage_input->GetInputDerivativeValue(&dvx[0],&xyz_list[0][0],gauss);6889 vyaverage_input->GetInputDerivativeValue(&dvy[0],&xyz_list[0][0],gauss);6890 6891 dvxdx=dvx[0];6892 dvydy=dvy[1];6893 D_scalar=gauss->weight*Jdet;6894 6895 D[0][0]=D_scalar*dvxdx;6896 D[0][1]=0.;6897 D[1][0]=0.;6898 D[1][1]=D_scalar*dvydy;6899 TripleMultiply(B,2,numnodes,1,6900 &D[0][0],2,2,0,6901 B,2,numnodes,0,6902 &Ke->values[0],1);6903 6904 D[0][0]=D_scalar*vx;6905 D[1][1]=D_scalar*vy;6906 TripleMultiply(B,2,numnodes,1,6907 &D[0][0],2,2,0,6908 Bprime,2,numnodes,0,6909 &Ke->values[0],1);6910 6911 if(stabilization==1){6912 /*Streamline upwinding*/6913 vel=sqrt(vx*vx+vy*vy);6914 D[0][0]=h/(2*vel)*vx*vx;6915 D[1][0]=h/(2*vel)*vy*vx;6916 D[0][1]=h/(2*vel)*vx*vy;6917 D[1][1]=h/(2*vel)*vy*vy;6918 }6919 else if(stabilization==2){6920 /*SSA*/6921 vxaverage_input->GetInputAverage(&vx);6922 vyaverage_input->GetInputAverage(&vy);6923 D[0][0]=h/2.0*fabs(vx);6924 D[0][1]=0.;6925 D[1][0]=0.;6926 D[1][1]=h/2.0*fabs(vy);6927 }6928 if(stabilization==1 || stabilization==2){6929 D[0][0]=D_scalar*D[0][0];6930 D[1][0]=D_scalar*D[1][0];6931 D[0][1]=D_scalar*D[0][1];6932 D[1][1]=D_scalar*D[1][1];6933 TripleMultiply(Bprime,2,numnodes,1,6934 &D[0][0],2,2,0,6935 Bprime,2,numnodes,0,6936 &Ke->values[0],1);6937 }6938 }6939 6940 /*Clean up and return*/6941 xDelete<IssmDouble>(basis);6942 xDelete<IssmDouble>(B);6943 xDelete<IssmDouble>(Bprime);6944 delete gauss;6945 return Ke;6946 }6947 /*}}}*/6948 /*FUNCTION Tria::CreateKMatrixBalancethickness_DG {{{*/6949 ElementMatrix* Tria::CreateKMatrixBalancethickness_DG(void){6950 6951 /*Intermediaries*/6952 IssmDouble vx,vy,D_scalar,Jdet;6953 IssmDouble xyz_list[NUMVERTICES][3];6954 6955 /*Fetch number of nodes for this finite element*/6956 int numnodes = this->NumberofNodes();6957 6958 /*Initialize Element matrix and vectors*/6959 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);6960 IssmDouble* basis = xNew<IssmDouble>(numnodes);6961 IssmDouble* B = xNew<IssmDouble>(2*numnodes);6962 IssmDouble* Bprime = xNew<IssmDouble>(2*numnodes);6963 IssmDouble D[2][2];6964 6965 /*Retrieve all inputs and parameters*/6966 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);6967 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);6968 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);6969 6970 /*Start looping on the number of gaussian points:*/6971 GaussTria* gauss=new GaussTria(2);6972 for(int ig=gauss->begin();ig<gauss->end();ig++){6973 6974 gauss->GaussPoint(ig);6975 6976 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);6977 /*WARNING: B and Bprime are inverted compared to usual masstransport!!!!*/6978 GetBMasstransport(Bprime,&xyz_list[0][0],gauss);6979 GetBprimeMasstransport(B,&xyz_list[0][0],gauss);6980 6981 vx_input->GetInputValue(&vx,gauss);6982 vy_input->GetInputValue(&vy,gauss);6983 6984 D_scalar=-gauss->weight*Jdet;6985 D[0][0]=D_scalar*vx;6986 D[0][1]=0.;6987 D[1][0]=0.;6988 D[1][1]=D_scalar*vy;6989 6990 TripleMultiply(B,2,numnodes,1,6991 &D[0][0],2,2,0,6992 Bprime,2,numnodes,0,6993 &Ke->values[0],1);6994 }6995 6996 /*Clean up and return*/6997 xDelete<IssmDouble>(basis);6998 xDelete<IssmDouble>(B);6999 xDelete<IssmDouble>(Bprime);7000 delete gauss;7001 return Ke;7002 }7003 /*}}}*/7004 /*FUNCTION Tria::CreateKMatrixBalancevelocity{{{*/7005 ElementMatrix* Tria::CreateKMatrixBalancevelocity(void){7006 7007 /*Intermediaries */7008 IssmDouble xyz_list[NUMVERTICES][3];7009 IssmDouble dhdt_g,mb_g,ms_g,Jdet;7010 IssmDouble h,gamma,thickness;7011 IssmDouble hnx,hny,dhnx[2],dhny[2];7012 7013 /*Fetch number of nodes and dof for this finite element*/7014 int numnodes = this->NumberofNodes();7015 7016 /*Initialize Element matrix and vectors*/7017 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters,NoneApproximationEnum);7018 IssmDouble* B = xNew<IssmDouble>(2*numnodes);7019 IssmDouble* basis = xNew<IssmDouble>(numnodes);7020 IssmDouble* dbasis = xNew<IssmDouble>(2*numnodes);7021 IssmDouble* HNx = xNew<IssmDouble>(numnodes);7022 IssmDouble* HNy = xNew<IssmDouble>(numnodes);7023 IssmDouble* H = xNew<IssmDouble>(numnodes);7024 IssmDouble* Nx = xNew<IssmDouble>(numnodes);7025 IssmDouble* Ny = xNew<IssmDouble>(numnodes);7026 7027 /*Retrieve all Inputs and parameters: */7028 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);7029 Input* H_input =inputs->GetInput(ThicknessEnum); _assert_(H_input);7030 h=sqrt(2.*this->GetArea());7031 7032 /*Get vector N for all nodes and build HNx and HNy*/7033 GetInputListOnNodes(Nx,SurfaceSlopeXEnum);7034 GetInputListOnNodes(Ny,SurfaceSlopeYEnum);7035 GetInputListOnNodes(H,ThicknessEnum);7036 for(int i=0;i<numnodes;i++){7037 IssmDouble norm=sqrt(Nx[i]*Nx[i]+Ny[i]*Ny[i]+1.e-10);7038 HNx[i] = -H[i]*Nx[i]/norm;7039 HNy[i] = -H[i]*Ny[i]/norm;7040 }7041 7042 /*Start looping on the number of gaussian points:*/7043 GaussTria* gauss=new GaussTria(2);7044 for(int ig=gauss->begin();ig<gauss->end();ig++){7045 7046 gauss->GaussPoint(ig);7047 7048 H_input->GetInputValue(&thickness,gauss);7049 if(thickness<50.) thickness=50.;7050 TriaRef::GetInputDerivativeValue(&dhnx[0],HNx,&xyz_list[0][0],gauss);7051 TriaRef::GetInputDerivativeValue(&dhny[0],HNy,&xyz_list[0][0],gauss);7052 TriaRef::GetInputValue(&hnx,HNx,gauss);7053 TriaRef::GetInputValue(&hny,HNy,gauss);7054 7055 gamma=h/(2.*thickness+1.e-10);7056 7057 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);7058 GetNodalFunctions(basis,gauss);7059 GetNodalFunctionsDerivatives(dbasis,&xyz_list[0][0],gauss);7060 7061 for(int i=0;i<numnodes;i++){7062 for(int j=0;j<numnodes;j++){7063 Ke->values[i*numnodes+j] += gauss->weight*Jdet*(7064 (basis[i]+gamma*(basis[i]*(dhnx[0]+dhny[1]) + dbasis[0*numnodes+i]*hnx + dbasis[1*numnodes+i]*hny))*7065 (basis[j]*(dhnx[0]+dhny[1]) + dbasis[0*numnodes+j]*hnx + dbasis[1*numnodes+j]*hny)7066 );7067 }7068 }7069 }7070 7071 /*Clean up and return*/7072 xDelete<IssmDouble>(basis);7073 xDelete<IssmDouble>(dbasis);7074 xDelete<IssmDouble>(H);7075 xDelete<IssmDouble>(Nx);7076 xDelete<IssmDouble>(Ny);7077 xDelete<IssmDouble>(HNx);7078 xDelete<IssmDouble>(HNy);7079 xDelete<IssmDouble>(B);7080 delete gauss;7081 return Ke;7082 }7083 /*}}}*/7084 /*FUNCTION Tria::CreateKMatrixSmoothedSlope {{{*/7085 ElementMatrix* Tria::CreateKMatrixSmoothedSlope(void){7086 7087 /* Intermediaries */7088 IssmDouble D_scalar,Jdet,thickness;7089 IssmDouble xyz_list[NUMVERTICES][3];7090 IssmDouble l=8.;7091 7092 /*Fetch number of nodes and dof for this finite element*/7093 int numnodes = this->NumberofNodes();7094 7095 /*Initialize Element matrix and vectors*/7096 ElementMatrix* Ke = new ElementMatrix(nodes,numnodes,this->parameters);7097 IssmDouble* dbasis = xNew<IssmDouble>(2*numnodes);7098 IssmDouble* basis = xNew<IssmDouble>(numnodes);7099 7100 /*Retrieve all inputs and parameters*/7101 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);7102 Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);7103 7104 /* Start looping on the number of gaussian points: */7105 GaussTria* gauss=new GaussTria(2);7106 for(int ig=gauss->begin();ig<gauss->end();ig++){7107 7108 gauss->GaussPoint(ig);7109 7110 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);7111 thickness_input->GetInputValue(&thickness,gauss);7112 if(thickness<50.) thickness=50.;7113 7114 GetNodalFunctions(basis,gauss);7115 GetNodalFunctionsDerivatives(dbasis,&xyz_list[0][0],gauss);7116 7117 for(int i=0;i<numnodes;i++){7118 for(int j=0;j<numnodes;j++){7119 Ke->values[i*numnodes+j] += gauss->weight*Jdet*(7120 basis[i]*basis[j]7121 +(l*thickness)*(l*thickness)*(dbasis[0*numnodes+i]*dbasis[0*numnodes+j] + dbasis[1*numnodes+i]*dbasis[1*numnodes+j])7122 );7123 }7124 }7125 }7126 7127 /*Clean up and return*/7128 delete gauss;7129 xDelete<IssmDouble>(dbasis);7130 xDelete<IssmDouble>(basis);7131 return Ke;7132 5103 } 7133 5104 /*}}}*/ -
issm/trunk-jpl/src/c/classes/Elements/Tria.h
r16982 r16993 68 68 void SetwiseNodeConnectivity(int* d_nz,int* o_nz,Node* node,bool* flags,int* flagsindices,int set1_enum,int set2_enum); 69 69 void CreateDVector(Vector<IssmDouble>* df); 70 void CreateJacobianMatrix(Matrix<IssmDouble>* Jff);71 70 void Delta18oParameterization(void); 72 71 void ElementSizes(IssmDouble* hx,IssmDouble* hy,IssmDouble* hz){_error_("not implemented yet");}; … … 202 201 void AddInput(int input_enum, IssmDouble* values, int interpolation_enum); 203 202 void AddMaterialInput(int input_enum, IssmDouble* values, int interpolation_enum); 204 ElementMatrix* CreateKMatrix(void);205 ElementMatrix* CreateKMatrixBalancethickness(void);206 ElementMatrix* CreateKMatrixBalancethickness_DG(void);207 ElementMatrix* CreateKMatrixBalancethickness_CG(void);208 ElementMatrix* CreateKMatrixBalancevelocity(void);209 ElementMatrix* CreateKMatrixSmoothedSlope(void);210 ElementMatrix* CreateKMatrixMelting(void);211 ElementMatrix* CreateKMatrixMasstransport(void);212 ElementMatrix* CreateKMatrixMasstransport_CG(void);213 ElementMatrix* CreateKMatrixMasstransport_DG(void);214 ElementMatrix* CreateKMatrixExtrusion(void);215 ElementMatrix* CreateKMatrixExtrusionVolume(void);216 ElementMatrix* CreateKMatrixExtrusionSurface(void);217 ElementMatrix* CreateKMatrixExtrusionBed(void);218 ElementMatrix* CreateKMatrixFreeSurfaceTop(void);219 ElementMatrix* CreateKMatrixFreeSurfaceTop1D(void);220 ElementMatrix* CreateKMatrixFreeSurfaceBase(void);221 ElementMatrix* CreateKMatrixFreeSurfaceBase1D(void);222 ElementMatrix* CreateMassMatrix(void);223 ElementMatrix* CreateBasalMassMatrix(void);224 203 IssmDouble EnthalpyDiffusionParameter(IssmDouble enthalpy,IssmDouble pressure){_error_("not implemented");}; 225 204 IssmDouble EnthalpyDiffusionParameterVolume(int numvertices,IssmDouble* enthalpy,IssmDouble* pressure){_error_("not implemented");}; … … 283 262 284 263 #ifdef _HAVE_STRESSBALANCE_ 285 ElementMatrix* CreateKMatrixStressbalanceSSA(void);286 ElementMatrix* CreateKMatrixStressbalanceSSAViscous(void);287 ElementMatrix* CreateKMatrixStressbalanceSSAFriction(void);288 ElementMatrix* CreateKMatrixStressbalanceSIA(void);289 ElementMatrix* CreateKMatrixStressbalanceFS(void);290 ElementMatrix* CreateKMatrixStressbalanceFSViscous(void);291 ElementMatrix* CreateKMatrixStressbalanceFSFriction(void);292 264 void PVectorGLSstabilization(ElementVector* pe); 293 ElementMatrix* CreateJacobianStressbalanceSSA(void);294 265 IssmDouble GetYcoord(GaussTria* gauss); 295 #endif296 297 #ifdef _HAVE_CONTROL_298 ElementMatrix* CreateKMatrixAdjointBalancethickness(void);299 ElementMatrix* CreateKMatrixAdjointSSA(void);300 266 #endif 301 267 … … 309 275 310 276 #ifdef _HAVE_HYDROLOGY_ 311 ElementMatrix* CreateKMatrixHydrologyShreve(void);312 ElementMatrix* CreateKMatrixHydrologyDCInefficient(void);313 ElementMatrix* CreateKMatrixHydrologyDCEfficient(void);314 277 ElementMatrix* CreateEPLDomainMassMatrix(void); 315 278 void CreateHydrologyWaterVelocityInput(void); … … 324 287 325 288 #ifdef _HAVE_DAMAGE_ 326 ElementMatrix* CreateKMatrixDamageEvolution(void);327 ElementMatrix* CreateKMatrixDamageEvolution_CG(void);328 289 void DamageEvolutionF(IssmDouble* flist); 329 290 #endif -
issm/trunk-jpl/src/c/modules/CreateJacobianMatrixx/CreateJacobianMatrixx.cpp
r16164 r16993 10 10 void CreateJacobianMatrixx(Matrix<IssmDouble>** pJff,FemModel* femmodel,IssmDouble kmax){ 11 11 12 int i ,connectivity;13 int configuration_type ;12 int i; 13 int configuration_type,analysisenum; 14 14 Element *element = NULL; 15 15 Load *load = NULL; … … 21 21 /*Recover some parameters*/ 22 22 femmodel->parameters->FindParam(&configuration_type,ConfigurationTypeEnum); 23 femmodel->parameters->FindParam(&connectivity,MeshAverageVertexConnectivityEnum); 23 femmodel->parameters->FindParam(&analysisenum,AnalysisTypeEnum); 24 Analysis* analysis = EnumToAnalysis(analysisenum); 24 25 25 26 /*Initialize Jacobian Matrix*/ … … 29 30 for(i=0;i<femmodel->elements->Size();i++){ 30 31 element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i)); 31 element->CreateJacobianMatrix(Jff); 32 ElementMatrix* Je = analysis->CreateJacobianMatrix(element); 33 if(Je) Je->AddToGlobal(Jff); 34 delete Je; 32 35 } 33 36 for (i=0;i<femmodel->loads->Size();i++){ … … 39 42 40 43 /*Assign output pointer*/ 44 delete analysis; 41 45 *pJff=Jff; 42 46 -
issm/trunk-jpl/src/c/modules/CreateJacobianMatrixx/CreateJacobianMatrixx.h
r16126 r16993 6 6 7 7 #include "../../classes/classes.h" 8 #include "../../analyses/analyses.h" 8 9 9 10 /* local prototypes: */ -
issm/trunk-jpl/src/c/modules/SystemMatricesx/SystemMatricesx.cpp
r16982 r16993 41 41 for (i=0;i<femmodel->elements->Size();i++){ 42 42 element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i)); 43 ElementMatrix* Ke = element->CreateKMatrix(); 44 //ElementVector* pe = element->CreatePVector(); 43 ElementMatrix* Ke = analysis->CreateKMatrix(element); 45 44 ElementVector* pe = analysis->CreatePVector(element); 46 45 element->ReduceMatrices(Ke,pe); … … 73 72 for (i=0;i<femmodel->elements->Size();i++){ 74 73 element=dynamic_cast<Element*>(femmodel->elements->GetObjectByOffset(i)); 75 ElementMatrix* Ke = element->CreateKMatrix(); 76 //ElementMatrix* Ke = analysis->CreateKMatrix(element); 77 //ElementVector* pe = element->CreatePVector(); 74 ElementMatrix* Ke = analysis->CreateKMatrix(element); 78 75 ElementVector* pe = analysis->CreatePVector(element); 79 76 element->ReduceMatrices(Ke,pe);
Note:
See TracChangeset
for help on using the changeset viewer.