!----------------------------------------------------------------------------------------------------------------------------------!
SUBROUTINE gbem_lap_assem
!----------------------------------------------------------------------------------------------------------------------------------!

!===purpose===! 

!**********************************************************************************************************************************!
!**********************************  GALERKIN BEM for 3D LAPLACE EQUATION: SINGULAR FORMULATION  **********************************!
!************************************  3-NODED TRIANGULAR ELEMENT: SEMI-ANALYTIC INTEGRATION  *************************************!
!************************************************  PIECEWISE LINEAR APPROXIMATION  ************************************************!
!*********************************************  Assemble h and g influence matrices  **********************************************!
!**********************************************************************************************************************************!

!*** Developer: Sylvain Nintcheu Fata
!*** Version:   V.1.1
!*** Released:  Jun 14, 2012

 
USE KINDS
USE SRF_GEOM, ONLY: nbnd,nbelt  ! nbnd == Total number of boundary nodes
                                ! nbelt == Total number of boundary elements
USE DISCR_BIE,ONLY: h,g         ! h == Potential influence matrix <==> Coefficient matrix acting on the vector of boundary potentials
                                ! g == Flux influence matrix <==> Coefficient matrix acting on the vector of boundary fluxes
USE SRF_GEOM, ONLY: EltDiam     ! EltDiam(k) == Diameter of the k-th boundary element
USE SRF_GEOM, ONLY: EltAreax2   ! EltAreax2(k) = 2*Area of the k-th boundary element
USE SRF_GEOM, ONLY: shfe1,shfe2 ! shfe1(l,k,i) == l-th shape function evaluated at Gauss point (k,i) for edge-adjacent integration: E'
				! shfe2(l,k,i) == l-th shape function evaluated at Gauss point (k,i) for edge-adjacent integration: E"
USE SRF_GEOM, ONLY: shfv	! shfv(l,k,i) == l-th shape function evaluated at Gauss point (k,i) for vertex-adjacent integration
USE GAUSS1D,  ONLY: xi1,xi2,xi3 ! xi1,xi2,xi3 == Arrays to store Gauss-Legendre points for integration over a segment [0,1]
USE GAUSS1D,  ONLY: wwg1 ! wwg1(k,i) = wg1(i)*wg1(k), where wg1(k) is the k-th Gauss-Legendre weight factor corresponding to xi1(k)
USE GAUSS1D,  ONLY: wwg2 ! wwg2(k,i) = wg2(i)*wg2(k), where wg2(k) is the k-th Gauss-Legendre weight factor corresponding to xi2(k)
USE GAUSS1D,  ONLY: wwg3 ! wwg3(k,i) = wg3(i)*wg3(k), where wg3(k) is the k-th Gauss-Legendre weight factor corresponding to xi3(k)


IMPLICIT NONE

 character(len=1) :: flag='U' ! flag='U' <==> Integration type is Undefined
 integer(kind=k9) :: i,k,elP,elQ,alloc_st



    allocate(h(nbnd,nbnd),g(nbnd,nbnd),STAT=alloc_st)
    if ( alloc_st == 0 ) then ! If h,g are successfully allocated
          loop0a: do k=1,nbnd ! loop over all boundary nodes
             loop0b: do i=1,nbnd ! loop over all boundary nodes
                h(i,k) = 0.0_dp; g(i,k) = 0.0_dp
             enddo loop0b
          enddo loop0a  

!*** Assemble h and g influence matrices **********************************************************!
 	  loop1a: do elP=1,nbelt ! Loop over all boundary elements

 	     call gbem_lap_iex_int_c(elP) ! Element P and element Q coincide ==> Coincident integration

 	     loop1b: do elQ=elP+1,nbelt ! Loop over the remaining boundary elements

 	  	if (EltAreax2(elQ) >= EltAreax2(elP)) then ! EltAreax2(elQ) = 2*area(elQ)

 	  	  call int_type(elP,elQ,flag) ! Determine integration type ==> get flag

 	  	    if ( flag == 'E' ) then	         ! If element P and element Q share a common edge
 	  		call gbem_lap_iex_int_e(elP,elQ) ! Edge-adjacent integration

 	  	    elseif( flag == 'V' ) then           ! If element P and element Q share a common vertex
 	  		call gbem_lap_iex_int_v(elP,elQ) ! Vertex-adjacent integration
 
 	  	    else			         ! Element P and element Q are not adjoining
 	  		call gbem_lap_iex_int(elP,elQ)   ! Non-Singular integration
 	  	    endif
 	  	else ! EltAreax2(elQ) < EltAreax2(elP)

 	  	  call int_type(elQ,elP,flag) ! Determine integration type ==> get flag

 	  	    if ( flag == 'E' ) then	         ! If element Q and element P share a common edge
 	  		call gbem_lap_iex_int_e(elQ,elP) ! Edge-adjacent integration
 
 	  	    elseif( flag == 'V' ) then           ! If element Q and element P share a common vertex
 	  		call gbem_lap_iex_int_v(elQ,elP) ! Vertex-adjacent integration
 
 	  	    else			         ! Element Q and element P are not adjoining
 	  		call gbem_lap_iex_int(elQ,elP)   ! Non-Singular integration
 	  	    endif
 	  	endif
 	     enddo loop1b
 	  enddo loop1a
!*** End Assemble h and g influence matrices ******************************************************!
    else
          write(*,*)'gbem_lap_assem: Allocate arrays "h,g" failed with Status=',alloc_st
          stop
    endif

    deallocate(shfv,shfe1,shfe2)
    deallocate(wwg1,wwg2,wwg3)
    deallocate(xi1,xi2,xi3)
    deallocate(EltAreax2,EltDiam)

!----------------------------------------------------------------------------------------------------------------------------------!
END SUBROUTINE gbem_lap_assem
!----------------------------------------------------------------------------------------------------------------------------------!
