#include <stdio.h>
#include <stdlib.h>


void cbem_poi_input(const char *InfParams, const char *InfData)
{

/* ===purpose=== */

/**********************************************************************************************************************************/
/********************************  COLLOCATION BEM for 3D POISSON EQUATION: SINGULAR FORMULATION  *********************************/
/************************************  3-NODED TRIANGULAR ELEMENT: SEMI-ANALYTIC INTEGRATION  *************************************/
/***********************************************  PIECEWISE CONSTANT APPROXIMATION  ***********************************************/
/**********************************************  Data input for 3D Poisson equation  **********************************************/
/**********************************************************************************************************************************/

/* Developer: Sylvain Nintcheu Fata */
/* Version:   V.1.1                 */
/* Released:  Aug 21, 2012          */

 
   extern const int mx_nd_elt; /* mx_nd_elt == Maximum number of nodes per element */
   extern int nbnd,nbelt;      /* nbnd == Total number of boundary nodes */
                               /* nbelt == Total number of boundary elements */
   extern int **belt, *eltbc;  /* belt[i][0:2] == Global indices of boundary nodes on the i-th element */
                               /* eltbc[i] = {0,1} ==> {Dirichlet,Neunamm} boundary condition is prescribed on belt[i][0:2] */
   extern int nmax_simp;       /* nmax_simp == Maximum number of Simpson's rule iterations for the integration of the Newton potential */
   extern double simp_eps;     /* simp_eps == Absolute tolerance on Simpson's rule for the integration of the Newton potential */
   extern double gm_eps,f_eps; /* gm_eps == Tolerance on the geometry */
                               /* f_eps == Tolerance on the argument of a function */
   extern double **bnd;        /* bnd[i][0:2] = Cartesian coordinates of the i-th boundary node */
   extern double *pbv;         /* pbv[i] == Prescribed Boundary Value at the centroid of the i-th boundary element */
   extern int ldim;            /* ldim == Dimension of the iterative solver BiCGSTAB(ldim) */
   extern int mxmatvec;        /* mxmatvec == Maximum number of matrix-vector mutiplications in the iterative solver BiCGSTAB(ldim) */
   extern double slv_eps;      /* slv_eps == Tolerance on the BiCGSTAB(ldim) iterative solver */
   extern int ncx,ncy,ncz;     /* ncx,ncy,ncz == Total number of cells in the computational box in the x,y,z-coordinate */
			       /* directions respectively                                                               */
   extern double nbfac;        /* nbfac == Parameter characterizing the near-neighboring region of a given cell */
   extern int sparseflg; /* sparseflg == Parameter that determines the sparsity pattern of the preconditoner                          */
			 /* sparseflg = 0 ==> no preconditoner                                                                        */
			 /* sparseflg = 1 ==> the sparsity pattern of the preconditoner is given by Cell self-interactions            */
			 /* sparseflg = 1+n ==> the sparsity pattern of the preconditoner is given by Cell + n Neighbors interactions */

   FILE *fp;
   int i;
   


   if ((fp = fopen(InfParams,"r")) != NULL)
   {   /* Read parameters */
       fscanf(fp,"%lf",&gm_eps); /* gm_eps == Tolerance on the geometry */
       fscanf(fp,"%*[^\n]");     /* Read and discard rest of line */
       fscanf(fp,"%lf",&f_eps);  /* f_eps == Tolerance on the argument of a function */
       fscanf(fp,"%*[^\n]");     /* Read and discard rest of line */
       fscanf(fp,"%lf",&simp_eps); /* simp_eps == Absolute tolerance on Simpson's rule for the integration of the Newton potential */
       fscanf(fp,"%*[^\n]");       /* Read and discard rest of line */
       fscanf(fp,"%d",&nmax_simp); /* nmax_simp == Maximum number of Simpson's rule iterations for the integration of the Newton potential */
       fscanf(fp,"%*[^\n]");       /* Read and discard rest of line */
       fscanf(fp,"%d",&ldim);     /* ldim == Dimension of the iterative solver BiCGSTAB(ldim) */
       fscanf(fp,"%*[^\n]");      /* Read and discard rest of line */
       fscanf(fp,"%d",&mxmatvec); /* mxmatvec == Maximum number of matrix-vector mutiplication in the iterative solver BiCGSTAB(ldim) */
       fscanf(fp,"%*[^\n]");      /* Read and discard rest of line */
       fscanf(fp,"%lf",&slv_eps); /* slv_eps == Tolerance on the BiCGSTAB(ldim) iterative solver */
       fscanf(fp,"%*[^\n]");      /* Read and discard rest of line */
       fscanf(fp,"%d %d %d",&ncx,&ncy,&ncz); /* Parameters of the computational box containing the boundary mesh */
       fscanf(fp,"%*[^\n]");                 /* Read and discard rest of line */
       fscanf(fp,"%lf",&nbfac);    /* nbfac == Neighbor Factor */
       fscanf(fp,"%*[^\n]");       /* Read and discard rest of line */
       fscanf(fp,"%d",&sparseflg); /* Parameter that determines the sparsity pattern of the preconditoner */
       fscanf(fp,"%*[^\n]");       /* Read and discard rest of line */
       fclose(fp); /* close InfParams */
   }
   else
   {fprintf(stderr, "\nError opening file \"%s\".\n",InfParams); exit(1);}


   if ((fp = fopen(InfData,"r")) != NULL)
   {   // Read parameters
       fscanf(fp,"%d",&nbnd);  /* nbnd == Total number of boundary nodes */
       fscanf(fp,"%*[^\n]");   /* Read and discard rest of line */
       fscanf(fp,"%d",&nbelt); /* nbelt == Total number of boundary elements */
       fscanf(fp,"%*[^\n]");   /* Read and discard rest of line <==> while( (ch = fgetc(fp)) != '\n' ) continue; */
       
       if ( (bnd = (double **)malloc(nbnd*sizeof(double *))) != NULL ) /* If bnd is successfully allocated */
       {
           for (i=0; i<nbnd; i++)    /* Loop over all boundary nodes */
	   {
	       if ( (bnd[i] = (double *)malloc(3*sizeof(double))) != NULL ) /* If bnd[i] is successfully allocated */
	       {   /* Read the Cartesian coordinates of boundary nodes */
	           /* bnd[i][0:2] = Cartesian coordinates of the i-th boundary node */
		   fscanf(fp,"%lf %lf %lf", &bnd[i][0], &bnd[i][1], &bnd[i][2]);
	       }
	       else
	       {printf("cbem_poi_input: Allocate array \"bnd[%d]\" failed\n",i); exit(1);}
	       
	   }
       }
       else
       {printf("cbem_poi_input: Allocate array \"bnd\" failed\n"); exit(1);}
       

       pbv = (double *)malloc(nbelt*sizeof(double));
       if ( pbv == NULL ) /* If pbv is not successfully allocated */
       {printf("cbem_poi_input: Allocate array \"pbv\" failed\n"); exit(1);}
       
       eltbc = (int *)malloc(nbelt*sizeof(int));
       if ( eltbc == NULL ) /* If eltbc is not successfully allocated */
       {printf("cbem_poi_input: Allocate array \"eltbc\" failed\n"); exit(1);}
       
       belt = (int **)malloc(nbelt*sizeof(int *));
       if ( belt == NULL ) /* If belt is not successfully allocated */
       {printf("cbem_poi_input: Allocate array \"belt\" failed\n"); exit(1);}
       
       for (i=0; i<nbelt; i++) /* Loop over all boundary elements */
       {
	   if ( (belt[i] = (int *)malloc(mx_nd_elt*sizeof(int))) != NULL ) /* If belt[i] is successfully allocated */
	   {    /* Read the characteristics of each boundary element */
	        fscanf(fp,"%d %d %d %lf %d", &belt[i][0], &belt[i][1], &belt[i][2], &pbv[i], &eltbc[i]);
	   }
	   else
	   {printf("cbem_poi_input: Allocate array \"belt[%d]\" failed\n",i); exit(1);}
       }

       fclose(fp); /* close InfData */
   }
   else
   {fprintf(stderr, "\nError opening file \"%s\".\n",InfData); exit(1);}

}
