Changeset 16773
- Timestamp:
- 11/14/13 20:04:08 (11 years ago)
- Location:
- issm/trunk-jpl/src/c/analyses
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/c/analyses/StressbalanceAnalysis.cpp
r16769 r16773 943 943 InputUpdateFromSolutionHO(solution,element); 944 944 return; 945 case SIAApproximationEnum:946 InputUpdateFromSolutionHO(solution,element);947 return;948 945 case L1L2ApproximationEnum: 949 946 InputUpdateFromSolutionSSA(solution,element); … … 961 958 } 962 959 }/*}}}*/ 963 void StressbalanceAnalysis::InputUpdateFromSolutionSSA(IssmDouble* solution,Element* element){/*{{{*/ 960 void StressbalanceAnalysis::InputUpdateFromSolutionFS(IssmDouble* solution,Element* element){/*{{{*/ 961 962 int i,dim,meshtype; 963 int* vdoflist=NULL; 964 int* pdoflist=NULL; 965 IssmDouble FSreconditioning; 966 967 element->FindParam(&meshtype,MeshTypeEnum); 968 element->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum); 969 switch(meshtype){ 970 case Mesh2DverticalEnum: dim = 2; break; 971 case Mesh3DEnum: dim = 3; break; 972 default: _error_("mesh "<<EnumToStringx(meshtype)<<" not supported yet"); 973 } 974 975 /*Fetch number of nodes and dof for this finite element*/ 976 int vnumnodes = element->GetNumberOfNodesVelocity(); 977 int pnumnodes = element->GetNumberOfNodesPressure(); 978 int vnumdof = vnumnodes*dim; 979 int pnumdof = pnumnodes*1; 980 981 /*Initialize values*/ 982 IssmDouble* values = xNew<IssmDouble>(vnumdof+pnumdof); 983 IssmDouble* vx = xNew<IssmDouble>(vnumnodes); 984 IssmDouble* vy = xNew<IssmDouble>(vnumnodes); 985 IssmDouble* vz = xNew<IssmDouble>(vnumnodes); 986 IssmDouble* vel = xNew<IssmDouble>(vnumnodes); 987 IssmDouble* pressure = xNew<IssmDouble>(pnumnodes); 988 989 /*Prepare coordinate system list*/ 990 int* cs_list = xNew<int>(vnumnodes+pnumnodes); 991 if(dim==2){ 992 for(i=0;i<vnumnodes;i++) cs_list[i] = XYEnum; 993 } 994 else{ 995 for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum; 996 } 997 for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum; 998 999 /*Get dof list: */ 1000 element->GetDofListVelocity(&vdoflist,GsetEnum); 1001 element->GetDofListPressure(&pdoflist,GsetEnum); 1002 1003 /*Use the dof list to index into the solution vector: */ 1004 for(i=0;i<vnumdof;i++) values[i] =solution[vdoflist[i]]; 1005 for(i=0;i<pnumdof;i++) values[vnumdof+i]=solution[pdoflist[i]]; 1006 1007 /*Transform solution in Cartesian Space*/ 1008 element->TransformSolutionCoord(&values[0],&cs_list[0]); 1009 1010 /*Ok, we have vx and vy in values, fill in all arrays: */ 1011 for(i=0;i<vnumnodes;i++){ 1012 vx[i] = values[i*dim+0]; 1013 vy[i] = values[i*dim+1]; 1014 if(xIsNan<IssmDouble>(vx[i])) _error_("NaN found in solution vector"); 1015 if(xIsNan<IssmDouble>(vy[i])) _error_("NaN found in solution vector"); 1016 1017 if(dim==3){ 1018 vz[i] = values[i*dim+2]; 1019 if(xIsNan<IssmDouble>(vz[i])) _error_("NaN found in solution vector"); 1020 } 1021 } 1022 for(i=0;i<pnumnodes;i++){ 1023 pressure[i] = values[vnumdof+i]; 1024 if(xIsNan<IssmDouble>(pressure[i])) _error_("NaN found in solution vector"); 1025 } 1026 1027 /*Recondition pressure and compute vel: */ 1028 for(i=0;i<pnumnodes;i++) pressure[i] = pressure[i]*FSreconditioning; 1029 if(dim==3) for(i=0;i<vnumnodes;i++) vel[i] = sqrt(vx[i]*vx[i] + vy[i]*vy[i] + vz[i]*vz[i]); 1030 else for(i=0;i<vnumnodes;i++) vel[i] = sqrt(vx[i]*vx[i] + vy[i]*vy[i]); 1031 1032 /*Now, we have to move the previous inputs to old 1033 * status, otherwise, we'll wipe them off: */ 1034 element->InputChangeName(VxEnum,VxPicardEnum); 1035 element->InputChangeName(VyEnum,VyPicardEnum); 1036 element->InputChangeName(PressureEnum,PressurePicardEnum); 1037 if(dim==3) element->InputChangeName(VzEnum,VzPicardEnum); 1038 1039 /*Add vx and vy as inputs to the tria element: */ 1040 element->AddInput(VxEnum,vx,P1Enum); 1041 element->AddInput(VyEnum,vy,P1Enum); 1042 element->AddInput(VelEnum,vel,P1Enum); 1043 element->AddInput(PressureEnum,pressure,P1Enum); 1044 if(dim==3) element->AddInput(VzEnum,vz,P1Enum); 1045 1046 /*Free ressources:*/ 1047 xDelete<IssmDouble>(pressure); 1048 xDelete<IssmDouble>(vel); 1049 xDelete<IssmDouble>(vz); 1050 xDelete<IssmDouble>(vy); 1051 xDelete<IssmDouble>(vx); 1052 xDelete<IssmDouble>(values); 1053 xDelete<int>(vdoflist); 1054 xDelete<int>(pdoflist); 1055 xDelete<int>(cs_list); 1056 }/*}}}*/ 1057 void StressbalanceAnalysis::InputUpdateFromSolutionHO(IssmDouble* solution,Element* element){/*{{{*/ 1058 1059 int i,meshtype; 1060 IssmDouble rho_ice,g; 1061 int* doflist=NULL; 1062 IssmDouble* xyz_list=NULL; 1063 1064 /*Fetch number of nodes and dof for this finite element*/ 1065 int numnodes = element->GetNumberOfNodes(); 1066 int numdof = numnodes*2; 1067 1068 /*Fetch dof list and allocate solution vectors*/ 1069 element->GetDofList(&doflist,HOApproximationEnum,GsetEnum); 1070 IssmDouble* values = xNew<IssmDouble>(numdof); 1071 IssmDouble* vx = xNew<IssmDouble>(numnodes); 1072 IssmDouble* vy = xNew<IssmDouble>(numnodes); 1073 IssmDouble* vz = xNew<IssmDouble>(numnodes); 1074 IssmDouble* vel = xNew<IssmDouble>(numnodes); 1075 IssmDouble* pressure = xNew<IssmDouble>(numnodes); 1076 IssmDouble* surface = xNew<IssmDouble>(numnodes); 1077 1078 /*Use the dof list to index into the solution vector: */ 1079 for(i=0;i<numdof;i++) values[i]=solution[doflist[i]]; 1080 1081 /*Transform solution in Cartesian Space*/ 1082 element->TransformSolutionCoord(&values[0],XYEnum); 1083 element->FindParam(&meshtype,MeshTypeEnum); 1084 1085 /*Ok, we have vx and vy in values, fill in vx and vy arrays: */ 1086 for(i=0;i<numnodes;i++){ 1087 vx[i]=values[i*2+0]; 1088 vy[i]=values[i*2+1]; 1089 1090 /*Check solution*/ 1091 if(xIsNan<IssmDouble>(vx[i])) _error_("NaN found in solution vector"); 1092 if(xIsNan<IssmDouble>(vy[i])) _error_("NaN found in solution vector"); 1093 } 1094 1095 /*Get Vz and compute vel*/ 1096 element->GetInputListOnNodes(&vz[0],VzEnum,0.); 1097 for(i=0;i<numnodes;i++) vel[i]=sqrt(vx[i]*vx[i] + vy[i]*vy[i] + vz[i]*vz[i]); 1098 1099 /*For pressure: we have not computed pressure in this analysis, for this element. We are in 2D, 1100 *so the pressure is just the pressure at the bedrock: */ 1101 rho_ice = element->GetMaterialParameter(MaterialsRhoIceEnum); 1102 g = element->GetMaterialParameter(ConstantsGEnum); 1103 element->GetVerticesCoordinates(&xyz_list); 1104 element->GetInputListOnNodes(&surface[0],SurfaceEnum); 1105 for(i=0;i<numnodes;i++) pressure[i]=rho_ice*g*(surface[i]-xyz_list[i*3+2]); 1106 1107 /*Now, we have to move the previous Vx and Vy inputs to old 1108 * status, otherwise, we'll wipe them off: */ 1109 element->InputChangeName(VxEnum,VxPicardEnum); 1110 element->InputChangeName(VyEnum,VyPicardEnum); 1111 element->InputChangeName(PressureEnum,PressurePicardEnum); 1112 1113 /*Add vx and vy as inputs to the tria element: */ 1114 element->AddInput(VxEnum,vx,P1Enum); 1115 element->AddInput(VyEnum,vy,P1Enum); 1116 element->AddBasalInput(VelEnum,vel,P1Enum); 1117 element->AddBasalInput(PressureEnum,pressure,P1Enum); 1118 1119 /*Free ressources:*/ 1120 xDelete<IssmDouble>(surface); 1121 xDelete<IssmDouble>(pressure); 1122 xDelete<IssmDouble>(vel); 1123 xDelete<IssmDouble>(vz); 1124 xDelete<IssmDouble>(vy); 1125 xDelete<IssmDouble>(vx); 1126 xDelete<IssmDouble>(values); 1127 xDelete<IssmDouble>(xyz_list); 1128 xDelete<int>(doflist); 1129 }/*}}}*/ 1130 void StressbalanceAnalysis::InputUpdateFromSolutionL1L2(IssmDouble* solution,Element* element){/*{{{*/ 964 1131 965 1132 int i,meshtype; … … 1060 1227 if(meshtype!=Mesh2DhorizontalEnum) delete basalelement; 1061 1228 }/*}}}*/ 1062 void StressbalanceAnalysis::InputUpdateFromSolution HO(IssmDouble* solution,Element* element){/*{{{*/1229 void StressbalanceAnalysis::InputUpdateFromSolutionSSA(IssmDouble* solution,Element* element){/*{{{*/ 1063 1230 1064 1231 int i,meshtype; … … 1066 1233 int* doflist=NULL; 1067 1234 IssmDouble* xyz_list=NULL; 1235 Element* basalelement=NULL; 1236 1237 /*Deal with pressure first*/ 1238 int numvertices = element->GetNumberOfVertices(); 1239 IssmDouble* pressure = xNew<IssmDouble>(numvertices); 1240 IssmDouble* thickness = xNew<IssmDouble>(numvertices); 1241 IssmDouble* surface = xNew<IssmDouble>(numvertices); 1242 1243 element->FindParam(&meshtype,MeshTypeEnum); 1244 rho_ice =element->GetMaterialParameter(MaterialsRhoIceEnum); 1245 g =element->GetMaterialParameter(ConstantsGEnum); 1246 switch(meshtype){ 1247 case Mesh2DhorizontalEnum: 1248 element->GetInputListOnVertices(thickness,ThicknessEnum); 1249 for(i=0;i<numvertices;i++) pressure[i]=rho_ice*g*thickness[i]; 1250 break; 1251 case Mesh3DEnum: 1252 element->GetVerticesCoordinates(&xyz_list); 1253 element->GetInputListOnVertices(surface,SurfaceEnum); 1254 for(i=0;i<numvertices;i++) pressure[i]=rho_ice*g*(surface[i]-xyz_list[i*3+2]); 1255 break; 1256 default: _error_("mesh "<<EnumToStringx(meshtype)<<" not supported yet"); 1257 } 1258 element->AddInput(PressureEnum,pressure,P1Enum); 1259 xDelete<IssmDouble>(pressure); 1260 xDelete<IssmDouble>(thickness); 1261 xDelete<IssmDouble>(surface); 1262 1263 /*Get basal element*/ 1264 switch(meshtype){ 1265 case Mesh2DhorizontalEnum: 1266 basalelement = element; 1267 break; 1268 case Mesh3DEnum: 1269 if(!element->IsOnBed()){xDelete<IssmDouble>(xyz_list); return;} 1270 basalelement=element->SpawnBasalElement(); 1271 break; 1272 default: _error_("mesh "<<EnumToStringx(meshtype)<<" not supported yet"); 1273 } 1068 1274 1069 1275 /*Fetch number of nodes and dof for this finite element*/ 1070 int numnodes = element->GetNumberOfNodes();1276 int numnodes = basalelement->GetNumberOfNodes(); 1071 1277 int numdof = numnodes*2; 1072 1278 1073 1279 /*Fetch dof list and allocate solution vectors*/ 1074 element->GetDofList(&doflist,NoneApproximationEnum,GsetEnum);1280 basalelement->GetDofList(&doflist,SSAApproximationEnum,GsetEnum); 1075 1281 IssmDouble* values = xNew<IssmDouble>(numdof); 1076 1282 IssmDouble* vx = xNew<IssmDouble>(numnodes); … … 1078 1284 IssmDouble* vz = xNew<IssmDouble>(numnodes); 1079 1285 IssmDouble* vel = xNew<IssmDouble>(numnodes); 1080 IssmDouble* pressure = xNew<IssmDouble>(numnodes);1081 IssmDouble* surface = xNew<IssmDouble>(numnodes);1082 1286 1083 1287 /*Use the dof list to index into the solution vector: */ … … 1085 1289 1086 1290 /*Transform solution in Cartesian Space*/ 1087 element->TransformSolutionCoord(&values[0],XYEnum);1088 element->FindParam(&meshtype,MeshTypeEnum);1291 basalelement->TransformSolutionCoord(&values[0],XYEnum); 1292 basalelement->FindParam(&meshtype,MeshTypeEnum); 1089 1293 1090 1294 /*Ok, we have vx and vy in values, fill in vx and vy arrays: */ … … 1099 1303 1100 1304 /*Get Vz and compute vel*/ 1101 element->GetInputListOnNodes(&vz[0],VzEnum,0.);1305 basalelement->GetInputListOnNodes(&vz[0],VzEnum,0.); 1102 1306 for(i=0;i<numnodes;i++) vel[i]=sqrt(vx[i]*vx[i] + vy[i]*vy[i] + vz[i]*vz[i]); 1103 1104 /*For pressure: we have not computed pressure in this analysis, for this element. We are in 2D,1105 *so the pressure is just the pressure at the bedrock: */1106 rho_ice = element->GetMaterialParameter(MaterialsRhoIceEnum);1107 g = element->GetMaterialParameter(ConstantsGEnum);1108 element->GetVerticesCoordinates(&xyz_list);1109 element->GetInputListOnNodes(&surface[0],SurfaceEnum);1110 for(i=0;i<numnodes;i++) pressure[i]=rho_ice*g*(surface[i]-xyz_list[i*3+2]);1111 1307 1112 1308 /*Now, we have to move the previous Vx and Vy inputs to old … … 1114 1310 element->InputChangeName(VxEnum,VxPicardEnum); 1115 1311 element->InputChangeName(VyEnum,VyPicardEnum); 1116 element->InputChangeName(PressureEnum,PressurePicardEnum);1117 1312 1118 1313 /*Add vx and vy as inputs to the tria element: */ 1119 element->Add Input(VxEnum,vx,P1Enum);1120 element->Add Input(VyEnum,vy,P1Enum);1314 element->AddBasalInput(VxEnum,vx,P1Enum); 1315 element->AddBasalInput(VyEnum,vy,P1Enum); 1121 1316 element->AddBasalInput(VelEnum,vel,P1Enum); 1122 element->AddBasalInput(PressureEnum,pressure,P1Enum);1123 1317 1124 1318 /*Free ressources:*/ 1125 xDelete<IssmDouble>(surface);1126 xDelete<IssmDouble>(pressure);1127 1319 xDelete<IssmDouble>(vel); 1128 1320 xDelete<IssmDouble>(vz); … … 1132 1324 xDelete<IssmDouble>(xyz_list); 1133 1325 xDelete<int>(doflist); 1134 }/*}}}*/ 1135 void StressbalanceAnalysis::InputUpdateFromSolutionFS(IssmDouble* solution,Element* element){/*{{{*/ 1136 1137 int i,dim,meshtype; 1138 int* vdoflist=NULL; 1139 int* pdoflist=NULL; 1140 IssmDouble FSreconditioning; 1141 1142 element->FindParam(&meshtype,MeshTypeEnum); 1143 element->FindParam(&FSreconditioning,StressbalanceFSreconditioningEnum); 1144 switch(meshtype){ 1145 case Mesh2DverticalEnum: dim = 2; break; 1146 case Mesh3DEnum: dim = 3; break; 1147 default: _error_("mesh "<<EnumToStringx(meshtype)<<" not supported yet"); 1148 } 1149 1150 /*Fetch number of nodes and dof for this finite element*/ 1151 int vnumnodes = element->GetNumberOfNodesVelocity(); 1152 int pnumnodes = element->GetNumberOfNodesPressure(); 1153 int vnumdof = vnumnodes*dim; 1154 int pnumdof = pnumnodes*1; 1155 1156 /*Initialize values*/ 1157 IssmDouble* values = xNew<IssmDouble>(vnumdof+pnumdof); 1158 IssmDouble* vx = xNew<IssmDouble>(vnumnodes); 1159 IssmDouble* vy = xNew<IssmDouble>(vnumnodes); 1160 IssmDouble* vz = xNew<IssmDouble>(vnumnodes); 1161 IssmDouble* vel = xNew<IssmDouble>(vnumnodes); 1162 IssmDouble* pressure = xNew<IssmDouble>(pnumnodes); 1163 1164 /*Prepare coordinate system list*/ 1165 int* cs_list = xNew<int>(vnumnodes+pnumnodes); 1166 if(dim==2){ 1167 for(i=0;i<vnumnodes;i++) cs_list[i] = XYEnum; 1168 } 1169 else{ 1170 for(i=0;i<vnumnodes;i++) cs_list[i] = XYZEnum; 1171 } 1172 for(i=0;i<pnumnodes;i++) cs_list[vnumnodes+i] = PressureEnum; 1173 1174 /*Get dof list: */ 1175 element->GetDofListVelocity(&vdoflist,GsetEnum); 1176 element->GetDofListPressure(&pdoflist,GsetEnum); 1177 1178 /*Use the dof list to index into the solution vector: */ 1179 for(i=0;i<vnumdof;i++) values[i] =solution[vdoflist[i]]; 1180 for(i=0;i<pnumdof;i++) values[vnumdof+i]=solution[pdoflist[i]]; 1181 1182 /*Transform solution in Cartesian Space*/ 1183 element->TransformSolutionCoord(&values[0],&cs_list[0]); 1184 1185 /*Ok, we have vx and vy in values, fill in all arrays: */ 1186 for(i=0;i<vnumnodes;i++){ 1187 vx[i] = values[i*dim+0]; 1188 vy[i] = values[i*dim+1]; 1189 if(xIsNan<IssmDouble>(vx[i])) _error_("NaN found in solution vector"); 1190 if(xIsNan<IssmDouble>(vy[i])) _error_("NaN found in solution vector"); 1191 1192 if(dim==3){ 1193 vz[i] = values[i*dim+2]; 1194 if(xIsNan<IssmDouble>(vz[i])) _error_("NaN found in solution vector"); 1195 } 1196 } 1197 for(i=0;i<pnumnodes;i++){ 1198 pressure[i] = values[vnumdof+i]; 1199 if(xIsNan<IssmDouble>(pressure[i])) _error_("NaN found in solution vector"); 1200 } 1201 1202 /*Recondition pressure and compute vel: */ 1203 for(i=0;i<pnumnodes;i++) pressure[i] = pressure[i]*FSreconditioning; 1204 if(dim==3) for(i=0;i<vnumnodes;i++) vel[i] = sqrt(vx[i]*vx[i] + vy[i]*vy[i] + vz[i]*vz[i]); 1205 else for(i=0;i<vnumnodes;i++) vel[i] = sqrt(vx[i]*vx[i] + vy[i]*vy[i]); 1206 1207 /*Now, we have to move the previous inputs to old 1208 * status, otherwise, we'll wipe them off: */ 1209 element->InputChangeName(VxEnum,VxPicardEnum); 1210 element->InputChangeName(VyEnum,VyPicardEnum); 1211 element->InputChangeName(PressureEnum,PressurePicardEnum); 1212 if(dim==3) element->InputChangeName(VzEnum,VzPicardEnum); 1213 1214 /*Add vx and vy as inputs to the tria element: */ 1215 element->AddInput(VxEnum,vx,P1Enum); 1216 element->AddInput(VyEnum,vy,P1Enum); 1217 element->AddInput(VelEnum,vel,P1Enum); 1218 element->AddInput(PressureEnum,pressure,P1Enum); 1219 if(dim==3) element->AddInput(VzEnum,vz,P1Enum); 1220 1221 /*Free ressources:*/ 1222 xDelete<IssmDouble>(pressure); 1223 xDelete<IssmDouble>(vel); 1224 xDelete<IssmDouble>(vz); 1225 xDelete<IssmDouble>(vy); 1226 xDelete<IssmDouble>(vx); 1227 xDelete<IssmDouble>(values); 1228 xDelete<int>(vdoflist); 1229 xDelete<int>(pdoflist); 1230 xDelete<int>(cs_list); 1326 if(meshtype!=Mesh2DhorizontalEnum) delete basalelement; 1231 1327 }/*}}}*/ 1232 1328 void StressbalanceAnalysis::InputUpdateFromSolutionSSAHO(IssmDouble* solution,Element* element){/*{{{*/ … … 1252 1348 /*Fetch dof list and allocate solution vectors*/ 1253 1349 basalelement->GetDofList(&SSAdoflist,SSAApproximationEnum,GsetEnum); 1254 element ->GetDofList(&HOdoflist, HOApproximationEnum, GsetEnum);1350 element ->GetDofList(&HOdoflist, HOApproximationEnum, GsetEnum); 1255 1351 IssmDouble* HOvalues = xNew<IssmDouble>(numdof); 1256 1352 IssmDouble* SSAvalues = xNew<IssmDouble>(numdof); -
issm/trunk-jpl/src/c/analyses/StressbalanceAnalysis.h
r16762 r16773 24 24 void InputUpdateFromSolutionFS(IssmDouble* solution,Element* element); 25 25 void InputUpdateFromSolutionHO(IssmDouble* solution,Element* element); 26 void InputUpdateFromSolutionL1L2(IssmDouble* solution,Element* element); 26 27 void InputUpdateFromSolutionSSA(IssmDouble* solution,Element* element); 27 28 void InputUpdateFromSolutionSSAHO(IssmDouble* solution,Element* element);
Note:
See TracChangeset
for help on using the changeset viewer.