River Node Network Model - Flow Balance Issue

Hi,

I’m working on a node network model that routes water through nodes representing a river system to satisfy agricultural demand for water (Demand_AG). The issue I have is with my flow balance at nodes (EQ3a). This constraint is currently formulated as an inequality such that flows entering each node (sum of inflows, upstream flow, and reach gains) must equal or exceed the flows leaving the node. While the model executes with this formulation, it allows the model to disappear water downstream (i.e. total flow leaving a node can be less than total flow entering a node). I’ve reformulated this constraint as an equality by replace ‘=G=’ with ‘=E=’, but the model becomes infeasible with the error warning CPLEX 1217 (model is integer infeasible). I do not understand why I can’t formulate this constraint such that total outflows at a given node must equal total inflows. I would appreciate any help in explaining why the model becomes infeasible when EQ3a is set as an inequality, and how I could reformulate the flow balance so that node outflows must equal node inflows. Thanks!

*===============

    1. Declare sets
      *===============

SETS

  • Sets
    j Nodes in the river network
    t Timestep in year_month [YYYY_MM]
    NodeType Types of nodes [Junction ExistingReservoir ProposedReservoir Demand_AG]
    ;

*Define aliases
Alias (j,k) ;

*=================================

    1. Define Parameters and Scalars
      *=================================

PARAMETERS

  • Parameters - Flow
    EXISTS(j,NodeType) Assigns NodeType to nodes (j) [Junction ExistingReservoir ProposedReservoir Demand_AG]
    linkExist(j,k) Describes whether link exists between node (j) and node (k) [1=yes 0=no]
    inflow(j,t) External inflows that generate flow in the network. Includes headflow and tributaries. [taf per month]
    gainLoss(j,k,t) Gains or losses on flows between node (j) and node (k) due to unaccounted inflow or diversion in system. [taf]
    maxQ(j,k) Maximum allowable flow on link between nodes (j) and (k). [taf per month]
    minQ(j,k) Minimum allowable flow on link between nodes (j) and (k) such as a minimum instream flow. [taf per month]
  • Parameters - Demand
    demandAG(j,t) Agricultural demand for each timestep [taf per month]

;

SCALARS
priceAG Price of agricultural water [$M per taf] /0.02/

  • ;

*===================================================

    1. Read sets and parameter input
      *===================================================

*-----------------

  • Load - Flow
    *-----------------
    $CALL GDXXRW.EXE input=RiverModel_INPUT.xlsx output=TEST_Input_Data.gdx Set=t rng=Timestep_t!A1:A100 Rdim=1 Set=j rng=Nodes_j!A1:A100 Rdim=1 Set=NodeType rng=NodeType!A1 Rdim=1 Par=EXISTS rng=EXISTS!A1 Rdim=1 Cdim=1 Par=linkExist rng=Link_Exist!A1 Rdim=1 Cdim=1 Par=inflow rng=Inflow_taf!A1 Rdim=1 Cdim=1 Par=gainLoss rng=GainLoss_taf!A1 Rdim=2 Cdim=1 Par=maxQ rng=MaxQ_taf!A1 Rdim=2 Par=minQ rng=MinQ_taf!A1 Rdim=2
    $GDXIN TEST_Input_Data.gdx
    $LOAD t
    $LOAD j
    $LOAD NodeType
    $LOAD EXISTS
    $LOAD linkExist
    $LOAD inflow
    $LOAD gainLoss
    $LOAD maxQ
    $LOAD minQ
    $GDXIN

*-----------------

  • Load - Demand
    *-----------------
    $CALL GDXXRW.EXE input=RiverModel_INPUT.xlsx output=TEST_Input_Data.gdx Par=demandAG rng=Demand_AG_taf!A1 Rdim=1 Cdim=1
    $GDXIN TEST_Input_Data.gdx
    $LOAD demandAG
    $GDXIN

*-----------------

  • Close GDX file
    *-----------------
    *$GDXIN

*===================

    1. Define Variables
      *===================

VARIABLES

  • Variables - Flow
    Z Objective function value
    Q(j,k,t) Flow in links in timestep (t) [taf per month]
  • Variables - Demand
    Sag(j,t) Scarcity at agricultural demand sites. [taf]
    LOSSag(j,t) Economic loss at agricultural demand sites. [$M per month]
    LOSStot(t) Total economic loss across all demand sites (dem). [$M per month].

NONNEGATIVE VARIABLES

  • Variables - Demand
    Sag
    ;

*============================

    1. Declare model equations
      *============================

EQUATIONS
*-------------------

  • Objective Functions
    *-------------------
    EQ1 Z Objective function to minimize water scarcity costs. [$M]

*-------------------

  • Model Constraints - Flow
    *-------------------
    EQ3a(j,t) Streamflow mass balance equations at each nodes.
    EQ3b(j,k,t) Minimum streamflow constraint [taf per month].
    EQ3c(j,k,t) Maximum streamflow constraint [taf per month].

*-------------------

  • Model Constraints - Demand
    *-------------------
    EQ6a(j,t) Scarcity at agricultural demand sites. [taf per month]
    EQ6b(j,t) Economic loss at agricultural demand sites. [$M per month]
    EQ8a(t) Total economic loss across all demand sites. [$M per month]

;

*============================

    1. Define Model Equations
      *============================
      *-------------------
  • Objective Functions
    *-------------------

  • Water scarcity objective
    EQ1… Z =E= sum(t, LOSStot(t)) ;

*-------------------

  • Model Constraints - Flow
    *-------------------
    EQ3a(j,t)$EXISTS(j,‘Junction’)… inflow(j,t) + sum(k$linkExist(k,j), (Q(k,j,t) + gainLoss(k,j,t))) =G= sum(k$linkExist(j,k), Q(j,k,t)) ;
    EQ3b(j,k,t)$linkExist(j,k)… Q(j,k,t) =G= minQ(j,k) ;
    EQ3c(j,k,t)$linkExist(j,k)… Q(j,k,t) =L= maxQ(j,k) ;

*-------------------

  • Model Constraints - Demand
    *-------------------
    EQ6a(j,t)$EXISTS(j,“Demand_AG”)… Sag(j,t) =E= demandAG(j,t) - sum(k$linkExist(k,j), Q(k,j,t)) ;
    EQ6b(j,t)$EXISTS(j,“Demand_AG”)… LOSSag(j,t) =E= Sag(j,t) * priceAG ;
    EQ8a(t)… LOSStot(t) =E= sum(j$EXISTS(j,“Demand_AG”), LOSSag(j,t)) ;



    *=======================================================================
    1. Solve model
      *=======================================================================

*-------------------

  • Define the model and solve all equations listed above
    *-------------------
    Model RiverModel /all/ ;

*-------------------

  • Solve Model
    *-------------------
    Solve RiverModel minimize Z using LP ;


    *-------------------

  • Save and export model outputs
    *-------------------

  • Export all input data and results to a GAMS gdx file
    Execute_Unload “Rivermodel_OutputData.gdx” ;

  • Dump all the input data and results to an Excel file
    Execute “gdx2xls Rivermodel_OutputData.gdx” ;

  • Click File menu => RUN (F9) or Solve icon and examine solution report in .LST file


*End of Code


RiverModel_INPUT.xlsx (22 KB)
RiverModel.gms (7.19 KB)