Code covered by the BSD License  

Highlights from
getwdsdata.m

from getwdsdata.m by Philip Jonkergouw
Get water distribution system data from an EPANET input file

getwdsdata(wdsfile, code, id)
function [x, t] = getwdsdata(wdsfile, code, id)
% getwdsdata
%
% Get water distribution system data from an EPANET input file
% 
% Syntax
%
%   [x] = getwdsdata(wdsfile, code)
%   [x] = getwdsdata(wdsfile, code, id)
%   [x,t] = getwdsdata(...)
%
% Description
%
% [x] = getwdsdata(wdsfile, code) returns static water distribution system
% data for all nodes/links from an EPANET 2 input file. The type of data is
% specified by the character array 'code'.
%
% [x] = getwdsdata(wdsfile, code, id) returns static water distribution
% system data for the nodes/links specified in cell array of strings 'id'
% from an EPANET 2 input file.
%
% [x,t] = getwdsdata(...) returns dynamic water distribution
% system data with the time steps from an EPANET 2 input file.
%
% Example
%
% [cl, t] = getwdsdata('Net1.inp', 'en_quality', {'2', '12'})
%
% Author: Philip Jonkergouw
% Email:  pjonkergouw@gmail.com
% Date:   July 2007


% Initialise a few variables ...
code = upper(code);
errorcode = 0;
x = []; t = [];
if (nargin < 3) id = []; end

% Find out what is required ...

% Static node value?
s = 'EN_ELEVATIONEN_BASEDEMANDEN_PATTERNEN_EMITTEREN_INITQUALEN_SOURCEQUALEN_SOURCEPATEN_SOURCETYPEEN_TANKLEVEL';
if ~isempty(findstr(s, code))
    isstatic = 1;
    location = 'node';
end

% Dynamic node value?
s = 'EN_DEMANDEN_HEADEN_PRESSUREEN_QUALITYEN_SOURCEMASS';
if ~isempty(findstr(s, code))
    isstatic = 0;
    location = 'node';
end

% Static link value?
s = 'EN_DIAMETEREN_LENGTHEN_ROUGHNESSEN_MINORLOSSEN_INITSTATUSEN_INITSETTINGEN_KBULKEN_KWALL';
if ~isempty(findstr(s, code))
    isstatic = 1;
    location = 'link';
end

% Dynamic link value?
s = 'EN_FLOWEN_VELOCITYEN_HEADLOSSEN_STATUSEN_SETTINGEN_ENERGY';
if ~isempty(findstr(s, code))
    isstatic = 0;
    location = 'link';
end

% Water quality data?
ishydraulic = 1;
if strcmp(code, 'EN_QUALITY') ishydraulic = 0; end

% Load the EPANET 2 dynamic link library ...
if ~libisloaded('epanet2') loadlibrary('epanet2', 'epanet2.h'); end

% Open the water distribution system ...
s = which(wdsfile);
if ~isempty(s) wdsfile = s; end

[errorcode] = calllib('epanet2', 'ENopen', wdsfile, '', '');
if (errorcode)
    fprintf('Could not open network ''%s''.\nReturned empty array.\n', wdsfile);
    return;
end

% Retrieve the indices ...
nlocations = length(id);
if ~nlocations
    % Retrieve data for all nodes/links
    countcode = getenconstant(['EN_', upper(location), 'COUNT']);
    [errorcode, nlocations] = calllib('epanet2', 'ENgetcount', countcode, nlocations);
    if (errorcode)
        fprintf(['Problem retrieving number of ', location, 's.\n']);
        [errorcode] = calllib('epanet2', 'ENclose');
        unloadlibrary('epanet2');
        return;
    end
    nlocations = double(nlocations);
    index = 1:nlocations;
else
    getindexfunc = ['ENget', location, 'index'];
    for n = 1:nlocations
        index(1,n) = 0;
        [errorcode, id{n}, index(1,n)] = calllib('epanet2', getindexfunc, id{n}, index(1,n));
        if (errorcode)
            fprintf(['Problem retrieving index for ', location, ' ''', id{n}, '''.\n']);
            [errorcode] = calllib('epanet2', 'ENclose');
            unloadlibrary('epanet2');
            return;
        end
    end
end

getvaluefunc = ['ENget', location, 'value'];
% Obtain correct epanet code ...
epanetcode = getenconstant(code);

if isstatic
    % Static output required. No need to run simulation ...
    for n = 1:nlocations
        x(n) = 0;
        [errorcode, x(n)] = calllib('epanet2', getvaluefunc, index(n), epanetcode, x(n));
        if (errorcode)
            s = '                   ';
            getidfunc = ['ENget', location, 'id'];
            [errorcode, s] = calllib('epanet2', getidfunc, index(n), s);
            if (errorcode)
                fprintf(['Problem retrieving value for ', location, ' ''', x(n), ''' (index).\n']);
            else
                fprintf(['Problem retrieving value for ', location, ' ''', s, '''(id).\n']);
            end
            [errorcode] = calllib('epanet2', 'ENclose');
            unloadlibrary('epanet2');
            return;
        end
    end
else
    % Non-static output required. Run simulation ...
    nextfunc = 'ENnextH';
    initflag = 11;
    enflag = 'H';
    if ~ishydraulic
        enflag = 'Q';
        nextfunc = 'ENstepQ';
        % Solve hydraulics prior to running WQ simulation ...
        [errorcode] = calllib('epanet2', 'ENsolveH');
        initflag = 0;
    end
    
    % Assign function calls (WQ or Hydraulic) ...
    initfunc  = ['ENinit', enflag];
    openfunc  = ['ENopen', enflag];
    runfunc   = ['ENrun', enflag];
    closefunc = ['ENclose', enflag];
    
    % Open and initialise the (WQ/Hydraulic) solver ...
    [errorcode] = calllib('epanet2', openfunc);
    [errorcode] = calllib('epanet2', initfunc, initflag);
    
    % Initialise some variables ...
    tval = 0; tstep = 1; value = 0.0; pt = 0;
    
    % Loop through simulation ...
    while tstep && ~errorcode
        [errorcode, tval] = calllib('epanet2', runfunc, tval);
        pt = pt + 1;
        for n = 1:nlocations
            [errorcode, value] = calllib('epanet2', getvaluefunc, index(n), epanetcode, value);
            x(pt, n) = double(value);
        end
        t(pt) = double(tval)/3600;
        % Continue to the next time step ...
        [errorcode, tstep] = calllib('epanet2', nextfunc, tstep);
    end
    % Close the solver
    [errorcode] = calllib('epanet2', closefunc);
end
% Close EPANET ...
[errorcode] = calllib('epanet2', 'ENclose');
if (errorcode) fprintf('EPANET error occurred. Code %g\n', num2str(errorcode)); end
% Convert to double precision ...
x = double(x);

if libisloaded('epanet2') unloadlibrary('epanet2'); end

Contact us at files@mathworks.com