vtf-logo

weno/applications/euler/2d/RM_Jacobs/src/cles_dcflag.f

c     xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
c
c                Curvature based detection
c
c     xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

      subroutine cles_dcflag(ux,vx,dcflag,ncomps,nvars,
     $     ixlo,ixhi,iylo,iyhi, nx, ny, dx, dy, 
     $     direction,extra)

      implicit none
 
      include 'cles.i'
      include 'cuser.i'

      integer ncomps, nvars
      integer ixlo, ixhi, iylo,iyhi
      integer nx, ny, direction, extra(*)
      integer dcflag(1:nx+1,1:ny+1,2)
      double precision ux(ncomps,ixlo:ixhi,iylo:iyhi)
      double precision vx(nvars,ixlo:ixhi,iylo:iyhi)
      double precision dx, dy

      integer i, j, m, slow, shigh, l, nspanx, nspany
      double precision grdS1, grdS2, x, y
      double precision apress, bpress, cpress
      double precision arho, brho, crho

      integer dcspan
      parameter (dcspan=6)

c--------------------------------------------------------------------------
c     Use gradient detection for the scalar

      if ( direction .eq. 1 ) then
c     test criteria at each point
         do j=1, ny, 1
            do i = 1, nx, 1
               grdS1 = (vx(6,i+1,j)-vx(6,i-1,j))/2.0d0
               grdS2 = (vx(7,i+1,j)-vx(7,i-1,j))/2.0d0
               if (abs(grdS1).gt.gradS .or. 
     $              abs(grdS2).gt.gradS) then
c     we will use WENO here
                  slow = max(i-dcspan,1)
                  shigh = min(i+1+dcspan,nx+1)
                  do m=slow,shigh
                     dcflag(m,j,direction) = CLES_SWITCH_WENO
                  enddo
               end if
            enddo
         enddo
      else
         do j=1, ny, 1
            do i = 1, nx, 1
               grdS1 = (vx(6,i,j+1)-vx(6,i,j-1))/2.0d0
               grdS2 = (vx(7,i,j+1)-vx(7,i,j-1))/2.0d0
               if (abs(grdS1).gt.gradS .or. 
     $              abs(grdS2).gt.gradS) then
c     we will use WENO here
                  slow = max(j-dcspan,1)
                  shigh = min(j+1+dcspan,ny+1)
                  do m=slow,shigh
                     dcflag(i,m,direction) = CLES_SWITCH_WENO
                  enddo
               end if
            enddo
         enddo
      endif
c--------------------------------------------------------------------------

c--------------------------------------------------------------------------
c     Correlation detection 
      
      if ( direction .eq. 1 ) then
c     This is esentially (nghost - span)*2.
         nspanx = (1-ixlo-span)*2
         if ( nspanx .lt. 2 ) then
            print *, 'Number of ghost cells is too low for'//
     $           ' non-linear projection flagging'
            stop
         endif

         do j=1, ny, 1
         do l=1-nspanx, 1+nx*2+nspanx, 1
            if ( mod(l,2) .eq. 0 ) then
c     Center of cell
               i = l/2
c     Correlation of the pressure field (nfield=5) with a centered tanh
               call TanhCorrel(span,span,thvec,sumth,sumth2,
     &              vx,nvars,ixlo,ixhi,iylo,iyhi,i,j,5,direction,
     $              apress,bpress,cpress)
            
               if ( abs(bpress) .lt. minjump*abs(apress) ) cycle
               if ( abs(cpress).lt. minc) cycle
               
c            call TanhCorrel(span,span,thvec,sumth,sumth2,
c     &           vx,nvars,ixlo,ixhi,iylo,iyhi,i,j,1,direction,arho,brho,crho)

c            if ( abs(brho) .lt. minjump*abs(arho) ) cycle
c            if ( abs(crho).lt. minc) cycle

c            if ( crho*cpress .lt. 0.0 ) then
               slow = max(i-dcspan,1)
               shigh = min(i+dcspan+1,nx+1)
               do m=slow,shigh
                  dcflag(m,j,direction) = CLES_SWITCH_WENO
               enddo
