From 754a01ce06bb342163723ec11569a10bb8e50c57 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Thu, 19 Dec 2024 10:12:04 +0100 Subject: [PATCH 01/13] A first chunk of changes for the recent sgp4 additions in heyoka. --- doc/api_model.rst | 1 + heyoka/docstrings.cpp | 122 +++++++++++++++++++++++++-------------- heyoka/docstrings.hpp | 3 +- heyoka/expose_models.cpp | 20 ++++++- 4 files changed, 101 insertions(+), 45 deletions(-) diff --git a/doc/api_model.rst b/doc/api_model.rst index 10d5f590..a0761ee3 100644 --- a/doc/api_model.rst +++ b/doc/api_model.rst @@ -27,4 +27,5 @@ Functions fixed_centres pendulum sgp4 + sgp4_is_deep_space sgp4_propagator diff --git a/heyoka/docstrings.cpp b/heyoka/docstrings.cpp index 2bdd4d54..84fe0cc1 100644 --- a/heyoka/docstrings.cpp +++ b/heyoka/docstrings.cpp @@ -748,14 +748,18 @@ variable ``v``. )"; } -std::string sgp4_model() +std::string sgp4() { - return R"(sgp4() -> list[expression] + return R"(sgp4(inputs: list[expression] | None = None) -> list[expression] -Produces the expression for the SGP4 propagator. +Produces the expressions for the SGP4 propagator. .. versionadded:: 5.1.0 +.. versionchanged:: 7.0.0 + + This function now optionally accepts a list of input expressions. + .. note:: This is a low-level function for advanced use cases. If you are looking for a fast, @@ -763,28 +767,37 @@ Produces the expression for the SGP4 propagator. to :func:`~heyoka.model.sgp4_propagator()`. SGP4 is a widely-used analytical propagator for the dynamics of Earth-orbiting satellites, -described in detail in the `spacetrack report #3 `__. -It takes in input a `two-line element set (TLE) `__ and -a time delta, and returns the Cartesian state vector (position and velocity) of the spacecraft at the specified -time in the True Equator Mean Equinox (TEME) reference frame. +described in detail in the `spacetrack report #3 `__ +(see also the `update from 2006 `__, +on which this implementation is based). + +SGP4 takes in input a general perturbations element set (GPE), for instance in the form of +a `two-line element set (aka TLE) `__, and +a time delta relative to the epoch in the GPE. It returns the Cartesian state vector +(position and velocity) of the spacecraft at the specified time in the True Equator Mean Equinox +(TEME) reference frame. + +If *inputs* is provided and it has nonzero length, it must be a list of 8 expressions, +which must represent, respectively: + +- ``n0``: the mean motion from the GPE (in [rad / min]), +- ``e0``: the eccentricity from the GPE, +- ``i0``: the inclination from the GPE (in [rad]), +- ``node0``: the right ascension of the ascending node from the GPE (in [rad]), +- ``omega0``: the argument of perigee from the GPE (in [rad]), +- ``m0``: the mean anomaly from the GPE (in [rad]), +- ``bstar``: the `BSTAR `__ drag term from + the GPE (in the same unit as given in the GPE), +- ``tsince``: the time elapsed from the GPE epoch (in [min]). + +If *inputs* is not provided or it has a length of zero, 8 variable expressions named +``["n0", "e0", "i0", "node0", "omega0", "m0", "bstar", "tsince"]`` will be used as inputs. This function will return 7 expressions: the first 6 correspond to the Cartesian state (position and velocity respectively) of the spacecraft according to the SGP4 algorithm, while the last expression represents an error code which, if nonzero, signals the occurrence of an error in the SGP4 propagation -routine. The expressions are formulated in terms of the following 8 input variables: - -- ``n0``: the mean motion from the TLE (in [rad / min]), -- ``e0``: the eccentricity from the TLE, -- ``i0``: the inclination from the TLE (in [rad]), -- ``node0``: the right ascension of the ascending node from the TLE (in [rad]), -- ``omega0``: the argument of perigee from the TLE (in [rad]), -- ``m0``: the mean anomaly from the TLE (in [rad]), -- ``bstar``: the `BSTAR `__ drag term from - the TLE (in the same unit as given in the TLE), -- ``tsince``: the time elapsed from the TLE epoch (in [min]). - -The Cartesian coordinates ``x, y, z`` of the satellite are returned in [km], while the velocities ``vx, vy, vz`` -are returned in [km / s]. When nonzero, the error code can assume the following values: +routine. The Cartesian coordinates ``x, y, z`` of the satellite are returned in [km], while the velocities +``vx, vy, vz`` are returned in [km / s]. When nonzero, the error code can assume the following values: - 1: the mean eccentricity is outside the range [0.0, 1.0], - 2: the mean mean motion is less than zero, @@ -796,8 +809,10 @@ are returned in [km / s]. When nonzero, the error code can assume the following .. note:: Currently this function does not implement the deep-space part of the - SGP4 algorithm and consequently it should not be used with satellites - whose orbital period is greater than 225 minutes. + SGP4 algorithm (aka SDP4), and consequently it should not be used with satellites + whose orbital period is greater than 225 minutes. You can use the + :py:func:`~heyoka.model.sgp4_is_deep_space()` function to check whether + a GPE is deep-space or not. .. seealso:: @@ -806,6 +821,29 @@ are returned in [km / s]. When nonzero, the error code can assume the following :returns: the Cartesian state vector of an Earth-orbiting satellite according to the SGP4 algorithm, plus an error code. +:raises ValueError: if the list of inputs has a length other than 0 or 8. + +)"; +} + +std::string sgp4_is_deepspace() +{ + return R"(sgp4_is_deep_space(n0: float, e0: float, i0: float) -> bool + +Check whether a GPE is deep-space. + +.. versionadded:: 7.0.0 + +This function takes in input the mean motion, eccentricity and inclination from a general +perturbations element set (GPE), and determines whether or not the propagation of the GPE +requires the SDP4 deep-space algorithm. + +:param n0: the mean motion from the GPE (in [rad / min]). +:param e0: the eccentricity from the GPE. +:param i0: the inclination from the GPE (in [rad]). + +:returns: a flag signalling whether or not the input GPE requires deep-space propagation. + )"; } @@ -836,7 +874,8 @@ Constructor. :py:func:`~heyoka.model.sgp4_propagator()`. The constructor will initialise the propagator from *sat_list*, which must be a list -of TLEs represented as ``Satrec`` objects from the `sgp4 Python module `__. +of general perturbations element sets (GPEs) represented as ``Satrec`` objects from the +`sgp4 Python module `__. The *diff_order* argument indicates the desired differentiation order. If equal to 0, then derivatives are disabled. @@ -844,7 +883,7 @@ derivatives are disabled. *kwargs* can optionally contain keyword arguments from the :ref:`api_common_kwargs_llvm` set and the :ref:`api_common_kwargs_cfunc` set. -:param sat_list: the list of TLEs. +:param sat_list: the list of satellites. :param diff_order: the derivatives order. :raises ImportError: if the sgp4 Python module is not available. @@ -911,22 +950,21 @@ std::string sgp4_propagator_diff_order() std::string sgp4_propagator_sat_data(const std::string &suffix, const std::string &tp) { - return fmt::format(R"(The TLE data. + return fmt::format(R"(The GPE data. -A 9 x :py:attr:`~heyoka.model.sgp4_propagator_{}.nsats` array containing the TLE orbital -elements, the BSTAR coefficient and the TLE epoch (with fractional correction) of each satellite. +A 9 x :py:attr:`~heyoka.model.sgp4_propagator_{}.nsats` array containing the general +perturbations element sets (GPEs) of each satellite. The rows contain the following quantities: -0. the mean motion from the TLE (in [rad / min]), -1. the eccentricity from the TLE, -2. the inclination from the TLE (in [rad]), -3. the right ascension of the ascending node from the TLE (in [rad]), -4. the argument of perigee from the TLE (in [rad]), -5. the mean anomaly from the TLE (in [rad]), -6. the `BSTAR `__ drag term from - the TLE (in the same unit as given in the TLE), -7. the reference epoch from the TLE (as a Julian date), +0. the mean motion (in [rad / min]), +1. the eccentricity, +2. the inclination (in [rad]), +3. the right ascension of the ascending node (in [rad]), +4. the argument of perigee (in [rad]), +5. the mean anomaly (in [rad]), +6. the `BSTAR `__ drag term (in the same unit as given in the GPE), +7. the reference epoch (as a Julian date), 8. a fractional correction to the epoch (in Julian days). :rtype: numpy.ndarray[{}] @@ -999,7 +1037,7 @@ up to the specified *times*. The *times* array can contain either floating-point values (of type :py:class:`{1}`), or Julian dates (represented via the :py:attr:`~heyoka.model.sgp4_propagator_{0}.jdtype` type). In the former case, -the input *times* will be interpreted as minutes elapsed since the TLE reference epochs (which in general differ +the input *times* will be interpreted as minutes elapsed since the GPE reference epochs (which in general differ from satellite to satellite). In the latter case, the states will be propagated up to the specified Julian dates. *times* can be either a one-dimensional array, or a two-dimensional one. In the former case (scalar propagation), @@ -1035,17 +1073,17 @@ std::string sgp4_propagator_replace_sat_data() { return R"(replace_sat_data(self, sat_list: list) -> None -Replace the TLE data. +Replace the GPE data. -This method will replace the TLE data in the propagator with the data from *sat_list*. -As usual, *sat_list* must be a list of TLEs represented as ``Satrec`` objects +This method will replace the GPE data in the propagator with the data from *sat_list*. +As usual, *sat_list* must be a list of GPEs represented as ``Satrec`` objects from the `sgp4 Python module `__. The number of satellites in *sat_list* must be equal to the number of satellites in the propagator - that is, it is not possible to change the total number of satellites in the propagator via this method. -:param sat_list: the new list of TLEs. +:param sat_list: the new list of GPEs. :raises TypeError: if one or more elements in *sat_list* is not a ``Satrec`` object. :raises ValueError: if a satellite with an orbital period above 225 minutes is detected. diff --git a/heyoka/docstrings.hpp b/heyoka/docstrings.hpp index 833e9278..4c12fc48 100644 --- a/heyoka/docstrings.hpp +++ b/heyoka/docstrings.hpp @@ -50,7 +50,8 @@ std::string nrlmsise00_tn(); std::string jb08_tn(); std::string fixed_centres(); std::string pendulum(); -std::string sgp4_model(); +std::string sgp4(); +std::string sgp4_is_deepspace(); // var_ode_sys() and related. std::string var_args(); diff --git a/heyoka/expose_models.cpp b/heyoka/expose_models.cpp index 7982fdc8..a0c195a6 100644 --- a/heyoka/expose_models.cpp +++ b/heyoka/expose_models.cpp @@ -6,7 +6,6 @@ // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "docstrings.hpp" #include #include @@ -453,8 +452,25 @@ void expose_models(py::module_ &m) "time_expr"_a, docstrings::jb08_tn().c_str()); // sgp4. - m.def("_model_sgp4", &hy::model::sgp4, docstrings::sgp4_model().c_str()); + m.def( + "_model_sgp4", + [](const std::optional> &inputs_) { + if (inputs_) { + std::vector inputs; + inputs.reserve(inputs_->size()); + std::ranges::transform(*inputs_, std::back_inserter(inputs), [](const auto &vex) { + return std::visit([](const auto &v) { return hy::expression(v); }, vex); + }); + + return hy::model::sgp4(inputs); + } else { + return hy::model::sgp4(); + } + }, + "inputs"_a.noconvert() = py::none{}, docstrings::sgp4().c_str()); expose_sgp4_propagators(m); + m.def("_model_sgp4_is_deep_space", &hy::model::sgp4_is_deep_space, "n0"_a.noconvert(), "e0"_a.noconvert(), + "i0"_a.noconvert(), docstrings::sgp4_is_deepspace().c_str()); } } // namespace heyoka_py From f1f3e0fab59ae48f0d14befdc2723e00082c3c1e Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Thu, 19 Dec 2024 10:44:21 +0100 Subject: [PATCH 02/13] More WIP. --- doc/api_model.rst | 2 +- doc/notebooks/sgp4_propagator.ipynb | 115 ++++++++++++++-------------- heyoka/docstrings.cpp | 6 +- heyoka/docstrings.hpp | 2 +- heyoka/expose_models.cpp | 4 +- heyoka/model/__init__.py | 6 +- 6 files changed, 67 insertions(+), 68 deletions(-) diff --git a/doc/api_model.rst b/doc/api_model.rst index a0761ee3..29dfd747 100644 --- a/doc/api_model.rst +++ b/doc/api_model.rst @@ -27,5 +27,5 @@ Functions fixed_centres pendulum sgp4 - sgp4_is_deep_space + gpe_is_deep_space sgp4_propagator diff --git a/doc/notebooks/sgp4_propagator.ipynb b/doc/notebooks/sgp4_propagator.ipynb index 1f9d842d..78021002 100644 --- a/doc/notebooks/sgp4_propagator.ipynb +++ b/doc/notebooks/sgp4_propagator.ipynb @@ -28,14 +28,14 @@ "\n", "## Getting the TLEs\n", "\n", - "The SGP4 algorithm takes in input a [two-line element set (TLE)](https://en.wikipedia.org/wiki/Two-line_element_set), which contains the orbital elements of the satellite at a reference epoch, the [drag coefficient](https://en.wikipedia.org/wiki/BSTAR) and additional information not used in the orbital propagation. Up-to-date TLEs can be downloaded from several resources on the web, including [CelesTrak](https://celestrak.org/) and [Space-Track](https://www.space-track.org). For the purpose of this tutorial, we will be using an offline copy of the TLE catalog of all objects tracked by [Space-Track](https://www.space-track.org), downloaded in July 2024. In order to parse the TLE data, we will be using the [Skyfield](https://rhodesmill.org/skyfield) library.\n", + "The SGP4 algorithm takes in input a general perturbations element set (GPE), which contains the averaged orbital elements of the satellite at a reference epoch, the [drag coefficient](https://en.wikipedia.org/wiki/BSTAR) and additional information not used in the orbital propagation. Up-to-date GPEs in the form of two-line elements (TLEs) can be downloaded from several resources on the web, including [CelesTrak](https://celestrak.org/) and [Space-Track](https://www.space-track.org). For the purpose of this tutorial, we will be using an offline copy of the TLE catalog of all objects tracked by [Space-Track](https://www.space-track.org), downloaded in July 2024. In order to parse the TLE data, we will be using the [Skyfield](https://rhodesmill.org/skyfield) library.\n", "\n", "Let us begin by loading the TLE data:" ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 5, "id": "cefefa7d-863f-43c7-8572-0a386c04d0d6", "metadata": {}, "outputs": [ @@ -63,12 +63,12 @@ "id": "d4705fd1-ee5f-4924-91b3-98880f51c136", "metadata": {}, "source": [ - "Because, as mentioned earlier, heyoka.py's SGP4 propagator does not support deep-space objects, we will be filtering them out from the satellites list:" + "Because, as mentioned earlier, heyoka.py's SGP4 propagator does not support deep-space objects, we have to remove them from the satellites list. We can accomplish this with the help of the {py:func}`~heyoka.model.gpe_is_deep_space()` function:" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 6, "id": "ea330930-d21a-417a-b22a-9a255c0dd908", "metadata": {}, "outputs": [ @@ -81,11 +81,10 @@ } ], "source": [ - "import math\n", + "import heyoka as hy\n", "\n", - "# Retain only satellites whose TLE orbital\n", - "# period is less than 225 minutes.\n", - "sats = list(filter(lambda sat: 2 * math.pi / sat.no_kozai < 225,\n", + "# Retain only non-deep-space satellites\n", + "sats = list(filter(lambda sat: not hy.model.gpe_is_deep_space(sat.no_kozai, sat.ecco, sat.inclo),\n", " (sat.model for sat in satellites)))\n", "\n", "print(f\"Total number of objects (excluding deep-space): {len(sats)}\")" @@ -111,12 +110,11 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 7, "id": "dc973893-42ec-463f-9ad2-ea5db15fcf0b", "metadata": {}, "outputs": [], "source": [ - "import heyoka as hy\n", "prop = hy.model.sgp4_propagator(sats)" ] }, @@ -125,7 +123,7 @@ "id": "1e3ec1fa-1c09-46f7-a8fe-f6da4c33edb2", "metadata": {}, "source": [ - "{py:func}`~heyoka.model.sgp4_propagator()` takes as only mandatory input argument the list of TLEs, represented as ``Satrec`` objects from the [sgp4 Python module](https://pypi.org/project/sgp4/) (on which Skyfield depends). It returns a propagator object, by default of type {py:func}`~heyoka.model.sgp4_propagator_dbl()` (i.e., a double-precision propagator). You can also request a single-precision propagator via the {ref}`fp_type keyword argument `." + "{py:func}`~heyoka.model.sgp4_propagator()` takes as only mandatory input argument the list of satellites, represented as ``Satrec`` objects from the [sgp4 Python module](https://pypi.org/project/sgp4/) (on which Skyfield depends). It returns a propagator object, by default of type {py:func}`~heyoka.model.sgp4_propagator_dbl()` (i.e., a double-precision propagator). You can also request a single-precision propagator via the {ref}`fp_type keyword argument `." ] }, { @@ -139,12 +137,12 @@ "\n", "In order to extract maximum performance via the use of [SIMD](https://en.wikipedia.org/wiki/Single_instruction,_multiple_data) instructions, the propagator API requires that data referring to different satellites is stored contiguously in a [structure of arrays](https://en.wikipedia.org/wiki/AoS_and_SoA) fashion.\n", "\n", - "As an example of what this means, we can take a look at the shape of the {py:attr}`~heyoka.model.sgp4_propagator_dbl.sat_data` property of the propagator class, which is a two-dimensional array containing the TLE data for all the satellites:" + "As an example of what this means, we can take a look at the shape of the {py:attr}`~heyoka.model.sgp4_propagator_dbl.sat_data` property of the propagator class, which is a two-dimensional array containing the GPE data for all the satellites:" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 8, "id": "4abc1c61-9ec6-437c-8203-b32a08c38c0a", "metadata": {}, "outputs": [ @@ -154,7 +152,7 @@ "(9, 22333)" ] }, - "execution_count": 4, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -168,12 +166,12 @@ "id": "53cdb872-8b78-4b1b-9870-cd7f418b8d0c", "metadata": {}, "source": [ - "We can see that we have 9 rows (each referring to a different TLE quantity) and 22333 columns (each referring to a different satellite). Thus, for instance, the TLE mean motions for all satellites are stored contiguously next to each other in the first row of the array:" + "We can see that we have 9 rows (each referring to a different GPE quantity) and 22333 columns (each referring to a different satellite). Thus, for instance, the GPE mean motions for all satellites are stored contiguously next to each other in the first row of the array:" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 9, "id": "2fc97b50-1b49-410f-87ad-8fd58b6e15a7", "metadata": {}, "outputs": [ @@ -181,16 +179,16 @@ "data": { "text/plain": [ "array([0.04736197, 0.05185823, 0.05002965, ..., 0.05346113, 0.05652762,\n", - " 0.07130705])" + " 0.07130705], shape=(22333,))" ] }, - "execution_count": 5, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# Print the TLE mean motions of all satellites.\n", + "# Print the GPE mean motions of all satellites.\n", "prop.sat_data[0]" ] }, @@ -221,7 +219,7 @@ ], "source": [ "# Transpose sat_data so that each rows\n", - "# contains all TLE data for a single\n", + "# contains all GPE data for a single\n", "# satellite\n", "prop.sat_data.T.shape" ] @@ -233,14 +231,14 @@ "source": [ "## Scalar propagation\n", "\n", - "We are now ready to perform our first orbit propagation by invoking the call operator of the propagator object, which accepts in input a list of propagation times (one per satellite). The times can be passed either as an array of floating-point values, or as an array of Julian dates. In the former case, the times are interpreted as minutes elapsed since the TLE reference epoch of the satellite. In the latter case, the state of each satellite is propagated up to the specified Julian date. Here we will be focusing on date-based propagation as it is by far the most useful one.\n", + "We are now ready to perform our first orbit propagation by invoking the call operator of the propagator object, which accepts in input a list of propagation times (one per satellite). The times can be passed either as an array of floating-point values, or as an array of Julian dates (represented via the {py:attr}`~heyoka.model.sgp4_propagator_dbl.jdtype` datatype). In the former case, the times are interpreted as minutes elapsed since the GPE reference epoch of the satellite. In the latter case, the state of each satellite is propagated up to the specified Julian date. Here we will be focusing on date-based propagation as it is by far the most useful one.\n", "\n", "We begin by creating an (empty) array of Julian dates:" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 10, "id": "5024d054-919b-41ea-a1f1-521ac9097282", "metadata": {}, "outputs": [], @@ -263,7 +261,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 11, "id": "a3dd3dd5-2207-4399-b138-8722508c97bc", "metadata": {}, "outputs": [], @@ -282,7 +280,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 12, "id": "1bb560f2-69dc-490e-bd75-40d689abf067", "metadata": {}, "outputs": [], @@ -306,7 +304,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 13, "id": "c339c20c-75b5-43e4-85ea-7bfea426f85e", "metadata": {}, "outputs": [], @@ -326,7 +324,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 14, "id": "ed16ba6a-35c2-46e3-b4d9-35962ea6cbd1", "metadata": {}, "outputs": [ @@ -336,7 +334,7 @@ "(7, 22333)" ] }, - "execution_count": 11, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -355,7 +353,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 15, "id": "12192555-65d6-40ab-8c1f-fda89311b285", "metadata": {}, "outputs": [ @@ -366,7 +364,7 @@ " 4.56880512e+00, 3.18182714e+00])" ] }, - "execution_count": 12, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -395,7 +393,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 16, "id": "65668259-b4d9-4d4d-924a-551236ce064f", "metadata": {}, "outputs": [], @@ -416,7 +414,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 17, "id": "6511d2f2-3f8d-4bba-9641-6c4ab4800c4c", "metadata": {}, "outputs": [], @@ -442,7 +440,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 18, "id": "aa8ea5ee-5ec4-4293-9f70-47312a8037c7", "metadata": {}, "outputs": [ @@ -493,12 +491,12 @@ "\n", "In addition to being able to propagate the state of a satellite to a single date, our propagator is also capable of propagating the state to multiple dates at a time. We call this *batch mode* propagation.\n", "\n", - "Batch mode is enabled by simply passing a two-dimensional array of dates to the call operator of the propagator, rather than a one-dimensional list. As usual, the number of columns must be equal to the number of satellites, while the number of rows represents the number of propagations to be performed per satellite:" + "Batch mode is enabled by simply passing a two-dimensional array of dates to the call operator of the propagator, rather than a one-dimensional list. As usual with batch mode in heyoka.py, the number of columns must be equal to the number of satellites, while the number of rows represents the number of propagations to be performed per satellite:" ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 19, "id": "af75af08-acf1-4ed9-9d75-8f593ca52065", "metadata": {}, "outputs": [], @@ -526,7 +524,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 20, "id": "a3fbf0cc-9c75-4604-bae7-037c5deab92b", "metadata": {}, "outputs": [], @@ -544,7 +542,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 21, "id": "026d6bd2-1066-4cdd-96a2-9cad7c1781e1", "metadata": {}, "outputs": [ @@ -554,7 +552,7 @@ "(30, 7, 22333)" ] }, - "execution_count": 18, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -573,7 +571,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 22, "id": "58cb674d-8cf2-42f4-9117-1efd67286ee5", "metadata": {}, "outputs": [ @@ -592,10 +590,11 @@ " [-1.78968059e+00, 7.17637365e-01, -3.13760364e+00, ...,\n", " 1.27142972e+00, 3.09883769e+00, -7.98112991e+00],\n", " [ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, ...,\n", - " 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])" + " 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]],\n", + " shape=(7, 22333))" ] }, - "execution_count": 19, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -616,7 +615,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 23, "id": "784d6c9b-021d-4734-bc77-2a62b4a698d2", "metadata": {}, "outputs": [], @@ -635,7 +634,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 24, "id": "6d4569cf-29fa-4118-9f99-29abe0d45411", "metadata": {}, "outputs": [ @@ -695,14 +694,14 @@ "\n", "As we mentioned in the introduction, our SGP4 implementation is fully differentiable - meaning that it supports not only the propagation of state vectors, but also of their derivatives.\n", "\n", - "At this time, the derivatives with respect to the TLE orbital elements and the BSTAR coefficient are computed, but it is not difficult to add the ability to fully customise the list of quantities with respect to which the derivatives are computed. Please [let us know](https://github.com/bluescarni/heyoka.py/issues) if you are interested in such a feature.\n", + "At this time, the derivatives with respect to the GPE orbital elements and the BSTAR coefficient are computed, but it is not difficult to add the ability to fully customise the list of quantities with respect to which the derivatives are computed. Please [let us know](https://github.com/bluescarni/heyoka.py/issues) if you are interested in such a feature.\n", "\n", "In order to enable the computation of derivatives, we need to pass a nonzero ``diff_order`` to the {py:func}`~heyoka.model.sgp4_propagator()` function:" ] }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 26, "id": "b76471fe-f380-4812-92c3-57b82c63c9d1", "metadata": {}, "outputs": [], @@ -723,7 +722,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 27, "id": "3d6fc2ae-3c80-4c77-bc12-54bf8aeccef1", "metadata": {}, "outputs": [ @@ -733,7 +732,7 @@ "1" ] }, - "execution_count": 23, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } @@ -752,7 +751,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 28, "id": "4c0157e9-8fd8-4f9d-a023-34b2f2737451", "metadata": {}, "outputs": [ @@ -762,7 +761,7 @@ "[n0, e0, i0, node0, omega0, m0, bstar]" ] }, - "execution_count": 24, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -776,7 +775,7 @@ "id": "9767c4aa-6291-4832-bf2e-8f3bacf80d8c", "metadata": {}, "source": [ - "These are the TLE quantities, specifically:\n", + "These are the standard GPE quantities, specifically:\n", "\n", "- ``n0``: the mean motion,\n", "- ``e0``: the eccentricity,\n", @@ -791,7 +790,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 29, "id": "1badd9a7-8b0c-4759-ac49-2eacf87e5920", "metadata": {}, "outputs": [], @@ -835,7 +834,7 @@ "id": "9bb82e63-7919-46db-af15-8c7ff2b99ebe", "metadata": {}, "source": [ - "Clearly, in addition to the 7 propagation outputs, now we also have the $7 \\times 7 = 49$ derivatives of the outputs with respect to the TLE quantities. The derivatives are stored in the propagation output right after the state, in row-major order. For instance, the index range $\\left[ 7, 14 \\right)$ contains the derivatives of the Cartesian position $x$ with respect to the TLE quantities (in the order they show up in {py:attr}`~heyoka.model.sgp4_propagator_dbl.diff_args`). The index range $\\left[ 14, 21 \\right)$ contains the derivatives of the Cartesian position $y$, and so on.\n", + "In addition to the 7 propagation outputs, now we also have the $7 \\times 7 = 49$ derivatives of the outputs with respect to the GPE quantities, for a total of 56 output quantities. The derivatives are stored in the propagation output right after the state, in row-major order. For instance, the index range $\\left[ 7, 14 \\right)$ contains the derivatives of the Cartesian position $x$ with respect to the GPE quantities (in the order they show up in {py:attr}`~heyoka.model.sgp4_propagator_dbl.diff_args`). The index range $\\left[ 14, 21 \\right)$ contains the derivatives of the Cartesian position $y$, and so on.\n", "\n", "This means that we can easily fetch the Jacobian of, say, the first satellite's state vector as:" ] @@ -978,12 +977,12 @@ "The second helper is the {py:func}`~heyoka.model.sgp4_propagator_dbl.get_mindex()` method. Given an integral index into the output of a differentiable propagator, this method returns the differentiation multiindex associated to that output quantity.\n", "The multiindex returned by {py:func}`~heyoka.model.sgp4_propagator_dbl.get_mindex()` begins with the component index, while the remaining indices represent the differentiation orders. Let us see a couple of examples.\n", "\n", - "We know from earlier that at index 7 we have the first-order derivative of component 0 (i.e., the Cartesian $x$ position of the satellite) with respect to the first TLE orbital element - that is, $\\frac{\\partial x}{\\partial n_0}$. Let us check:" + "We know from earlier that at index 7 we have the first-order derivative of component 0 (i.e., the Cartesian $x$ position of the satellite) with respect to the first GPE orbital element - that is, $\\frac{\\partial x}{\\partial n_0}$. Let us check:" ] }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 30, "id": "a9c34612-8d35-47dd-9824-966cf49de5e5", "metadata": {}, "outputs": [ @@ -993,7 +992,7 @@ "[0, 1, 0, 0, 0, 0, 0, 0]" ] }, - "execution_count": 31, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -1012,7 +1011,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 31, "id": "88d6f015-375d-4e08-bfd0-30063ad6a1e7", "metadata": {}, "outputs": [ @@ -1022,7 +1021,7 @@ "[0, 0, 1, 0, 0, 0, 0, 0]" ] }, - "execution_count": 32, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -1184,7 +1183,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "heyoka_py", "language": "python", "name": "python3" }, @@ -1198,7 +1197,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.12.4" } }, "nbformat": 4, diff --git a/heyoka/docstrings.cpp b/heyoka/docstrings.cpp index 84fe0cc1..c18f9326 100644 --- a/heyoka/docstrings.cpp +++ b/heyoka/docstrings.cpp @@ -811,7 +811,7 @@ routine. The Cartesian coordinates ``x, y, z`` of the satellite are returned in Currently this function does not implement the deep-space part of the SGP4 algorithm (aka SDP4), and consequently it should not be used with satellites whose orbital period is greater than 225 minutes. You can use the - :py:func:`~heyoka.model.sgp4_is_deep_space()` function to check whether + :py:func:`~heyoka.model.gpe_is_deep_space()` function to check whether a GPE is deep-space or not. .. seealso:: @@ -826,9 +826,9 @@ routine. The Cartesian coordinates ``x, y, z`` of the satellite are returned in )"; } -std::string sgp4_is_deepspace() +std::string gpe_is_deep_space() { - return R"(sgp4_is_deep_space(n0: float, e0: float, i0: float) -> bool + return R"(gpe_is_deep_space(n0: float, e0: float, i0: float) -> bool Check whether a GPE is deep-space. diff --git a/heyoka/docstrings.hpp b/heyoka/docstrings.hpp index 4c12fc48..adc4e322 100644 --- a/heyoka/docstrings.hpp +++ b/heyoka/docstrings.hpp @@ -51,7 +51,7 @@ std::string jb08_tn(); std::string fixed_centres(); std::string pendulum(); std::string sgp4(); -std::string sgp4_is_deepspace(); +std::string gpe_is_deep_space(); // var_ode_sys() and related. std::string var_args(); diff --git a/heyoka/expose_models.cpp b/heyoka/expose_models.cpp index a0c195a6..089e77ac 100644 --- a/heyoka/expose_models.cpp +++ b/heyoka/expose_models.cpp @@ -469,8 +469,8 @@ void expose_models(py::module_ &m) }, "inputs"_a.noconvert() = py::none{}, docstrings::sgp4().c_str()); expose_sgp4_propagators(m); - m.def("_model_sgp4_is_deep_space", &hy::model::sgp4_is_deep_space, "n0"_a.noconvert(), "e0"_a.noconvert(), - "i0"_a.noconvert(), docstrings::sgp4_is_deepspace().c_str()); + m.def("_model_gpe_is_deep_space", &hy::model::gpe_is_deep_space, "n0"_a.noconvert(), "e0"_a.noconvert(), + "i0"_a.noconvert(), docstrings::gpe_is_deep_space().c_str()); } } // namespace heyoka_py diff --git a/heyoka/model/__init__.py b/heyoka/model/__init__.py index 13ec9196..df9c2092 100644 --- a/heyoka/model/__init__.py +++ b/heyoka/model/__init__.py @@ -40,8 +40,8 @@ def sgp4_propagator( This function will construct an SGP4 propagator from the input arguments. - The only mandatory argument is *sat_list*, which must be a list - of TLEs represented as ``Satrec`` objects from the `sgp4 Python module `__. + The only mandatory argument is *sat_list*, which must be a list of general perturbations element set (GPEs) + represented as ``Satrec`` objects from the `sgp4 Python module `__. The *diff_order* argument indicates the desired differentiation order. If equal to 0, then derivatives are disabled. @@ -53,7 +53,7 @@ def sgp4_propagator( *kwargs* can also optionally contain keyword arguments from the :ref:`api_common_kwargs_llvm` set and the :ref:`api_common_kwargs_cfunc` set. - :param sat_list: the list of TLEs. + :param sat_list: the list of GPEs. :param diff_order: the derivatives order. :raises TypeError: if an unsupported :ref:`fp_type ` is specified. From 34700b2663840fb6604aa9970b0292ff00cbbc40 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Thu, 19 Dec 2024 10:57:39 +0100 Subject: [PATCH 03/13] More docs work. --- doc/notebooks/sgp4_propagator.ipynb | 2 +- heyoka/docstrings.cpp | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/doc/notebooks/sgp4_propagator.ipynb b/doc/notebooks/sgp4_propagator.ipynb index 78021002..ffe26865 100644 --- a/doc/notebooks/sgp4_propagator.ipynb +++ b/doc/notebooks/sgp4_propagator.ipynb @@ -21,7 +21,7 @@ "\n", "```{note}\n", "\n", - "At this time, heyoka.py's SGP4 propagator does not implement support for deep-space propagation (i.e., the so-called SDP4 algorithm). As a consequence, the propagator will throw an exception if a deep-space orbit is detected.\n", + "At this time, heyoka.py's SGP4 propagator does not implement support for deep-space propagation (i.e., the so-called SDP4 algorithm). As a consequence, the propagator should not be used with deep-space satellites.\n", "Please [let us know](https://github.com/bluescarni/heyoka.py/issues) if you are interested in support for deep-space propagations.\n", "\n", "```\n", diff --git a/heyoka/docstrings.cpp b/heyoka/docstrings.cpp index c18f9326..9b2ee4c9 100644 --- a/heyoka/docstrings.cpp +++ b/heyoka/docstrings.cpp @@ -756,7 +756,7 @@ Produces the expressions for the SGP4 propagator. .. versionadded:: 5.1.0 -.. versionchanged:: 7.0.0 +.. versionadded:: 7.0.0 This function now optionally accepts a list of input expressions. @@ -818,8 +818,8 @@ routine. The Cartesian coordinates ``x, y, z`` of the satellite are returned in `NORAD Two-Line Element Set Format `_ -:returns: the Cartesian state vector of an Earth-orbiting satellite according to the SGP4 algorithm, - plus an error code. +:returns: a list of 7 expressions representing the Cartesian state vector of an Earth-orbiting + satellite and an error code, as functions of the *inputs*. :raises ValueError: if the list of inputs has a length other than 0 or 8. @@ -870,7 +870,7 @@ Constructor. .. note:: - Instead of using this constructor, consider using the factory function + As an alternative to this constructor, consider using the factory function :py:func:`~heyoka.model.sgp4_propagator()`. The constructor will initialise the propagator from *sat_list*, which must be a list @@ -888,7 +888,6 @@ and the :ref:`api_common_kwargs_cfunc` set. :raises ImportError: if the sgp4 Python module is not available. :raises TypeError: if one or more elements in *sat_list* is not a ``Satrec`` object. -:raises ValueError: if a satellite with an orbital period above 225 minutes is detected. )"; } @@ -1086,7 +1085,6 @@ in the propagator via this method. :param sat_list: the new list of GPEs. :raises TypeError: if one or more elements in *sat_list* is not a ``Satrec`` object. -:raises ValueError: if a satellite with an orbital period above 225 minutes is detected. :raises ValueError: if the number of satellites in *sat_list* differs from the number of satellites in the propagator. From 84644fa216e12c94ae1f610e6eb7e2b4337be83d Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Thu, 19 Dec 2024 11:07:42 +0100 Subject: [PATCH 04/13] Small testing additions. --- heyoka/_test_model.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/heyoka/_test_model.py b/heyoka/_test_model.py index e60e382c..4804c466 100644 --- a/heyoka/_test_model.py +++ b/heyoka/_test_model.py @@ -447,6 +447,32 @@ def test_jb08(self): ) def test_sgp4(self): + from . import par, time as tm from .model import sgp4 self.assertEqual(len(sgp4()), 7) + self.assertEqual(len(sgp4([])), 7) + + # Test also with custom inputs. + self.assertEqual(len(sgp4(["a", "b", "c", "d", "e", "f", par[0], tm])), 7) + + def test_gpe_is_deep_space(self): + try: + from sgp4.api import Satrec + except ImportError: + return + + from .model import gpe_is_deep_space + + # A non-deepspace TLE. + s1 = "1 00045U 60007A 24187.45810325 .00000504 00000-0 14841-3 0 9992" + t1 = "2 00045 66.6943 81.3521 0257384 317.3173 40.8180 14.34783636277898" + sat = Satrec.twoline2rv(s1, t1) + + self.assertFalse(gpe_is_deep_space(sat.no_kozai, sat.ecco, sat.inclo)) + + # A deepspace TLE. + t1 = "2 00045 66.6943 81.3521 0257384 317.3173 40.8180 6.34783636277898" + sat = Satrec.twoline2rv(s1, t1) + + self.assertTrue(gpe_is_deep_space(sat.no_kozai, sat.ecco, sat.inclo)) From c8f8669b52ca4aa718cd04d7cdbc047d2daa5c9e Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Thu, 19 Dec 2024 11:22:13 +0100 Subject: [PATCH 05/13] Simplify several docstrings. --- heyoka/docstrings.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/heyoka/docstrings.cpp b/heyoka/docstrings.cpp index 9b2ee4c9..321962bb 100644 --- a/heyoka/docstrings.cpp +++ b/heyoka/docstrings.cpp @@ -391,7 +391,7 @@ as variable names. std::string sum() { - return R"(sum(terms: collections.abc.Sequence[expression]) -> expression + return R"(sum(terms: list[expression]) -> expression Multivariate summation. @@ -413,7 +413,7 @@ If *terms* is empty, zero will be returned. std::string prod() { - return R"(prod(terms: collections.abc.Sequence[expression]) -> expression + return R"(prod(terms: list[expression]) -> expression Multivariate product. @@ -698,9 +698,9 @@ std::string var_args_all() std::string fixed_centres() { - return R"(fixed_centres(Gconst: expression | str | numpy.single | float | numpy.longdouble = 1., masses: collections.abc.Sequence[expression | str | numpy.single | float | numpy.longdouble] = [], positions: collections.abc.Iterable = numpy.empty((0, 3), dtype=float)) -> list[tuple[expression, expression]] + return R"(fixed_centres(Gconst: expression = 1., masses: list[expression] = [], positions: collections.abc.Iterable = numpy.empty((0, 3), dtype=float)) -> list[tuple[expression, expression]] -Produces the expression for the dynamics in a fixed-centres problem. +Produces the expressions for the dynamics in a fixed-centres problem. In the fixed-centres problem, a test particle moves in the Newtonian gravitational field generated by a number of massive particles whose positions are fixed in space. The test particle's Cartesian position and @@ -708,7 +708,7 @@ velocity are represented by the variables ``[x, y, z]`` and ``[vx, vy, vz]`` res Several checks are run on the input arguments: -- *positions* must be convertible into an ``N x 3`` array, with each row containing +- *positions* must be (convertible into) an ``N x 3`` array, with each row containing the Cartesian position vector of a mass, - the number of elements in *masses* must be equal to the number of three-dimensional position vectors in *positions*. @@ -726,7 +726,7 @@ Several checks are run on the input arguments: std::string pendulum() { - return R"(pendulum(gconst: expression | str | numpy.single | float | numpy.longdouble = 1., length: expression | str | numpy.single | float | numpy.longdouble = 1.) -> list[tuple[expression, expression]] + return R"(pendulum(gconst: expression = 1., length: expression = 1.) -> list[tuple[expression, expression]] Produces the expression for the dynamics of the simple pendulum. From 2cc50abef8afea1766baccace60ef0e305fbd4fd Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Thu, 19 Dec 2024 11:26:40 +0100 Subject: [PATCH 06/13] Expose get_params(). --- heyoka/_test_expression.py | 11 +++++++++++ heyoka/expose_expression.cpp | 6 ++++++ 2 files changed, 17 insertions(+) diff --git a/heyoka/_test_expression.py b/heyoka/_test_expression.py index 15be0709..c5ce4dcd 100644 --- a/heyoka/_test_expression.py +++ b/heyoka/_test_expression.py @@ -406,3 +406,14 @@ def test_select(self): "The numerical arguments of select() must be all of the same type" in str(cm.exception) ) + + def test_get_params(self): + from . import make_vars, par, get_params + + x, y = make_vars("x", "y") + + self.assertEqual(get_params(x + y), []) + self.assertEqual(get_params(x + par[42]), [par[42]]) + + self.assertEqual(get_params([x + y, x - y]), []) + self.assertEqual(get_params([x + par[42], par[1] - y]), [par[1], par[42]]) diff --git a/heyoka/expose_expression.cpp b/heyoka/expose_expression.cpp index d43e8b8c..8550d7dc 100644 --- a/heyoka/expose_expression.cpp +++ b/heyoka/expose_expression.cpp @@ -70,6 +70,7 @@ namespace py = pybind11; // be there when doing mixed-mode arithmetic between real and float32 for instance. // Perhaps something to do with pybind11's conversion machinery (since the exposition // of real does not use pybind11)? +// NOTE: this may be solved in the new NumPy 2 dtype API, need to check at one point. void expose_expression(py::module_ &m) { namespace hey = heyoka; @@ -231,6 +232,11 @@ void expose_expression(py::module_ &m) [](const v_ex_t &arg) { return std::visit([](const auto &v) { return hey::get_variables(v); }, arg); }, "arg"_a); + // get_params(). + m.def( + "get_params", + [](const v_ex_t &arg) { return std::visit([](const auto &v) { return hey::get_params(v); }, arg); }, "arg"_a); + // rename_variables(). m.def( "rename_variables", From ed0269d7c6f7d18aff9bb37b7b1dc5c4a13b1b28 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Thu, 19 Dec 2024 11:41:12 +0100 Subject: [PATCH 07/13] Update changelog. --- doc/breaking_changes.rst | 4 ++-- doc/changelog.rst | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/doc/breaking_changes.rst b/doc/breaking_changes.rst index 3215c95c..0920015d 100644 --- a/doc/breaking_changes.rst +++ b/doc/breaking_changes.rst @@ -10,8 +10,8 @@ Breaking changes 7.0.0 ----- -Updated Python dependencies -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Updated Python and NumPy requirements +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ heyoka.py now depends on NumPy>=2. This is due to changes introduced by NumPy 2 in the DType API, which make it unfeasible to support both NumPy 1 and 2 at the same time. diff --git a/doc/changelog.rst b/doc/changelog.rst index e38369e2..ad1af175 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -9,12 +9,22 @@ Changelog New ~~~ +- New function :func:`~heyoka.model.gpe_is_deep_space()` to detect + deep-space GPEs + (`#207 `__). - Upload the source distribution to PyPI (`#203 `__). Changes ~~~~~~~ +- Small tweaks to the behaviour of the SGP4 propagator: non-normalised double-length + Julian dates are now accepted, deep-space GPEs do not result in exceptions any more, + and performance improvements for the + :func:`~heyoka.model.sgp4_propagator_dbl.replace_sat_data()` function + (`#207 `__). +- The parallel compilation feature has been temporarily disabled due to several LLVM bugs + (`#206 `__). - heyoka.py now requires version 7.0.0 of the heyoka C++ library (`#206 `__). From 124bc3e908e190811f7e2750982482674b339daa Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Thu, 19 Dec 2024 11:43:02 +0100 Subject: [PATCH 08/13] Update changelog. --- doc/changelog.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/changelog.rst b/doc/changelog.rst index ad1af175..e5733ca2 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -9,6 +9,9 @@ Changelog New ~~~ +- Expose the ``get_params()`` function, which returns a list of + parameters for an input expression or list of expressions + (`#207 `__). - New function :func:`~heyoka.model.gpe_is_deep_space()` to detect deep-space GPEs (`#207 `__). From 6969f88d73f74c298e2c7ff6295a81c90617f567 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Thu, 19 Dec 2024 12:00:09 +0100 Subject: [PATCH 09/13] Another changelog tweak. --- doc/changelog.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/changelog.rst b/doc/changelog.rst index e5733ca2..87b115e4 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -10,7 +10,7 @@ New ~~~ - Expose the ``get_params()`` function, which returns a list of - parameters for an input expression or list of expressions + parameters contained in an expression or a list of expressions (`#207 `__). - New function :func:`~heyoka.model.gpe_is_deep_space()` to detect deep-space GPEs From 3fcaa42546890fb58dacfae0d009d7ea17343b08 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Thu, 19 Dec 2024 12:00:27 +0100 Subject: [PATCH 10/13] Tweak the CI scripts to lower the runtime. --- tools/conda_docs.sh | 4 +--- tools/gha_conda_asan.sh | 4 +--- tools/gha_conda_static.sh | 8 ++------ tools/gha_osx_heyoka_head.sh | 8 ++------ tools/gha_osx_heyoka_head_static.sh | 8 ++------ 5 files changed, 8 insertions(+), 24 deletions(-) diff --git a/tools/conda_docs.sh b/tools/conda_docs.sh index 3f09163f..da2289e1 100644 --- a/tools/conda_docs.sh +++ b/tools/conda_docs.sh @@ -39,11 +39,9 @@ cd build cmake -G Ninja ../ \ -DCMAKE_INSTALL_PREFIX=$deps_dir \ - -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_PREFIX_PATH=$deps_dir \ -DHEYOKA_WITH_MPPP=yes \ - -DHEYOKA_WITH_SLEEF=yes \ - -DCMAKE_CXX_FLAGS_DEBUG="-g -Og" + -DHEYOKA_WITH_SLEEF=yes ninja -j2 -v install diff --git a/tools/gha_conda_asan.sh b/tools/gha_conda_asan.sh index f6b86a65..d8ce94dc 100755 --- a/tools/gha_conda_asan.sh +++ b/tools/gha_conda_asan.sh @@ -34,10 +34,8 @@ cd build cmake ../ -G Ninja \ -DCMAKE_INSTALL_PREFIX=$deps_dir \ -DCMAKE_PREFIX_PATH=$deps_dir \ - -DCMAKE_BUILD_TYPE=Debug \ -DHEYOKA_WITH_MPPP=yes \ - -DHEYOKA_WITH_SLEEF=yes \ - -DCMAKE_CXX_FLAGS_DEBUG="-g -Og -fsanitize=address" + -DHEYOKA_WITH_SLEEF=yes ninja -j2 -v install diff --git a/tools/gha_conda_static.sh b/tools/gha_conda_static.sh index 4eefdf85..27524be0 100755 --- a/tools/gha_conda_static.sh +++ b/tools/gha_conda_static.sh @@ -34,12 +34,10 @@ cd build cmake ../ -G Ninja \ -DCMAKE_INSTALL_PREFIX=$deps_dir \ -DCMAKE_PREFIX_PATH=$deps_dir \ - -DCMAKE_BUILD_TYPE=Debug \ -DHEYOKA_WITH_MPPP=yes \ -DHEYOKA_WITH_SLEEF=yes \ -DHEYOKA_FORCE_STATIC_LLVM=yes \ - -DHEYOKA_HIDE_LLVM_SYMBOLS=yes \ - -DCMAKE_CXX_FLAGS_DEBUG="-g -Og" + -DHEYOKA_HIDE_LLVM_SYMBOLS=yes ninja -j2 -v install @@ -51,9 +49,7 @@ cd build cmake ../ -G Ninja \ -DCMAKE_INSTALL_PREFIX=$deps_dir \ - -DCMAKE_PREFIX_PATH=$deps_dir \ - -DCMAKE_BUILD_TYPE=Debug \ - -DCMAKE_CXX_FLAGS_DEBUG="-g -Og" + -DCMAKE_PREFIX_PATH=$deps_dir ninja -j2 -v install diff --git a/tools/gha_osx_heyoka_head.sh b/tools/gha_osx_heyoka_head.sh index 8c2147ad..8a65fc89 100644 --- a/tools/gha_osx_heyoka_head.sh +++ b/tools/gha_osx_heyoka_head.sh @@ -29,10 +29,8 @@ cd build cmake ../ -G Ninja \ -DCMAKE_INSTALL_PREFIX=$deps_dir \ -DCMAKE_PREFIX_PATH=$deps_dir \ - -DCMAKE_BUILD_TYPE=Debug \ -DHEYOKA_WITH_SLEEF=yes \ - -DHEYOKA_WITH_MPPP=yes \ - -DCMAKE_CXX_FLAGS_DEBUG="-g -Og" + -DHEYOKA_WITH_MPPP=yes ninja -j2 -v install @@ -44,9 +42,7 @@ cd build cmake ../ -G Ninja \ -DCMAKE_INSTALL_PREFIX=$deps_dir \ - -DCMAKE_PREFIX_PATH=$deps_dir \ - -DCMAKE_BUILD_TYPE=Debug \ - -DCMAKE_CXX_FLAGS_DEBUG="-g -Og" + -DCMAKE_PREFIX_PATH=$deps_dir ninja -j2 -v install diff --git a/tools/gha_osx_heyoka_head_static.sh b/tools/gha_osx_heyoka_head_static.sh index b77c128a..a5a9af3c 100644 --- a/tools/gha_osx_heyoka_head_static.sh +++ b/tools/gha_osx_heyoka_head_static.sh @@ -29,12 +29,10 @@ cd build cmake ../ -G Ninja \ -DCMAKE_INSTALL_PREFIX=$deps_dir \ -DCMAKE_PREFIX_PATH=$deps_dir \ - -DCMAKE_BUILD_TYPE=Debug \ -DHEYOKA_WITH_SLEEF=yes \ -DHEYOKA_WITH_MPPP=yes \ -DHEYOKA_FORCE_STATIC_LLVM=yes \ - -DHEYOKA_HIDE_LLVM_SYMBOLS=yes \ - -DCMAKE_CXX_FLAGS_DEBUG="-g -Og" + -DHEYOKA_HIDE_LLVM_SYMBOLS=yes ninja -j2 -v install @@ -46,9 +44,7 @@ cd build cmake ../ -G Ninja \ -DCMAKE_INSTALL_PREFIX=$deps_dir \ - -DCMAKE_PREFIX_PATH=$deps_dir \ - -DCMAKE_BUILD_TYPE=Debug \ - -DCMAKE_CXX_FLAGS_DEBUG="-g -Og" + -DCMAKE_PREFIX_PATH=$deps_dir ninja -j2 -v install From d374b0ea06154c806374f3b5c38438268800d328 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Thu, 19 Dec 2024 12:03:12 +0100 Subject: [PATCH 11/13] Fix tle format in test. --- heyoka/_test_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/heyoka/_test_model.py b/heyoka/_test_model.py index 4804c466..da8fba16 100644 --- a/heyoka/_test_model.py +++ b/heyoka/_test_model.py @@ -472,7 +472,7 @@ def test_gpe_is_deep_space(self): self.assertFalse(gpe_is_deep_space(sat.no_kozai, sat.ecco, sat.inclo)) # A deepspace TLE. - t1 = "2 00045 66.6943 81.3521 0257384 317.3173 40.8180 6.34783636277898" + t1 = "2 00045 66.6943 81.3521 0257384 317.3173 40.8180 6.34783636277898" sat = Satrec.twoline2rv(s1, t1) self.assertTrue(gpe_is_deep_space(sat.no_kozai, sat.ecco, sat.inclo)) From 364a63e50fc259b12cee31a70e2540540d3316ee Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 21 Dec 2024 14:11:11 +0100 Subject: [PATCH 12/13] Ping for ci. From ba8df8b974f796b8a62138f6ec5849bbb4eb7486 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sun, 22 Dec 2024 16:02:43 +0100 Subject: [PATCH 13/13] Update docs. --- doc/api_common_kwargs.rst | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/doc/api_common_kwargs.rst b/doc/api_common_kwargs.rst index 845017ed..9826988f 100644 --- a/doc/api_common_kwargs.rst +++ b/doc/api_common_kwargs.rst @@ -55,12 +55,10 @@ These are keyword arguments influencing just-in-time (JIT) compilation via LLVM. .. warning:: - Due to several LLVM issues around parallel JIT compilation, the ``parjit`` flag is currently **off** - by default on Unix platforms and completely **disabled** on Windows. Turning on ``parjit`` on Unix - platforms is considered safe but can very rarely result in a runtime exception being thrown. + Due to several LLVM issues around parallel JIT compilation, the ``parjit`` flag has temporarily been disabled. - We expect the ``parjit`` feature to become more stable in later LLVM releases, at which point it will - be turned on by default. + We expect the parallel compilation feature to become more stable in later LLVM releases, at which point + the ``parjit`` flag will be re-enabled. .. _api_common_kwargs_cfunc: