# CP2K-RS Extended Interface
This directory contains custom extensions to the CP2K C API that provide additional functionality beyond the standard `libcp2k.h` interface.
## Overview
The standard `libcp2k.h` provides approximately 25 basic functions for interacting with CP2K. While these cover fundamental operations (force environments, energy/force calculations), they represent less than 1% of CP2K's capabilities.
This extensions directory provides a framework for exposing additional CP2K functionality to Rust in a maintainable way.
## Directory Structure
```
extensions/
├── README.md # This file
├── fortran/ # Fortran wrapper modules
│ ├── libcp2k_extended.F90 # Quickstep/DFT internals
│ ├── libcp2k_mpi.F90 # MPI-aware init/finalize wrappers
│ └── stress_tensor_wrapper.F90 # Legacy stress/virial wrapper (not built)
├── include/ # C header files
│ └── libcp2k_extended.h
└── patches/ # Git patches for CP2K (if needed)
```
## Current Extensions
### Implemented
1. **MPI-aware initialization** (`libcp2k_mpi.F90`)
- `cp2k_init_with_mpi_check()`
- `cp2k_finalize_with_mpi_check()`
2. **Extended Quickstep/DFT access** (`libcp2k_extended.F90`)
- Stress and virial tensors
- Eigenvalues, occupations, HOMO/LUMO
- MO coefficient matrix + dimensions
- Electron density grid + metadata
- Electron count, Fermi energy, total spin
- K-point counts and eigenvalues
- Atomic charges and dipole moment (exposed; see implementation notes in `libcp2k_extended.F90`)
3. **Legacy stress wrapper** (`stress_tensor_wrapper.F90`)
- Kept for reference; the build currently compiles `libcp2k_extended.F90` instead.
### Planned / future extensions
- Basis set metadata queries
- Restart file save/load helpers
- Position constraints
## How Extensions Work
### Architecture
```
┌─────────────────────────────────────┐
│ CP2K Fortran Core │
│ (thousands of subroutines) │
└──────────────┬──────────────────────┘
│
↓
┌──────────────┴──────────────────────┐
│ f77_interface.F │
│ (internal Fortran API) │
└──────────────┬──────────────────────┘
│
↓
┌──────────────┴──────────────────────┐
│ libcp2k.F (standard) │
│ + stress_tensor_wrapper.F90 │ ← Our extensions
│ + [other wrappers] │
└──────────────┬──────────────────────┘
│
↓ ISO_C_BINDING
┌──────────────┴──────────────────────┐
│ libcp2k.h (standard) │
│ + libcp2k_extended.h │ ← Our headers
└──────────────┬──────────────────────┘
│
↓
┌──────────────┴──────────────────────┐
│ Rust FFI (bindgen) │
│ + Safe Rust wrappers │
└─────────────────────────────────────┘
```
### Implementation Process
To add a new extension:
1. **Study CP2K internals** - Find the relevant Fortran subroutines
2. **Create Fortran wrapper** - Use `ISO_C_BINDING` to expose functionality
3. **Add C declaration** - Update `libcp2k_extended.h`
4. **Update build system** - Modify `build.rs` to compile the extension
5. **Create Rust FFI** - Add unsafe extern declarations
6. **Add safe wrapper** - Wrap in safe Rust API
7. **Write tests** - Test with real CP2K calculations
8. **Document** - Add examples and API docs
## Building with Extensions
### Prerequisites
- Fortran compiler (gfortran or ifort)
- CP2K source code (the build system clones this automatically)
- All standard CP2K dependencies
### Build Commands
```bash
# Build with extensions (requires building CP2K)
CP2K_RS_BUILD_CP2K=1 cargo build --release --features build-cp2k
# Or use the build script
../../../scripts/build_with_cp2k.sh
```
### Development Build
For faster iteration during development:
```bash
# Header-only mode (no actual CP2K library)
cargo build --release
```
This compiles the Rust code and FFI layer without building CP2K itself.
## Example: Stress Tensor Usage
### Fortran Wrapper (stress_tensor_wrapper.F90)
```fortran
SUBROUTINE cp2k_get_stress_tensor(env_id, stress) BIND(C)
USE ISO_C_BINDING
USE f77_interface
INTEGER(C_INT), VALUE :: env_id
REAL(C_DOUBLE), DIMENSION(3,3), INTENT(OUT) :: stress
! Implementation details...
END SUBROUTINE
```
### C Header (libcp2k_extended.h)
```c
void cp2k_get_stress_tensor(int env_id, double stress[3][3]);
```
### Rust Usage
```rust
use cp2k_rs::ForceEnv;
let mut force_env = ForceEnv::new("input.inp", "output.out")?;
force_env.calc_energy_force()?;
// Get stress tensor (with extension)
let stress = force_env.get_stress_tensor()?;
println!("Stress tensor (GPa):\n{}", stress);
// Calculate pressure
let pressure = (stress[[0,0]] + stress[[1,1]] + stress[[2,2]]) / 3.0;
println!("Pressure: {} GPa", pressure);
```
## Testing Extensions
### Integration Test Example
```rust
#[test]
#[cfg(feature = "build-cp2k")]
fn test_stress_tensor() {
use cp2k_rs::{init, finalize, ForceEnv};
init().unwrap();
let mut force_env = ForceEnv::new(
"tests/data/stress_test.inp",
"stress_test.out"
).unwrap();
force_env.calc_energy_force().unwrap();
let stress = force_env.get_stress_tensor().unwrap();
// Stress tensor should be symmetric
assert!((stress[[0,1]] - stress[[1,0]]).abs() < 1e-6);
assert!((stress[[0,2]] - stress[[2,0]]).abs() < 1e-6);
assert!((stress[[1,2]] - stress[[2,1]]).abs() < 1e-6);
finalize().unwrap();
}
```
## Troubleshooting
### Build Errors
**Problem**: Fortran compilation fails
```
error: undefined reference to 'some_cp2k_function'
```
**Solution**: Ensure you're building with CP2K source:
```bash
CP2K_RS_BUILD_CP2K=1 cargo build --features build-cp2k
```
### Runtime Errors
**Problem**: Function returns zero values
```rust
let stress = force_env.get_stress_tensor()?; // All zeros
```
**Solution**: Ensure energy/force calculation was done first:
```rust
force_env.calc_energy_force()?; // Must call this first
let stress = force_env.get_stress_tensor()?;
```
### Include Path Issues
**Problem**: Can't find CP2K headers during compilation
**Solution**: The build system automatically configures include paths. If issues persist, check that `CP2K_SRC_DIR` environment variable points to CP2K source.
## Resources
- [CP2K Source Code](https://github.com/cp2k/cp2k)
- [CP2K Developer Documentation](https://www.cp2k.org/dev:index)
- [ISO_C_BINDING Tutorial](https://gcc.gnu.org/onlinedocs/gfortran/ISO_005fC_005fBINDING.html)
- [Rust FFI Nomicon](https://doc.rust-lang.org/nomicon/ffi.html)
## License
This code is licensed under GPL-2.0-or-later, consistent with CP2K's license.
## Support
For questions or issues with extensions:
1. Check the main project README
2. Open an issue on the project repository
3. For CP2K-specific questions, consult the [CP2K mailing list](https://groups.google.com/g/cp2k)