c            endif
            else
c     Wall of cell
               i = 1+l/2
c     Correlation of the pressure field (nfield=5) with a shifted tanh
               call TanhCorrel(span,span-1,thvecbis,sumthbis,sumth2bis,
     &              vx,nvars,ixlo,ixhi,iylo,iyhi,i,j,5,direction,
     $              apress,bpress,cpress)

               if ( abs(bpress) .lt. minjump*abs(apress) ) cycle
               if ( abs(cpress).lt. minc) cycle
            
c            call TanhCorrel(span,span-1,thvecbis,sumthbis,sumth2bis,
c     &           vx,nvars,ixlo,ixhi,iylo,iyhi,i,j,1,direction,arho,brho,crho)

c            if ( abs(brho) .lt. minjump*abs(arho)) cycle
c            if ( abs(crho).lt. minc) cycle

c            if ( crho*cpress .lt. 0.0 ) then
               slow = max(i-dcspan,1)
               shigh = min(i+dcspan,nx+1)
               do m=slow,shigh
                  dcflag(m,j,direction) = CLES_SWITCH_WENO
               enddo
c     endif
            endif
         enddo
         enddo
      else
c     This is esentially (nghost - span)*2.
         nspany = (1-iylo-span)*2
         if ( nspany .lt. 2 ) then
            print *, 'Number of ghost cells is too low for'//
     $           ' non-linear projection flagging'
            stop
         endif

         do i=1, nx, 1
         do l=1-nspany, 1+ny*2+nspany, 1
            if ( mod(l,2) .eq. 0 ) then
c     Center of cell
               j = l/2
c     Correlation of the pressure field (nfield=5) with a centered tanh
               call TanhCorrel(span,span,thvec,sumth,sumth2,
     &              vx,nvars,ixlo,ixhi,iylo,iyhi,i,j,5,direction,
     $              apress,bpress,cpress)
            
               if ( abs(bpress) .lt. minjump*abs(apress) ) cycle
               if ( abs(cpress).lt. minc) cycle
               
c            call TanhCorrel(span,span,thvec,sumth,sumth2,
c     &           vx,nvars,ixlo,ixhi,iylo,iyhi,i,j,1,direction,arho,brho,crho)

c            if ( abs(brho) .lt. minjump*abs(arho) ) cycle
c            if ( abs(crho).lt. minc) cycle

c            if ( crho*cpress .lt. 0.0 ) then
               slow = max(j-dcspan,1)
               shigh = min(j+dcspan+1,ny+1)
               do m=slow,shigh
                  dcflag(i,m,direction) = CLES_SWITCH_WENO
               enddo
c            endif
            else
c     Wall of cell
               j = 1+l/2
c     Correlation of the pressure field (nfield=5) with a shifted tanh
               call TanhCorrel(span,span-1,thvecbis,sumthbis,sumth2bis,
     &              vx,nvars,ixlo,ixhi,iylo,iyhi,i,j,5,direction,
     $              apress,bpress,cpress)

               if ( abs(bpress) .lt. minjump*abs(apress) ) cycle
               if ( abs(cpress).lt. minc) cycle
            
c            call TanhCorrel(span,span-1,thvecbis,sumthbis,sumth2bis,
c     &           vx,nvars,ixlo,ixhi,iylo,iyhi,i,j,1,direction,arho,brho,crho)

c            if ( abs(brho) .lt. minjump*abs(arho)) cycle
c            if ( abs(crho).lt. minc) cycle

c            if ( crho*cpress .lt. 0.0 ) then
               slow = max(j-dcspan,1)
               shigh = min(j+dcspan,ny+1)
               do m=slow,shigh
                  dcflag(i,m,direction) = CLES_SWITCH_WENO
               enddo
c     endif
            endif
         enddo
         enddo
      endif
c--------------------------------------------------------------------------
      
