Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief Interface to the DeePMD-kit or a c++ wrapper.
10 : !> \par History
11 : !> 07.2019 created [Yongbin Zhuang]
12 : !> 06.2021 refactored [Yunpei Liu]
13 : !> 10.2023 adapt to DeePMD-kit C Interface [Yunpei Liu]
14 : !> \author Yongbin Zhuang
15 : ! **************************************************************************************************
16 :
17 : MODULE deepmd_wrapper
18 : USE ISO_C_BINDING, ONLY: C_ASSOCIATED,&
19 : C_CHAR,&
20 : C_DOUBLE,&
21 : C_F_POINTER,&
22 : C_INT,&
23 : C_NULL_CHAR,&
24 : C_NULL_PTR,&
25 : C_PTR
26 : USE kinds, ONLY: default_string_length,&
27 : dp
28 : #include "./base/base_uses.f90"
29 :
30 : IMPLICIT NONE
31 : PRIVATE
32 : PUBLIC :: deepmd_model_type, deepmd_model_load, deepmd_model_compute, deepmd_model_release
33 :
34 : TYPE deepmd_model_type
35 : PRIVATE
36 : TYPE(C_PTR) :: c_ptr = C_NULL_PTR
37 : END TYPE deepmd_model_type
38 :
39 : CONTAINS
40 :
41 : ! **************************************************************************************************
42 : !> \brief Load DP from a model file.
43 : !> \param filename Path to the model file.
44 : !> \return Pointer to the DP model.
45 : ! **************************************************************************************************
46 2 : FUNCTION deepmd_model_load(filename) RESULT(model)
47 : CHARACTER(len=*), INTENT(IN) :: filename
48 : TYPE(deepmd_model_type) :: model
49 :
50 : CHARACTER(LEN=*), PARAMETER :: routineN = 'deepmd_model_load'
51 :
52 : CHARACTER(LEN=1, KIND=C_CHAR), DIMENSION(:), &
53 2 : POINTER :: error_f_ptr
54 : CHARACTER(LEN=default_string_length) :: error_str
55 : INTEGER :: handle, i
56 : TYPE(C_PTR) :: error_c_ptr
57 : INTERFACE
58 : FUNCTION NewDeepPot(filename) BIND(C, name="DP_NewDeepPot")
59 : IMPORT :: C_PTR, C_CHAR
60 : CHARACTER(kind=C_CHAR), DIMENSION(*) :: filename
61 : TYPE(C_PTR) :: NewDeepPot
62 : END FUNCTION
63 : END INTERFACE
64 : INTERFACE
65 : FUNCTION DeepPotCheckOK(model) BIND(C, name="DP_DeepPotCheckOK")
66 : IMPORT :: C_PTR
67 : TYPE(C_PTR), VALUE :: model
68 : TYPE(C_PTR) :: DeepPotCheckOK
69 : END FUNCTION DeepPotCheckOK
70 : END INTERFACE
71 : INTERFACE
72 : SUBROUTINE DeleteChar(ptr) BIND(C, name="DP_DeleteChar")
73 : IMPORT :: C_PTR
74 : TYPE(C_PTR), VALUE :: ptr
75 : END SUBROUTINE DeleteChar
76 : END INTERFACE
77 :
78 2 : CALL timeset(routineN, handle)
79 :
80 : #if defined(__DEEPMD)
81 : CPASSERT(.NOT. C_ASSOCIATED(model%c_ptr))
82 2 : model%c_ptr = NewDeepPot(filename=TRIM(filename)//C_NULL_CHAR)
83 2 : CPASSERT(C_ASSOCIATED(model%c_ptr))
84 :
85 : ! Check for errors.
86 2 : error_c_ptr = DeepPotCheckOK(model%c_ptr)
87 2 : CPASSERT(C_ASSOCIATED(error_c_ptr))
88 4 : CALL C_F_POINTER(error_c_ptr, error_f_ptr, shape=(/default_string_length/))
89 2 : error_str = ""
90 2 : DO i = 1, default_string_length
91 2 : IF (error_f_ptr(i) == C_NULL_CHAR) EXIT
92 2 : error_str(i:i) = error_f_ptr(i)
93 : END DO
94 2 : CALL DeleteChar(error_c_ptr)
95 2 : IF (LEN_TRIM(error_str) > 0) CPABORT(TRIM(error_str))
96 : #else
97 : CPABORT("CP2K was compiled without libdeepmd_c library.")
98 : MARK_USED(filename)
99 : MARK_USED(model)
100 : MARK_USED(i)
101 : MARK_USED(error_str)
102 : MARK_USED(error_c_ptr)
103 : MARK_USED(error_f_ptr)
104 : #endif
105 :
106 2 : CALL timestop(handle)
107 2 : END FUNCTION deepmd_model_load
108 :
109 : ! **************************************************************************************************
110 : !> \brief Compute energy, force and virial from DP.
111 : !> \param model Pointer to the DP model.
112 : !> \param natom Number of atoms.
113 : !> \param coord Coordinates of the atoms.
114 : !> \param atype Atom types.
115 : !> \param cell Cell vectors.
116 : !> \param energy Potential energy.
117 : !> \param force Forces.
118 : !> \param virial Virial tensor.
119 : !> \param atomic_energy Atomic energies.
120 : !> \param atomic_virial Atomic virial tensors.
121 : ! **************************************************************************************************
122 2 : SUBROUTINE deepmd_model_compute(model, natom, coord, atype, cell, energy, force, virial, &
123 2 : atomic_energy, atomic_virial)
124 : TYPE(deepmd_model_type) :: model
125 : INTEGER :: natom
126 : REAL(kind=dp), DIMENSION(natom, 3), INTENT(IN) :: coord
127 : INTEGER, DIMENSION(natom), INTENT(IN) :: atype
128 : REAL(kind=dp), DIMENSION(9), INTENT(IN) :: cell
129 : REAL(kind=dp), INTENT(OUT) :: energy
130 : REAL(kind=dp), DIMENSION(natom, 3), INTENT(OUT) :: force
131 : REAL(kind=dp), DIMENSION(9), INTENT(OUT) :: virial
132 : REAL(kind=dp), DIMENSION(natom), INTENT(OUT) :: atomic_energy
133 : REAL(kind=dp), DIMENSION(natom, 9), INTENT(OUT) :: atomic_virial
134 :
135 : CHARACTER(LEN=*), PARAMETER :: routineN = 'deepmd_model_compute'
136 :
137 : INTEGER :: handle
138 : INTERFACE
139 : SUBROUTINE DeepPotCompute(model, natom, coord, atype, cell, energy, force, virial, &
140 : atomic_energy, atomic_virial) BIND(C, name="DP_DeepPotCompute")
141 : IMPORT :: C_PTR, C_INT, C_DOUBLE
142 : TYPE(C_PTR), VALUE :: model
143 : INTEGER(C_INT), VALUE :: natom
144 : REAL(C_DOUBLE), DIMENSION(natom, 3) :: coord
145 : INTEGER(C_INT), DIMENSION(natom) :: atype
146 : REAL(C_DOUBLE), DIMENSION(9) :: cell
147 : REAL(C_DOUBLE) :: energy
148 : REAL(C_DOUBLE), DIMENSION(natom, 3) :: force
149 : REAL(C_DOUBLE), DIMENSION(9) :: virial
150 : REAL(C_DOUBLE), DIMENSION(natom) :: atomic_energy
151 : REAL(C_DOUBLE), DIMENSION(natom, 9) :: atomic_virial
152 : END SUBROUTINE
153 : END INTERFACE
154 :
155 2 : CALL timeset(routineN, handle)
156 :
157 : #if defined(__DEEPMD)
158 2 : CPASSERT(C_ASSOCIATED(model%c_ptr))
159 : CALL DeepPotCompute(model=model%c_ptr, &
160 : natom=natom, &
161 : coord=coord, &
162 : atype=atype, &
163 : cell=cell, &
164 : energy=energy, &
165 : force=force, &
166 : virial=virial, &
167 : atomic_energy=atomic_energy, &
168 2 : atomic_virial=atomic_virial)
169 : #else
170 : CPABORT("CP2K was compiled without libdeepmd_c library.")
171 : MARK_USED(model)
172 : MARK_USED(natom)
173 : MARK_USED(coord)
174 : MARK_USED(atype)
175 : MARK_USED(cell)
176 : energy = 0.0_dp
177 : force = 0.0_dp
178 : virial = 0.0_dp
179 : atomic_energy = 0.0_dp
180 : atomic_virial = 0.0_dp
181 : #endif
182 :
183 2 : CALL timestop(handle)
184 2 : END SUBROUTINE
185 :
186 : ! **************************************************************************************************
187 : !> \brief Releases a deepmd model and all its ressources.
188 : !> \param model Pointer to the DP model.
189 : ! **************************************************************************************************
190 2 : SUBROUTINE deepmd_model_release(model)
191 : TYPE(deepmd_model_type) :: model
192 :
193 : CHARACTER(LEN=*), PARAMETER :: routineN = 'deepmd_model_release'
194 :
195 : INTEGER :: handle
196 : INTERFACE
197 : SUBROUTINE DeleteDeepPot(model) BIND(C, name="DP_DeleteDeepPot")
198 : IMPORT :: C_PTR
199 : TYPE(C_PTR), VALUE :: model
200 : END SUBROUTINE DeleteDeepPot
201 : END INTERFACE
202 :
203 2 : CALL timeset(routineN, handle)
204 :
205 : #if defined(__DEEPMD)
206 2 : CPASSERT(C_ASSOCIATED(model%c_ptr))
207 2 : CALL DeleteDeepPot(model%c_ptr)
208 2 : model%c_ptr = C_NULL_PTR
209 : #else
210 : CPABORT("CP2K was compiled without libdeepmd_c library.")
211 : MARK_USED(model)
212 : #endif
213 :
214 2 : CALL timestop(handle)
215 2 : END SUBROUTINE deepmd_model_release
216 :
217 0 : END MODULE deepmd_wrapper
|