aboutsummaryrefslogtreecommitdiff
path: root/src/qlm_tetrad.F90
diff options
context:
space:
mode:
Diffstat (limited to 'src/qlm_tetrad.F90')
-rw-r--r--src/qlm_tetrad.F90324
1 files changed, 324 insertions, 0 deletions
diff --git a/src/qlm_tetrad.F90 b/src/qlm_tetrad.F90
new file mode 100644
index 0000000..85837dc
--- /dev/null
+++ b/src/qlm_tetrad.F90
@@ -0,0 +1,324 @@
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Functions.h"
+#include "cctk_Parameters.h"
+
+
+
+subroutine qlm_calc_tetrad (CCTK_ARGUMENTS, hn)
+ use adm_metric_simple
+ use cctk
+ use classify
+ use matinv
+ use pointwise2
+ use qlm_boundary
+ use qlm_derivs
+ use qlm_gram_schmidt
+ use qlm_variables
+ use ricci4
+ use tensor
+ use tensor4
+ implicit none
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_FUNCTIONS
+ DECLARE_CCTK_PARAMETERS
+ integer :: hn
+
+ CCTK_REAL, parameter :: one=1, two=2
+ CCTK_REAL, parameter :: gg4(0:3,0:3,0:3) = 0
+ CCTK_REAL :: gg(3,3), dgg(3,3,3), gg_dot(3,3)
+ CCTK_REAL :: kk(3,3)
+ CCTK_REAL :: g4(0:3,0:3), gu4(0:3,0:3), dg4(0:3,0:3,0:3)
+ CCTK_REAL :: gamma4(0:3,0:3,0:3)
+ CCTK_REAL :: ee(0:3,0:3), ee_p(0:3,1:3), ee_p_p(0:3,1:3)
+ CCTK_REAL :: dee_spher(1:3,1:3,1:3), ee_inv(1:3,1:3)
+ CCTK_REAL :: dee(0:3,0:3,0:3), gee(0:3,0:3,0:3)
+ CCTK_REAL :: m1(0:3), m2(0:3) ! temporary variables to calculate mm
+ CCTK_REAL :: ss(0:3) ! spacelike outward normal to horizon
+ CCTK_REAL :: tt(0:3) ! timelike unit normal to hypersurface
+ CCTK_REAL :: ll(0:3) ! future null vector on the horizon
+ CCTK_REAL :: nn(0:3) ! future inward null vector
+ CCTK_COMPLEX :: mm(0:3) ! vector on horizon within the hypersurface
+ CCTK_REAL :: gtt(0:3,0:3), gss(0:3,0:3)
+ CCTK_REAL :: gm1(0:3,0:3), gm2(0:3,0:3)
+ CCTK_REAL :: gll(0:3,0:3), gnn(0:3,0:3)
+ CCTK_COMPLEX :: gmm(0:3,0:3)
+ CCTK_REAL :: nabla_ll(0:3,0:3), nabla_nn(0:3,0:3)
+ CCTK_COMPLEX :: nabla_mm(0:3,0:3)
+
+ CCTK_REAL :: t0, t1, t2
+ logical :: ce0, ce1, ce2
+ CCTK_REAL :: delta_space(2)
+
+ CCTK_REAL :: count, accuracy
+
+ integer :: lsh(2)
+ integer :: i, j
+ integer :: a, b, c, d
+ CCTK_REAL :: theta, phi
+
+ logical :: lerr
+
+ character*2, parameter :: crlf = achar(13) // achar(10)
+ character :: msg*1000
+
+ if (veryverbose/=0) then
+ call CCTK_INFO ("Setting tetrad")
+ end if
+
+ lsh(:) = (/ qlm_ntheta(hn), qlm_nphi(hn) /)
+ delta_space(:) = (/ qlm_delta_theta(hn), qlm_delta_phi(hn) /)
+
+ count = 0
+ accuracy = 0
+
+ ! Calculate the coordinates
+ do j = 1+qlm_nghostsphi(hn), qlm_nphi(hn)-qlm_nghostsphi(hn)
+ do i = 1+qlm_nghoststheta(hn), qlm_ntheta(hn)-qlm_nghoststheta(hn)
+ theta = qlm_origin_theta(hn) + (i-1)*qlm_delta_theta(hn)
+ phi = qlm_origin_phi(hn) + (j-1)*qlm_delta_phi(hn)
+
+ ! Get the variables from the arrays
+ gg(1,1) = qlm_gxx(i,j)
+ gg(1,2) = qlm_gxy(i,j)
+ gg(1,3) = qlm_gxz(i,j)
+ gg(2,2) = qlm_gyy(i,j)
+ gg(2,3) = qlm_gyz(i,j)
+ gg(3,3) = qlm_gzz(i,j)
+ gg(2,1) = gg(1,2)
+ gg(3,1) = gg(1,3)
+ gg(3,2) = gg(2,3)
+
+ dgg(1,1,1) = qlm_dgxxx(i,j)
+ dgg(1,2,1) = qlm_dgxyx(i,j)
+ dgg(1,3,1) = qlm_dgxzx(i,j)
+ dgg(2,2,1) = qlm_dgyyx(i,j)
+ dgg(2,3,1) = qlm_dgyzx(i,j)
+ dgg(3,3,1) = qlm_dgzzx(i,j)
+ dgg(2,1,1) = dgg(1,2,1)
+ dgg(3,1,1) = dgg(1,3,1)
+ dgg(3,2,1) = dgg(2,3,1)
+ dgg(1,1,2) = qlm_dgxxy(i,j)
+ dgg(1,2,2) = qlm_dgxyy(i,j)
+ dgg(1,3,2) = qlm_dgxzy(i,j)
+ dgg(2,2,2) = qlm_dgyyy(i,j)
+ dgg(2,3,2) = qlm_dgyzy(i,j)
+ dgg(3,3,2) = qlm_dgzzy(i,j)
+ dgg(2,1,2) = dgg(1,2,2)
+ dgg(3,1,2) = dgg(1,3,2)
+ dgg(3,2,2) = dgg(2,3,2)
+ dgg(1,1,3) = qlm_dgxxz(i,j)
+ dgg(1,2,3) = qlm_dgxyz(i,j)
+ dgg(1,3,3) = qlm_dgxzz(i,j)
+ dgg(2,2,3) = qlm_dgyyz(i,j)
+ dgg(2,3,3) = qlm_dgyzz(i,j)
+ dgg(3,3,3) = qlm_dgzzz(i,j)
+ dgg(2,1,3) = dgg(1,2,3)
+ dgg(3,1,3) = dgg(1,3,3)
+ dgg(3,2,3) = dgg(2,3,3)
+
+ kk(1,1) = qlm_kxx(i,j)
+ kk(1,2) = qlm_kxy(i,j)
+ kk(1,3) = qlm_kxz(i,j)
+ kk(2,2) = qlm_kyy(i,j)
+ kk(2,3) = qlm_kyz(i,j)
+ kk(3,3) = qlm_kzz(i,j)
+ kk(2,1) = kk(1,2)
+ kk(3,1) = kk(1,3)
+ kk(3,2) = kk(2,3)
+
+
+
+ ! Calculate 4-metric
+ call calc_3metricdot_simple (kk, gg_dot)
+ call calc_4metricderivs_simple (gg,dgg,gg_dot, g4,dg4)
+ call calc_4inv (g4, gu4)
+ call calc_4connections (gu4,dg4, gamma4)
+
+
+
+ ! The following must be consistent with qlm_tetrad.F90
+
+ ee = TAT_nan()
+ dee_spher = TAT_nan()
+ dee = TAT_nan()
+
+ ee(0,:) = 0
+ dee(0,:,:) = 0
+
+
+
+ ee(1,0) = 0
+ ee(1,1) = qlm_x(i,j,hn) - qlm_origin_x(hn)
+ ee(1,2) = qlm_y(i,j,hn) - qlm_origin_y(hn)
+ ee(1,3) = qlm_z(i,j,hn) - qlm_origin_z(hn)
+
+ ee_p(1,1) = qlm_x_p(i,j,hn) - qlm_origin_x_p(hn)
+ ee_p(1,2) = qlm_y_p(i,j,hn) - qlm_origin_y_p(hn)
+ ee_p(1,3) = qlm_z_p(i,j,hn) - qlm_origin_z_p(hn)
+
+ ee_p_p(1,1) = qlm_x_p_p(i,j,hn) - qlm_origin_x_p_p(hn)
+ ee_p_p(1,2) = qlm_y_p_p(i,j,hn) - qlm_origin_y_p_p(hn)
+ ee_p_p(1,3) = qlm_z_p_p(i,j,hn) - qlm_origin_z_p_p(hn)
+
+ dee(1,0,:) = 0
+ dee(1,1:3,0) = timederiv (ee(1,1:3), ee_p(1,1:3), ee_p_p(1,1:3), t0,t1,t2, ce0,ce1,ce2)
+ dee_spher(1,:,1) = 0 ! this is a choice
+ dee_spher(1,1,2:3) = deriv (qlm_x(:,:,hn), i,j, delta_space)
+ dee_spher(1,2,2:3) = deriv (qlm_y(:,:,hn), i,j, delta_space)
+ dee_spher(1,3,2:3) = deriv (qlm_z(:,:,hn), i,j, delta_space)
+
+
+
+ ee(2:3,0) = 0
+ ee(2:3,1) = deriv (qlm_x(:,:,hn), i,j, delta_space)
+ ee(2:3,2) = deriv (qlm_y(:,:,hn), i,j, delta_space)
+ ee(2:3,3) = deriv (qlm_z(:,:,hn), i,j, delta_space)
+
+ ee_p(2:3,1) = deriv (qlm_x_p(:,:,hn), i,j, delta_space)
+ ee_p(2:3,2) = deriv (qlm_y_p(:,:,hn), i,j, delta_space)
+ ee_p(2:3,3) = deriv (qlm_z_p(:,:,hn), i,j, delta_space)
+
+ ee_p_p(2:3,1) = deriv (qlm_x_p_p(:,:,hn), i,j, delta_space)
+ ee_p_p(2:3,2) = deriv (qlm_y_p_p(:,:,hn), i,j, delta_space)
+ ee_p_p(2:3,3) = deriv (qlm_z_p_p(:,:,hn), i,j, delta_space)
+
+ dee(2:3,0,:) = 0
+ dee(2:3,1:3,0) = timederiv (ee(2:3,1:3), ee_p(2:3,1:3), ee_p_p(2:3,1:3), t0,t1,t2, ce0,ce1,ce2)
+ dee_spher(2:3,:,1) = 0 ! this is a choice
+ dee_spher(2:3,1,2:3) = deriv2 (qlm_x(:,:,hn), i,j, delta_space)
+ dee_spher(2:3,2,2:3) = deriv2 (qlm_y(:,:,hn), i,j, delta_space)
+ dee_spher(2:3,3,2:3) = deriv2 (qlm_z(:,:,hn), i,j, delta_space)
+
+ ! ee_a^i
+ ! dee_spher_a^i,b
+ ! dee_a^i,j = ee_j^b dee_spher_a^i,b
+ call calc_inv3 (ee(1:3,1:3), ee_inv, lerr)
+ if (lerr) then
+ call CCTK_WARN (3, "Could not invert matrix")
+ end if
+ do a=1,3
+ do b=1,3
+ do c=1,3
+ dee(a,b,c) = 0
+ do d=1,3
+ dee(a,b,c) = dee(a,b,c) + ee_inv(c,d) * dee_spher(a,b,d)
+ end do
+ end do
+ end do
+ end do
+
+ do a=0,3
+ do b=0,3
+ gee(:,a,b) = dee(:,a,b)
+ do c=0,3
+ gee(:,a,b) = gee(:,a,b) + ee(:,c) * gamma4(a,c,b)
+ end do
+ end do
+ end do
+
+
+
+ ! tt
+ tt(:) = ee(0,:)
+ gtt(:,:) = gee(0,:,:)
+
+ ! m1 = ep
+ m1(:) = ee(3,:)
+ gm1(:,:) = gee(3,:,:)
+ call gram_schmidt_normalise (g4,gg4, m1,gm1, one)
+
+ ! m2 = et
+ m2(:) = ee(2,:)
+ gm2(:,:) = gee(2,:,:)
+ call gram_schmidt_project (g4,gg4, m1,gm1, one, m2,gm2)
+ call gram_schmidt_normalise (g4,gg4, m2,gm2, one)
+
+ ! ss = er
+ ss(:) = ee(1,:)
+ gss(:,:) = gee(1,:,:)
+ call gram_schmidt_project (g4,gg4, m1,gm1, one, ss,gss)
+ call gram_schmidt_project (g4,gg4, m2,gm2, one, ss,gss)
+ call gram_schmidt_normalise (g4,gg4, ss,gss, one)
+
+
+
+ ! ll = (tt + ss) / sqrt(two)
+ ll = (tt + ss) / sqrt(two)
+ gll = (gtt + gss) / sqrt(two)
+
+ ! nn = (tt - ss) / sqrt(two)
+ nn = (tt - ss) / sqrt(two)
+ gnn = (gtt - gss) / sqrt(two)
+
+ ! mm = cmplx(m1, m2, kind(mm)) / sqrt(two)
+ mm = cmplx(m1, m2, kind(mm)) / sqrt(two)
+ gmm = cmplx(gm1, gm2, kind(gmm)) / sqrt(two)
+
+
+
+ ! Store the stuff into the arrays
+ do a=0,3
+ do b=0,3
+ nabla_ll(a,b) = 0
+ nabla_nn(a,b) = 0
+ nabla_mm(a,b) = 0
+ do c=0,3
+ nabla_ll(a,b) = nabla_ll(a,b) + g4(a,c) * gll(c,b)
+ nabla_nn(a,b) = nabla_nn(a,b) + g4(a,c) * gnn(c,b)
+ nabla_mm(a,b) = nabla_mm(a,b) + g4(a,c) * gmm(c,b)
+ end do
+ qlm_tetrad_derivs(i,j)%nabla_ll(a,b) = nabla_ll(a,b)
+ qlm_tetrad_derivs(i,j)%nabla_nn(a,b) = nabla_nn(a,b)
+ qlm_tetrad_derivs(i,j)%nabla_mm(a,b) = nabla_mm(a,b)
+ end do
+ end do
+
+ qlm_l0(i,j,hn) = ll(0)
+ qlm_l1(i,j,hn) = ll(1)
+ qlm_l2(i,j,hn) = ll(2)
+ qlm_l3(i,j,hn) = ll(3)
+
+ qlm_n0(i,j,hn) = nn(0)
+ qlm_n1(i,j,hn) = nn(1)
+ qlm_n2(i,j,hn) = nn(2)
+ qlm_n3(i,j,hn) = nn(3)
+
+ qlm_m0(i,j,hn) = mm(0)
+ qlm_m1(i,j,hn) = mm(1)
+ qlm_m2(i,j,hn) = mm(2)
+ qlm_m3(i,j,hn) = mm(3)
+
+ end do
+ end do
+
+ if (count > 0) then
+ accuracy = sqrt(accuracy / count)
+ end if
+
+ if (veryverbose/=0) then
+ write (msg, '("Tetrad accuracy L2 norm: ",g12.4)') accuracy
+ call CCTK_INFO (msg)
+ end if
+
+!!$ if (accuracy > 1.0d-12) then
+ if (accuracy > 1.0d-8) then
+ call CCTK_WARN (1, "Tetrad is not accurate")
+ end if
+
+ call set_boundary (CCTK_PASS_FTOF, hn, qlm_l0(:,:,hn), +1)
+ call set_boundary (CCTK_PASS_FTOF, hn, qlm_l1(:,:,hn), +1)
+ call set_boundary (CCTK_PASS_FTOF, hn, qlm_l2(:,:,hn), +1)
+ call set_boundary (CCTK_PASS_FTOF, hn, qlm_l3(:,:,hn), +1)
+
+ call set_boundary (CCTK_PASS_FTOF, hn, qlm_n0(:,:,hn), +1)
+ call set_boundary (CCTK_PASS_FTOF, hn, qlm_n1(:,:,hn), +1)
+ call set_boundary (CCTK_PASS_FTOF, hn, qlm_n2(:,:,hn), +1)
+ call set_boundary (CCTK_PASS_FTOF, hn, qlm_n3(:,:,hn), +1)
+
+ call set_boundary (CCTK_PASS_FTOF, hn, qlm_m0(:,:,hn), +1)
+ call set_boundary (CCTK_PASS_FTOF, hn, qlm_m1(:,:,hn), +1)
+ call set_boundary (CCTK_PASS_FTOF, hn, qlm_m2(:,:,hn), +1)
+ call set_boundary (CCTK_PASS_FTOF, hn, qlm_m3(:,:,hn), +1)
+
+end subroutine qlm_calc_tetrad