Changeset 17028


Ignore:
Timestamp:
12/19/13 05:36:17 (11 years ago)
Author:
jbondzio
Message:

DEL: UpdateBasalConstraintsEnthalpy, ComputeBasalMeltingrate and DrainWaterfraction from Element and its children. DEL: module PostprocessingEnthalpyx

Location:
issm/trunk-jpl/src/c
Files:
1 deleted
7 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/c/Makefile.am

    r16911 r17028  
    391391#}}}
    392392#Thermal sources  {{{
    393 thermal_sources = ./modules/PostprocessingEnthalpyx/PostprocessingEnthalpyx.h\
    394                                            ./modules/PostprocessingEnthalpyx/PostprocessingEnthalpyx.cpp\
    395                                                 ./analyses/ThermalAnalysis.h\
     393thermal_sources = ./analyses/ThermalAnalysis.h\
    396394                                                ./analyses/ThermalAnalysis.cpp\
    397395                                                ./analyses/EnthalpyAnalysis.h\
  • issm/trunk-jpl/src/c/classes/Elements/Element.h

    r17027 r17028  
    271271                virtual void UpdateConstraintsExtrudeFromTop(void)=0;
    272272
    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                 #endif
    278 
    279273                #ifdef _HAVE_HYDROLOGY_
    280274                virtual void GetHydrologyDCInefficientHmax(IssmDouble* ph_max,int index)=0;
  • issm/trunk-jpl/src/c/classes/Elements/Penta.cpp

    r17014 r17028  
    32823282#endif
    32833283
    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 test
    3432                 }
    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_pmp
    3440                         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.66
    3457                         heating[iv]=(heatflux+basalfriction+geothermalflux[iv]);
    3458                         meltingrate_enthalpy[iv]=heating[iv]/((1-waterfraction)*latentheat*rho_ice); // m/s water equivalent
    3459                 }               
    3460         }
    3461         // enthalpy might have been changed, update
    3462         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 once
    3472                 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 rate
    3478         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                 else
    3551                         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 #endif
    3566 
    35673284#ifdef _HAVE_CONTROL_
    35683285/*FUNCTION Penta::ControlInputGetGradient{{{*/
  • issm/trunk-jpl/src/c/classes/Elements/Penta.h

    r17014 r17028  
    269269                void           UpdateConstraintsExtrudeFromBase(void){_error_("not implemented yet");};
    270270                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                 #endif
    276271                /*}}}*/
    277272};
  • issm/trunk-jpl/src/c/classes/Elements/Seg.h

    r17027 r17028  
    159159                void        ZeroLevelsetCoordinates(IssmDouble** pxyz_zero,IssmDouble* xyz_list,int levelsetenum){_error_("not implemented");};
    160160
    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                 #endif
    166161                #ifdef _HAVE_HYDROLOGY_
    167162                void    GetHydrologyDCInefficientHmax(IssmDouble* ph_max, Node* innode){_error_("not implemented yet");};
  • issm/trunk-jpl/src/c/classes/Elements/Tria.h

    r17014 r17028  
    266266                void UpdateConstraintsExtrudeFromBase(void);
    267267                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                 #endif
    273268
    274269                #ifdef _HAVE_HYDROLOGY_
  • issm/trunk-jpl/src/c/modules/modules.h

    r16485 r17028  
    7676#include "./PointCloudFindNeighborsx/PointCloudFindNeighborsx.h"
    7777#include "./PositiveDegreeDayx/PositiveDegreeDayx.h"
    78 #include "./PostprocessingEnthalpyx/PostprocessingEnthalpyx.h"
    7978#include "./PropagateFlagsFromConnectivityx/PropagateFlagsFromConnectivityx.h"
    8079#include "./Reduceloadx/Reduceloadx.h"
Note: See TracChangeset for help on using the changeset viewer.