forked from dtamayo/reboundx
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgr_potential.c
132 lines (124 loc) · 6.16 KB
/
gr_potential.c
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
/** * @file gr_potential.c
* @brief Post-newtonian general relativity corrections using a simple potential that gets the pericenter precession right.
* @author Pengshuai (Sam) Shi, Hanno Rein, Dan Tamayo <[email protected]>
*
* @section LICENSE
* Copyright (c) 2015 Pengshuai (Sam) Shi, Hanno Rein, Dan Tamayo
*
* This file is part of reboundx.
*
* reboundx is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* reboundx is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with rebound. If not, see <http://www.gnu.org/licenses/>.
*
* The section after the dollar signs gets built into the documentation by a script. All lines must start with space * space like below.
* Tables always must be preceded and followed by a blank line. See http://docutils.sourceforge.net/docs/user/rst/quickstart.html for a primer on rst.
* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
*
* $General Relativity$ // Effect category (must be the first non-blank line after dollar signs and between dollar signs to be detected by script).
*
* ======================= ===============================================
* Authors H. Rein, D. Tamayo
* Implementation Paper *In progress*
* Based on `Nobili and Roxburgh 1986 <http://labs.adsabs.harvard.edu/adsabs/abs/1986IAUS..114..105N/>`_.
* C Example :ref:`c_example_gr`
* Python Example `GeneralRelativity.ipynb <https://github.com/dtamayo/reboundx/blob/master/ipython_examples/GeneralRelativity.ipynb>`_.
* ======================= ===============================================
*
* This is the simplest potential you can use for general relativity.
* It assumes that the masses are dominated by a single central body.
* It gets the precession right, but gets the mean motion wrong by :math:`\mathcal{O}(GM/ac^2)`.
* It's the fastest option, and because it's not velocity-dependent, it automatically keeps WHFast symplectic.
* Nice if you have a single-star system, don't need to get GR exactly right, and want speed.
*
* **Effect Parameters**
*
* ============================ =========== ==================================================================
* Field (C type) Required Description
* ============================ =========== ==================================================================
* c (double) Yes Speed of light in the units used for the simulation.
* ============================ =========== ==================================================================
*
* **Particle Parameters**
*
* If no particles have gr_source set, effect will assume the particle at index 0 in the particles array is the source.
*
* ============================ =========== ==================================================================
* Field (C type) Required Description
* ============================ =========== ==================================================================
* gr_source (int) No Flag identifying the particle as the source of perturbations.
* ============================ =========== ==================================================================
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "rebound.h"
#include "reboundx.h"
static void rebx_calculate_gr_potential(struct reb_particle* const particles, const int N, const double C2, const double G){
const struct reb_particle source = particles[0];
const double prefac1 = 6.*(G*source.m)*(G*source.m)/C2;
for (int i=1; i<N; i++){
const struct reb_particle p = particles[i];
const double dx = p.x - source.x;
const double dy = p.y - source.y;
const double dz = p.z - source.z;
const double r2 = dx*dx + dy*dy + dz*dz;
const double prefac = prefac1/(r2*r2);
particles[i].ax -= prefac*dx;
particles[i].ay -= prefac*dy;
particles[i].az -= prefac*dz;
particles[0].ax += p.m/source.m*prefac*dx;
particles[0].ay += p.m/source.m*prefac*dy;
particles[0].az += p.m/source.m*prefac*dz;
}
}
void rebx_gr_potential(struct reb_simulation* const sim, struct rebx_force* const gr_potential, struct reb_particle* const particles, const int N){
double* c = rebx_get_param(sim->extras, gr_potential->ap, "c");
if (c == NULL){
reb_error(sim, "REBOUNDx Error: Need to set speed of light in gr effect. See examples in documentation.\n");
}
else{
const double C2 = (*c)*(*c);
rebx_calculate_gr_potential(particles, N, C2, sim->G);
}
}
static double rebx_calculate_gr_potential_potential(struct reb_simulation* const sim, const double C2){
const struct reb_particle* const particles = sim->particles;
const int _N_real = sim->N - sim->N_var;
const double G = sim->G;
const struct reb_particle source = particles[0];
const double mu = G*source.m;
const double prefac = 3.*mu*mu/C2;
double H = 0.;
for (int i=1;i<_N_real;i++){
struct reb_particle pi = particles[i];
double dx = pi.x - source.x;
double dy = pi.y - source.y;
double dz = pi.z - source.z;
double r2 = dx*dx + dy*dy + dz*dz;
H -= prefac*pi.m/r2;
}
return H;
}
double rebx_gr_potential_potential(struct rebx_extras* const rebx, const struct rebx_force* const gr_potential){
double* c = rebx_get_param(rebx, gr_potential->ap, "c");
if (c == NULL){
rebx_error(rebx, "Need to set speed of light in gr effect. See examples in documentation.\n");
}
const double C2 = (*c)*(*c);
if (rebx->sim == NULL){
rebx_error(rebx, ""); // rebx_error gives meaningful err
return 0;
}
return rebx_calculate_gr_potential_potential(rebx->sim, C2);
}