ddx 0.6.0
Libary for domain-decomposition methods for polarizable continuum models
ddx_pcm.f90
Go to the documentation of this file.
1
11
13module ddx_pcm
14! Get ddx-operators
16implicit none
17
20
21contains
22
31subroutine pcm_energy(constants, state, esolv, ddx_error)
32 implicit none
33 type(ddx_constants_type), intent(in) :: constants
34 type(ddx_state_type), intent(in) :: state
35 type(ddx_error_type), intent(inout) :: ddx_error
36 real(dp), intent(out) :: esolv
37 real(dp), external :: ddot
38 ! dummy operation on unused interface arguments
39 if (ddx_error % flag .eq. 0) continue
40 esolv = pt5*ddot(constants % n, state % xs, 1, state % psi, 1)
41end subroutine pcm_energy
42
55subroutine pcm_setup(params, constants, workspace, state, phi_cav, psi, ddx_error)
56 implicit none
57 type(ddx_params_type), intent(in) :: params
58 type(ddx_constants_type), intent(in) :: constants
59 type(ddx_workspace_type), intent(inout) :: workspace
60 type(ddx_state_type), intent(inout) :: state
61 type(ddx_error_type), intent(inout) :: ddx_error
62 real(dp), intent(in) :: phi_cav(constants % ncav)
63 real(dp), intent(in) :: psi(constants % nbasis, params % nsph)
64
65 ! dummy operation on unused interface arguments
66 if (ddx_error % flag .eq. 0) continue
67
68 call cav_to_spherical(params, constants, workspace, phi_cav, &
69 & state % phi)
70 state % phi = - state % phi
71 state % phi_cav = phi_cav
72 state % psi = psi
73end subroutine pcm_setup
74
83subroutine pcm_guess(params, constants, workspace, state, ddx_error)
84 implicit none
85 type(ddx_params_type), intent(in) :: params
86 type(ddx_constants_type), intent(in) :: constants
87 type(ddx_workspace_type), intent(inout) :: workspace
88 type(ddx_state_type), intent(inout) :: state
89 type(ddx_error_type), intent(inout) :: ddx_error
90
91 state % xs = zero
92 call prec_repsx(params, constants, workspace, state % phi, &
93 & state % phieps, ddx_error)
94
95end subroutine pcm_guess
96
105subroutine pcm_guess_adjoint(params, constants, workspace, state, ddx_error)
106 implicit none
107 type(ddx_params_type), intent(in) :: params
108 type(ddx_constants_type), intent(in) :: constants
109 type(ddx_workspace_type), intent(inout) :: workspace
110 type(ddx_state_type), intent(inout) :: state
111 type(ddx_error_type), intent(inout) :: ddx_error
112
113 state % y = zero
114 call ldm1x(params, constants, workspace, state % psi, state % s, ddx_error)
115
116end subroutine pcm_guess_adjoint
117
128subroutine pcm_solve(params, constants, workspace, state, tol, ddx_error)
129 implicit none
130 type(ddx_params_type), intent(in) :: params
131 type(ddx_constants_type), intent(in) :: constants
132 type(ddx_workspace_type), intent(inout) :: workspace
133 type(ddx_state_type), intent(inout) :: state
134 type(ddx_error_type), intent(inout) :: ddx_error
135 real(dp), intent(in) :: tol
136 ! local variables
137 real(dp) :: start_time, finish_time
138
139 call rinfx(params, constants, workspace, state % phi, state % phiinf, &
140 & ddx_error)
141
142 state % phieps_niter = params % maxiter
143 start_time = omp_get_wtime()
144 call jacobi_diis(params, constants, workspace, tol, state % phiinf, &
145 & state % phieps, state % phieps_niter, state % phieps_rel_diff, &
146 & repsx, prec_repsx, hnorm, ddx_error)
147 finish_time = omp_get_wtime()
148 state % phieps_time = finish_time - start_time
149
150 if (ddx_error % flag .ne. 0) then
151 call update_error(ddx_error, "ddpcm_solve: solver for ddPCM " // &
152 & "system did not converge, exiting")
153 return
154 end if
155
156 state % xs_niter = params % maxiter
157 start_time = omp_get_wtime()
158 call jacobi_diis(params, constants, workspace, tol, state % phieps, &
159 & state % xs, state % xs_niter, state % xs_rel_diff, lx, ldm1x, &
160 & hnorm, ddx_error)
161 finish_time = omp_get_wtime()
162 state % xs_time = finish_time - start_time
163
164 if (ddx_error % flag .ne. 0) then
165 call update_error(ddx_error, "ddpcm_solve: solver for ddCOSMO " // &
166 & "system did not converge, exiting")
167 return
168 end if
169
170end subroutine pcm_solve
171
182subroutine pcm_solve_adjoint(params, constants, workspace, state, tol, ddx_error)
183 implicit none
184 type(ddx_params_type), intent(in) :: params
185 type(ddx_constants_type), intent(in) :: constants
186 type(ddx_workspace_type), intent(inout) :: workspace
187 type(ddx_state_type), intent(inout) :: state
188 real(dp), intent(in) :: tol
189 type(ddx_error_type), intent(inout) :: ddx_error
190 ! local variables
191 real(dp) :: start_time, finish_time
192
193 state % s_niter = params % maxiter
194 start_time = omp_get_wtime()
195 call jacobi_diis(params, constants, workspace, tol, state % psi, &
196 & state % s, state % s_niter, state % s_rel_diff, lstarx, ldm1x, &
197 & hnorm, ddx_error)
198 finish_time = omp_get_wtime()
199 state % s_time = finish_time - start_time
200
201 if (ddx_error % flag .ne. 0) then
202 call update_error(ddx_error, "ddpcm_solve_adjoint: solver for ddCOSMO " // &
203 & "system did not converge, exiting")
204 return
205 end if
206
207 state % y_niter = params % maxiter
208 start_time = omp_get_wtime()
209 call jacobi_diis(params, constants, workspace, tol, state % s, state % y, &
210 & state % y_niter, state % y_rel_diff, repsstarx, prec_repsstarx, &
211 & hnorm, ddx_error)
212 finish_time = omp_get_wtime()
213 state % y_time = finish_time - start_time
214
215 if (ddx_error % flag .ne. 0) then
216 call update_error(ddx_error, "ddpcm_solve_adjoint: solver for ddPCM " // &
217 & "system did not converge, exiting")
218 return
219 end if
220
221 ! compute the real adjoint solution and store it in Q
222 state % q = state % s - fourpi/(params % eps - one)*state % y
223
224 call pcm_derivative_setup(params, constants, workspace, state)
225
226end subroutine pcm_solve_adjoint
227
239subroutine pcm_solvation_force_terms(params, constants, workspace, &
240 & state, e_cav, force, ddx_error)
241 implicit none
242 type(ddx_params_type), intent(in) :: params
243 type(ddx_constants_type), intent(in) :: constants
244 type(ddx_workspace_type), intent(inout) :: workspace
245 type(ddx_state_type), intent(inout) :: state
246 type(ddx_error_type), intent(inout) :: ddx_error
247 real(dp), intent(in) :: e_cav(3, constants % ncav)
248 real(dp), intent(out) :: force(3, params % nsph)
249
250 real(dp) :: start_time, finish_time
251 integer :: isph
252
253 ! dummy operation on unused interface arguments
254 if (ddx_error % flag .eq. 0) continue
255
256 start_time = omp_get_wtime()
257
258 call gradr(params, constants, workspace, state % g, state % ygrid, force)
259
260 do isph = 1, params % nsph
261 call contract_grad_l(params, constants, isph, state % xs, &
262 & state % sgrid, workspace % tmp_vylm(:, 1), &
263 & workspace % tmp_vdylm(:, :, 1), workspace % tmp_vplm(:, 1), &
264 & workspace % tmp_vcos(:, 1), workspace % tmp_vsin(:, 1), &
265 & force(:, isph))
266 call contract_grad_u(params, constants, isph, state % qgrid, &
267 & state % phi_grid, force(:, isph))
268 end do
269 force = - pt5 * force
270
271 call zeta_grad(params, constants, state, e_cav, force)
272
273 finish_time = omp_get_wtime()
274 state % force_time = finish_time - start_time
275
276end subroutine pcm_solvation_force_terms
277
286subroutine pcm_derivative_setup(params, constants, workspace, state)
287 type(ddx_params_type), intent(in) :: params
288 type(ddx_constants_type), intent(in) :: constants
289 type(ddx_workspace_type), intent(inout) :: workspace
290 type(ddx_state_type), intent(inout) :: state
291
292 real(dp), external :: ddot
293 integer :: icav, isph, igrid
294
295 ! dummy operation on unused interface arguments
296 if (allocated(workspace % tmp_pot)) continue
297
298 ! Get grid values of S and Y
299 call dgemm('T', 'N', params % ngrid, params % nsph, &
300 & constants % nbasis, one, constants % vgrid, constants % vgrid_nbasis, &
301 & state % s, constants % nbasis, zero, state % sgrid, params % ngrid)
302 call dgemm('T', 'N', params % ngrid, params % nsph, &
303 & constants % nbasis, one, constants % vgrid, constants % vgrid_nbasis, &
304 & state % y, constants % nbasis, zero, state % ygrid, params % ngrid)
305
306 ! Get the values of phi on the grid
307 call ddcav_to_grid_work(params % ngrid, params % nsph, constants % ncav, &
308 & constants % icav_ia, constants % icav_ja, state % phi_cav, &
309 & state % phi_grid)
310
311 state % g = - (state % phieps - state % phi)
312 state % qgrid = state % sgrid - fourpi/(params % eps - one)*state % ygrid
313
314 ! assemble the intermediate zeta: S weighted by U evaluated on the
315 ! exposed grid points.
316 icav = 0
317 do isph = 1, params % nsph
318 do igrid = 1, params % ngrid
319 if (constants % ui(igrid, isph) .ne. zero) then
320 icav = icav + 1
321 state % zeta(icav) = constants % wgrid(igrid) * &
322 & constants % ui(igrid, isph) * ddot(constants % nbasis, &
323 & constants % vgrid(1, igrid), 1, state % q(1, isph), 1)
324 end if
325 end do
326 end do
327
328end subroutine pcm_derivative_setup
329
330end module ddx_pcm
subroutine pcm_setup(params, constants, workspace, state, phi_cav, psi, ddx_error)
Given the potential at the cavity points, assemble the RHS for ddCOSMO or for ddPCM.
Definition: ddx_pcm.f90:56
subroutine pcm_guess(params, constants, workspace, state, ddx_error)
Do a guess for the primal ddPCM linear system.
Definition: ddx_pcm.f90:84
subroutine pcm_energy(constants, state, esolv, ddx_error)
Compute the ddPCM energy.
Definition: ddx_pcm.f90:32
subroutine pcm_solvation_force_terms(params, constants, workspace, state, e_cav, force, ddx_error)
Compute the solvation contribution to the ddPCM forces.
Definition: ddx_pcm.f90:241
subroutine pcm_solve(params, constants, workspace, state, tol, ddx_error)
Solve the ddPCM primal linear system.
Definition: ddx_pcm.f90:129
subroutine pcm_solve_adjoint(params, constants, workspace, state, tol, ddx_error)
Solve the ddPCM adjpint linear system.
Definition: ddx_pcm.f90:183
subroutine pcm_guess_adjoint(params, constants, workspace, state, ddx_error)
Do a guess for the adjoint ddPCM linear system.
Definition: ddx_pcm.f90:106
Operators shared among ddX methods.
subroutine repsx(params, constants, workspace, x, y, ddx_error)
Apply operator to spherical harmonics.
subroutine prec_repsstarx(params, constants, workspace, x, y, ddx_error)
Apply preconditioner for ddPCM adjoint linear system.
subroutine prec_repsx(params, constants, workspace, x, y, ddx_error)
Apply preconditioner for ddPCM primal linear system.
subroutine lx(params, constants, workspace, x, y, ddx_error)
Single layer operator matvec.
subroutine rinfx(params, constants, workspace, x, y, ddx_error)
Apply operator to spherical harmonics.
subroutine ldm1x(params, constants, workspace, x, y, ddx_error)
Diagonal preconditioning for Lx operator.
subroutine repsstarx(params, constants, workspace, x, y, ddx_error)
Apply operator to spherical harmonics.
subroutine lstarx(params, constants, workspace, x, y, ddx_error)
Adjoint single layer operator matvec.
High-level subroutines for ddpcm.
Definition: ddx_pcm.f90:13
subroutine pcm_derivative_setup(params, constants, workspace, state)
This routines precomputes the intermediates to be used in the evaluation of ddCOSMO analytical deriva...
Definition: ddx_pcm.f90:287