aboutsummaryrefslogtreecommitdiff
path: root/src/qlm_coordinates.F90
blob: 17b7b0c2d90d312d667ef9e41fca303eb8ba3f0b (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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#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
  use tensor2
  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)
        
        call calc_2det (qq, dtq)
        
        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)
        
        call calc_2det (qq, dtq)
        
        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)
    
    call calc_2det (qq, dtq)
    
    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