Skip to content

RESTGroup/dftd4-rs

Repository files navigation

dftd4 FFI bindings

This project contains dftd4 FFI bindings, wrapper and build-from-source.

Current binding of dftd4: v4.1.0

Source code of dftd4 is available on github.

This crate is not official bindgen project. It is originally intended to potentially serve rust electronic structure toolkit REST.

Crate dftd4

This crate contains dftd4 FFI bindings and wrapper.

Resources Badges
Crate Crate
API Document API Documentation
FFI Binding v4.1.0

Example: B97m with D4

For example, full code for computing B97m dispersion energy with D4:

use dftd4::prelude::*;

// atom indices
let numbers = vec![1, 6, 6, 6, 6, 6, 6, 1, 1, 1, 1, 1, 35, 6, 9, 9, 9];
// geometry in angstrom
#[rustfmt::skip]
let positions = vec![
    0.002144194,   0.361043475,   0.029799709,
    0.015020592,   0.274789738,   1.107648016,
    1.227632658,   0.296655040,   1.794629427,
    1.243958826,   0.183702791,   3.183703934,
    0.047958213,   0.048915002,   3.886484583,
   -1.165135654,   0.026954348,   3.200213281,
   -1.181832083,   0.139828643,   1.810376587,
    2.155807907,   0.399177037,   1.249441585,
    2.184979344,   0.198598553,   3.716170761,
    0.060934662,  -0.040672756,   4.964014252,
   -2.093220602,  -0.078628959,   3.745125056,
   -2.122845437,   0.123257119,   1.277645797,
   -0.268325907,  -3.194209024,   1.994458950,
    0.049999933,  -5.089197474,   1.929391171,
    0.078949601,  -5.512441335,   0.671851563,
    1.211983937,  -5.383996300,   2.498664281,
   -0.909987405,  -5.743747328,   2.570721738,
];
// convert angstrom to bohr
let positions = positions.iter().map(|&x| x / 0.52917721067).collect::<Vec<f64>>();
// generate DFTD4 model
let model = DFTD4Model::new(&numbers, &positions, None, None, None);
// retrive the DFTD4 parameters
let param = DFTD4Param::load_rational_damping("b97m", true);
// obtain the dispersion energy and gradient, without sigma
let (energy, gradient, _) = model.get_dispersion(&param, true).into();
let gradient = gradient.unwrap();

println!("Dispersion energy: {}", energy);
let energy_ref = -0.025765015532807658;
assert!((energy - energy_ref).abs() < 1e-9);
println!("Dispersion gradient:");
gradient.chunks(3).for_each(|chunk| println!("{:16.9?}", chunk));

Example: Custom parameters by toml

use dftd4::prelude::*;

// Use custom parameters by toml string
// Note: version = "d4", "d4bj", "bj", or "atm" all resolve to bj-eeq-atm (the default)
// The version field is optional — omitting it also defaults to bj-eeq-atm.
let input = r#"{version = "d4bj", a1 = 0.40868035, s8 = 2.02929367, a2 = 4.53807137, atm = false}"#;
// You can also use the following input to specify B3LYP-D4 parameters
// let input = r#"{version = "d4bj", method = "b3lyp"}"#;
// Or simply omit version (defaults to bj-eeq-atm):
// let input = r#"{method = "b3lyp"}"#;
// toml parameter type
let damping_param = dftd4_parse_damping_param_from_toml(input);
// FFI parameter type
let dftd4_param = damping_param.new_param();

let atom_numbers = vec![8, 1, 1];
// coordinates in bohr
#[rustfmt::skip]
let coordinates = vec![
    0.000000, 0.000000, 0.000000,
    0.000000, 0.000000, 1.807355,
    1.807355, 0.000000, -0.452500,
];
let model = DFTD4Model::new(&atom_numbers, &coordinates, None, None, None);
let res = model.get_dispersion(&dftd4_param, false);
let eng = res.energy;
println!("Dispersion energy: {eng}");

