static void _MDBedloadFlux (int itemID) { float trnfac, rslope,Qday, alphabed,pixel_length; float rhofluid, rhosand, trneff,rhosed,rhowater,anglerep,degTOr; float Qb_kg_sec, Qb_kg_day; float upstream_Qb, deltaQb,i; char string [256]; // Set parameters rhofluid = 1000; // Fluid density rhosand = 2670; // Sand density trneff = 0.1; // Bedload efficency anglerep = 32.21; // Limiting angle degTOr = 1.745329252e-2; // 2.0*PI/360.0 convert degrees to radians alphabed = 1.0; trnfac = ( rhofluid * rhosand * trneff ) / ((rhosand - rhofluid) * tan( anglerep*degTOr )); //printf("Bedload,trnfac: %f\n",trnfac); pixel_length = pow( MFModelGetArea(itemID), 0.5 ); //printf("pixel_length: %f\n",pixel_length); rslope = MFVarGetFloat (_MDInMinSlopeID,itemID, 0.0)/pixel_length;// in % Qday = MFVarGetFloat (_MDInDischargeID ,itemID, 0.0); // in m3/s Qb_kg_sec = trnfac * rslope * pow( Qday, alphabed ); // in kg/s Qb_kg_day = Qb_kg_sec * (24*60*60); // in kg/s MFVarSetFloat (_MDOutBedloadFluxID, itemID, Qb_kg_sec); // Calculate Qb budget upstream_Qb = MFVarGetFloat (_MDInUpStreamQbID,itemID, 0.0); deltaQb = upstream_Qb - Qb_kg_sec; //local bedload budget MFVarSetFloat (_MDOutDeltaBedloadID, itemID, deltaQb); MFVarSetFloat (_MDInUpStreamQbID , itemID, (upstream_Qb*-1)); MFVarSetFloat (_MDInUpStreamQbID , itemID, Qb_kg_sec); }
static void _MDRunoff (int itemID) { // Input float baseFlow; float stormRunoffTotal; // RJS 082812 float runoffPoolRelease; // RJS 082812 float surfaceRO; float runoffCorr; float propStW; // RJS 100313 float propSuW; // RJS 100313 float propGrW; // RJS 100313 float totalRO; // RJS 100313 baseFlow = MFVarGetFloat (_MDInBaseFlowID, itemID, 0.0); runoffPoolRelease = MFVarGetFloat (_MDInRunoffPoolReleaseID, itemID, 0.0); // RJS 042712 stormRunoffTotal = MFVarGetFloat (_MDInStormRunoffTotalID, itemID, 0.0); // RJS 082812 surfaceRO = runoffPoolRelease + stormRunoffTotal; // RJS 082812 runoffCorr = _MDInRunoffCorrID == MFUnset ? 1.0 : MFVarGetFloat (_MDInRunoffCorrID, itemID, 1.0); totalRO = baseFlow + runoffPoolRelease + stormRunoffTotal; propStW = totalRO > 0.0 ? stormRunoffTotal / totalRO : 0.33333; propSuW = totalRO > 0.0 ? runoffPoolRelease / totalRO : 0.33333; propGrW = totalRO > 0.0 ? baseFlow / totalRO : 0.33333; // if ((itemID == 1576) || (itemID == 1568)) { // printf("m = %d, d = %d --yes-- id = %d, area = %f, baseFlow = %f, runoffPoolRelease = %f, stormRunoff = %f, surfaceRO = %f\n", MFDateGetCurrentMonth(), MFDateGetCurrentDay(), itemID, MFModelGetArea (itemID), baseFlow * MFModelGetArea (itemID) / (1000 * 86400), runoffPoolRelease * MFModelGetArea (itemID) / (1000 * 86400), stormRunoffTotal * MFModelGetArea (itemID) / (1000 * 86400),surfaceRO * MFModelGetArea (itemID) / (1000 * 86400)); // printf("m = %d, d = %d --yes-- id = %d, area = %f, baseFlow = %f, runoffPoolRelease = %f, stormRunoff = %f, surfaceRO = %f\n", MFDateGetCurrentMonth(), MFDateGetCurrentDay(), itemID, MFModelGetArea (itemID), baseFlow, runoffPoolRelease, stormRunoffTotal,surfaceRO); // } MFVarSetFloat (_MDOutRunoffID, itemID, (baseFlow + surfaceRO) * runoffCorr); MFVarSetFloat (_MDOutTotalSurfRunoffID, itemID, surfaceRO); // RJS 082812 MFVarSetFloat (_MDOutPropROStormWaterID, itemID, propStW); // RJS 100313 MFVarSetFloat (_MDOutPropROSurfaceWaterID, itemID, propSuW); // RJS 100313 MFVarSetFloat (_MDOutPropROGroundWaterID, itemID, propGrW); // RJS 100313 }
static void _MDSmallReservoirCapacity (int itemID) { // Input float irrAreaFraction; // Irrigated arrea fraction float accumSurfRunoff; // Accumulated surface runoff [mm] float accumIrrDemand; // Accumulated irrigational water demand [mm] // Output float smallResCapacity; // maximum storage, m3 // Local float potResCapacity; if ((irrAreaFraction = MFVarGetFloat (_MDInIrrAreaID, itemID, 0.0)) > 0.0) { accumSurfRunoff = MFVarGetFloat (_MDInRainSurfRunoffID, itemID, 0.0) * MFVarGetFloat (_MDInSmallResStorageFractionID, itemID, 1.0); accumIrrDemand = MFVarGetFloat (_MDInIrrGrossDemandID, itemID, 0.0); smallResCapacity = MFVarGetFloat (_MDOutSmallResCapacityID, itemID, 0.0); if (MFDateGetDayOfYear () > 1) { accumSurfRunoff += MFVarGetFloat (_MDOutRainSurfRunoffAccumulatedID, itemID, 0.0); accumIrrDemand += MFVarGetFloat (_MDOutIrrGrossDemandAccumulatedID, itemID, 0.0); } potResCapacity = accumSurfRunoff < accumIrrDemand ? accumSurfRunoff : accumIrrDemand; smallResCapacity = smallResCapacity > potResCapacity ? smallResCapacity : potResCapacity; } else accumSurfRunoff = accumIrrDemand = smallResCapacity = 0.0; MFVarSetFloat (_MDOutRainSurfRunoffAccumulatedID, itemID, accumSurfRunoff); MFVarSetFloat (_MDOutIrrGrossDemandAccumulatedID, itemID, accumIrrDemand); MFVarSetFloat (_MDOutSmallResCapacityID, itemID, smallResCapacity); }
static void _MDBaseFlow2 (int itemID) { // Input // Output float grdWater; // Groundwater size [mm] float grdWaterChg; // Groundwater change [mm/dt] float grdWaterRecharge; // Groundwater recharge [mm/dt] float grdWaterUptake; // Groundwater uptake [mm/dt] float percolation; // Soil to Groundwater percolation (mm/dt) float baseFlow = 0.0; // Base flow from groundwater [mm/dt] // Local grdWaterChg = grdWater = MFVarGetFloat (_MDOutGrdWatID, itemID, 0.0); if (_MDInSoilPercolationID != MFUnset ) { percolation = MFVarGetFloat(_MDInSoilPercolationID,itemID,0.0); // SZ 10212014 } else { percolation = 0.0; } if (grdWater < 0.0) grdWaterChg = grdWater = 0.0; //RJS 071511 grdWaterRecharge = MFVarGetFloat (_MDInRechargeID, itemID, 0.0); grdWater = grdWater + grdWaterRecharge + percolation; baseFlow = grdWater * _MDGroundWatBETA; grdWater = grdWater - baseFlow; grdWaterChg = grdWater - grdWaterChg; // if ((MFDateGetCurrentYear() > 0) && (grdWater != grdWater)) printf("itemID %d: grdWater %.2e baseFlow %.2e alpha %.2e percolation %.2e recharge %.2e\n", itemID, grdWater, baseFlow, _MDGroundWatBETA, percolation, grdWaterRecharge); MFVarSetFloat (_MDOutGrdWatID, itemID, grdWater); MFVarSetFloat (_MDOutGrdWatChgID, itemID, grdWaterChg); MFVarSetFloat (_MDOutGrdWatRechargeID, itemID, grdWaterRecharge); MFVarSetFloat (_MDOutBaseFlowID, itemID, baseFlow); }
static void _MDReservoirDW (int itemID) { // Input float discharge; // Current discharge [m3/s] float meanDischarge; // Long-term mean annual discharge [m3/s] float resCapacity; // Reservoir capacity [km3] // Output float resStorage; // Reservoir storage [km3] float resStorageChg; // Reservoir storage change [km3/dt] float resRelease; // Reservoir release [m3/s] // local float prevResStorage; // Reservoir storage from the previous time step [km3] float dt; // Time step length [s] float balance; // water balance [m3/s] // Parameters float drySeasonPct = 0.60; // RJS 071511 float wetSeasonPct = 0.16; // RJS 071511 float year = 0; // RJS 082311 discharge = MFVarGetFloat (_MDInDischargeID, itemID, 0.0); meanDischarge = MFVarGetFloat (_MDInDischMeanID, itemID, discharge); year = MFDateGetCurrentYear(); if ((resCapacity = MFVarGetFloat (_MDInResCapacityID, itemID, 0.0)) <= 0.0) { MFVarSetFloat (_MDOutResStorageID, itemID, 0.0); MFVarSetFloat (_MDOutResStorageChgID, itemID, 0.0); MFVarSetFloat (_MDOutResReleaseID, itemID, discharge); return; } dt = MFModelGet_dt (); prevResStorage = MFVarGetFloat(_MDOutResStorageID, itemID, 0.0); resRelease = discharge > meanDischarge ? wetSeasonPct * discharge : drySeasonPct * discharge + (meanDischarge - discharge); resStorage = prevResStorage + (discharge - resRelease) * 86400.0 / 1e9; if (resStorage > resCapacity) { resRelease = discharge * dt / 1e9 + prevResStorage - resCapacity; resRelease = resRelease * 1e9 / dt; resStorage = resCapacity; } else if (resStorage < 0.0) { resRelease = prevResStorage + discharge * dt / 1e9; resRelease = resRelease * 1e9 / dt; resStorage=0; } resStorageChg = resStorage - prevResStorage; balance = discharge - resRelease - (resStorageChg / 86400 * 1e9); // water balance MFVarSetFloat (_MDOutResStorageID, itemID, resStorage); MFVarSetFloat (_MDOutResStorageChgID, itemID, resStorageChg); }
static void _MDWaterBalance(int itemID) { // Input float precip = MFVarGetFloat(_MDInPrecipID, itemID, 0.0); float etp = MFVarGetFloat(_MDInEvaptrsID, itemID, 0.0); float snowPackChg = MFVarGetFloat(_MDInSnowPackChgID, itemID, 0.0); float soilMoistChg = MFVarGetFloat(_MDInSoilMoistChgID, itemID, 0.0); float grdWaterChg = MFVarGetFloat(_MDInGrdWatChgID, itemID, 0.0); float runoff = MFVarGetFloat(_MDInRunoffID, itemID, 0.0); float runoffPoolChg = MFVarGetFloat(_MDInRunoffPoolChgID, itemID, 0.0); float irrAreaFrac = 0.0; float irrGrossDemand = 0.0; float irrReturnFlow = 0.0; float irrEvapotransp = 0.0; float irrSoilMoistChg = 0.0; float irrUptakeGrdWater = 0.0; float irrUptakeRiver = 0.0; float irrUptakeExcess = 0.0; float smallResStorageChg = 0.0; float smallResRelease = 0.0; float smallResEvapo = 0.0; // Output float balance; float balance2; if (_MDInIrrGrossDemandID != MFUnset) { irrAreaFrac = MFVarGetFloat (_MDInIrrAreaFracID, itemID, 0.0); irrGrossDemand = MFVarGetFloat (_MDInIrrGrossDemandID, itemID, 0.0); irrReturnFlow = MFVarGetFloat (_MDInIrrReturnFlowID, itemID, 0.0); irrEvapotransp = MFVarGetFloat (_MDInIrrEvapotranspID, itemID, 0.0); irrSoilMoistChg = _MDInIrrSoilMoistChgID != MFUnset ? MFVarGetFloat (_MDInIrrSoilMoistChgID, itemID, 0.0) : 0.0; irrUptakeGrdWater = _MDInIrrUptakeGrdWaterID != MFUnset ? MFVarGetFloat (_MDInIrrUptakeGrdWaterID, itemID, 0.0) : 0.0; irrUptakeRiver = _MDInIrrUptakeRiverID != MFUnset ? MFVarGetFloat (_MDInIrrUptakeRiverID, itemID, 0.0) : 0.0; irrUptakeExcess = MFVarGetFloat (_MDInIrrUptakeExcessID, itemID, 0.0); if (_MDInSmallResReleaseID != MFUnset) { smallResRelease = MFVarGetFloat (_MDInSmallResReleaseID, itemID, 0.0); smallResStorageChg = MFVarGetFloat (_MDInSmallResStorageChgID, itemID, 0.0); smallResEvapo = MFVarGetFloat (_MDInSmallResEvapoID, itemID, 0.0); } balance = (precip - snowPackChg) * irrAreaFrac + irrGrossDemand - irrEvapotransp - irrSoilMoistChg - irrReturnFlow; MFVarSetFloat (_MDOutIrrWaterBalanceID, itemID, balance); balance = irrGrossDemand - (irrUptakeGrdWater + irrUptakeRiver + irrUptakeExcess + smallResRelease); MFVarSetFloat (_MDOutIrrUptakeBalanceID, itemID, balance); } balance = precip + irrUptakeRiver + irrUptakeExcess - (etp + runoff + grdWaterChg + snowPackChg + soilMoistChg + smallResStorageChg); balance2 = precip + irrUptakeRiver + irrUptakeExcess - (etp + runoff + grdWaterChg + snowPackChg + soilMoistChg + smallResStorageChg + runoffPoolChg); // printf("d = %d, m = %d, y = %d, waterbalance = %f\n", MFDateGetCurrentDay(), MFDateGetCurrentMonth(), MFDateGetCurrentYear(), balance2); if (fabs (balance2) > 0.001 ) // printf ("TIEM %i WaterBalance! %f precip %f etp = %f runoff = %f grdWaterChg = %f snowPackChg = %f soilMoistChg = %f runoffPoolChg %f\n", itemID ,balance2,precip,etp,runoff,grdWaterChg,snowPackChg,soilMoistChg,runoffPoolChg); MFVarSetFloat (_MDOutWaterBalanceID, itemID , balance); }
static void _MDWaterBalanceInput (int itemID) { float runoff = MFVarGetFloat(_MDInRunoffID, itemID, 0.0); float balance = runoff; MFVarSetFloat (_MDOutWaterBalanceID, itemID , balance); }
static void _MDRainIntercept (int itemID) { // Input float precip; // daily precipitation [mm/day] float sPackChg;// snow pack change [mm/day] float pet; // daily potential evapotranspiration [mm/day] float height; // canopy height [m] float lai; // projected leaf area index float sai; // projected stem area index // Local float epi; // daily potential interception [mm/day] float eis; // maximum amount of evaporated interception during "storm" [mm] float c; // canopy storage capacity [mm] // Output float intercept; // estimated interception [mm] precip = MFVarGetFloat (_MDInPrecipID, itemID, 0.0); pet = MFVarGetFloat (_MDInPetID, itemID, 0.0); intercept = 0.0; if ((pet > 0.0) && (precip > 0.0)) { lai = MFVarGetFloat (_MDInLeafAreaIndexID, itemID, 0.0); sai = MFVarGetFloat (_MDInStemAreaIndexID, itemID, 0.0); c = MDConstInterceptCI * (lai + sai) / 2.0; if (c > 0.0) { sPackChg = MFVarGetFloat (_MDInSPackChgID, itemID, 0.0); height = MFVarGetFloat (_MDInCParamCHeightID, itemID, 0.0); if (sPackChg > 0.0) precip = precip - sPackChg; epi = pet * (height < MDConstInterceptCH ? 1.0 + height / MDConstInterceptCH : 2.0); eis = MDConstInterceptD * epi; intercept = precip < (eis + c) ? /* capacity is not reached */ precip : /* capacity exceeded */ (eis + c); if (intercept > pet) intercept = pet; // FBM Addition } } MFVarSetFloat (_MDOutInterceptID,itemID, intercept); }
static void _MDRainInfiltrationSimple (int itemID) { float surplus; float surfRunoff; float infiltration; if (_MDInfiltrationFractionID != MFUnset) _MDInfiltrationFrac = MFVarGetFloat(_MDInfiltrationFractionID,itemID,0.0); surplus = MFVarGetFloat(_MDInRainWaterSurplusID, itemID, 0.0); surfRunoff = surplus * (1.0 - _MDInfiltrationFrac); infiltration = surplus *_MDInfiltrationFrac; MFVarSetFloat (_MDOutRainSurfRunoffID, itemID, surfRunoff); MFVarSetFloat (_MDOutRainInfiltrationID, itemID, infiltration); // printf("Infiltraction %f surfRunoff %f \n",infiltration,surfRunoff); }
static void _MDGrossRadianceOtto (int itemID) { // Input int day; float lambda; // Output float grossRad; // Local int hour; double eta, sigma,sinphi,sp,sbb,sotd; day = MFDateGetDayOfYear (); lambda = MFModelGetLatitude (itemID) * DTOR; sp = 1360.0 * 3600.0 * 24.0 * 0.041841 / 41860.0; // FBM 0.041841 conversion from cal/cm2 to MJ/m2 grossRad = 0.0; sigma = -23.4856 * cos (2.0 * M_PI * (day + 11.0) / 365.25) * DTOR; for (hour = 0; hour < 24; hour++) { eta = (double) ((hour + 1)) * M_PI / 12.0; sinphi = sin (lambda) * sin (sigma) + cos (lambda) * cos (sigma) * cos (eta); sotd = 1 - (0.016729 * cos (0.9856 * (day - 4.0) * DTOR)); sbb = sp * sinphi / pow (sotd,2.0); if (sbb >= 0) grossRad += sbb; } MFVarSetFloat (_MDOutGrossRadID, itemID, grossRad / 24.0); }
static void _MDWTempRiver (int itemID) { float RechargeT; float GrdWaterT; // float SurfaceRO; // comment out 082812 float TotalSurfRunoff; // RJS 082812 float GrdWaterRO; float TemperatureRO; RechargeT = MFVarGetFloat (_MDInWTempSurfRunoffPoolID, itemID, 0.0); // RJS 060512 GrdWaterT = MFVarGetFloat (_MDInWTempGrdWaterID, itemID, 0.0); // SurfaceRO = MFVarGetFloat (_MDInSurfRunoffID, itemID, 0.0); // comment out 082812 TotalSurfRunoff = MFVarGetFloat (_MDInTotalSurfRunoffID, itemID, 0.0); // RJS 082812 GrdWaterRO = MFVarGetFloat (_MDInBaseFlowID, itemID, 0.0); // SurfaceRO = MDMaximum(0, SurfaceRO); // comment out 082812 GrdWaterRO = MDMaximum(0, GrdWaterRO); TotalSurfRunoff = MDMaximum(0, TotalSurfRunoff); // RJS 082812 // TemperatureRO = MDMaximum((((SurfaceRO * RechargeT) + (GrdWaterRO * GrdWaterT)) / (SurfaceRO + GrdWaterRO)),0.0); // commented out 082812 TemperatureRO = MDMaximum((((TotalSurfRunoff * RechargeT) + (GrdWaterRO * GrdWaterT)) / (TotalSurfRunoff + GrdWaterRO)),0.0); // RJS 082812 MFVarSetFloat(_MDOutWTempRiverID,itemID,TemperatureRO); }
static void _MDWTempSurfRunoffPool (int itemID) { float SurfRunoffT; float SurfRunoffPoolT; float SurfRunoff; float SurfRunoffPool; SurfRunoffT = MFVarGetFloat (_MDInWTempSurfRunoffID, itemID, 0.0); SurfRunoffPoolT = MFVarGetFloat (_MDOutWTempSurfRunoffPoolID, itemID, 0.0); SurfRunoff = MFVarGetFloat (_MDInRainSurfRunoffID, itemID, 0.0); SurfRunoffPool = MFVarGetFloat (_MDInRunoffPoolID, itemID, 0.0); SurfRunoff = MDMaximum(0, SurfRunoff); SurfRunoffPool = MDMaximum(0, SurfRunoffPool); if (!isnan(SurfRunoffPool) && !isnan(SurfRunoff) && ((SurfRunoffPool + SurfRunoff) > 0) && !isnan(SurfRunoffPoolT) && !isnan(SurfRunoffT)){ SurfRunoffPoolT = MDMaximum(((SurfRunoffPool * SurfRunoffPoolT) + (SurfRunoff * SurfRunoffT)) / (SurfRunoffPool + SurfRunoff), 0.0); MFVarSetFloat (_MDOutWTempSurfRunoffPoolID, itemID, SurfRunoffPoolT); } else{ MFVarSetMissingVal(_MDOutWTempSurfRunoffPoolID,itemID); } }
static void _MDSurfRunoff (int itemID) { // Input float surfRunoff; // Surface runoff [mm/dt] surfRunoff = MFVarGetFloat (_MDInRainSurfRunoffID, itemID, 0.0) - (_MDInSmallResUptakeID != MFUnset ? MFVarGetFloat (_MDInSmallResUptakeID, itemID, 0.0) : 0.0); MFVarSetFloat (_MDOutSurfRunoffID, itemID, surfRunoff); }
static void _MDRunoffVolume (int itemID) { // Input float runoff; runoff = MFVarGetFloat (_MDInRunoffID, itemID, 0.0) * MFModelGetArea (itemID) / (MFModelGet_dt () * 1000.0); // if((itemID == 25014) && (runoff * 86400 < -0.000009)) printf("############ runoff = %f\n", runoff * 86400); //runoff = 0.0; //RJS 071511 MFVarSetFloat (_MDOutRunoffVolumeID, itemID, runoff); }
static void _MDWTempGrdWater (int itemID) { float airT; float RechargeT; float GrdWaterT; float RainRechargeIn; float IrrReturnFlow; float GrdWaterStorage; airT = MFVarGetFloat (_MDInAirTempID, itemID, 0.0); RechargeT = MFVarGetFloat (_MDInWTempSurfRunoffID, itemID, 0.0); RainRechargeIn = MFVarGetFloat (_MDInRainRechargeID, itemID, 0.0); if (_MDInIrrReturnFlowID != MFUnset){ IrrReturnFlow = MFVarGetFloat (_MDInIrrReturnFlowID, itemID, 0.0); } else { IrrReturnFlow = 0; } GrdWaterStorage = MFVarGetFloat (_MDOutGrdWaterID, itemID, 0.0); GrdWaterT = MFVarGetFloat (_MDOutWTempGrdWaterID, itemID, 0.0); //if (itemID == 233){ // printf("Stop itemID %d day %d \n", itemID, MFDateGetCurrentDay()); // } //TODO: why is RainRechargeIn < 0 sometimes? RainRechargeIn = MDMaximum(0, RainRechargeIn); IrrReturnFlow = MDMaximum(0, IrrReturnFlow); GrdWaterStorage = MDMaximum(0, GrdWaterStorage); if (!isnan(GrdWaterStorage) && !isnan(RainRechargeIn) && !isnan(IrrReturnFlow) && ((GrdWaterStorage + RainRechargeIn + IrrReturnFlow) > 0) && !isnan(GrdWaterT) && !isnan(RechargeT) && !isnan(airT)){ GrdWaterT = MDMaximum( (((GrdWaterStorage * GrdWaterT) + (RainRechargeIn * RechargeT) + (IrrReturnFlow * airT)) / (GrdWaterStorage + RainRechargeIn + IrrReturnFlow)), 0.0); // if (GrdWaterT > 30){ // printf("Stop itemID %d day %d \n", itemID, MFDateGetCurrentDay()); // } // GrdWaterT = MDMinimum(GrdWaterT, 40); //does this need to be properly mass balanced? GRdwater T might just keep going up. MFVarSetFloat (_MDOutWTempGrdWaterID,itemID,GrdWaterT); } else{ MFVarSetMissingVal(_MDOutWTempGrdWaterID,itemID); } if (GrdWaterT > 100) printf("m = %d, d = %d, itemID = %d, GrdWaterT = %f, RainRechargeIn = %f\n", MFDateGetCurrentMonth (), MFDateGetCurrentDay (), itemID, GrdWaterT, RainRechargeIn); // if (itemID == 486) printf("y = %d, m = %d, d = %d, GwT = %f, ReT = %f, AirT = %f, Recharge = %f, GW = %f\n", MFDateGetCurrentYear(), MFDateGetCurrentMonth(), MFDateGetCurrentDay(), GrdWaterT, RechargeT, airT, RainRechargeIn, GrdWaterStorage); }
static void _MDReservoirNeuralNet (int itemID) { // Input float discharge; // Current discharge [m3/s] float meanDischarge; // Long-term mean annual discharge [m3/s] float resCapacity; // Reservoir capacity [km3] float discharge_t_1; float discharge_t_2; float discharge_t_3; float discharge_min; float discharge_max; // Output float resStorage; // Reservoir storage [km3] float resStorageChg; // Reservoir storage change [km3/dt] float resRelease; // Reservoir release [m3/s] float res_release_t_1; float res_release_t_2; // local float prevResStorage; // Reservoir storage from the previous time step [km3] float dt; // Time step length [s] float balance; // water balance [m3/s] // Parameters float drySeasonPct = 0.60; // RJS 071511 float wetSeasonPct = 0.16; // RJS 071511 float year = 0; // RJS 082311 discharge = MFVarGetFloat (_MDInDischargeID, itemID, 0.0); meanDischarge = MFVarGetFloat (_MDInDischMeanID, itemID, discharge); year = MFDateGetCurrentYear(); if ((resCapacity = MFVarGetFloat (_MDInResCapacityID, itemID, 0.0)) <= 0.0) { MFVarSetFloat (_MDOutResStorageID, itemID, 0.0); MFVarSetFloat (_MDOutResStorageChgID, itemID, 0.0); MFVarSetFloat (_MDOutResReleaseID, itemID, discharge); return; } discharge_min = MFVarGetFloat(_MDInDischMinID, itemID, 0.0); discharge_max = MFVarGetFloat(_MDInDischMaxID, itemID, 0.0); discharge_t_1 = discharge; discharge_t_2 = MFVarGetFloat(_MDOutDisch_t_1_ID, itemID, 0.0); discharge_t_3 = MFVarGetFloat(_MDOutDisch_t_2_ID, itemID, 0.0); res_release_t_1 = MFVarGetFloat(_MDOutResReleaseID, itemID, 0.0); res_release_t_2 = MFVarGetFloat(_MDOutResRelease_t_1_ID, itemID, 0.0); // put code here... // MFVarSetFloat(_MDOutDisch_t_1_ID, itemID, discharge_t_1); MFVarSetFloat(_MDOutDisch_t_2_ID, itemID, discharge_t_2); MFVarSetFloat(_MDOutResReleaseID, itemID, resRelease); MFVarSetFloat(_MDOutResRelease_t_1_ID, itemID, res_release_t_1); }
static void _MDRunoffInput2 (int itemID) { // RJS 061312 ADDED THIS WHOLE FUNCTION // Input float baseFlow; // " float runoffPoolRelease; float totalRO; float prop = 0.33333; // " baseFlow = MFVarGetFloat (_MDInBaseFlowID, itemID, 0.0); runoffPoolRelease = MFVarGetFloat (_MDInRunoffPoolReleaseID, itemID, 0.0); // RJS 042712 totalRO = baseFlow + runoffPoolRelease; MFVarSetFloat (_MDOutRunoffID, itemID, totalRO); // " MFVarSetFloat (_MDOutTotalSurfRunoffID, itemID, runoffPoolRelease); // RJS 082812 MFVarSetFloat (_MDOutPropROStormWaterID, itemID, prop); MFVarSetFloat (_MDOutPropROSurfaceWaterID, itemID, prop); MFVarSetFloat (_MDOutPropROGroundWaterID, itemID, prop); }
static void _MDWTempNoSurfRunoffPool (int itemID) { float SurfRunoffT; float SurfRunoffPoolT; SurfRunoffT = MFVarGetFloat (_MDInWTempSurfRunoffID, itemID, 0.0); SurfRunoffPoolT = SurfRunoffT; MFVarSetFloat (_MDOutWTempSurfRunoffPoolID, itemID, SurfRunoffPoolT); }
static void _MDRunoffMean (int itemID) { int nSteps; float runoff; float runoffMean; runoff = MFVarGetFloat (_MDInRunoffID, itemID, 0.0); nSteps = MFVarGetInt (_MDInAvgNStepsID, itemID, 0); runoffMean = MFVarGetFloat (_MDOutRunoffMeanID, itemID, 0.0); runoffMean = (float) (((double) runoffMean * (double) nSteps + runoff) / ((double) (nSteps + 1))); MFVarSetFloat (_MDOutRunoffMeanID, itemID, runoffMean); }
static void _MDDischMean (int itemID) { int nSteps; float accumDisch; float dischMean; accumDisch = MFVarGetFloat (_MDInAccumDischargeID, itemID, 0.0); nSteps = MFVarGetInt (_MDInAvgNStepsID, itemID, 0); dischMean = MFVarGetFloat (_MDOutDischMeanID, itemID, 0.0); dischMean = (float) (((double) dischMean * (double) nSteps + accumDisch) / ((double) (nSteps + 1))); MFVarSetFloat (_MDOutDischMeanID, itemID, dischMean); }
static void _MDDischarge (int itemID) { float discharge; // Discharge [m3/s] discharge = MFVarGetFloat (_MDInDischLevel1ID, itemID, 0.0); if (_MDInDischObservedID != MFUnset) discharge = MFVarGetFloat (_MDInDischObservedID, itemID, discharge); // if (itemID == 1224 || itemID == 531) printf("**MDDischarge** itemID = %d, day = %d, discharge = %f\n", itemID, MFDateGetCurrentDay(), discharge); MFVarSetFloat (_MDOutDischargeID, itemID, discharge); }
static void _MDDischLevel1 (int itemID) { float discharge; if ((_MDInDischReleasedID != MFUnset) && (!MFVarTestMissingVal (_MDInDischReleasedID, itemID))) discharge = MFVarGetFloat (_MDInDischReleasedID, itemID, 0.0); else discharge = MFVarGetFloat (_MDInDischLevel2ID, itemID, 0.0); // if (itemID == 25014) printf("discharge= %f\n",discharge); // if (itemID == 1224 || itemID == 531) printf("**DischLevel1** itemID = %d, day = %d, discharge = %f\n", itemID, MFDateGetCurrentDay(), discharge); MFVarSetFloat (_MDOutDischLevel1ID, itemID, discharge); }
static void _MDRunoffInput (int itemID) { // RJS 061312 ADDED THIS WHOLE FUNCTION // Input float baseFlow; // " float surfaceRO; float prop = 0.33333; // " baseFlow = MFVarGetFloat (_MDInBaseFlowID, itemID, 0.0); // " // surfaceRO = MFVarGetFloat (_MDInRunoffPoolReleaseID, itemID, 0.0); // " surfaceRO = MFVarGetFloat (_MDInTotalSurfRunoffID, itemID, 0.0); // RJS 082812, replaces line above // if ((itemID == 1576) || (itemID == 1568)) { // printf("id = %d, area = %f, baseFlow_RO = %f, baseFlow_Q = %f, surfaceRO_RO = %f, surfaceRO_Q = %f\n",itemID, MFModelGetArea (itemID), baseFlow, baseFlow * MFModelGetArea (itemID) / (1000 * 86400), surfaceRO, surfaceRO * MFModelGetArea (itemID) / (1000 * 86400)); // } MFVarSetFloat (_MDOutRunoffID, itemID, (baseFlow + surfaceRO)); // " MFVarSetFloat (_MDOutTotalSurfRunoffID, itemID, surfaceRO); // RJS 082812 MFVarSetFloat (_MDOutPropROStormWaterID, itemID, prop); MFVarSetFloat (_MDOutPropROSurfaceWaterID, itemID, prop); MFVarSetFloat (_MDOutPropROGroundWaterID, itemID, prop); } // "
static void _MDSoilAvailWaterCap (int itemID) { float fieldCapacity; // Field capacity [m/m] float wiltingPoint; // Wilting point [m/m] float rootingDepth; // Rooting depth [mm] fieldCapacity = MFVarGetFloat (_MDInSoilFieldCapacityID, itemID, 0.0); wiltingPoint = MFVarGetFloat (_MDInSoilWiltingPointID, itemID, 0.0); rootingDepth = MFVarGetFloat (_MDInSoilRootingDepthID, itemID, 0.0); if (fieldCapacity < wiltingPoint) fieldCapacity = wiltingPoint; MFVarSetFloat (_MDOutSoilAvailWaterCapID, itemID, rootingDepth * (fieldCapacity - wiltingPoint)); }
static void _MDChloride (int itemID) { float discharge = 0.0; // streamflow m3/s float postConc_SC = 0.0; // ionic strength uS/cm float postConc_Cl = 0.0; // chloride conc. (mg / L ) float postFlux_Cl = 0.0; // chloride flux (in streamflow from cell) (kg/day) discharge = MFVarGetFloat (_MDInDischargeID, itemID, 0.0); // m3/sec, discharge leaving the grid cell, after routing! postConc_SC = MFVarGetFloat (_MDInPostConc_SCID, itemID, 0.0); // uS/cm // RELATION BETWEEN SPECIFIC CONDUCTANCE AND CHLORIDE CONCENTRATION // FROM 2013 LOVOTECS SNAPSHOTS float m = 0.23348651; float b = -2.29974005; postConc_Cl = m*postConc_SC + b > 0.000001 ? m*postConc_SC + b : 0.000001; // calculate fluxes postFlux_Cl = (discharge * MDConst_m3PerSecTOm3PerDay) * postConc_Cl / 1000. ; // kg/day MFVarSetFloat (_MDOutPostConc_ClID, itemID, postConc_Cl); MFVarSetFloat (_MDOutFlux_ClID, itemID, postFlux_Cl); }
static void _MDCParamZ0g (int itemID) { // Input int cover; // Local static float lookup [] = { 0.02, 0.02, 0.02, 0.01, 0.01, 0.005, 0.001, 0.001 }; cover = MFVarGetInt (_MDInCoverID, itemID, 7); // defaulting missing value to water. if ((cover < 0) || (cover >= (int) (sizeof (lookup) / sizeof (lookup [0])))) { CMmsgPrint (CMmsgWarning,"Warning: Invalid cover [%d] in: %s:%d\n",cover,__FILE__,__LINE__); return; } MFVarSetFloat (_MDOutCParamZ0gID,itemID, lookup [cover]); }
static void _MDRainPotETPsTaylor (int itemID) { // Priestley and Taylor (1972) PE in mm for day // Input float dayLen; // daylength in fraction of day float i0hDay; // daily potential insolation on horizontal [MJ/m2] float albedo; // albedo float airT; // air temperatur [degree C] float solRad; // daily solar radiation on horizontal [MJ/m2] float vPress; // daily average vapor pressure [kPa] float sHeat = 0.0; // average subsurface heat storage for day [W/m2] // Local float solNet; // average net solar radiation for daytime [W/m2] float lngNet; // average net longwave radiation for day [W/m2] float aa; // available energy [W/m2] float es; // vapor pressure at airT [kPa] float delta; // dEsat/dTair [kPa/K] float dd; // vapor pressure deficit [kPa] float le; // latent heat [W/m2] // Output float pet; if (MFVarTestMissingVal (_MDInDayLengthID, itemID) || MFVarTestMissingVal (_MDInI0HDayID, itemID) || MFVarTestMissingVal (_MDInCParamAlbedoID, itemID) || MFVarTestMissingVal (_MDInAtMeanID, itemID) || MFVarTestMissingVal (_MDInSolRadID, itemID) || MFVarTestMissingVal (_MDInVPressID, itemID)) { MFVarSetMissingVal (_MDOutPetID,itemID); return; } dayLen = MFVarGetFloat (_MDInDayLengthID, itemID, 0.0); i0hDay = MFVarGetFloat (_MDInI0HDayID, itemID, 0.0); albedo = MFVarGetFloat (_MDInCParamAlbedoID, itemID, 0.0); airT = MFVarGetFloat (_MDInAtMeanID, itemID, 0.0); solRad = MFVarGetFloat (_MDInSolRadID, itemID, 0.0); vPress = MFVarGetFloat (_MDInVPressID, itemID, 0.0); solNet = (1.0 - albedo) * solRad / MDConstIGRATE; lngNet = MDSRadNETLong (i0hDay,airT,solRad,vPress); aa = solNet + lngNet - sHeat; es = MDPETlibVPressSat (airT); delta = MDPETlibVPressDelta (airT); dd = es - vPress; le = MDConstPTALPHA * delta * aa / (delta + MDConstPSGAMMA); pet = MDConstEtoM * MDConstIGRATE * le; MFVarSetFloat (_MDOutPetID,itemID,pet); }
static void _MDCParamAlbedo (int itemID) { // Input int cover; float snowPack; // Local static float albedo [] = { 0.14, 0.18, 0.18, 0.20, 0.20, 0.22, 0.26, 0.10 }; static float albedoSnow [] = { 0.14, 0.23, 0.35, 0.50, 0.50, 0.50, 0.50, 0.50 }; cover = MFVarGetInt (_MDInCoverID, itemID, 7); // defaulting missing value to water. if ((cover < 0) || (cover >= (int) (sizeof (albedo) / sizeof (albedo [0])))) { CMmsgPrint (CMmsgWarning,"Warning: Invalid cover [%d] in: %s:%d\n",cover,__FILE__,__LINE__); return; } snowPack = MFVarGetFloat (_MDInSnowPackID, itemID, 0.0); MFVarSetFloat (_MDOutCParamAlbedoID,itemID,snowPack > 0.0 ? albedoSnow[cover] : albedo[cover]); }
static void _MDReservoir (int itemID) { // Input float discharge; // Current discharge [m3/s] float meanDischarge; // Long-term mean annual discharge [m3/s] float resCapacity; // Reservoir capacity [km3] // Output float resStorage; // Reservoir storage [km3] float resStorageChg; // Reservoir storage change [km3/dt] float resRelease; // Reservoir release [m3/s] // local float prevResStorage; // Reservoir storage from the previous time step [km3] float dt; // Time step length [s] float beta; // Residence time [a] // wet { -0.19 B + 0.88 Q_t } & {Q_t > Q_m } // dry {0.47 B + 1.12 Q_t } & {Q_t \le Q_m } discharge = MFVarGetFloat (_MDInDischargeID, itemID, 0.0); meanDischarge = MFVarGetFloat (_MDInDischMeanID, itemID, discharge); if ((resCapacity = MFVarGetFloat (_MDInResCapacityID, itemID, 0.0)) <= 0.0) { MFVarSetFloat (_MDOutResStorageID, itemID, 0.0); MFVarSetFloat (_MDOutResStorageChgID, itemID, 0.0); MFVarSetFloat (_MDOutResReleaseID, itemID, discharge); return; } beta = resCapacity /(meanDischarge * 3600 * 24 * 365/1e9); dt = MFModelGet_dt (); prevResStorage = MFVarGetFloat(_MDOutResStorageID, itemID, 0.0); resRelease = discharge > meanDischarge ? - 0.19 * beta + 0.88 * discharge : 0.47 * beta + 1.12 * discharge; resStorage = prevResStorage + (discharge - resRelease) * 86400.0 / 1e9; if (resStorage > resCapacity) { resRelease = discharge * dt / 1e9 + prevResStorage - resCapacity; resRelease = resRelease * 1e9 / dt; resStorage = resCapacity; } else if (resStorage < 0.0) { resRelease = prevResStorage + discharge * dt / 1e9; resRelease = resRelease * 1e9 / dt; resStorage=0; } resStorageChg = resStorage - prevResStorage; MFVarSetFloat (_MDOutResStorageID, itemID, resStorage); MFVarSetFloat (_MDOutResStorageChgID, itemID, resStorageChg); MFVarSetFloat (_MDOutResReleaseID, itemID, resRelease); }
static void _MFUserFunc (void *commonPtr,void *threadData, size_t taskId) { int iFunc, varID, link, uLink, objectId; MFVariable_t *var; double value; objectId = _MFDomain->ObjNum - taskId - 1; for (var = MFVarGetByID (varID = 1);var != (MFVariable_t *) NULL;var = MFVarGetByID (++varID)) if (var->Route) { value = 0.0; for (link = 0; link < _MFDomain->Objects [objectId].ULinkNum; ++link) { uLink = _MFDomain->Objects [objectId].ULinks [link]; value += MFVarGetFloat (varID,uLink,0.0); } MFVarSetFloat (varID, objectId, value); } for (iFunc = 0;iFunc < _MFFunctionNum; ++iFunc) (_MFFunctions [iFunc]) (objectId); }