25subroutine mkrhs(params, constants, workspace, phi_flag, phi_cav, grad_flag, &
26 & gradphi_cav, hessian_flag, hessianphi_cav, psi, charges)
29 type(ddx_params_type),
intent(in) :: params
30 type(ddx_workspace_type),
intent(inout) :: workspace
31 type(ddx_constants_type),
intent(in) :: constants
32 integer,
intent(in) :: phi_flag, grad_flag, hessian_flag
33 real(dp),
intent(out) :: phi_cav(constants % ncav)
34 real(dp),
intent(out) :: gradphi_cav(3, constants % ncav)
35 real(dp),
intent(out) :: hessianphi_cav(3, 3, constants % ncav)
36 real(dp),
intent(out) :: psi(constants % nbasis, &
38 real(dp),
intent(in) :: charges(params % nsph)
40 integer :: isph, igrid, icav, inode, jnear, jnode, jsph, i
41 real(dp) :: d(3), v, tmpv, r, gradv(3), hessianv(3, 3), tmpd(3)
42 real(dp),
allocatable :: grid_grad(:,:,:), grid_hessian(:,:,:,:), &
43 & grid_hessian2(:,:,:)
44 real(dp),
external :: dnrm2
46 write(6, *)
"Warning: subroutine mkrhs is deprecated"
48 if (grad_flag .eq. 1)
allocate(grid_grad(params % ngrid, 3, &
50 if (hessian_flag .eq. 1)
allocate(grid_hessian(params % ngrid, &
51 & 3, 3, params % nsph), grid_hessian2(params % ngrid, &
56 if (params % fmm .eq. 0)
then
57 do icav = 1, constants % ncav
61 do isph = 1, params % nsph
62 d = constants % ccav(:, icav) - &
63 & params % csph(:, isph)
66 tmpv = charges(isph) / r
72 tmpd = three / r * tmpd
73 hessianv(:, 1) = hessianv(:, 1) + tmpd*d(1)
74 hessianv(:, 2) = hessianv(:, 2) + tmpd*d(2)
75 hessianv(:, 3) = hessianv(:, 3) + tmpd*d(3)
76 hessianv(1, 1) = hessianv(1, 1) - tmpv
77 hessianv(2, 2) = hessianv(2, 2) - tmpv
78 hessianv(3, 3) = hessianv(3, 3) - tmpv
80 if (phi_flag .eq. 1)
then
83 if (grad_flag .eq. 1)
then
84 gradphi_cav(:, icav) = gradv
86 if (hessian_flag .eq. 1)
then
87 hessianphi_cav(:, :, icav) = hessianv
93 do isph = 1, params % nsph
94 inode = constants % snode(isph)
95 workspace % tmp_sph(1, isph) = &
97 & / params % rsph(isph) / sqrt4pi
98 workspace % tmp_sph(2:, isph) = zero
99 workspace % tmp_node_m(1, inode) = &
100 & workspace % tmp_sph(1, isph)
101 workspace % tmp_node_m(2:, inode) = zero
106 & workspace % tmp_node_m)
109 & workspace % tmp_node_m, workspace % tmp_node_l)
112 & workspace % tmp_node_l)
114 call tree_l2p(params, constants, one, &
115 & workspace % tmp_node_l, zero, &
116 & workspace % tmp_grid, workspace % tmp_sph_l)
119 & params % lmax, one, workspace % tmp_sph, &
120 & one, workspace % tmp_grid)
123 call dgemm(
'T',
'N', params % ngrid, params % nsph, &
124 & constants % nbasis, one, constants % vgrid2, &
125 & constants % vgrid_nbasis, workspace % tmp_sph, &
126 & constants % nbasis, one, workspace % tmp_grid, &
130 if (phi_flag.eq.1)
then
132 do isph = 1, params % nsph
133 do igrid = 1, params % ngrid
135 if(constants % ui(igrid, isph) .eq. zero) cycle
137 phi_cav(icav) = workspace % tmp_grid(igrid, isph)
144 if (grad_flag.eq.1 .or. hessian_flag.eq.1)
then
145 if (grad_flag.eq.1) grid_grad(:, :, :) = zero
146 if (hessian_flag.eq.1) grid_hessian(:, :, :, :) = zero
151 do isph = 1, params % nsph
153 do igrid = 1, params % ngrid
154 if(constants % ui(igrid, isph) .eq. zero) cycle
157 inode = constants % snode(isph)
158 do jnear = constants % snear(inode), &
159 & constants % snear(inode+1) - 1
162 jnode = constants % near(jnear)
163 jsph = constants % order( &
164 & constants % cluster(1, jnode))
165 d = params % csph(:, isph) + &
166 & constants % cgrid(:, igrid) &
167 & *params % rsph(isph) &
168 & - params % csph(:, jsph)
170 r = sqrt(d(1)*d(1) + d(2)*d(2) + d(3)*d(3))
172 tmpv = charges(jsph) / r
173 if (grad_flag.eq.1) grid_grad(igrid, :, isph) = &
174 & grid_grad(igrid, :, isph) - tmpv * d
175 tmpd = three * tmpv * d
177 if (hessian_flag.eq.1)
then
178 grid_hessian(igrid, 1, :, isph) = &
179 & grid_hessian(igrid, 1, :, isph) + d(1)*tmpd
180 grid_hessian(igrid, 2, :, isph) = &
181 & grid_hessian(igrid, 2, :, isph) + d(2)*tmpd
182 grid_hessian(igrid, 3, :, isph) = &
183 & grid_hessian(igrid, 3, :, isph) + d(3)*tmpd
184 grid_hessian(igrid, 1, 1, isph) = &
185 & grid_hessian(igrid, 1, 1, isph) - tmpv
186 grid_hessian(igrid, 2, 2, isph) = &
187 & grid_hessian(igrid, 2, 2, isph) - tmpv
188 grid_hessian(igrid, 3, 3, isph) = &
189 & grid_hessian(igrid, 3, 3, isph) - tmpv
197 if ((params % pl .gt. 0) .and. (grad_flag.eq.1))
then
200 & workspace % tmp_node_l, &
201 & workspace % tmp_sph_l_grad, &
202 & workspace % tmp_sph_l)
205 call dgemm(
'T',
'N', params % ngrid, &
206 & 3*params % nsph, (params % pl)**2, &
207 & -one, constants % vgrid2, &
208 & constants % vgrid_nbasis, &
209 & workspace % tmp_sph_l_grad, &
210 & (params % pl+1)**2, one, grid_grad, &
214 if ((params % pl .gt. 1) .and. (hessian_flag.eq.1))
then
219 do isph = 1, params % nsph
220 inode = constants % snode(isph)
221 workspace % tmp_node_l(:, inode) = &
222 & workspace % tmp_sph_l_grad(:, i, isph)
229 & workspace % tmp_node_l, &
230 & workspace % tmp_sph_l_grad2, &
231 & workspace % tmp_sph_l)
233 call dgemm(
'T',
'N', params % ngrid, &
234 & 3*params % nsph, (params % pl-1)**2, &
235 & one, constants % vgrid2, &
236 & constants % vgrid_nbasis, &
237 & workspace % tmp_sph_l_grad2, &
238 & (params % pl+1)**2, zero, grid_hessian2, &
241 grid_hessian(:, i, :, :) = grid_hessian(:, i, :, :) + grid_hessian2
247 do isph = 1, params % nsph
248 do igrid = 1, params % ngrid
249 if(constants % ui(igrid, isph) .eq. zero) cycle
251 if (grad_flag .eq. 1) gradphi_cav(:, icav) = &
252 & grid_grad(igrid, :, isph)
253 if (hessian_flag .eq. 1) hessianphi_cav(:, :, icav) = &
254 & grid_hessian(igrid, :, :, isph)
261 do isph = 1, params % nsph
262 psi(1, isph) = sqrt4pi * charges(isph)
266 if (grad_flag .eq. 1)
deallocate(grid_grad)
267 if (hessian_flag .eq. 1)
deallocate(grid_hessian, grid_hessian2)
285subroutine ddsolve_legacy(ddx_data, state, phi_cav, e_cav, hessianphi_cav, &
286 & psi, tol, esolv, force, ddx_error)
288 type(ddx_type),
intent(inout) :: ddx_data
289 type(ddx_state_type),
intent(inout) :: state
290 real(dp),
intent(in) :: phi_cav(ddx_data % constants % ncav), &
291 & e_cav(3, ddx_data % constants % ncav), &
292 & hessianphi_cav(3, ddx_data % constants % ncav), &
293 & psi(ddx_data % constants % nbasis, ddx_data % params % nsph), tol
295 real(dp),
intent(out) :: esolv, force(3, ddx_data % params % nsph)
296 type(ddx_error_type),
intent(inout) :: ddx_error
298 write(6, *)
"Warning: subroutine ddsolve_legacy is deprecated"
301 select case(ddx_data % params % model)
304 call ddcosmo(ddx_data % params, ddx_data % constants, &
305 & ddx_data % workspace, state, phi_cav, psi, e_cav, &
306 & tol, esolv, force, ddx_error)
309 call ddpcm(ddx_data % params, ddx_data % constants, &
310 & ddx_data % workspace, state, phi_cav, psi, e_cav, &
311 & tol, esolv, force, ddx_error)
314 call ddlpb(ddx_data % params, ddx_data % constants, &
315 & ddx_data % workspace, state, phi_cav, e_cav, &
316 & psi, tol, esolv, hessianphi_cav, force, ddx_error)
319 call update_error(ddx_error,
"unsupported solvation " // &
320 &
" model in the dd solver.")
323end subroutine ddsolve_legacy
342subroutine ddcosmo(params, constants, workspace, state, phi_cav, &
343 & psi, e_cav, tol, esolv, force, ddx_error)
345 type(ddx_params_type),
intent(in) :: params
346 type(ddx_constants_type),
intent(in) :: constants
347 type(ddx_workspace_type),
intent(inout) :: workspace
348 type(ddx_state_type),
intent(inout) :: state
349 real(dp),
intent(in) :: phi_cav(constants % ncav), &
350 & psi(constants % nbasis, params % nsph), tol
351 real(dp),
intent(out) :: esolv
352 real(dp),
intent(in) :: e_cav(3, constants % ncav)
353 real(dp),
intent(out),
optional :: force(3, params % nsph)
354 type(ddx_error_type),
intent(inout) :: ddx_error
356 write(6, *)
"Warning: subroutine ddcosmo is deprecated"
358 call cosmo_setup(params, constants, workspace, state, phi_cav, psi, ddx_error)
359 if (ddx_error % flag .ne. 0)
then
360 call update_error(ddx_error, &
361 &
"ddlpb: ddcosmo_setup returned an error, exiting")
364 call cosmo_guess(params, constants, workspace, state, ddx_error)
365 if (ddx_error % flag .ne. 0)
then
366 call update_error(ddx_error, &
367 &
"ddlpb: ddcosmo_guess returned an error, exiting")
370 call cosmo_solve(params, constants, workspace, state, tol, ddx_error)
371 if (ddx_error % flag .ne. 0)
then
372 call update_error(ddx_error, &
373 &
"ddlpb: ddcosmo_solve returned an error, exiting")
377 call cosmo_energy(constants, state, esolv, ddx_error)
380 if (params % force .eq. 1)
then
382 call cosmo_guess_adjoint(params, constants, workspace, state, ddx_error)
383 if (ddx_error % flag .ne. 0)
then
384 call update_error(ddx_error, &
385 &
"ddlpb: ddcosmo_guess_adjoint returned an error, exiting")
388 call cosmo_solve_adjoint(params, constants, workspace, state, tol, &
390 if (ddx_error % flag .ne. 0)
then
391 call update_error(ddx_error, &
392 &
"ddlpb: ddcosmo_guess_adjoint returned an error, exiting")
398 call cosmo_solvation_force_terms(params, constants, workspace, &
399 & state, e_cav, force, ddx_error)
420subroutine ddpcm(params, constants, workspace, state, phi_cav, &
421 & psi, e_cav, tol, esolv, force, ddx_error)
423 type(ddx_params_type),
intent(in) :: params
424 type(ddx_constants_type),
intent(in) :: constants
425 type(ddx_workspace_type),
intent(inout) :: workspace
426 type(ddx_state_type),
intent(inout) :: state
427 type(ddx_error_type),
intent(inout) :: ddx_error
428 real(dp),
intent(in) :: phi_cav(constants % ncav), &
429 & psi(constants % nbasis, params % nsph), tol
430 real(dp),
intent(out) :: esolv
431 real(dp),
intent(in) :: e_cav(3, constants % ncav)
432 real(dp),
intent(out),
optional :: force(3, params % nsph)
434 write(6, *)
"Warning: subroutine ddpcm is deprecated"
436 call pcm_setup(params, constants, workspace, state, phi_cav, psi, ddx_error)
437 if (ddx_error % flag .ne. 0)
then
438 call update_error(ddx_error, &
439 &
"ddlpb: ddpcm_setup returned an error, exiting")
442 call pcm_guess(params, constants, workspace, state, ddx_error)
443 if (ddx_error % flag .ne. 0)
then
444 call update_error(ddx_error, &
445 &
"ddlpb: ddpcm_guess returned an error, exiting")
448 call pcm_solve(params, constants, workspace, state, tol, ddx_error)
449 if (ddx_error % flag .ne. 0)
then
450 call update_error(ddx_error, &
451 &
"ddlpb: ddpcm_solve returned an error, exiting")
455 call pcm_energy(constants, state, esolv, ddx_error)
458 if (params % force .eq. 1)
then
460 call pcm_guess_adjoint(params, constants, workspace, state, ddx_error)
461 if (ddx_error % flag .ne. 0)
then
462 call update_error(ddx_error, &
463 &
"ddlpb: ddpcm_guess_adjoint returned an error, exiting")
466 call pcm_solve_adjoint(params, constants, workspace, state, &
468 if (ddx_error % flag .ne. 0)
then
469 call update_error(ddx_error, &
470 &
"ddlpb: ddpcm_guess_adjoint returned an error, exiting")
476 call pcm_solvation_force_terms(params, constants, workspace, &
477 & state, e_cav, force, ddx_error)
499subroutine ddlpb(params, constants, workspace, state, phi_cav, e_cav, &
500 & psi, tol, esolv, hessianphi_cav, force, ddx_error)
502 type(ddx_params_type),
intent(in) :: params
503 type(ddx_constants_type),
intent(inout) :: constants
504 type(ddx_workspace_type),
intent(inout) :: workspace
505 type(ddx_state_type),
intent(inout) :: state
506 real(dp),
intent(in) :: phi_cav(constants % ncav), &
507 & e_cav(3, constants % ncav), &
508 & psi( constants % nbasis, params % nsph), tol
509 real(dp),
intent(out) :: esolv
510 real(dp),
intent(out),
optional :: force(3, params % nsph)
511 real(dp),
intent(in),
optional :: hessianphi_cav(3, 3, constants % ncav)
512 type(ddx_error_type),
intent(inout) :: ddx_error
514 write(6, *)
"Warning: subroutine ddlpb is deprecated"
516 call lpb_setup(params, constants, workspace, state, phi_cav, &
517 & e_cav, psi, ddx_error)
518 if (ddx_error % flag .ne. 0)
then
519 call update_error(ddx_error, &
520 &
"ddlpb: ddlpb_setup returned an error, exiting")
523 call lpb_guess(params, constants, workspace, state, tol, ddx_error)
524 if (ddx_error % flag .ne. 0)
then
525 call update_error(ddx_error, &
526 &
"ddlpb: ddlpb_guess returned an error, exiting")
529 call lpb_solve(params, constants, workspace, state, tol, ddx_error)
530 if (ddx_error % flag .ne. 0)
then
531 call update_error(ddx_error, &
532 &
"ddlpb: ddlpb_solve returned an error, exiting")
537 call lpb_energy(constants, state, esolv, ddx_error)
540 if(params % force .eq. 1)
then
541 call lpb_guess_adjoint(params, constants, workspace, state, tol, ddx_error)
542 if (ddx_error % flag .ne. 0)
then
543 call update_error(ddx_error, &
544 &
"ddlpb: ddlpb_guess_adjoint returned an error, exiting")
547 call lpb_solve_adjoint(params, constants, workspace, state, tol, ddx_error)
548 if (ddx_error % flag .ne. 0)
then
549 call update_error(ddx_error, &
550 &
"ddlpb: ddlpb_solve_adjoint returned an error, exiting")
553 call lpb_solvation_force_terms(params, constants, workspace, &
554 & state, hessianphi_cav, force, ddx_error)
subroutine ddcosmo(params, constants, workspace, state, phi_cav, psi, e_cav, tol, esolv, force, ddx_error)
ddCOSMO solver
subroutine ddpcm(params, constants, workspace, state, phi_cav, psi, e_cav, tol, esolv, force, ddx_error)
ddPCM solver
Core routines and parameters of the ddX software.
subroutine tree_grad_l2l(params, constants, node_l, sph_l_grad, work)
TODO.
subroutine tree_l2l_rotation(params, constants, node_l)
Transfer local coefficients over a tree.
subroutine tree_m2m_rotation(params, constants, node_m)
Transfer multipole coefficients over a tree.
subroutine tree_l2p(params, constants, alpha, node_l, beta, grid_v, sph_l)
TODO.
subroutine tree_m2l_rotation(params, constants, node_m, node_l)
Transfer multipole local coefficients into local over a tree.
subroutine tree_m2p(params, constants, p, alpha, sph_m, beta, grid_v)
TODO.
Routines which are only used by the tests and should not be used by external software.
High-level module of the ddX software.