Cargo features of dftd4

Default cargo features of dftd4 are:

  • api-v4_0: Corresponding to the original dftd4 v4.0. This will enable rational damping (BJ), custom D4 model, pairwise dispersion, properties, and numerical hessian. D4S model also included in api-v4_0.
  • dynamic_loading: This will enable dynamic loading of libdftd4 library, which can be more flexible for users who do not want to perform static linking. Please place libdftd4.so in LD_LIBRARY_PATH (for macos, place libdftd4.dylib in DYLD_LIBRARY_PATH), or make dftd4 available in your python environment, and function symbols will be loaded at runtime.

Other cargo features of dftd4 are:

  • api-v3_0 through api-v4_0: Versioned API features (cumulative). Each version enables all functions introduced in that version. Note: dynamic loading ignores API version features — all functions are available at runtime.
  • api-v4_0: Enables D4S dispersion model support.

Installation guide and Crate dftd4-src

This crate is only useful for static loading: If you enabled cargo feature dynamic_loading (which is enabled by default), you just need to place libdftd4.so in LD_LIBRARY_PATH, or make dftd4 available in your python environment. The library will be loaded at runtime, so you do not need to perform any static loading.

If you need to link dftd4 library by static loading (either static linking by libdftd4.a or dynamic linking by libdftd4.so), proceed to the following instructions.

Resources Badges
Crate Crate

To use crate dftd4 in rust, you may need to perform some configuration to properly link libdftd4.so into your own program.

Install dftd4

Please refer to original github repository for more instructions.

The easiest way is install from conda/mamba, and you can retrive the shared/static library therein.

Manually link dftd4 into your project

Similar to other projects, after library search path properly defined

println!("cargo:rustc-link-search=native={}", path);

you may link dftd4 and mctc-lib, multicharge by cargo instructions in your own project:

// following code is for static linking
println!("cargo:rustc-link-lib=static=dftd4");
println!("cargo:rustc-link-lib=static=mctc-lib");
println!("cargo:rustc-link-lib=static=multicharge");
// following code is for dynamic linking
println!("cargo:rustc-link-lib=dftd4");
println!("cargo:rustc-link-lib=mctc-lib");
println!("cargo:rustc-link-lib=multicharge");

It should be noted that, for static linking, you may also need to dynamic link Fortran, OpenMP, BLAS, LAPACK libraries (for the library installed by conda or mamba, it is usually gfortran and gomp, blas, lapack).

Link dftd4 by crate dftd4-src

You can also link dftd4 by crate dftd4-src.

First, in your own project's lib.rs or main.rs, you need to add a line for explicitly importing this library:

extern crate dftd4_src;

If you have compiled dftd4 library, make sure path of it (together with mctc-lib) is either in

  • DFTD4_DIR
  • REST_EXT_DIR
  • LD_LIBRARY_PATH
  • or in other common system library paths.

If you have not compiled dftd4 library, you may try out cargo feature build_from_source, but that can also cause trobule when distributing your program binary, so use with caution.

Cargo features of dftd4-src

  • build_from_source: This will use CMake and meson, and pull code from github to first perform build for dftd4. Though this option can be developer-friendly (you do not need to perform any other configurations to make program compile and run by cargo), build_from_source does not provide customized compilation.

    CMake configurable variables (can be defined as environment variables):

    • DFTD4_SRC: git repository source directory or URL;
    • DFTD4_VER: version of DFT-D4 (default v4.1.0);
  • static: This will link static libary instead of dynamic one. Please note that 1. static linking may require additional Fortran and OpenMP linking, which is not provided in this crate; 2. staticly linking LGPL-3.0 license may require your project to be GPL-3.0.

License

This repository is licensed under LGPL-3.0, the same to dftd4.

Some parts of this project is derivative work of original library dftd4, and contains some source code (headers, toml parameters) and AI-translated/generated code.

About

dftd4 FFI bindings, wrapper and build-from-source

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors