static void _MDSpecCond (int itemID) { float stormflowVol = 0.0; float baseflowVol = 0.0; float runoffpoolreleaseVol = 0.0; float discharge = 0.0; float waterStorage = 0.0; // New Variables // float Developed = 0.0; float preFlux_SC = 0.0; float postFlux_SC = 0.0; float storeWater_SC = 0.0; float postStoreWater_SC = 0.0; float SCTotalIn = 0.0; float postConc_SC = 0.0; float massBalance_SC = 0.0; float localLoad_SC = 0.0; float baseflowConc_SC = 0.0; float stormflowConc_SC = 0.0; float surfflowConc_SC = 0.0; float clean_intrcp = 0.0; float airTemperature = 0.0; baseflowVol = MFVarGetFloat (_MDInBaseFlowID, itemID,0.0) * MFModelGetArea (itemID) / (MFModelGet_dt () * 1000.0); // TODO: Either need to define BaseFlowVolumeDef or calculate internally here. stormflowVol = MFVarGetFloat (_MDInStormRunoffTotalID, itemID,0.0) * MFModelGetArea (itemID) / (MFModelGet_dt () * 1000.0); runoffpoolreleaseVol = MFVarGetFloat (_MDInRunoffPoolReleaseID, itemID,0.0) * MFModelGetArea (itemID) / (MFModelGet_dt () * 1000.0); discharge = MFVarGetFloat (_MDInDischargeID, itemID, 0.0); // m3/sec, discharge leaving the grid cell, after routing! waterStorage = MFVarGetFloat (_MDInRiverStorageID, itemID, 0.0); // m3/sec, storage rate remaining in grid cell at end of timestep - routed to retention airTemperature = MFVarGetFloat (_MDInAirTemperatureID, itemID, 0.0); // degrees C // New Variables // Developed = MFVarGetFloat (_MDInSubFractionID, itemID, 0.0); // proportion developed land // DEFINE IONIC CONTENT: ic = m3*(uS/cm) // Assumes that ionic strength behaves linearly and conservatively. Strictly this is only valid when // ionic strength is controlled by a few conservative ions. Therefore, this is valid for salt impacted // streams; however, this breaks down at low ionic strength waters. Therefore - this deep in the chloride analysis // we are operating with the understanding that we are only really looking at chloride impacts - not chloride itself. - SZ 6/12/2014 preFlux_SC = MFVarGetFloat (_MDOutFlux_SCID, itemID, 0.0); // ic/day storeWater_SC = MFVarGetFloat (_MDOutStoreWater_SCID, itemID, 0.0); // ic/day /// BASEFLOW LOADING OF SPECIFIC CONDUCTANCE /// /// attributed to the groundwater and surface runoff pools - impervious runof is attributed with clean water /// [email protected] for details on loading estimation /// //baseflowConc_SC = 25.94 + 13.32 * (Developed); // Baseflow_SC relation (0.9 Quantile based) to Developed area. Developed should already be in PER clean_intrcp = 21.72;//25.94; baseflowConc_SC = clean_intrcp + 9.602 * (Developed); // Baseflow SC relation (regression to zero storm flow) to Devloped area. // Predicting dilution rate based on AWC and Ksat does not help time-series predictions. Though there is an apparent dependence on these factors in the lovotecs data. surfflowConc_SC = MDMaximum(0.64 * baseflowConc_SC,clean_intrcp); // 0.8244 // Average fraction of baseflow SC exhibited during storm events (at daily flow exceedance of 1% P1) stormflowConc_SC = (airTemperature < 2.0) ? 15.0*Developed/100.*baseflowConc_SC : MDMaximum(0.20 * baseflowConc_SC,0.8*clean_intrcp); // Winter-time salting. // Calculate input loadings localLoad_SC = (baseflowConc_SC * baseflowVol + surfflowConc_SC * runoffpoolreleaseVol + stormflowVol*stormflowConc_SC ) * 86400 ; // ic/day SCTotalIn = localLoad_SC + preFlux_SC + storeWater_SC; // ic/day if (discharge > 0.0000001) { // Calculate pre-tranformation concentration - for cells with accumulated discharge postConc_SC = SCTotalIn / (discharge * 86400.); // uS/cm } else { // Force concentrations to local values for minimal accumulation / dessicated cells postConc_SC = baseflowConc_SC; // Force negligible discharge to the baseflow concentration } //Calculates the fluxes/storage for the mixing (appropriate for speccond) case postFlux_SC = (discharge * MDConst_m3PerSecTOm3PerDay) * postConc_SC ; // ic/day postStoreWater_SC = (waterStorage ) * postConc_SC ; // ic/day // Calculates the mass balances massBalance_SC = (SCTotalIn - (postFlux_SC + postStoreWater_SC )) / SCTotalIn; // Print mass balance errors if (MFDateGetCurrentYear() > 0){ if ( (massBalance_SC > 0.001)) { printf("itemID = %d, %d-%d-%d, MB_SC = %f\n",itemID, MFDateGetCurrentYear(), MFDateGetCurrentMonth(), MFDateGetCurrentDay(), massBalance_SC); printf("\tTotalIn: %f, Local: %f , UpFlux: %f, InStore: %f\n",SCTotalIn,localLoad_SC,preFlux_SC,storeWater_SC); printf("\tDownFlux: %f, discharge; %f, OutStore: %f , storage: %f\n",postFlux_SC,discharge, postStoreWater_SC,waterStorage); } // Debug prints //if ((itemID == 8310)) { //printf("itemID = %d, order %f, Store_SC %f, Store %f Store2 %f StoreDelta %f StorePrev %f StoreSCconc %f \n ",itemID, order, storeWater_SC, waterStorage*86400.,(discharge - dischargePre)*86400.,waterStorageChange*86400.,waterStoragePrev, storeWater_SC / waterStoragePrev ) ; //} //if (postConc_SC < 21.70){ //printf("itemID = %d, order %f, Store_SC %f, Store %f Store2 %f StoreDelta %f StorePrev %f StoreSCconc %f \n ",itemID, order, storeWater_SC, waterStorage*86400.,(discharge - dischargePre)*86400.,waterStorageChange*86400.,waterStoragePrev, storeWater_SC / waterStoragePrev ) ; // printf("itemID %d ro %f bf %f srf %f str %f bfSC %f srfSC %f strSC %f \n",itemID,runoffVol,baseflowVol,runoffpoolreleaseVol,stormflowVol,baseflowConc_SC,stormflowConc_SC,clean_intrcp); //} } // Set Output MFVarSetFloat (_MDOutFlux_SCID, itemID, postFlux_SC); MFVarSetFloat (_MDOutLocalLoadSCID, itemID, localLoad_SC); MFVarSetFloat (_MDOutPostConc_SCID, itemID, postConc_SC); MFVarSetFloat (_MDOutStoreWater_SCID, itemID, postStoreWater_SC); }
static void _MDWTempRiverRoute (int itemID) { float Q; float Q_incoming; float RO_Vol; float RO_WTemp; float QxT_input; float QxT; float QxTnew = 0; float QxTout = 0; float Q_WTemp; float Q_WTemp_new; float StorexT; float StorexT_new; float DeltaStorexT; float SnowPack; //processing variables float channelWidth; float waterStorageChange; float waterStorage; float ResWaterStorageChange = 0; float ResWaterStorage = 0; float solarRad; float windSpeed; float cloudCover; float Tair; float Tequil = 0; float HeatLoss_int = 4396.14; // is intercept assuming no wind and clouds float HeatLoss_slope = 1465.38; // is slope assuming no wind and clouds float deltaT; float ReservoirArea; float ReservoirDepth; float ReservoirVelocity; // conservative mixing variables (parallel to those above_ float QxT_mix; float QxTnew_mix = 0; float QxTout_mix = 0; float Q_WTemp_mix; float StorexT_mix; float StorexT_new_mix; float DeltaStorexT_mix; float QxTRemoval; int day; int month; float resCapacity; //RJS 071511 Reservoir capacity [km3] float QxT_postThermal; //RJS 081311 float QxT_mix_postThermal; //RJS 081311 float Q_WTemp_postThermal; //RJS 081311 float Q_WTemp_mix_postThermal; //RJS 081311 float warmingTemp; //RJS 081311 float wdl_QxT; //RJS 081311 float thermal_wdl; //RJS 081311 float StorexT_postThermal; //RJS 081711 float DeltaStorexT_postThermal; //RJS 081711 float StorexT_mix_postThermal; //RJS 081711 float DeltaStorexT_mix_postThermal; //RJS 081711 float deltaT_postThermal; //RJS 081711 day = MFDateGetCurrentDay(); month = MFDateGetCurrentMonth(); Q = MFVarGetFloat (_MDInDischargeID, itemID, 0.0); Q_incoming = MFVarGetFloat (_MDInDischargeIncomingID, itemID, 0.0); // already includes local runoff RO_Vol = MFVarGetFloat (_MDInRunoffVolumeID, itemID, 0.0); RO_WTemp = MFVarGetFloat (_MDInWTempRiverID, itemID, 0.0); SnowPack = MFVarGetFloat (_MDInSnowPackID, itemID, 0.0); if (_MDInResStorageID != MFUnset){ ResWaterStorageChange = MFVarGetFloat ( _MDInResStorageChangeID, itemID, 0.0) * pow(1000,3); // convert to m3/ ResWaterStorage = MFVarGetFloat ( _MDInResStorageID, itemID, 0.0) * pow(1000,3); // convert to m3 resCapacity = MFVarGetFloat (_MDInResCapacityID, itemID, 0.0); //RJS 071511 } else { ResWaterStorageChange = ResWaterStorage = resCapacity = 0.0; //RJS 071511 } waterStorageChange = MFVarGetFloat ( _MDInRiverStorageChgID, itemID, 0.0); waterStorage = MFVarGetFloat ( _MDInRiverStorageID, itemID, 0.0); channelWidth = MFVarGetFloat ( _MDInRiverWidthID, itemID, 0.0); solarRad = MFVarGetFloat ( _MDInSolarRadID, itemID, 0.0); //MJ/m2/d - CHECK UNITS windSpeed = MFVarGetFloat ( _MDInWindSpeedID, itemID, 0.0); cloudCover = MFVarGetFloat ( _MDInCloudCoverID, itemID, 0.0); Tair = MFVarGetFloat ( _MDInAirTemperatureID, itemID, 0.0); QxT = MFVarGetFloat (_MDFlux_QxTID, itemID, 0.0); StorexT = MFVarGetFloat (_MDStorage_QxTID, itemID, 0.0); QxT_mix = MFVarGetFloat (_MDFluxMixing_QxTID, itemID, 0.0); StorexT_mix = MFVarGetFloat (_MDStorageMixing_QxTID, itemID, 0.0); warmingTemp = MFVarGetFloat (_MDInWarmingTempID, itemID, 0.0); //RJS 072011 wdl_QxT = MFVarGetFloat (_MDInWdl_QxTID, itemID, 0.0); //RJS 072011 thermal_wdl = MFVarGetFloat (_MDInThermalWdlID, itemID, 0.0)* 1000000 / 365 / 86400; //RJS 072011 // if (itemID == 5132){ // printf("Stop itemID %d day %d \n", itemID, MFDateGetCurrentDay()); // } //TODO: combine with reservoir check above - also make reservoir hydraulics generally accessible //TODO: add effect of water withdrawals if(Q < 0.0) Q = 0.0; //RJS 120409 if(Q_incoming < 0.0) Q_incoming = 0.0; //RJS 120409 // if(RO_Vol < 0.0) RO_Vol = 0.0; //RJS 071511 if(resCapacity > 0.0){ waterStorage = waterStorage + ResWaterStorage; waterStorageChange = waterStorageChange + ResWaterStorageChange; ReservoirArea = pow(((ResWaterStorage / pow(10,6)) / 9.208),(1 / 1.114)) * 1000 * 1000; // m2, from Takeuchi 1997 - original equation has V in 10^6 m3 and A in km2 ReservoirDepth = (ResWaterStorage / ReservoirArea); //m ReservoirVelocity = Q / (ReservoirArea); // m/s channelWidth = MDMaximum(channelWidth, (Q / (ReservoirDepth * ReservoirVelocity))); // m QxT_input = RO_Vol * RO_WTemp * 86400.0; //RJS 071511 //m3*degC/d QxTnew = QxT + QxT_input + StorexT; //RJS 071511 //m3*degC/d QxTnew_mix = QxT_mix + QxT_input + StorexT_mix; //RJS 071511 if (Q_incoming > 0.000001) { Q_WTemp = QxTnew / ((Q_incoming) * 86400 + (waterStorage - waterStorageChange)); //RJS 071511 //degC Q_WTemp_mix = QxTnew_mix / ((Q_incoming) * 86400 + (waterStorage - waterStorageChange)); //RJS 071511 //degC // if (itemID == 25014) printf("Q_incoming > 0.000001\n"); } else { if (waterStorage > 0) { Q_WTemp = StorexT / waterStorage; // RJS 071511 //degC Q_WTemp_mix = StorexT_mix / waterStorage; // RJS 071511 //degC // if (itemID == 25014) printf("waterStorage > 0\n"); } else { Q_WTemp = 0.0; //RJS 071511 Q_WTemp_mix = 0.0; //RJS 071511 // if (itemID == 25014) printf("else\n"); } } Q_WTemp_new = Q_WTemp; //RJS 071511 StorexT_new = waterStorage * Q_WTemp_new; //RJS 071511 //m3*degC DeltaStorexT = StorexT_new - StorexT; //RJS 071511 QxTout = Q * 86400.0 * Q_WTemp_new ; //RJS 071511 //m3*degC/d QxTRemoval = QxTnew - (StorexT_new + QxTout); //RJS 071511 //m3*degC/d StorexT_new_mix = waterStorage * Q_WTemp_mix; //RJS 071511 //m3*degC DeltaStorexT_mix = StorexT_new_mix - StorexT_mix; //RJS 071511 QxTout_mix = Q * 86400.0 * Q_WTemp_mix; //RJS 071511 //m3*degC/s // if (itemID == 5033) printf("m = %d, d = %d, itemID = %d, QxTout = %f, QxTout_mix = %f, Q = %f, Q_WTemp_new = %f\n", MFDateGetCurrentMonth (), MFDateGetCurrentDay (), itemID, QxTout, QxTout_mix, Q, Q_WTemp_new); // if (itemID == 4704) printf("m = %d, d = %d, itemID = %d, QxTout = %f, QxTout_mix = %f, Q = %f, Q_WTemp_new = %f\n", MFDateGetCurrentMonth (), MFDateGetCurrentDay (), itemID, QxTout, QxTout_mix, Q, Q_WTemp_new); //New experimental QxT_postThermal = thermal_wdl > Q ? 86400 * Q * (Q_WTemp_new + warmingTemp) : 86400 * ((thermal_wdl * (Q_WTemp_new + warmingTemp)) + ((Q - thermal_wdl) * Q_WTemp_new)); QxT_mix_postThermal = thermal_wdl > Q ? 86400 * Q * (Q_WTemp_mix + warmingTemp) : 86400 * ((thermal_wdl * (Q_WTemp_mix + warmingTemp)) + ((Q - thermal_wdl) * Q_WTemp_mix)); Q_WTemp_postThermal = Q > 0.000001 ? QxT_postThermal / (Q * 86400) : 0.0; Q_WTemp_mix_postThermal = Q > 0.000001 ? QxT_mix_postThermal / (Q * 86400) : 0.0; StorexT_postThermal = waterStorage * Q_WTemp_postThermal; DeltaStorexT_postThermal = StorexT_postThermal - StorexT; StorexT_mix_postThermal = waterStorage * Q_WTemp_mix_postThermal; DeltaStorexT_mix_postThermal = StorexT_mix_postThermal - StorexT_mix; deltaT_postThermal = Q_WTemp_postThermal - Q_WTemp; // if (itemID == 5033) printf("QxT_pt = %f, Q_WTemp_pt = %f\n", QxT_postThermal, Q_WTemp_postThermal); //if (itemID == 4704) printf("QxT_pt = %f, Q_WTemp_pt = %f\n", QxT_postThermal, Q_WTemp_postThermal); //end MFVarSetFloat(_MDLocalIn_QxTID, itemID, QxT_input); // MFVarSetFloat(_MDRemoval_QxTID, itemID, QxTRemoval); // MFVarSetFloat(_MDFlux_QxTID, itemID, QxTout); MFVarSetFloat(_MDFlux_QxTID, itemID, QxT_postThermal); //RJS new // MFVarSetFloat(_MDStorage_QxTID, itemID, StorexT_new); MFVarSetFloat(_MDStorage_QxTID, itemID, StorexT_postThermal); //RJS new // MFVarSetFloat(_MDDeltaStorage_QxTID, itemID, DeltaStorexT); MFVarSetFloat(_MDDeltaStorage_QxTID, itemID, DeltaStorexT_postThermal); //RJS new // MFVarSetFloat(_MDWTemp_QxTID, itemID, Q_WTemp_new); MFVarSetFloat(_MDWTemp_QxTID, itemID, Q_WTemp_postThermal); //RJS new // MFVarSetFloat(_MDWTempDeltaT_QxTID, itemID, deltaT); // MFVarSetFloat(_MDWTempDeltaT_QxTID, itemID, deltaT_postThermal); //RJS new // MFVarSetFloat(_MDFluxMixing_QxTID, itemID, QxTout_mix); MFVarSetFloat(_MDFluxMixing_QxTID, itemID, QxT_mix_postThermal); //RJS new // MFVarSetFloat(_MDStorageMixing_QxTID, itemID, StorexT_new_mix); MFVarSetFloat(_MDStorageMixing_QxTID, itemID, StorexT_mix_postThermal); //RJS new // MFVarSetFloat(_MDDeltaStorageMixing_QxTID, itemID, DeltaStorexT_mix); MFVarSetFloat(_MDDeltaStorageMixing_QxTID, itemID, DeltaStorexT_mix_postThermal); //RJS new // MFVarSetFloat(_MDWTempMixing_QxTID, itemID, Q_WTemp_mix); MFVarSetFloat(_MDWTempMixing_QxTID, itemID, Q_WTemp_mix_postThermal); //RJS new // MFVarSetFloat(_MDLocalIn_QxTID, itemID, QxT_input); //RJS 071511 //// MFVarSetFloat(_MDRemoval_QxTID, itemID, QxTRemoval); //RJS 071511 // MFVarSetFloat(_MDFlux_QxTID, itemID, QxTout); //RJS 071511 // MFVarSetFloat(_MDStorage_QxTID, itemID, StorexT_new); //RJS 071511 // MFVarSetFloat(_MDDeltaStorage_QxTID, itemID, DeltaStorexT); //RJS 071511 // MFVarSetFloat(_MDWTemp_QxTID, itemID, Q_WTemp_new); //RJS 071511 //// MFVarSetFloat(_MDWTempDeltaT_QxTID, itemID, deltaT); //RJS 071511 // MFVarSetFloat(_MDFluxMixing_QxTID, itemID, QxTout_mix); //RJS 071511 // MFVarSetFloat(_MDStorageMixing_QxTID, itemID, StorexT_new_mix); //RJS 071511 // MFVarSetFloat(_MDDeltaStorageMixing_QxTID, itemID, DeltaStorexT_mix); //RJS 071511 // MFVarSetFloat(_MDWTempMixing_QxTID, itemID, Q_WTemp_mix); //RJS 071511 } else{ ReservoirArea = 0.0; ReservoirVelocity = 0.0; ReservoirDepth = 0.0; // } = %f //RJS commented out 071511 //TODO: RO_Vol has been set to never be less than 0 in MDWRunoff QxT_input = RO_Vol * RO_WTemp * 86400.0; //m3*degC/d //if (itemID == 188 && month == 5 && day == 1){ // printf("Stop: Q %f RO_Vol %f QxT %f QxT_input %f \n", Q, RO_Vol, QxT, QxT_input); //} //note: calculation for input concentration is changed from previous iterations // to use incoming Q. Also use WaterStorage from previous time step/ // TODO: Need to include a variable that accounts for losses due to discharge disappearing (Drying) // TODO: Make all these changes for other bgc flux models // Q_incoming includes local runoff!!! if((Q_incoming) > 0.000001) { //do not include water storage in this check - will screw up mixing estimates QxTnew = QxT + QxT_input + StorexT; //m3*degC/d QxTnew_mix = QxT_mix + QxT_input + StorexT_mix; Q_WTemp = QxTnew / ((Q_incoming) * 86400 + (waterStorage - waterStorageChange)); //degC Q_WTemp_mix = QxTnew_mix / ((Q_incoming) * 86400 + (waterStorage - waterStorageChange)); //degC ///Temperature Processing using Dingman 1972 if (cloudCover < 95){ // clear skies, assume cloud cover < 95% convertcalories / cm2 /d to kJ/m2/d HeatLoss_int = (105 + 23 * windSpeed) * 4.1868 / 1000 * 100 * 100; // kJ/m2/d HeatLoss_slope = (35 + 4.2 * windSpeed) * 4.1868 / 1000 * 100 * 100;// kJ/m2/d/degC } else{ // cloudy skies, assume cloud cover > 95% HeatLoss_int = (-73 + 9.1 * windSpeed) * 4.1868 / 1000 * 100 * 100; HeatLoss_slope = (37 + 4.6 * windSpeed) * 4.1868 / 1000 * 100 * 100; } Tequil = Tair + (((solarRad * 1000) - HeatLoss_int) / HeatLoss_slope); //solar rad converted from MJ to kJ/m2/d // use exponential form //TODO channelWidth can equal 0 when waterStorage > 0.0, so need to check here // Apply model only to large enough discharges, otherwise assume temperature equils equilibrium // if (channelWidth > 0 && Q > 0.001){ if (channelWidth > 0){ Q_WTemp_new = MDMaximum(0, (((Q_WTemp - Tequil) * exp((-HeatLoss_slope * MFModelGetLength(itemID)) / (999.73 * 4.1922 * (Q * 86400.0 / channelWidth)))) + Tequil)); } else { Q_WTemp_new = MDMaximum(0, Tequil); } //if cell has reservoir, assume reservoir exchange dominates //if(ResWaterStorage > 0){ // Q_WTemp_new = MDMaximum(0, (((Q_WTemp - Tequil) * exp((-HeatLoss_slope * ReservoirArea) / (999.73 * 4.1922 * (Q * 86400.0)))) + Tequil)); //} deltaT = Q_WTemp_new - Q_WTemp; //if (Q_WTemp_new > 50){ // if (Q_WTemp_mix > 30){ // printf("Toggle"); // printf("Stop WaterTemp > 50 itemID %d XCoord %f YCoord %f month %d day %d Q %f Q_incoming %f waterStorage %f " // "RO_Vol %f RO_WTemp %f QxT %f QxT_mix %f StorexT %f Storext_mix %f QxT_input %f QxTnew %f Q_WTemp %f Q_WTemp_mix %f Q_WTemp_new %f Tequil %f \n", // itemID, MFModelGetXCoord(itemID),MFModelGetYCoord(itemID), month, day, Q, Q_incoming, waterStorage, // RO_Vol, RO_WTemp, QxT, QxT_mix, StorexT, StorexT_mix, QxT_input, QxTnew, Q_WTemp, Q_WTemp_mix, Q_WTemp_new, Tequil); // } StorexT_new = waterStorage * Q_WTemp_new; //m3*degC DeltaStorexT = StorexT_new - StorexT; // QxTout = Q * 86400.0 * Q_WTemp_new ; //m3*degC/d QxTRemoval = QxTnew - (StorexT_new + QxTout); //m3*degC/d StorexT_new_mix = waterStorage * Q_WTemp_mix; //m3*degC DeltaStorexT_mix = StorexT_new_mix - StorexT_mix; QxTout_mix = Q * 86400.0 * Q_WTemp_mix; //m3*degC/s // if (itemID == 5033) printf("m = %d, d = %d, itemID = %d, QxTout = %f, QxTout_mix = %f, Q = %f, Q_WTemp_new = %f\n", MFDateGetCurrentMonth (), MFDateGetCurrentDay (), itemID, QxTout, QxTout_mix, Q, Q_WTemp_new); // if (itemID == 4704) printf("m = %d, d = %d, itemID = %d, QxTout = %f, QxTout_mix = %f, Q = %f, Q_WTemp_new = %f\n", MFDateGetCurrentMonth (), MFDateGetCurrentDay (), itemID, QxTout, QxTout_mix, Q, Q_WTemp_new); // if (QxT_input > 1000) printf("m = %d, d = %d, itemID = %d, QxT_input = %f, RO_Vol = %f, RO_WTemp = %f, QxT = %f, QxT_mix = %f\n, QxTout = %f, QxTout_mix = %f, Q = %f\n", MFDateGetCurrentMonth (), MFDateGetCurrentDay (), itemID, QxT_input, RO_Vol, RO_WTemp, QxT, QxT_mix, QxTout, QxTout_mix, Q); // if (Q_WTemp_new > 50) printf("m = %d, d = %d, itemID = %d, QxT_input = %f, RO_Vol = %f, RO_WTemp = %f\n channelWidth = %f, Q_WTemp = %f, Q_WTemp_new = %f, Q_WTemp_mix = %f, Tair = %f, Q = %f, Q_incoming = %f\n", MFDateGetCurrentMonth (), MFDateGetCurrentDay (), itemID, QxT_input, RO_Vol, RO_WTemp, channelWidth, Q_WTemp, Q_WTemp_new, Q_WTemp_mix, Tair, Q, Q_incoming); //New experimental QxT_postThermal = thermal_wdl > Q ? 86400 * Q * (Q_WTemp_new + warmingTemp) : 86400 * ((thermal_wdl * (Q_WTemp_new + warmingTemp)) + ((Q - thermal_wdl) * Q_WTemp_new)); QxT_mix_postThermal = thermal_wdl > Q ? 86400 * Q * (Q_WTemp_mix + warmingTemp) : 86400 * ((thermal_wdl * (Q_WTemp_mix + warmingTemp)) + ((Q - thermal_wdl) * Q_WTemp_mix)); Q_WTemp_postThermal = Q > 0.000001 ? QxT_postThermal / (Q * 86400) : 0.0; Q_WTemp_mix_postThermal = Q > 0.000001 ? QxT_mix_postThermal / (Q * 86400) : 0.0; StorexT_postThermal = waterStorage * Q_WTemp_postThermal; DeltaStorexT_postThermal = StorexT_postThermal - StorexT; StorexT_mix_postThermal = waterStorage * Q_WTemp_mix_postThermal; DeltaStorexT_mix_postThermal = StorexT_mix_postThermal - StorexT_mix; deltaT_postThermal = Q_WTemp_postThermal - Q_WTemp; // if (itemID == 5033) printf("QxT_pt = %f, Q_WTemp_pt = %f\n", QxT_postThermal, Q_WTemp_postThermal); //if (itemID == 4704) printf("QxT_pt = %f, Q_WTemp_pt = %f\n", QxT_postThermal, Q_WTemp_postThermal); //end MFVarSetFloat(_MDLocalIn_QxTID, itemID, QxT_input); MFVarSetFloat(_MDRemoval_QxTID, itemID, QxTRemoval); // MFVarSetFloat(_MDFlux_QxTID, itemID, QxTout); MFVarSetFloat(_MDFlux_QxTID, itemID, QxT_postThermal); //RJS new // MFVarSetFloat(_MDStorage_QxTID, itemID, StorexT_new); MFVarSetFloat(_MDStorage_QxTID, itemID, StorexT_postThermal); //RJS new // MFVarSetFloat(_MDDeltaStorage_QxTID, itemID, DeltaStorexT); MFVarSetFloat(_MDDeltaStorage_QxTID, itemID, DeltaStorexT_postThermal); //RJS new // MFVarSetFloat(_MDWTemp_QxTID, itemID, Q_WTemp_new); MFVarSetFloat(_MDWTemp_QxTID, itemID, Q_WTemp_postThermal); //RJS new // MFVarSetFloat(_MDWTempDeltaT_QxTID, itemID, deltaT); MFVarSetFloat(_MDWTempDeltaT_QxTID, itemID, deltaT_postThermal); //RJS new // MFVarSetFloat(_MDFluxMixing_QxTID, itemID, QxTout_mix); MFVarSetFloat(_MDFluxMixing_QxTID, itemID, QxT_mix_postThermal); //RJS new // MFVarSetFloat(_MDStorageMixing_QxTID, itemID, StorexT_new_mix); MFVarSetFloat(_MDStorageMixing_QxTID, itemID, StorexT_mix_postThermal); //RJS new // MFVarSetFloat(_MDDeltaStorageMixing_QxTID, itemID, DeltaStorexT_mix); MFVarSetFloat(_MDDeltaStorageMixing_QxTID, itemID, DeltaStorexT_mix_postThermal); //RJS new // MFVarSetFloat(_MDWTempMixing_QxTID, itemID, Q_WTemp_mix); MFVarSetFloat(_MDWTempMixing_QxTID, itemID, Q_WTemp_mix_postThermal); //RJS new } else{ if (waterStorage > 0){ QxTnew = QxT_input + StorexT; //m3*degC QxTnew_mix = QxT_input + StorexT_mix; } else{ QxTnew = 0; QxTnew_mix = 0; } StorexT_new = 0.0; //m3*degC DeltaStorexT = StorexT_new - StorexT; // QxTout = 0.0; //m3*degC/dStorexT_new_mix = 0; //m3*degC QxTRemoval = 0.0; //m3*degC/d StorexT_new_mix = 0.0; //m3*degC DeltaStorexT_mix = StorexT_new_mix - StorexT_mix; QxTout_mix = 0.0; //m3*degC/s // printf("m = %d, d = %d, itemID = %d, QxT_input = %f, RO_Vol = %f, RO_WTemp = %f\n Q_WTemp = %f, Q_WTemp_new = %f, Q_WTemp_mix = %f, Q = %f, Q_incoming = %f\n", MFDateGetCurrentMonth (), MFDateGetCurrentDay (), itemID, QxT_input, RO_Vol, RO_WTemp, Q_WTemp, Q_WTemp_new, Q_WTemp_mix, Q, Q_incoming); MFVarSetFloat(_MDLocalIn_QxTID, itemID, 0.0); MFVarSetFloat(_MDRemoval_QxTID, itemID, QxTRemoval); MFVarSetFloat(_MDFlux_QxTID, itemID, QxTout); MFVarSetFloat(_MDStorage_QxTID, itemID, StorexT_new); MFVarSetFloat(_MDDeltaStorage_QxTID, itemID, DeltaStorexT); MFVarSetFloat(_MDFluxMixing_QxTID, itemID, QxTout_mix); MFVarSetFloat(_MDStorageMixing_QxTID, itemID, StorexT_new_mix); MFVarSetFloat(_MDDeltaStorageMixing_QxTID, itemID, DeltaStorexT_mix); MFVarSetMissingVal(_MDWTemp_QxTID, itemID); MFVarSetMissingVal(_MDWTempDeltaT_QxTID, itemID); MFVarSetMissingVal(_MDWTempMixing_QxTID, itemID); } float mb; float mbmix; mb = QxT_input + QxT - QxTRemoval - QxTout - DeltaStorexT; mbmix = (QxT_input + QxT_mix - QxTout_mix - DeltaStorexT_mix); } //RJS 071511 //if (mbmix > 100000){ //printf("mass balance = mb %f mbmix %f \n", mb, mbmix); //} // if (itemID == 25014) printf("Q_WTemp_new = %f, QxTnew = %f, Q_incoming = %f, Q_m3 = %f, waterStorage = %f, waterStorageChange = %f, \n", Q_WTemp_new, QxTnew, Q_incoming, Q_incoming * 86400, waterStorage, waterStorageChange); // if (itemID == 25014) printf("T_river = %f, T_runoff = %f, T_storage = %f\n", QxT/Q_incoming, RO_WTemp, StorexT/(waterStorage - waterStorageChange)); // if (itemID == 25014) printf("*** m = %d, d = %d, resCapacity = %f, waterStorage = %f, waterStorageChange = %f\n", MFDateGetCurrentMonth(), MFDateGetCurrentDay(), resCapacity, waterStorage, waterStorageChange); // if (itemID == 25014) printf("Q_incoming = %f, Q = %f, RO_vol = %f\n", Q_incoming, Q, RO_Vol); // if (itemID == 25014) printf("m = %d, d = %d, m3 degC: QxT = %f, StorexT = %f, QxT_input = %f\n", MFDateGetCurrentMonth(), MFDateGetCurrentDay(), QxT, StorexT, QxT_input); // if (itemID == 25014) printf("volume: Q_incoming = %f, waterStorage - change = %f, RO_Vol = %f\n", Q_incoming * 86400, waterStorage - waterStorageChange, RO_Vol * 86400); // if (itemID == 25014) printf("flux = %f, storage = %f, RO_WTemp = %f\n", QxT / (Q_incoming * 86400), StorexT / (waterStorage - waterStorageChange), RO_WTemp); // if (itemID == 5033) printf("END: itemID = %d, m = %d, d= %d, Q = %f, QxT_pt = %f, Q_WTemp_pt = %f, QxTout = %f, \n", itemID, MFDateGetCurrentMonth(), MFDateGetCurrentDay(), Q, QxT_postThermal, Q_WTemp_postThermal, QxTout); // if (itemID == 4704) printf("END: itemID = %d, m = %d, d= %d, Q = %f, QxT_pt = %f, Q_WTemp_pt = %f, QxTout = %f, \n", itemID, MFDateGetCurrentMonth(), MFDateGetCurrentDay(), Q, QxT_postThermal, Q_WTemp_postThermal, QxTout); }
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 _MDWaterBalance(int itemID) { // Input float precip = MFVarGetFloat(_MDInPrecipID, itemID, 0.0); float etp = MFVarGetFloat(_MDInEvaptrsID, itemID, 0.0); float pet = MFVarGetFloat(_MDInPetID, 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 runoffPool = MFVarGetFloat(_MDInRunoffPoolID, itemID, 0.0); float runoffPoolRecharge = MFVarGetFloat(_MDInRunoffPoolRechargeID, itemID, 0.0); float runoffPoolRelease = MFVarGetFloat(_MDInRunoffPoolReleaseID, itemID, 0.0); float awCap = MFVarGetFloat(_MDInSoilAvailWaterCapID, itemID, 0.0); float h2oAreaFrac = MFVarGetFloat(_MDInH2OFractionID, itemID, 0.0); float impAreaFrac = MFVarGetFloat(_MDInImpFractionID, itemID, 0.0); float snowfall = MFVarGetFloat(_MDInSnowFallID, itemID, 0.0); float snowmelt = MFVarGetFloat(_MDInSnowMeltID, itemID, 0.0); float snowpack = MFVarGetFloat(_MDInSnowPackID, itemID, 0.0); float stormRunoffImp = MFVarGetFloat(_MDInStormRunoffImpID, itemID, 0.0); float stormRunoffH2O = MFVarGetFloat(_MDInStormRunoffH2OID, itemID, 0.0); float stormRunoffTotal = MFVarGetFloat(_MDInStormRunoffTotalID, itemID, 0.0); float precipPerv = MFVarGetFloat(_MDInPrecipPervID, itemID, 0.0); float runoffToPerv = MFVarGetFloat(_MDInRunofftoPervID, itemID, 0.0); float soilMoist = MFVarGetFloat(_MDInSoilMoistID, itemID, 0.0); float soilMoistNotScaled = MFVarGetFloat(_MDInSoilMoistNotScaledID, itemID, 0.0); float etpNotScaled = MFVarGetFloat(_MDInEvaptrsNotScaledID, itemID, 0.0); float excess = MFVarGetFloat(_MDInExcessID, itemID, 0.0); float excessNotScaled = MFVarGetFloat(_MDInExcessNotScaledID, itemID, 0.0); float soilMoistChgNotScaled = MFVarGetFloat(_MDInSoilMoistChgNotScaledID, itemID, 0.0); float surplus = MFVarGetFloat(_MDInRainWaterSurplusID, itemID, 0.0); float surfRunoff = MFVarGetFloat(_MDInRainSurfRunoffID, itemID, 0.0); float infiltration = MFVarGetFloat(_MDInRainInfiltrationID, itemID, 0.0); float grdWater = MFVarGetFloat(_MDInGrdWatID, itemID, 0.0); float grdWaterRecharge = MFVarGetFloat(_MDInGrdWatRechargeID, itemID, 0.0); float baseFlow = MFVarGetFloat(_MDInBaseFlowID, itemID, 0.0); float totalSurfRunoff = MFVarGetFloat(_MDInTotalSurfRunoffID, itemID, 0.0); float runoffVol = MFVarGetFloat (_MDInRunoffVolumeID, itemID, 0.0); float QPre = MFVarGetFloat (_MDInQPreID, itemID, 0.0); float QOut = MFVarGetFloat (_MDInQOutID, itemID, 0.0); float QCur = MFVarGetFloat (_MDInQCurID, itemID, 0.0); float storage = MFVarGetFloat (_MDInRiverStorageID, itemID, 0.0); float C0; float C1; float C2; if (_MDInMuskingumC0ID != MFUnset) { C0 = MFVarGetFloat (_MDInMuskingumC0ID, itemID, 1.0); C1 = MFVarGetFloat (_MDInMuskingumC1ID, itemID, 0.0); C2 = MFVarGetFloat (_MDInMuskingumC2ID, itemID, 0.0); } else if (_MDInCascadeC0ID != MFUnset) { C0 = MFVarGetFloat (_MDInCascadeC0ID, itemID, 1.0); C1 = 0.0; C2 = 1.-C0; } else { C0 = 1.0; C1 = 0.0; C2 = 0.0; } float discharge = MFVarGetFloat (_MDInDischargeID, itemID, 0.0); float storageChg = MFVarGetFloat (_MDInRiverStorChgID, itemID, 0.0); float QOut_initial = MFVarGetFloat (_MDInDischRJSID, itemID, 0.0); float propStW_RO = MFVarGetFloat (_MDInPropROStormWaterID, itemID, 0.0); float propSuW_RO = MFVarGetFloat (_MDInPropROSurfaceWaterID, itemID, 0.0); float propGrW_RO = MFVarGetFloat (_MDInPropROGroundWaterID, itemID, 0.0); float propStW_Qin = MFVarGetFloat (_MDInPropQinStormWaterID, itemID, 0.0); float propSuW_Qin = MFVarGetFloat (_MDInPropQinSurfaceWaterID, itemID, 0.0); float propGrW_Qin = MFVarGetFloat (_MDInPropQinGroundWaterID, itemID, 0.0); float propStW_RSin = MFVarGetFloat (_MDInPropRSinStormWaterID, itemID, 0.0); float propSuW_RSin = MFVarGetFloat (_MDInPropRSinSurfaceWaterID, itemID, 0.0); float propGrW_RSin = MFVarGetFloat (_MDInPropRSinGroundWaterID, itemID, 0.0); float StW_Qout = MFVarGetFloat (_MDInQStormWaterID, itemID, 0.0); float SuW_Qout = MFVarGetFloat (_MDInQSurfaceWaterID, itemID, 0.0); float GrW_Qout = MFVarGetFloat (_MDInQGroundWaterID, itemID, 0.0); float propStW_RSout = MFVarGetFloat (_MDInPropRSStormWaterID, itemID, 0.0); float propSuW_RSout = MFVarGetFloat (_MDInPropRSSurfaceWaterID, itemID, 0.0); float propGrW_RSout = MFVarGetFloat (_MDInPropRSGroundWaterID, itemID, 0.0); float propFlag_RO = MFVarGetFloat (_MDInPropROFlagID, itemID, 0.0); float propFlag_Qin = MFVarGetFloat (_MDInPropQinFlagID, itemID, 0.0); float propFlag_RSin = MFVarGetFloat (_MDInPropRSinFlagID, itemID, 0.0); float Flag_Qout = MFVarGetFloat (_MDInQFlagID, itemID, 0.0); float propFlag_RSout = MFVarGetFloat (_MDInPropRSFlagID, 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; float balance2b; 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); balance2b = (precip + irrUptakeRiver + irrUptakeExcess - (etp + runoff + grdWaterChg + snowPackChg + soilMoistChg + smallResStorageChg + runoffPoolChg)) / (etp + runoff + grdWaterChg + snowPackChg + soilMoistChg + smallResStorageChg + runoffPoolChg); 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 (MFDateGetCurrentYear() >= 2000) { // if ((itemID == 1063) || (itemID == 1063)) { if (fabs (balance2) > 0.0001 ) { // printf ("TIEM %i %d %d %d WaterBalance! %f precip %f etp = %f runoff = %f grdWaterChg = %f snowPackChg = %f soilMoistChg = %f runoffPoolChg %f\n runoffPool = %f, runoffPoolRecharge = %f, runoffPoolRelease = %f\n", itemID, MFDateGetCurrentMonth(), MFDateGetCurrentDay(), MFDateGetCurrentYear(), balance2,precip,etp,runoff,grdWaterChg,snowPackChg,soilMoistChg,runoffPoolChg,runoffPool, runoffPoolRecharge, runoffPoolRelease); printf ("%i, %d, %d, %d, %f, %f, %f, %f, %f, %f,", itemID, MFDateGetCurrentYear(), MFDateGetCurrentMonth(), MFDateGetCurrentDay(), balance2b, balance2, awCap, impAreaFrac, h2oAreaFrac, precip); printf ("%f, %f, %f, %f,", snowPackChg, snowfall, snowmelt, snowpack); printf ("%f, %f, %f, %f, %f,", stormRunoffImp, stormRunoffH2O, stormRunoffTotal, precipPerv, runoffToPerv); printf ("%f, %f, %f, %f, %f, %f, %f, %f, %f,", soilMoistChg, soilMoistChgNotScaled, soilMoist, soilMoistNotScaled, pet, etp, etpNotScaled, excess, excessNotScaled); printf ("%f, %f, %f,", surplus, surfRunoff, infiltration); printf ("%f, %f, %f, %f,", grdWater, grdWaterChg, grdWaterRecharge, baseFlow); printf ("%f, %f, %f, %f,", runoffPool, runoffPoolChg, runoffPoolRecharge, runoffPoolRelease); printf ("%f, %f,", totalSurfRunoff, runoff); printf ("%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f,", C0, C1, C2, runoffVol, discharge, QPre, QCur, QOut_initial, QOut, storage, storageChg); printf ("%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f,", propStW_RO, propSuW_RO, propGrW_RO, propStW_Qin, propSuW_Qin, propGrW_Qin, propStW_RSin, propSuW_RSin, propGrW_RSin, StW_Qout, SuW_Qout, GrW_Qout, propStW_RSout, propSuW_RSout, propGrW_RSout, propFlag_RO, propFlag_Qin, propFlag_RSin, Flag_Qout, propFlag_RSout); } // } MFVarSetFloat (_MDOutWaterBalanceID, itemID , balance); }
static void _MDRiverGPP (int itemID) { float channelWidth; //GPP drivers/parameters float par2bottom; //MJ / m2 /d float DIN = 1; //mg/l float DIP = 0.05; //mg/l float Ks_N = 0.1; float Ks_P = 0.01; float Km = 0.01; // algal mortality d-1 float Ks = 0.01; // algal sloughing d-1 float Ben_C2CHL = 50; //Benthic Carbon variables float uEinsteinperm2stoWattperm2 = 0.2174; //see websitehttp://www.seabird.com/application_notes/AN11General.htm based on Morel and Smith 1974, valid for sun altitudes > 22 degrees float daylength = 12; //hours of light per day needed to convert daily par to per second float Ed; float Ek = 100; // PAR in microEinsteins / m2/s at onset of saturation - in Table 10.1 of Kirk, ueinsteins / m2 / s float Ben_GPPmax; //g C / h / g chl at light saturation float Ben_GPP; // g C / m2 /d float Ben_MORTALITY; float Ben_Ra; float Ben_NPP; float Ben_AlgaeC; float Ben_AlgaeCHL; float Ben_AlgaeC_REACH; float Ben_GPP_REACH; float Ben_Ra_REACH; float Ben_NPP_REACH; float Ben_Mortality_REACH; float day; day = MFDateGetCurrentDay(); float month; month = MFDateGetCurrentMonth(); channelWidth = MFVarGetFloat ( _MDInRiverWidthID, itemID, 0.0); par2bottom = MFVarGetFloat ( _MDInPAR2BottomID, itemID, 0.0); Ben_AlgaeCHL = MFVarGetFloat ( _MDBenthicAlgaeCHLID, itemID, 0.0); // g Chl / m2 Ben_AlgaeC = MFVarGetFloat ( _MDBenthicAlgaeCID, itemID, 0.0); // g C / m2 //TODO: How to get Chl spun up - uptake depends on CHL, but CHL starts at 0. The following is a place holder: Ben_AlgaeC = ((day == 1 && Ben_AlgaeC == 0.0) ? 0.1 : Ben_AlgaeC); Ben_AlgaeCHL = ((day == 1 && Ben_AlgaeC == 0.0) ? 0.1 * Ben_C2CHL : Ben_AlgaeCHL); Ed = (par2bottom / (daylength * 60 * 60)) * pow(10,6) * 1 * (1 / uEinsteinperm2stoWattperm2); // uEinsteins / m2 / s, average for day assuming daylight hours and converted from radiation units of MJ/m2/d Ben_GPPmax = MDMaximum(0.0, MDMaximum(1, (3.7 - (0.1 * Ben_AlgaeCHL)))); //g C / hr / g chl at light saturation Ryther and Yentsch 1957, but add a self shading control //refs for the eqn Ryther and Yentsch 1957; Kirk 1994 (EQN 10.4) Ben_GPP = Ben_AlgaeCHL * Ben_GPPmax * daylength * DIN / (DIN + Ks_N) * DIP / (DIP + Ks_P) * (1 - exp(-Ed / Ek)); //g C / m2 / d // N limitation P limitation decay from light saturation float Ben_RespRate = 0.1; //d-1 Ben_Ra = MDMinimum(Ben_AlgaeC * 0.9, Ben_AlgaeC * Ben_RespRate); // g C / m2 / day autotrophic respiration Ks = 0.05 + 0.01 * (Ben_AlgaeC + Ben_GPP - Ben_Ra); Ben_MORTALITY = MDMinimum((Ben_AlgaeC - Ben_Ra), (Ben_AlgaeC - Ben_Ra) * (Km + Ks)); //gC / m2 / day; Ben_NPP = Ben_GPP - Ben_Ra; Ben_AlgaeC = Ben_AlgaeC + Ben_GPP - Ben_MORTALITY - Ben_Ra ; // g C / m2 / day Ben_AlgaeCHL = Ben_AlgaeC / Ben_C2CHL; //g Chl / m2 //if (par2bottom > 0.0){ if (itemID == 175){ printf("itemID %d month %f day %f par2bottom %f Ed %f Ben_GPP %f Ben_Ra %f Ben_NPP %f Ben_Mortality %f Ben_AlgaeC %f Ben_AlgaeCHL %f \n", itemID, month, day, par2bottom, Ed, Ben_GPP, Ben_Ra, Ben_NPP, Ben_MORTALITY, Ben_AlgaeC, Ben_AlgaeCHL ); } Ben_AlgaeC_REACH = Ben_AlgaeC * channelWidth * MFModelGetLength(itemID); Ben_GPP_REACH = Ben_GPP * channelWidth * MFModelGetLength(itemID); Ben_Ra_REACH = Ben_Ra * channelWidth * MFModelGetLength(itemID); Ben_NPP_REACH = Ben_NPP * channelWidth * MFModelGetLength(itemID); Ben_Mortality_REACH = Ben_MORTALITY * channelWidth * MFModelGetLength(itemID); MFVarSetFloat(_MDBenthicAlgaeCHLID, itemID, Ben_AlgaeCHL); MFVarSetFloat(_MDBenthicAlgaeCID, itemID, Ben_AlgaeC); MFVarSetFloat(_MDBenthicGPPID, itemID, Ben_GPP); MFVarSetFloat(_MDBenthicRaID, itemID, Ben_Ra); MFVarSetFloat(_MDBenthicNPPID, itemID, Ben_NPP); MFVarSetFloat(_MDBenthicMortalityID, itemID, Ben_MORTALITY); MFVarSetFloat(_MDBenthicAlgaeC_REACHID, itemID, Ben_AlgaeC_REACH); MFVarSetFloat(_MDBenthicGPP_REACHID, itemID, Ben_GPP_REACH); MFVarSetFloat(_MDBenthicRa_REACHID, itemID, Ben_Ra_REACH); MFVarSetFloat(_MDBenthicNPP_REACHID, itemID, Ben_NPP_REACH); MFVarSetFloat(_MDBenthicMortality_REACHID, itemID, Ben_Mortality_REACH); }
static void _MDDO2 (int itemID) { // establishing local variables int day = 0; // day of month int month = 0; // month of year int year = 0; // year float Q_in = 0.0; // incoming discharge (m3/s) includes runoff float Q_out = 0.0; // outgoing discharge (m3/s) float Runoff = 0.0; // local grid cell runoff (mm/d) float RunoffVolume = 0.0; // local grid cell runoff (m3/s) float RiverTemp = 0.0; // River temperature (deg C) float do2_RO_conc = 0.0; // concentration of do2 in runoff (mg/L) float do2_RO_mass = 0.0; // mass of do2 in runoff (kg/d) float do2_Riv_conc_in = 0.0; // do2 oncentration of incoming river discharge (mg/l) float do2_Riv_mass_in = 0.0; // do2 mass in incoming river discharge (kg/d) float do2_Riv_conc_out = 0.0; // do2 concentration leaving in discharge (mg/L) float do2_Riv_mass_out = 0.0; // o2 mmass leaving in river grid cell (kg/d) float do2_Riv_mass_removed = 0.0; //(kg/d) float do2_Riv_mass_added = 0.0; //(kg/d) float do2_RivStor_mass_pre = 0.0; // mass of do2 remaining from yesterday in local river (kg/d) float do2_RivStor_mass_post = 0.0; // mass of do2 to remain in river until tomorrow float do2_RivStor_conc_pre = 0.0; float do2_RivStor_conc_post = 0.0; float water_RivStor_pre = 0.0; // volume of water remaining from yesterday in river grid cell (m3/d) float water_RivStor_post = 0.0; // volume of water that remains in grid cell until tomorrow (m3/d) float water_RivStor_chg = 0.0; // change in volume of water stored in river over current time step float do2_Riv_mass_total_pre = 0.0; // total mass of do2 in River before processing float water_Riv_total_in = 0.0; // total water in river float do2_Riv_conc_total_pre = 0.0; // total concentration of do2 in River before processing float do2_RivStor_mass_chg = 0.0; float do2_Riv_mixing_mass_in = 0.0; float do2_RivStor_mixing_mass_post = 0.0; float do2_RivStor_mixing_mass_chg = 0.0; float do2_Riv_mass_total_post = 0.0; float do2_Riv_conc_total_post = 0.0; float do2_RivStor_mass_chg2 = 0.0; float do2_RivStor_mixing_mass_pre = 0.0; float do2_Riv_mixing_mass_total = 0.0; float do2_Riv_mixing_conc_total = 0.0; float do2_Riv_mixing_mass_out = 0.0; float do2_RivStor_mixing_mass_chg2 = 0.0; // Read-in values from greater model day = MFDateGetCurrentDay(); // reads in day of month month = MFDateGetCurrentMonth(); // reads in month of year year = MFDateGetCurrentYear(); // reads in year Q_in = MFVarGetFloat (_MDInDischarge0ID, itemID, 0.0); // this includes local runoff Q_out = MFVarGetFloat (_MDInDischargeID, itemID, 0.0); Runoff = MFVarGetFloat (_MDInRunoffID, itemID, 0.0); RunoffVolume = MFVarGetFloat (_MDInRunoffVolumeID, itemID, 0.0); RiverTemp = MFVarGetFloat (_MDInWTempRiverID, itemID, 0.0); water_RivStor_post = MFVarGetFloat (_MDInRiverStorageID, itemID, 0.0); water_RivStor_chg = MFVarGetFloat (_MDInRiverStorageChgID, itemID, 0.0); do2_Riv_mass_in = MFVarGetFloat (_MDOutRiverMassDO2ID, itemID, 0.0); do2_RivStor_mass_post = MFVarGetFloat (_MDOutRiverStorMassDO2ID, itemID, 0.0); do2_RivStor_mass_chg = MFVarGetFloat (_MDOutRiverStorMassChgDO2ID, itemID, 0.0); do2_Riv_mixing_mass_in = MFVarGetFloat (_MDOutRiverMixingMassDO2ID, itemID, 0.0); do2_RivStor_mixing_mass_post = MFVarGetFloat (_MDOutRiverMixingStorMassDO2ID, itemID, 0.0); do2_RivStor_mixing_mass_chg = MFVarGetFloat (_MDOutRiverMixingStorMassChgDO2ID, itemID, 0.0); // loading calculations do2_RO_conc = 1.0; do2_RO_mass = do2_RO_conc * 1000 / 1000000 * RunoffVolume * 86400; water_RivStor_pre = water_RivStor_post - water_RivStor_chg; do2_RivStor_mass_pre = do2_RivStor_mass_post - do2_RivStor_mass_chg; // note: this needs to be updated (ROB) do2_Riv_mass_total_pre = do2_Riv_mass_in + do2_RO_mass + do2_RivStor_mass_pre; water_Riv_total_in = Q_in + water_RivStor_pre; //m3/s do2_Riv_conc_total_pre = water_Riv_total_in > 0.0 ? (do2_Riv_mass_total_pre / (water_Riv_total_in * 86400)) * 1000000 / 1000 : 0.0; // mg/L do2_Riv_mass_removed = 1.0; // to be calculated do2_Riv_mass_added = 1.0; // to be calculated do2_Riv_mass_total_post = do2_Riv_mass_total_pre + do2_Riv_mass_added - do2_Riv_mass_removed; // kg/d do2_Riv_conc_total_post = water_Riv_total_in > 0.0 ? (do2_Riv_mass_total_post / (water_Riv_total_in * 86400)) * 1000000 / 1000 : 0.0; // mg/L do2_Riv_mass_out = do2_Riv_conc_total_post * Q_out / 1000000 * 1000 * 86400; do2_RivStor_mass_post = do2_Riv_conc_total_post * water_RivStor_post / 1000000 * 1000; do2_RivStor_mass_chg2 = do2_RivStor_mass_post - do2_RivStor_mass_pre; //mixing calcs do2_RivStor_mixing_mass_pre = do2_RivStor_mixing_mass_post - do2_RivStor_mixing_mass_chg; do2_Riv_mixing_mass_total = do2_Riv_mixing_mass_in + do2_RO_mass + do2_RivStor_mixing_mass_pre; // kg/d do2_Riv_mixing_conc_total = water_Riv_total_in > 0.0 ? (do2_Riv_mixing_mass_total / water_Riv_total_in * 86400) * 1000000 / 1000 : 0.0; // mg/L do2_Riv_mixing_mass_out = do2_Riv_mixing_conc_total * Q_out / 1000000 * 1000 * 86400; do2_RivStor_mixing_mass_post = do2_Riv_mixing_conc_total * water_RivStor_post / 1000000 * 1000; do2_RivStor_mixing_mass_chg2 = do2_RivStor_mixing_mass_post - do2_RivStor_mixing_mass_pre; MFVarSetFloat (_MDOutRiverMassDO2ID, itemID, do2_Riv_mass_out); MFVarSetFloat (_MDOutRiverStorMassDO2ID, itemID, do2_RivStor_mass_post); MFVarSetFloat (_MDOutRiverStorMassChgDO2ID, itemID, do2_RivStor_mass_chg2); MFVarSetFloat (_MDOutRiverConcDO2ID, itemID, do2_Riv_conc_total_post); MFVarSetFloat (_MDOutRiverMixingMassDO2ID, itemID, do2_Riv_mixing_mass_out); MFVarSetFloat (_MDOutRiverMixingStorMassDO2ID, itemID, do2_RivStor_mixing_mass_post); MFVarSetFloat (_MDOutRiverMixingStorMassChgDO2ID, itemID, do2_RivStor_mixing_mass_chg2); MFVarSetFloat (_MDOutRiverMixingConcDO2ID, itemID, do2_Riv_mixing_conc_total); if (itemID == 5) printf("itemID = %d, y = %d, m = %d, d = %d... riverMass = %f, riverConc = %f\n", itemID, year, month, day, do2_Riv_mass_out, do2_Riv_conc_total_post); }
static void _MDRainSMoistChg (int itemID) { // Input float airT; // Air temperature [degreeC] float precip; // Precipitation [mm/dt] float pet; // Potential evapotranspiration [mm/dt] float intercept; // Interception (when the interception module is turned on) [mm/dt] float sPackChg; // Snow pack change [mm/dt] float impSnowFallRO = 0.0; // Immediate runoff from snowfall on HCIA [mm/dt] // SZ 09242014 float irrAreaFrac = 0.0; // Irrigated area fraction float impAreaFrac = 0.0; // Impervious area fraction // RJS 082812 float h2oAreaFrac = 0.0; // H2O area fraction RJS 100103 float runoffToPerv = 0.0; // runoff from impervious to pervious [mm/dt] RJS 082812 float stormRunoffTotal = 0.0; // RJS 082812 float excess = 0.0; // RJS 082812 float sMoist = 0.0; // Soil moisture [mm/dt] float percolation = 0.0; // Drainage to groundwater [mm/dt] // SZ 10202014 // Output float sMoistChg = 0.0; // Soil moisture change [mm/dt] float evapotrans; // Local float waterIn; float awCap; float gm; float iceContent; // float imperviousSoil; // 1.0 = soil AWC layer takes into account impervious surfaces already, 2.0 = soil AWC layer does not take into account imp data // imperviousSoil = MFVarGetFloat (_MDInImperviousSoilID, itemID, 0.0); // RJS 091213 airT = MFVarGetFloat (_MDInAirTMeanID, itemID, 0.0); precip = MFVarGetFloat (_MDInPrecipID, itemID, 0.0); sPackChg = MFVarGetFloat (_MDInSPackChgID, itemID, 0.0); pet = MFVarGetFloat (_MDInPotETID, itemID, 0.0); awCap = MFVarGetFloat (_MDInSoilAvailWaterCapID, itemID, 0.0); impAreaFrac = MFVarGetFloat (_MDInImpFractionID, itemID, 0.0); // RJS 082812 h2oAreaFrac = MFVarGetFloat (_MDInH2OFractionID, itemID, 0.0); // RJS 100113 runoffToPerv = MFVarGetFloat (_MDInRunoffToPervID, itemID, 0.0); // RJS 082812 stormRunoffTotal = MFVarGetFloat (_MDInStormRunoffTotalID, itemID, 0.0); // RJS 082812 sMoist = MFVarGetFloat (_MDOutSoilMoistNotScaledID, itemID, 0.0); iceContent = _MDInRelativeIceContent != MFUnset ? MFVarGetFloat (_MDInRelativeIceContent, itemID, 0.0) : 0.0; intercept = _MDInInterceptID != MFUnset ? MFVarGetFloat (_MDInInterceptID, itemID, 0.0) : 0.0; irrAreaFrac = _MDInIrrAreaFracID != MFUnset ? MFVarGetFloat (_MDInIrrAreaFracID, itemID, 0.0) : 0.0; /* if (_MDOutPercolationID != MFUnset) { percolation = MFVarGetFloat (_MDOutPercolationID, itemID,0.0); // SZ 10202014 } else { percolation = 0.0; } */ //if (iceContent> 0.0) printf ("IceContent upper Layer = %f\n",iceContent); //reduce available water capacity by ice content // awCap= awCap - (awCap * iceContent); impSnowFallRO = (_MDInImpSnowFallROID != MFUnset) ? MFVarGetFloat(_MDInImpSnowFallROID,itemID,0.0) : 0.0; waterIn = precip - intercept - sPackChg + runoffToPerv - impSnowFallRO; // RJS 082812 // added impSnowFallRO // SZ 09242014 //* if (airT > 0.0) { // this was commented out prior to 082812, uncommented 082812 // waterIn = precip - intercept - sPackChg; // RJS commented out 082812 pet = pet > intercept ? pet - intercept : 0.0; if (sPackChg <= 0.0) { if (awCap > 0.0) { if (waterIn > pet) { sMoistChg = waterIn - pet < awCap - sMoist ? waterIn - pet : awCap - sMoist; excess = precip - intercept - sPackChg + runoffToPerv - pet - sMoistChg ; // RJS 082812 } else { gm = (1.0 - exp (- _MDSoilMoistALPHA * sMoist / awCap)) / (1.0 - exp (- _MDSoilMoistALPHA)); sMoistChg = (waterIn - pet) * gm; } if (sMoist + sMoistChg > awCap) { sMoistChg = awCap - sMoist; excess = precip - intercept - sPackChg + runoffToPerv - pet - sMoistChg; // RJS 082812 } if (sMoist + sMoistChg < 0.0) sMoistChg = - sMoist; sMoist = sMoist + sMoistChg; } else { // RJS 082812 added brackets sMoist = sMoistChg = 0.0; // RJS 082812 moved into brackets if (waterIn - sMoistChg > pet + intercept) excess = precip - intercept - sPackChg + runoffToPerv - pet - sMoistChg ; // RJS 082812 else excess = 0.0; // RJS 082812 } // evapotrans = pet + intercept < precip - sPackChg - sMoistChg ? // RJS commented out 082812 // pet + intercept : precip - sPackChg - sMoistChg; // RJS commented out 082812 evapotrans = pet + intercept < waterIn - sMoistChg? // RJS 082812 pet + intercept : waterIn - sMoistChg; // RJS 082812 } else { sMoistChg = evapotrans = excess = 0.0; } //* } // this was commented out prior to 082812. Uncommented 082812 // else { sMoistChg = 0.0; evapotrans = 0.0; } //* else { //* sMoistChg = 0.0; // RJS 082812 //* evapotrans = 0.0; // RJS 082812 //* excess = precip - intercept - sPackChg + runoffToPerv; // RJS 082812 //* } // RJS 082812 percolation = sMoist * _MDparPercolation; sMoistChg -= percolation; sMoist = sMoist - percolation; float balance = waterIn - evapotrans - sMoistChg - excess - percolation; // RJS 082812 // SZ 10202014 //if (itemID == 132) { // printf("**** itemID = %d, month = %d, day = %d, airT = %f, surplus = %f, stormRunoff = %f, intercept = %f\n", itemID, MFDateGetCurrentMonth (), MFDateGetCurrentDay (), airT, precip - sPackChg - evapotrans - sMoistChg - stormRunoffTotal, stormRunoffTotal, intercept); // printf("Alpha = %f, sMoist = %f, sMoistChg = %f, precip = %f, transp = %f, waterIn = %f\n", _MDSoilMoistALPHA, sMoist, sMoistChg, precip, evapotrans, waterIn); // printf("pet = %f, awCap = %f, precip = %f, sPackChg = %f, excess = %f, airT = %f\n", pet, awCap, precip, sPackChg, excess, airT); // printf("balance = %f, gm = %f, impAreaFrac = %f, runofftoPerv(basin) = %f, runofftoPerv(perv) = %f\n", balance, gm, impAreaFrac, runoffToPerv * (1.00 - impAreaFrac), runoffToPerv); // } // if (itemID == 1) printf("%d-%d-%d, Alpha = %f\n",MFDateGetCurrentYear(), MFDateGetCurrentMonth(),MFDateGetCurrentDay(),_MDSoilMoistALPHA); if ( (fabs(balance) > 0.00001) && (itemID == 3161)) { printf("**** itemID = %d, month = %d, day = %d, airT = %f, surplus = %f, stormRunoff = %f, intercept = %f\n", itemID, MFDateGetCurrentMonth (), MFDateGetCurrentDay (), airT, precip - sPackChg - evapotrans - sMoistChg - stormRunoffTotal, stormRunoffTotal, intercept); printf("Alpha = %f, sMoist = %f, sMoistChg = %f, precip = %f, transp = %f, waterIn = %f\n", _MDSoilMoistALPHA, sMoist, sMoistChg, precip, evapotrans, waterIn); printf("pet = %f, awCap = %f, precip = %f, sPackChg = %f, excess = %f, airT = %f\n", pet, awCap, precip, sPackChg, excess, airT); printf("balance = %f, gm = %f, impAreaFrac = %f, runofftoPerv(basin) = %f, runofftoPerv(perv) = %f\n", balance, gm, impAreaFrac, runoffToPerv * (1.00 - impAreaFrac), runoffToPerv); } //if ((itemID == 486)) printf("y = %d, m = %d, d = %d, ******* precip = %f, transp = %f, sPackChg = %f, sMoist = %f, sMoistChg = %f, awCap = %f, excess = %f\n", MFDateGetCurrentYear(), MFDateGetCurrentMonth(), MFDateGetCurrentDay(), precip, evapotrans, sPackChg, sMoist, sMoistChg, awCap, excess); //RJS 071511 MFVarSetFloat (_MDOutExcessNotScaledID, itemID, excess); //RJS 091813 MFVarSetFloat (_MDOutEvaptrsNotScaledID, itemID, evapotrans); // RJS 082812 MFVarSetFloat (_MDOutSoilMoistNotScaledID, itemID, sMoist); MFVarSetFloat (_MDOutSMoistChgNotScaledID, itemID, sMoistChg); MFVarSetFloat (_MDOutExcessID, itemID, excess * (1.0 - irrAreaFrac - impAreaFrac - h2oAreaFrac)); //RJS 100113 "-h2oAreaFrac" MFVarSetFloat (_MDOutEvaptrsID, itemID, evapotrans * (1.0 - irrAreaFrac - impAreaFrac - h2oAreaFrac)); //RJS 100113 "-h2oAreaFrac" MFVarSetFloat (_MDOutSoilMoistID, itemID, sMoist * (1.0 - irrAreaFrac - impAreaFrac - h2oAreaFrac)); //RJS 100113 "-h2oAreaFrac" MFVarSetFloat (_MDOutSMoistChgID, itemID, sMoistChg * (1.0 - irrAreaFrac - impAreaFrac - h2oAreaFrac)); //RJS 100113 "-h2oAreaFrac" if (_MDOutPercolationID != MFUnset) MFVarSetFloat (_MDOutPercolationID, itemID, percolation * (1.0 - irrAreaFrac - impAreaFrac - h2oAreaFrac)); //SZ 10202014 if (_MDOutLiquidSoilMoistureID != MFUnset) MFVarSetFloat (_MDOutLiquidSoilMoistureID,itemID, sMoist/awCap); }