c--------------------------------------------------------------------------
c     Flag the boundaries 
      if ( direction .eq. 1 ) then
         do j=1, ny
            do i=1, nx
               call cles_xLocation(i,x)
               if ( x.lt.(GeomMin(1)+2.0d0*dx) ) then
                  if ( trunc .ne. 1 ) then
                  do m=1, i+1
                     dcflag(m,j,direction) = CLES_SWITCH_WENO
                  enddo
                  endif
               else if (x.gt.(GeomMax(1)-2.0d0*dx)) then
                  do m=i,nx+1
                     dcflag(m,j,direction) = CLES_SWITCH_WENO
                  enddo
               endif
            enddo
         enddo
      else
         do j=1, ny
            do i=1, nx
               call cles_yLocation(j,y)
               if ( y.lt.(GeomMin(2)+2.0d0*dy) ) then
                  do m=1, j+1
                     dcflag(i,m,direction) = CLES_SWITCH_WENO
                  enddo
               else if (y.gt.(GeomMax(2)-2.0d0*dy)) then
                  do m=j,ny+1
                     dcflag(i,m,direction) = CLES_SWITCH_WENO
                  enddo
               endif
            enddo
         enddo
      endif
c--------------------------------------------------------------------------  

      return
      end


c     xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
   
      subroutine TanhCorrel(span,span1,thvec,sumth,sumth2,
     &     vx,nvars,ixlo,ixhi,iylo,iyhi,i,j,nfield,direction,a,b,c)

c     xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 
c     Correlation based detection of the field vx(.,nfield) with a tanh 
c     profile. Local least-square fitting of a+b*tanh(x/dwidth) or abis
c     +bbis*tanh((x+dx/2)/dwidth)
c     Thickness of the profile in terms of grid sizes. A value of 1 means 
c     a discontinuity of 6 grids points because of the thickness of the 
c     tanh(): dwidth (e.g. = 0.75d0)
c     Minimum value of a correlation coefficient considered to be a good 
c     match: minc (e.g. = 0.9d0)
c     To discriminate small oscillations in the coorelated field that have 
c     no meaning, we stipulate that any jump in the field below 'minjump' 
c     of the mean value is not a jump (e.g. minjump = 0.02d0 for 2%)
    
      implicit none

c      include 'cuser.i'

      double precision sumth,sumth2      
      integer span,span1,nvars,ixlo,ixhi,iylo,iyhi,i,j,nfield,direction
      double precision thvec(-span:span1)   
      double precision vx(nvars,ixlo:ixhi,iylo:iyhi)
      double precision a,b,c
      
      integer m
      double precision sumy,sumyt,sum
      double precision det,dp

      a = 0.0d0
      b = 0.0d0
      det = 0.0d0
      
      sumy = 0.0d0
      sumyt = 0.0d0
      if ( direction .eq. 1 ) then
         do m=-span,span1, 1
            sumy = sumy + vx(nfield,i+m,j)
            sumyt = sumyt + vx(nfield,i+m,j)*thvec(m)
         enddo
      else
         do m=-span,span1, 1
            sumy = sumy + vx(nfield,i,j+m)
            sumyt = sumyt + vx(nfield,i,j+m)*thvec(m)
         enddo
      endif
         
c     Optimal values
      det = dble(span1+span+1)*sumth2-sumth*sumth
      a = (sumy*sumth2-sumth*sumyt)/det
      b = (dble(span1+span+1)*sumyt-sumth*sumy)/det
         
c     Compute correlation 
      dp = 0.0d0
      c = 0.0d0
      sum = 0.0d0
      sumy = 0.0d0
      if ( direction .eq. 1 ) then
         do m=-span,span1, 1
            dp = vx(nfield,i+m,j)-a
            sum = sum + dp*thvec(m)
            sumy = sumy + dp*dp
         enddo
      else
         do m=-span,span1, 1
            dp = vx(nfield,i,j+m)-a
            sum = sum + dp*thvec(m)
            sumy = sumy + dp*dp
         enddo
      endif
      if ( abs(sumy) .lt. 1.0d-12 ) then
         c = 0.0d0
      else
         c = sum/sqrt(sumy*sumth2)
      endif

      return
      end