ddx 1.0.0
Libary for domain-decomposition methods for polarizable continuum models
ddx_cinterface.f90
1module ddx_cinterface
2 use, intrinsic :: iso_c_binding
3 use ddx
4 implicit none
5
7 type(ddx_params_type) :: params
8 type(ddx_constants_type) :: constants
9 type(ddx_workspace_type) :: workspace
10 end type ddx_setup_type
11
12contains
13!
14! Generic stuff
15!
16subroutine ddx_get_banner(message, maxlen) bind(C)
17 integer(c_int), intent(in), value :: maxlen
18 character(len=1, kind=C_char), intent(out) :: message(maxlen)
19 integer :: length, i
20 character (len=4095) :: header
21 call get_banner(header)
22 message(maxlen) = c_null_char
23 length = min(maxlen-1, 4095)
24 do i = length, 1, -1
25 if (header(i:i) .eq. ' ') then
26 length = i-1
27 else
28 exit
29 endif
30 enddo
31 message(length + 1) = c_null_char
32 do i = 1, length
33 message(i) = header(i:i)
34 enddo
35end
36
37function ddx_supported_lebedev_grids(n, grids) result(c_ngrids) bind(C)
38 integer(c_int), intent(in), value :: n
39 integer(c_int), intent(out) :: grids(n)
40 integer(c_int) :: c_ngrids
41 c_ngrids = min(n, nllg)
42 grids(1:c_ngrids) = ng0(1:c_ngrids)
43end
44
45! With reference to a atomic sphere `sphere` of radius `r` centred at `a` compute:
46! 4π |x - a|^l
47! ------ ----------- Y_l^m(|x - a|)
48! 2l + 1 r^l
49! lmax should be identical to the value stored inside c_ddx or less.
50subroutine ddx_scaled_ylm(c_ddx, lmax, x, sphere, ylm) bind(C)
51 type(c_ptr), intent(in), value :: c_ddx
52 integer(c_int), intent(in), value :: lmax
53 real(c_double), intent(in) :: x(3)
54 integer(c_int), intent(in), value :: sphere
55 real(c_double), intent(out) :: ylm((lmax+1)**2)
56 real(dp) :: delta(3)
57 real(dp) :: ratio, rho, ctheta, stheta, cphi, sphi, dnorm
58 real(dp) :: vplm((lmax+1)**2), vcos(lmax+1), vsin(lmax+1)
59 double precision, external :: dnrm2
60 integer :: ind, m, l
61 type(ddx_setup_type), pointer :: ddx_model
62 call c_f_pointer(c_ddx, ddx_model)
63
64 associate(rsph => ddx_model%params%rsph, lmax => ddx_model%params%lmax, vscales => ddx_model%constants%vscales)
65 delta = x(:) - ddx_model%params%csph(:, sphere)
66 dnorm = dnrm2(3, delta, 1)
67 delta = delta / dnorm
68 call ylmbas(delta, rho, ctheta, stheta, cphi, sphi, lmax, vscales, ylm, vplm, vcos, vsin)
69 do l = 0, lmax
70 ratio = ddx_model%constants%v4pi2lp1(l+1) * (dnorm / rsph(sphere))**l
71 do m = -l, l
72 ind = l*(l+1) + m + 1
73 ylm(ind) = ylm(ind) * ratio
74 enddo
75 enddo
76 end associate
77end
78
79!
80! Error
81!
82
83function ddx_allocate_error() result(c_error) bind(C)
84 type(c_ptr) :: c_error
85 type(ddx_error_type), pointer :: ddx_error
86 allocate(ddx_error)
87 c_error = c_loc(ddx_error)
88end function
89
90function ddx_get_error_flag(c_error) result(has_error) bind(C)
91 type(c_ptr), intent(in), value :: c_error
92 type(ddx_error_type), pointer :: ddx_error
93 integer(c_int) :: has_error
94 call c_f_pointer(c_error, ddx_error)
95 has_error = ddx_error%flag
96end
97
98subroutine ddx_get_error_message(c_error, message, maxlen) bind(C)
99 type(c_ptr), intent(in), value :: c_error
100 integer(c_int), intent(in), value :: maxlen
101 character(len=1, kind=C_char), intent(out) :: message(maxlen)
102 character(len=2047) :: error_message
103 type(ddx_error_type), pointer :: ddx_error
104 integer :: length, i
105 call c_f_pointer(c_error, ddx_error)
106 if (ddx_error%flag .ne. 0) then
107 error_message = ddx_error%message
108 else
109 error_message = ''
110 endif
111
112 ! Convert to C message
113 message(maxlen) = c_null_char
114 length = min(maxlen-1, ddx_error%message_length-1)
115 do i = length, 1, -1
116 if (error_message(i:i) .eq. ' ') then
117 length = i-1
118 else
119 exit
120 endif
121 enddo
122 message(length + 1) = c_null_char
123 do i = 1, length
124 message(i) = error_message(i:i)
125 enddo
126end
127
128!
129! Electrostatics container
130!
131function ddx_allocate_electrostatics(c_ddx, c_error) result(c_electrostatics) bind(C)
132 type(c_ptr), intent(in), value :: c_ddx, c_error
133 type(ddx_setup_type), pointer :: ddx_model
134 type(ddx_error_type), pointer :: ddx_error
135 type(c_ptr) :: c_electrostatics
136 type(ddx_electrostatics_type), pointer :: electrostatics
137 call c_f_pointer(c_ddx, ddx_model)
138 call c_f_pointer(c_error, ddx_error)
139 allocate(electrostatics)
140 call allocate_electrostatics(ddx_model%params, ddx_model%constants, electrostatics, ddx_error)
141 c_electrostatics = c_loc(electrostatics)
142end function
143
144subroutine ddx_deallocate_electrostatics(c_electrostatics, c_error) bind(C)
145 type(c_ptr), intent(in), value :: c_electrostatics, c_error
146 type(ddx_electrostatics_type), pointer :: electrostatics
147 type(ddx_error_type), pointer :: ddx_error
148 call c_f_pointer(c_electrostatics, electrostatics)
149 call c_f_pointer(c_error, ddx_error)
150 call deallocate_electrostatics(electrostatics, ddx_error)
151 deallocate(electrostatics)
152end
153
154subroutine ddx_multipole_electrostatics(c_ddx, nsph, nmultipoles, multipoles, &
155 & c_electrostatics, c_error) bind(C)
156 implicit none
157 type(c_ptr), intent(in), value :: c_ddx, c_electrostatics, c_error
158 integer(c_int), intent(in), value :: nsph, nmultipoles
159 real(c_double), intent(in) :: multipoles(nmultipoles, nsph)
160 type(ddx_setup_type), pointer :: ddx_model
161 type(ddx_error_type), pointer :: ddx_error
162 type(ddx_electrostatics_type), pointer :: electrostatics
163 integer :: mmax
164
165 call c_f_pointer(c_ddx, ddx_model)
166 call c_f_pointer(c_error, ddx_error)
167 call c_f_pointer(c_electrostatics, electrostatics)
168 mmax = int(sqrt(dble(nmultipoles)) - 1d0)
169
170 call multipole_electrostatics(ddx_model%params, ddx_model%constants, ddx_model%workspace, &
171 & multipoles, mmax, electrostatics, ddx_error)
172end
173!
174! Setup object
175!
176function ddx_allocate_model(model, enable_force, solvent_epsilon, &
177 & solvent_kappa, eta, se, lmax, n_lebedev, incore, maxiter, &
178 & jacobi_n_diis, enable_fmm, fmm_multipole_lmax, &
179 & fmm_local_lmax, n_proc, n_spheres, sphere_centres, &
180 & sphere_radii, length_logfile, c_logfile, switching, c_error) &
181 & result(c_ddx) bind(C)
182 integer(c_int), intent(in), value :: model, enable_force, lmax, &
183 & n_lebedev, maxiter, incore, jacobi_n_diis, enable_fmm, &
184 & fmm_multipole_lmax, fmm_local_lmax, n_proc, n_spheres, &
185 & length_logfile, switching
186 real(c_double), intent(in) :: sphere_centres(3, n_spheres), sphere_radii(n_spheres)
187 real(c_double), intent(in), value :: eta, se, solvent_epsilon, solvent_kappa
188 type(c_ptr), intent(in), value :: c_error
189 type(ddx_error_type), pointer :: ddx_error
190 !type(c_funptr), value :: printfctn
191 type(c_ptr) :: c_ddx
192 integer :: passproc, i
193 type(ddx_setup_type), pointer :: ddx_model
194 character(len=1, kind=C_char), intent(in) :: c_logfile(length_logfile)
195 character(len=255) :: logfile
196
197 call c_f_pointer(c_error, ddx_error)
198
199 ! Allocate DDX object
200 allocate(ddx_model)
201 c_ddx = c_loc(ddx_model)
202
203 ! Convert to Fortran objects
204 passproc = n_proc
205 logfile = ''
206 do i = 1, min(length_logfile, 255)
207 if (c_logfile(i) .ne. c_null_char) then
208 logfile(i:i) = c_logfile(i)
209 endif
210 enddo
211
212 call params_init(model, enable_force, solvent_epsilon, &
213 & solvent_kappa, eta, se, lmax, n_lebedev, incore, maxiter, &
214 & jacobi_n_diis, enable_fmm, fmm_multipole_lmax, &
215 & fmm_local_lmax, passproc, n_spheres, sphere_centres, &
216 & sphere_radii, logfile, switching, ddx_model%params, ddx_error)
217 if (ddx_error%flag .ne. 0) then
218 return
219 endif
220 call constants_init(ddx_model%params, ddx_model%constants, ddx_error)
221 if (ddx_error%flag .ne. 0) then
222 return
223 endif
224 call workspace_init(ddx_model%params, ddx_model%constants, ddx_model%workspace, ddx_error)
225 if (ddx_error%flag .ne. 0) then
226 return
227 endif
228end function
229
230subroutine ddx_deallocate_model(c_ddx, c_error) bind(C)
231 type(c_ptr), intent(in), value :: c_ddx, c_error
232 type(ddx_setup_type), pointer :: ddx_model
233 type(ddx_error_type), pointer :: ddx_error
234 call c_f_pointer(c_ddx, ddx_model)
235 call c_f_pointer(c_error, ddx_error)
236 call params_free(ddx_model%params, ddx_error)
237 call constants_free(ddx_model%constants, ddx_error)
238 call workspace_free(ddx_model%workspace, ddx_error)
239 deallocate(ddx_model)
240end
241
242subroutine ddx_get_logfile(c_ddx, message, maxlen) bind(C)
243 type(c_ptr), intent(in), value :: c_ddx
244 integer(c_int), intent(in), value :: maxlen
245 character(len=1, kind=C_char), intent(out) :: message(maxlen)
246 type(ddx_setup_type), pointer :: ddx_model
247 integer :: length, i
248 call c_f_pointer(c_ddx, ddx_model)
249 ! Convert to C message
250 message(maxlen) = c_null_char
251 length = min(maxlen-1, 255)
252 do i = length, 1, -1
253 if (ddx_model%params%output_filename(i:i) .eq. ' ') then
254 length = i-1
255 else
256 exit
257 endif
258 enddo
259 message(length + 1) = c_null_char
260 do i = 1, length
261 message(i) = ddx_model%params%output_filename(i:i)
262 enddo
263end
264
265! Generated block, see scripts/generate_cinterface.py
266function ddx_get_enable_fmm(c_ddx) result(c_fmm) bind(C)
267 type(c_ptr), intent(in), value :: c_ddx
268 type(ddx_setup_type), pointer :: ddx_model
269 integer(c_int) :: c_fmm
270 call c_f_pointer(c_ddx, ddx_model)
271 c_fmm = ddx_model % params % fmm
272end function
273
274function ddx_get_enable_force(c_ddx) result(c_force) bind(C)
275 type(c_ptr), intent(in), value :: c_ddx
276 type(ddx_setup_type), pointer :: ddx_model
277 integer(c_int) :: c_force
278 call c_f_pointer(c_ddx, ddx_model)
279 c_force = ddx_model % params % force
280end function
281
282function ddx_get_jacobi_n_diis(c_ddx) result(c_jacobi_ndiis) bind(C)
283 type(c_ptr), intent(in), value :: c_ddx
284 type(ddx_setup_type), pointer :: ddx_model
285 integer(c_int) :: c_jacobi_ndiis
286 call c_f_pointer(c_ddx, ddx_model)
287 c_jacobi_ndiis = ddx_model % params % jacobi_ndiis
288end function
289
290function ddx_get_lmax(c_ddx) result(c_lmax) bind(C)
291 type(c_ptr), intent(in), value :: c_ddx
292 type(ddx_setup_type), pointer :: ddx_model
293 integer(c_int) :: c_lmax
294 call c_f_pointer(c_ddx, ddx_model)
295 c_lmax = ddx_model % params % lmax
296end function
297
298function ddx_get_incore(c_ddx) result(c_matvecmem) bind(C)
299 type(c_ptr), intent(in), value :: c_ddx
300 type(ddx_setup_type), pointer :: ddx_model
301 integer(c_int) :: c_matvecmem
302 call c_f_pointer(c_ddx, ddx_model)
303 c_matvecmem = ddx_model % params % matvecmem
304end function
305
306function ddx_get_maxiter(c_ddx) result(c_maxiter) bind(C)
307 type(c_ptr), intent(in), value :: c_ddx
308 type(ddx_setup_type), pointer :: ddx_model
309 integer(c_int) :: c_maxiter
310 call c_f_pointer(c_ddx, ddx_model)
311 c_maxiter = ddx_model % params % maxiter
312end function
313
314function ddx_get_model(c_ddx) result(c_model) bind(C)
315 type(c_ptr), intent(in), value :: c_ddx
316 type(ddx_setup_type), pointer :: ddx_model
317 integer(c_int) :: c_model
318 call c_f_pointer(c_ddx, ddx_model)
319 c_model = ddx_model % params % model
320end function
321
322function ddx_get_n_lebedev(c_ddx) result(c_ngrid) bind(C)
323 type(c_ptr), intent(in), value :: c_ddx
324 type(ddx_setup_type), pointer :: ddx_model
325 integer(c_int) :: c_ngrid
326 call c_f_pointer(c_ddx, ddx_model)
327 c_ngrid = ddx_model % params % ngrid
328end function
329
330function ddx_get_n_spheres(c_ddx) result(c_nsph) bind(C)
331 type(c_ptr), intent(in), value :: c_ddx
332 type(ddx_setup_type), pointer :: ddx_model
333 integer(c_int) :: c_nsph
334 call c_f_pointer(c_ddx, ddx_model)
335 c_nsph = ddx_model % params % nsph
336end function
337
338function ddx_get_n_proc(c_ddx) result(c_nproc) bind(C)
339 type(c_ptr), intent(in), value :: c_ddx
340 type(ddx_setup_type), pointer :: ddx_model
341 integer(c_int) :: c_nproc
342 call c_f_pointer(c_ddx, ddx_model)
343 c_nproc = ddx_model % params % nproc
344end function
345
346function ddx_get_fmm_local_lmax(c_ddx) result(c_pl) bind(C)
347 type(c_ptr), intent(in), value :: c_ddx
348 type(ddx_setup_type), pointer :: ddx_model
349 integer(c_int) :: c_pl
350 call c_f_pointer(c_ddx, ddx_model)
351 c_pl = ddx_model % params % pl
352end function
353
354function ddx_get_fmm_multipole_lmax(c_ddx) result(c_pm) bind(C)
355 type(c_ptr), intent(in), value :: c_ddx
356 type(ddx_setup_type), pointer :: ddx_model
357 integer(c_int) :: c_pm
358 call c_f_pointer(c_ddx, ddx_model)
359 c_pm = ddx_model % params % pm
360end function
361
362function ddx_get_switching(c_ddx) result(c_switching) bind(C)
363 type(c_ptr), intent(in), value :: c_ddx
364 type(ddx_setup_type), pointer :: ddx_model
365 integer(c_int) :: c_switching
366 call c_f_pointer(c_ddx, ddx_model)
367 c_switching = ddx_model % params % switching
368end function
369
370function ddx_get_solvent_epsilon(c_ddx) result(c_eps) bind(C)
371 type(c_ptr), intent(in), value :: c_ddx
372 type(ddx_setup_type), pointer :: ddx_model
373 real(c_double) :: c_eps
374 call c_f_pointer(c_ddx, ddx_model)
375 c_eps = ddx_model % params % eps
376end function
377
378function ddx_get_eta(c_ddx) result(c_eta) bind(C)
379 type(c_ptr), intent(in), value :: c_ddx
380 type(ddx_setup_type), pointer :: ddx_model
381 real(c_double) :: c_eta
382 call c_f_pointer(c_ddx, ddx_model)
383 c_eta = ddx_model % params % eta
384end function
385
386function ddx_get_solvent_kappa(c_ddx) result(c_kappa) bind(C)
387 type(c_ptr), intent(in), value :: c_ddx
388 type(ddx_setup_type), pointer :: ddx_model
389 real(c_double) :: c_kappa
390 call c_f_pointer(c_ddx, ddx_model)
391 c_kappa = ddx_model % params % kappa
392end function
393
394function ddx_get_shift(c_ddx) result(c_se) bind(C)
395 type(c_ptr), intent(in), value :: c_ddx
396 type(ddx_setup_type), pointer :: ddx_model
397 real(c_double) :: c_se
398 call c_f_pointer(c_ddx, ddx_model)
399 c_se = ddx_model % params % se
400end function
401
402subroutine ddx_get_sphere_centres(c_ddx, nsph, c_csph) bind(C)
403 type(c_ptr), intent(in), value :: c_ddx
404 integer(c_int), intent(in), value :: nsph
405 real(c_double), intent(out) :: c_csph(3, nsph)
406 type(ddx_setup_type), pointer :: ddx_model
407 call c_f_pointer(c_ddx, ddx_model)
408 c_csph(:, :) = ddx_model % params % csph(:, :)
409end subroutine
410
411subroutine ddx_get_sphere_radii(c_ddx, nsph, c_rsph) bind(C)
412 type(c_ptr), intent(in), value :: c_ddx
413 integer(c_int), intent(in), value :: nsph
414 real(c_double), intent(out) :: c_rsph(nsph)
415 type(ddx_setup_type), pointer :: ddx_model
416 call c_f_pointer(c_ddx, ddx_model)
417 c_rsph(:) = ddx_model % params % rsph(:)
418end subroutine
419
420function ddx_get_n_basis(c_ddx) result(c_nbasis) bind(C)
421 type(c_ptr), intent(in), value :: c_ddx
422 type(ddx_setup_type), pointer :: ddx_model
423 integer(c_int) :: c_nbasis
424 call c_f_pointer(c_ddx, ddx_model)
425 c_nbasis = ddx_model % constants % nbasis
426end function
427
428function ddx_get_n_cav(c_ddx) result(c_ncav) bind(C)
429 type(c_ptr), intent(in), value :: c_ddx
430 type(ddx_setup_type), pointer :: ddx_model
431 integer(c_int) :: c_ncav
432 call c_f_pointer(c_ddx, ddx_model)
433 c_ncav = ddx_model % constants % ncav
434end function
435
436subroutine ddx_get_cavity(c_ddx, ncav, c_ccav) bind(C)
437 type(c_ptr), intent(in), value :: c_ddx
438 integer(c_int), intent(in), value :: ncav
439 real(c_double), intent(out) :: c_ccav(3, ncav)
440 type(ddx_setup_type), pointer :: ddx_model
441 call c_f_pointer(c_ddx, ddx_model)
442 c_ccav(:, :) = ddx_model % constants % ccav(:, :)
443end subroutine
444! end generated block
445
446!
447! State object
448!
449function ddx_allocate_state(c_ddx, c_error) result(c_state) bind(C)
450 type(c_ptr), intent(in), value :: c_ddx, c_error
451 type(ddx_setup_type), pointer :: ddx_model
452 type(ddx_error_type), pointer :: ddx_error
453 type(c_ptr) :: c_state
454 type(ddx_state_type), pointer :: state
455 call c_f_pointer(c_ddx, ddx_model)
456 call c_f_pointer(c_error, ddx_error)
457 allocate(state)
458 call allocate_state(ddx_model%params, ddx_model%constants, state, ddx_error)
459 c_state = c_loc(state)
460end function
461
462subroutine ddx_deallocate_state(c_state, c_error) bind(C)
463 type(c_ptr), intent(in), value :: c_state, c_error
464 type(ddx_state_type), pointer :: state
465 type(ddx_error_type), pointer :: ddx_error
466 call c_f_pointer(c_state, state)
467 call c_f_pointer(c_error, ddx_error)
468 call deallocate_state(state, ddx_error)
469 deallocate(state)
470end subroutine
471
472subroutine ddx_get_x(c_state, nbasis, nsph, x) bind(C)
473 type(c_ptr), intent(in), value :: c_state
474 type(ddx_state_type), pointer :: state
475 integer(c_int), intent(in), value :: nsph, nbasis
476 real(c_double), intent(out) :: x(nbasis, nsph)
477 call c_f_pointer(c_state, state)
478
479 if (allocated(state%x_lpb)) then ! Case for ddLPB
480 x(:, :) = state%x_lpb(:, :, 1) ! Use only the first of the two solutions
481 else
482 x(:, :) = state%xs(:, :)
483 endif
484end subroutine
485
486function ddx_get_x_niter(c_state) bind(C) result(c_niter)
487 type(c_ptr), intent(in), value :: c_state
488 type(ddx_state_type), pointer :: state
489 integer(c_int) :: c_niter
490 call c_f_pointer(c_state, state)
491 if (allocated(state%x_lpb)) then ! Case for ddLPB
492 c_niter = state%x_lpb_niter
493 else
494 c_niter = state%xs_niter
495 endif
496end function
497
498subroutine ddx_get_s(c_state, nbasis, nsph, s) bind(C)
499 type(c_ptr), intent(in), value :: c_state
500 type(ddx_state_type), pointer :: state
501 integer(c_int), intent(in), value :: nsph, nbasis
502 real(c_double), intent(out) :: s(nbasis, nsph)
503 call c_f_pointer(c_state, state)
504 if (allocated(state%x_adj_lpb)) then ! Case for ddLPB
505 s(:, :) = state%x_adj_lpb(:, :, 1) ! Use only the first of the two solutions
506 else
507 s(:, :) = state%s(:, :)
508 endif
509end subroutine
510
511function ddx_get_s_niter(c_state) bind(C) result(c_niter)
512 type(c_ptr), intent(in), value :: c_state
513 type(ddx_state_type), pointer :: state
514 integer(c_int) :: c_niter
515 call c_f_pointer(c_state, state)
516 if (allocated(state%x_adj_lpb)) then ! Case for ddLPB
517 c_niter = state%x_adj_lpb_niter
518 else
519 c_niter = state%s_niter
520 endif
521end function
522
523subroutine ddx_get_xi(c_state, c_ddx, ncav, xi) bind(C)
524 type(c_ptr), intent(in), value :: c_state, c_ddx
525 type(ddx_state_type), pointer :: state
526 type(ddx_setup_type), pointer :: ddx_model
527 integer(c_int), intent(in), value :: ncav
528 real(c_double), intent(out) :: xi(ncav)
529 call c_f_pointer(c_ddx, ddx_model)
530 call c_f_pointer(c_state, state)
531 call ddproject_cav(ddx_model%params, ddx_model%constants, state%q, xi)
532end subroutine
533
534subroutine ddx_get_zeta_dip(c_state, c_ddx, ncav, zeta_dip) bind(C)
535 type(c_ptr), intent(in), value :: c_state, c_ddx
536 type(ddx_state_type), pointer :: state
537 type(ddx_setup_type), pointer :: ddx_model
538 integer(c_int), intent(in), value :: ncav
539 real(c_double), intent(out) :: zeta_dip(3, ncav)
540 call c_f_pointer(c_ddx, ddx_model)
541 call c_f_pointer(c_state, state)
542 if (allocated(state%zeta_dip)) then
543 zeta_dip(:, :) = state%zeta_dip(:, :)
544 else
545 zeta_dip(:, :) = 0d0
546 endif
547end subroutine
548
549!
550! High level APIs (model nonspecific)
551!
552function ddx_ddrun(c_ddx, c_state, c_electrostatics, nbasis, nsph, &
553 & psi, tol, force, read_guess, c_error) result(c_energy) bind(C)
554 type(c_ptr), intent(in), value :: c_ddx, c_state, c_electrostatics, &
555 & c_error
556 integer(c_int), intent(in), value :: nbasis, nsph
557 real(c_double), intent(in) :: psi(nbasis, nsph)
558 real(c_double), intent(in), value :: tol
559 real(c_double), intent(out) :: force(3, nsph)
560 real(c_double) :: c_energy
561 integer(c_int), intent(in), value :: read_guess
562 type(ddx_setup_type), pointer :: ddx_model
563 logical :: do_guess
564
565 ! at least return something in case of errors
566 c_energy = zero
567
568 ! setup
569 do_guess = read_guess.eq.0
570 call c_f_pointer(c_ddx, ddx_model)
571 call ddx_setup(c_ddx, c_state, c_electrostatics, nbasis, nsph, psi, c_error)
572 if (ddx_get_error_flag(c_error) .ne. 0) return
573
574 ! primal linear system
575 if (do_guess) then
576 call ddx_fill_guess(c_ddx, c_state, tol, c_error)
577 if (ddx_get_error_flag(c_error) .ne. 0) return
578 end if
579 call ddx_solve(c_ddx, c_state, tol, c_error)
580 if (ddx_get_error_flag(c_error) .ne. 0) return
581
582 ! energy
583 c_energy = ddx_energy(c_ddx, c_state, c_error)
584 if (ddx_get_error_flag(c_error) .ne. 0) return
585
586 ! adjoint linear system
587 if (ddx_model%params%force .eq. 1) then
588 if (do_guess) then
589 call ddx_fill_guess_adjoint(c_ddx, c_state, tol, c_error)
590 end if
591 if (ddx_get_error_flag(c_error) .ne. 0) return
592 call ddx_solve_adjoint(c_ddx, c_state, tol, c_error)
593 if (ddx_get_error_flag(c_error) .ne. 0) return
594 end if
595
596 ! forces
597 if (ddx_model%params%force .eq. 1) then
598 call ddx_solvation_force_terms(c_ddx, c_state, c_electrostatics, &
599 & nsph, force, c_error)
600 if (ddx_get_error_flag(c_error) .ne. 0) return
601 end if
602
603end function
604
605subroutine ddx_setup(c_ddx, c_state, c_electrostatics, nbasis, nsph, psi, c_error) bind(C)
606 type(c_ptr), intent(in), value :: c_ddx, c_state, c_electrostatics, &
607 & c_error
608 integer(c_int), intent(in), value :: nbasis, nsph
609 real(c_double), intent(in) :: psi(nbasis, nsph)
610 type(ddx_setup_type), pointer :: ddx_model
611 type(ddx_state_type), pointer :: state
612 type(ddx_electrostatics_type), pointer :: electrostatics
613 type(ddx_error_type), pointer :: ddx_error
614 call c_f_pointer(c_ddx, ddx_model)
615 call c_f_pointer(c_state, state)
616 call c_f_pointer(c_electrostatics, electrostatics)
617 call c_f_pointer(c_error, ddx_error)
618 call setup(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, &
619 & electrostatics, psi, ddx_error)
620end subroutine
621
622subroutine ddx_fill_guess(c_ddx, c_state, tol, c_error) bind(C)
623 type(c_ptr), intent(in), value :: c_ddx, c_state, c_error
624 real(c_double), intent(in), value :: tol
625 type(ddx_setup_type), pointer :: ddx_model
626 type(ddx_state_type), pointer :: state
627 type(ddx_error_type), pointer :: ddx_error
628 call c_f_pointer(c_ddx, ddx_model)
629 call c_f_pointer(c_state, state)
630 call c_f_pointer(c_error, ddx_error)
631 call fill_guess(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, &
632 & tol, ddx_error)
633end subroutine
634
635subroutine ddx_fill_guess_adjoint(c_ddx, c_state, tol, c_error) bind(C)
636 type(c_ptr), intent(in), value :: c_ddx, c_state, c_error
637 real(c_double), intent(in), value :: tol
638 type(ddx_setup_type), pointer :: ddx_model
639 type(ddx_state_type), pointer :: state
640 type(ddx_error_type), pointer :: ddx_error
641 call c_f_pointer(c_ddx, ddx_model)
642 call c_f_pointer(c_state, state)
643 call c_f_pointer(c_error, ddx_error)
644 call fill_guess_adjoint(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, &
645 & tol, ddx_error)
646end subroutine
647
648subroutine ddx_solve(c_ddx, c_state, tol, c_error) bind(C)
649 type(c_ptr), intent(in), value :: c_ddx, c_state, c_error
650 real(c_double), intent(in), value :: tol
651 type(ddx_setup_type), pointer :: ddx_model
652 type(ddx_state_type), pointer :: state
653 type(ddx_error_type), pointer :: ddx_error
654 call c_f_pointer(c_ddx, ddx_model)
655 call c_f_pointer(c_state, state)
656 call c_f_pointer(c_error, ddx_error)
657 call solve(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, tol, ddx_error)
658end subroutine
659
660subroutine ddx_solve_adjoint(c_ddx, c_state, tol, c_error) bind(C)
661 type(c_ptr), intent(in), value :: c_ddx, c_state, c_error
662 real(c_double), intent(in), value :: tol
663 type(ddx_setup_type), pointer :: ddx_model
664 type(ddx_state_type), pointer :: state
665 type(ddx_error_type), pointer :: ddx_error
666 call c_f_pointer(c_ddx, ddx_model)
667 call c_f_pointer(c_state, state)
668 call c_f_pointer(c_error, ddx_error)
669 call solve_adjoint(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, &
670 & tol, ddx_error)
671end subroutine
672
673function ddx_energy(c_ddx, c_state, c_error) result(c_energy) bind(C)
674 type(c_ptr), intent(in), value :: c_ddx, c_state, c_error
675 type(ddx_setup_type), pointer :: ddx_model
676 type(ddx_state_type), pointer :: state
677 type(ddx_error_type), pointer :: ddx_error
678 real(c_double) :: c_energy
679 call c_f_pointer(c_ddx, ddx_model)
680 call c_f_pointer(c_state, state)
681 call c_f_pointer(c_error, ddx_error)
682 call energy(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, &
683 & c_energy, ddx_error)
684end function
685
686subroutine ddx_solvation_force_terms(c_ddx, c_state, c_electrostatics, &
687 & nsph, forces, c_error) bind(C)
688 type(c_ptr), intent(in), value :: c_ddx, c_state, c_electrostatics, &
689 & c_error
690 integer(c_int), intent(in), value :: nsph
691 real(c_double), intent(out) :: forces(3, nsph)
692 type(ddx_setup_type), pointer :: ddx_model
693 type(ddx_state_type), pointer :: state
694 type(ddx_electrostatics_type), pointer :: electrostatics
695 type(ddx_error_type), pointer :: ddx_error
696 call c_f_pointer(c_ddx, ddx_model)
697 call c_f_pointer(c_state, state)
698 call c_f_pointer(c_electrostatics, electrostatics)
699 call c_f_pointer(c_error, ddx_error)
700 call solvation_force_terms(ddx_model%params, ddx_model%constants, ddx_model%workspace, &
701 & state, electrostatics, forces, ddx_error)
702end subroutine
703
704!
705! Cosmo
706!
707! Setup the problem in the state
708subroutine ddx_cosmo_setup(c_ddx, c_state, ncav, nbasis, nsph, psi, phi_cav, c_error) bind(C)
709 type(c_ptr), intent(in), value :: c_error
710 type(c_ptr), intent(in), value :: c_ddx, c_state
711 integer(c_int), intent(in), value :: ncav, nbasis, nsph
712 real(c_double), intent(in) :: phi_cav(ncav), psi(nbasis, nsph)
713 type(ddx_setup_type), pointer :: ddx_model
714 type(ddx_error_type), pointer :: ddx_error
715 type(ddx_state_type), pointer :: state
716 call c_f_pointer(c_ddx, ddx_model)
717 call c_f_pointer(c_error, ddx_error)
718 call c_f_pointer(c_state, state)
719 call cosmo_setup(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, phi_cav, psi, ddx_error)
720end subroutine
721
722! Put a guess for the problem into the state (optional)
723subroutine ddx_cosmo_guess(c_ddx, c_state, c_error) bind(C)
724 type(c_ptr), intent(in), value :: c_error
725 type(c_ptr), intent(in), value :: c_ddx, c_state
726 type(ddx_setup_type), pointer :: ddx_model
727 type(ddx_error_type), pointer :: ddx_error
728 type(ddx_state_type), pointer :: state
729 call c_f_pointer(c_ddx, ddx_model)
730 call c_f_pointer(c_error, ddx_error)
731 call c_f_pointer(c_state, state)
732 call cosmo_guess(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, ddx_error)
733end
734
735! Solve the problem
736subroutine ddx_cosmo_solve(c_ddx, c_state, tol, c_error) bind(C)
737 type(c_ptr), intent(in), value :: c_error
738 type(c_ptr), intent(in), value :: c_ddx, c_state
739 type(ddx_setup_type), pointer :: ddx_model
740 type(ddx_error_type), pointer :: ddx_error
741 type(ddx_state_type), pointer :: state
742 real(c_double), intent(in), value :: tol
743 call c_f_pointer(c_ddx, ddx_model)
744 call c_f_pointer(c_error, ddx_error)
745 call c_f_pointer(c_state, state)
746 call cosmo_solve(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, tol, ddx_error)
747end subroutine
748
749! Put a guess for the adjoint problem into the state (optional)
750subroutine ddx_cosmo_guess_adjoint(c_ddx, c_state, c_error) bind(C)
751 type(c_ptr), intent(in), value :: c_error
752 type(c_ptr), intent(in), value :: c_ddx, c_state
753 type(ddx_setup_type), pointer :: ddx_model
754 type(ddx_error_type), pointer :: ddx_error
755 type(ddx_state_type), pointer :: state
756 call c_f_pointer(c_ddx, ddx_model)
757 call c_f_pointer(c_error, ddx_error)
758 call c_f_pointer(c_state, state)
759 call cosmo_guess_adjoint(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, ddx_error)
760end
761
762! Solve the adjoint problem inside the state
763subroutine ddx_cosmo_solve_adjoint(c_ddx, c_state, tol, c_error) bind(C)
764 type(c_ptr), intent(in), value :: c_error
765 type(c_ptr), intent(in), value :: c_ddx, c_state
766 type(ddx_setup_type), pointer :: ddx_model
767 type(ddx_error_type), pointer :: ddx_error
768 type(ddx_state_type), pointer :: state
769 real(c_double), intent(in), value :: tol
770 call c_f_pointer(c_ddx, ddx_model)
771 call c_f_pointer(c_error, ddx_error)
772 call c_f_pointer(c_state, state)
773 call cosmo_solve_adjoint(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, tol, ddx_error)
774end
775
776! Compute the ddCOSMO energy
777function ddx_cosmo_energy(c_ddx, c_state, c_error) result(c_energy) bind(C)
778 type(c_ptr), intent(in), value :: c_error
779 type(c_ptr), intent(in), value :: c_ddx, c_state
780 type(ddx_setup_type), pointer :: ddx_model
781 type(ddx_error_type), pointer :: ddx_error
782 type(ddx_state_type), pointer :: state
783 real(c_double) :: c_energy
784 call c_f_pointer(c_ddx, ddx_model)
785 call c_f_pointer(c_error, ddx_error)
786 call c_f_pointer(c_state, state)
787 call cosmo_energy(ddx_model%constants, state, c_energy, ddx_error)
788end function
789
790! Compute the forces
791subroutine ddx_cosmo_solvation_force_terms(c_ddx, c_state, nsph, ncav, e_cav, forces, c_error) bind(C)
792 type(c_ptr), intent(in), value :: c_error
793 type(c_ptr), intent(in), value :: c_ddx, c_state
794 type(ddx_setup_type), pointer :: ddx_model
795 type(ddx_error_type), pointer :: ddx_error
796 type(ddx_state_type), pointer :: state
797 integer(c_int), intent(in), value :: nsph, ncav
798 real(c_double), intent(in) :: e_cav(3, ncav)
799 real(c_double), intent(out) :: forces(3, nsph)
800 call c_f_pointer(c_ddx, ddx_model)
801 call c_f_pointer(c_error, ddx_error)
802 call c_f_pointer(c_state, state)
803 call cosmo_solvation_force_terms(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, e_cav, forces, ddx_error)
804end
805
806!
807! PCM
808!
809subroutine ddx_pcm_setup(c_ddx, c_state, ncav, nbasis, nsph, psi, phi_cav, c_error) bind(C)
810 type(c_ptr), intent(in), value :: c_error
811 type(c_ptr), intent(in), value :: c_ddx, c_state
812 integer(c_int), intent(in), value :: ncav, nbasis, nsph
813 real(c_double), intent(in) :: phi_cav(ncav), psi(nbasis, nsph)
814 type(ddx_setup_type), pointer :: ddx_model
815 type(ddx_error_type), pointer :: ddx_error
816 type(ddx_state_type), pointer :: state
817 call c_f_pointer(c_ddx, ddx_model)
818 call c_f_pointer(c_error, ddx_error)
819 call c_f_pointer(c_state, state)
820 call pcm_setup(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, phi_cav, psi, ddx_error)
821end subroutine
822
823subroutine ddx_pcm_guess(c_ddx, c_state, c_error) bind(C)
824 type(c_ptr), intent(in), value :: c_error
825 type(c_ptr), intent(in), value :: c_ddx, c_state
826 type(ddx_setup_type), pointer :: ddx_model
827 type(ddx_error_type), pointer :: ddx_error
828 type(ddx_state_type), pointer :: state
829 call c_f_pointer(c_ddx, ddx_model)
830 call c_f_pointer(c_error, ddx_error)
831 call c_f_pointer(c_state, state)
832 call pcm_guess(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, ddx_error)
833end
834
835subroutine ddx_pcm_solve(c_ddx, c_state, tol, c_error) bind(C)
836 type(c_ptr), intent(in), value :: c_error
837 type(c_ptr), intent(in), value :: c_ddx, c_state
838 type(ddx_setup_type), pointer :: ddx_model
839 type(ddx_error_type), pointer :: ddx_error
840 type(ddx_state_type), pointer :: state
841 real(c_double), intent(in), value :: tol
842 call c_f_pointer(c_ddx, ddx_model)
843 call c_f_pointer(c_error, ddx_error)
844 call c_f_pointer(c_state, state)
845 call pcm_solve(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, tol, ddx_error)
846end subroutine
847
848subroutine ddx_pcm_guess_adjoint(c_ddx, c_state, c_error) bind(C)
849 type(c_ptr), intent(in), value :: c_error
850 type(c_ptr), intent(in), value :: c_ddx, c_state
851 type(ddx_setup_type), pointer :: ddx_model
852 type(ddx_error_type), pointer :: ddx_error
853 type(ddx_state_type), pointer :: state
854 call c_f_pointer(c_ddx, ddx_model)
855 call c_f_pointer(c_error, ddx_error)
856 call c_f_pointer(c_state, state)
857 call pcm_guess_adjoint(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, ddx_error)
858end
859
860subroutine ddx_pcm_solve_adjoint(c_ddx, c_state, tol, c_error) bind(C)
861 type(c_ptr), intent(in), value :: c_error
862 type(c_ptr), intent(in), value :: c_ddx, c_state
863 type(ddx_setup_type), pointer :: ddx_model
864 type(ddx_error_type), pointer :: ddx_error
865 type(ddx_state_type), pointer :: state
866 real(c_double), intent(in), value :: tol
867 call c_f_pointer(c_ddx, ddx_model)
868 call c_f_pointer(c_error, ddx_error)
869 call c_f_pointer(c_state, state)
870 call pcm_solve_adjoint(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, tol, ddx_error)
871end
872
873function ddx_pcm_energy(c_ddx, c_state, c_error) result(c_energy) bind(C)
874 type(c_ptr), intent(in), value :: c_error
875 type(c_ptr), intent(in), value :: c_ddx, c_state
876 type(ddx_setup_type), pointer :: ddx_model
877 type(ddx_error_type), pointer :: ddx_error
878 type(ddx_state_type), pointer :: state
879 real(c_double) :: c_energy
880 call c_f_pointer(c_ddx, ddx_model)
881 call c_f_pointer(c_error, ddx_error)
882 call c_f_pointer(c_state, state)
883 call pcm_energy(ddx_model%constants, state, c_energy, ddx_error)
884end function
885
886subroutine ddx_pcm_solvation_force_terms(c_ddx, c_state, nsph, ncav, e_cav, forces, c_error) bind(C)
887 type(c_ptr), intent(in), value :: c_error
888 type(c_ptr), intent(in), value :: c_ddx, c_state
889 type(ddx_setup_type), pointer :: ddx_model
890 type(ddx_error_type), pointer :: ddx_error
891 type(ddx_state_type), pointer :: state
892 integer(c_int), intent(in), value :: nsph, ncav
893 real(c_double), intent(in) :: e_cav(3, ncav)
894 real(c_double), intent(out) :: forces(3, nsph)
895 call c_f_pointer(c_ddx, ddx_model)
896 call c_f_pointer(c_error, ddx_error)
897 call c_f_pointer(c_state, state)
898 call pcm_solvation_force_terms(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, e_cav, forces, ddx_error)
899end
900
901!
902! LPB
903!
904subroutine ddx_lpb_setup(c_ddx, c_state, ncav, nbasis, nsph, psi, phi_cav, gradphi_cav, c_error) bind(C)
905 type(c_ptr), intent(in), value :: c_error
906 type(c_ptr), intent(in), value :: c_ddx, c_state
907 integer(c_int), intent(in), value :: ncav, nbasis, nsph
908 real(c_double), intent(in) :: phi_cav(ncav), psi(nbasis, nsph), gradphi_cav(3, ncav)
909 type(ddx_setup_type), pointer :: ddx_model
910 type(ddx_error_type), pointer :: ddx_error
911 type(ddx_state_type), pointer :: state
912 call c_f_pointer(c_ddx, ddx_model)
913 call c_f_pointer(c_error, ddx_error)
914 call c_f_pointer(c_state, state)
915 call lpb_setup(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, phi_cav, gradphi_cav, psi, ddx_error)
916end subroutine
917
918subroutine ddx_lpb_guess(c_ddx, c_state, tol, c_error) bind(C)
919 type(c_ptr), intent(in), value :: c_error
920 type(c_ptr), intent(in), value :: c_ddx, c_state
921 real(c_double), intent(in), value :: tol
922 type(ddx_setup_type), pointer :: ddx_model
923 type(ddx_error_type), pointer :: ddx_error
924 type(ddx_state_type), pointer :: state
925 call c_f_pointer(c_ddx, ddx_model)
926 call c_f_pointer(c_error, ddx_error)
927 call c_f_pointer(c_state, state)
928 call lpb_guess(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, tol, ddx_error)
929end
930
931subroutine ddx_lpb_solve(c_ddx, c_state, tol, c_error) bind(C)
932 type(c_ptr), intent(in), value :: c_error
933 type(c_ptr), intent(in), value :: c_ddx, c_state
934 type(ddx_setup_type), pointer :: ddx_model
935 type(ddx_error_type), pointer :: ddx_error
936 type(ddx_state_type), pointer :: state
937 real(c_double), intent(in), value :: tol
938 call c_f_pointer(c_ddx, ddx_model)
939 call c_f_pointer(c_error, ddx_error)
940 call c_f_pointer(c_state, state)
941 call lpb_solve(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, tol, ddx_error)
942end subroutine
943
944subroutine ddx_lpb_guess_adjoint(c_ddx, c_state, tol, c_error) bind(C)
945 type(c_ptr), intent(in), value :: c_error
946 type(c_ptr), intent(in), value :: c_ddx, c_state
947 real(c_double), intent(in), value :: tol
948 type(ddx_setup_type), pointer :: ddx_model
949 type(ddx_error_type), pointer :: ddx_error
950 type(ddx_state_type), pointer :: state
951 call c_f_pointer(c_ddx, ddx_model)
952 call c_f_pointer(c_error, ddx_error)
953 call c_f_pointer(c_state, state)
954 call lpb_guess_adjoint(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, tol, ddx_error)
955end
956
957subroutine ddx_lpb_solve_adjoint(c_ddx, c_state, tol, c_error) bind(C)
958 type(c_ptr), intent(in), value :: c_error
959 type(c_ptr), intent(in), value :: c_ddx, c_state
960 type(ddx_setup_type), pointer :: ddx_model
961 type(ddx_error_type), pointer :: ddx_error
962 type(ddx_state_type), pointer :: state
963 real(c_double), intent(in), value :: tol
964 call c_f_pointer(c_ddx, ddx_model)
965 call c_f_pointer(c_error, ddx_error)
966 call c_f_pointer(c_state, state)
967 call lpb_solve_adjoint(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, tol, ddx_error)
968end
969
970function ddx_lpb_energy(c_ddx, c_state, c_error) result(c_energy) bind(C)
971 type(c_ptr), intent(in), value :: c_error
972 type(c_ptr), intent(in), value :: c_ddx, c_state
973 type(ddx_setup_type), pointer :: ddx_model
974 type(ddx_error_type), pointer :: ddx_error
975 type(ddx_state_type), pointer :: state
976 real(c_double) :: c_energy
977 call c_f_pointer(c_ddx, ddx_model)
978 call c_f_pointer(c_error, ddx_error)
979 call c_f_pointer(c_state, state)
980 call lpb_energy(ddx_model%constants, state, c_energy, ddx_error)
981end function
982
983subroutine ddx_lpb_solvation_force_terms(c_ddx, c_state, nsph, ncav, g_cav, forces, c_error) bind(C)
984 type(c_ptr), intent(in), value :: c_error
985 type(c_ptr), intent(in), value :: c_ddx, c_state
986 type(ddx_setup_type), pointer :: ddx_model
987 type(ddx_error_type), pointer :: ddx_error
988 type(ddx_state_type), pointer :: state
989 integer(c_int), intent(in), value :: nsph, ncav
990 real(c_double), intent(in) :: g_cav(3, 3, ncav)
991 real(c_double), intent(out) :: forces(3, nsph)
992 call c_f_pointer(c_ddx, ddx_model)
993 call c_f_pointer(c_error, ddx_error)
994 call c_f_pointer(c_state, state)
995 call lpb_solvation_force_terms(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, g_cav, forces, ddx_error)
996end
997
998!
999! multipolar solutes
1000!
1001subroutine ddx_multipole_electrostatics_0(c_ddx, nsph, ncav, nmultipoles, multipoles, &
1002 & phi_cav, c_error) bind(C)
1003 type(c_ptr), intent(in), value :: c_ddx
1004 type(ddx_setup_type), pointer :: ddx_model
1005 integer(c_int), intent(in), value :: nsph, ncav, nmultipoles
1006 real(c_double), intent(in) :: multipoles(nmultipoles, nsph)
1007 real(c_double), intent(out) :: phi_cav(ncav)
1008 type(c_ptr), intent(in), value :: c_error
1009 type(ddx_error_type), pointer :: ddx_error
1010 integer :: mmax
1011 call c_f_pointer(c_error, ddx_error)
1012 call c_f_pointer(c_ddx, ddx_model)
1013 mmax = int(sqrt(dble(nmultipoles)) - 1d0)
1014 call multipole_electrostatics_0(ddx_model%params, ddx_model%constants, &
1015 & ddx_model%workspace, multipoles, mmax, phi_cav, ddx_error)
1016end
1017
1018subroutine ddx_multipole_electrostatics_1(c_ddx, nsph, ncav, nmultipoles, multipoles, &
1019 & phi_cav, e_cav, c_error) bind(C)
1020 type(c_ptr), intent(in), value :: c_error
1021 type(c_ptr), intent(in), value :: c_ddx
1022 type(ddx_setup_type), pointer :: ddx_model
1023 type(ddx_error_type), pointer :: ddx_error
1024 integer(c_int), intent(in), value :: nsph, ncav, nmultipoles
1025 real(c_double), intent(in) :: multipoles(nmultipoles, nsph)
1026 real(c_double), intent(out) :: phi_cav(ncav), e_cav(3, ncav)
1027 integer :: mmax
1028 call c_f_pointer(c_ddx, ddx_model)
1029 call c_f_pointer(c_error, ddx_error)
1030 mmax = int(sqrt(dble(nmultipoles)) - 1d0)
1031 call multipole_electrostatics_1(ddx_model%params, ddx_model%constants, &
1032 & ddx_model%workspace, multipoles, mmax, phi_cav, e_cav, ddx_error)
1033end
1034
1035subroutine ddx_multipole_electrostatics_2(c_ddx, nsph, ncav, nmultipoles, multipoles, &
1036 & phi_cav, e_cav, g_cav, c_error) bind(C)
1037 type(c_ptr), intent(in), value :: c_error
1038 type(c_ptr), intent(in), value :: c_ddx
1039 type(ddx_setup_type), pointer :: ddx_model
1040 type(ddx_error_type), pointer :: ddx_error
1041 integer(c_int), intent(in), value :: nsph, ncav, nmultipoles
1042 real(c_double), intent(in) :: multipoles(nmultipoles, nsph)
1043 real(c_double), intent(out) :: phi_cav(ncav), e_cav(3, ncav), g_cav(3, 3, ncav)
1044 integer :: mmax
1045 call c_f_pointer(c_ddx, ddx_model)
1046 call c_f_pointer(c_error, ddx_error)
1047 mmax = int(sqrt(dble(nmultipoles)) - 1d0)
1048 call multipole_electrostatics_2(ddx_model%params, ddx_model%constants, &
1049 & ddx_model%workspace, multipoles, mmax, phi_cav, e_cav, g_cav, ddx_error)
1050end
1051
1052subroutine ddx_multipole_psi(c_ddx, nbasis, nsph, nmultipoles, multipoles, psi, c_error) bind(C)
1053 type(c_ptr), intent(in), value :: c_error
1054 type(c_ptr), intent(in), value :: c_ddx
1055 type(ddx_setup_type), pointer :: ddx_model
1056 type(ddx_error_type), pointer :: ddx_error
1057 integer(c_int), intent(in), value :: nmultipoles, nsph, nbasis
1058 real(c_double), intent(in) :: multipoles(nmultipoles, nsph)
1059 real(c_double), intent(out) :: psi(nbasis, nsph)
1060 integer :: mmax
1061 call c_f_pointer(c_ddx, ddx_model)
1062 call c_f_pointer(c_error, ddx_error)
1063 mmax = int(sqrt(dble(nmultipoles)) - 1d0)
1064 call multipole_psi(ddx_model%params, multipoles, mmax, psi)
1065end
1066
1067subroutine ddx_multipole_force_terms(c_ddx, c_state, nsph, nmultipoles, multipoles, &
1068 & forces, c_error) bind(C)
1069 type(c_ptr), intent(in), value :: c_error
1070 type(c_ptr), intent(in), value :: c_ddx, c_state
1071 type(ddx_setup_type), pointer :: ddx_model
1072 type(ddx_error_type), pointer :: ddx_error
1073 type(ddx_state_type), pointer :: state
1074 integer(c_int), intent(in), value :: nmultipoles, nsph
1075 integer :: mmax
1076 real(c_double), intent(in) :: multipoles(nmultipoles, nsph)
1077 real(c_double), intent(inout) :: forces(3, nsph)
1078 call c_f_pointer(c_ddx, ddx_model)
1079 call c_f_pointer(c_error, ddx_error)
1080 call c_f_pointer(c_state, state)
1081 mmax = int(sqrt(dble(nmultipoles)) - 1d0)
1082 forces = zero
1083 call multipole_force_terms(ddx_model%params, ddx_model%constants, ddx_model%workspace, state, mmax, &
1084 & multipoles, forces, ddx_error)
1085end
1086
1087end
void ddx_get_sphere_centres(const void *ddx, int nsph, double *c_csph)
void ddx_multipole_electrostatics_2(const void *ddx, int nsph, int ncav, int nmultipoles, const double *multipoles, double *phi_cav, double *e_cav, double *g_cav, void *error)
void ddx_get_logfile(const void *ddx, char *logfile, int maxlen)
void ddx_get_cavity(const void *ddx, int ncav, double *c_ccav)
void ddx_multipole_electrostatics_0(const void *ddx, int nsph, int ncav, int nmultipoles, const double *multipoles, double *phi_cav, void *error)
void ddx_lpb_guess_adjoint(const void *ddx, void *state, double tol, void *error)
void ddx_fill_guess(const void *ddx, void *state, double tol, void *error)
void ddx_get_s(const void *state, int nbasis, int nsph, double *s)
void ddx_lpb_solvation_force_terms(const void *ddx, void *state, int nsph, int ncav, const double *g_cav, double *forces, const void *error)
void * ddx_allocate_state(const void *ddx, void *error)
void ddx_solve_adjoint(const void *ddx, void *state, double tol, void *error)
double ddx_cosmo_energy(const void *ddx, void *state, void *error)
double ddx_get_solvent_kappa(const void *ddx)
void ddx_pcm_solve_adjoint(const void *ddx, void *state, double tol, void *error)
void ddx_cosmo_solve_adjoint(const void *ddx, void *state, double tol, void *error)
int ddx_get_n_cav(const void *ddx)
int ddx_get_error_flag(const void *error)
double ddx_pcm_energy(const void *ddx, void *state, void *error)
void ddx_cosmo_guess_adjoint(const void *ddx, void *state, void *error)
void ddx_solvation_force_terms(const void *ddx, void *state, void *electrostatics, int nsph, double *forces, void *error)
void ddx_multipole_electrostatics(void *ddx, int nsph, int nmultipoles, const double *multipoles, void *electrostatics, void *error)
void ddx_pcm_setup(const void *ddx, void *state, int ncav, int nbasis, int nsph, const double *psi, const double *phi_cav, void *error)
void ddx_lpb_setup(const void *ddx, void *state, int ncav, int nbasis, int nsph, const double *psi, const double *phi_cav, const double *e_cav, void *error)
void ddx_cosmo_setup(const void *ddx, void *state, int ncav, int nbasis, int nsph, const double *psi, const double *phi_cav, void *error)
void ddx_pcm_guess_adjoint(const void *ddx, void *state, void *error)
int ddx_get_n_lebedev(const void *ddx)
double ddx_get_solvent_epsilon(const void *ddx)
void ddx_get_error_message(const void *error, char *message, int maxlen)
int ddx_get_n_proc(const void *ddx)
void ddx_multipole_psi(const void *ddx, int nbasis, int nsph, int nmultipoles, const double *multipoles, double *psi, void *error)
void ddx_cosmo_guess(const void *ddx, void *state, void *error)
int ddx_get_n_spheres(const void *ddx)
void ddx_get_zeta_dip(const void *state, const void *ddx, int ncav, double *zeta_dip)
int ddx_get_s_niter(const void *state)
void ddx_get_banner(char *banner, int maxlen)
int ddx_get_enable_fmm(const void *ddx)
int ddx_get_lmax(const void *ddx)
void ddx_get_x(const void *state, int nbasis, int nsph, double *x)
void ddx_multipole_force_terms(const void *ddx, void *state, int nsph, int nmultipoles, const double *multipoles, double *forces, void *error)
double ddx_lpb_energy(const void *ddx, void *state, void *error)
void ddx_get_xi(const void *state, const void *ddx, int ncav, double *xi)
int ddx_get_incore(const void *ddx)
int ddx_get_x_niter(const void *state)
double ddx_energy(const void *ddx, void *state, void *error)
void ddx_deallocate_electrostatics(void *electrostatics, void *error)
void ddx_deallocate_model(void *ddx, void *error)
int ddx_get_switching(const void *ddx)
void ddx_scaled_ylm(const void *ddx, int lmax, const double *x, int sphere, double *ylm)
void ddx_pcm_solvation_force_terms(const void *ddx, void *state, int nsph, int ncav, const double *e_cav, double *forces, void *error)
void ddx_setup(const void *ddx, void *state, const void *electrostatics, int nbasis, int nsph, const double *psi, void *error)
double ddx_get_eta(const void *ddx)
void ddx_cosmo_solvation_force_terms(const void *ddx, void *state, int nsph, int ncav, const double *e_cav, double *forces, void *error)
void ddx_lpb_solve(const void *ddx, void *state, double tol, void *error)
int ddx_get_maxiter(const void *ddx)
int ddx_get_enable_force(const void *ddx)
int ddx_get_model(const void *ddx)
double ddx_get_shift(const void *ddx)
double ddx_ddrun(const void *ddx, void *state, void *electrostatics, int nbasis, int nsph, double *psi, const double tol, double *forces, int read_guess, void *error)
int ddx_supported_lebedev_grids(int maxlen, int *grids)
void ddx_deallocate_state(void *state, void *error)
int ddx_get_n_basis(const void *ddx)
void ddx_lpb_guess(const void *ddx, void *state, double tol, void *error)
void ddx_cosmo_solve(const void *ddx, void *state, double tol, void *error)
void * ddx_allocate_model(int model, int enable_force, double solvent_epsilon, double solvent_kappa, double eta, double shift, int lmax, int n_lebedev, int incore, int maxiter, int jacobi_n_diis, int enable_fmm, int fmm_multipole_lmax, int fmm_local_lmax, int n_proc, int n_spheres, const double *sphere_centres, const double *sphere_radii, int length_logfile, const char *logfile, int switching, void *error)
void ddx_lpb_solve_adjoint(const void *ddx, void *state, double tol, void *error)
void ddx_get_sphere_radii(const void *ddx, int nsph, double *c_rsph)
void * ddx_allocate_error()
void ddx_fill_guess_adjoint(const void *ddx, void *state, double tol, void *error)
void * ddx_allocate_electrostatics(void *ddx, void *error)
int ddx_get_jacobi_n_diis(const void *ddx)
void ddx_pcm_guess(const void *ddx, void *state, void *error)
void ddx_solve(const void *ddx, void *state, double tol, void *error)
void ddx_pcm_solve(const void *ddx, void *state, double tol, void *error)
int ddx_get_fmm_multipole_lmax(const void *ddx)
int ddx_get_fmm_local_lmax(const void *ddx)
void ddx_multipole_electrostatics_1(const void *ddx, int nsph, int ncav, int nmultipoles, const double *multipoles, double *phi_cav, double *e_cav, void *error)
High-level module of the ddX software.
Definition: ddx.f90:2