/*
   This file belongs to Aeneas. Aeneas is a GNU package released under GPL 3 license.
   This code is a simulator for Submicron 3D Semiconductor Devices. 
   It implements the Monte Carlo transport in 3D tetrahedra meshes
   for the simulation of the semiclassical Boltzmann equation for both electrons.
   It also includes all the relevant quantum effects for nanodevices.

   Copyright (C) 2007 Jean Michel Sellier <sellier@dmi.unict.it>
 
   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, 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 <http://www.gnu.org/licenses/>.
*/

// Last modified : 16 august 2007, Siracusa, Jean Michel Sellier

// The input file unit is the micron

void load_mesh(char inp[])
{
/*
  ============================================================================
   Programmer    : Jean Michel Sellier
   Creation      : 07 Dic.2003, Paris, J.M.Sellier
   Purpose       : Load the 3D mesh INRIA format file called "device.mesh"
  ============================================================================
*/

 int i;
 int dum;
 
 FILE *fp;

 fp=fopen(inp,"r");

// check the existence of the input file
// *************************************
// if the file does not exist the code close the PETSc library and exit.
 if(fp==NULL){
   printf("INPUT file 'device.mesh' does not exist\nexit\n");
   system("PAUSE");
   exit(0);
 }

// *************************************************************
//  Load 'device.mesh' and store the mesh in the correct arrays
// *************************************************************

// Read the number of vertices
// ***************************
/* The code skip two rows which have to be in the following format:
   MeshVersionFormatted 0 (or 1)
   Dimension
   3
   Vertices */
// Ng = number of vertices of the mesh (nombre total de noeuds du maillage)
 fscanf(fp,"%*s %*d %*s %*d %*s %d",&Ng);
 printf("Number of vertices = %d\n",Ng);

// allocation for i_front
/*  printf("Allocating memory for mesh arrays...\n");
  i_front = malloc((Ng+1)*sizeof(int));
  if(i_front==NULL){
    printf("load_mesh : not enough memory for i_front allocation!\n");
    system("PAUSE");
    exit(0);
  }
  for(i=0;i<3;i++){
    coord[i] = malloc((Ng+1)*sizeof(double));
    if(coord[i]==NULL){
      printf("load_mesh : not enough memory for coord[%d] allocation!\n",i);
      system("PAUSE");
      exit(0);
    }
  }*/
// read the global coordinate of the mesh vertices and related reference number
// ****************************************************************************
// i_front[i] = reference number of the i-th vertex (nombre de reference du noeud)
//               This number = 0 if we are inside the device
//                 ''       != 0 if we are on the frontier
//               In this latter case this number makes one understand what
//               kind of boundary conditions one has to impose on that vertex.
// coord[0][i] = global coordinate x of the i-th vertex (i=0..Ng-1)
// coord[1][i] = global coordinate y of the i-th vertex
// coord[2][i] = global coordinate z of the i-th vertex
// French comment:
// Pour k=0..dim-1 (dim = dimension de l'espace) et n=0..Ng-1, coord[k][n] est la k-ieme
// coordonee du noeud de numero global n.


 for(i=0;i<Ng;i++){
   fscanf(fp,"%lg %lg %lg %d",&coord[0][i],&coord[1][i],&coord[2][i],&i_front[i]);
   coord[0][i]*=1.e-6;
   coord[1][i]*=1.e-6;
   coord[2][i]*=1.e-6;
   
//   printf("%2.20g %2.20g %2.20g %d\n",coord[0][i],coord[1][i],coord[2][i],i_front[i]);
 }

/*
// Then we skip the informations about the triangles edges
// *******************************************************
// The following skipped row has to be as follows:
//   Edges
 fscanf(fp,"%*s %d",&dum);
// printf("%d\n",dum);
 for(i=1;i<=dum;i++) fscanf(fp,"%*d %*d %*d");
*/

// Then we skip the informations about the triangles
// *************************************************
// (This gives us informations about the definition of triangles)
// The skipped row has to be as follows:
//   Triangles
 fscanf(fp,"%*s %d",&dum);
//printf("dum = %d\n",dum);
// Allocate arrays and set values  for **noeud_geo and *i_dom
//  PetscMalloc(Ne*sizeof(PetscInt),&i_dom);
//  PetscMalloc(ng,&noeud_geo);
//  for(i=0;i<ng;i++) PetscMalloc(Ne*sizeof(PetscInt),&noeud_geo[i]);
 for(i=0;i<dum;i++){
   fscanf(fp,"%*d %*d %*d %*d\n");
//   fscanf(fp,"%d %d %d %d\n",&noeud_geo[0][i],&noeud_geo[1][i],&noeud_geo[2][i],&i_dom[i]);
//   printf("%d %d %d %d %d\n",i,noeud_geo[0][i],noeud_geo[1][i],noeud_geo[2][i],i_dom[i]);
 }
// Read informations about the various tetrahedra
// **********************************************
// (this gives us informations about the definition of tetrahedra)
// i_dom[i] = reference number of the i-th tetrahedra
// noeud_geo[0][i] = global number of the first vertex in the i-th tetrahedra
// noeud_geo[1][i] = global number of the second vertex in the i-th tetrahedra
// noeud_geo[2][i] = global number of the third vertex in the i-th tetrahedra
// noeud_geo[3][i] = global number of the fourth vertex in the i-th tetrahedra
// The skipped row has to be as follows:
//   Tetrahedra
 fscanf(fp,"%*s %d",&Ne);
 printf("Number of elements (tetrahedra) = %d\n",Ne);

// allocations
/*  i_dom = malloc((Ne+1)*sizeof(int));
  for(i=0;i<4;i++) noeud_geo[i] = malloc((Ne+1)*sizeof(int));
  if(i_dom==NULL){
    printf("load_mesh : not enough memory for i_front allocation!\n");
    system("PAUSE");
    exit(0);
  }*/

// Allocate arrays and set values  for **noeud_geo and *i_dom
//  PetscMalloc(Ne*sizeof(PetscInt),&i_dom);
//  PetscMalloc(ng,&noeud_geo);
//  for(i=0;i<ng;i++) PetscMalloc(Ne*sizeof(PetscInt),&noeud_geo[i]);
 for(i=0;i<Ne;i++){
   fscanf(fp,"%d %d %d %d %d",&noeud_geo[0][i],&noeud_geo[1][i],
                                &noeud_geo[2][i],&noeud_geo[3][i],&i_dom[i]);
//   printf("%d %d %d %d %d %d\n",i,noeud_geo[0][i],noeud_geo[1][i],
//                             noeud_geo[2][i],noeud_geo[3][i],i_dom[i]);
 }

 fclose(fp);

// various dynamical allocations
#include "../services/dynamical_allocations.h"
}
