aboutsummaryrefslogtreecommitdiff
path: root/src/findnormals.F90
blob: 3d6a7d04bb6761c05c8571f1840b4d896106ef1d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
! $Header$

! Take a mask where the boundary has been been marked.
! Return information about the normals in these locations.

#include "cctk.h"
#include "cctk_Parameters.h"

#include "maskvalues.h"

subroutine excision_findnormals (ierr, mask, dirx, diry, dirz, ni, nj, nk)

  implicit none

  DECLARE_CCTK_FUNCTIONS
  DECLARE_CCTK_PARAMETERS
  
  ! Arguments
  
  ! out: zero for success, nonzero for error
  integer      :: ierr
  
  ! in: array sizes for grid functions
  !     (you can pass in cctk_lsh(:) for these)
  integer      :: ni,nj,nk

  ! in: mask
  CCTK_REAL    :: mask(ni,nj,nk)
  
  ! out: normal directions to use for interpolation
  CCTK_REAL    :: dirx(ni,nj,nk), diry(ni,nj,nk), dirz(ni,nj,nk)

! Extra variables.
  integer i,j,k,ii,jj,kk
  integer sx,sy,sz,smax

! Initialise direction arrays to zero.

  dirx = 0
  diry = 0
  dirz = 0

! Loop over grid points.

  do k=2,nk-1
     do j=2,nj-1
        do i=2,ni-1

!          Check if the point is in the boundary.

           if (mask(i,j,k)==MASK_BOUNDARY) then

!             Initialise integer vector (sx,sy,sz) to zero.

              sx = 0; sy = 0; sz = 0

!             Loop around nearest neighbours.

              do kk=-1,1
                 do jj=-1,1
                    do ii=-1,1

!                      If a neighbour is active, add its relative
!                      coordinates to (sx,sy,sz).

                       if (mask(i+ii,j+jj,k+kk)==MASK_ACTIVE) then
                          sx = sx + ii; sy = sy + jj; sz = sz + kk
                       end if

                    end do
                 end do
              end do

!             Find maximum component of (sx,sy,sz).

              smax = max(abs(sx),abs(sy),abs(sz))

!             Do an integer division of (sx,sy,sz) with smax.
!             This ensures that we end up with a vector that
!             has only 0 and +-1 as components.

              sx = sx/smax
              sy = sy/smax
              sz = sz/smax

              dirx(i,j,k) = sx
              diry(i,j,k) = sy
              dirz(i,j,k) = sz

!             Sanity check.

              if (mask(i+sx,j+sy,k+sz) /= MASK_ACTIVE) then
                 call CCTK_WARN (0, "Mask boundary layer is too thick")
              end if

           end if
           
        end do
     end do
  end do
  
  ! Success

  ierr = 0
  
end subroutine excision_findnormals