12 using namespace Utilities;
13 using namespace Z4VectorShortcuts;
20 double *s_x, *s_y, *s_z;
21 double al, A, Am1, be, B, phi, R, r,
X;
22 int ivar, i,
j, k, i3D, indx;
26 if (solve_momentum_constraint)
29 s_x =
new double[n1*n2*n3]();
30 s_y =
new double[n1*n2*n3]();
31 s_z =
new double[n1*n2*n3]();
32 allocate_derivs (&U, nvar);
33 for (ivar = 0; ivar < nvar; ivar++)
34 for (i = 0; i < n1; i++)
35 for (
j = 0;
j < n2;
j++)
36 for (k = 0; k < n3; k++)
38 i3D = Index(ivar,i,
j,k,1,n1,n2,n3);
40 al = Pih * (2 * i + 1) / n1;
42 be = Pih * (2 *
j + 1) / n2;
44 phi = 2. * Pi * k / n3;
47 AB_To_XR (nvar, A, B, &
X, &R, U);
49 C_To_c (nvar,
X, R, &(s_x[i3D]), &r, U);
51 rx3_To_xyz (nvar, s_x[i3D], r, phi, &(s_y[i3D]), &(s_z[i3D]), U);
62 for (ivar = 0; ivar < nvar; ivar++)
63 for (i = 0; i < n1; i++)
64 for (
j = 0;
j < n2;
j++)
65 for (k = 0; k < n3; k++)
67 indx = Index(ivar,i,
j,k,1,n1,n2,n3);
68 v.d0[indx]/=(-cos(Pih * (2 * i + 1) / n1)-1.0);
70 Derivatives_AB3 (nvar, n1, n2, n3,
v);
71 if (do_initial_debug_output &&
TP_MyProc() == 0)
73 debug_file=fopen(
"initial.dat",
"w");
75 for (ivar = 0; ivar < nvar; ivar++)
76 for (i = 0; i < n1; i++)
77 for (
j = 0;
j < n2;
j++)
79 al = Pih * (2 * i + 1) / n1;
82 be = Pih * (2 *
j + 1) / n2;
85 indx = Index(ivar,i,
j,0,1,n1,n2,n3);
86 U.
d0[0] = Am1 *
v.d0[indx];
87 U.
d1[0] =
v.d0[indx] + Am1 *
v.d1[indx];
88 U.
d2[0] = Am1 *
v.d2[indx];
89 U.
d3[0] = Am1 *
v.d3[indx];
90 U.
d11[0] = 2 *
v.d1[indx] + Am1 *
v.d11[indx];
91 U.
d12[0] =
v.d2[indx] + Am1 *
v.d12[indx];
92 U.
d13[0] =
v.d3[indx] + Am1 *
v.d13[indx];
93 U.
d22[0] = Am1 *
v.d22[indx];
94 U.
d23[0] = Am1 *
v.d23[indx];
95 U.
d33[0] = Am1 *
v.d33[indx];
97 AB_To_XR (nvar, A, B, &
X, &R, U);
99 C_To_c (nvar,
X, R, &(s_x[indx]), &r, U);
101 rx3_To_xyz (nvar, s_x[i3D], r, phi, &(s_y[indx]), &(s_z[indx]), U);
103 "%.16g %.16g %.16g %.16g %.16g %.16g %.16g %.16g %.16g %.16g "
104 "%.16g %.16g %.16g %.16g %.16g %.16g %.16g %.16g %.16g\n",
105 (
double)s_x[indx], (
double)s_y[indx],
108 (
double)(-cos(Pih * (2 * i + 1) / n1)-1.0),
124 fprintf(debug_file,
"\n\n");
125 for (i=n2-10; i<n2; i++)
128 indx = Index(0,0,i,0,1,n1,n2,n3);
129 d = PunctIntPolAtArbitPosition(0, nvar, n1, n2, n3,
v,
130 s_x[indx], 0.0, 0.0);
131 fprintf(debug_file,
"%.16g %.16g\n",
132 (
double)s_x[indx], (
double)d);
134 fprintf(debug_file,
"\n\n");
135 for (i=n2-10; i<n2-1; i++)
138 int ip= Index(0,0,i+1,0,1,n1,n2,n3);
139 indx = Index(0,0,i,0,1,n1,n2,n3);
140 for (
j=-10;
j<10;
j++)
142 d = PunctIntPolAtArbitPosition(0, nvar, n1, n2, n3,
v,
143 s_x[indx]+(s_x[ip]-s_x[indx])*
j/10,
145 fprintf(debug_file,
"%.16g %.16g\n",
146 (
double)(s_x[indx]+(s_x[ip]-s_x[indx])*
j/10), (
double)d);
149 fprintf(debug_file,
"\n\n");
150 for (i = 0; i < n1; i++)
151 for (
j = 0;
j < n2;
j++)
153 X = 2*(2.0*i/n1-1.0);
157 C_To_c (nvar,
X, R, &(s_x[indx]), &r, U);
158 rx3_To_xyz (nvar, s_x[i3D], r, phi, &(s_y[indx]), &(s_z[indx]), U);
159 *U.
d0 = s_x[indx]*s_x[indx];
166 C_To_c (nvar,
X, R, &(s_x[indx]), &r, U);
168 "%.16g %.16g %.16g %.16g %.16g %.16g %.16g %.16g %.16g %.16g %.16g\n",
169 (
double)s_x[indx], (
double)r, (
double)
X, (
double)R, (
double)U.
d0[0],
183 free_derivs (&U, nvar);
192 nvar = 1; n1 = npoints_A; n2 = npoints_B; n3 = npoints_phi;
193 _n1_low = npoints_A_low; _n2_low = npoints_B_low; _n3_low = npoints_phi_low;
198 int imin[3], imax[3];
199 int const ntotal = n1 * n2 * n3 * nvar;
203 static double *F = NULL;
210 allocate_derivs (&
u, ntotal);
211 allocate_derivs (&
v, ntotal);
212 allocate_derivs (&cf_v, ntotal);
215 TP_INFO (
"Solving puncture equation for BH-NS/NS-NS system");
217 TP_INFO (
"Solving puncture equation for BH-BH system");
219 TP_INFO (
"b = %g", par_b);
222 for (
int j = 0;
j < ntotal;
j++)
246 if (use_external_initial_guess)
248 set_initial_guess(
v);
254 if(!(give_bare_mass)) {
255 double tmp, mp_adm_err, mm_adm_err;
258 double M_p = target_M_plus;
259 double M_m = target_M_minus;
261 TP_INFO (
"Attempting to find bare masses.");
262 TP_INFO (
"Target ADM masses: M_p=%g and M_m=%g",
263 (
double) M_p, (
double) M_m);
264 TP_INFO (
"ADM mass tolerance: %g", (
double) adm_tol);
268 TP_INFO (
"Bare masses: mp=%.15g, mm=%.15g",
269 (
double)mp, (
double)mm);
270 Newton (nvar, n1, n2, n3,
v, Newton_tol, 1);
272 F_of_v (nvar, n1, n2, n3,
v, F,
u);
274 up = PunctIntPolAtArbitPosition(0, nvar, n1, n2, n3,
v, par_b, 0., 0.);
275 um = PunctIntPolAtArbitPosition(0, nvar, n1, n2, n3,
v,-par_b, 0., 0.);
278 mp_adm = (1 + up) * mp + mp * mm / (4. * par_b);
279 mm_adm = (1 + um) * mm + mp * mm / (4. * par_b);
282 mp_adm_err = fabs(M_p-mp_adm);
283 mm_adm_err = fabs(M_m-mm_adm);
284 TP_INFO (
"ADM mass error: M_p_err=%.15g, M_m_err=%.15g",
285 (
double)mp_adm_err, (
double)mm_adm_err);
289 tmp = -4*par_b*( 1 + um + up + um*up ) +
290 sqrt(16*par_b*M_m*(1 + um)*(1 + up) +
291 pow(-M_m + M_p + 4*par_b*(1 + um)*(1 + up),2));
292 mp = (tmp + M_p - M_m)/(2.*(1 + up));
293 mm = (tmp - M_p + M_m)/(2.*(1 + um));
299 }
while ( (mp_adm_err > adm_tol) ||
300 (mm_adm_err > adm_tol) );
302 TP_INFO (
"Found bare masses.");
304 TP_INFO (
"Use input bare masses." );
307 Newton (nvar, n1, n2, n3,
v, Newton_tol, Newton_maxit);
309 F_of_v (nvar, n1, n2, n3,
v, F,
u);
311 SpecCoef(n1, n2, n3, 0,
v.d0, cf_v.d0);
317 for (
int i = 0; i < n1; i++)
318 for (
int j = 0;
j < n2;
j++)
319 for (
int k = 0; k < n3; k++) _d0contig[ctr++] = cf_v.d0[i + n1 * (
j + n2 * k)];
325 for (
int i = 0; i < _n1_low; i++)
326 for (
int j = 0;
j < _n2_low;
j++)
327 for (
int k = 0; k < _n3_low; k++) _d0contig_low[ctr++] = cf_v.d0[i + n1 * (
j + n2 * k)];
330 "The two puncture masses are mp=%.17g and mm=%.17g",
331 (
double) mp, (
double) mm);
333 up = PunctIntPolAtArbitPosition(0, nvar, n1, n2, n3,
v, par_b, 0., 0.);
334 um = PunctIntPolAtArbitPosition(0, nvar, n1, n2, n3,
v,-par_b, 0., 0.);
337 mp_adm = (1 + up) * mp + mp * mm / (4. * par_b);
338 mm_adm = (1 + um) * mm + mp * mm / (4. * par_b);
340 TP_INFO (
"Puncture 1 ADM mass is %g", (
double) mp_adm);
341 TP_INFO (
"Puncture 2 ADM mass is %g", (
double) mm_adm);
345 - 4*par_b*PunctEvalAtArbitPosition(
v.d0, 0, 1, 0, 0, nvar, n1, n2, n3));
346 TP_INFO (
"The total ADM mass is %g", (
double) admMass);
367 J1 = -(center_offset[2]*par_P_minus[1]) + center_offset[1]*par_P_minus[2] - center_offset[2]*par_P_plus[1] + center_offset[1]*par_P_plus[2] + par_S_minus[0] + par_S_plus[0];
368 J2 = center_offset[2]*par_P_minus[0] - center_offset[0]*par_P_minus[2] + par_b*par_P_minus[2] + center_offset[2]*par_P_plus[0] - center_offset[0]*par_P_plus[2] - par_b*par_P_plus[2] + par_S_minus[1] + par_S_plus[1];
369 J3 = -(center_offset[1]*par_P_minus[0]) + center_offset[0]*par_P_minus[1] - par_b*par_P_minus[1] - center_offset[1]*par_P_plus[0] + center_offset[0]*par_P_plus[1] + par_b*par_P_plus[1] + par_S_minus[2] + par_S_plus[2];
372 if (grid_setup_method ==
"Taylor expansion")
376 else if (grid_setup_method ==
"evaluation")
382 TP_ERROR (
"Illegal value for grid_setup_method.");
386 if(initial_lapse ==
"twopunctures")
387 TP_ERROR(
"Please specify a lapse which we can use");
388 antisymmetric_lapse = (initial_lapse ==
"twopunctures-antisymmetric");
389 averaged_lapse = (initial_lapse ==
"twopunctures-averaged");
390 pmn_lapse = (initial_lapse ==
"psi^n");
392 TP_INFO (
"Setting initial lapse to psi^%f profile.",
393 (
double)initial_lapse_psi_exponent);
394 brownsville_lapse = (initial_lapse ==
"brownsville");
395 if (brownsville_lapse)
396 TP_INFO (
"Setting initial lapse to a Brownsville-style profile "
398 (
double)initial_lapse_psi_exponent);
400 TP_INFO (
"Preparing interpolation of result");
401 if (metric_type ==
"static conformal") {
402 if (conformal_storage ==
"factor") {
404 }
else if (conformal_storage ==
"factor+derivs") {
406 }
else if (conformal_storage ==
"factor+derivs+2nd derivs") {
423 TP_ERROR (
"You must call Run() before interpolating.");
427 double x=pos[0],
y=pos[1], z=pos[2];
429 xx =
x - center_offset[0];
430 yy =
y - center_offset[1];
431 zz = z - center_offset[2];
444 const double TP4 = TP_epsilon*TP_epsilon*TP_epsilon*TP_epsilon;
447 = sqrt((xx - par_b)*(xx - par_b) + yy*yy + zz*zz);
449 = sqrt((xx + par_b)*(xx + par_b) + yy*yy + zz*zz);
455 U = PunctTaylorExpandAtArbitPosition
456 (0, nvar, n1, n2, n3,
v, xx, yy, zz);
459 U = PunctIntPolAtArbitPositionFast(cf_v, xx, yy, zz, low_res);
464 r_plus = pow (pow (r_plus, 4) + TP4, 0.25);
465 r_minus = pow (pow (r_minus, 4) + TP4, 0.25);
466 if (r_plus < TP_Tiny)
468 if (r_minus < TP_Tiny)
472 + 0.5 * mm / r_minus + U;
473 #define EXTEND(M,r) \
474 ( M * (3./8 * pow(r, 4) / pow(TP_Extend_Radius, 5) - \
475 5./4 * pow(r, 2) / pow(TP_Extend_Radius, 3) + \
476 15./8 / TP_Extend_Radius))
477 if (r_plus < TP_Extend_Radius) {
479 + 0.5 * EXTEND(mp,r_plus)
480 + 0.5 * mm / r_minus + U;
482 if (r_minus < TP_Extend_Radius) {
484 + 0.5 * EXTEND(mm,r_minus)
485 + 0.5 * mp / r_plus + U;
487 double static_psi = 1;
490 BY_Aijofxyz (xx, yy, zz, Aij);
493 if (multiply_old_lapse)
494 TP_WARN(
"@todo: Old Lapse is not be possible, Q as input vector is undefined.");
497 if ((conformal_state > 0) || (pmn_lapse) || (brownsville_lapse)) {
499 double xp, yp, zp, rp, ir;
501 double p, px, py, pz, pxx, pxy, pxz, pyy, pyz, pzz;
504 pxx = pxy = pxz = 0.0;
505 pyy = pyz = pzz = 0.0;
511 rp = sqrt (xp*xp + yp*yp + zp*zp);
512 rp = pow (pow (rp, 4) + TP4, 0.25);
517 if (rp < TP_Extend_Radius) {
531 pxx += xp*xp*s5 + s3;
534 pyy += yp*yp*s5 + s3;
536 pzz += zp*zp*s5 + s3;
542 rp = sqrt (xp*xp + yp*yp + zp*zp);
543 rp = pow (pow (rp, 4) + TP4, 0.25);
548 if (rp < TP_Extend_Radius) {
562 pxx += xp*xp*s5 + s3;
565 pyy += yp*yp*s5 + s3;
567 pzz += zp*zp*s5 + s3;
572 if (conformal_state >= 1) {
576 if (conformal_state >= 2) {
581 if (conformal_state >= 3) {
591 Q[
lapse] = pow(
p, initial_lapse_psi_exponent);
592 if (brownsville_lapse)
593 Q[
lapse] = 2.0/(1.0+pow(
p, initial_lapse_psi_exponent));
601 for(
int i=0; i<
Qlen; i++) Q[i] = 0;
603 Q[
g11] = pow (psi1 / static_psi, 4);
606 Q[
g22] = pow (psi1 / static_psi, 4);
608 Q[
g33] = pow (psi1 / static_psi, 4);
610 const double oneoverpsisq = 1./(psi1*psi1);
611 Q[
K11] = Aij[0][0] * oneoverpsisq;
612 Q[
K12] = Aij[0][1] * oneoverpsisq;
613 Q[
K13] = Aij[0][2] * oneoverpsisq;
614 Q[
K22] = Aij[1][1] * oneoverpsisq;
615 Q[
K23] = Aij[1][2] * oneoverpsisq;
616 Q[
K33] = Aij[2][2] * oneoverpsisq;
618 if (antisymmetric_lapse || averaged_lapse) {
620 ((1.0 -0.5* mp /r_plus -0.5* mm/r_minus)
621 /(1.0 +0.5* mp /r_plus +0.5* mm/r_minus));
623 if (r_plus < TP_Extend_Radius) {
625 ((1.0 -0.5*EXTEND(mp, r_plus) -0.5* mm/r_minus)
626 /(1.0 +0.5*EXTEND(mp, r_plus) +0.5* mm/r_minus));
628 if (r_minus < TP_Extend_Radius) {
630 ((1.0 -0.5*EXTEND(mm, r_minus) -0.5* mp/r_plus)
631 /(1.0 +0.5*EXTEND(mp, r_minus) +0.5* mp/r_plus));
634 if (averaged_lapse) {
638 if (multiply_old_lapse)
643 if (conformal_state >= 2) {
646 if (conformal_state >= 3) {
656 if (use_sources && rescale_sources)
658 TP_WARN(
"@TODO Rescale_Sources is in some other thorn and has not been copied");
660 Rescale_Sources(cctkGH,
661 cctk_lsh[0]*cctk_lsh[1]*cctk_lsh[2],
663 (conformal_state > 0) ? psi : NULL,
673 free_derivs (&
u, ntotal);
674 free_derivs (&
v, ntotal);
675 free_derivs (&cf_v, ntotal);
void Interpolate(const double *const pos, double *Q, bool low_res=false)
Interpolation function for an external caller.
void set_initial_guess(derivs v)
double * dvector(long nl, long nh)
void free_dvector(double *v, long nl, long nh)
This file contains aliases for making access to the long state vector Q as used eg.