1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
/*----------------------------------------------------------------------------*/
/* CP2K: A general program to perform molecular dynamics simulations */
/* Copyright 2000-2025 CP2K developers group <https://cp2k.org> */
/* */
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*----------------------------------------------------------------------------*/
#include <stdbool.h>
/*******************************************************************************
* \brief Definitions for the functions exported in libcp2k.F
* \author Mohammad Hossein Bani-Hashemian
******************************************************************************/
#ifndef LIBCP2K_H
#define LIBCP2K_H
#ifdef __cplusplus
extern "C" {
#endif
typedef int force_env_t;
/*******************************************************************************
* \brief Get the CP2K version string
* \param version_str The buffer to write the version string into
* \param str_length The size of the buffer (must be large enough)
******************************************************************************/
void cp2k_get_version(char *version_str, int str_length);
/*******************************************************************************
* \brief Initialize CP2K and MPI
* \warning You are supposed to call cp2k_finalize() before exiting the program.
******************************************************************************/
void cp2k_init();
/*******************************************************************************
* \brief Initialize CP2K without initializing MPI
* \warning You are supposed to call cp2k_finalize() before exiting the program.
******************************************************************************/
void cp2k_init_without_mpi();
/*******************************************************************************
* \brief Finalize CP2K and MPI
******************************************************************************/
void cp2k_finalize();
/*******************************************************************************
* \brief Finalize CP2K and without finalizing MPI
******************************************************************************/
void cp2k_finalize_without_mpi();
/*******************************************************************************
* \brief Create a new force environment
* \param new_force_env the created force environment
* \param input_file_path Path to a CP2K input file
* \param output_file_path Path to a file where CP2K is going to append its
* output (created if non-existent)
* \warning You are supposed to call cp2k_destroy_force_env() to cleanup,
* before cp2k_finalize().
******************************************************************************/
void cp2k_create_force_env(force_env_t *new_force_env,
const char *input_file_path,
const char *output_file_path);
/*******************************************************************************
* \brief Create a new force environment (custom managed MPI)
* \param new_force_env the created force environment
* \param input_file_path Path to a CP2K input file
* \param output_file_path Path to a file where CP2K is will write its output.
* Will be created if not existent, otherwise appended.
* \param mpi_comm Fortran MPI communicator if MPI is not managed by CP2K
* \warning You are supposed to call cp2k_destroy_force_env() to cleanup,
* before cp2k_finalize().
******************************************************************************/
void cp2k_create_force_env_comm(force_env_t *new_force_env,
const char *input_file_path,
const char *output_file_path, int mpi_comm);
/*******************************************************************************
* \brief Destroy/cleanup a force environment
* \param force_env the force environment
******************************************************************************/
void cp2k_destroy_force_env(force_env_t force_env);
/*******************************************************************************
* \brief Set positions of the particles
* \param force_env the force environment
* \param new_pos Array containing the new positions of the particles
* \param n_el Size of the new_pos array
******************************************************************************/
void cp2k_set_positions(force_env_t force_env, const double *new_pos, int n_el);
/*******************************************************************************
* \brief Set velocity of the particles
* \param force_env the force environment
* \param new_vel Array containing the new velocities of the particles
* \param n_el Size of the new_vel array
******************************************************************************/
void cp2k_set_velocities(force_env_t force_env, const double *new_vel,
int n_el);
/*******************************************************************************
* \brief Set the size of the cell
* \param force_env the force environment
* \param new_cell Array containing the new cell
******************************************************************************/
void cp2k_set_cell(force_env_t force_env, const double *new_cell);
/*******************************************************************************
* \brief Get an arbitrary result as 1D array from CP2K
* \param force_env the force environment
* \param description The string tag of the result
* \param results Pre-allocated array
* \param n_el size of the results array
******************************************************************************/
void cp2k_get_result(force_env_t force_env, const char *description,
double *result, int n_el);
/*******************************************************************************
* \brief Get the number of atoms
* \param force_env the force environment
* \param natom The number of atoms
******************************************************************************/
void cp2k_get_natom(force_env_t force_env, int *natom);
/*******************************************************************************
* \brief Get the number of particles
* \param force_env the force environment
* \param nparticle The number of particles
******************************************************************************/
void cp2k_get_nparticle(force_env_t force_env, int *nparticle);
/*******************************************************************************
* \brief Get the positions of the particles
* \param force_env the force environment
* \param pos Pre-allocated array of at least 3*nparticle elements.
* Use cp2k_get_nparticle() to get the number of particles.
* \param n_el Size of the force array
******************************************************************************/
void cp2k_get_positions(force_env_t force_env, double *pos, int n_el);
/*******************************************************************************
* \brief Get the forces for the particles
* \param force_env the force environment
* \param force Pre-allocated array of at least 3*nparticle elements.
* Use cp2k_get_nparticle() to get the number of particles.
* \param n_el Size of the force array
******************************************************************************/
void cp2k_get_forces(force_env_t force_env, double *force, int n_el);
/*******************************************************************************
* \brief Get the potential energy of the system
* \param force_env the force environment
* \param e_pot The potential energy
******************************************************************************/
void cp2k_get_potential_energy(force_env_t force_env, double *e_pot);
/*******************************************************************************
* \brief Get the size of the cell
* \param force_env the force environment
* \param cell Array containing the cell
******************************************************************************/
void cp2k_get_cell(force_env_t force_env, double *cell);
/*******************************************************************************
* \brief Get the size of the qmmm cell
* \param force_env the force environment
* \param cell Array containing the qmmm cell
******************************************************************************/
void cp2k_get_qmmm_cell(force_env_t force_env, double *cell);
/*******************************************************************************
* \brief Calculate energy and forces of the system
* \param force_env the force environment
******************************************************************************/
void cp2k_calc_energy_force(force_env_t force_env);
/*******************************************************************************
* \brief Calculate only the energy of the system
* \param force_env the force environment
******************************************************************************/
void cp2k_calc_energy(force_env_t force_env);
/*******************************************************************************
* \brief Make a CP2K run with the given input file
* \param input_file_path Path to a CP2K input file
* \param output_file_path Path to a file where CP2K is going to append its
* output (created if non-existent)
******************************************************************************/
void cp2k_run_input(const char *input_file_path, const char *output_file_path);
/*******************************************************************************
* \brief Make a CP2K run with the given input file (custom managed MPI)
* \param input_file_path Path to a CP2K input file
* \param output_file_path Path to a file where CP2K is going to append its
* output (created if non-existent)
* \param mpi_comm Fortran MPI communicator if MPI is not managed by CP2K
******************************************************************************/
void cp2k_run_input_comm(const char *input_file_path,
const char *output_file_path, int mpi_comm);
/*******************************************************************************
* \brief Transport parameters read from a CP2K input file.
* This definition matches the respective type definition in the
* transport_env_types module
******************************************************************************/
typedef struct {
int n_occ;
int n_atoms;
double energy_diff;
double evoltfactor;
double e_charge;
double boltzmann;
double h_bar;
int iscf;
int method;
int qt_formalism;
int injection_method;
int rlaxis_integration_method;
int linear_solver;
int matrixinv_method;
int transport_neutral;
int num_pole;
int ordering;
int row_ordering;
int verbosity;
int pexsi_np_symb_fact;
int n_kpoint;
int num_interval;
int num_contacts;
int stride_contacts;
int tasks_per_energy_point;
int tasks_per_pole;
int gpus_per_point;
int n_points_beyn;
int ncrc_beyn;
int tasks_per_integration_point;
int n_points_inv;
int cutout[2];
double colzero_threshold;
double eps_limit;
double eps_limit_cc;
double eps_decay;
double eps_singularity_curvatures;
double eps_mu;
double eps_eigval_degen;
double eps_fermi;
double energy_interval;
double min_interval;
double temperature;
double dens_mixing;
double n_rand_beyn;
double n_rand_cc_beyn;
double svd_cutoff;
int *contacts_data;
int *nsgf;
double *zeff;
bool obc_equilibrium;
bool extra_scf;
} cp2k_transport_parameters;
/*******************************************************************************
* \brief CP2K's C-interoperable CSR matrix
* This definition matches the respective type definition in the
* transport_env_types module
******************************************************************************/
typedef struct {
int nrows_total;
int ncols_total;
int nze_total;
int nze_local;
int nrows_local;
int data_type;
int first_row;
int *rowptr_local;
int *colind_local;
int *nzerow_local;
double *nzvals_local;
} cp2k_csr_interop_type;
/*******************************************************************************
* \brief Function pointer type for the externally evaluated density matrix
* Function pointer type pointing to a C routine that takes the S and H
* matrices as input and outputs a P matrix.
*
* Function definition example:
* \code{.c}
* void c_scf_method(
* cp2k_transport_parameters cp2k_transport_params,
* cp2k_csr_interop_type S,
* cp2k_csr_interop_type KS,
* cp2k_csr_interop_type* P,
* cp2k_csr_interop_type* PImag
* );
* \endcode
* \sa cp2k_transport_parameters, cp2k_csr_interop_type
******************************************************************************/
typedef void (*ext_method_callback_f_ptr)(
cp2k_transport_parameters, // Transport parameters
cp2k_csr_interop_type, // S-Matrix
cp2k_csr_interop_type, // H-Matrix
cp2k_csr_interop_type *, // P-Matrix
cp2k_csr_interop_type * // PImag-Matrix
);
/*******************************************************************************
* \brief Set the function callback for the externally evaluated density matrix
******************************************************************************/
void cp2k_transport_set_callback(force_env_t force_env,
ext_method_callback_f_ptr func);
/*******************************************************************************
* \brief Get the number of molecular orbitals in the active space
* \param force_env the force environment
* \returns The number of elements or -1 if unavailable
******************************************************************************/
int cp2k_active_space_get_mo_count(force_env_t force_env);
/*******************************************************************************
* \brief Get the Fock submatrix for the active space
* \param force_env the force environment
* \param buf Pre-allocated array of at least mo_count^2 elements.
* Use `cp2k_active_space_get_mo_count()` to get the number of
* molecular orbitals.
* \param buf_len Size of the buf array
* \returns The number of elements written to buf or -1 if unavailable
******************************************************************************/
long int cp2k_active_space_get_fock_sub(force_env_t force_env, double *buf,
long int buf_len);
/*******************************************************************************
* \brief Get the number of non-zero elements in the ERI matrix
* \param force_env the force environment
* \returns The number of elements or -1 if unavailable
******************************************************************************/
long int cp2k_active_space_get_eri_nze_count(force_env_t force_env);
/*******************************************************************************
* \brief Get the non-zero elements of the ERI matrix
* The buf_coords will contain the coordinates in the format
* `[i1, j1, k1, l1, i2, j2, k2, l2, ... ]`.
*
* \param force_env the force environment
* \param buf_coords Pre-allocated array of at least 4*nze_count elements.
* Use `cp2k_active_space_get_eri_nze_count()` to get the
* number of non-zero elements.
* \param buf_coords_len Size of the buf_coords array
* \param buf_values Pre-allocated array of at least nze_count elements.
* Use `cp2k_active_space_get_eri_nze_count()` to get the
* number of non-zero elements.
* \param buf_values_len Size of the buf_values array
* \returns The number of elements written to buf_values or -1 if unavailable
******************************************************************************/
int cp2k_active_space_get_eri(force_env_t force_env, int *buf_coords,
long int buf_coords_len, double *buf_values,
long int buf_values_len);
#ifdef __cplusplus
}
#endif
#endif