8000 Implementation of the ddX continuum solvation library by robin-dahl · Pull Request #235 · tblite/tblite · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Implementation of the ddX continuum solvation library #235

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails 10000 .

Already on GitHub? Sign in to your account

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,17 @@ endif()
if(NOT TARGET "s-dftd3::s-dftd3")
find_package("s-dftd3" REQUIRED)
endif()

set(EXAMPLES OFF CACHE BOOL "Disable ddx examples" FORCE)
if(NOT TARGET "ddx::ddx")
find_package("ddx" REQUIRED)
endif()

set(
lib-deps
"OpenMP::OpenMP_Fortran"
"LAPACK::LAPACK"
"$<$<VERSION_LESS:${CMAKE_VERSION},3.20>:BLAS::BLAS>"
"ddx::ddx"
"toml-f::toml-f"
"mctc-lib::mctc-lib"
"dftd4::dftd4"
Expand Down Expand Up @@ -106,6 +111,18 @@ if(NOT EXISTS "${PROJECT_BINARY_DIR}/include")
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/include")
endif()

add_library(ddx_includes INTERFACE)
install(TARGETS ddx_includes EXPORT "${PROJECT_NAME}-targets")
target_include_directories(ddx_includes
INTERFACE
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/_deps/ddx-build/src>
$<INSTALL_INTERFACE:include/ddx>
)
install(DIRECTORY "${CMAKE_BINARY_DIR}/_deps/ddx-build/src/"
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ddx
FILES_MATCHING PATTERN "*.mod")
target_link_libraries("${PROJECT_NAME}-lib" PUBLIC ddx_includes)

# Add example application
add_subdirectory("app")

Expand Down
39 changes: 32 additions & 7 deletions app/cli.f90
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ module tblite_cli
& help_text_fit, help_text_tagdiff, help_text_guess
use tblite_features, only : get_tblite_feature
use tblite_lapack_solver, only : lapack_algorithm
use tblite_solvation, only : solvation_input, cpcm_input, alpb_input, &
& cds_input, shift_input, solvent_data, get_solvent_data, solution_state, born_kernel
use tblite_solvation, only : solvation_input, ddx_input, alpb_input, &
& cds_input, shift_input, solvent_data, get_solvent_data, solution_state, born_kernel, &
& ddx_solvation_model
use tblite_version, only : get_tblite_version
implicit none
private
Expand Down Expand Up @@ -250,7 +251,9 @@ subroutine get_run_arguments(config, list, start, error)
character(len=:), allocatable :: arg
logical :: solvent_not_found, parametrized_solvation
logical, allocatable :: alpb
integer :: ddx_model
integer, allocatable :: kernel, sol_state
real(wp) :: kappa = 0.0_wp
type(solvent_data), allocatable :: solvent

iarg = start
Expand Down Expand Up @@ -375,18 +378,30 @@ subroutine get_run_arguments(config, list, start, error)
exit
end select

case("--cpcm")
case("--cosmo", "--cpcm", "--pcm", "--lpb")
if (allocated(solvent)) then
call fatal_error(error, "Cannot use multiple solvation models")
exit
end if
if (arg == "--cosmo") then
ddx_model = ddx_solvation_model%cosmo
else if (arg == "--cpcm") then
ddx_model = ddx_solvation_model%cpcm
else if (arg == "--pcm") then
ddx_model = ddx_solvation_model%pcm
else if (arg == "--lpb") then
ddx_model = ddx_solvation_model%lpb
else
call fatal_error(error, "Unknown ddX solvation model '"//arg//"' specified")
exit
end if
parametrized_solvation = .false.

! Check for solvent information
iarg = iarg + 1
call list%get(iarg, arg)
if (.not.allocated(arg)) then
call fatal_error(error, "Missing argument for CPCM")
call fatal_error(error, "Missing argument for ddX solvation")
exit
end if
solvent_not_found = .false.
Expand All @@ -398,6 +413,16 @@ subroutine get_run_arguments(config, list, start, error)
end if
if (allocated(error)) exit

case("--kappa")
if (ddx_model /= ddx_solvation_model%lpb) then
call fatal_error(error, "Kappa is only needed for LPB solvation model")
exit
end if
iarg = iarg + 1
call list%get(iarg, arg)
call get_argument_as_real(arg, kappa, error)
if (allocated(error)) exit

case("--gb", "--gbe")
if (allocated(solvent)) then
call fatal_error(error, "Cannot use multiple solvation models")
Expand Down Expand Up @@ -572,13 +597,13 @@ subroutine get_run_arguments(config, list, start, error)
config%solvation%alpb = alpb_input(solvent%eps, kernel=kernel, alpb=alpb)
end if
else
! CPCM solvation model
! ddX solvation model
if (sol_state /= solution_state%gsolv) then
call fatal_error(error, "Solution state shift not supported for CPCM")
call fatal_error(error, "Solution state shift not supported for ddX solvation")
return
end if
allocate(config%solvation)
config%solvation%cpcm = cpcm_input(solvent%eps)
config%solvation%ddx = ddx_input(solvent%eps, ddx_model, kappa=kappa)
end if
end if

Expand Down
9 changes: 8 additions & 1 deletion app/cli_help.f90
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,14 @@ module tblite_cli_help
" Solvent is specified by dielectric constant or the solvent name."//nl//&
" --gb <real>/<name> Use generalized Born solvation model (GB)."//nl//&
" Solvent is specified by dielectric constant or solvent name."//nl//&
" --cpcm <real>/<name> Use polarizable continuum solvation model (CPCM)."//nl//&
" --cosmo <real>/<name> "//nl//&
" Use conductor-like screening solvation model (COSMO)."//nl//&
" Solvent is specified by dielectric constant or solvent name."//nl//&
" --cpcm <real>/<name> Use conductor-like polarizable continuum solvation model (CPCM)."//nl//&
" Solvent is specified by dielectric constant or solvent name."//nl//&
" --pcm <real>/<name> Use polarizable continuum solvation model (PCM)."//nl//&
" Solvent is specified by dielectric constant or solvent name."//nl//&
" --lpb <real>/<name> Use linearized Poisson-Boltzmann solvation model (LPB)."//nl//&
" Solvent is specified by dielectric constant or solvent name."//nl//&
" --born-kernel <name> Specify Born kernel to use with ALPB, GBSA or GB solvation model."//nl//&
" Possible options are p16 (default for ALPB) and still (default for GB/GBSA)."//nl//&
Expand Down
42 changes: 42 additions & 0 deletions config/cmake/Findddx.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# This file is part of tblite.
# SPDX-Identifier: LGPL-3.0-or-later
#
# tblite is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# tblite is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with tblite. If not, see <https://www.gnu.org/licenses/>.

set(_lib "ddx")
set(_pkg "DDX")
set(_url "https://github.com/ddsolvation/ddx")
set(_rev "HEAD")

if(NOT DEFINED "${_pkg}_FIND_METHOD")
if(DEFINED "${PROJECT_NAME}-dependency-method")
set("${_pkg}_FIND_METHOD" "${${PROJECT_NAME}-dependency-method}")
else()
set("${_pkg}_FIND_METHOD" "cmake" "pkgconf" "subproject" "fetch")
endif()
set("_${_pkg}_FIND_METHOD")
endif()

include("${CMAKE_CURRENT_LIST_DIR}/tblite-utils.cmake")

tblite_find_package("${_lib}" "${${_pkg}_FIND_METHOD}" "${_url}" "${_rev}")

if(DEFINED "_${_pkg}_FIND_METHOD")
unset("${_pkg}_FIND_METHOD")
unset("_${_pkg}_FIND_METHOD")
endif()
unset(_lib)
unset(_pkg)
unset(_url)
unset(_rev)
9 changes: 9 additions & 0 deletions config/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,12 @@ tomlf_dep = dependency(
default_options: ['default_library=static'],
)
lib_deps += tomlf_dep

# Create ddX library as subproject
ddx_dep = dependency(
'ddx',
version: '>=0.1.0',
fallback: ['ddx', 'ddx_dep'],
default_options: ['default_library=static'],
)
lib_deps += ddx_dep
4 changes: 4 additions & 0 deletions config/template.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,8 @@ if(NOT TARGET "@PROJECT_NAME@::@PROJECT_NAME@")
if(NOT TARGET "dftd4::dftd4")
find_dependency("dftd4")
endif()

if(NOT TARGET "ddx::ddx")
find_dependency("ddx")
endif()
endif()
19 changes: 15 additions & 4 deletions include/tblite/solvation.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,27 @@ enum tblite_solvation_param{
tblite_solvation_gbsa_gfn2 = 22,
};

/// Create new CPCM implicit solvation container using internal parameters
enum tblite_ddx_solvation_model{
tblite_ddx_solvation_cosmo = 11,
tblite_ddx_solvation_cpcm = 12,
tblite_ddx_solvation_pcm = 2,
tblite_ddx_solvation_lpb = 3
};

/// Create new ddx implicit solvation container using internal parameters
///
/// @param error: Error handle
/// @param mol: Molecular structure data
/// @param eps: epsilon value for solvent
/// @param model: type of solvation model to use (COSMO=11, CPCM=12, PCM=2, LPB=3)
/// @param kappa: dielectric constant of solvent (only used in LPB)
/// @return New interaction container
TBLITE_API_ENTRY tblite_container TBLITE_API_CALL
tblite_new_cpcm_solvation_epsilon(tblite_error error,
tblite_structure mol,
double eps);
tblite_new_ddx_solvation_epsilon(tblite_error error,
tblite_structure mol,
double eps,
int model,
double kappa);

/// Create new ALPB implicit solvation container using internal parameters
///
Expand Down
5 changes: 3 additions & 2 deletions man/tblite-run.1.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ Supported geometry input formats are:
Use generalized Born solvation model (GB).
Solvent is specified by dielectric constant or solvent name.

*--cpcm* _real_|_string_::
Use polarizable continuum solvation model (CPCM).
*--ddx* _real_|_string_::
Use solvation models based on domain decomposition.
Method can either be COSMO (1), CPCM (2), PCM (3), or LPB (4)
Solvent is specified by dielectric constant or solvent name.

*--born-kernel* _string_::
Expand Down
4 changes: 2 additions & 2 deletions python/tblite/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ class Calculator(Structure):
"spin-polarization": library.new_spin_polarization,
"alpb-solvation": library.new_alpb_solvation,
"gbsa-solvation": library.new_gbsa_solvation,
"cpcm-solvation": library.new_cpcm_solvation,
"ddx-solvation": library.new_ddx_solvation,
"gbe-solvation": library.new_gbe_solvation,
"gb-solvation": library.new_gb_solvation,
}
Expand Down Expand Up @@ -553,7 +553,7 @@ def add(self, interaction, *args) -> None:
spin-polarization Spin polarization Scaling factor
alpb-solvation ALPB implicit solvation Solvent name, solution state (optional)
gbsa-solvation GBSA implicit solvation Solvent name, solution state (optional)
cpcm-solvation CPCM implicit solvation Epsilon
ddx-solvation ddX implicit solvation Epsilon, model, kappa (if model=LPB)
gbe-solvation GBε implicit solvation Epsilon, Born kernel
gb-solvation GB implicit solvation Epsilon, Born kernel
=================== =========================== =========================================
Expand Down
2 changes: 1 addition & 1 deletion python/tblite/qcschema.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
electric-field Uniform electric field Field vector
spin-polarization Spin polarization Scaling factor
alpb-solvation ALPB implicit solvation Epsilon or solvent
cpcm-solvation CPCM implicit solvation Epsilon or solvent
ddx-solvation ddX implicit solvation Epsilon or solvent
=================== ==================================== =====================
"""

Expand Down
7 changes: 3 additions & 4 deletions python/tblite/test_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,16 +508,15 @@ def test_post_processing_api():
assert wbo_sp.ndim == 3


def test_solvation_gfn2_cpcm():
"""Test CPCM solvation with GFN2-xTB"""
def test_solvation_gfn2_ddx():
"""Test (ddX) COSMO solvation with GFN2-xTB"""
numbers, positions = get_crcp2()

calc = Calculator("GFN2-xTB", numbers, positions)
calc.set("accuracy", 1.0)
calc.add("cpcm-solvation", 7.0)
calc.add("ddx-solvation", 7.0)

energy = calc.singlepoint().get("energy")

assert energy == approx(-28.43287176929)


Expand Down
19 changes: 11 additions & 8 deletions src/tblite/api/solvation.f90
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,16 @@ module tblite_api_solvation
use tblite_data_spin, only : get_spin_constant
use tblite_external_field, only : electric_field
use tblite_spin, only : spin_polarization, new_spin_polarization
use tblite_solvation, only : solvation_input, cpcm_input, alpb_input, &
use tblite_solvation, only : solvation_input, ddx_input, alpb_input, &
& solvent_data, get_solvent_data, solvation_type, new_solvation, solution_state, &
& new_solvation_cds, new_solvation_shift, cds_input, shift_input, born_kernel
& new_solvation_cds, new_solvation_shift, cds_input, shift_input, born_kernel, &
& ddx_solvation_model
use tblite_api_utils, only: c_f_character
implicit none
private

public :: new_gb_solvation_epsilon_api, new_alpb_solvation_solvent_api, &
& new_cpcm_solvation_epsilon_api
& new_ddx_solvation_epsilon_api

enum, bind(c)
enumerator :: &
Expand All @@ -57,20 +58,22 @@ module tblite_api_solvation
contains


function new_cpcm_solvation_epsilon_api(verr, vmol, eps) result(vcont) &
& bind(C, name=namespace//"new_cpcm_solvation_epsilon")
function new_ddx_solvation_epsilon_api(verr, vmol, eps, model, kappa) result(vcont) &
& bind(C, name=namespace//"new_ddx_solvation_epsilon")
type(c_ptr), value :: verr
type(vp_error), pointer :: err
type(c_ptr), value :: vmol
type(vp_structure), pointer :: mol
real(kind=c_double), value :: eps
integer(c_int), value :: model
real(kind=c_double), value :: kappa
type(c_ptr) :: vcont
type(vp_container), pointer :: cont

type(solvation_input) :: solvmodel
class(solvation_type), allocatable :: solv

if (debug) print '("[Info]", 1x, a)', "new_cpcm_solvation_epsilon"
if (debug) print '("[Info]", 1x, a)', "new_ddx_solvation_epsilon"
vcont = c_null_ptr

if (.not.c_associated(verr)) return
Expand All @@ -82,15 +85,15 @@ function new_cpcm_solvation_epsilon_api(verr, vmol, eps) result(vcont) &
end if
call c_f_pointer(vmol, mol)

solvmodel%cpcm = cpcm_input(eps)
solvmodel%ddx = ddx_input(eps, model, kappa=kappa)
call new_solvation(solv, mol%ptr, solvmodel, err%ptr)
if (allocated(err%ptr)) return

allocate(cont)
call move_alloc(solv, cont%ptr)

vcont = c_loc(cont)
end function new_cpcm_solvation_epsilon_api
end function new_ddx_solvation_epsilon_api

function new_gb_solvation_epsilon_api(verr, vmol, eps, version, born_type) result(vcont) &
& bind(C, name=namespace//"new_gb_solvation_epsilon")
Expand Down
8 changes: 4 additions & 4 deletions src/tblite/solvation.f90
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ module tblite_solvation
use mctc_env, only : error_type, fatal_error
use mctc_io, only : structure_type
use tblite_solvation_alpb, only : alpb_solvation, new_alpb, alpb_input, born_kernel
use tblite_solvation_cpcm, only : cpcm_solvation, new_cpcm, cpcm_input
use tblite_solvation_ddx, only : ddx_solvation, ddx_solvation_model, new_ddx, ddx_input
use tblite_solvation_cds, only : cds_solvation, new_cds, cds_input
use tblite_solvation_shift, only : shift_solvation, new_shift, shift_input, solution_state
use tblite_solvation_data, only : solvent_data, get_solvent_data
Expand All @@ -38,7 +38,7 @@ module tblite_solvation
private

public :: alpb_solvation, new_alpb, alpb_input, born_kernel
public :: cpcm_solvation, new_cpcm, cpcm_input
public :: ddx_solvation, ddx_solvation_model, new_ddx, ddx_input
public :: cds_solvation, new_cds, cds_input
public :: shift_solvation, new_shift, shift_input
public :: solvent_data, get_solvent_data
Expand Down Expand Up @@ -77,8 +77,8 @@ subroutine new_solvation(solv, mol, input, error, method)
return
end if

if (allocated(input%cpcm)) then
solv = cpcm_solvation(mol, input%cpcm)
if (allocated(input%ddx)) then
solv = ddx_solvation(mol, input%ddx)
return
end if

Expand Down
Loading
0