(!******************************************************
   Mosel Example Problems
   ======================

   file j1water2.mos
   `````````````````
   Water conveyance/water supply management
   - Record version -

   A water transport network is provided. Nodes correspond
   to cities, reservoirs, and pumping stations. Arcs
   correspond to pipes. Capacities for each reservoir,
   demand for each city, and capacities for the pipe
   connections are given. How much water should flow through
   each pipe to maximize the flow in the network?

   A network transformation is presented to introduce fictitious
   source and sink nodes. A LP model based on the transport
   network representation is presented. All data and decision
   variables are grouped in a single record data struture.

   (c) 2008-2022 Fair Isaac Corporation
       author: S. Heipcke, July 2006
*******************************************************!)

model "J-1 Water supply (2)"
 uses "mmxprs"

 declarations
  ARCS: range                       ! Set of arcs
  NODES=1..12
  
  PIPE: array(ARCS) of record       ! Definition of arcs (= pipes)
   Source,Sink: integer             !   start/end point of arc
   Capacity: integer                !   arc capacity
   flow: mpvar                      !   flow on arc
  end-record

  SOURCE,SINK: integer              ! Number of source and sink nodes
 end-declarations

 initializations from 'j1water2.dat'
  PIPE(Source,Sink,Capacity) SOURCE SINK
 end-initializations

! Objective: total flow
 TotalFlow:= sum(a in ARCS | PIPE(a).Sink=SINK) PIPE(a).flow

! Flow balances in nodes
 forall(n in NODES | n<>SOURCE and n<>SINK) 
  sum(a in ARCS | PIPE(a).Source=n) PIPE(a).flow = 
   sum(a in ARCS | PIPE(a).Sink=n) PIPE(a).flow

! Capacity limits
 forall(a in ARCS) PIPE(a).flow <= PIPE(a).Capacity

! Solve the problem
 maximize(TotalFlow)
 
! Solution printing
 writeln("Total flow: ", getobjval)
 forall(a in ARCS) 
  writeln(PIPE(a).Source, " -> ", PIPE(a).Sink, ": ", getsol(PIPE(a).flow))
 
end-model
