This directory provides a C++ interface to the goSPL extensions (EnhancedModel and DataDrivenTectonics) through Python C API bindings.
The C++ interface allows external C++ simulation codes to:
- Create and manage EnhancedModel instances
- Run goSPL simulations with granular time control
- Apply time-dependent velocity data using DataDrivenTectonics
- Monitor simulation progress and control execution
gospl_extensions.h- C++ header defining the interfacegospl_extensions.cpp- C++ implementation using Python C APIgospl_python_interface.py- Python bridge module
enhanced_model_driver.cpp- Basic C++ driver (equivalent to enhanced_model_basic.py)enhanced_model_advanced_driver.cpp- Advanced C++ driver with elevation tracking (equivalent to enhanced_model_advanced.py)test_interface.cpp- Simple test program for the interface
Makefile- Build system for compiling shared library and executablesCMakeLists.txt- CMake build configuration (alternative)
-
goSPL Environment: Activate the gospl conda environment
conda activate gospl
-
Build Tools: Ensure you have a C++ compiler and Python development headers
# On Ubuntu/Debian: sudo apt install build-essential python3-dev python3-numpy # On CentOS/RHEL: sudo yum install gcc-c++ python3-devel python3-numpy
-
goSPL Extensions: Ensure the parent gospl_extensions package is working
cd .. python -c "from gospl_model_ext import EnhancedModel; print('✅ Extensions working')"
# Build everything (shared library + executables)
make
# Install locally for external C++ project integration
make install-local
# Run basic interface tests
make test
# Run with actual goSPL simulation (requires config file)
make test-gospl
# Run advanced simulation with elevation tracking
make test-gospl-advanced
# Clean build artifacts
make clean
# Show build configuration
make debug-infoThe install-local target creates a standard library structure for integration with external C++ projects like DynEarthSol:
make install-localThis creates:
../lib/libgospl_extensions.so- Shared library for linking../include/gospl_extensions.h- Header file for inclusion
The external project's build system can then use standard linking:
CXXFLAGS += -I./gospl_extensions/include
LDFLAGS += -L./gospl_extensions/lib -lgospl_extensionsmkdir build
cd build
cmake ..
make# Get Python configuration
PYTHON_INCLUDE=$(python3 -c "import sys; print(f'-I{sys.prefix}/include/python{sys.version_info.major}.{sys.version_info.minor}')")
NUMPY_INCLUDE=$(python3 -c "import numpy; print(f'-I{numpy.get_include()}')")
PYTHON_LIBS=$(python3-config --ldflags)
# Build shared library
g++ -std=c++14 -Wall -fPIC -O3 $PYTHON_INCLUDE $NUMPY_INCLUDE -shared -o libgospl_extensions.so gospl_extensions.cpp $PYTHON_LIBS
# Build driver
g++ -std=c++14 -Wall -O3 $PYTHON_INCLUDE $NUMPY_INCLUDE -o enhanced_model_driver enhanced_model_driver.cpp -L. -lgospl_extensions $PYTHON_LIBS# Test the interface without goSPL simulation
./test_interfaceThis tests:
- Python interpreter initialization
- Function loading
- Velocity field generation
- Basic error handling
# Ensure you have a goSPL config file
ls ../examples/input-escarpment.yml
# Run the full C++ driver
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./enhanced_model_driver ../examples/input-escarpment.ymlThis runs the complete C++ equivalent of enhanced_model_basic.py:
- Creates EnhancedModel instance
- Demonstrates all three new methods (
runProcessesForDt,runProcessesForSteps,runProcessesUntilTime) - Runs controlled simulation with time-dependent tectonics
- Shows real landscape evolution physics
# Build and run advanced driver
make advanced-driver
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./enhanced_model_advanced_driver ../examples/input-escarpment.ymlThis runs the complete C++ equivalent of enhanced_model_advanced.py:
- Creates EnhancedModel with elevation interpolation capabilities
- Tracks elevation changes at velocity sampling points
- Updates velocity coordinates based on evolving topography
- Provides detailed before/after elevation analysis
- Demonstrates sophisticated coupling between tectonics and topography
#include "gospl_extensions.h"
int main() {
// Initialize
if (initialize_gospl_extensions() != 0) {
return 1;
}
// Create model
ModelHandle model = create_enhanced_model("config.yml");
if (model < 0) {
finalize_gospl_extensions();
return 1;
}
// Run simulation
double elapsed = run_processes_for_dt(model, 1.0, 1); // dt=1.0, verbose=true
// Apply velocity data
double coords[300], velocities[300]; // 100 points * 3 components
create_velocity_field(0.0, 5.0, 5.0, 0.1, coords, velocities);
apply_velocity_data(model, coords, velocities, 100, 1.0, 3, 1.0);
// Cleanup
destroy_model(model);
finalize_gospl_extensions();
return 0;
}int initialize_gospl_extensions()- Initialize Python and load extensionsvoid finalize_gospl_extensions()- Clean up Python interpreter
ModelHandle create_enhanced_model(const char* config_path)- Create model instanceint destroy_model(ModelHandle handle)- Destroy model instance
double run_processes_for_dt(ModelHandle, double dt, int verbose)- Run for specific dtint run_processes_for_steps(ModelHandle, int num_steps, double dt, int verbose)- Run multiple stepsint run_processes_until_time(ModelHandle, double target_time, double dt, int verbose)- Run until time
int apply_velocity_data(ModelHandle, const double* coords, const double* velocities, int num_points, double timer, int k, double power)- Apply external velocitiesint interpolate_elevation_to_points(ModelHandle, const double* coords, int num_points, double* elevations, int k, double power)- Interpolate elevation field to external pointsint create_velocity_field(double t, double center_x, double center_y, double amplitude, double* coords, double* velocities)- Generate test velocity field
double get_current_time(ModelHandle)- Get current simulation timedouble get_time_step(ModelHandle)- Get model time step
The C++ interface is specifically designed to integrate with DynEarthSol, a finite element geodynamic modeling code. This allows for two-way coupling between geodynamic processes (DynEarthSol) and landscape evolution processes (GoSPL).
-
DynEarthSol handles:
- Tectonic deformation and stress evolution
- Temperature and fluid flow
- Rock rheology and material properties
- Mesh adaptation and remeshing
-
GoSPL handles:
- Surface erosion and sedimentation
- Hillslope diffusion
- River incision and transport
- Marine processes
-
Coupling mechanism:
- DynEarthSol provides surface velocities to GoSPL
- GoSPL evolves surface topography over each timestep
- Updated elevations are returned to DynEarthSol
- Process repeats for each simulation timestep
-
Clone gospl_extensions in DynEarthSol directory:
cd /path/to/DynEarthSol git clone https://github.com/GeoFLAC/gospl_extensions.git -
Build gospl_extensions for local integration:
conda activate gospl # Activate gospl environment cd gospl_extensions/cpp_interface make install-local cd ../..
-
Configure DynEarthSol build:
# In DynEarthSol Makefile, set: use_gospl = 1
-
Build DynEarthSol:
conda deactivate # Use system compiler for DynEarthSol make -
Configure simulation:
# In DynEarthSol config file: control.surface_process_option = 11 control.surface_process_gospl_config_file = "gospl_config.yml"
DynEarthSol/
├── Makefile # use_gospl = 1
├── gospl_extensions/ # Cloned repository
│ ├── lib/
│ │ └── libgospl_extensions.so # Built by make install-local
│ ├── include/
│ │ └── gospl_extensions.h # Built by make install-local
│ └── cpp_interface/
│ ├── Makefile # Contains install-local target
│ └── ...
├── gospl_driver/ # DynEarthSol GoSPL integration code
│ ├── gospl-driver.hpp
│ ├── gospl-driver.cxx
│ └── examples/
│ └── gospl_config_example.yml
└── dynearthsol3d # Built executable with GoSPL support
When properly configured, DynEarthSol will:
- Initialize GoSPL at startup using the specified config file
- At each timestep, extract surface node coordinates and velocities
- Pass this data to GoSPL for landscape evolution
- Receive updated surface elevations from GoSPL
- Update the DynEarthSol mesh with new surface topography
The integration is seamless and controlled by the surface_process_option = 11 setting.
-
Python headers not found:
# Install development headers sudo apt install python3-dev # Or check Python installation python3-config --includes
-
NumPy headers not found:
# Check NumPy installation python3 -c "import numpy; print(numpy.get_include())"
-
Library linking errors:
# Set library path export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH # Or install system-wide sudo make install
-
Python import errors:
# Ensure gospl environment is activated conda activate gospl # Check extensions work python3 -c "from gospl_model_ext import EnhancedModel"
-
Config file errors:
# Use absolute path to config file ./enhanced_model_driver /full/path/to/input-escarpment.yml -
Memory or stability issues:
- Make sure to call
destroy_model()for each created model - Call
finalize_gospl_extensions()at program exit - Check for Python exceptions in console output
- Make sure to call
The C++ interface adds minimal overhead:
- Function calls go through Python C API (microsecond latency)
- Actual simulation runs at full goSPL speed
- Memory is managed by Python/NumPy (efficient)
- No data copying for large arrays (numpy views)
For high-performance applications:
- Batch multiple time steps when possible
- Minimize create/destroy model cycles
- Use larger time steps (dt) when appropriate
- Consider keeping the interface initialized for the application lifetime
See enhanced_model_driver.cpp for a complete example that demonstrates:
- Model initialization and cleanup
- All three time-stepping methods
- Time-dependent velocity field application
- Error handling and progress monitoring
- Integration with DataDrivenTectonics
The C++ driver produces equivalent results to enhanced_model_basic.py but can be integrated into larger C++ simulation frameworks.