Changeset 24010
- Timestamp:
- 06/11/19 11:07:32 (6 years ago)
- Location:
- issm/trunk-jpl/src
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified issm/trunk-jpl/src/c/analyses/GLheightadvectionAnalysis.cpp ¶
r23966 r24010 17 17 18 18 /*First fetch data: */ 19 if(iomodel->domaintype==Domain3DEnum) iomodel->FetchData(2,"md.mesh.vertexonbase","md.mesh.vertexonsurface"); 19 20 ::CreateNodes(nodes,iomodel,GLheightadvectionAnalysisEnum,P1Enum); 21 iomodel->DeleteData(2,"md.mesh.vertexonbase","md.mesh.vertexonsurface"); 20 22 }/*}}}*/ 21 23 int GLheightadvectionAnalysis::DofsPerNode(int** doflist,int domaintype,int approximation){/*{{{*/ … … 56 58 ElementMatrix* GLheightadvectionAnalysis::CreateKMatrix(Element* element){/*{{{*/ 57 59 60 /* Spawn basal element */ 61 if(!element->IsOnBase()) return NULL; 62 Element* basalelement = element->SpawnBasalElement(); 63 58 64 /* Check if ice in element */ 59 if(!element->IsIceInElement()) return NULL; 60 //if(!element->IsFloating()) return NULL; 65 if(!basalelement->IsIceInElement()) return NULL; 61 66 62 67 /*Intermediaries */ … … 65 70 IssmDouble Jdet,D_scalar,onboundary; 66 71 IssmDouble vel,vx,vy; 67 IssmDouble* xyz_list = NULL; 72 IssmDouble* xyz_list = NULL; 73 Input* vx_input = NULL; 74 Input* vy_input = NULL; 75 Input* bc_input = NULL; 68 76 69 77 /*Get problem dimension*/ 70 element->FindParam(&domaintype,DomainTypeEnum);78 basalelement->FindParam(&domaintype,DomainTypeEnum); 71 79 switch(domaintype){ 72 80 case Domain2DhorizontalEnum: dim = 2; break; … … 76 84 77 85 /*Fetch number of nodes and dof for this finite element*/ 78 int numnodes = element->GetNumberOfNodes();86 int numnodes = basalelement->GetNumberOfNodes(); 79 87 80 88 /*Initialize Element vector and other vectors*/ 81 ElementMatrix* Ke = element->NewElementMatrix();89 ElementMatrix* Ke = basalelement->NewElementMatrix(); 82 90 IssmDouble* basis = xNew<IssmDouble>(numnodes); 83 91 IssmDouble* dbasis = xNew<IssmDouble>(dim*numnodes); … … 86 94 87 95 /*Retrieve all inputs and parameters*/ 88 element->GetVerticesCoordinates(&xyz_list); 89 //Input* vx_input=element->GetInput(BaseSlopeXEnum); _assert_(vx_input); 90 //Input* vy_input=element->GetInput(BaseSlopeYEnum); _assert_(vy_input); 91 Input* vx_input=element->GetInput(VxEnum); _assert_(vx_input); 92 Input* vy_input=element->GetInput(VyEnum); _assert_(vy_input); 93 Input* bc_input=element->GetInput(MeshVertexonboundaryEnum); _assert_(bc_input); 94 95 IssmDouble h = element->CharacteristicLength(); 96 basalelement->GetVerticesCoordinates(&xyz_list); 97 switch(domaintype){ 98 case Domain2DhorizontalEnum: 99 vx_input=basalelement->GetInput(VxEnum); _assert_(vx_input); 100 vy_input=basalelement->GetInput(VyEnum); _assert_(vy_input); 101 bc_input=basalelement->GetInput(MeshVertexonboundaryEnum); _assert_(bc_input); 102 break; 103 case Domain3DEnum: 104 vx_input=basalelement->GetInput(VxAverageEnum); _assert_(vx_input); 105 vy_input=basalelement->GetInput(VyAverageEnum); _assert_(vy_input); 106 bc_input=basalelement->GetInput(MeshVertexonboundaryEnum); _assert_(bc_input); 107 break; 108 default: _error_("mesh "<<EnumToStringx(domaintype)<<" not supported yet"); 109 } 110 IssmDouble h = basalelement->CharacteristicLength(); 96 111 97 112 /* Start looping on the number of gaussian points: */ 98 Gauss* gauss= element->NewGauss(4);113 Gauss* gauss=basalelement->NewGauss(4); 99 114 for(int ig=gauss->begin();ig<gauss->end();ig++){ 100 115 gauss->GaussPoint(ig); 101 116 102 element->JacobianDeterminant(&Jdet,xyz_list,gauss);103 element->NodalFunctions(basis,gauss);104 element->NodalFunctionsDerivatives(dbasis,xyz_list,gauss);105 GetBprime(Bprime, element,dim,xyz_list,gauss);117 basalelement->JacobianDeterminant(&Jdet,xyz_list,gauss); 118 basalelement->NodalFunctions(basis,gauss); 119 basalelement->NodalFunctionsDerivatives(dbasis,xyz_list,gauss); 120 GetBprime(Bprime,basalelement,dim,xyz_list,gauss); 106 121 107 122 /*Get velocity*/ … … 168 183 xDelete<IssmDouble>(Bprime); 169 184 delete gauss; 185 if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;}; 170 186 return Ke; 171 187 172 188 }/*}}}*/ 173 189 ElementVector* GLheightadvectionAnalysis::CreatePVector(Element* element){/*{{{*/ 174 175 190 return NULL; 176 191 }/*}}}*/ … … 203 218 for(int i=0;i<femmodel->elements->Size();i++){ 204 219 Element *element = xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i)); 205 206 220 int numnodes = element->GetNumberOfNodes(); 207 221 IssmDouble *mask = xNew<IssmDouble>(numnodes); -
TabularUnified issm/trunk-jpl/src/c/classes/Elements/Element.cpp ¶
r23999 r24010 2157 2157 } 2158 2158 /*}}}*/ 2159 void Element::Ismip6FloatingiceMeltingRate(){/*{{{*/ 2160 2161 if(!this->IsIceInElement() || !this->IsFloating()) return; 2162 2163 int numvertices = this->GetNumberOfVertices(); 2164 int basinid,num_basins,M,N; 2165 IssmDouble tf,gamma0,base,delta_t_basin,mean_tf_basin,absval; 2166 IssmDouble basalmeltrate[numvertices]; 2167 bool islocal; 2168 IssmDouble* delta_t = NULL; 2169 IssmDouble* mean_tf = NULL; 2170 IssmDouble* depths = NULL; 2171 2172 /*Get variables*/ 2173 IssmDouble rhoi = this->FindParam(MaterialsRhoIceEnum); 2174 IssmDouble rhow = this->FindParam(MaterialsRhoSeawaterEnum); 2175 IssmDouble lf = this->FindParam(MaterialsLatentheatEnum); 2176 IssmDouble cp = this->FindParam(MaterialsMixedLayerCapacityEnum); 2177 2178 /*Hard code sea water density to be consistent with ISMIP6 documentation*/ 2179 rhow = 1028.; 2180 2181 /* Get parameters and inputs */ 2182 this->inputs->GetInputValue(&basinid,BasalforcingsIsmp6BasinIdEnum); 2183 this->parameters->FindParam(&num_basins,BasalforcingsIsmp6NumBasinsEnum); 2184 this->parameters->FindParam(&gamma0,BasalforcingsIsmp6Gamma0Enum); 2185 this->parameters->FindParam(&delta_t,&M,BasalforcingsIsmp6DeltaTEnum); _assert_(M==num_basins); 2186 this->parameters->FindParam(&islocal,BasalforcingsIsmp6IsLocalEnum); 2187 if(!islocal) { 2188 this->parameters->FindParam(&mean_tf,&N,BasalforcingsIsmp6AverageTfEnum); _assert_(N==num_basins); 2189 } 2190 Input* tf_input=this->GetInput(BasalforcingsIsmp6TfShelfEnum); _assert_(tf_input); 2191 delta_t_basin = delta_t[basinid]; 2192 if(!islocal) mean_tf_basin = mean_tf[basinid]; 2193 2194 /*Compute melt rate for Local and Nonlocal parameterizations*/ 2195 Gauss* gauss=this->NewGauss(); 2196 for(int i=0;i<numvertices;i++){ 2197 gauss->GaussVertex(i); 2198 tf_input->GetInputValue(&tf,gauss); 2199 if(!islocal) { 2200 absval = mean_tf_basin+delta_t_basin; 2201 if (absval<0) {absval = -1.*absval;} 2202 basalmeltrate[i] = gamma0*pow((rhow*cp)/(rhoi*lf),2)*(tf+delta_t_basin)*absval;} 2203 else {basalmeltrate[i] = gamma0*pow((rhow*cp)/(rhoi*lf),2)*pow(max(tf+delta_t_basin,0.),2);} 2204 } 2205 2206 /*Return basal melt rate*/ 2207 this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrate,P1Enum); 2208 2209 /*Cleanup and return*/ 2210 delete gauss; 2211 xDelete<IssmDouble>(delta_t); 2212 xDelete<IssmDouble>(mean_tf); 2213 xDelete<IssmDouble>(depths); 2214 2215 }/*}}}*/ 2159 2216 bool Element::IsWaterInElement(){/*{{{*/ 2160 2217 return (this->inputs->Max(MaskOceanLevelsetEnum)>0.); … … 2520 2577 } 2521 2578 /*}}}*/ 2579 void Element::PicoUpdateBoxid(int* max_boxid_basin_list){/*{{{*/ 2580 2581 if(!this->IsIceInElement() || !this->IsFloating()) return; 2582 2583 int basin_id; 2584 IssmDouble dist_gl,dist_cf; 2585 2586 inputs->GetInputValue(&basin_id,BasalforcingsPicoBasinIdEnum); 2587 IssmDouble boxid_max=reCast<IssmDouble>(max_boxid_basin_list[basin_id])+1.; 2588 2589 Input* dist_gl_input=inputs->GetInput(DistanceToGroundinglineEnum); _assert_(dist_gl_input); 2590 Input* dist_cf_input=inputs->GetInput(DistanceToCalvingfrontEnum); _assert_(dist_cf_input); 2591 2592 /*Get dist_gl and dist_cf at center of element*/ 2593 Gauss* gauss=this->NewGauss(1); gauss->GaussPoint(0); 2594 dist_gl_input->GetInputValue(&dist_gl,gauss); 2595 dist_cf_input->GetInputValue(&dist_cf,gauss); 2596 delete gauss; 2597 2598 /*Ensure values are positive for floating ice*/ 2599 dist_gl = fabs(dist_gl); 2600 dist_cf = fabs(dist_cf); 2601 2602 /*Compute relative distance to grounding line*/ 2603 IssmDouble rel_dist_gl=dist_gl/(dist_gl+dist_cf); 2604 2605 /*Assign box numbers based on rel_dist_gl*/ 2606 int boxid = -1; 2607 for(IssmDouble i=0.;i<boxid_max;i++){ 2608 IssmDouble lowbound = 1. -sqrt((boxid_max-i )/boxid_max); 2609 IssmDouble highbound = 1. -sqrt((boxid_max-i-1.)/boxid_max); 2610 if(rel_dist_gl>=lowbound && rel_dist_gl<=highbound){ 2611 boxid=reCast<int>(i); 2612 break; 2613 } 2614 } 2615 if(boxid==-1) _error_("No boxid found for element " << this->Sid() << "!"); 2616 2617 this->inputs->AddInput(new IntInput(BasalforcingsPicoBoxIdEnum, boxid)); 2618 2619 }/*}}}*/ 2620 void Element::PicoUpdateBox(int loopboxid){/*{{{*/ 2621 2622 if(!this->IsIceInElement() || !this->IsFloating()) return; 2623 2624 int boxid; 2625 this->inputs->GetInputValue(&boxid,BasalforcingsPicoBoxIdEnum); 2626 if(loopboxid!=boxid) return; 2627 2628 int NUMVERTICES = this->GetNumberOfVertices(); 2629 int basinid, maxbox, num_basins, numnodes, M; 2630 IssmDouble gamma_T, overturning_coeff, thickness; 2631 IssmDouble pressure, T_star,p_coeff, q_coeff; 2632 bool isplume; 2633 2634 /*Get variables*/ 2635 IssmDouble rhoi = this->FindParam(MaterialsRhoIceEnum); 2636 IssmDouble rhow = this->FindParam(MaterialsRhoSeawaterEnum); 2637 IssmDouble earth_grav = this->FindParam(ConstantsGEnum); 2638 IssmDouble rho_star = 1033.; // kg/m^3 2639 IssmDouble nu = rhoi/rhow; 2640 IssmDouble latentheat = this->FindParam(MaterialsLatentheatEnum); 2641 IssmDouble c_p_ocean = this->FindParam(MaterialsMixedLayerCapacityEnum); 2642 IssmDouble lambda = latentheat/c_p_ocean; 2643 IssmDouble a = -0.0572; // K/psu 2644 IssmDouble b = 0.0788 + this->FindParam(MaterialsMeltingpointEnum); //K 2645 IssmDouble c = 7.77e-4; 2646 IssmDouble alpha = 7.5e-5; // 1/K 2647 IssmDouble Beta = 7.7e-4; // K 2648 2649 /* Get non-box-specific parameters and inputs */ 2650 this->parameters->FindParam(&num_basins, BasalforcingsPicoNumBasinsEnum); 2651 this->parameters->FindParam(&gamma_T,BasalforcingsPicoGammaTEnum); 2652 this->parameters->FindParam(&overturning_coeff,BasalforcingsPicoOverturningCoeffEnum); 2653 this->parameters->FindParam(&maxbox,BasalforcingsPicoMaxboxcountEnum); 2654 this->inputs->GetInputValue(&basinid,BasalforcingsPicoBasinIdEnum); 2655 this->parameters->FindParam(&isplume, BasalforcingsPicoIsplumeEnum); 2656 Input* thickness_input=this->GetInput(ThicknessEnum); _assert_(thickness_input); 2657 _assert_(basinid<=num_basins); 2658 2659 IssmDouble* boxareas = NULL; 2660 this->parameters->FindParam(&boxareas,&M,BasalforcingsPicoBoxAreaEnum); 2661 _assert_(M==num_basins*maxbox); 2662 2663 IssmDouble area_boxi = boxareas[basinid*maxbox+boxid]; 2664 IssmDouble g1 = area_boxi*gamma_T; 2665 2666 IssmDouble basalmeltrates_shelf[NUMVERTICES]; 2667 IssmDouble potential_pressure_melting_point[NUMVERTICES]; 2668 IssmDouble Tocs[NUMVERTICES]; 2669 IssmDouble Socs[NUMVERTICES]; 2670 2671 /* First box calculations */ 2672 if(boxid==0){ 2673 /* Get box1 parameters and inputs */ 2674 IssmDouble time, toc_farocean, soc_farocean; 2675 this->parameters->FindParam(&time,TimeEnum); 2676 this->parameters->FindParam(&toc_farocean, basinid, time, BasalforcingsPicoFarOceantemperatureEnum); 2677 this->parameters->FindParam(&soc_farocean, basinid, time, BasalforcingsPicoFarOceansalinityEnum); 2678 IssmDouble s1 = soc_farocean/(nu*lambda); 2679 IssmDouble overturnings[NUMVERTICES]; 2680 2681 /* Start looping on the number of verticies and calculate ocean vars */ 2682 Gauss* gauss=this->NewGauss(); 2683 for(int i=0;i<NUMVERTICES;i++){ 2684 gauss->GaussVertex(i); 2685 thickness_input->GetInputValue(&thickness,gauss); 2686 pressure = (rhoi*earth_grav*1e-4)*thickness; 2687 T_star = a*soc_farocean+b-c*pressure-toc_farocean; 2688 p_coeff = g1/(overturning_coeff*rho_star*(Beta*s1-alpha)); 2689 q_coeff = T_star*(g1/(overturning_coeff*rho_star*(Beta*s1-alpha))); 2690 2691 /* To avoid negatives under the square root */ 2692 if((0.25*pow(p_coeff,2)-q_coeff)<0) q_coeff = 0.25*p_coeff*p_coeff; 2693 2694 Tocs[i] = toc_farocean-(-0.5*p_coeff+sqrt(0.25*pow(p_coeff,2)-q_coeff)); 2695 Socs[i] = soc_farocean-(soc_farocean/(nu*lambda))*(toc_farocean-Tocs[i]); 2696 potential_pressure_melting_point[i] = a*Socs[i]+b-c*pressure; 2697 if(!isplume) basalmeltrates_shelf[i] = (-gamma_T/(nu*lambda))*(potential_pressure_melting_point[i]-Tocs[i]); 2698 overturnings[i] = overturning_coeff*rho_star*(Beta*(soc_farocean-Socs[i])-alpha*(toc_farocean-Tocs[i])); 2699 } 2700 2701 if(!isplume) this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1Enum); 2702 this->AddInput(BasalforcingsPicoSubShelfOceanTempEnum,Tocs,P1Enum); 2703 this->AddInput(BasalforcingsPicoSubShelfOceanSalinityEnum,Socs,P1Enum); 2704 this->AddInput(BasalforcingsPicoSubShelfOceanOverturningEnum,overturnings,P1Enum); 2705 2706 /*Cleanup and return*/ 2707 delete gauss; 2708 } 2709 2710 /* Subsequent box calculations */ 2711 else { 2712 /* Get subsequent box parameters and inputs */ 2713 IssmDouble* toc_weighted_avg = NULL; 2714 IssmDouble* soc_weighted_avg = NULL; 2715 IssmDouble* overturning_weighted_avg = NULL; 2716 this->parameters->FindParam(&toc_weighted_avg,&num_basins,BasalforcingsPicoAverageTemperatureEnum); 2717 this->parameters->FindParam(&soc_weighted_avg,&num_basins,BasalforcingsPicoAverageSalinityEnum); 2718 this->parameters->FindParam(&overturning_weighted_avg,&num_basins,BasalforcingsPicoAverageOverturningEnum); 2719 IssmDouble mean_toc = toc_weighted_avg[basinid]; 2720 IssmDouble mean_soc = soc_weighted_avg[basinid]; 2721 IssmDouble mean_overturning = overturning_weighted_avg[basinid]; 2722 IssmDouble g2 = g1/(nu*lambda); 2723 2724 /* Start looping on the number of verticies and calculate ocean vars */ 2725 Gauss* gauss=this->NewGauss(); 2726 for(int i=0;i<NUMVERTICES;i++){ 2727 gauss->GaussVertex(i); 2728 thickness_input->GetInputValue(&thickness,gauss); 2729 pressure = (rhoi*earth_grav*1.e-4)*thickness; 2730 T_star = a*mean_soc+b-c*pressure-mean_toc; 2731 Tocs[i] = mean_toc+T_star*(g1/(mean_overturning+g1-g2*a*mean_soc)); 2732 Socs[i] = mean_soc-mean_soc*((mean_toc-Tocs[i])/(nu*lambda)); 2733 potential_pressure_melting_point[i] = a*Socs[i]+b-c*pressure; 2734 if(!isplume) basalmeltrates_shelf[i] = (-gamma_T/(nu*lambda))*(potential_pressure_melting_point[i]-Tocs[i]); 2735 } 2736 2737 if(!isplume) this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1Enum); 2738 this->AddInput(BasalforcingsPicoSubShelfOceanTempEnum,Tocs,P1Enum); 2739 this->AddInput(BasalforcingsPicoSubShelfOceanSalinityEnum,Socs,P1Enum); 2740 2741 /*Cleanup and return*/ 2742 xDelete<IssmDouble>(toc_weighted_avg); 2743 xDelete<IssmDouble>(soc_weighted_avg); 2744 xDelete<IssmDouble>(overturning_weighted_avg); 2745 delete gauss; 2746 } 2747 2748 /*Cleanup and return*/ 2749 xDelete<IssmDouble>(boxareas); 2750 2751 }/*}}}*/ 2752 void Element::PicoComputeBasalMelt(){/*{{{*/ 2753 2754 if(!this->IsIceInElement() || !this->IsFloating()) return; 2755 2756 int NUMVERTICES = this->GetNumberOfVertices(); 2757 IssmDouble E0, Cd, CdT, YT, lam1, lam2, lam3, M0, CdTS0, y1, y2, x0; 2758 IssmDouble Tf_gl, YTS, CdTS, G1, G2, G3, g_alpha, M, l, X_hat, M_hat; 2759 IssmDouble alpha, zgl, Toc, Soc, z_base, yts, slopex, slopey; 2760 2761 /*Get variables*/ 2762 E0 = 3.6e-2; //Entrainment coefficient 2763 Cd = 2.5e-3; //Drag coefficient 2764 CdT = 1.1e-3; //Turbulent heat exchange coefficient 2765 YT = CdT/sqrt(Cd); //Heat exchange coefficient 2766 lam1 = -5.73e-2; //Freezing point-salinity coefficient (degrees C) 2767 lam2 = 8.32e-2; //Freezing point offset (degrees C) 2768 lam3 = 7.61e-4; //Freezing point-depth coefficient (K m-1) 2769 M0 = 10.; //Melt-rate parameter (m yr-1 C-2) 2770 CdTS0 = 6e-4; //Heat exchange parameter 2771 y1 = 0.545; //Heat exchange parameter 2772 y2 = 3.5e-5; //Heat exchange parameter 2773 x0 = 0.56; //Dimentionless scaling factor 2774 2775 /*Define arrays*/ 2776 IssmDouble basalmeltrates_shelf[NUMVERTICES]; //Basal melt-rate 2777 2778 /*Polynomial coefficients*/ 2779 IssmDouble p[12]; 2780 p[0] = 0.1371330075095435; 2781 p[1] = 5.527656234709359E1; 2782 p[2] = -8.951812433987858E2; 2783 p[3] = 8.927093637594877E3; 2784 p[4] = -5.563863123811898E4; 2785 p[5] = 2.218596970948727E5; 2786 p[6] = -5.820015295669482E5; 2787 p[7] = 1.015475347943186E6; 2788 p[8] = -1.166290429178556E6; 2789 p[9] = 8.466870335320488E5; 2790 p[10] = -3.520598035764990E5; 2791 p[11] = 6.387953795485420E4; 2792 2793 /*Get inputs*/ 2794 Input* zgl_input = this->GetInput(GroundinglineHeightEnum); _assert_(zgl_input); 2795 Input* toc_input = this->GetInput(BasalforcingsPicoSubShelfOceanTempEnum); _assert_(toc_input); 2796 Input* soc_input = this->GetInput(BasalforcingsPicoSubShelfOceanSalinityEnum); _assert_(soc_input); 2797 Input* base_input = this->GetInput(BaseEnum); _assert_(base_input); 2798 Input* baseslopex_input = this->GetInput(BaseSlopeXEnum); _assert_(baseslopex_input); 2799 Input* baseslopey_input = this->GetInput(BaseSlopeYEnum); _assert_(baseslopey_input); 2800 this->FindParam(&yts, ConstantsYtsEnum); 2801 2802 /*Loop over the number of vertices in this element*/ 2803 Gauss* gauss=this->NewGauss(); 2804 for(int i=0;i<NUMVERTICES;i++){ 2805 gauss->GaussVertex(i); 2806 2807 /*Get inputs*/ 2808 zgl_input->GetInputValue(&zgl,gauss); 2809 toc_input->GetInputValue(&Toc,gauss); //(K) 2810 soc_input->GetInputValue(&Soc,gauss); 2811 base_input->GetInputValue(&z_base,gauss); 2812 baseslopex_input->GetInputValue(&slopex,gauss); 2813 baseslopey_input->GetInputValue(&slopey,gauss); 2814 2815 /*Compute ice shelf base slope (radians)*/ 2816 alpha = atan(sqrt(slopex*slopex + slopey*slopey)); 2817 if(alpha>=M_PI) alpha = M_PI - 0.001; //ensure sin(alpha) > 0 for meltrate calculations 2818 2819 /*Make necessary conversions*/ 2820 Toc = Toc-273.15; 2821 if(zgl>z_base) zgl=z_base; 2822 2823 /*Low bound for Toc to ensure X_hat is between 0 and 1*/ 2824 if(Toc<lam1*Soc+lam2) Toc=lam1*Soc+lam2; 2825 2826 /*Compute parameters needed for melt-rate calculation*/ 2827 Tf_gl = lam1*Soc+lam2+lam3*zgl; //Characteristic freezing point 2828 YTS = YT*(y1+y2*(((Toc-Tf_gl)*E0*sin(alpha))/(lam3*(CdTS0+E0*sin(alpha))))); //Effective heat exchange coefficient 2829 CdTS = sqrt(Cd)*YTS; //Heat exchange coefficient 2830 G1 = sqrt(sin(alpha)/(Cd+E0*sin(alpha))); //Geometric factor 2831 G2 = sqrt(CdTS/(CdTS+E0*sin(alpha))); //Geometric factor 2832 G3 = (E0*sin(alpha))/(CdTS+E0*sin(alpha)); //Geometric factor 2833 g_alpha = G1*G2*G3; //Melt scaling factor 2834 M = M0*g_alpha*pow((Toc-Tf_gl),2); //Melt-rate scale 2835 l = ((Toc-Tf_gl)*(x0*CdTS+E0*sin(alpha)))/(lam3*x0*(CdTS+E0*sin(alpha))); //Length scale 2836 X_hat = (z_base-zgl)/l; //Dimentionless coordinate system 2837 2838 /*Compute polynomial fit*/ 2839 M_hat = 0.; //Reset summation variable for each node 2840 for(int ii=0;ii<12;ii++) { 2841 M_hat += p[ii]*pow(X_hat,ii); //Polynomial fit 2842 } 2843 2844 /*Compute melt-rate*/ 2845 basalmeltrates_shelf[i] = (M*M_hat)/yts; //Basal melt-rate (m/s) 2846 } 2847 2848 /*Save computed melt-rate*/ 2849 this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1Enum); 2850 2851 /*Cleanup and return*/ 2852 delete gauss; 2853 2854 }/*}}}*/ 2522 2855 void Element::PositiveDegreeDay(IssmDouble* pdds,IssmDouble* pds,IssmDouble signorm,bool ismungsm,bool issetpddfac){/*{{{*/ 2523 2856 -
TabularUnified issm/trunk-jpl/src/c/classes/Elements/Element.h ¶
r23993 r24010 134 134 bool IsIceInElement(); 135 135 bool IsLandInElement(); 136 void Ismip6FloatingiceMeltingRate(); 136 137 bool IsWaterInElement(); 137 138 void LinearFloatingiceMeltingRate(); … … 145 146 ElementMatrix* NewElementMatrixCoupling(int number_nodes,int approximation_enum=NoneApproximationEnum); 146 147 ElementVector* NewElementVector(int approximation_enum=NoneApproximationEnum); 148 void PicoUpdateBoxid(int* pmax_boxid_basin); 149 void PicoUpdateBox(int loopboxid); 150 void PicoComputeBasalMelt(); 147 151 void PositiveDegreeDay(IssmDouble* pdds,IssmDouble* pds,IssmDouble signorm,bool ismungsm,bool issetpddfac); 148 152 void PositiveDegreeDaySicopolis(bool isfirnwarming); … … 257 261 virtual bool IsFaceOnBoundary(void)=0; 258 262 virtual bool IsIcefront(void)=0; 259 virtual void Ismip6FloatingiceMeltingRate(void)=0;260 263 virtual bool IsNodeOnShelfFromFlags(IssmDouble* flags)=0; 261 264 virtual bool IsOnBase()=0; … … 299 302 virtual int NumberofNodesPressure(void)=0; 300 303 virtual int NumberofNodesVelocity(void)=0; 301 virtual void PicoUpdateBoxid(int* pmax_boxid_basin)=0;302 virtual void PicoUpdateBox(int loopboxid)=0;303 virtual void PicoComputeBasalMelt(void)=0;304 304 virtual void PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding)=0; 305 305 virtual int PressureInterpolation()=0; -
TabularUnified issm/trunk-jpl/src/c/classes/Elements/Penta.h ¶
r23801 r24010 95 95 IssmDouble IceVolume(bool scaled); 96 96 IssmDouble IceVolumeAboveFloatation(bool scaled); 97 void Ismip6FloatingiceMeltingRate(void){_error_("not implemented yet");};98 97 void InputDepthAverageAtBase(int enum_type,int average_enum_type); 99 98 void InputExtrude(int enum_type,int start); … … 144 143 int NumberofNodesPressure(void); 145 144 int NumberofNodesVelocity(void); 146 void PicoUpdateBoxid(int* pmax_boxid_basin){_error_("not implemented yet");};147 void PicoUpdateBox(int loopboxid){_error_("not implemented yet");};148 void PicoComputeBasalMelt(void){_error_("not implemented yet");};149 145 void PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding); 150 146 int PressureInterpolation(); -
TabularUnified issm/trunk-jpl/src/c/classes/Elements/Seg.h ¶
r23795 r24010 88 88 bool IsFaceOnBoundary(void){_error_("not implemented yet");}; 89 89 bool IsIcefront(void); 90 void Ismip6FloatingiceMeltingRate(void){_error_("not implemented yet");};91 90 bool IsNodeOnShelfFromFlags(IssmDouble* flags){_error_("not implemented yet");}; 92 91 bool IsOnBase(){_error_("not implemented yet");}; … … 130 129 int NumberofNodesPressure(void){_error_("not implemented yet");}; 131 130 int NumberofNodesVelocity(void){_error_("not implemented yet");}; 132 void PicoUpdateBoxid(int* pmax_boxid_basin){_error_("not implemented yet");};133 void PicoUpdateBox(int loopboxid){_error_("not implemented yet");};134 void PicoComputeBasalMelt(void){_error_("not implemented yet");};135 131 void PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding){_error_("not implemented yet");}; 136 132 int PressureInterpolation(void){_error_("not implemented yet");}; -
TabularUnified issm/trunk-jpl/src/c/classes/Elements/Tetra.h ¶
r23795 r24010 88 88 IssmDouble IceVolume(bool scaled){_error_("not implemented yet");}; 89 89 IssmDouble IceVolumeAboveFloatation(bool scaled){_error_("not implemented yet");}; 90 void Ismip6FloatingiceMeltingRate(void){_error_("not implemented yet");};91 90 bool IsFaceOnBoundary(void){_error_("not implemented yet");}; 92 91 bool IsIcefront(void); … … 138 137 int NumberofNodesPressure(void); 139 138 int NumberofNodesVelocity(void); 140 void PicoUpdateBoxid(int* pmax_boxid_basin){_error_("not implemented yet");};141 void PicoUpdateBox(int loopboxid){_error_("not implemented yet");};142 void PicoComputeBasalMelt(void){_error_("not implemented yet");};143 139 void PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding){_error_("not implemented yet");}; 144 140 int PressureInterpolation(void); -
TabularUnified issm/trunk-jpl/src/c/classes/Elements/Tria.cpp ¶
r23999 r24010 2726 2726 return isicefront; 2727 2727 }/*}}}*/ 2728 void Tria::Ismip6FloatingiceMeltingRate(void){/*{{{*/2729 2730 if(!this->IsIceInElement() || !this->IsFloating()) return;2731 2732 int basinid,num_basins,M,N;2733 IssmDouble tf,gamma0,base,delta_t_basin,mean_tf_basin,absval;2734 IssmDouble basalmeltrate[NUMVERTICES];2735 bool islocal;2736 IssmDouble* delta_t = NULL;2737 IssmDouble* mean_tf = NULL;2738 IssmDouble* depths = NULL;2739 2740 /*Get variables*/2741 IssmDouble rhoi = this->FindParam(MaterialsRhoIceEnum);2742 IssmDouble rhow = this->FindParam(MaterialsRhoSeawaterEnum);2743 IssmDouble lf = this->FindParam(MaterialsLatentheatEnum);2744 IssmDouble cp = this->FindParam(MaterialsMixedLayerCapacityEnum);2745 2746 /*Hard code sea water density to be consistent with ISMIP6 documentation*/2747 rhow = 1028.;2748 2749 /* Get parameters and inputs */2750 this->inputs->GetInputValue(&basinid,BasalforcingsIsmp6BasinIdEnum);2751 this->parameters->FindParam(&num_basins,BasalforcingsIsmp6NumBasinsEnum);2752 this->parameters->FindParam(&gamma0,BasalforcingsIsmp6Gamma0Enum);2753 this->parameters->FindParam(&delta_t,&M,BasalforcingsIsmp6DeltaTEnum); _assert_(M==num_basins);2754 this->parameters->FindParam(&islocal,BasalforcingsIsmp6IsLocalEnum);2755 if(!islocal) {2756 this->parameters->FindParam(&mean_tf,&N,BasalforcingsIsmp6AverageTfEnum); _assert_(N==num_basins);2757 }2758 Input* tf_input=this->GetInput(BasalforcingsIsmp6TfShelfEnum); _assert_(tf_input);2759 delta_t_basin = delta_t[basinid];2760 if(!islocal) mean_tf_basin = mean_tf[basinid];2761 2762 /* Compute melt rate */2763 Gauss* gauss=this->NewGauss();2764 for(int i=0;i<NUMVERTICES;i++){2765 gauss->GaussVertex(i);2766 tf_input->GetInputValue(&tf,gauss);2767 if(!islocal) {2768 absval = mean_tf_basin+delta_t_basin;2769 if (absval<0) {absval = -1.*absval;}2770 basalmeltrate[i] = gamma0*pow((rhow*cp)/(rhoi*lf),2)*(tf+delta_t_basin)*absval;}2771 else {basalmeltrate[i] = gamma0*pow((rhow*cp)/(rhoi*lf),2)*pow(max(tf+delta_t_basin,0.),2);}2772 }2773 2774 /*Return basal melt rate*/2775 this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrate,P1Enum);2776 2777 /*Cleanup and return*/2778 delete gauss;2779 xDelete<IssmDouble>(delta_t);2780 xDelete<IssmDouble>(mean_tf);2781 xDelete<IssmDouble>(depths);2782 2783 }/*}}}*/2784 2728 bool Tria::IsNodeOnShelfFromFlags(IssmDouble* flags){/*{{{*/ 2785 2729 … … 3269 3213 } 3270 3214 /*}}}*/ 3271 void Tria::PicoUpdateBoxid(int* max_boxid_basin_list){/*{{{*/3272 3273 if(!this->IsIceInElement() || !this->IsFloating()) return;3274 3275 int basin_id;3276 IssmDouble dist_gl,dist_cf;3277 3278 inputs->GetInputValue(&basin_id,BasalforcingsPicoBasinIdEnum);3279 IssmDouble boxid_max=reCast<IssmDouble>(max_boxid_basin_list[basin_id])+1.;3280 3281 Input* dist_gl_input=inputs->GetInput(DistanceToGroundinglineEnum); _assert_(dist_gl_input);3282 Input* dist_cf_input=inputs->GetInput(DistanceToCalvingfrontEnum); _assert_(dist_cf_input);3283 3284 /*Get dist_gl and dist_cf at center of element*/3285 Gauss* gauss=this->NewGauss(1); gauss->GaussPoint(0);3286 dist_gl_input->GetInputValue(&dist_gl,gauss);3287 dist_cf_input->GetInputValue(&dist_cf,gauss);3288 delete gauss;3289 3290 /*Ensure values are positive for floating ice*/3291 dist_gl = fabs(dist_gl);3292 dist_cf = fabs(dist_cf);3293 3294 /*Compute relative distance to grounding line*/3295 IssmDouble rel_dist_gl=dist_gl/(dist_gl+dist_cf);3296 3297 /*Assign box numbers based on rel_dist_gl*/3298 int boxid = -1;3299 for(IssmDouble i=0.;i<boxid_max;i++){3300 IssmDouble lowbound = 1. -sqrt((boxid_max-i )/boxid_max);3301 IssmDouble highbound = 1. -sqrt((boxid_max-i-1.)/boxid_max);3302 if(rel_dist_gl>=lowbound && rel_dist_gl<=highbound){3303 boxid=reCast<int>(i);3304 break;3305 }3306 }3307 if(boxid==-1) _error_("No boxid found for element " << this->Sid() << "!");3308 3309 this->inputs->AddInput(new IntInput(BasalforcingsPicoBoxIdEnum, boxid));3310 }/*}}}*/3311 void Tria::PicoUpdateBox(int loopboxid){/*{{{*/3312 3313 if(!this->IsIceInElement() || !this->IsFloating()) return;3314 3315 int boxid;3316 this->inputs->GetInputValue(&boxid,BasalforcingsPicoBoxIdEnum);3317 if(loopboxid!=boxid) return;3318 3319 int basinid, maxbox, num_basins, numnodes, M;3320 IssmDouble gamma_T, overturning_coeff, thickness;3321 IssmDouble pressure, T_star,p_coeff, q_coeff;3322 bool isplume;3323 3324 /*Get variables*/3325 IssmDouble rhoi = this->FindParam(MaterialsRhoIceEnum);3326 IssmDouble rhow = this->FindParam(MaterialsRhoSeawaterEnum);3327 IssmDouble earth_grav = this->FindParam(ConstantsGEnum);3328 IssmDouble rho_star = 1033.; // kg/m^33329 IssmDouble nu = rhoi/rhow;3330 IssmDouble latentheat = this->FindParam(MaterialsLatentheatEnum);3331 IssmDouble c_p_ocean = this->FindParam(MaterialsMixedLayerCapacityEnum);3332 IssmDouble lambda = latentheat/c_p_ocean;3333 IssmDouble a = -0.0572; // K/psu3334 IssmDouble b = 0.0788 + this->FindParam(MaterialsMeltingpointEnum); //K3335 IssmDouble c = 7.77e-4;3336 IssmDouble alpha = 7.5e-5; // 1/K3337 IssmDouble Beta = 7.7e-4; // K3338 3339 /* Get non-box-specific parameters and inputs */3340 this->parameters->FindParam(&num_basins, BasalforcingsPicoNumBasinsEnum);3341 this->parameters->FindParam(&gamma_T,BasalforcingsPicoGammaTEnum);3342 this->parameters->FindParam(&overturning_coeff,BasalforcingsPicoOverturningCoeffEnum);3343 this->parameters->FindParam(&maxbox,BasalforcingsPicoMaxboxcountEnum);3344 this->inputs->GetInputValue(&basinid,BasalforcingsPicoBasinIdEnum);3345 this->parameters->FindParam(&isplume, BasalforcingsPicoIsplumeEnum);3346 Input* thickness_input=this->GetInput(ThicknessEnum); _assert_(thickness_input);3347 _assert_(basinid<=num_basins);3348 3349 IssmDouble* boxareas = NULL;3350 this->parameters->FindParam(&boxareas,&M,BasalforcingsPicoBoxAreaEnum);3351 _assert_(M==num_basins*maxbox);3352 3353 IssmDouble area_boxi = boxareas[basinid*maxbox+boxid];3354 IssmDouble g1 = area_boxi*gamma_T;3355 3356 IssmDouble basalmeltrates_shelf[NUMVERTICES];3357 IssmDouble potential_pressure_melting_point[NUMVERTICES];3358 IssmDouble Tocs[NUMVERTICES];3359 IssmDouble Socs[NUMVERTICES];3360 3361 /* First box calculations */3362 if(boxid==0){3363 /* Get box1 parameters and inputs */3364 IssmDouble time, toc_farocean, soc_farocean;3365 this->parameters->FindParam(&time,TimeEnum);3366 this->parameters->FindParam(&toc_farocean, basinid, time, BasalforcingsPicoFarOceantemperatureEnum);3367 this->parameters->FindParam(&soc_farocean, basinid, time, BasalforcingsPicoFarOceansalinityEnum);3368 IssmDouble s1 = soc_farocean/(nu*lambda);3369 IssmDouble overturnings[NUMVERTICES];3370 3371 /* Start looping on the number of verticies and calculate ocean vars */3372 Gauss* gauss=this->NewGauss();3373 for(int i=0;i<NUMVERTICES;i++){3374 gauss->GaussVertex(i);3375 thickness_input->GetInputValue(&thickness,gauss);3376 pressure = (rhoi*earth_grav*1e-4)*thickness;3377 T_star = a*soc_farocean+b-c*pressure-toc_farocean;3378 p_coeff = g1/(overturning_coeff*rho_star*(Beta*s1-alpha));3379 q_coeff = T_star*(g1/(overturning_coeff*rho_star*(Beta*s1-alpha)));3380 3381 /* To avoid negatives under the square root */3382 if((0.25*pow(p_coeff,2)-q_coeff)<0) q_coeff = 0.25*p_coeff*p_coeff;3383 3384 Tocs[i] = toc_farocean-(-0.5*p_coeff+sqrt(0.25*pow(p_coeff,2)-q_coeff));3385 Socs[i] = soc_farocean-(soc_farocean/(nu*lambda))*(toc_farocean-Tocs[i]);3386 potential_pressure_melting_point[i] = a*Socs[i]+b-c*pressure;3387 if(!isplume) basalmeltrates_shelf[i] = (-gamma_T/(nu*lambda))*(potential_pressure_melting_point[i]-Tocs[i]);3388 overturnings[i] = overturning_coeff*rho_star*(Beta*(soc_farocean-Socs[i])-alpha*(toc_farocean-Tocs[i]));3389 }3390 3391 if(!isplume) this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1Enum);3392 this->AddInput(BasalforcingsPicoSubShelfOceanTempEnum,Tocs,P1Enum);3393 this->AddInput(BasalforcingsPicoSubShelfOceanSalinityEnum,Socs,P1Enum);3394 this->AddInput(BasalforcingsPicoSubShelfOceanOverturningEnum,overturnings,P1Enum);3395 3396 /*Cleanup and return*/3397 delete gauss;3398 }3399 3400 /* Subsequent box calculations */3401 else {3402 /* Get subsequent box parameters and inputs */3403 IssmDouble* toc_weighted_avg = NULL;3404 IssmDouble* soc_weighted_avg = NULL;3405 IssmDouble* overturning_weighted_avg = NULL;3406 this->parameters->FindParam(&toc_weighted_avg,&num_basins,BasalforcingsPicoAverageTemperatureEnum);3407 this->parameters->FindParam(&soc_weighted_avg,&num_basins,BasalforcingsPicoAverageSalinityEnum);3408 this->parameters->FindParam(&overturning_weighted_avg,&num_basins,BasalforcingsPicoAverageOverturningEnum);3409 IssmDouble mean_toc = toc_weighted_avg[basinid];3410 IssmDouble mean_soc = soc_weighted_avg[basinid];3411 IssmDouble mean_overturning = overturning_weighted_avg[basinid];3412 IssmDouble g2 = g1/(nu*lambda);3413 3414 /* Start looping on the number of verticies and calculate ocean vars */3415 Gauss* gauss=this->NewGauss();3416 for(int i=0;i<NUMVERTICES;i++){3417 gauss->GaussVertex(i);3418 thickness_input->GetInputValue(&thickness,gauss);3419 pressure = (rhoi*earth_grav*1.e-4)*thickness;3420 T_star = a*mean_soc+b-c*pressure-mean_toc;3421 Tocs[i] = mean_toc+T_star*(g1/(mean_overturning+g1-g2*a*mean_soc));3422 Socs[i] = mean_soc-mean_soc*((mean_toc-Tocs[i])/(nu*lambda));3423 potential_pressure_melting_point[i] = a*Socs[i]+b-c*pressure;3424 if(!isplume) basalmeltrates_shelf[i] = (-gamma_T/(nu*lambda))*(potential_pressure_melting_point[i]-Tocs[i]);3425 }3426 3427 if(!isplume) this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1Enum);3428 this->AddInput(BasalforcingsPicoSubShelfOceanTempEnum,Tocs,P1Enum);3429 this->AddInput(BasalforcingsPicoSubShelfOceanSalinityEnum,Socs,P1Enum);3430 3431 /*Cleanup and return*/3432 xDelete<IssmDouble>(toc_weighted_avg);3433 xDelete<IssmDouble>(soc_weighted_avg);3434 xDelete<IssmDouble>(overturning_weighted_avg);3435 delete gauss;3436 }3437 3438 /*Cleanup and return*/3439 xDelete<IssmDouble>(boxareas);3440 }3441 /*}}}*/3442 void Tria::PicoComputeBasalMelt(void){/*{{{*/3443 3444 if(!this->IsIceInElement() || !this->IsFloating()) return;3445 3446 IssmDouble E0, Cd, CdT, YT, lam1, lam2, lam3, M0, CdTS0, y1, y2, x0;3447 IssmDouble Tf_gl, YTS, CdTS, G1, G2, G3, g_alpha, M, l, X_hat, M_hat;3448 IssmDouble alpha, zgl, Toc, Soc, z_base, yts, slopex, slopey;3449 3450 /*Get variables*/3451 E0 = 3.6e-2; //Entrainment coefficient3452 Cd = 2.5e-3; //Drag coefficient3453 CdT = 1.1e-3; //Turbulent heat exchange coefficient3454 YT = CdT/sqrt(Cd); //Heat exchange coefficient3455 lam1 = -5.73e-2; //Freezing point-salinity coefficient (degrees C)3456 lam2 = 8.32e-2; //Freezing point offset (degrees C)3457 lam3 = 7.61e-4; //Freezing point-depth coefficient (K m-1)3458 M0 = 10.; //Melt-rate parameter (m yr-1 C-2)3459 CdTS0 = 6e-4; //Heat exchange parameter3460 y1 = 0.545; //Heat exchange parameter3461 y2 = 3.5e-5; //Heat exchange parameter3462 x0 = 0.56; //Dimentionless scaling factor3463 3464 /*Define arrays*/3465 IssmDouble basalmeltrates_shelf[NUMVERTICES]; //Basal melt-rate3466 3467 /*Polynomial coefficients*/3468 IssmDouble p[12];3469 p[0] = 0.1371330075095435;3470 p[1] = 5.527656234709359E1;3471 p[2] = -8.951812433987858E2;3472 p[3] = 8.927093637594877E3;3473 p[4] = -5.563863123811898E4;3474 p[5] = 2.218596970948727E5;3475 p[6] = -5.820015295669482E5;3476 p[7] = 1.015475347943186E6;3477 p[8] = -1.166290429178556E6;3478 p[9] = 8.466870335320488E5;3479 p[10] = -3.520598035764990E5;3480 p[11] = 6.387953795485420E4;3481 3482 /*Get inputs*/3483 Input* zgl_input = this->GetInput(GroundinglineHeightEnum); _assert_(zgl_input);3484 Input* toc_input = this->GetInput(BasalforcingsPicoSubShelfOceanTempEnum); _assert_(toc_input);3485 Input* soc_input = this->GetInput(BasalforcingsPicoSubShelfOceanSalinityEnum); _assert_(soc_input);3486 Input* base_input = this->GetInput(BaseEnum); _assert_(base_input);3487 Input* baseslopex_input = this->GetInput(BaseSlopeXEnum); _assert_(baseslopex_input);3488 Input* baseslopey_input = this->GetInput(BaseSlopeYEnum); _assert_(baseslopey_input);3489 this->FindParam(&yts, ConstantsYtsEnum);3490 3491 /*Loop over the number of vertices in this element*/3492 Gauss* gauss=this->NewGauss();3493 for(int i=0;i<NUMVERTICES;i++){3494 gauss->GaussVertex(i);3495 3496 /*Get inputs*/3497 zgl_input->GetInputValue(&zgl,gauss);3498 toc_input->GetInputValue(&Toc,gauss); //(K)3499 soc_input->GetInputValue(&Soc,gauss);3500 base_input->GetInputValue(&z_base,gauss);3501 baseslopex_input->GetInputValue(&slopex,gauss);3502 baseslopey_input->GetInputValue(&slopey,gauss);3503 3504 /*Compute ice shelf base slope (radians)*/3505 alpha = atan(sqrt(slopex*slopex + slopey*slopey));3506 if(alpha>=M_PI) alpha = M_PI - 0.001; //ensure sin(alpha) > 0 for meltrate calculations3507 3508 /*Make necessary conversions*/3509 Toc = Toc-273.15;3510 if(zgl>z_base) zgl=z_base;3511 3512 /*Low bound for Toc to ensure X_hat is between 0 and 1*/3513 if(Toc<lam1*Soc+lam2) Toc=lam1*Soc+lam2;3514 3515 /*Compute parameters needed for melt-rate calculation*/3516 Tf_gl = lam1*Soc+lam2+lam3*zgl; //Characteristic freezing point3517 YTS = YT*(y1+y2*(((Toc-Tf_gl)*E0*sin(alpha))/(lam3*(CdTS0+E0*sin(alpha))))); //Effective heat exchange coefficient3518 CdTS = sqrt(Cd)*YTS; //Heat exchange coefficient3519 G1 = sqrt(sin(alpha)/(Cd+E0*sin(alpha))); //Geometric factor3520 G2 = sqrt(CdTS/(CdTS+E0*sin(alpha))); //Geometric factor3521 G3 = (E0*sin(alpha))/(CdTS+E0*sin(alpha)); //Geometric factor3522 g_alpha = G1*G2*G3; //Melt scaling factor3523 M = M0*g_alpha*pow((Toc-Tf_gl),2); //Melt-rate scale3524 l = ((Toc-Tf_gl)*(x0*CdTS+E0*sin(alpha)))/(lam3*x0*(CdTS+E0*sin(alpha))); //Length scale3525 X_hat = (z_base-zgl)/l; //Dimentionless coordinate system3526 3527 /*Compute polynomial fit*/3528 M_hat = 0.; //Reset summation variable for each node3529 for(int ii=0;ii<12;ii++) {3530 M_hat += p[ii]*pow(X_hat,ii); //Polynomial fit3531 }3532 3533 /*Compute melt-rate*/3534 basalmeltrates_shelf[i] = (M*M_hat)/yts; //Basal melt-rate (m/s)3535 }3536 3537 /*Save computed melt-rate*/3538 this->AddInput(BasalforcingsFloatingiceMeltingRateEnum,basalmeltrates_shelf,P1Enum);3539 3540 /*Cleanup and return*/3541 delete gauss;3542 }/*}}}*/3543 3215 void Tria::PotentialUngrounding(Vector<IssmDouble>* potential_ungrounding){/*{{{*/ 3544 3216 -
TabularUnified issm/trunk-jpl/src/c/classes/Elements/Tria.h ¶
r23993 r24010 98 98 IssmDouble IcefrontMassFluxLevelset(bool scaled); 99 99 IssmDouble GroundinglineMassFlux(bool scaled); 100 void Ismip6FloatingiceMeltingRate(void);101 100 void InputDepthAverageAtBase(int enum_type,int average_enum_type); 102 101 void InputExtrude(int enum_type,int start){_error_("not implemented"); /*For penta only*/}; … … 116 115 int NumberofNodesPressure(void); 117 116 int NumberofNodesVelocity(void); 118 void PicoUpdateBoxid(int* pmax_boxid_basin);119 void PicoUpdateBox(int loopboxid);120 void PicoComputeBasalMelt(void);121 117 void PotentialUngrounding(Vector<IssmDouble>* potential_sheet_ungrounding); 122 118 int PressureInterpolation(); -
TabularUnified issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatePicox/FloatingiceMeltingRatePicox.cpp ¶
r23255 r24010 12 12 bool isplume; 13 13 14 15 16 17 18 19 20 21 14 /*First, reset all melt to 0 */ 15 for(int i=0;i<femmodel->elements->Size();i++){ 16 Element* element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i)); 17 int numvertices = element->GetNumberOfVertices(); 18 IssmDouble* values = xNewZeroInit<IssmDouble>(numvertices); 19 element->AddInput(BasalforcingsFloatingiceMeltingRateEnum,values,P1Enum); 20 xDelete<IssmDouble>(values); 21 } 22 22 23 23 /*PICO melt rate parameterization (Reese et al., 2018)*/ 24 25 26 27 28 29 24 femmodel->parameters->FindParam(&maxbox,BasalforcingsPicoMaxboxcountEnum); 25 UpdateBoxIdsPico(femmodel); 26 ComputeBoxAreasPico(femmodel); 27 for(int i=0;i<maxbox;i++){ 28 UpdateBoxPico(femmodel,i); 29 ComputeAverageOceanvarsPico(femmodel,i); 30 30 } 31 31 … … 103 103 void ComputeBoxAreasPico(FemModel* femmodel){/*{{{*/ 104 104 105 int num_basins,maxbox,basinid,boxid ;105 int num_basins,maxbox,basinid,boxid,domaintype; 106 106 IssmDouble dist_max,area; 107 107 … … 113 113 for(int i=0;i<femmodel->elements->Size();i++){ 114 114 Element* element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i)); 115 if(!element->IsIceInElement() || !element->IsFloating()) continue; 116 element->inputs->GetInputValue(&boxid,BasalforcingsPicoBoxIdEnum); 117 element->inputs->GetInputValue(&basinid,BasalforcingsPicoBasinIdEnum); 118 boxareas[basinid*maxbox+boxid]+=element->GetHorizontalSurfaceArea(); 115 if(!element->IsOnBase()) continue; 116 Element* basalelement = element->SpawnBasalElement(); 117 if(!basalelement->IsIceInElement() || !basalelement->IsFloating()) continue; 118 basalelement->inputs->GetInputValue(&boxid,BasalforcingsPicoBoxIdEnum); 119 basalelement->inputs->GetInputValue(&basinid,BasalforcingsPicoBasinIdEnum); 120 boxareas[basinid*maxbox+boxid]+=basalelement->GetHorizontalSurfaceArea(); 121 basalelement->FindParam(&domaintype,DomainTypeEnum); 122 if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;}; 119 123 } 120 124 … … 140 144 void ComputeAverageOceanvarsPico(FemModel* femmodel, int boxid){/*{{{*/ 141 145 142 int num_basins, basinid, maxbox, M ;146 int num_basins, basinid, maxbox, M, domaintype; 143 147 IssmDouble area, toc, soc, overturning; 144 148 IssmDouble* boxareas=NULL; … … 157 161 for(int i=0;i<femmodel->elements->Size();i++){ 158 162 Element* element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i)); 159 if(!element->IsIceInElement() || !element->IsFloating()) continue; 163 if(!element->IsOnBase()) continue; 164 Element* basalelement = element->SpawnBasalElement(); 165 if(!basalelement->IsIceInElement() || !basalelement->IsFloating()) continue; 160 166 int el_boxid; 161 element->inputs->GetInputValue(&el_boxid,BasalforcingsPicoBoxIdEnum);167 basalelement->inputs->GetInputValue(&el_boxid,BasalforcingsPicoBoxIdEnum); 162 168 if(el_boxid!=boxid) continue; 163 169 164 Input* tocs_input= element->GetInput(BasalforcingsPicoSubShelfOceanTempEnum); _assert_(tocs_input);165 Input* socs_input= element->GetInput(BasalforcingsPicoSubShelfOceanSalinityEnum); _assert_(socs_input);166 167 element->inputs->GetInputValue(&basinid,BasalforcingsPicoBasinIdEnum);168 Gauss* gauss= element->NewGauss(1); gauss->GaussPoint(0);170 Input* tocs_input=basalelement->GetInput(BasalforcingsPicoSubShelfOceanTempEnum); _assert_(tocs_input); 171 Input* socs_input=basalelement->GetInput(BasalforcingsPicoSubShelfOceanSalinityEnum); _assert_(socs_input); 172 173 basalelement->inputs->GetInputValue(&basinid,BasalforcingsPicoBasinIdEnum); 174 Gauss* gauss=basalelement->NewGauss(1); gauss->GaussPoint(0); 169 175 tocs_input->GetInputValue(&toc,gauss); 170 176 socs_input->GetInputValue(&soc,gauss); 171 177 delete gauss; 172 area= element->GetHorizontalSurfaceArea();178 area=basalelement->GetHorizontalSurfaceArea(); 173 179 toc_weighted_avg[basinid]+=toc*area; 174 180 soc_weighted_avg[basinid]+=soc*area; 181 basalelement->FindParam(&domaintype,DomainTypeEnum); 182 if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;}; 175 183 } 176 184 … … 194 202 for(int i=0;i<femmodel->elements->Size();i++){ 195 203 Element* element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i)); 196 if(!element->IsIceInElement() || !element->IsFloating()) continue; 204 if(!element->IsOnBase()) continue; 205 Element* basalelement = element->SpawnBasalElement(); 206 if(!basalelement->IsIceInElement() || !basalelement->IsFloating()) continue; 197 207 int el_boxid; 198 element->inputs->GetInputValue(&el_boxid,BasalforcingsPicoBoxIdEnum);208 basalelement->inputs->GetInputValue(&el_boxid,BasalforcingsPicoBoxIdEnum); 199 209 if(el_boxid!=boxid) continue; 200 210 201 Input* overturnings_input= element->GetInput(BasalforcingsPicoSubShelfOceanOverturningEnum); _assert_(overturnings_input);202 203 element->inputs->GetInputValue(&basinid,BasalforcingsPicoBasinIdEnum);204 Gauss* gauss= element->NewGauss(1); gauss->GaussPoint(0);211 Input* overturnings_input=basalelement->GetInput(BasalforcingsPicoSubShelfOceanOverturningEnum); _assert_(overturnings_input); 212 213 basalelement->inputs->GetInputValue(&basinid,BasalforcingsPicoBasinIdEnum); 214 Gauss* gauss=basalelement->NewGauss(1); gauss->GaussPoint(0); 205 215 overturnings_input->GetInputValue(&overturning,gauss); 206 216 delete gauss; 207 area= element->GetHorizontalSurfaceArea();217 area=basalelement->GetHorizontalSurfaceArea(); 208 218 overturning_weighted_avg[basinid]+=overturning*area; 219 basalelement->FindParam(&domaintype,DomainTypeEnum); 220 if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;}; 209 221 } 210 222 -
TabularUnified issm/trunk-jpl/src/c/modules/FloatingiceMeltingRatex/FloatingiceMeltingRatex.cpp ¶
r23982 r24010 73 73 void FloatingiceMeltingRateIsmip6x(FemModel* femmodel){/*{{{*/ 74 74 75 int num_basins, basinid, num_depths;75 int num_basins, basinid, num_depths, domaintype; 76 76 IssmDouble area, tf, base, time; 77 77 bool islocal; … … 154 154 for(int i=0;i<femmodel->elements->Size();i++){ 155 155 Element* element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i)); 156 if(!element->IsIceInElement() || !element->IsFloating()) continue; 157 Input* tf_input=element->GetInput(BasalforcingsIsmp6TfShelfEnum); _assert_(tf_input); 158 element->inputs->GetInputValue(&basinid,BasalforcingsIsmp6BasinIdEnum); 159 Gauss* gauss=element->NewGauss(1); gauss->GaussPoint(0); 156 if(!element->IsOnBase()) continue; 157 /*Spawn basal element if on base to compute element area*/ 158 Element* basalelement = element->SpawnBasalElement(); 159 if(!basalelement->IsIceInElement() || !basalelement->IsFloating()) continue; 160 Input* tf_input=basalelement->GetInput(BasalforcingsIsmp6TfShelfEnum); _assert_(tf_input); 161 basalelement->inputs->GetInputValue(&basinid,BasalforcingsIsmp6BasinIdEnum); 162 Gauss* gauss=basalelement->NewGauss(1); gauss->GaussPoint(0); 160 163 tf_input->GetInputValue(&tf,gauss); 161 164 delete gauss; 162 area= element->GetHorizontalSurfaceArea();165 area=basalelement->GetHorizontalSurfaceArea(); 163 166 tf_weighted_avg[basinid]+=tf*area; 164 167 areas_summed[basinid] +=area; 168 /*Delete spawned element if we are in 3D*/ 169 basalelement->FindParam(&domaintype,DomainTypeEnum); 170 if(domaintype!=Domain2DhorizontalEnum){basalelement->DeleteMaterials(); delete basalelement;}; 165 171 } 166 172 … … 174 180 } 175 181 182 /*Compute meltrates*/ 183 for(int i=0;i<femmodel->elements->Size();i++){ 184 Element* element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i)); 185 element->Ismip6FloatingiceMeltingRate(); 186 } 187 176 188 /*Cleanup and return */ 177 189 xDelete<IssmDouble>(tf_weighted_avg); … … 180 192 xDelete<IssmDouble>(areas_summed_cpu); 181 193 xDelete<IssmDouble>(tf_depths); 182 183 /*Compute meltrates*/184 for(int i=0;i<femmodel->elements->Size();i++){185 Element* element=xDynamicCast<Element*>(femmodel->elements->GetObjectByOffset(i));186 element->Ismip6FloatingiceMeltingRate();187 }188 194 } 189 195 /*}}}*/ -
TabularUnified issm/trunk-jpl/src/m/classes/basalforcingsismip6.m ¶
r23906 r24010 19 19 function self = extrude(self,md) % {{{ 20 20 self.basin_id=project3d(md,'vector',self.basin_id,'type','element','layer',1); 21 self.tf=project3d(md,'vector',self.tf,'type','element','layer',1); 22 self.delta_t=project3d(md,'vector',self.delta_t,'type','element','layer',1); 21 %self.tf=project3d(md,'vector',self.tf,'type','element','layer',1); 22 %self.delta_t=project3d(md,'vector',self.delta_t,'type','element','layer',1); 23 self.tf=project3d(md,'vector',self.tf,'type','node'); 23 24 self.geothermalflux=project3d(md,'vector',self.geothermalflux,'type','element','layer',1); %bedrock only gets geothermal flux 24 25 self.groundedice_melting_rate=project3d(md,'vector',self.groundedice_melting_rate,'type','node','layer',1); -
TabularUnified issm/trunk-jpl/src/m/classes/basalforcingspico.m ¶
r22918 r24010 13 13 farocean_temperature = NaN; 14 14 farocean_salinity = NaN; 15 isplume = NaN;15 isplume = 0; 16 16 geothermalflux = NaN; 17 17 groundedice_melting_rate = NaN; … … 68 68 md = checkfield(md,'fieldname','basalforcings.overturning_coeff','numel',1,'NaN',1,'Inf',1,'>',0); 69 69 md = checkfield(md,'fieldname','basalforcings.gamma_T','numel',1,'NaN',1,'Inf',1,'>',0); 70 md = checkfield(md,'fieldname','basalforcings.farocean_temperature','NaN',1,'Inf',1,' >',0,'size',[md.basalforcings.num_basins+1 NaN]);70 md = checkfield(md,'fieldname','basalforcings.farocean_temperature','NaN',1,'Inf',1,'size',[md.basalforcings.num_basins+1 NaN]); 71 71 md = checkfield(md,'fieldname','basalforcings.farocean_salinity','NaN',1,'Inf',1,'>',0,'size',[md.basalforcings.num_basins+1 NaN]); 72 72 md = checkfield(md,'fieldname','basalforcings.isplume','values',[0 1]);
Note:
See TracChangeset
for help on using the changeset viewer.