rfa 0.5.9

A port ERFA to Rust.
Documentation
use crate::rfam::*;
use crate::utils::*;

///  Nutation, IAU 2000B model.
///
///  Given:
///   * date1,date2 TT as a 2-part Julian Date (Note 1)
///
///  Returned:
///   * dpsi,deps nutation, luni-solar + planetary (Note 2)
///
/// # Notes:
///
/// 1) The TT date date1+date2 is a Julian Date, apportioned in any
///    convenient way between the two arguments.  For example,
///    JD(TT)=2450123.7 could be expressed in any of these ways,
///    among others:
///
///    |    date1    |      date2   |                      |
///    |-------------|--------------|----------------------|
///    |2450123.7    |       0.0    |  (JD method)         |
///    |2451545.0    |   -1421.3    |  (J2000 method)      |
///    |2400000.5    |   50123.2    |  (MJD method)        |
///    |2450123.5    |       0.2    | (date & time method) |
///
///    The JD method is the most natural and convenient to use in
///    cases where the loss of several decimal digits of resolution
///    is acceptable.  The J2000 method is best matched to the way
///    the argument is handled internally and will deliver the
///    optimum resolution.  The MJD method and the date & time methods
///    are both good compromises between resolution and convenience.
///
///  2) The nutation components in longitude and obliquity are in radians
///     and with respect to the equinox and ecliptic of date.  The
///     obliquity at J2000.0 is assumed to be the Lieske et al. (1977)
///     value of 84381.448 arcsec.  (The errors that result from using
///     this function with the IAU 2006 value of 84381.406 arcsec can be
///     neglected.)
///
///     The nutation model consists only of luni-solar terms, but
///     includes also a fixed offset which compensates for certain long-
///     period planetary terms (Note 7).
///
///  3) This function is an implementation of the IAU 2000B abridged
///     nutation model formally adopted by the IAU General Assembly in
///     2000.  The function computes the MHB_2000_SHORT luni-solar
///     nutation series (Luzum 2001), but without the associated
///     corrections for the precession rate adjustments and the offset
///     between the GCRS and J2000.0 mean poles.
///
///  4) The full IAU 2000A (MHB2000) nutation model contains nearly 1400
///     terms.  The IAU 2000B model (McCarthy & Luzum 2003) contains only
///     77 terms, plus additional simplifications, yet still delivers
///     results of 1 mas accuracy at present epochs.  This combination of
///     accuracy and size makes the IAU 2000B abridged nutation model
///     suitable for most practical applications.
///
///     The function delivers a pole accurate to 1 mas from 1900 to 2100
///     (usually better than 1 mas, very occasionally just outside
///     1 mas).  The full IAU 2000A model, which is implemented in the
///     function eraNut00a (q.v.), delivers considerably greater accuracy
///     at current dates;  however, to realize this improved accuracy,
///     corrections for the essentially unpredictable free-core-nutation
///     (FCN) must also be included.
///
///  5) The present function provides classical nutation.  The
///     MHB_2000_SHORT algorithm, from which it is adapted, deals also
///     with (i) the offsets between the GCRS and mean poles and (ii) the
///     adjustments in longitude and obliquity due to the changed
///     precession rates.  These additional functions, namely frame bias
///     and precession adjustments, are supported by the ERFA functions
///     eraBi00  and eraPr00.
///
///  6) The MHB_2000_SHORT algorithm also provides "total" nutations,
///     comprising the arithmetic sum of the frame bias, precession
///     adjustments, and nutation (luni-solar + planetary).  These total
///     nutations can be used in combination with an existing IAU 1976
///     precession implementation, such as eraPmat76,  to deliver GCRS-
///     to-true predictions of mas accuracy at current epochs.  However,
///     for symmetry with the eraNut00a  function (q.v. for the reasons),
///     the RFA functions do not generate the "total nutations"
///     directly.  Should they be required, they could of course easily
///     be generated by calling eraBi00, eraPr00 and the present function
///     and adding the results.
///
///  7) The IAU 2000B model includes "planetary bias" terms that are
///     fixed in size but compensate for long-period nutations.  The
///     amplitudes quoted in McCarthy & Luzum (2003), namely
///     Dpsi = -1.5835 mas and Depsilon = +1.6339 mas, are optimized for
///     the "total nutations" method described in Note 6.  The Luzum
///     (2001) values used in this ERFA implementation, namely -0.135 mas
///     and +0.388 mas, are optimized for the "rigorous" method, where
///     frame bias, precession and nutation are applied separately and in
///     that order.  During the interval 1995-2050, the ERFA
///     implementation delivers a maximum error of 1.001 mas (not
///     including FCN).
///
/// # References:
///   * Lieske, J.H., Lederle, T., Fricke, W., Morando, B., "Expressions
///     for the precession quantities based upon the IAU /1976/ system of
///     astronomical constants", Astron.Astrophys. 58, 1-2, 1-16. (1977)
///   * Luzum, B., private communication, 2001 (Fortran code
///     MHB_2000_SHORT)
///   * McCarthy, D.D. & Luzum, B.J., "An abridged model of the
///     precession-nutation of the celestial pole", Cel.Mech.Dyn.Astron.
///     85, 37-49 (2003)
///   * Simon, J.-L., Bretagnon, P., Chapront, J., Chapront-Touze, M.,
///     Francou, G., Laskar, J., Astron.Astrophys. 282, 663-683 (1994)
///
///  This revision:  2021 May 11

