Malla de (433) Eros con 739 vértices y 1474 caras
Este código es una implementación validada en C ++ 17 del modelo de gravedad poliédrica por Tsoulis et al .. Además, el modelo proporciona una unión de Python. Inicialmente se creó en un proyecto de colaboración entre TU Munich y el equipo de conceptos avanzados de ESA.
Si esta implementación le resulta útil, considere citar el documento que lo acompaña publicado en la revista de software de código abierto .
La implementación se basa en el documento Tsoulis, D., 2012. Cálculo analítico del tensor de gravedad total de una fuente poliédrica homogénea de forma arbitraria utilizando integrales de línea. Geofísica, 77 (2), pp.f1-f11. y su implementación correspondiente en Fortran.
Los detalles complementarios se pueden encontrar en el documento más reciente Tsoulis, Dimitrios; Gavriilidou, Georgia. Una revisión computacional de la formulación analítica integral de la línea de la señal de gravedad poliédrica. Prospección Geofísica, 2021, 69. Jg., Nr. 8-9, S. 1745-1760. y su implementación correspondiente en MATLAB, que se basa fuertemente en la implementación anterior en Fortran.
Nota
Las páginas GitHub de este proyecto contienen la documentación completa de la biblioteca C ++ y la interfaz de Python, así como el fondo del modelo de gravedad y la configuración avanzada no detalladas aquí.
La evaluación del modelo de gravedad poliédrica requiere los siguientes parámetros:
Nombre |
---|
Malla poliédrica (ya sea como vértices y caras o como archivos de origen poliédrico) |
Densidad constante |
La unidad de malla y la densidad de constantes debe coincidir. Eche un vistazo a la documentación para ver los archivos de malla compatibles.
El cálculo genera los siguientes parámetros para cada punto de cálculo p . ¡Las unidades de la salida respectiva dependen de las unidades de los parámetros de entrada (malla y densidad)! Por lo tanto, si, por ejemplo, tu malla está en
Nombre | Unidad (si está en malla en | Comentario |
---|---|---|
El potencial o también llamado energía específica | ||
La acre de acerslación gravitacional en las tres direcciones cartesianas | ||
La tasa de cambio espacial de la acleración gravitacional |
Nota
La salida de este modelo de gravedad obedece a las convenciones de geodesia y geophysics de signos. Por lo tanto, el potencial
El siguiente ejemplo muestra cómo usar la interfaz Python para calcular la gravedad alrededor de un cubo:
import numpy as np
from polyhedral_gravity import Polyhedron , GravityEvaluable , evaluate , PolyhedronIntegrity , NormalOrientation
# We define the cube as a polyhedron with 8 vertices and 12 triangular faces
# The polyhedron's normals point outwards (see below for checking this)
# The density is set to 1.0
cube_vertices = np . array (
[[ - 1 , - 1 , - 1 ], [ 1 , - 1 , - 1 ], [ 1 , 1 , - 1 ], [ - 1 , 1 , - 1 ],
[ - 1 , - 1 , 1 ], [ 1 , - 1 , 1 ], [ 1 , 1 , 1 ], [ - 1 , 1 , 1 ]]
)
cube_faces = np . array (
[[ 1 , 3 , 2 ], [ 0 , 3 , 1 ], [ 0 , 1 , 5 ], [ 0 , 5 , 4 ], [ 0 , 7 , 3 ], [ 0 , 4 , 7 ],
[ 1 , 2 , 6 ], [ 1 , 6 , 5 ], [ 2 , 3 , 6 ], [ 3 , 7 , 6 ], [ 4 , 5 , 6 ], [ 4 , 6 , 7 ]]
)
cube_density = 1.0
computation_point = np . array ([ 0 , 0 , 0 ])
Primero definimos un poliedro de densidad constante de vertices
y faces
cube_polyhedron = Polyhedron (
polyhedral_source = ( cube_vertices , cube_faces ),
density = cube_density ,
)
En caso de que desee entregar el poliedro a través de un formato de archivo compatible, simplemente reemplace el argumento polyhedral_source
con una lista de cadenas , donde cada cadena es la ruta a un formato de archivo compatible, por ejemplo polyhedral_source=["eros.node","eros.face"]
o polyhedral_source=["eros.mesh"]
.
Continuando, la forma más sencilla de calcular la gravedad es usar la función evaluate
:
potential , acceleration , tensor = evaluate (
polyhedron = cube_polyhedron ,
computation_points = computation_point ,
parallel = True ,
)
La forma más avanzada es usar la clase GravityEvaluable
. Conta cachorra la estructura de datos internos y las propiedades que pueden reutilizarse para múltiples evaluaciones. Esto es especialmente útil si desea calcular la gravedad para múltiples puntos de cálculo, pero no conozca los "puntos futuros" de antemano.
evaluable = GravityEvaluable ( polyhedron = cube_polyhedron ) # stores intermediate computation steps
potential , acceleration , tensor = evaluable (
computation_points = computation_point ,
parallel = True ,
)
# Any future evaluable call after this one will be faster
Tenga en cuenta que el computation_point
también podría ser una matriz en forma de (N, 3) para calcular múltiples puntos a la vez. En este caso, el valor de retorno de evaluate(..)
o un GravityEvaluable
será una lista de trillizos que comprenden potencial, aceleración y tensor.
El modelo de gravedad requiere que todas las normales de la unidad plana del poliedro apunten consistentemente hacia afuera o hacia adentro del poliedro. Puede especificar esto a través de normal_orientation
. ¡Esta propiedad está, por defecto, verificada al construir el Polyhedron
! Por lo tanto, no se preocupe, es imposible si no está desactivado explícitamente crear un Polyhedron
inválido. Puede deshabilitar/ habilitar esta configuración a través del indicador opcional integrity_check
e incluso puede reparar automáticamente el pedido a través de HEAL
. Si confía en que su malla se define correctamente (por ejemplo, se verifica una vez con la verificación de integridad), puede deshabilitar esta verificación (a través de DISABLE
) para evitar la sobrecarga de tiempo de ejecución adicional de la verificación.
cube_polyhedron = Polyhedron (
polyhedral_source = ( cube_vertices , cube_faces ),
density = cube_density ,
normal_orientation = NormalOrientation . INWARDS , # OUTWARDS (default) or INWARDS
integrity_check = PolyhedronIntegrity . VERIFY , # VERIFY (default), DISABLE or HEAL
)
Consejo
Se representan más ejemplos y tramas en el cuaderno Jupyter.
El siguiente ejemplo muestra cómo usar la biblioteca C ++ para calcular la gravedad. Funciona análoga al ejemplo de Python anterior.
// Defining the input like above in the Python example
std::vector<std::array< double , 3 >> vertices = ...
std::vector<std::array< size_t , 3 >> faces = ...
double density = 1.0 ;
// The constant density polyhedron is defined by its vertices & faces
// It also supports the hand-over of NormalOrientation and PolyhedronIntegrity as optional arguments
// as above described for the Python Interface
Polyhedron polyhedron{vertices, faces, density};
std::vector<std::array< double , 3 >> points = ...
std::array< double , 3 > point = points[ 0 ];
bool parallel = true ;
La biblioteca C ++ también proporciona dos formas de calcular la gravedad. A través de la función libre evaluate
...
const auto [pot, acc, tensor] = GravityModel::evaluate(polyhedron, point, parallel);
... o a través de la clase GravityEvaluable
.
// Instantiation of the GravityEvaluable object
GravityEvaluable evaluable{polyhedron};
// From now, we can evaluate the gravity model for any point with
const auto [potential, acceleration, tensor] = evaluable(point, parallel);
// or for multiple points with
const auto results = evaluable(points, parallel);
De manera similar a Python, la implementación de C ++ también proporciona capacidades de verificación de malla.
Consejo
Como referencia, eche un vistazo al método principal del ejecutable de C ++.
La interfaz de Python se puede instalar fácilmente con conda:
conda install -c conda-forge polyhedral-gravity-model
Como segunda opción, también puede instalar la interfaz Python con PIP de Pypi.
pip install polyhedral-gravity
Los binarios para las plataformas más comunes están disponibles en PYPI, incluidos Windows, Linux y MacOS. Para MacOS y Linux, se proporcionan binarios para x86_64
y aarch64
. En caso de que pip
use la distribución de origen, asegúrese de tener un compilador capaz de C ++ 17 y instalados CMake.
El proyecto utiliza las siguientes dependencias, todas ellas se configuran automáticamente a través de CMake:
atan(..)
El módulo se construirá utilizando un compilador capaz C ++ 17, CMake. Simplemente ejecute el siguiente comando en la carpeta raíz del repositorio:
pip install .
Para modificar las opciones de compilación (como la paralelización), eche un vistazo al siguiente párrafo. Las opciones se modifican configurando las variables de entorno antes de ejecutar la pip install .
Comando, por ejemplo:
export POLYHEDRAL_GRAVITY_PARALLELIZATION= " TBB "
pip install .
(Opcional: para una compilación más rápida, puede instalar todas las dependencias disponibles para su sistema en su entorno local de Python. De esa manera, no se pueden obtener de GitHub).
El programa se construye mediante el uso de CMake. Así que primero asegúrese de instalar CMake y luego siga estos pasos:
mkdir build
cd build
cmake .. < options >
cmake --build .
Las siguientes opciones están disponibles:
Nombre (predeterminado) | Opción |
---|---|
Polyhedral_gravity_parallelization ( CPP ) | CPP = Ejecución en serie / OMP o TBB = Ejecución paralela con OpenMP o TBB de Intel |
Logging_level ( INFO ) | TRACE , DEBUG , INFO , WARN , ERROR , CRITICAL , OFF |
Build_polyhedral_gravity_docs ( OFF ) | Construir esta documentación |
Build_polyhedral_gravity_tests ( ON ) | Construir las pruebas |
Build_polyhedral_python_interface ( ON ) | Construye la interfaz Python |
Durante la prueba, Polyhedral_Gravity_Parallelization = TBB
ha sido el más desempeñado. Además, no se recomienda cambiar el logging_level a algo más que INFO=2
.
La configuración recomendada de CMake utilizando el backend TBB
se vería así:
cmake .. -POLYHEDRAL_GRAVITY_PARALLELIZATION= " TBB "
Después de la construcción, el modelo de gravedad se puede ejecutar ejecutando:
./polyhedralGravity < YAML-Configuration-File >
donde el archivo de configuración YAML contiene los parámetros requeridos. Se pueden encontrar ejemplos de archivos de configuración y archivos fuente poliédricos en este repositorio en la carpeta /example-config/
.
La configuración debe parecer similar al ejemplo dado a continuación. Se requiere especificar los archivos de origen de la malla de Polyhedron (más información sobre el archivo compatible en la documentación), la densidad del poliedro y los puntos de cálculo deseados donde se calculará el tensor de gravedad. Además, uno debe especificar el nombre del archivo de salida .csv.
---
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, units must match with the mesh (see section below)
points : # Location of the computation point(s) P
- [ 0, 0, 0 ] # Here it is situated at the origin
check_mesh : true # Fully optional, enables mesh autodetect+repair of
# the polyhedron's vertex ordering (not given: true)
output :
filename : " gravity_result.csv " # The name of the output file
El ejecutable produce un archivo CSV que contiene
El proyecto usa Googletest para las pruebas. En Oder para ejecutar esas pruebas, simplemente ejecute el siguiente comando en el directorio de compilación:
ctest
Para el conjunto de pruebas de Python, ejecute el siguiente comando en la carpeta raíz del repositorio:
pytest
Nos complace aceptar contribuciones al proyecto en forma de sugerencias, informes de errores y solicitudes de extracción. Eche un vistazo a las pautas contribuyentes para obtener más información.