## Copyright (C) 2020 Andreas Stahel
## 
## This program is free software: you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
## 
## This program is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
## 
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see
## <https://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn{function file}{}@var{FEMmesh} = ReadMeshTriangle(@var{name.1})
##
##   read a mesh generated by CreateMeshTriangle(@var{name})
##
##parameter: @var{name.1} the filename
##
##return value: @var{FEMmesh} the mesh stored in @var{name} 
##
##Sample call:
##@verbatim
##CreateMeshTriangle('Test',[0,-1,-1;1,-1,-2;1,2,-1;0,2,-2],0.01)
##Mesh = ReadMeshTriangle('Test.1');
##   will create a mesh with 0<=x<=1, -1<=y<=+2
##   and a typical area of 0.01 for each triangle
##@end verbatim
## @c Will be cut out in ??? info file and replaced with the same
## @c references explicitly there, since references to core Octave
## @c functions are not automatically transformed from here to there.
## @c BEGIN_CUT_TEXINFO
## @seealso{CreateMeshTriangle, CreateMeshRect}
## @c END_CUT_TEXINFO
## @end deftypefn

## Author: Andreas Stahel <andreas.stahel@gmx.com>
## Created: 2020-03-30

function Mesh = ReadMeshTriangle(name)

[fid,msg] = fopen(strcat(name,".map"),"r");
if (fid == -1)
  nomap = true;
else
  nomap = false;
  n   = fscanf(fid,"%d",1);
  map = zeros(n,1);
  for k = 1:n;
    tmp = fscanf(fid,"%d",[1,1]);
    map(k) = fscanf(fid,"%e",1);
  endfor
  fclose(fid);
endif

[fid,msg] = fopen(strcat(name,".node"),"r");
n = fscanf(fid,"%d",1);
if (nomap==true) map = linspace(1,n,n);endif
nodes = zeros(n,3);
tmp = fscanf(fid,"%d",[1,3]);
for k = 1:n;
  tmp = fscanf(fid,"%d",1);
  nodes(map(k),:) = fscanf(fid,"%e",[1,3]);
endfor
fclose(fid);

[fid,msg] = fopen(strcat(name,".ele"),"r");
n = fscanf(fid,"%d",1);
elem = zeros(n,4);
tmp = fscanf(fid,"%d",[1,2]);
for k = 1:n;
  tmp = fscanf(fid,"%d",1);
  elem(k,1:3) = fscanf(fid,"%e",[1,3]);
  for kk=1:3 elem(k,kk) = map(elem(k,kk));endfor
endfor
elem(:,4) = 1; %% default type 1
fclose(fid);

[fid,msg] = fopen(strcat(name,".poly"),"r");
tmp = fscanf(fid,"%d",[1,4]);
n = fscanf(fid,"%d",1);
edges = zeros(n,3);
tmp = fscanf(fid,"%d",[1,1]);
for k = 1:n;
  tmp = fscanf(fid,"%d",[1,1]);
  tmp = fscanf(fid,"%1c",[1,1]);
  edges(k,:) = fscanf(fid,"%e",[1,3]);
  for kk = 1:2 edges(k,kk) = map(edges(k,kk));endfor
 %% edges(k,3) = min([nodes(edges(k,1),3),nodes(edges(k,2),3)]);
endfor
fclose(fid);

%% determine area of elements and the GP (Gauss integration Points)
nElem = size(elem)(1);
elemArea = zeros(nElem,1);
GP = zeros(3*nElem,2); Mesh.GPT = zeros(3*nElem,1);
%% for each element
for ne = 1:nElem
  v0 = nodes(elem(ne,1),1:2);
  v1 = nodes(elem(ne,2),1:2)-v0;
  v2 = nodes(elem(ne,3),1:2)-v0;
  GP(3*ne-2,:) = v0+v1/6+v2/6;
  GP(3*ne-1,:) = v0+v1*2/3+v2/6;
  GP(3*ne,:)   = v0+v1/6+v2*2/3;
  elemArea(ne) = abs(det([v1;v2]))/2;
endfor

Mesh.type     = 'linear';
Mesh.elem     = elem(:,[1 2 3]);
Mesh.elemT    = elem(:,4);
Mesh.edges    = edges(:,[1 2]);
Mesh.edgesT   = edges(:,3);
Mesh.nodes    = nodes(:,[1 2]);
Mesh.nodesT   = nodes(:,3);
Mesh.GP       = GP;
Mesh.elemArea = elemArea;

if (Mesh.edgesT(1)<-9);  %% elasticity
  Mesh.nodesT = [fix(Mesh.nodesT/10), mod(Mesh.nodesT,-10)];
  BCtype = [fix(Mesh.edgesT/10), mod(Mesh.edgesT,-10)];
  ind_x = find(BCtype(:,1)==-1);
  Mesh.nodesT(edges(ind_x,[1,2])(:),1) = -1;
  ind_y = find(BCtype(:,2)==-1);
  Mesh.nodesT(edges(ind_y,[1 2])(:),2) = -1;
endif

ind = (Mesh.nodesT~=-1);
Mesh.node2DOF = cumsum(ind).*ind;
Mesh.nDOF = sum(ind);

endfunction


