Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
gomezzz committed Jun 15, 2022
1 parent 1ece02d commit f3cc4d9
Show file tree
Hide file tree
Showing 104 changed files with 578,130 additions and 0 deletions.
57 changes: 57 additions & 0 deletions .github/workflows/ctest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [ main ]
pull_request:
branches: [ main ]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build-and-test"
build-and-test-linux:
# The type of runner that the job will run on
runs-on: ubuntu-latest

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2

- name: Build
run: |
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
- name: Test
run: cd build/test && ./polyhedralGravity_test

build-windows:
# The type of runner that the job will run on
runs-on: windows-latest

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2

- name: Build
run: |
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --config Release
# No testing on Windows GitHub since it takes too long
# - name: Test
# run: cd build && ctest

113 changes: 113 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
cmake_minimum_required(VERSION 3.16)
project(polyhedralGravity)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# Best Combo: HOST CPP, DEVICE OMP
# Parallelization on the HOST
set(PARALLELIZATION_HOST "CPP" CACHE STRING "Host parallelization chosen by the user
(CPP= Serial, OMP = OpenMP, TBB = Intel Threading Building Blocks")
set_property(CACHE PARALLELIZATION_HOST PROPERTY STRINGS CPP, OMP, TBB)

# Parallelization on the DEVICE
set(PARALLELIZATION_DEVICE "CPP" CACHE STRING "Device parallelization chosen by the user
(CPP= Serial, OMP = OpenMP, TBB = Intel Threading Building Blocks")
set_property(CACHE PARALLELIZATION_DEVICE PROPERTY STRINGS CPP, OMP, TBB)

# Set the Logging Level
set(LOGGING_LEVEL "2" CACHE STRING "Set the Logging level, default (INFO=2), available options:
TRACE=0, DEBUG=1, INFO=2, WARN=3, ERROR=4, CRITICAL=5, OFF=6")
set_property(CACHE LOGGING_LEVEL PROPERTY STRINGS 0, 1, 2, 3, 4, 5, 6)

# Enforce to use an already installed tbb library instead of compiling from source
option(USE_LOCAL_TBB "Uses the local tbb installation rather than on using the automatically fetched version from
GitHub via CMake (Default: OFF)" OFF)

option(BUILD_POLYHEDRAL_GRAVITY_DOCS "Builds the documentation (Default: OFF)" OFF)

add_compile_definitions(SPDLOG_ACTIVE_LEVEL=${LOGGING_LEVEL})

# Appends the the module path to contain additional CMake modules for this project
# and include everything necessary
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

include(spdlog)
include(tetgen)
include(yaml)
include(thrust)
include(xsimd)

# Main file, containing the gravity model's driver
set(mainFile ${PROJECT_SOURCE_DIR}/src/main.cpp)

# Including the actual Polyhedral source files
file(GLOB_RECURSE SRC
"${PROJECT_SOURCE_DIR}/src/polyhedralGravity/*.h"
"${PROJECT_SOURCE_DIR}/src/polyhedralGravity/*.cpp")

add_library(${PROJECT_NAME}_lib ${SRC})

# Adds the include Path PROJECT_SOURCE_DIR/src to the target polyhedralGravity
target_include_directories(${PROJECT_NAME}_lib PUBLIC
"${PROJECT_SOURCE_DIR}/src"
)

# Link libaries
target_link_libraries(${PROJECT_NAME}_lib
spdlog
tetgen
yaml-cpp
xsimd
)

# Get a version of tbb from the github repository, simplifies compilation for the user since tbb does not need to be
# preinstalled but rather gets automatically set up via CMake
# Nevertheless, there is still the option to enforce to use a local installation if one exists
if (NOT USE_LOCAL_TBB AND (${PARALLELIZATION_HOST} STREQUAL "TBB" OR ${PARALLELIZATION_DEVICE} STREQUAL "TBB"))
include(tbb)
thrust_set_TBB_target(tbb)
endif ()

# Thrust set-up i.e. the parallelization library, create targets according to the users specification
thrust_create_target(Thrust HOST ${PARALLELIZATION_HOST} DEVICE ${PARALLELIZATION_DEVICE})
message(STATUS "Set Parallelization: HOST ${PARALLELIZATION_HOST} DEVICE ${PARALLELIZATION_DEVICE}")
target_link_libraries(${PROJECT_NAME}_lib
Thrust
)

# This definitions will set the main eval(..) routine to be executed on the DEVICE if the users has given
# an option parallelize on the Device
if(NOT PARALLELIZATION_DEVICE STREQUAL "CPP")
add_compile_definitions(DEVICE)
endif()

# Building the standalone Executable
add_executable(${PROJECT_NAME} ${mainFile})

# Link executable with library
target_link_libraries(${PROJECT_NAME} PUBLIC ${PROJECT_NAME}_lib)

if (BUILD_POLYHEDRAL_GRAVITY_DOCS)
add_subdirectory(${PROJECT_SOURCE_DIR}/docs)
endif ()

# Option to build tests or not
option(BUILD_POLYHEDRAL_GRAVITY_TESTS "Set to on if the tests should be built (Default: ON)" ON)
# Only build the tests if they are enabled
if (BUILD_POLYHEDRAL_GRAVITY_TESTS)
message(STATUS "Building the Polyhedral Gravity Tests")
# Enables CTest, must be in the top-level CMakeList.txt, otherwise it won't work
enable_testing()

# Subdirectory where the tests are located
add_subdirectory(${PROJECT_SOURCE_DIR}/test)
endif ()

# Option to build the python interface
option(BUILD_POLYHEDRAL_PYTHON_INTERFACE "Set this to on if the python interface should be built (Default: ON)" ON)
# Build the polyhedral gravity python interface
if(BUILD_POLYHEDRAL_PYTHON_INTERFACE)
message(STATUS "Building the Polyhedral Gravity Python Interface")
add_subdirectory(${PROJECT_SOURCE_DIR}/python-binding)
endif()
129 changes: 129 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# polyhedral-gravity-model-cpp

![Build and Test](https://github.com/schuhmaj/polyhedral-gravity-model-cpp/actions/workflows/ctest.yml/badge.svg)
[![Documentation Status](https://readthedocs.org/projects/polyhedral-gravity-model-cpp/badge/?version=latest)](https://polyhedral-gravity-model-cpp.readthedocs.io/en/latest/?badge=latest)

Implementation of the Polyhedral Gravity Model in C++ 17.

The implementation is based on the paper [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)
and its corresponding [implementation in FORTRAN](https://software.seg.org/2012/0001/index.html).

Supplementary details can be found in the more recent paper [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)
and its corresponding [implementation in MATLAB](https://github.com/Gavriilidou/GPolyhedron),
which is strongly based on the former implementation in FORTRAN.

## Documentation

The full extensive documentation can be found on [readthedocs](https://polyhedral-gravity-model-cpp.readthedocs.io/en/latest/).


## Requirements
The project uses the following dependencies,
all of them are **automatically** set-up via CMake:

- GoogleTest 1.11.0 (only required for testing)
- spdlog 1.9.2 (required for logging)
- tetgen 1.6 (required for I/O)
- yaml-cpp 0.7.0 (required for I/O)
- thrust 1.16.0 (required for parallelization and utility)
- xsimd 8.1.0 (required for vectorization of the `atan(..)`)

## Build
The program is build by using CMake. So first make sure that you installed
CMake and then follow these steps:

mkdir build
cd build
cmake .. <options>
cmake --build .

The following options are available:

| Name (Default) | Options and Remark |
|:------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|
| PARALLELIZATION_HOST (`CPP`) | `CPP` = Serial Execution on Host, `OMP`/ `TBB` = Parallel Execution on Host with OpenMP or Intel's TBB |
| PARALLELIZATION_DEVICE (`CPP`) | `CPP`= Serial Execution on Device, `OMP`/ `TBB` = Parallel Execution on Device with OpenMP or Intel's TBB |
| LOGGING_LEVEL (`2`) | `0`= TRACE, `1`=DEBUG, `2`=INFO, `3`=WARN, `4`=ERROR, `5`=CRITICAL, `6`=OFF |

During testing the combination PARALLELIZATION_HOST=`CPP` and PARALLELIZATION_DEVICE=`TBB`
has been the most performant.
It is further not recommend to change the LOGGING_LEVEL to something else than `INFO=2`.

The recommended CMake command would look like this (we only need to change `PARALLELIZATION_DEVICE`, since
the defaults of the others are already correctly set):

cmake .. -DPARALLELIZATION_DEVICE="TBB"

## Execution

### Overview

After the build, the gravity model can be run by executing:

./polyhedralGravity <YAML-Configuration-File>

where the YAML-Configuration-File contains the required parameters.
Examples for Configuration Files and Polyhedral Source Files can be
found in this repository in the folder `/example-config/`.

### Config File

The configuration should look similar to the given example below.
It is required to specify the source-files of the polyhedron's mesh (more info
about the supported file in the [next paragraph](#polyhedron-source-files)), the density
of the polyhedron, and the wished computation points where the
gravity tensor shall be computed.
Further one must specify the name of the .csv output file.

````yaml
---
gravityModel:
input:
polyhedron: #polyhedron source-file(s)
- "../example-config/data/tsoulis.node" #.node contains the vertices
- "../example-config/data/tsoulis.face" #.face contains the triangular faces
density: 2670.0 #constant density in [kg/m^3]
points: #Location of the computation point(s) P
- [0, 0, 0] #Here it is situated at the origin
output:
filename: "gravity_result.csv" #The name of the output file

````

### Polyhedron Source Files

The implementation supports multiple common mesh formats for
the polyhedral source. These include:

| File Suffix | Name | Comment |
|:-------------------:|:--------------------------------------------------:|--------------------------------------------------------------------------------------------------------------------------------------------------|
| `.node` and `.face` | TetGen's files | These two files need to be given as a pair to the input. [Documentation of TetGen's files](https://wias-berlin.de/software/tetgen/fformats.html) |
| `.mesh` | Medit's mesh files | Single file containing every needed mesh information. |
| `.ply` | The Polygon File format/ Stanfoard Triangle format | Single file containing every needed mesh information. Blender File Format. |
| `.off` | Object File Format | Single file containing every needed mesh information. |
| `.stl` | Stereolithography format | Single file containing every needed mesh information. Blender File Format. |

**Notice!** Only the ASCII versions of those respective files are supported! This is especially
important for e.g. the `.ply` files which also can be in binary format.

Good tools to convert your Polyhedron to a supported format (also for interchanging
ASCII and binary format) are e.g.:

- [Meshio](https://github.com/nschloe/meshio) for Python
- [OpenMesh](https://openmesh-python.readthedocs.io/en/latest/readwrite.html) for Python

### Output

The calculation outputs the following parameters for every Computation Point _P_:

| Name | Unit | Comment |
|:----------------------------:|:---------------:|:-----------------------------------------------------------------:|
| V | m^2/s^2 or J/kg | The potential or also called specific energy |
| Vx, Vy, Vz | m/s^2 | The gravitational accerleration in the three cartesian directions |
| Vxx, Vyy, Vzz, Vxy, Vxz, Vyz | 1/s^2 | The spatial rate of change of the gravitational accleration |

## Testing
The project uses GoogleTest for testing. In oder to execute those
tests just execute the following command in the build directory:

ctest
12 changes: 12 additions & 0 deletions cmake/FindSphinx.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Adapted from https://devblogs.microsoft.com/cppblog/clear-functional-c-documentation-with-sphinx-breathe-doxygen-cmake/
# Look for an executable called sphinx-build
find_program(SPHINX_EXECUTABLE
NAMES sphinx-build
DOC "Path to sphinx-build executable")

include(FindPackageHandleStandardArgs)

# Handle standard arguments to find_package like REQUIRED and QUIET
find_package_handle_standard_args(Sphinx
"Failed to find sphinx-build executable"
SPHINX_EXECUTABLE)
18 changes: 18 additions & 0 deletions cmake/gtest.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
include(FetchContent)

message(STATUS "Setting up gtest")

#Adapted from https://cliutils.gitlab.io/modern-cmake/chapters/testing/googletest.html
#Fetches the version 1.11.0 from the official github for googletest
FetchContent_Declare(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.11.0
)

FetchContent_MakeAvailable(googletest)

# Disable warnings from the library target
target_compile_options(gtest_main PRIVATE -w)
# Disable warnings from included headers
get_target_property(propval gtest_main INTERFACE_INCLUDE_DIRECTORIES)
target_include_directories(gtest_main SYSTEM PUBLIC "${propval}")
11 changes: 11 additions & 0 deletions cmake/pybind11.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
include(FetchContent)

message(STATUS "Setting up pybind11")

#Fetches the version 2.9.2 from the official github of pybind11
FetchContent_Declare(pybind11
GIT_REPOSITORY https://github.com/pybind/pybind11
GIT_TAG v2.9.2
)

FetchContent_MakeAvailable(pybind11)
22 changes: 22 additions & 0 deletions cmake/spdlog.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
include(FetchContent)

message(STATUS "Setting up spdlog")

#Fetches the version 1.9.2 for spdlog
FetchContent_Declare(spdlog
GIT_REPOSITORY https://github.com/gabime/spdlog.git
GIT_TAG v1.9.2
)

# Disable stuff we don't need
option(SPDLOG_BUILD_EXAMPLE "" OFF)
option(SPDLOG_BUILD_TESTS "" OFF)
option(SPDLOG_INSTALL "" OFF)

FetchContent_MakeAvailable(spdlog)

# Disable warnings from the library target
target_compile_options(spdlog PRIVATE -w)
# Disable warnings from included headers
get_target_property(propval spdlog INTERFACE_INCLUDE_DIRECTORIES)
target_include_directories(spdlog SYSTEM PUBLIC "${propval}")
11 changes: 11 additions & 0 deletions cmake/tbb.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
include(FetchContent)

message(STATUS "Setting up tbb via CMake")

#Fetches the version v2021.5.0 from the official github of tbb
FetchContent_Declare(tbb
GIT_REPOSITORY https://github.com/oneapi-src/oneTBB.git
GIT_TAG v2021.5.0
)

FetchContent_MakeAvailable(tbb)
Loading

0 comments on commit f3cc4d9

Please sign in to comment.