aboutsummaryrefslogtreecommitdiff
path: root/src/qlm_coordinates.F90
diff options
context:
space:
mode:
Diffstat (limited to 'src/qlm_coordinates.F90')
-rw-r--r--src/qlm_coordinates.F90181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/qlm_coordinates.F90 b/src/qlm_coordinates.F90
new file mode 100644
index 0000000..6807bcd
--- /dev/null
+++ b/src/qlm_coordinates.F90
@@ -0,0 +1,181 @@
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Functions.h"
+#include "cctk_Parameters.h"
+
+
+
+subroutine qlm_calc_coordinates (CCTK_ARGUMENTS, hn)
+ use cctk
+ use constants
+ use qlm_boundary
+ implicit none
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_FUNCTIONS
+ DECLARE_CCTK_PARAMETERS
+ integer :: hn
+
+ CCTK_REAL, parameter :: one=1, two=2, half=one/two
+ CCTK_REAL :: z0, z0dot, z1, z1dot
+ CCTK_REAL :: qq(2,2), dtq
+ CCTK_REAL :: integral_z, area, radius
+ integer :: i0,j0
+ integer :: i,j
+
+ if (veryverbose/=0) then
+ call CCTK_INFO ("Finding invariant coordinates")
+ end if
+
+ ! latitude of "equator"
+ i0 = (qlm_ntheta(hn)+1)/2
+ ! longitude of zero meridian
+ j0 = 1+qlm_nghostsphi(hn)
+
+
+
+ ! calculate area
+ area = 0
+ do j = 1+qlm_nghostsphi(hn), qlm_nphi(hn)-qlm_nghostsphi(hn)
+ do i = 1+qlm_nghoststheta(hn), qlm_ntheta(hn)-qlm_nghoststheta(hn)
+
+ ! 2-metric on the horizon
+ qq(1,1) = qlm_qtt(i,j,hn)
+ qq(1,2) = qlm_qtp(i,j,hn)
+ qq(2,2) = qlm_qpp(i,j,hn)
+ qq(2,1) = qq(1,2)
+ dtq = qq(1,1) * qq(2,2) - qq(1,2) * qq(2,1)
+
+ area = area + sqrt(dtq) * qlm_delta_theta(hn) * qlm_delta_phi(hn)
+
+ end do
+ end do
+ radius = sqrt(area / (4*pi))
+
+
+
+ ! initial value
+ qlm_inv_z(i0,j0,hn) = 0
+
+ ! d_a z = 1/R^2 xi^b eps_ba
+
+ ! transport along equator
+ do j = j0+1, qlm_nphi(hn)-qlm_nghostsphi(hn)
+ i = i0
+
+ z0 = qlm_inv_z(i,j-1,hn)
+ z0dot = rhs(i,j-1,(/0,1/))
+ z1 = z0 + qlm_delta_phi(hn) * z0dot
+ z1dot = rhs(i,j,(/0,1/))
+ qlm_inv_z(i,j,hn) = z0 + half * qlm_delta_phi(hn) * (z0dot + z1dot)
+ end do
+
+ ! transport along meridians
+ do j = 1+qlm_nghostsphi(hn), qlm_nphi(hn)-qlm_nghostsphi(hn)
+ do i = i0-1, 1+qlm_nghoststheta(hn), -1
+ z0 = qlm_inv_z(i+1,j,hn)
+ z0dot = rhs(i+1,j,(/-1,0/))
+ z1 = z0 + qlm_delta_theta(hn) * z0dot
+ z1dot = rhs(i,j,(/-1,0/))
+ qlm_inv_z(i,j,hn) = z0 + half * qlm_delta_theta(hn) * (z0dot + z1dot)
+ end do
+
+ do i = i0+1, qlm_ntheta(hn)-qlm_nghoststheta(hn)
+ z0 = qlm_inv_z(i-1,j,hn)
+ z0dot = rhs(i-1,j,(/1,0/))
+ z1 = z0 + qlm_delta_theta(hn) * z0dot
+ z1dot = rhs(i,j,(/1,0/))
+ qlm_inv_z(i,j,hn) = z0 + half * qlm_delta_theta(hn) * (z0dot + z1dot)
+ end do
+ end do
+
+ ! normalise
+ integral_z = 0
+ do j = 1+qlm_nghostsphi(hn), qlm_nphi(hn)-qlm_nghostsphi(hn)
+ do i = 1+qlm_nghoststheta(hn), qlm_ntheta(hn)-qlm_nghoststheta(hn)
+
+ ! 2-metric on the horizon
+ qq(1,1) = qlm_qtt(i,j,hn)
+ qq(1,2) = qlm_qtp(i,j,hn)
+ qq(2,2) = qlm_qpp(i,j,hn)
+ qq(2,1) = qq(1,2)
+ dtq = qq(1,1) * qq(2,2) - qq(1,2) * qq(2,1)
+
+ integral_z = integral_z + qlm_inv_z(i,j,hn) * sqrt(dtq) * qlm_delta_theta(hn) * qlm_delta_phi(hn)
+
+ end do
+ end do
+ qlm_inv_z(:,:,hn) = qlm_inv_z(:,:,hn) - integral_z / area
+
+ ! boundary conditions
+ call set_boundary (CCTK_PASS_FTOF, hn, qlm_inv_z(:,:,hn), +1)
+
+
+
+#if 0
+
+ ! initial value
+ qlm_inv_phi(i0,j0,hn) = 0
+
+ ! xi^a d_a phi = C
+ ! z^a d_a phi = 0
+ ! z^a = (R^4 / q_bc xi^b xi^c) q^ab d_b z
+ ! v^a = A z^a + B xi^a
+ ! v^a d_a phi = (A z^a + B xi^a) d_a phi
+ ! = B C
+ ! (choose C=1, and normalise later)
+
+#error "replace z by phi"
+ ! transport along equator
+ do j = j0+1, qlm_nphi(hn)-qlm_nghostsphi(hn)
+ i = i0
+
+ z0 = qlm_inv_z(i,j-1,hn)
+ z0dot = rhs(i,j-1,(/0,1/))
+ z1 = z0 + qlm_delta_phi(hn) * z0dot
+ z1dot = rhs(i,j,(/0,1/))
+ qlm_inv_z(i,j,hn) = z0 + half * qlm_delta_phi(hn) * (z0dot + z1dot)
+ end do
+
+ ! transport along meridians
+ do j = 1+qlm_nghostsphi(hn), qlm_nphi(hn)-qlm_nghostsphi(hn)
+ do i = i0-1, 1+qlm_nghoststheta(hn), -1
+ z0 = qlm_inv_z(i+1,j,hn)
+ z0dot = rhs(i+1,j,(/-1,0/))
+ z1 = z0 + qlm_delta_theta(hn) * z0dot
+ z1dot = rhs(i,j,(/-1,0/))
+ qlm_inv_z(i,j,hn) = z0 + half * qlm_delta_theta(hn) * (z0dot + z1dot)
+ end do
+
+ do i = i0+1, qlm_ntheta(hn)-qlm_nghoststheta(hn)
+ z0 = qlm_inv_z(i-1,j,hn)
+ z0dot = rhs(i-1,j,(/1,0/))
+ z1 = z0 + qlm_delta_theta(hn) * z0dot
+ z1dot = rhs(i,j,(/1,0/))
+ qlm_inv_z(i,j,hn) = z0 + half * qlm_delta_theta(hn) * (z0dot + z1dot)
+ end do
+ end do
+
+#error "normalise"
+
+#endif
+
+contains
+
+ function rhs (i, j, vv) result (zdot)
+ integer, intent(in) :: i, j
+ integer, intent(in) :: vv(2)
+ CCTK_REAL :: zdot
+ CCTK_REAL :: qq(2,2), dtq
+
+ ! 2-metric on the horizon
+ qq(1,1) = qlm_qtt(i,j,hn)
+ qq(1,2) = qlm_qtp(i,j,hn)
+ qq(2,2) = qlm_qpp(i,j,hn)
+ qq(2,1) = qq(1,2)
+ dtq = qq(1,1) * qq(2,2) - qq(1,2) * qq(2,1)
+
+ zdot = vv(1) * (- (1/radius**2) * qlm_xi_p(i,j,hn) * sqrt(dtq)) &
+ + vv(2) * (+ (1/radius**2) * qlm_xi_t(i,j,hn) * sqrt(dtq))
+ end function rhs
+
+end subroutine qlm_calc_coordinates