static void _MDDischRouteMuskingumCoeff (int itemID) {
// Input
	float yMean;            // Average depth at mean discharge [m]
	float wMean;            // River width at mean discharge [m]
	float vMean;            // Mean velocity
	float beta;             // Riverbed shape exponent []
	float slope;            // Riverbed slope [m/km]
// Output
	float C0;               // Muskingum C0 coefficient (current inflow)
	float C1;               // Muskingum C1 coefficient (previous inflow)
	float C2;               // MUskingum C2 coefficient (previous outflow)
// Local
	float xi;               // Flood-wave/flow velocity ratio
	float C;                // Cell Courant number;
	float D;                // Cell Reynolds number;
	float dt;               // time step length [s]
	float dL;               // Cell length [m]
	
	dL        = MFModelGetLength (itemID);
	slope     = MFVarGetFloat (_MDInRiverbedSlopeID,         itemID, 0.0) / 1000.0;
	yMean     = MFVarGetFloat (_MDInRiverbedAvgDepthMeanID,  itemID, 0.0);
	wMean     = MFVarGetFloat (_MDInRiverbedWidthMeanID,     itemID, 0.0);
	vMean     = MFVarGetFloat (_MDInRiverbedVelocityMeanID,  itemID, 0.0);
	beta      = MFVarGetFloat (_MDInRiverbedShapeExponentID, itemID, 0.0);
	if (CMmathEqualValues (vMean,     0.0)) {
		MFVarSetFloat (_MDOutMuskingumC0ID, itemID, 0.0);
		MFVarSetFloat (_MDOutMuskingumC1ID, itemID, 0.0);
		MFVarSetFloat (_MDOutMuskingumC2ID, itemID, 0.0);
		MFVarSetFloat (_MDOutCourantID,     itemID, 0.0);
		return;
	}
	if (CMmathEqualValues (dL,        0.0) ||
	    CMmathEqualValues (slope,     0.0) ||
	    CMmathEqualValues (yMean,     0.0) ||
	    CMmathEqualValues (wMean,     0.0) ||
	    (beta  < 0.0)) { 
	    // Falling back to flow-accumulation
		MFVarSetFloat (_MDOutMuskingumC0ID, itemID, 1.0);
		MFVarSetFloat (_MDOutMuskingumC1ID, itemID, 0.0);
		MFVarSetFloat (_MDOutMuskingumC2ID, itemID, 0.0);
		MFVarSetFloat (_MDOutCourantID,     itemID, 0.0);
		return;
	}
	dt = MFModelGet_dt (); 

	xi = 1 + beta * (2.0 / 3.0) / (beta + 1);
	C = xi * vMean * dt / dL;
	D = yMean / (dL * slope * xi);

	C0 = (-1 + C + D) / (1 + C + D);
	C1 = ( 1 + C - D) / (1 + C + D);
	C2 = ( 1 - C + D) / (1 + C + D);
//   if ((C0 < 0.0) || (C1 < 0.0) || (C2 < 0.0)) { C0 = 1.0; C1 = 0; C2 = 0; } // According to Pounce C1 and C2 can be negative

	MFVarSetFloat (_MDOutMuskingumC0ID, itemID, C0);
	MFVarSetFloat (_MDOutMuskingumC1ID, itemID, C1);
	MFVarSetFloat (_MDOutMuskingumC2ID, itemID, C2);
	MFVarSetFloat (_MDOutCourantID,     itemID, C);
}
Пример #2
0
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);
}
Пример #3
0
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);
}
Пример #4
0
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);
}
Пример #5
0
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);
}