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

void dgemv_(char *trans,int *m,int *n,double *alpha,double *a,int *lda,double *x,int *incx,double *beta,double *y,int *incy);


void cbem_lap_lrhs(void)
{

/* ===purpose=== */

/**********************************************************************************************************************************/
/********************************  COLLOCATION BEM for 3D LAPLACE EQUATION: SINGULAR FORMULATION  *********************************/
/***************************************  3-NODED TRIANGULAR ELEMENT: ANALYTIC INTEGRATION  ***************************************/
/***********************************************  PIECEWISE CONSTANT APPROXIMATION  ***********************************************/
/**********************************  Form the left- and right-hand sides of the discretized BIE  **********************************/
/**********************************************************************************************************************************/

/* Developer: Sylvain Nintcheu Fata, Oak Ridge National Laboratory */
/* Version:   V.1.2                                                */
/* Released:  Apr 14, 2011                                         */

 
   extern int nbelt;        /* nbelt == Total number of boundary elements */
   extern int *eltbc;       /* eltbc[k] = {0,1} ==> {Dirichlet,Neunamm} boundary condition is prescribed on element k */
   extern double *h,*g;     /* h == Potential influence matrix, g == Flux influence matrix */
   extern double *rhs;      /* rhs == Right-hand side of the Discretized BIE */
   extern double *phi,*flx; /* phi == Vector containing boundary potentials */
                            /* flx == Vector containing boundary fluxes */
   extern double *pbv;      /* pbv == Vector containing Prescribed Boundary Values */

   char tr;
   int k,i,j,stride,incx,incy;
   double alp,bet;



/*** Initialization: Prescribed boundary conditions ==> flux and potential vectors */
   if ( (phi = (double *)malloc(nbelt*sizeof(double))) == NULL ) /* If phi is not successfully allocated */
   {printf("cbem_lap_lrhs: Allocate array \"phi\" failed\n"); exit(1);}
   
   if ( (flx = (double *)malloc(nbelt*sizeof(double))) == NULL ) /* If flx is not successfully allocated */
   {printf("cbem_lap_lrhs: Allocate array \"flx\" failed\n"); exit(1);}

   for (k=0; k< nbelt; k++) /* Loop over all boundary elements */
   {
      if (eltbc[k] == 0) /* eltbc[k] = 0 ==> Dirichlet data is prescribed on element k */
      {
         phi[k] = pbv[k]; flx[k] = 0.0;
      }
      else /* eltbc[k] = 1 ==> Neumann data is prescribed on element k */
      {
         phi[k] = 0.0; flx[k] = pbv[k];
      }
   }

   free(pbv);

   if ( (rhs = (double *)malloc(nbelt*sizeof(double))) != NULL ) /* If rhs is successfully allocated */
   {
      /* rhs = matmul(h,phi) - matmul(g,flx) */
      tr = 'n'; alp = 1.0; incx = 1; bet = 0.0; incy = 1;
      dgemv_(&tr,&nbelt,&nbelt,&alp,g,&nbelt,flx,&incx,&bet,rhs,&incy); /* rhs = matmul(g,flx) */

      bet = -1.0;
      dgemv_(&tr,&nbelt,&nbelt,&alp,h,&nbelt,phi,&incx,&bet,rhs,&incy); /* rhs = matmul(h,phi) - rhs */
    }
    else
    {printf("cbem_lap_lrhs: Allocate array \"rhs\" failed\n"); exit(1);}

/*** Rearrange columns: Form the Left-hand side coefficient matrix in g */
    for (k=0; k<nbelt; k++)
       if (eltbc[k] == 1) /* if Neumann data is prescribed on element k */
       {
          stride = nbelt*k;
	  for (i=0; i<nbelt; i++) 
	  {
	     j = i+stride; /* Column-major order in h and g matrices: stride = nbelt*k */
	     g[j] = -h[j];
	  }
       }
       
    free(h);

}
