aboutsummaryrefslogtreecommitdiff
path: root/src/NoExcision_mod.F90
diff options
context:
space:
mode:
Diffstat (limited to 'src/NoExcision_mod.F90')
-rw-r--r--src/NoExcision_mod.F90266
1 files changed, 266 insertions, 0 deletions
diff --git a/src/NoExcision_mod.F90 b/src/NoExcision_mod.F90
new file mode 100644
index 0000000..646d335
--- /dev/null
+++ b/src/NoExcision_mod.F90
@@ -0,0 +1,266 @@
+! $Header$
+
+#include "cctk.h"
+
+module NoExcision_mod
+
+ implicit none
+
+ CCTK_REAL, parameter :: zero = 0.0
+ integer, parameter :: wp = kind(zero)
+ CCTK_REAL, parameter :: one = 1.0_wp
+ CCTK_REAL, parameter :: two = 2.0_wp
+ CCTK_INT :: infnorm_handle, sum_handle
+ CCTK_INT :: sym_selector
+ CCTK_INT :: loop_counter
+ CCTK_REAL, dimension(16) :: infnormresid
+ CCTK_REAL, dimension(16) :: delta_new, delta_old, alpha, beta, absres
+ character(len=18), dimension(16) :: red_names = (/ 'NoExcision::redgxx', &
+ 'NoExcision::redgxy', &
+ 'NoExcision::redgxz', &
+ 'NoExcision::redgyy', &
+ 'NoExcision::redgyz', &
+ 'NoExcision::redgzz', &
+ 'NoExcision::redkxx', &
+ 'NoExcision::redkxy', &
+ 'NoExcision::redkxz', &
+ 'NoExcision::redkyy', &
+ 'NoExcision::redkyz', &
+ 'NoExcision::redkzz', &
+ 'NoExcision::red', &
+ 'NoExcision::redx', &
+ 'NoExcision::redy', &
+ 'NoExcision::redz' /)
+ character(len=5), dimension(16) :: var_names = (/ ' gxx', ' gxy', &
+ ' gxz', ' gyy', &
+ ' gyz', ' gzz', &
+ ' kxx', ' kxy', &
+ ' kxz', ' kyy', &
+ ' kyz', ' kzz', &
+ ' alp', 'betax', &
+ 'betay', 'betaz' /)
+ integer :: nx, ny, nz
+ integer :: ii
+ logical, dimension(16) :: cont = (/ (.true., ii=1, 16) /)
+
+ contains
+
+ ! This is the basic residual calculation routine...
+
+ subroutine residual (val, mask, res, si, order )
+ CCTK_REAL, dimension(:,:,:), intent(in) :: val
+ CCTK_INT, dimension(:,:,:), intent(in) :: mask
+ CCTK_REAL, dimension(:,:,:), intent(out) :: res
+ CCTK_REAL, intent(in) :: si
+ CCTK_INT, intent(in) :: order
+ CCTK_REAL, parameter :: six = 6.0_wp
+ CCTK_REAL, parameter :: sixth = 1.0_wp / six
+ CCTK_REAL, parameter :: four = 4.0_wp
+ CCTK_REAL, parameter :: eighteen = 18.0_wp
+ CCTK_REAL, parameter :: eighteenth = 1.0_wp / eighteen
+ CCTK_REAL, parameter :: fifteen = 15.0_wp
+ CCTK_REAL, parameter :: sixty = 60.0_wp
+ CCTK_REAL, parameter :: sixtieth = 1.0_wp / sixty
+ integer :: i, j, k
+
+ select case (order)
+ case (2)
+
+ do k = 2, nz-1
+ do j = 2, ny-1
+ do i = 2, nx-1
+
+ if (mask(i,j,k) > 0) then
+
+ res(i,j,k) = val(i+1,j,k) + val(i-1,j,k) + val(i,j+1,k) + &
+ val(i,j-1,k) + val(i,j,k+1) + val(i,j,k-1) - &
+ six * val(i,j,k)
+ res(i,j,k) = sign(one,si) * res(i,j,k)
+
+ end if
+
+ end do
+ end do
+ end do
+
+ case (4)
+
+ do k = 3, nz-2
+ do j = 3, ny-2
+ do i = 3, nx-2
+
+ if (mask(i,j,k) > 0) then
+
+ res(i,j,k) = - ( val(i+2,j,k) + val(i-2,j,k) + &
+ val(i,j+2,k) + val(i,j-2,k) + &
+ val(i,j,k+2) + val(i,j,k-2) ) + &
+ four * ( val(i+1,j,k) + val(i-1,j,k) + &
+ val(i,j+1,k) + val(i,j-1,k) + &
+ val(i,j,k+1) + val(i,j,k-1) ) - &
+ eighteen * val(i,j,k)
+ res(i,j,k) = sign(one,si) * res(i,j,k)
+
+ end if
+
+ end do
+ end do
+ end do
+
+ case (6)
+
+ do k = 4, nz-3
+ do j = 4, ny-3
+ do i = 4, nx-3
+
+ if (mask(i,j,k) > 0) then
+
+ res(i,j,k) = ( val(i+3,j,k) + val(i-3,j,k) + &
+ val(i,j+3,k) + val(i,j-3,k) + &
+ val(i,j,k+3) + val(i,j,k-3) ) - &
+ six * ( val(i+2,j,k) + val(i-2,j,k) + &
+ val(i,j+2,k) + val(i,j-2,k) + &
+ val(i,j,k+2) + val(i,j,k-2) ) + &
+ fifteen * ( val(i+1,j,k) + val(i-1,j,k) + &
+ val(i,j+1,k) + val(i,j-1,k) + &
+ val(i,j,k+1) + val(i,j,k-1) ) - &
+ sixty * val(i,j,k)
+ res(i,j,k) = sign(one,si) * res(i,j,k)
+
+ end if
+
+ end do
+ end do
+ end do
+
+ case default
+
+ call CCTK_WARN ( 0, 'Internal error: Order out of range' )
+
+ end select
+
+ end subroutine residual
+
+
+ ! This is the routine calculating residuals for all variables, that
+ ! have not yet converged.
+
+ subroutine residual_all ( v1, v2, v3, v4, v5, v6, v7, v8, &
+ v9, v10, v11, v12, v13, v14, v15, v16, &
+ r1, r2, r3, r4, r5, r6, r7, r8, &
+ r9, r10, r11, r12, r13, r14, r15, r16, &
+ mask, si, order )
+
+ CCTK_REAL, dimension(:,:,:), intent(in) :: v1, v2, v3, v4, v5, v6, &
+ v7, v8, v9, v10, v11, v12, &
+ v13, v14, v15, v16
+ CCTK_REAL, dimension(:,:,:), intent(out) :: r1, r2, r3, r4, r5, r6, &
+ r7, r8, r9, r10, r11, r12, &
+ r13, r14, r15, r16
+ CCTK_INT, dimension(:,:,:), intent(in) :: mask
+ CCTK_REAL, intent(in) :: si
+ CCTK_INT, intent(in) :: order
+
+ if ( cont(1) ) call residual ( v1, mask, r1, si, order )
+ if ( cont(2) ) call residual ( v2, mask, r2, si, order )
+ if ( cont(3) ) call residual ( v3, mask, r3, si, order )
+ if ( cont(4) ) call residual ( v4, mask, r4, si, order )
+ if ( cont(5) ) call residual ( v5, mask, r5, si, order )
+ if ( cont(6) ) call residual ( v6, mask, r6, si, order )
+ if ( cont(7) ) call residual ( v7, mask, r7, si, order )
+ if ( cont(8) ) call residual ( v8, mask, r8, si, order )
+ if ( cont(9) ) call residual ( v9, mask, r9, si, order )
+ if ( cont(10) ) call residual ( v10, mask, r10, si, order )
+ if ( cont(11) ) call residual ( v11, mask, r11, si, order )
+ if ( cont(12) ) call residual ( v12, mask, r12, si, order )
+ if ( cont(13) ) call residual ( v13, mask, r13, si, order )
+ if ( cont(14) ) call residual ( v14, mask, r14, si, order )
+ if ( cont(15) ) call residual ( v15, mask, r15, si, order )
+ if ( cont(16) ) call residual ( v16, mask, r16, si, order )
+
+ end subroutine residual_all
+
+
+ ! This routine multiplies two variables. Only does it according
+ ! to the mask and only for variables that have not converged yet.
+
+ subroutine multiply ( u1, u2, u3, u4, u5, u6, u7, u8, &
+ u9, u10, u11, u12, u13, u14, u15, u16, &
+ v1, v2, v3, v4, v5, v6, v7, v8, &
+ v9, v10, v11, v12, v13, v14, v15, v16, &
+ r1, r2, r3, r4, r5, r6, r7, r8, &
+ r9, r10, r11, r12, r13, r14, r15, r16, &
+ mask )
+
+ CCTK_REAL, dimension(:,:,:), intent(in) :: u1, u2, u3, u4, u5, u6, &
+ u7, u8, u9, u10, u11, u12, &
+ u13, u14, u15, u16
+ CCTK_REAL, dimension(:,:,:), intent(in) :: v1, v2, v3, v4, v5, v6, &
+ v7, v8, v9, v10, v11, v12, &
+ v13, v14, v15, v16
+ CCTK_REAL, dimension(:,:,:), intent(out) :: r1, r2, r3, r4, r5, r6, &
+ r7, r8, r9, r10, r11, r12, &
+ r13, r14, r15, r16
+ CCTK_INT, dimension(:,:,:), intent(in) :: mask
+
+ if ( cont(1) ) where ( mask > 0 ) r1 = u1*v1
+ if ( cont(2) ) where ( mask > 0 ) r2 = u2*v2
+ if ( cont(3) ) where ( mask > 0 ) r3 = u3*v3
+ if ( cont(4) ) where ( mask > 0 ) r4 = u4*v4
+ if ( cont(5) ) where ( mask > 0 ) r5 = u5*v5
+ if ( cont(6) ) where ( mask > 0 ) r6 = u6*v6
+ if ( cont(7) ) where ( mask > 0 ) r7 = u7*v7
+ if ( cont(8) ) where ( mask > 0 ) r8 = u8*v8
+ if ( cont(9) ) where ( mask > 0 ) r9 = u9*v9
+ if ( cont(10) ) where ( mask > 0 ) r10 = u10*v10
+ if ( cont(11) ) where ( mask > 0 ) r11 = u11*v11
+ if ( cont(12) ) where ( mask > 0 ) r12 = u12*v12
+ if ( cont(13) ) where ( mask > 0 ) r13 = u13*v13
+ if ( cont(14) ) where ( mask > 0 ) r14 = u14*v14
+ if ( cont(15) ) where ( mask > 0 ) r15 = u15*v15
+ if ( cont(16) ) where ( mask > 0 ) r16 = u16*v16
+
+ end subroutine multiply
+
+
+ ! This routine takes the product of a scalar and a variable and
+ ! adds it to the product of another scalar and variable. Does it
+ ! according to the mask and only for variables that have not yet
+ ! converged.
+
+ subroutine multiply_sum ( u1, u2, u3, u4, u5, u6, u7, u8, &
+ u9, u10, u11, u12, u13, u14, u15, u16, &
+ v1, v2, v3, v4, v5, v6, v7, v8, &
+ v9, v10, v11, v12, v13, v14, v15, v16, &
+ c1, c2, mask )
+
+ CCTK_REAL, dimension(:,:,:), intent(inout) :: u1, u2, u3, u4, u5, u6, &
+ u7, u8, u9, u10, u11, u12, &
+ u13, u14, u15, u16
+ CCTK_REAL, dimension(:,:,:), intent(in) :: v1, v2, v3, v4, v5, v6, &
+ v7, v8, v9, v10, v11, v12, &
+ v13, v14, v15, v16
+ CCTK_REAL, dimension(16), intent(in) :: c1, c2
+ CCTK_INT, dimension(:,:,:), intent(in) :: mask
+
+
+ if ( cont(1) ) where ( mask > 0 ) u1 = c1(1)*u1 + c2(1)*v1
+ if ( cont(2) ) where ( mask > 0 ) u2 = c1(2)*u2 + c2(2)*v2
+ if ( cont(3) ) where ( mask > 0 ) u3 = c1(3)*u3 + c2(3)*v3
+ if ( cont(4) ) where ( mask > 0 ) u4 = c1(4)*u4 + c2(4)*v4
+ if ( cont(5) ) where ( mask > 0 ) u5 = c1(5)*u5 + c2(5)*v5
+ if ( cont(6) ) where ( mask > 0 ) u6 = c1(6)*u6 + c2(6)*v6
+ if ( cont(7) ) where ( mask > 0 ) u7 = c1(7)*u7 + c2(7)*v7
+ if ( cont(8) ) where ( mask > 0 ) u8 = c1(8)*u8 + c2(8)*v8
+ if ( cont(9) ) where ( mask > 0 ) u9 = c1(9)*u9 + c2(9)*v9
+ if ( cont(10) ) where ( mask > 0 ) u10 = c1(10)*u10 + c2(10)*v10
+ if ( cont(11) ) where ( mask > 0 ) u11 = c1(11)*u11 + c2(11)*v11
+ if ( cont(12) ) where ( mask > 0 ) u12 = c1(12)*u12 + c2(12)*v12
+ if ( cont(13) ) where ( mask > 0 ) u13 = c1(13)*u13 + c2(13)*v13
+ if ( cont(14) ) where ( mask > 0 ) u14 = c1(14)*u14 + c2(14)*v14
+ if ( cont(15) ) where ( mask > 0 ) u15 = c1(15)*u15 + c2(15)*v15
+ if ( cont(16) ) where ( mask > 0 ) u16 = c1(16)*u16 + c2(16)*v16
+
+ end subroutine multiply_sum
+
+
+end module NoExcision_mod