double node_getSurfArea(int j, double d) // // Input: j = node index // d = water depth (ft) // Output: returns surface area of water at a node (ft2) // Purpose: computes surface area of water stored at a node from water depth. // { switch (Node[j].type) { case STORAGE: return storage_getSurfArea(j, d); default: return 0.0; } }
double storage_getLosses(int j, double tStep) // // Input: j = node index // tStep = time step (sec) // Output: returns evaporation + seepage loss over a time step (ft3) // Purpose: computes combined volume of water evaporated & infiltrated from // a storage node over a given time step. // { int i, k; double depth; double area = -1.0; double evapRate; double seepRate; double evapLoss = 0.0; double seepLoss = 0.0; double totalLoss = 0.0; double lossRatio; // --- get evap. & seepage rates k = Node[j].subIndex; evapRate = Evap.rate * Storage[k].fEvap; seepRate = Storage[k].seepRate; if ( evapRate > 0.0 || seepRate > 0.0 ) { // --- find surface area available for evaporation depth = 0.5 * (Node[j].oldDepth + Node[j].newDepth); area = storage_getSurfArea(j, depth); // --- compute evap loss over this area evapLoss = area * evapRate * tStep; // --- compute seepage loss through effective area if ( seepRate > 0.0 ) { // --- find effective area for seepage (the larger of the // area at the current depth and the largest area below // that depth -- for storage shapes with decreasing area // above some depth) i = Storage[k].aCurve; if ( i >= 0 ) area = MAX(area, table_getMaxY(&Curve[i], depth*UCF(LENGTH))); // --- find seepage loss across this area seepLoss = area * seepRate * tStep; } } // --- total loss over time step cannot exceed stored volume totalLoss = evapLoss + seepLoss; if ( totalLoss > 0.0 ) { lossRatio = 0.5 * (Node[j].oldVolume + Node[j].newVolume) / totalLoss; if ( lossRatio < 1.0 ) { evapLoss *= lossRatio; seepLoss *= lossRatio; totalLoss *= lossRatio; } } // --- save evap & infil losses at the node Storage[Node[j].subIndex].evapLoss = evapLoss; Storage[Node[j].subIndex].seepLoss = seepLoss; return totalLoss; }
double storage_getLosses(int j, double tStep) // // Input: j = node index // tStep = time step (sec) // Output: returns volume of water evaporated & infiltrated (ft3) // Purpose: computes volume of water evaporated & infiltrated from a storage // node over a given time step. // { double depth; double area = 0.0; double area0 = 0.0; double evapRate; double evapLoss = 0.0; double infilLoss = 0.0; double totalLoss = 0.0; double maxLoss; TGrnAmpt* infil; // --- adjust evaporation rate for storage unit's evaporation potential evapRate = Evap.rate * Storage[Node[j].subIndex].fEvap; if ( evapRate > 0.0 ) { // --- find surface area available for evaporation depth = Node[j].oldDepth; if ( depth > FUDGE ) area += storage_getSurfArea(j, depth); depth = Node[j].newDepth; if ( depth > FUDGE ) area += storage_getSurfArea(j, depth); // --- compute evaporation loss over average area evapLoss = 0.5 * area * evapRate * tStep; } // --- compute infiltration loss infil = Storage[Node[j].subIndex].infil; if (infil) { // --- find average depth over time step depth = 0.5 * (Node[j].oldDepth + Node[j].newDepth); // --- get surface area at avg. depth and at bottom of unit area0 = storage_getSurfArea(j, 0.0); area = area0; if ( depth > FUDGE ) area = storage_getSurfArea(j, depth); if ( area > 0.0 ) { // --- get average depth assuming sloped sides depth = depth / 2.0 * (1.0 + area0/area); // --- compute infil. loss considering ponded depth infilLoss = grnampt_getInfil(infil, tStep, 0.0, depth) * area * tStep; } } // --- compute total loss totalLoss = evapLoss + infilLoss; maxLoss = 0.5 * (Node[j].oldVolume + Node[j].newVolume); if ( totalLoss > 0.0 ) { if ( totalLoss > maxLoss ) { evapLoss = (evapLoss / totalLoss) * maxLoss; totalLoss = maxLoss; } } Storage[Node[j].subIndex].evapLoss = evapLoss; Storage[Node[j].subIndex].losses = totalLoss; return totalLoss; }