{"id":20921142,"url":"https://github.com/esa/polyhedral-gravity-model","last_synced_at":"2025-04-09T07:08:11.069Z","repository":{"id":40515163,"uuid":"503791742","full_name":"esa/polyhedral-gravity-model","owner":"esa","description":"Implementation of a polyhedral gravity model in C++17 with a Python Binding","archived":false,"fork":false,"pushed_at":"2025-02-13T19:14:38.000Z","size":21889,"stargazers_count":27,"open_issues_count":2,"forks_count":10,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-02T02:40:34.651Z","etag":null,"topics":["cpp17","gravity","polyhedral-model","python"],"latest_commit_sha":null,"homepage":"https://esa.github.io/polyhedral-gravity-model/","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/esa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-15T14:06:02.000Z","updated_at":"2025-03-21T15:18:24.000Z","dependencies_parsed_at":"2023-10-11T22:12:28.199Z","dependency_job_id":"72aaaa51-f749-4678-b693-96d8e1ef0475","html_url":"https://github.com/esa/polyhedral-gravity-model","commit_stats":{"total_commits":85,"total_committers":5,"mean_commits":17.0,"dds":0.05882352941176472,"last_synced_commit":"6b432a63b3577172ea090c7e24b8264994e395f1"},"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esa%2Fpolyhedral-gravity-model","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esa%2Fpolyhedral-gravity-model/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esa%2Fpolyhedral-gravity-model/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esa%2Fpolyhedral-gravity-model/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/esa","download_url":"https://codeload.github.com/esa/polyhedral-gravity-model/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247994121,"owners_count":21030050,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp17","gravity","polyhedral-model","python"],"created_at":"2024-11-18T19:09:16.313Z","updated_at":"2025-04-09T07:08:11.052Z","avatar_url":"https://github.com/esa.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"# polyhedral-gravity-model\n\n[![DOI](https://joss.theoj.org/papers/10.21105/joss.06384/status.svg)](https://doi.org/10.21105/joss.06384)\n![GitHub](https://img.shields.io/github/license/esa/polyhedral-gravity-model)\n![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/esa/polyhedral-gravity-model/.github%2Fworkflows%2Fbuild-and-test.yml?logo=GitHub%20Actions\u0026label=Build%20and%20Test)\n![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/esa/polyhedral-gravity-model/.github%2Fworkflows%2Fdocs.yml?logo=GitBook\u0026label=Documentation)\n\n![PyPI](https://img.shields.io/pypi/v/polyhedral-gravity)\n![Static Badge](https://img.shields.io/badge/platform-linux--64_%7C_win--64_%7C_osx--64_%7C_linux--arm64_%7C_osx--arm64-lightgrey)\n![PyPI - Downloads](https://img.shields.io/pypi/dm/polyhedral-gravity)\n\n![Conda](https://img.shields.io/conda/v/conda-forge/polyhedral-gravity-model)\n![Conda](https://img.shields.io/conda/pn/conda-forge/polyhedral-gravity-model)\n![Conda](https://img.shields.io/conda/dn/conda-forge/polyhedral-gravity-model)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"paper/figures/eros_010.png\" width=\"50%\"\u003e\n  \u003cbr\u003e\n  \u003cem\u003e\n    \u003ca href=\"https://github.com/gomezzz/geodesyNets/blob/master/3dmeshes/eros_lp.pk\"\u003eMesh of (433) Eros\u003c/a\u003e with 739 vertices and 1474 faces\n  \u003c/em\u003e\n\u003c/p\u003e\n\n## Table of Contents\n\n- [References](#references)\n- [Documentation \u0026 Examples](#documentation--examples)\n  - [Input \u0026 Output (C++ and Python)](#input--output-c-and-python)\n  - [Minimal Python Example](#minimal-python-example)\n  - [Minimal C++ Example](#minimal-c-example)\n- [Installation](#installation)\n  - [With conda](#with-conda)\n  - [With pip](#with-pip)\n  - [From source](#from-source)\n- [C++ Library \u0026 Executable](#c-library--executable)\n  - [Building the C++ Library \u0026 Executable](#building-the-c-library--executable)\n  - [Running the C++ Executable](#running-the-c-executable)\n- [Testing](#testing)\n- [Contributing](#contributing)\n\n## References\n\nThis code is a validated implementation in C++17 of the Polyhedral Gravity Model\nby Tsoulis et al.. Additionally, the model provides a Python binding.\nIt was initially created in a collaborative project between\nTU Munich and ESA's Advanced Concepts Team.\n\nIf this implementation proves useful to you, please consider citing the \n[accompanying paper](https://doi.org/10.21105/joss.06384)\npublished in the *Journal of Open Source Software*.\n\nThe implementation is based on the\npaper [Tsoulis, D., 2012. Analytical computation of the full gravity tensor of a homogeneous arbitrarily shaped polyhedral source using line integrals. Geophysics, 77(2), pp.F1-F11.](http://dx.doi.org/10.1190/geo2010-0334.1)\nand its corresponding implementation in FORTRAN.\n\nSupplementary details can be found in the more recent\npaper [TSOULIS, Dimitrios; GAVRIILIDOU, Georgia. A computational review of the line integral analytical formulation of the polyhedral gravity signal. Geophysical Prospecting, 2021, 69. Jg., Nr. 8-9, S. 1745-1760.](https://doi.org/10.1111/1365-2478.13134)\nand its corresponding [implementation in MATLAB](https://github.com/Gavriilidou/GPolyhedron),\nwhich is strongly based on the former implementation in FORTRAN.\n\n## Documentation \u0026 Examples\n\n\u003e [!NOTE]\n\u003e The [GitHub Pages](https://esa.github.io/polyhedral-gravity-model) of this project\ncontain the full extensive documentation of the C++ Library and Python Interface\nas well as background on the gravity model and advanced settings not detailed here.\n\n## Input \u0026 Output (C++ and Python)\n\n### Input\n\nThe evaluation of the polyhedral gravity model requires the following parameters:\n\n| Name                                                                       |\n|----------------------------------------------------------------------------|\n| Polyhedral Mesh (either as vertices \u0026 faces or as polyhedral source files) |\n| Constant Density $\\rho$                                                    |\n\nThe mesh and the constants density's unit must match.\nHave a look the documentation to view the [supported mesh files](https://esa.github.io/polyhedral-gravity-model/quickstart/supported_input.html).\n\n### Output\n\nThe calculation outputs the following parameters for every Computation Point *P*.\nThe units of the respective output depend on the units of the input parameters (mesh and density)!\nHence, if e.g. your mesh is in $km$, the density must match. Further, output units will be different accordingly.\n\n|                            Name                            | Unit (if mesh in $[m]$ and $\\rho$ in $[kg/m^3]$) |                              Comment                              |\n|:----------------------------------------------------------:|:------------------------------------------------:|:-----------------------------------------------------------------:|\n|                            $V$                             |       $\\frac{m^2}{s^2}$ or $\\frac{J}{kg}$        |           The potential or also called specific energy            |\n|                    $V_x$, $V_y$, $V_z$                     |                 $\\frac{m}{s^2}$                  | The gravitational accerleration in the three cartesian directions |\n| $V_{xx}$, $V_{yy}$, $V_{zz}$, $V_{xy}$, $V_{xz}$, $V_{yz}$ |                 $\\frac{1}{s^2}$                  |   The spatial rate of change of the gravitational accleration    |\n\n\n\u003e[!NOTE]\n\u003eThis gravity model's output obeys to the geodesy and geophysics sign conventions.\nHence, the potential $V$ for a polyhedron with a mass $m \u003e 0$ is defined as **positive**.\nAccordingly, the accelerations are defined as $\\textbf{g} = + \\nabla V$.\n\n\n### Minimal Python Example\n\nThe following example shows how to use the python interface to compute the gravity\naround a cube:\n\n```python\nimport numpy as np\nfrom polyhedral_gravity import Polyhedron, GravityEvaluable, evaluate, PolyhedronIntegrity, NormalOrientation\n\n# We define the cube as a polyhedron with 8 vertices and 12 triangular faces\n# The polyhedron's normals point outwards (see below for checking this)\n# The density is set to 1.0\ncube_vertices = np.array(\n  [[-1, -1, -1], [1, -1, -1], [1, 1, -1], [-1, 1, -1],\n   [-1, -1, 1], [1, -1, 1], [1, 1, 1], [-1, 1, 1]]\n)\ncube_faces = np.array(\n  [[1, 3, 2], [0, 3, 1], [0, 1, 5], [0, 5, 4], [0, 7, 3], [0, 4, 7],\n   [1, 2, 6], [1, 6, 5], [2, 3, 6], [3, 7, 6], [4, 5, 6], [4, 6, 7]]\n)\ncube_density = 1.0\ncomputation_point = np.array([0, 0, 0])\n```\n\nWe first define a constant density Polyhedron from `vertices` and `faces`\n\n```python\ncube_polyhedron = Polyhedron(\n  polyhedral_source=(cube_vertices, cube_faces),\n  density=cube_density,\n)\n```\n\nIn case you want to hand over the polyhedron via a [supported file format](https://esa.github.io/polyhedral-gravity-model/quickstart/supported_input.html),\njust replace the `polyhedral_source` argument with *a list of strings*,\nwhere each string is the path to a supported file format, e.g. `polyhedral_source=[\"eros.node\",\"eros.face\"]` or `polyhedral_source=[\"eros.mesh\"]`.\n\nContinuing, the simplest way to compute the gravity is to use the `evaluate` function:\n\n```python\npotential, acceleration, tensor = evaluate(\n  polyhedron=cube_polyhedron,\n  computation_points=computation_point,\n  parallel=True,\n)\n```\n\nThe more advanced way is to use the `GravityEvaluable` class. It caches the\ninternal data structure and properties which can be reused for multiple\nevaluations. This is especially useful if you want to compute the gravity\nfor multiple computation points, but don't know the \"future points\" in advance.\n\n```python\nevaluable = GravityEvaluable(polyhedron=cube_polyhedron) # stores intermediate computation steps\npotential, acceleration, tensor = evaluable(\n  computation_points=computation_point,\n  parallel=True,\n)\n# Any future evaluable call after this one will be faster\n```\n\nNote that the `computation_point` could also be (N, 3)-shaped array to compute multiple points at once.\nIn this case, the return value of `evaluate(..)` or an `GravityEvaluable` will\nbe a list of triplets comprising potential, acceleration, and tensor.\n\nThe gravity model requires that all the polyhedron's plane unit normals consistently\npoint outwards or inwards the polyhedron. You can specify this via the `normal_orientation`.\nThis property is - by default - checked when constructing the `Polyhedron`! So, don't worry, it\nis impossible if not **explicitly** disabled to create an invalid `Polyhedron`.\nYou can disable/ enable this setting via the optional `integrity_check` flag and can even\nautomatically repair the ordering via `HEAL`.\nIf you are confident that your mesh is defined correctly (e.g. checked once with the integrity check)\nyou can disable this check (via `DISABLE`) to avoid the additional runtime overhead of the check.\n\n```python\ncube_polyhedron = Polyhedron(\n  polyhedral_source=(cube_vertices, cube_faces),\n  density=cube_density,\n  normal_orientation=NormalOrientation.INWARDS, # OUTWARDS (default) or INWARDS\n  integrity_check=PolyhedronIntegrity.VERIFY,   # VERIFY (default), DISABLE or HEAL\n)\n```\n\n\u003e [!TIP]\n\u003e More examples and plots are depicted in the\n[jupyter notebook](script/polyhedral-gravity.ipynb).\n\n\n### Minimal C++ Example\n\nThe following example shows how to use the C++ library to compute the gravity.\nIt works analogously to the Python example above.\n\n```cpp\n// Defining the input like above in the Python example\nstd::vector\u003cstd::array\u003cdouble, 3\u003e\u003e vertices = ...\nstd::vector\u003cstd::array\u003csize_t, 3\u003e\u003e faces = ...\ndouble density = 1.0;\n// The constant density polyhedron is defined by its vertices \u0026 faces\n// It also supports the hand-over of NormalOrientation and PolyhedronIntegrity as optional arguments\n// as above described for the Python Interface\nPolyhedron polyhedron{vertices, faces, density};\nstd::vector\u003cstd::array\u003cdouble, 3\u003e\u003e points = ...\nstd::array\u003cdouble, 3\u003e point = points[0];\nbool parallel = true;\n```\n\nThe C++ library provides also two ways to compute the gravity. Via\nthe free function `evaluate`...\n\n```cpp\nconst auto[pot, acc, tensor] = GravityModel::evaluate(polyhedron, point, parallel);\n```\n\n... or via the `GravityEvaluable` class.\n\n```cpp\n// Instantiation of the GravityEvaluable object\nGravityEvaluable evaluable{polyhedron};\n\n// From now, we can evaluate the gravity model for any point with\nconst auto[potential, acceleration, tensor] = evaluable(point, parallel);\n// or for multiple points with\nconst auto results = evaluable(points, parallel);\n```\n\nSimilarly to Python, the C++ implementation also provides mesh checking capabilities.\n\n\u003e [!TIP]\n\u003e For reference, have a look at [the main method](./src/main.cpp) of the C++ executable.\n\n## Installation\n\n### With conda\n\nThe python interface can be easily installed with\n[conda](https://anaconda.org/conda-forge/polyhedral-gravity-model):\n\n```bash\nconda install -c conda-forge polyhedral-gravity-model\n```\n\n### With pip\n\nAs a second option, you can also install the python interface with pip from [PyPi](https://pypi.org/project/polyhedral-gravity/).\n\n```bash\npip install polyhedral-gravity\n```\n\nBinaries for the most common platforms are available on PyPI including\nWindows, Linux and macOS. For macOS and Linux, binaries for\n`x86_64` and `aarch64` are provided.\nIn case `pip` uses the source distribution, please make sure that\nyou have a C++17 capable compiler and CMake installed.\n\n### From source\n\nThe project uses the following dependencies,\nall of them are **automatically** set-up via CMake:\n\n- GoogleTest (1.15.2 or compatible), only required for testing\n- spdlog (1.13.0 or compatible), required for logging\n- tetgen (1.6 or compatible), required for I/O\n- yaml-cpp (0.8.0 or compatible), required for I/O\n- thrust (2.1.0 or compatible), required for parallelization and utility\n- xsimd (11.1.0 or compatible), required for vectorization of the `atan(..)`\n- pybind11 (2.12.0 or compatible), required for the Python interface, but not the C++ standalone\n\nThe module will be build using a C++17 capable compiler,\nCMake. Just execute the following command in\nthe repository root folder:\n\n```bash\npip install .\n```\n\nTo modify the build options (like parallelization) have a look\nat the [next paragraph](#building-the-c-library--executable). The options\nare modified by setting the environment variables before executing\nthe `pip install .` command, e.g.:\n\n```bash\nexport POLYHEDRAL_GRAVITY_PARALLELIZATION=\"TBB\"\npip install .\n```\n\n(Optional: For a faster build you can install all dependencies available\nfor your system in your local python environment. That way, they\nwon't be fetched from GitHub.)\n\n## C++ Library \u0026 Executable\n\n### Building the C++ Library \u0026 Executable\n\nThe program is build by using CMake. So first make sure that you installed\nCMake and then follow these steps:\n\n```bash\nmkdir build\ncd build\ncmake .. \u003coptions\u003e\ncmake --build .\n```\n\nThe following options are available:\n\n|                                               Name (Default) | Options                                                                                     |\n|-------------------------------------------------------------:|:--------------------------------------------------------------------------------------------|\n|                   POLYHEDRAL_GRAVITY_PARALLELIZATION (`CPP`) | `CPP` = Serial Execution / `OMP` or `TBB` = Parallel Execution with OpenMP or Intel\\'s TBB  |\n|                    POLYHEDRAL_GRAVITY_LOGGING_LEVEL (`INFO`) | `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `CRITICAL`, `OFF`                                |\n|                        BUILD_POLYHEDRAL_GRAVITY_DOCS (`OFF`) | Build this documentation                                                                    |\n|                        BUILD_POLYHEDRAL_GRAVITY_TESTS (`ON`) | Build the Tests                                                                             |\n|             BUILD_POLYHEDRAL_GRAVITY_PYTHON_INTERFACE (`ON`) | Build the Python interface                                                                  |\n\nDuring testing POLYHEDRAL_GRAVITY_PARALLELIZATION=`TBB` has been the most performant.\nIt is further not recommend to change the POLYHEDRAL_GRAVITY_LOGGING_LEVEL to something else than `INFO=2`.\n\nThe recommended CMake settings using the `TBB` backend would look like this:\n\n```bash\ncmake .. -POLYHEDRAL_GRAVITY_PARALLELIZATION=\"TBB\"\n```\n\n### Running the C++ Executable\n\nAfter the build, the gravity model can be run by executing:\n\n```bash\n./polyhedralGravity \u003cYAML-Configuration-File\u003e\n```\n\nwhere the YAML-Configuration-File contains the required parameters.\nExamples for Configuration Files and Polyhedral Source Files can be\nfound in this repository in the folder `/example-config/`.\n\n#### Input Configuration File\n\nThe configuration should look similar to the given example below.\nIt is required to specify the source-files of the polyhedron's mesh (more info\nabout the supported file in the [documentation](https://esa.github.io/polyhedral-gravity-model/quickstart/supported_input.html)), the density\nof the polyhedron, and the wished computation points where the\ngravity tensor shall be computed.\nFurther one must specify the name of the .csv output file.\n\n````yaml\n---\ngravityModel:\n  input:\n    polyhedron: #polyhedron source-file(s)\n      - \"../example-config/data/tsoulis.node\"   # .node contains the vertices\n      - \"../example-config/data/tsoulis.face\"   # .face contains the triangular faces\n    density: 2670.0                             # constant density, units must match with the mesh (see section below)\n    points: # Location of the computation point(s) P\n      - [ 0, 0, 0 ]                             # Here it is situated at the origin\n    check_mesh: true                            # Fully optional, enables mesh autodetect+repair of \n                                                # the polyhedron's vertex ordering (not given: true)\n  output:\n    filename: \"gravity_result.csv\"              # The name of the output file \n\n````\n\n#### Output\n\nThe executable produces a CSV file containing $V$, $V_x$, $V_y$, $V_z$,\n$V_{xx}$, $V_{yy}$, $V_{zz}$, $V_{xy}$, $V_{xz}$, $V_{yz}$ for every\ncomputation point *P*.\n\n## Testing\n\nThe project uses GoogleTest for testing. In oder to execute those\ntests just execute the following command in the build directory:\n\n```bash\nctest\n```\n\nFor the Python test suite, please execute the following command in the repository root folder:\n\n```bash\npytest\n```\n\n## Contributing\n\nWe are happy to accept contributions to the project in the form of\nsuggestions, bug reports and pull requests. Please have a look at\nthe [contributing guidelines](CONTRIBUTING.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesa%2Fpolyhedral-gravity-model","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fesa%2Fpolyhedral-gravity-model","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesa%2Fpolyhedral-gravity-model/lists"}