pub fn nut00b(date1: f64, date2: f64, dpsi: &mut f64, deps: &mut f64)
{
 
 /* Units of 0.1 microarcsecond to radians */
    const U2R: f64 = URSA_DAS2R / 1e7;
 
 /* ---------------------------------------- */
 /* Fixed offsets in lieu of planetary terms */
 /* ---------------------------------------- */
 
    const DPPLAN: f64 = -0.135 * URSA_DMAS2R;
    const DEPLAN: f64 =  0.388 * URSA_DMAS2R;
 
 /* --------------------------------------------------- */
 /* Luni-solar nutation: argument and term coefficients */
 /* --------------------------------------------------- */
 
 /* The units for the sine and cosine coefficients are */
 /* 0.1 microarcsec and the same per Julian century    */
 
    struct Xls {
       nl: i32, nlp: i32, nf: i32, nd: i32, nom: i32, /* coefficients of l,l',F,D,Om */
       ps: f64, pst: f64, pc: f64,     /* longitude sin, t*sin, cos coefficients */
       ec: f64, ect: f64, es: f64     /* obliquity cos, t*cos, sin coefficients */
 
    } 
    impl Xls {
        pub const fn new (nl: i32, nlp: i32, nf: i32, nd: i32, nom: i32, ps: f64, pst: f64, pc: f64, ec: f64, ect: f64, es: f64) ->Self{
            Xls { nl: nl, nlp: nlp, nf: nf, nd: nd, nom: nom, ps: ps, pst: pst, pc: pc, ec: ec, ect: ect, es: es }
        }
    }
    const X: [Xls; 77] = [
 
    /* 1-10 */
       Xls::new( 0, 0, 0, 0,1,
          -172064161.0, -174666.0, 33386.0, 92052331.0, 9086.0, 15377.0),
       Xls::new( 0, 0, 2,-2,2,
            -13170906.0, -1675.0, -13696.0, 5730336.0, -3015.0, -4587.0),
       Xls::new( 0, 0, 2, 0,2,-2276413.0,-234.0, 2796.0, 978459.0,-485.0,1374.0),
       Xls::new( 0, 0, 0, 0,2,2074554.0,  207.0, -698.0,-897492.0, 470.0,-291.0),
       Xls::new( 0, 1, 0, 0,0,1475877.0,-3633.0,11817.0, 73871.0,-184.0,-1924.0),
       Xls::new( 0, 1, 2,-2,2,-516821.0, 1226.0, -524.0, 224386.0,-677.0,-174.0),
       Xls::new( 1, 0, 0, 0,0, 711159.0,   73.0, -872.0,  -6750.0,   0.0, 358.0),
       Xls::new( 0, 0, 2, 0,1,-387298.0, -367.0,  380.0, 200728.0,  18.0, 318.0),
       Xls::new( 1, 0, 2, 0,2,-301461.0,  -36.0,  816.0, 129025.0, -63.0, 367.0),
       Xls::new( 0,-1, 2,-2,2, 215829.0, -494.0,  111.0, -95929.0, 299.0, 132.0),
 
    /* 11-20 */
       Xls::new( 0, 0, 2,-2,1, 128227.0,  137.0,  181.0, -68982.0,  -9.0,  39.0),
       Xls::new(-1, 0, 2, 0,2, 123457.0,   11.0,   19.0, -53311.0,  32.0,  -4.0),
       Xls::new(-1, 0, 0, 2,0, 156994.0,   10.0, -168.0,  -1235.0,   0.0,  82.0),
       Xls::new( 1, 0, 0, 0,1,  63110.0,   63.0,   27.0, -33228.0,   0.0,  -9.0),
       Xls::new(-1, 0, 0, 0,1, -57976.0,  -63.0, -189.0,  31429.0,   0.0, -75.0),
       Xls::new(-1, 0, 2, 2,2, -59641.0,  -11.0,  149.0,  25543.0, -11.0,  66.0),
       Xls::new( 1, 0, 2, 0,1, -51613.0,  -42.0,  129.0,  26366.0,   0.0,  78.0),
       Xls::new(-2, 0, 2, 0,1,  45893.0,   50.0,   31.0, -24236.0, -10.0,  20.0),
       Xls::new( 0, 0, 0, 2,0,  63384.0,   11.0, -150.0,  -1220.0,   0.0,  29.0),
       Xls::new( 0, 0, 2, 2,2, -38571.0,   -1.0,  158.0,  16452.0, -11.0,  68.0),
 
    /* 21-30 */
       Xls::new( 0,-2, 2,-2,2,  32481.0,    0.0,    0.0, -13870.0,   0.0,   0.0),
       Xls::new(-2, 0, 0, 2,0, -47722.0,    0.0,  -18.0,    477.0,   0.0, -25.0),
       Xls::new( 2, 0, 2, 0,2, -31046.0,   -1.0,  131.0,  13238.0, -11.0,  59.0),
       Xls::new( 1, 0, 2,-2,2,  28593.0,    0.0,   -1.0, -12338.0,  10.0,  -3.0),
       Xls::new(-1, 0, 2, 0,1,  20441.0,   21.0,   10.0, -10758.0,   0.0,  -3.0),
       Xls::new( 2, 0, 0, 0,0,  29243.0,    0.0,  -74.0,   -609.0,   0.0,  13.0),
       Xls::new( 0, 0, 2, 0,0,  25887.0,    0.0,  -66.0,   -550.0,   0.0,  11.0),
       Xls::new( 0, 1, 0, 0,1, -14053.0,  -25.0,   79.0,   8551.0,  -2.0, -45.0),
       Xls::new(-1, 0, 0, 2,1,  15164.0,   10.0,   11.0,  -8001.0,   0.0,  -1.0),
       Xls::new( 0, 2, 2,-2,2, -15794.0,   72.0,  -16.0,   6850.0, -42.0,  -5.0),
 
    /* 31-40 */
       Xls::new( 0, 0,-2, 2,0,  21783.0,    0.0,   13.0,   -167.0,   0.0,  13.0),
       Xls::new( 1, 0, 0,-2,1, -12873.0,  -10.0,  -37.0,   6953.0,   0.0, -14.0),
       Xls::new( 0,-1, 0, 0,1, -12654.0,   11.0,   63.0,   6415.0,   0.0,  26.0),
       Xls::new(-1, 0, 2, 2,1, -10204.0,    0.0,   25.0,   5222.0,   0.0,  15.0),
       Xls::new( 0, 2, 0, 0,0,  16707.0,  -85.0,  -10.0,    168.0,  -1.0,  10.0),
       Xls::new( 1, 0, 2, 2,2,  -7691.0,    0.0,   44.0,   3268.0,   0.0,  19.0),
       Xls::new(-2, 0, 2, 0,0, -11024.0,    0.0,  -14.0,    104.0,   0.0,   2.0),
       Xls::new( 0, 1, 2, 0,2,   7566.0,  -21.0,  -11.0,  -3250.0,   0.0,  -5.0),
       Xls::new( 0, 0, 2, 2,1,  -6637.0,  -11.0,   25.0,   3353.0,   0.0,  14.0),
       Xls::new( 0,-1, 2, 0,2,  -7141.0,   21.0,    8.0,   3070.0,   0.0,   4.0),
 
    /* 41-50 */
       Xls::new( 0, 0, 0, 2,1,  -6302.0,  -11.0,    2.0,   3272.0,   0.0,   4.0),
       Xls::new( 1, 0, 2,-2,1,   5800.0,   10.0,    2.0,  -3045.0,   0.0,  -1.0),
       Xls::new( 2, 0, 2,-2,2,   6443.0,    0.0,   -7.0,  -2768.0,   0.0,  -4.0),
       Xls::new(-2, 0, 0, 2,1,  -5774.0,  -11.0,  -15.0,   3041.0,   0.0,  -5.0),
       Xls::new( 2, 0, 2, 0,1,  -5350.0,    0.0,   21.0,   2695.0,   0.0,  12.0),
       Xls::new( 0,-1, 2,-2,1,  -4752.0,  -11.0,   -3.0,   2719.0,   0.0,  -3.0),
       Xls::new( 0, 0, 0,-2,1,  -4940.0,  -11.0,  -21.0,   2720.0,   0.0,  -9.0),
       Xls::new(-1,-1, 0, 2,0,   7350.0,    0.0,   -8.0,    -51.0,   0.0,   4.0),
       Xls::new( 2, 0, 0,-2,1,   4065.0,    0.0,    6.0,  -2206.0,   0.0,   1.0),
       Xls::new( 1, 0, 0, 2,0,   6579.0,    0.0,  -24.0,   -199.0,   0.0,   2.0),
 
    /* 51-60 */
       Xls::new( 0, 1, 2,-2,1,   3579.0,    0.0,    5.0,  -1900.0,   0.0,   1.0),
       Xls::new( 1,-1, 0, 0,0,   4725.0,    0.0,   -6.0,    -41.0,   0.0,   3.0),
       Xls::new(-2, 0, 2, 0,2,  -3075.0,    0.0,   -2.0,   1313.0,   0.0,  -1.0),
       Xls::new( 3, 0, 2, 0,2,  -2904.0,    0.0,   15.0,   1233.0,   0.0,   7.0),
       Xls::new( 0,-1, 0, 2,0,   4348.0,    0.0,  -10.0,    -81.0,   0.0,   2.0),
       Xls::new( 1,-1, 2, 0,2,  -2878.0,    0.0,    8.0,   1232.0,   0.0,   4.0),
       Xls::new( 0, 0, 0, 1,0,  -4230.0,    0.0,    5.0,    -20.0,   0.0,  -2.0),
       Xls::new(-1,-1, 2, 2,2,  -2819.0,    0.0,    7.0,   1207.0,   0.0,   3.0),
       Xls::new(-1, 0, 2, 0,0,  -4056.0,    0.0,    5.0,     40.0,   0.0,  -2.0),
       Xls::new( 0,-1, 2, 2,2,  -2647.0,    0.0,   11.0,   1129.0,   0.0,   5.0),
 
    /* 61-70 */
       Xls::new(-2, 0, 0, 0,1,  -2294.0,    0.0,  -10.0,   1266.0,   0.0,  -4.0),
       Xls::new( 1, 1, 2, 0,2,   2481.0,    0.0,   -7.0,  -1062.0,   0.0,  -3.0),
       Xls::new( 2, 0, 0, 0,1,   2179.0,    0.0,   -2.0,  -1129.0,   0.0,  -2.0),
       Xls::new(-1, 1, 0, 1,0,   3276.0,    0.0,    1.0,     -9.0,   0.0,   0.0),
       Xls::new( 1, 1, 0, 0,0,  -3389.0,    0.0,    5.0,     35.0,   0.0,  -2.0),
       Xls::new( 1, 0, 2, 0,0,   3339.0,    0.0,  -13.0,   -107.0,   0.0,   1.0),
       Xls::new(-1, 0, 2,-2,1,  -1987.0,    0.0,   -6.0,   1073.0,   0.0,  -2.0),
       Xls::new( 1, 0, 0, 0,2,  -1981.0,    0.0,    0.0,    854.0,   0.0,   0.0),
       Xls::new(-1, 0, 0, 1,0,   4026.0,    0.0, -353.0,   -553.0,   0.0,-139.0),
       Xls::new( 0, 0, 2, 1,2,   1660.0,    0.0,   -5.0,   -710.0,   0.0,  -2.0),
 
    /* 71-77 */
       Xls::new(-1, 0, 2, 4,2,  -1521.0,    0.0,    9.0,    647.0,   0.0,   4.0),
       Xls::new(-1, 1, 0, 1,1,   1314.0,    0.0,    0.0,   -700.0,   0.0,   0.0),
       Xls::new( 0,-2, 2,-2,1,  -1283.0,    0.0,    0.0,    672.0,   0.0,   0.0),
       Xls::new( 1, 0, 2, 2,1,  -1331.0,    0.0,    8.0,    663.0,   0.0,   4.0),
       Xls::new(-2, 0, 2, 2,2,   1383.0,    0.0,   -2.0,   -594.0,   0.0,  -2.0),
       Xls::new(-1, 0, 0, 0,2,   1405.0,    0.0,    4.0,   -610.0,   0.0,   2.0),
       Xls::new( 1, 1, 2,-2,2,   1290.0,    0.0,    0.0,   -556.0,   0.0,   0.0)
    ];

 
 /* ------------------------------------------------------------------ */
 
 /* Interval between fundamental epoch J2000.0 and given date (JC). */
    let t = ((date1 - URSA_DJ00) + date2) / URSA_DJC;
 
 /* --------------------*/
 /* LUNI-SOLAR NUTATION */
 /* --------------------*/
 
 /* Fundamental (Delaunay) arguments from Simon et al. (1994) */
 
 /* Mean anomaly of the Moon. */
    let el = fmod(485868.249036 + (1717915923.2178) * t, URSA_TURNAS) * URSA_DAS2R;
 
 /* Mean anomaly of the Sun. */
    let elp = fmod(1287104.79305 + (129596581.0481) * t, URSA_TURNAS) * URSA_DAS2R;
 
 /* Mean argument of the latitude of the Moon. */
    let f = fmod(335779.526232 + (1739527262.8478) * t, URSA_TURNAS) * URSA_DAS2R;
 
 /* Mean elongation of the Moon from the Sun. */
    let d = fmod(1072260.70369 + (1602961601.2090) * t, URSA_TURNAS) * URSA_DAS2R;
 
 /* Mean longitude of the ascending node of the Moon. */
    let om = fmod(450160.398036 + (-6962890.5431) * t, URSA_TURNAS) * URSA_DAS2R;
 
 /* Initialize the nutation values. */
    let mut dp = 0.0;
    let mut de = 0.0;
 
 /* Summation of luni-solar nutation series (smallest terms first). */
    for x_i in X.iter() {
 
    /* Argument and functions. */
       let arg = fmod( x_i.nl as f64  * el  +
                   x_i.nlp as f64 * elp +
                   x_i.nf as f64  * f   +
                   x_i.nd as f64 * d   +
                   x_i.nom as f64 * om, URSA_D2PI  );
       let sarg = sin(arg);
       let carg = cos(arg);
 
    /* Term. */
       dp += (x_i.ps + x_i.pst * t) * sarg + x_i.pc * carg;
       de += (x_i.ec + x_i.ect * t) * carg + x_i.es * sarg;
    }
 
 /* Convert from 0.1 microarcsec units to radians. */
    let dpsils = dp * U2R;
    let depsls = de * U2R;
 
 /* ------------------------------*/
 /* IN LIEU OF PLANETARY NUTATION */
 /* ------------------------------*/
 
 /* Fixed offset to correct for missing terms in truncated series. */
    let dpsipl = DPPLAN;
    let depspl = DEPLAN;
 
 /* --------*/
 /* RESULTS */
 /* --------*/
 
 /* Add luni-solar and planetary components. */
    *dpsi = dpsils + dpsipl;
    *deps = depsls + depspl;
 
 /* Finished. */
 
 }