Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}