int steadyflow_execute(int j, float* qin, float* qout) // // Input: j = link index // qin = inflow to link (cfs) // Output: qin = adjusted inflow to link (limited by flow capacity) (cfs) // qout = link's outflow (cfs) // returns 1 if successful // Purpose: performs steady flow routing through a single link. // { int k; float s; float q; // --- use Manning eqn. to compute flow area for conduits if ( Link[j].type == CONDUIT ) { k = Link[j].subIndex; q = (*qin) / Conduit[k].barrels; if ( Link[j].xsect.type == DUMMY ) Conduit[k].a1 = 0.0; else { ////////////////////////////////////////////////////////////////////////////// // Comparison should be made against max. flow, not full flow. (LR - 3/10/06) ////////////////////////////////////////////////////////////////////////////// // if ( q > Link[j].qFull ) // { // q = Link[j].qFull; // Conduit[k].a1 = Link[j].xsect.aFull; // if ( q > Conduit[k].qMax ) { q = Conduit[k].qMax; Conduit[k].a1 = xsect_getAmax(&Link[j].xsect); (*qin) = q * Conduit[k].barrels; } else { s = q / Conduit[k].beta; Conduit[k].a1 = xsect_getAofS(&Link[j].xsect, s); } } Conduit[k].a2 = Conduit[k].a1; Conduit[k].q1 = q; Conduit[k].q2 = q; (*qout) = q * Conduit[k].barrels; } else (*qout) = (*qin); return 1; }
int steadyflow_execute(int j, double* qin, double* qout, double tStep) // // Input: j = link index // qin = inflow to link (cfs) // tStep = time step (sec) // Output: qin = adjusted inflow to link (limited by flow capacity) (cfs) // qout = link's outflow (cfs) // returns 1 if successful // Purpose: performs steady flow routing through a single link. // { int k; double s; double q; // --- use Manning eqn. to compute flow area for conduits if ( Link[j].type == CONDUIT ) { k = Link[j].subIndex; q = (*qin) / Conduit[k].barrels; if ( Link[j].xsect.type == DUMMY ) Conduit[k].a1 = 0.0; else { // --- subtract evap and infil losses from inflow q -= link_getLossRate(j, tStep); if ( q < 0.0 ) q = 0.0; // --- flow can't exceed full flow if ( q > Link[j].qFull ) { q = Link[j].qFull; Conduit[k].a1 = Link[j].xsect.aFull; (*qin) = q * Conduit[k].barrels; } // --- infer flow area from flow rate else { s = q / Conduit[k].beta; Conduit[k].a1 = xsect_getAofS(&Link[j].xsect, s); } } Conduit[k].a2 = Conduit[k].a1; Conduit[k].q1 = q; Conduit[k].q2 = q; (*qout) = q * Conduit[k].barrels; } else (*qout) = (*qin); return 1; }
int kinwave_execute(int j, double* qinflow, double* qoutflow, double tStep) // // Input: j = link index // qinflow = inflow at current time (cfs) // tStep = time step (sec) // Output: qoutflow = outflow at current time (cfs), // returns number of iterations used // Purpose: finds outflow over time step tStep given flow entering a // conduit using Kinematic Wave flow routing. // // t // | qin, ain |-------------------| qout, aout // | | Flow ---> | // |----> x q1, a1 |-------------------| q2, a2 // // { int k; int result = 1; double dxdt, dq; double ain, aout; double qin, qout; double a1, a2, q1, q2; // --- no routing for non-conduit link (*qoutflow) = (*qinflow); if ( Link[j].type != CONDUIT ) return result; // --- no routing for dummy xsection if ( Link[j].xsect.type == DUMMY ) return result; // --- assign module-level variables pXsect = &Link[j].xsect; Qfull = Link[j].qFull; Afull = Link[j].xsect.aFull; k = Link[j].subIndex; Beta1 = Conduit[k].beta / Qfull; // --- normalize flows and areas q1 = Conduit[k].q1 / Qfull; q2 = Conduit[k].q2 / Qfull; a1 = Conduit[k].a1 / Afull; a2 = Conduit[k].a2 / Afull; qin = (*qinflow) / Conduit[k].barrels / Qfull; // --- use full area when inlet flow >= full flow //(5.0.012 - LR) if ( qin >= 1.0 ) ain = 1.0; //(5.0.012 - LR) // --- get normalized inlet area corresponding to inlet flow else ain = xsect_getAofS(pXsect, qin/Beta1) / Afull; // --- check for no flow if ( qin <= TINY && q2 <= TINY ) { qout = 0.0; aout = 0.0; } // --- otherwise solve finite difference form of continuity eqn. else { // --- compute constant factors dxdt = link_getLength(j) / tStep * Afull / Qfull; dq = q2 - q1; C1 = dxdt * WT / WX; C2 = (1.0 - WT) * (ain - a1); C2 = C2 - WT * a2; C2 = C2 * dxdt / WX; C2 = C2 + (1.0 - WX) / WX * dq - qin; // --- starting guess for aout is value from previous time step aout = a2; // --- solve continuity equation for aout result = solveContinuity(qin, ain, &aout); // --- report error if continuity eqn. not solved if ( result == -1 ) { report_writeErrorMsg(ERR_KINWAVE, Link[j].ID); return 1; } if ( result <= 0 ) result = 1; // --- compute normalized outlet flow from outlet area qout = Beta1 * xsect_getSofA(pXsect, aout*Afull); if ( qin > 1.0 ) qin = 1.0; } // --- save new flows and areas Conduit[k].q1 = qin * Qfull; Conduit[k].a1 = ain * Afull; Conduit[k].q2 = qout * Qfull; Conduit[k].a2 = aout * Afull; (*qinflow) = Conduit[k].q1 * Conduit[k].barrels; (*qoutflow) = Conduit[k].q2 * Conduit[k].barrels; return result; }