Changeset 27035 for issm/trunk/src/c/analyses/FreeSurfaceTopAnalysis.cpp
- Timestamp:
- 06/01/22 05:01:48 (3 years ago)
- Location:
- issm/trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk
- Property svn:mergeinfo changed
/issm/trunk-jpl merged: 26745-26955,26957-27031
- Property svn:mergeinfo changed
-
issm/trunk/src
- Property svn:mergeinfo changed
-
issm/trunk/src/c/analyses/FreeSurfaceTopAnalysis.cpp
r26744 r27035 80 80 iomodel->FetchDataToInput(inputs,elements,"md.mask.ice_levelset",MaskIceLevelsetEnum); 81 81 iomodel->FetchDataToInput(inputs,elements,"md.initialization.vx",VxEnum); 82 iomodel->FetchDataToInput(inputs,elements,"md.initialization.vy",VyEnum); 82 83 if(iomodel->domaintype!=Domain2DhorizontalEnum){ 83 84 iomodel->FetchDataToInput(inputs,elements,"md.mesh.vertexonsurface",MeshVertexonsurfaceEnum); … … 111 112 }/*}}}*/ 112 113 ElementMatrix* FreeSurfaceTopAnalysis::CreateJacobianMatrix(Element* element){/*{{{*/ 113 _error_("Not implemented");114 _error_("Not implemented"); 114 115 }/*}}}*/ 115 116 ElementMatrix* FreeSurfaceTopAnalysis::CreateKMatrix(Element* element){/*{{{*/ … … 120 121 IssmDouble *xyz_list = NULL; 121 122 IssmDouble Jdet,D_scalar,dt,h; 122 IssmDouble vel,vx,vy ;123 IssmDouble vel,vx,vy,tau; 123 124 124 125 /*Get top element*/ … … 195 196 } 196 197 197 if(stabilization==2){ 198 if(stabilization==1){ 199 /*artifical diffusion*/ 200 if(dim==1){ 201 vx_input->GetInputAverage(&vx); 202 D[0]=h/2.*fabs(vx); 203 } 204 else{ 205 vx_input->GetInputAverage(&vx); 206 vy_input->GetInputAverage(&vy); 207 208 D[0*dim+0]=h/2.0*fabs(vx); 209 D[1*dim+1]=h/2.0*fabs(vy); 210 } 211 } 212 else if(stabilization==2){ 198 213 /*Streamline upwinding*/ 199 214 if(dim==1){ … … 209 224 } 210 225 } 211 else if(stabilization== 1){212 /*S SA*/226 else if(stabilization==5){ 227 /*SUPG*/ 213 228 if(dim==1){ 214 229 vx_input->GetInputAverage(&vx); 215 D[0]=h/2.*fabs(vx);230 tau=h/(2.*fabs(vx)+1e-10); 216 231 } 217 232 else{ 218 233 vx_input->GetInputAverage(&vx); 219 234 vy_input->GetInputAverage(&vy); 220 221 D[0*dim+0]=h/2.0*fabs(vx); 222 D[1*dim+1]=h/2.0*fabs(vy); 235 tau=1*h/(2.*pow(vx*vx+vy*vy,0.5)+1e-10); 223 236 } 224 237 } … … 229 242 for(int j=0;j<numnodes;j++){ 230 243 Ke->values[i*numnodes+j] += ( 231 232 233 244 dbasis[0*numnodes+i] *(D[0*dim+0]*dbasis[0*numnodes+j] + D[0*dim+1]*dbasis[1*numnodes+j]) + 245 dbasis[1*numnodes+i] *(D[1*dim+0]*dbasis[0*numnodes+j] + D[1*dim+1]*dbasis[1*numnodes+j]) 246 ); 234 247 } 235 248 } … … 237 250 else{ 238 251 for(int i=0;i<numnodes;i++) for(int j=0;j<numnodes;j++) Ke->values[i*numnodes+j] += dbasis[0*numnodes+i]*D[0]*dbasis[0*numnodes+j]; 252 } 253 } 254 else if(stabilization==5){ 255 D_scalar=gauss->weight*Jdet*dt; 256 if(dim==2){ 257 for(int i=0;i<numnodes;i++){ 258 for(int j=0;j<numnodes;j++){ 259 Ke->values[i*numnodes+j]+=tau*D_scalar* 260 (vx*dbasis[0*numnodes+i]+vy*dbasis[1*numnodes+i])* 261 (vx*dbasis[0*numnodes+j]+vy*dbasis[1*numnodes+j]); 262 } 263 } 264 } 265 else{ 266 for(int i=0;i<numnodes;i++) for(int j=0;j<numnodes;j++) Ke->values[i*numnodes+j]+=tau*D_scalar*(vx*dbasis[0*numnodes+i])*(vx*dbasis[0*numnodes+j]); 239 267 } 240 268 } … … 251 279 }/*}}}*/ 252 280 ElementVector* FreeSurfaceTopAnalysis::CreatePVector(Element* element){/*{{{*/ 281 253 282 /*Intermediaries*/ 254 int domaintype,dim ;283 int domaintype,dim,stabilization; 255 284 IssmDouble Jdet,dt; 256 IssmDouble ms,surface,v z;285 IssmDouble ms,surface,vx,vy,vz,tau; 257 286 Element* topelement = NULL; 258 287 IssmDouble *xyz_list = NULL; … … 284 313 ElementVector* pe = topelement->NewElementVector(); 285 314 IssmDouble* basis = xNew<IssmDouble>(numnodes); 315 IssmDouble* dbasis = xNew<IssmDouble>(dim*numnodes); 286 316 287 317 /*Retrieve all inputs and parameters*/ 288 318 topelement->GetVerticesCoordinates(&xyz_list); 289 319 topelement->FindParam(&dt,TimesteppingTimeStepEnum); 290 Input* ms_input = topelement->GetInput(SmbMassBalanceEnum); _assert_(ms_input); 291 Input* surface_input = topelement->GetInput(SurfaceEnum); _assert_(surface_input); 292 Input* vz_input = NULL; 320 Input *ms_input = topelement->GetInput(SmbMassBalanceEnum); _assert_(ms_input); 321 Input *surface_input = topelement->GetInput(SurfaceEnum); _assert_(surface_input); 322 Input *vz_input = NULL; 323 Input *vx_input = NULL; 324 Input *vy_input = NULL; 293 325 switch(dim){ 294 case 1: vz_input = topelement->GetInput(VyEnum); _assert_(vz_input); break; 295 case 2: vz_input = topelement->GetInput(VzEnum); _assert_(vz_input); break; 326 case 1: 327 vx_input=topelement->GetInput(VxEnum); _assert_(vx_input); 328 vz_input = topelement->GetInput(VyEnum) ; _assert_(vz_input); 329 break; 330 case 2: 331 vx_input=topelement->GetInput(VxEnum); _assert_(vx_input); 332 vy_input = topelement->GetInput(VyEnum); _assert_(vy_input); 333 vz_input = topelement->GetInput(VzEnum); _assert_(vz_input); 334 break; 296 335 default: _error_("not implemented"); 297 336 } 337 IssmDouble h = topelement->CharacteristicLength(); 298 338 299 339 /*Initialize mb_correction to 0, do not forget!:*/ … … 312 352 } 313 353 354 if(stabilization==5){ 355 /*SUPG*/ 356 topelement->NodalFunctionsDerivatives(dbasis,xyz_list,gauss); 357 if(dim==1){ 358 vx_input->GetInputAverage(&vx); 359 tau=h/(2.*fabs(vx)+1e-10); 360 for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(dt*ms+dt*vz)*tau*(vx*dbasis[0*numnodes+i]); 361 } 362 else{ 363 vx_input->GetInputAverage(&vx); 364 vy_input->GetInputAverage(&vy); 365 tau=h/(2.*pow(vx*vx+vy*vy,0.5)+1e-10); 366 for(int i=0;i<numnodes;i++) pe->values[i]+=Jdet*gauss->weight*(dt*ms+dt*vz)*tau*(vx*dbasis[0*numnodes+i]+vy*dbasis[1*numnodes+i]); 367 } 368 } 369 314 370 /*Clean up and return*/ 315 371 xDelete<IssmDouble>(xyz_list); 316 372 xDelete<IssmDouble>(basis); 373 xDelete<IssmDouble>(dbasis); 317 374 delete gauss; 318 375 if(topelement->IsSpawnedElement()){topelement->DeleteMaterials(); delete topelement;}; … … 321 378 }/*}}}*/ 322 379 void FreeSurfaceTopAnalysis::GetSolutionFromInputs(Vector<IssmDouble>* solution,Element* element){/*{{{*/ 323 380 _error_("not implemented yet"); 324 381 }/*}}}*/ 325 382 void FreeSurfaceTopAnalysis::GradientJ(Vector<IssmDouble>* gradient,Element* element,int control_type,int control_interp,int control_index){/*{{{*/ … … 329 386 330 387 element->InputUpdateFromSolutionOneDof(solution,SurfaceEnum); 388 389 /*Now, we need to do some "processing"*/ 390 int numvertices = element->GetNumberOfVertices(); 391 int migration_style; 392 393 IssmDouble* surface = xNew<IssmDouble>(numvertices); 394 IssmDouble* newsurface = xNew<IssmDouble>(numvertices); 395 IssmDouble* thickness = xNew<IssmDouble>(numvertices); 396 IssmDouble* base = xNew<IssmDouble>(numvertices); 397 IssmDouble* bed = xNew<IssmDouble>(numvertices); 398 IssmDouble* phi = xNew<IssmDouble>(numvertices); 399 IssmDouble* sealevel = xNew<IssmDouble>(numvertices); 400 401 IssmDouble minthickness = element->FindParam(MasstransportMinThicknessEnum); 402 IssmDouble rho_ice = element->FindParam(MaterialsRhoIceEnum); 403 IssmDouble rho_water = element->FindParam(MaterialsRhoSeawaterEnum); 404 405 bool isgroundingline; 406 element->FindParam(&isgroundingline,TransientIsgroundinglineEnum); 407 element->FindParam(&migration_style,GroundinglineMigrationEnum); 408 if(isgroundingline) element->GetInputListOnVertices(&bed[0],BedEnum); 409 410 element->GetInputListOnVertices(&base[0],BaseEnum); 411 element->GetInputListOnVertices(&surface[0],SurfaceEnum); 412 element->GetInputListOnVertices(&phi[0],MaskOceanLevelsetEnum); 413 element->GetInputListOnVertices(&sealevel[0],SealevelEnum); 414 415 for(int i=0;i<numvertices;i++){ 416 newsurface[i]=surface[i]; 417 thickness[i]=surface[i]-base[i]; 418 /*Check solution*/ 419 if(xIsNan<IssmDouble>(thickness[i])) _error_("NaN found in solution vector"); 420 if(xIsInf<IssmDouble>(thickness[i])) _error_("Inf found in solution vector"); 421 422 /* check for thickness<minthickness */ 423 if(thickness[i]<minthickness){ 424 thickness[i]=minthickness; 425 if(phi[i]>0.){ 426 if(base[i]<=bed[i]) base[i] = bed[i]; 427 newsurface[i] = base[i]+minthickness; 428 }else{ 429 // assume floatation condition 430 newsurface[i] = (1.-rho_ice/rho_water)*minthickness; 431 base[i] = -rho_ice/rho_water*minthickness; 432 } 433 } 434 435 /* update thickness */ 436 thickness[i]=newsurface[i]-base[i]; 437 /* some checks */ 438 if(thickness[i]<0.) _error_("thickness<0"); 439 if(newsurface[i]<base[i]) _error_("surface<base"); 440 } 441 442 /* update inputs */ 443 element->AddInput(BaseEnum,base,element->GetElementType()); 444 element->AddInput(SurfaceEnum,newsurface,element->GetElementType()); 445 element->AddInput(ThicknessEnum,thickness,element->GetElementType()); 446 447 /* Free resources */ 448 xDelete<IssmDouble>(newsurface); 449 xDelete<IssmDouble>(surface); 450 xDelete<IssmDouble>(thickness); 451 xDelete<IssmDouble>(base); 452 xDelete<IssmDouble>(bed); 453 xDelete<IssmDouble>(phi); 454 xDelete<IssmDouble>(sealevel); 331 455 }/*}}}*/ 332 456 void FreeSurfaceTopAnalysis::UpdateConstraints(FemModel* femmodel){/*{{{*/
Note:
See TracChangeset
for help on using the changeset viewer.