%
%  function [mesh] = triangle_mesh_reader( filename )
%
%  PURPOSE: Read mesh information from filename.node, filename.ele
%   and filename.edge  files generated by the 2D mesh generator
%   TRIANGLE
%
%  Input:
%         filename   string containing the base of the filenames 
%                    generated by TRIANGLE. (This Matlab functtion
%                    will read from  filename.node, filename.ele
%                    and filename.edge).
%
%  Output:
%         mesh       structure array with the following fields
%
%         mesh.p     Real np x 2
%                    array containing the x- and y- coordinates
%                    of the nodes
%
%         mesh.t     Integer nt x 3    or   nt x 6
%                    t(i,1:4) contains the indices of the vertices of
%                    triangle i. 
%                    If t is a nt x 6 array, t(i,4:6) contains 
%                    the indices of the edge mid-points of triangle i.
%
%         mesh.e     Integer ne x 3  or  ne x 4
%                    e(i,1:2) contains the indices of the vertices of
%                    edge i.
%                    If  mesh.e is of size ne x 3, then
%                        edge(i,3) contains the boundary marker of edge i.
%                        e(i,3) = 1  Dirichlet bdry conds are imposed on edge i
%                        e(i,3) = 2  Neumann bdry conds are imposed on edge i
%                        e(i,3) = 3  Robin bdry conds are imposed on edge i
%                    If  mesh.e is of size ne x 4, then
%                        e(i,3) contains the index of the midpoint of edge i. 
%                        e(i,4) contains the boundary marker
%                        e(i,4) = 1  Dirichlet bdry conds are imposed on edge i
%                        e(i,4) = 2  Neumann bdry conds are imposed on edge i
%
%  AUTHOR:  Denis Ridzal 
%           Matthias Heinkenschloss
%           Department of Computational and Applied Mathematics
%           Rice University
%           November 23, 2005
%
function [mesh] = triangle_mesh_reader( filename )

% open node file for reading
fid = fopen( [ filename '.node'] );
% read first line (number of vertices)
tmp = fscanf( fid, ' %d %d %d %d ', [1, 4]);
nv = tmp(1); dim = tmp(2); nattrib = tmp(3); bdrymarker = tmp(4);
% read node coorddinates (ignore attributes, i.e. assumed to be 0)
if (nattrib==0)
  tmp = fscanf( fid, ' %d %f %f %d', [3+nattrib+bdrymarker,nv]);
  % discard numbering indices and boundary markers 
  mesh.p = tmp(2:3,:)';
else
  fprintf('Vertices have additional attributes!\n');
  fprintf('Modify triangle_mesh_reader.m accordingly.\n');
  return;
end
fclose(fid);

% open element file for reading
fid = fopen( [ filename '.ele'] );
% read first line (number of vertices)
tmp = fscanf( fid, ' %d %d %d ', [1, 3]);
nt = tmp(1); nnodes = tmp(2); nattrib = tmp(3); 
% read node indices for triangle i (ignore attributes)
if( nnodes == 3 )
    tmp    = fscanf( fid, ' %d %d %d %d ', [1+nnodes,nt]);
end
if( nnodes == 6 )
    tmp    = fscanf( fid, ' %d %d %d %d %d %d %d', [1+nnodes,nt]);
end
mesh.t = tmp(2:1+nnodes,:)';
fclose(fid);

% open edge file for reading
fid = fopen( [ filename '.edge'] );
% read first line (number of vertices)
tmp = fscanf( fid, ' %d %d ', [1, 2]);
ne = tmp(1); bdrymarker = tmp(2); 
% read node indices for edge i and boundary marker
tmp    = fscanf( fid, ' %d %d %d %d ', [4, ne]);
fclose(fid);

if( size(mesh.t,1) == 3 )
    % get boundary edges only
    % (assume that all boundary edges have maker > 0!)
    mesh.e = tmp(2:4,:)';
    mesh.e = mesh.e(mesh.e(:,3) > 0,:);
else

    % get boundary edges only
    % (assume that all boundary edges have maker > 0!)
    ind = (tmp(4,:) > 0);
    ne  = sum(ind);
    mesh.e   = zeros(ne, 4);
    mesh.e(:,[1,2,4]) = tmp(2:4,ind)';

    % determine mid points
    %%% Get the number of nodes and vertices. Mid points have indices
    %%% nv+1,...,nn
    nn = size(mesh.p,1);
    nv = max( max(mesh.t(:,1:3)) );
    for i = 1:ne
        mid   = ones(nn-nv,1)*( 0.5*(mesh.p(mesh.e(i,1),:)+mesh.p(mesh.e(i,2),:)) );
        [x,k] = min( sum(abs(mesh.p(nv+1:nn,:)-mid),2) );
        mesh.e(i,3)   = nv+k;
    end
end

