Changeset 17028
- Timestamp:
- 12/19/13 05:36:17 (11 years ago)
- Location:
- issm/trunk-jpl/src/c
- Files:
-
- 1 deleted
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/c/Makefile.am
r16911 r17028 391 391 #}}} 392 392 #Thermal sources {{{ 393 thermal_sources = ./modules/PostprocessingEnthalpyx/PostprocessingEnthalpyx.h\ 394 ./modules/PostprocessingEnthalpyx/PostprocessingEnthalpyx.cpp\ 395 ./analyses/ThermalAnalysis.h\ 393 thermal_sources = ./analyses/ThermalAnalysis.h\ 396 394 ./analyses/ThermalAnalysis.cpp\ 397 395 ./analyses/EnthalpyAnalysis.h\ -
issm/trunk-jpl/src/c/classes/Elements/Element.h
r17027 r17028 271 271 virtual void UpdateConstraintsExtrudeFromTop(void)=0; 272 272 273 #ifdef _HAVE_THERMAL_274 virtual void UpdateBasalConstraintsEnthalpy(void)=0;275 virtual void ComputeBasalMeltingrate(void)=0;276 virtual void DrainWaterfraction(IssmDouble* drainrate_element)=0;277 #endif278 279 273 #ifdef _HAVE_HYDROLOGY_ 280 274 virtual void GetHydrologyDCInefficientHmax(IssmDouble* ph_max,int index)=0; -
issm/trunk-jpl/src/c/classes/Elements/Penta.cpp
r17014 r17028 3282 3282 #endif 3283 3283 3284 #ifdef _HAVE_THERMAL_3285 /*FUNCTION Penta::UpdateBasalConstraintsEnthalpy{{{*/3286 void Penta::UpdateBasalConstraintsEnthalpy(void){3287 3288 /*Intermediary*/3289 bool isenthalpy,isdynamicbasalspc,setspc;3290 int numindices, numindicesup;3291 IssmDouble pressure, pressureup;3292 IssmDouble h_pmp, enthalpy, enthalpyup;3293 IssmDouble watercolumn;3294 int *indices = NULL, *indicesup = NULL;3295 3296 /* Only update Constraints at the base of grounded ice*/3297 if(!IsOnBed() || IsFloating()) return;3298 3299 /*Check wether dynamic basal boundary conditions are activated */3300 parameters->FindParam(&isenthalpy,ThermalIsenthalpyEnum);3301 if(!isenthalpy) return;3302 parameters->FindParam(&isdynamicbasalspc,ThermalIsdynamicbasalspcEnum);3303 if(!isdynamicbasalspc) return;3304 3305 /*Fetch indices of basal & surface nodes for this finite element*/3306 BasalNodeIndices(&numindices,&indices,this->element_type);3307 SurfaceNodeIndices(&numindicesup,&indicesup,this->element_type);3308 _assert_(numindices==numindicesup);3309 3310 /*Get parameters and inputs: */3311 Input* pressure_input=inputs->GetInput(PressureEnum); _assert_(pressure_input);3312 Input* enthalpy_input=inputs->GetInput(EnthalpyEnum); _assert_(enthalpy_input);3313 Input* watercolumn_input=inputs->GetInput(WatercolumnEnum); //_assert_(watercolumn_input);3314 3315 /*if there is a temperate layer of zero thickness, set spc enthalpy=h_pmp at that node*/3316 GaussPenta* gauss=new GaussPenta();3317 GaussPenta* gaussup=new GaussPenta();3318 for(int i=0;i<numindices;i++){3319 gauss->GaussNode(this->element_type,indices[i]);3320 gaussup->GaussNode(this->element_type,indicesup[i]);3321 3322 /*Check wether there is a temperate layer at the base or not */3323 /*check if node is temperate, if not, continue*/3324 enthalpy_input->GetInputValue(&enthalpy, gauss);3325 pressure_input->GetInputValue(&pressure, gauss);3326 watercolumn_input->GetInputValue(&watercolumn,gauss);3327 setspc = false;3328 if (enthalpy>=matpar->PureIceEnthalpy(pressure)){3329 /*check if upper node is temperate, too.3330 if yes, then we have a temperate layer of positive thickness and reset the spc.3331 if not, apply dirichlet BC.*/3332 enthalpy_input->GetInputValue(&enthalpyup, gaussup);3333 pressure_input->GetInputValue(&pressureup, gaussup);3334 setspc=((enthalpyup<matpar->PureIceEnthalpy(pressureup)) && (watercolumn>=0.))?true:false;3335 }3336 3337 if (setspc) {3338 /*Calculate enthalpy at pressure melting point */3339 h_pmp=matpar->PureIceEnthalpy(pressure);3340 /*Apply Dirichlet condition (dof = 0 here, since there is only one degree of freedom per node)*/3341 nodes[indices[i]]->ApplyConstraint(1,h_pmp);3342 }3343 else {3344 /*remove spc*/3345 nodes[indices[i]]->DofInFSet(0);3346 }3347 }3348 3349 /*Free ressources:*/3350 xDelete<int>(indices);3351 xDelete<int>(indicesup);3352 delete gauss;3353 delete gaussup;3354 }3355 /*}}}*/3356 /*FUNCTION Penta::ComputeBasalMeltingrate{{{*/3357 void Penta::ComputeBasalMeltingrate(void){3358 /*Calculate the basal melt rates of the enthalpy model after Aschwanden 2012*/3359 /* melting rate is positive when melting, negative when refreezing*/3360 3361 /* Intermediaries */3362 bool isenthalpy, checkpositivethickness, istemperatelayer;3363 int i,j,iv,analysis_type;3364 IssmDouble xyz_list[NUMVERTICES][3];3365 IssmDouble xyz_list_tria[NUMVERTICES2D][3];3366 IssmDouble heatflux,kappa;3367 IssmDouble vec_heatflux[3];3368 IssmDouble normal_base[3], d1enthalpy[3];3369 IssmDouble basalmeltingrate[NUMVERTICES], watercolumn[NUMVERTICES];3370 IssmDouble enthalpy[NUMVERTICES],pressure[NUMVERTICES];3371 IssmDouble temperature, waterfraction;3372 IssmDouble latentheat, rho_ice;3373 IssmDouble basalfriction, alpha2;3374 IssmDouble vx[NUMVERTICES],vy[NUMVERTICES],vz[NUMVERTICES];3375 IssmDouble geothermalflux[NUMVERTICES];3376 IssmDouble dt, yts;3377 IssmDouble melting_overshoot,meltingrate_enthalpy[NUMVERTICES2D];3378 IssmDouble drainrate_element[NUMVERTICES2D],drainrate_column[NUMVERTICES2D];3379 IssmDouble lambda,heating[NUMVERTICES2D];3380 Friction *friction = NULL;3381 Penta *penta = NULL;3382 3383 /* Only compute melt rates at the base of grounded ice*/3384 if(!IsOnBed() || IsFloating()) return;3385 3386 /*Check wether enthalpy is activated*/3387 parameters->FindParam(&isenthalpy,ThermalIsenthalpyEnum);3388 if(!isenthalpy) return;3389 3390 /*Fetch parameters and inputs */3391 latentheat=matpar->GetLatentHeat();3392 rho_ice=matpar->GetRhoIce();3393 GetInputListOnVertices(&vx[0],VxEnum);3394 GetInputListOnVertices(&vy[0],VyEnum);3395 GetInputListOnVertices(&vz[0],VzEnum);3396 GetInputListOnVertices(&enthalpy[0],EnthalpyEnum);3397 GetInputListOnVertices(&pressure[0],PressureEnum);3398 GetInputListOnVertices(&watercolumn[0],WatercolumnEnum);3399 GetInputListOnVertices(&basalmeltingrate[0],BasalforcingsMeltingRateEnum);3400 GetInputListOnVertices(&geothermalflux[0],BasalforcingsGeothermalfluxEnum);3401 Input* enthalpy_input=inputs->GetInput(EnthalpyEnum); _assert_(enthalpy_input);3402 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);3403 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);3404 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);3405 3406 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);3407 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];3408 3409 /*Build friction element, needed later: */3410 parameters->FindParam(&analysis_type,AnalysisTypeEnum);3411 friction=new Friction(this,3);3412 3413 /******** MELTING RATES ************************************/3414 GaussPenta* gauss=new GaussPenta();3415 for(iv=0;iv<NUMVERTICES2D;iv++){3416 3417 gauss->GaussVertex(iv);3418 checkpositivethickness=true;3419 3420 _assert_(watercolumn[iv]>=0.);3421 3422 /*Calculate basal meltingrate after Fig.5 of A.Aschwanden 2012*/3423 meltingrate_enthalpy[iv]=0.;3424 heating[iv]=0.;3425 if((watercolumn[iv]>0.) && (enthalpy[iv]<matpar->PureIceEnthalpy(pressure[iv]))){3426 /*ensure that no ice is at T<Tm(p), if water layer present*/3427 enthalpy[iv]=matpar->PureIceEnthalpy(pressure[iv]);3428 }3429 else if(enthalpy[iv]<matpar->PureIceEnthalpy(pressure[iv])){3430 /*cold base: set q*n=q_geo*n+frictionheating as Neumann BC in Penta::CreatePVectorEnthalpySheet*/3431 checkpositivethickness=false; // cold base, skip next test3432 }3433 else {/*we have a temperate base, go to next test*/}3434 3435 if(checkpositivethickness){3436 /*ok, from here on all basal ice is temperate. Check for positive thickness of layer of temperate ice. */3437 istemperatelayer=false;3438 if(enthalpy[iv+NUMVERTICES2D]>=matpar->PureIceEnthalpy(pressure[iv+NUMVERTICES2D])) istemperatelayer=true;3439 if(istemperatelayer) for(i=0;i<3;i++) vec_heatflux[i]=0.; // TODO: add -k*nabla T_pmp3440 else{3441 enthalpy_input->GetInputDerivativeValue(&d1enthalpy[0],&xyz_list[0][0],gauss);3442 kappa=matpar->GetEnthalpyDiffusionParameterVolume(NUMVERTICES,&enthalpy[0],&pressure[0]); _assert_(kappa>0.);3443 for(i=0;i<3;i++) vec_heatflux[i]=-kappa*d1enthalpy[i];3444 }3445 3446 /*geothermal heatflux*/3447 NormalBase(&normal_base[0],&xyz_list_tria[0][0]);3448 heatflux=0.;3449 for(i=0;i<3;i++) heatflux+=(vec_heatflux[i])*normal_base[i];3450 3451 /*basal friction*/3452 friction->GetAlpha2(&alpha2,gauss,vx_input,vy_input,vz_input);3453 basalfriction=alpha2*(pow(vx[iv],2.0)+pow(vy[iv],2.0)+pow(vz[iv],2.0));3454 3455 matpar->EnthalpyToThermal(&temperature, &waterfraction, enthalpy[iv],pressure[iv]);3456 // -Mb= Fb-(q-q_geo)/((1-w)*L), cf Aschwanden 2012, eq.663457 heating[iv]=(heatflux+basalfriction+geothermalflux[iv]);3458 meltingrate_enthalpy[iv]=heating[iv]/((1-waterfraction)*latentheat*rho_ice); // m/s water equivalent3459 }3460 }3461 // enthalpy might have been changed, update3462 this->inputs->AddInput(new PentaInput(EnthalpyEnum,enthalpy,P1Enum));3463 3464 /******** DRAINAGE *****************************************/3465 for(iv=0; iv<NUMVERTICES2D; iv++)3466 drainrate_column[iv]=0.;3467 penta=this;3468 3469 for(;;){3470 for(iv=0; iv<NUMVERTICES2D; iv++) drainrate_element[iv]=0.;3471 penta->DrainWaterfraction(&drainrate_element[0]); // TODO: make sure every vertex is only drained once3472 for(iv=0; iv<NUMVERTICES2D; iv++) drainrate_column[iv]+=drainrate_element[iv];3473 3474 if(penta->IsOnSurface()) break;3475 penta=penta->GetUpperPenta();3476 }3477 // add drained water to melting rate3478 for(iv=0; iv<NUMVERTICES2D;iv++)3479 meltingrate_enthalpy[iv]+=drainrate_column[iv];3480 3481 /******** UPDATE MELTINGRATES AND WATERCOLUMN **************/3482 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);3483 for(iv=0;iv<NUMVERTICES2D;iv++){3484 if(reCast<bool,IssmDouble>(dt)){3485 if(watercolumn[iv]+meltingrate_enthalpy[iv]*dt<0.){3486 melting_overshoot=watercolumn[iv]+meltingrate_enthalpy[iv]*dt;3487 lambda=melting_overshoot/(meltingrate_enthalpy[iv]*dt); _assert_(lambda>0); _assert_(lambda<1);3488 basalmeltingrate[iv]=(1.-lambda)*meltingrate_enthalpy[iv];3489 watercolumn[iv]=0.;3490 yts=365*24*60*60;3491 enthalpy[iv]+=dt/yts*lambda*heating[iv];3492 }3493 else{3494 basalmeltingrate[iv]=meltingrate_enthalpy[iv];3495 watercolumn[iv]+=dt*meltingrate_enthalpy[iv];3496 }3497 }3498 else{3499 basalmeltingrate[iv]=meltingrate_enthalpy[iv];3500 watercolumn[iv]+=meltingrate_enthalpy[iv];3501 }3502 3503 _assert_(watercolumn[iv]>=0.);3504 }3505 3506 /*feed updated variables back into model*/3507 this->inputs->AddInput(new PentaInput(EnthalpyEnum,enthalpy,P1Enum));3508 this->inputs->AddInput(new PentaInput(WatercolumnEnum,watercolumn,P1Enum));3509 this->inputs->AddInput(new PentaInput(BasalforcingsMeltingRateEnum,basalmeltingrate,P1Enum));3510 3511 /*Clean up and return*/3512 delete gauss;3513 delete friction;3514 }3515 /*}}}*/3516 /*FUNCTION Penta::DrainWaterfraction{{{*/3517 void Penta::DrainWaterfraction(IssmDouble* drainrate_element){3518 3519 /*Intermediaries*/3520 bool isenthalpy;3521 int iv, index0;3522 IssmDouble waterfraction[NUMVERTICES], temperature[NUMVERTICES];3523 IssmDouble dw[NUMVERTICES];3524 IssmDouble enthalpy[NUMVERTICES], pressure[NUMVERTICES];3525 IssmDouble dt, height_element;3526 IssmDouble xyz_list[NUMVERTICES][3];3527 IssmDouble rho_water, rho_ice;3528 3529 /*Check wether enthalpy is activated*/3530 parameters->FindParam(&isenthalpy,ThermalIsenthalpyEnum);3531 if(!isenthalpy) return;3532 3533 rho_ice=matpar->GetRhoIce();3534 rho_water=matpar->GetRhoFreshwater();3535 3536 ::GetVerticesCoordinates(&xyz_list[0][0],vertices,NUMVERTICES);3537 this->GetInputListOnVertices(&enthalpy[0],EnthalpyEnum);3538 this->GetInputListOnVertices(&pressure[0],PressureEnum);3539 3540 this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);3541 for(iv=0;iv<NUMVERTICES;iv++){3542 matpar->EnthalpyToThermal(&temperature[iv],&waterfraction[iv], enthalpy[iv],pressure[iv]);3543 dw[iv]=DrainageFunctionWaterfraction(waterfraction[iv], dt);3544 }3545 3546 /*drain waterfraction, feed updated variables back into model*/3547 for(iv=0;iv<NUMVERTICES;iv++){3548 if(reCast<bool,IssmDouble>(dt))3549 waterfraction[iv]-=dw[iv]*dt;3550 else3551 waterfraction[iv]-=dw[iv];3552 matpar->ThermalToEnthalpy(&enthalpy[iv], temperature[iv], waterfraction[iv], pressure[iv]);3553 }3554 this->inputs->AddInput(new PentaInput(EnthalpyEnum,enthalpy,P1Enum));3555 this->inputs->AddInput(new PentaInput(WaterfractionEnum,waterfraction,P1Enum));3556 3557 /*return meltwater column equivalent to drained water*/3558 for(iv=0;iv<NUMVERTICES2D;iv++){3559 index0=(iv+NUMVERTICES2D);3560 height_element=fabs(xyz_list[index0][2]-xyz_list[iv][2]);3561 drainrate_element[iv]=(dw[iv]+dw[index0])/2.*rho_water/rho_ice*height_element;3562 }3563 }3564 /*}}}*/3565 #endif3566 3567 3284 #ifdef _HAVE_CONTROL_ 3568 3285 /*FUNCTION Penta::ControlInputGetGradient{{{*/ -
issm/trunk-jpl/src/c/classes/Elements/Penta.h
r17014 r17028 269 269 void UpdateConstraintsExtrudeFromBase(void){_error_("not implemented yet");}; 270 270 void UpdateConstraintsExtrudeFromTop(void){_error_("not implemented yet");}; 271 #ifdef _HAVE_THERMAL_272 void UpdateBasalConstraintsEnthalpy(void);273 void ComputeBasalMeltingrate(void);274 void DrainWaterfraction(IssmDouble* drainrate_element);275 #endif276 271 /*}}}*/ 277 272 }; -
issm/trunk-jpl/src/c/classes/Elements/Seg.h
r17027 r17028 159 159 void ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){_error_("not implemented");}; 160 160 161 #ifdef _HAVE_THERMAL_162 void UpdateBasalConstraintsEnthalpy(void){_error_("not implemented yet");};163 void ComputeBasalMeltingrate(void){_error_("not implemented yet");};164 void DrainWaterfraction(IssmDouble* drainrate_element){_error_("not implemented yet");};165 #endif166 161 #ifdef _HAVE_HYDROLOGY_ 167 162 void GetHydrologyDCInefficientHmax(IssmDouble* ph_max, Node* innode){_error_("not implemented yet");}; -
issm/trunk-jpl/src/c/classes/Elements/Tria.h
r17014 r17028 266 266 void UpdateConstraintsExtrudeFromBase(void); 267 267 void UpdateConstraintsExtrudeFromTop(void); 268 #ifdef _HAVE_THERMAL_269 void UpdateBasalConstraintsEnthalpy(void){_error_("not implemented yet");};270 void ComputeBasalMeltingrate(void){_error_("not implemented yet");};271 void DrainWaterfraction(IssmDouble* drainrate_element){_error_("not implemented yet");};272 #endif273 268 274 269 #ifdef _HAVE_HYDROLOGY_ -
issm/trunk-jpl/src/c/modules/modules.h
r16485 r17028 76 76 #include "./PointCloudFindNeighborsx/PointCloudFindNeighborsx.h" 77 77 #include "./PositiveDegreeDayx/PositiveDegreeDayx.h" 78 #include "./PostprocessingEnthalpyx/PostprocessingEnthalpyx.h"79 78 #include "./PropagateFlagsFromConnectivityx/PropagateFlagsFromConnectivityx.h" 80 79 #include "./Reduceloadx/Reduceloadx.h"
Note:
See TracChangeset
for help on using the changeset viewer.