/* readinputfile.h -- This file is part of Archimedes release 0.0.1.
   Archimedes is a simulator for Submicron 2D Silicon
   Devices. It implements the Monte Carlo method
   for the simulation of the semiclassical Boltzmann equation for both
   electrons and holes. It also includes the quantum effects by means 
   of effective potential method.

   Copyright (C) 2004 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 2, 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, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
   USA.  */


// ######################################################
// Created on 10 sep.2004, Siracusa, J.M.Sellier
// Last modif. : 05 oct.2004, Siracusa, J.M.Sellier
// ######################################################

// Read the geometrical and physical description of the device.
// The input file is interpreted like a "computer language".
// For the syntax of the commands of this language see
// the manual GNU Archimedes release 0.0.1

void
Read_Input_File(void)
{
 char s[80];
 long double num,num0;
 int ini,fin;
 int i,j;
 int LXflag=0, LYflag=0;
 
// Thess are the default values
// i.e. if nothing is specified
// in the input file we have
// the following values.
// ============================
 Model_Number=MCE; // here we choose the model
 Material=SILICON; // MESFET made of Silicon
 nx=50; // default # of cells in x-direction
 ny=50; // default # of cells in y-direction
 TF=5.0e-12; // Default Final Time in seconds
 DT=0.001e-12; // Default constant time step
 mstar=mstarSILICON; // coefficient of the Si elettronic effective mass
 msh=mstarHSILICON; // coefficient of the Si heavy hole effective mass
// standard doping concentration
 for(i=1;i<=nx+1;i++)
   for(j=1;j<=ny+1;j++){
      u2d[i][j][1]=N_D[i][j]=NI;
      h2d[i][j][1]=N_H[i][j]=NI;
      u2d[i][j][2]=u2d[i][j][3]=u2d[i][j][4]=0.;
   }
 TL=300.; // Lattice temperature in Kelvin
 NP1=2500; // Number of particle in n+ cell
 MEDIA=500; // Number of step on which we compute the various mean average
 Quantum_Flag=0; // No quantum effects taken into account
 MAXIMINI=0; // No computation of max and min of variables during simulation
 SAVEALWAYS=0; // we don't save at each step by default
 File_Format=GNUPLOTFORMAT; // output file in mesh format
// =====================

// Reading the input file
// ======================
 printf("\
Processing the input file\n\
=========================\n");
 do{
// read the current row
  fscanf(fp,"%s",s);
// if row is a comment then read it and ignore it
  if(strcmp(s,"#")==0){
    fgets(s,80,fp);
    printf("COMMENT ---> %s",s);
  }
// read and check if the material specified exists
  else if(strcmp(s,"MATERIAL")==0){
    fscanf(fp,"%s",s);
    if(strcmp(s,"SILICON")==0){
      Material=SILICON;
      mstar=mstarSILICON;
      msh=mstarHSILICON;
      printf("MATERIAL %s ---> Ok\n",s);
    }
// if the material specified does not exist then exit
    else{
      printf("%s: unknow specified material\n",progname);
      exit(EXIT_FAILURE);
    }
  }
// here we choose the charge particle transport simulated
  else if(strcmp(s,"TRANSPORT")==0){
    fscanf(fp,"%s",s);
    if(strcmp(s,"ELECTRONS")==0){
      Model_Number=MCE;
      printf("TRANSPORT %s ---> Ok\n",s);
    }
    else if(strcmp(s,"HOLES")==0){
      Model_Number=MCH;
      printf("TRANSPORT %s ---> Ok\n",s);
      printf("%s: hole transport not yet implemented\n",progname);
      exit(EXIT_FAILURE);
    }
    else if(strcmp(s,"BIPOLAR")==0){
      Model_Number=MCEH;
      printf("TRANSPORT %s ---> Ok\n",s);
      printf("%s: bipolar transport not yet implemented\n",progname);
      exit(EXIT_FAILURE);
    }
    else{
      printf("%s: unknown transport specification\n",progname);
      exit(EXIT_FAILURE);
    }
  }
// Specified the number of spatial step in x direction
  else if(strcmp(s,"XSPATIALSTEP")==0){
    fscanf(fp,"%Lg",&num);
    nx=(int) num;
    if(nx>NXM){
      printf("%s: too large x-spatial step\n",progname);
      exit(EXIT_FAILURE);
    }
    if(LXflag==0){
      printf("%s: you have to define the x-length first\n",progname);
      exit(EXIT_FAILURE);
    }
    dx=LX/nx; // spatial step in x-direction
    printf("XSPATIALSTEP = %d ---> Ok\n",nx);
  }
// Specified the number of spatial step in y direction
  else if(strcmp(s,"YSPATIALSTEP")==0){
    fscanf(fp,"%Lg",&num);
    ny=(int) num;
    if(ny>NYM){
      printf("%s: too large y-spatial step\n",progname);
      exit(EXIT_FAILURE);
    }
    if(LYflag==0){
      printf("%s: you have to define the y-length first\n",progname);
      exit(EXIT_FAILURE);
    }
    dy=LY/ny; // spatial step in y-direction
    printf("YSPATIALSTEP = %d ---> Ok\n",ny);
  }
// configuration of the final time of simulation
  else if(strcmp(s,"FINALTIME")==0){
    fscanf(fp,"%Lg",&num);
    TF=num;
    if(TF<=0.){
      printf("%s: not valid final time\n",progname);
      exit(EXIT_FAILURE);
    }
    printf("FINAL TIME = %g ---> Ok\n",TF);
  }
// configuration of the time step
  else if(strcmp(s,"TIMESTEP")==0){
    fscanf(fp,"%Lg",&num);
    DT=num;
    if(DT<=0.){
      printf("%s: not valid time step\n",progname);
      exit(EXIT_FAILURE);
    }
    printf("TIME STEP = %g ---> Ok\n",DT);
  }
// read the x length of the device
  else if(strcmp(s,"XLENGTH")==0){
    fscanf(fp,"%Lg",&num);
    LX=num;
    if(LX<=0.){
      printf("%s: not valid x-length\n",progname);
      exit(EXIT_FAILURE);
    }
    LXflag=1;
    printf("LENGTH X = %g ---> Ok\n",LX);
  }
// read the y length of the device
  else if(strcmp(s,"YLENGTH")==0){
    fscanf(fp,"%Lg",&num);
    LY=num;
    if(LY<=0.){
      printf("%s: not valid y-length\n",progname);
      exit(EXIT_FAILURE);
    }
    LYflag=1;
    printf("LENGTH Y = %g ---> Ok\n",LY);
  }
// read the donor doping density
  else if(strcmp(s,"DONORDENSITY")==0){
    real xmin,ymin,xmax,ymax,conc;
// read and check the xmin value
    fscanf(fp,"%Lg",&num);
    xmin=num;
    if(xmin<0.){
      printf("%s: not valid xmin value\n",progname);
      exit(EXIT_FAILURE);
    }
// read and check the ymin value
    fscanf(fp,"%Lg",&num);
    ymin=num;
    if(ymin<0.){
      printf("%s: not valid ymin value\n",progname);
      exit(EXIT_FAILURE);
    }
// read and check the xmax value
    fscanf(fp,"%Lg",&num);
    xmax=num;
    if(xmax>LX){
      printf("%s: not valid xmax value\n",progname);
      exit(EXIT_FAILURE);
    }
// read and check the ymax value
    fscanf(fp,"%Lg",&num);
    ymax=num;
    if(ymax>LY){
      printf("%s: not valid xmin value\n",progname);
      exit(EXIT_FAILURE);
    }
// read and check the donor concentration value
    fscanf(fp,"%Lg",&num);
    conc=num;
    if(conc<0.){
      printf("%s: not valid donor density\n",progname);
      exit(EXIT_FAILURE);
    }
    for(i=1;i<=nx+1;i++)
      for(j=1;j<=ny+1;j++)
        if((i-0.5)*dx>=xmin && (i-1.5)*dx<=xmax
         &&(j-0.5)*dy>=ymin && (j-1.5)*dy<=ymax)
          u2d[i][j][1]=N_D[i][j]=conc;
    printf("DONOR DENSITY %g %g %g %g %g ---> Ok\n",
           xmin,ymin,xmax,ymax,conc);
  }
// read the acceptor density in the n zone
// read the donor doping density
  else if(strcmp(s,"ACCEPTORDENSITY")==0){
    real xmin,ymin,xmax,ymax,conc;
// read and check the xmin value
    fscanf(fp,"%Lg",&num);
    xmin=num;
    if(xmin<0.){
      printf("%s: not valid xmin value\n",progname);
      exit(EXIT_FAILURE);
    }
// read and check the ymin value
    fscanf(fp,"%Lg",&num);
    ymin=num;
    if(ymin<0.){
      printf("%s: not valid ymin value\n",progname);
      exit(EXIT_FAILURE);
    }
// read and check the xmax value
    fscanf(fp,"%Lg",&num);
    xmax=num;
    if(xmax>LX){
      printf("%s: not valid xmax value\n",progname);
      exit(EXIT_FAILURE);
    }
// read and check the ymax value
    fscanf(fp,"%Lg",&num);
    ymax=num;
    if(ymax>LY){
      printf("%s: not valid xmin value\n",progname);
      exit(EXIT_FAILURE);
    }
// read and check the acceptor concentration value
    fscanf(fp,"%Lg",&num);
    conc=num;
    if(conc<0.){
      printf("%s: not valid acceptor density\n",progname);
      exit(EXIT_FAILURE);
    }
    for(i=1;i<=nx;i++)
      for(j=1;j<=ny;j++)
        if((i-0.5)*dx>=xmin && (i-1.5)*dx<=xmax
         &&(j-0.5)*dy>=ymin && (j-1.5)*dy<=ymax)
          h2d[i][j][1]=N_H[i][j]=conc;
    printf("ACCEPTOR DENSITY %g %g %g %g %g ---> Ok\n",
           xmin,ymin,xmax,ymax,conc);
  }
// read the lattice temperature
  else if(strcmp(s,"LATTICETEMPERATURE")==0){
    fscanf(fp,"%Lg",&num);
    TL=num;
    if(TL<=0.){
      printf("%s: not valid lattice temperature\n",progname);
      exit(EXIT_FAILURE);
    }
    printf("LATTICE TEMPERATURE = %g ---> Ok\n",TL);
  }
// read the statistical weight for electrons and holes
  else if(strcmp(s,"STATISTICALWEIGHT")==0){
    fscanf(fp,"%Lg",&num);
    NP1=(int) num;
    printf("STATISTICAL WEIGHT = %d ---> Ok\n",NP1);
  }
// configuration of the output format
  else if(strcmp(s,"OUTPUTFORMAT")==0){
    fscanf(fp,"%s",s);
    if(strcmp(s,"GNUPLOT")==0){
     File_Format=GNUPLOTFORMAT;
     printf("OUTPUT FORMAT = GNUPLOT/XD3D\n");
    }
    else if(strcmp(s,"MESH")==0){
     File_Format=MESHFORMAT;
     printf("OUTPUT FORMAT = MESH/BB\n");
    }
    else{
     printf("%s: unknown output format\n",progname);
     exit(EXIT_FAILURE);
    }
  }
// Definition of an eventual contact
  else if(strcmp(s,"CONTACT")==0){
    char pos[80],kind[80];
    real ipos,fpos,delt,dens;
    real potential;
    int i,j,k;
// read and check the "qualitative" position of the contact
    fscanf(fp,"%s",pos);
    if(strcmp(pos,"UP")!=0 && strcmp(pos,"DOWN")!=0
       && strcmp(pos,"LEFT")!=0 && strcmp(pos,"RIGHT")!=0){
      printf("%s: unknown position of contact\n",progname);
      exit(EXIT_FAILURE);
    }
    if(strcmp(pos,"DOWN")==0){
     i=0;
     delt=LX/nx;
    }
    if(strcmp(pos,"RIGHT")==0){
     i=1;
     delt=LY/ny;
    }
    if(strcmp(pos,"UP")==0){
     i=2;
     delt=LX/nx;
    }
    if(strcmp(pos,"LEFT")==0){
     i=3;
     delt=LY/ny;
    }
// read the "quantitative" position of the contact
    fscanf(fp,"%Lg %Lg",&num0,&num);
    ipos=num0;
    fpos=num;
    if(ipos>=fpos){
      printf("%s: not valid position of contact\n",progname);
      exit(EXIT_FAILURE);
    } 
// read and check the kind of contact
// It can be : Insulator, Schottky or Ohmic.
    fscanf(fp,"%s",kind);
    if(strcmp(kind,"INSULATOR")!=0 && strcmp(kind,"SCHOTTKY")!=0
       && strcmp(kind,"OHMIC")!=0){
      printf("%s: specified physical contact unknown\n",progname);
      exit(EXIT_FAILURE);
    }
    if(strcmp(kind,"INSULATOR")==0) k=0;
    if(strcmp(kind,"SCHOTTKY")==0) k=1;
    if(strcmp(kind,"OHMIC")==0) k=2;
// read the voltage applied to the contact
    fscanf(fp,"%Lg",&num);
    potential=num;
// read the electron density for the reservoir at contact
// if and only if the contact is ohmic
    if(k==2){
      fscanf(fp,"%Lg",&num);
      dens=num;
    }
// internal definition of the boundary conditions
// EDGE[i][j][k] = ref
// i = 0 BOTTOM EDGE
// i = 1 RIGHT EDGE
// i = 2 UPPER EDGE
// i = 3 LEFT EDGE
// j is the j-th cell
// k = 0
// ref = 0 INSULATOR
// ref = 1 SCHOTTKY
// ref = 2 OHMIC
// k = 1
// ref is the applied potential reference
// k = 2
// ref is the density of electron reservoirs at the contact
    ini=(int)(ipos/delt)+1;
    fin=(int)(fpos/delt)+2;
    for(j=ini;j<=fin;j++){
      EDGE[i][j][0]=k;
      if(k==0 || k==1){
        EDGE[i][j][1]=potential;
        EDGE[i][j][2]=0;
      }
      else if(k==2){
        EDGE[i][j][1]=potential;
        EDGE[i][j][2]=dens;
      }
    }

// Then everything is ok in the contact definition...
    if(k!=2)printf("CONTACT %s %g %g %s %g ---> Ok\n",
            pos,ipos,fpos,kind,potential);
    else if(k==2)printf("CONTACT %s %g %g %s %g %g ---> Ok\n",
            pos,ipos,fpos,kind,potential,dens);

  }
  else if(strcmp(s,"NOQUANTUMEFFECTS")==0){
    Quantum_Flag=0;
    printf("QUANTUM EFFECTS = NO --->Ok\n");
  }
  else if(strcmp(s,"QUANTUMEFFECTS")==0){
    Quantum_Flag=1;
    printf("QUANTUM EFFECTS = YES --->Ok\n");
  }
  else if(strcmp(s,"MEDIA")==0){
    fscanf(fp,"%Lg",&num);
    if(num<0){
      printf("%s: number of media is negative\n",progname);
      exit(EXIT_FAILURE);
    }
    MEDIA=(int) num;
    printf("MEDIA = %d ---> Ok\n",MEDIA);
  }
  else if(strcmp(s,"MAXIMINI")==0){
    MAXIMINI=1;
    printf("MAXIMINI ---> Ok\n");
  }
  else if(strcmp(s,"NOMAXIMINI")==0){
    MAXIMINI=0;
    printf("NO MAXIMINI ---> Ok\n");
  }
  else if(strcmp(s,"SAVEEACHSTEP")==0){
    SAVEALWAYS=1;
    printf("SAVE AT EACH TIME STEP ---> Ok\n");
  }
// elseif(strcmp(s,"")==0){
 }while(!feof(fp));
// computation of the maximum doping density
 DDmax=0.;
 for(i=1;i<=nx+1;i++)
   for(j=1;j<=ny+1;j++){
     if(DDmax<=N_D[i][j]) DDmax=N_D[i][j];
   }
 printf("=========================\n");
}

// =============================================
