/rust/registry/src/index.crates.io-1949cf8c6b5b557f/sofars-0.6.1/src/astro/ldn.rs
Line | Count | Source |
1 | | use crate::astro::ld; |
2 | | use crate::consts::{AULT, DAYSEC}; |
3 | | use crate::vm::{cp, pdp, pmp, pn, ppsp}; |
4 | | |
5 | | use super::IauLdBody; |
6 | | |
7 | | /// Light deflection by multiple solar−system bodies |
8 | | /// |
9 | | /// For a star, apply light deflection by multiple solar-system bodies, |
10 | | /// as part of transforming coordinate direction into natural direction. |
11 | | /// |
12 | | /// This function is part of the International Astronomical Union's |
13 | | /// SOFA (Standards of Fundamental Astronomy) software collection. |
14 | | /// |
15 | | /// Status: support function. |
16 | | /// |
17 | | /// Given: |
18 | | /// ``` |
19 | | /// n int number of bodies (note 1) |
20 | | /// b iauLDBODY[n] data for each of the n bodies (Notes 1,2): |
21 | | /// bm double mass of the body (solar masses, Note 3) |
22 | | /// dl double deflection limiter (Note 4) |
23 | | /// pv [2][3] barycentric PV of the body (au, au/day) |
24 | | /// ob double[3] barycentric position of the observer (au) |
25 | | /// sc double[3] observer to star coord direction (unit vector) |
26 | | /// ``` |
27 | | /// Returned: |
28 | | /// ``` |
29 | | /// sn double[3] observer to deflected star (unit vector) |
30 | | /// ``` |
31 | | /// 1) The array b contains n entries, one for each body to be |
32 | | /// considered. If n = 0, no gravitational light deflection will be |
33 | | /// applied, not even for the Sun. |
34 | | /// |
35 | | /// 2) The array b should include an entry for the Sun as well as for |
36 | | /// any planet or other body to be taken into account. The entries |
37 | | /// should be in the order in which the light passes the body. |
38 | | /// |
39 | | /// 3) In the entry in the b array for body i, the mass parameter |
40 | | /// b[i].bm can, as required, be adjusted in order to allow for such |
41 | | /// effects as quadrupole field. |
42 | | /// |
43 | | /// 4) The deflection limiter parameter b[i].dl is phi^2/2, where phi is |
44 | | /// the angular separation (in radians) between star and body at |
45 | | /// which limiting is applied. As phi shrinks below the chosen |
46 | | /// threshold, the deflection is artificially reduced, reaching zero |
47 | | /// for phi = 0. Example values suitable for a terrestrial |
48 | | /// observer, together with masses, are as follows: |
49 | | /// ``` |
50 | | /// body i b[i].bm b[i].dl |
51 | | /// |
52 | | /// Sun 1.0 6e-6 |
53 | | /// Jupiter 0.00095435 3e-9 |
54 | | /// Saturn 0.00028574 3e-10 |
55 | | /// ``` |
56 | | /// 5) For cases where the starlight passes the body before reaching the |
57 | | /// observer, the body is placed back along its barycentric track by |
58 | | /// the light time from that point to the observer. For cases where |
59 | | /// the body is "behind" the observer no such shift is applied. If |
60 | | /// a different treatment is preferred, the user has the option of |
61 | | /// instead using the iauLd function. Similarly, iauLd can be used |
62 | | /// for cases where the source is nearby, not a star. |
63 | | /// |
64 | | /// 6) The returned vector sn is not normalized, but the consequential |
65 | | /// departure from unit magnitude is always negligible. |
66 | | /// |
67 | | /// 7) The arguments sc and sn can be the same array. |
68 | | /// |
69 | | /// 8) For efficiency, validation is omitted. The supplied masses must |
70 | | /// be greater than zero, the position and velocity vectors must be |
71 | | /// right, and the deflection limiter greater than zero. |
72 | | /// |
73 | | /// Reference: |
74 | | /// |
75 | | /// Urban, S. & Seidelmann, P. K. (eds), Explanatory Supplement to |
76 | | /// the Astronomical Almanac, 3rd ed., University Science Books |
77 | | /// (2013), Section 7.2.4. |
78 | | /// |
79 | | /// Called: |
80 | | /// ``` |
81 | | /// iauCp copy p-vector |
82 | | /// iauPdp scalar product of two p-vectors |
83 | | /// iauPmp p-vector minus p-vector |
84 | | /// iauPpsp p-vector plus scaled p-vector |
85 | | /// iauPn decompose p-vector into modulus and direction |
86 | | /// iauLd light deflection by a solar-system body |
87 | | /// ``` |
88 | 0 | pub fn ldn(n: i32, b: &[IauLdBody], ob: &[f64; 3], sc: &[f64; 3]) -> [f64; 3] { |
89 | 0 | let mut sn = [0.0; 3]; |
90 | | /* Light time for 1 au (days) */ |
91 | | const CR: f64 = AULT / DAYSEC; |
92 | | |
93 | | // int i; |
94 | | // double v[3], dt, ev[3], em, e[3]; |
95 | | |
96 | | /* Star direction prior to deflection. */ |
97 | 0 | cp(&sc, &mut sn); |
98 | | |
99 | | /* Body by body. */ |
100 | 0 | for i in 0..n { |
101 | 0 | /* Body to observer vector at epoch of observation (au). */ |
102 | 0 | let v = pmp(ob, &b[i as usize].pv[0]); |
103 | 0 |
|
104 | 0 | /* Minus the time since the light passed the body (days). */ |
105 | 0 | let dt = pdp(&mut sn, &v) * CR; |
106 | 0 |
|
107 | 0 | /* Neutralize if the star is "behind" the observer. */ |
108 | 0 | let dt = dt.min(0.0); |
109 | 0 |
|
110 | 0 | /* Backtrack the body to the time the light was passing the body. */ |
111 | 0 | let ev = ppsp(&v, -dt, &b[i as usize].pv[1]); |
112 | 0 |
|
113 | 0 | /* Body to observer vector as magnitude and direction. */ |
114 | 0 | let (em, e) = pn(&ev); |
115 | 0 |
|
116 | 0 | /* Apply light deflection for this body. */ |
117 | 0 | sn = ld(b[i as usize].bm, sn, sn, e, em, b[i as usize].dl); |
118 | 0 | /* Next body. */ |
119 | 0 | } |
120 | | |
121 | 0 | sn |
122 | 0 | } |