55subroutine ddinit(model, nsph, coords, radii, eps, ddx_data, ddx_error, &
56 & force, kappa, eta, shift, lmax, ngrid, incore, maxiter, &
57 & jacobi_ndiis, enable_fmm, pm, pl, nproc, logfile, adjoint, &
61 integer,
intent(in) :: model, nsph
62 real(dp),
intent(in) :: coords(3, nsph), radii(nsph)
63 type(ddx_type),
target,
intent(out) :: ddx_data
64 type(ddx_error_type),
intent(inout) :: ddx_error
65 real(dp),
intent(in) :: eps
68 integer,
intent(in),
optional :: force, adjoint, lmax, ngrid, incore, &
69 & maxiter, jacobi_ndiis, enable_fmm, pm, pl, nproc, switching
70 real(dp),
intent(in),
optional :: kappa, eta, shift, eps_int
71 character(len=255),
intent(in),
optional :: logfile
74 integer :: local_force = default_force
75 integer :: local_adjoint = default_adjoint
76 integer :: local_lmax = default_lmax
77 integer :: local_ngrid = default_ngrid
78 integer :: local_incore = default_incore
79 integer :: local_maxiter = default_maxiter
80 integer :: local_jacobi_ndiis = default_jacobi_ndiis
81 integer :: local_enable_fmm = default_enable_fmm
82 integer :: local_pm = default_pm
83 integer :: local_pl = default_pl
84 integer :: local_nproc = default_nproc
85 integer :: local_switching = default_switching
87 real(dp) :: local_kappa = default_kappa
88 real(dp) :: local_eta = default_eta
89 real(dp) :: local_shift
90 real(dp) :: local_eps_int = default_eps_int
92 character(len=255) :: local_logfile = default_logfile
95 real(dp),
allocatable :: x(:), y(:), z(:)
99 if (model.lt.1 .or. model.gt.3)
then
100 call update_error(ddx_error,
"ddinit: wrong value of `model`")
103 local_shift = default_se(model)
106 if (
present(force)) local_force = force
107 if (
present(lmax)) local_lmax = lmax
108 if (
present(ngrid)) local_ngrid = ngrid
109 if (
present(incore)) local_incore = incore
110 if (
present(maxiter)) local_maxiter = maxiter
111 if (
present(jacobi_ndiis)) local_jacobi_ndiis = jacobi_ndiis
112 if (
present(enable_fmm)) local_enable_fmm = enable_fmm
113 if (
present(pm)) local_pm = pm
114 if (
present(pl)) local_pl = pl
115 if (
present(nproc)) local_nproc = nproc
116 if (
present(kappa)) local_kappa = kappa
117 if (
present(eta)) local_eta = eta
118 if (
present(logfile)) local_logfile = logfile
119 if (
present(switching)) local_switching = switching
120 if (
present(shift)) local_shift = shift
123 if (
present(adjoint))
then
124 local_adjoint = adjoint
125 call update_error(ddx_error, &
126 &
"ddinit: adjoint argument is not yet supported")
129 if (
present(eps_int))
then
130 local_eps_int = eps_int
131 call update_error(ddx_error, &
132 &
"ddinit: eps_int argument is not yet supported")
136 allocate(x(nsph), y(nsph), z(nsph), stat=info)
137 if (info .ne. 0)
then
138 call update_error(ddx_error,
"ddinit: allocation failed")
145 call allocate_model(nsph, x, y, z, radii, model, local_lmax, local_ngrid, &
146 & local_force, local_enable_fmm, local_pm, local_pl, local_shift, &
147 & local_eta, eps, local_kappa, local_incore, local_maxiter, &
148 & local_jacobi_ndiis, local_nproc, local_logfile, local_switching, &
149 & ddx_data, ddx_error)
151 deallocate(x, y, z, stat=info)
153 call update_error(ddx_error,
"ddinit: deallocation failed")
176subroutine ddrun(ddx_data, state, electrostatics, psi, tol, esolv, &
177 & ddx_error, force, read_guess)
178 type(ddx_type),
intent(inout) :: ddx_data
179 type(ddx_state_type),
intent(inout) :: state
180 type(ddx_electrostatics_type),
intent(in) :: electrostatics
181 real(dp),
intent(in) :: psi(ddx_data % constants % nbasis, &
182 & ddx_data % params % nsph)
183 real(dp),
intent(in) :: tol
184 real(dp),
intent(out) :: esolv
185 type(ddx_error_type),
intent(inout) :: ddx_error
186 real(dp),
intent(out),
optional :: force(3, ddx_data % params % nsph)
187 logical,
intent(in),
optional :: read_guess
192 if (
present(read_guess))
then
193 do_guess = .not.read_guess
200 if ((.not.
present(force)) .and. (ddx_data % params % force .eq. 1))
then
201 call update_error(ddx_error, &
202 &
"ddrun: forces are to be computed, but the optional force" // &
203 &
" array has not been passed.")
207 call setup(ddx_data % params, ddx_data % constants, &
208 & ddx_data % workspace, state, electrostatics, psi, ddx_error)
209 if (ddx_error % flag .ne. 0)
then
210 call update_error(ddx_error,
"ddrun: setup returned an error, exiting")
216 call fill_guess(ddx_data % params, ddx_data % constants, &
217 & ddx_data % workspace, state, tol, ddx_error)
218 if (ddx_error % flag .ne. 0)
then
219 call update_error(ddx_error, &
220 &
"ddrun: fill_guess returned an error, exiting")
224 call solve(ddx_data % params, ddx_data % constants, &
225 & ddx_data % workspace, state, tol, ddx_error)
226 if (ddx_error % flag .ne. 0)
then
227 call update_error(ddx_error,
"ddrun: solve returned an error, exiting")
232 call energy(ddx_data % params, ddx_data % constants, &
233 & ddx_data % workspace, state, esolv, ddx_error)
234 if (ddx_error % flag .ne. 0)
then
235 call update_error(ddx_error,
"ddrun: energy returned an error, exiting")
240 if (ddx_data % params % force .eq. 1)
then
243 & ddx_data % workspace, state, tol, ddx_error)
244 if (ddx_error % flag .ne. 0)
then
245 call update_error(ddx_error, &
246 &
"ddrun: fill_guess_adjoint returned an error, exiting")
250 call solve_adjoint(ddx_data % params, ddx_data % constants, &
251 & ddx_data % workspace, state, tol, ddx_error)
252 if (ddx_error % flag .ne. 0)
then
253 call update_error(ddx_error, &
254 &
"ddrun: solve_adjoint returned an error, exiting")
260 if (ddx_data % params % force .eq. 1)
then
263 & ddx_data % workspace, state, electrostatics, force, ddx_error)
264 if (ddx_error % flag .ne. 0)
then
265 call update_error(ddx_error, &
266 &
"ddrun: solvation_force_terms returned an error, exiting")
285subroutine setup(params, constants, workspace, state, electrostatics, &
288 type(ddx_params_type),
intent(in) :: params
289 type(ddx_constants_type),
intent(inout) :: constants
290 type(ddx_workspace_type),
intent(inout) :: workspace
291 type(ddx_state_type),
intent(inout) :: state
292 type(ddx_electrostatics_type),
intent(in) :: electrostatics
293 real(dp),
intent(in) :: psi(constants % nbasis, params % nsph)
294 type(ddx_error_type),
intent(inout) :: ddx_error
296 if (params % model .eq. 1)
then
297 call cosmo_setup(params, constants, workspace, state, &
298 & electrostatics % phi_cav, psi, ddx_error)
299 else if (params % model .eq. 2)
then
300 call pcm_setup(params, constants, workspace, state, &
301 & electrostatics % phi_cav, psi, ddx_error)
302 else if (params % model .eq. 3)
then
303 call lpb_setup(params, constants, workspace, state, &
304 & electrostatics % phi_cav, electrostatics % e_cav, &
307 call update_error(ddx_error,
"Unknow model in setup.")
323subroutine fill_guess(params, constants, workspace, state, tol, ddx_error)
325 type(ddx_params_type),
intent(in) :: params
326 type(ddx_constants_type),
intent(inout) :: constants
327 type(ddx_workspace_type),
intent(inout) :: workspace
328 type(ddx_state_type),
intent(inout) :: state
329 real(dp),
intent(in) :: tol
330 type(ddx_error_type),
intent(inout) :: ddx_error
332 if (.not.state % rhs_done)
then
333 call update_error(ddx_error, &
334 &
"In fill_guess, the RHS is not initialized")
338 if (params % model .eq. 1)
then
339 call cosmo_guess(params, constants, workspace, state, ddx_error)
340 else if (params % model .eq. 2)
then
341 call pcm_guess(params, constants, workspace, state, ddx_error)
342 else if (params % model .eq. 3)
then
343 call lpb_guess(params, constants, workspace, state, tol, ddx_error)
345 call update_error(ddx_error,
"Unknow model in fill_guess.")
349 if (ddx_error % flag .eq. 0)
then
350 state % guess_done = .true.
351 state % solved = .false.
368 type(ddx_params_type),
intent(in) :: params
369 type(ddx_constants_type),
intent(inout) :: constants
370 type(ddx_workspace_type),
intent(inout) :: workspace
371 type(ddx_state_type),
intent(inout) :: state
372 real(dp),
intent(in) :: tol
373 type(ddx_error_type),
intent(inout) :: ddx_error
375 if (.not.state % adjoint_rhs_done)
then
376 call update_error(ddx_error, &
377 &
"In fill_guess_adjoint, the adjoint RHS is not initialized")
381 if (params % model .eq. 1)
then
383 else if (params % model .eq. 2)
then
385 else if (params % model .eq. 3)
then
388 call update_error(ddx_error,
"Unknow model in fill_guess_adjoint.")
392 if (ddx_error % flag .eq. 0)
then
393 state % adjoint_guess_done = .true.
394 state % adjoint_solved = .false.
409subroutine solve(params, constants, workspace, state, tol, ddx_error)
411 type(ddx_params_type),
intent(in) :: params
412 type(ddx_constants_type),
intent(inout) :: constants
413 type(ddx_workspace_type),
intent(inout) :: workspace
414 type(ddx_state_type),
intent(inout) :: state
415 real(dp),
intent(in) :: tol
416 type(ddx_error_type),
intent(inout) :: ddx_error
418 if (.not.state % rhs_done)
then
419 call update_error(ddx_error,
"In solve, the RHS is not initialized")
422 if (.not.(state % solved .or. state % guess_done))
then
423 call update_error(ddx_error, &
424 &
"In solve, no guess or previous solution is provided")
428 if (params % model .eq. 1)
then
429 call cosmo_solve(params, constants, workspace, state, tol, ddx_error)
430 else if (params % model .eq. 2)
then
431 call pcm_solve(params, constants, workspace, state, tol, ddx_error)
432 else if (params % model .eq. 3)
then
433 call lpb_solve(params, constants, workspace, state, tol, ddx_error)
435 call update_error(ddx_error,
"Unknow model in solve.")
439 if (ddx_error % flag .eq. 0)
then
440 state % solved = .true.
455subroutine solve_adjoint(params, constants, workspace, state, tol, ddx_error)
457 type(ddx_params_type),
intent(in) :: params
458 type(ddx_constants_type),
intent(inout) :: constants
459 type(ddx_workspace_type),
intent(inout) :: workspace
460 type(ddx_state_type),
intent(inout) :: state
461 real(dp),
intent(in) :: tol
462 type(ddx_error_type),
intent(inout) :: ddx_error
464 if (.not.state % adjoint_rhs_done)
then
465 call update_error(ddx_error, &
466 &
"In solve_adjoint, the RHS is not initialized")
469 if (.not.(state % adjoint_solved .or. state % adjoint_guess_done))
then
470 call update_error(ddx_error, &
471 &
"In solve_adjoint, no guess or previous solution is provided")
475 if (params % model .eq. 1)
then
477 else if (params % model .eq. 2)
then
479 else if (params % model .eq. 3)
then
482 call update_error(ddx_error,
"Unknow model in solve_adjoint.")
486 if (ddx_error % flag .eq. 0)
then
487 state % adjoint_solved = .true.
502subroutine energy(params, constants, workspace, state, solvation_energy, ddx_error)
504 type(ddx_params_type),
intent(in) :: params
505 type(ddx_constants_type),
intent(in) :: constants
506 type(ddx_workspace_type),
intent(in) :: workspace
507 type(ddx_state_type),
intent(in) :: state
508 type(ddx_error_type),
intent(inout) :: ddx_error
509 real(dp),
intent(out) :: solvation_energy
512 if (
allocated(workspace % tmp_pot))
continue
514 if (.not.state % solved)
then
515 call update_error(ddx_error, &
516 &
"In energy, the solution is not available.")
519 if (.not.state % adjoint_rhs_done)
then
520 call update_error(ddx_error, &
521 &
"In energy, the adjoint RHS is not initialized")
526 if (params % model .eq. 1)
then
527 call cosmo_energy(constants, state, solvation_energy, ddx_error)
528 else if (params % model .eq. 2)
then
529 call pcm_energy(constants, state, solvation_energy, ddx_error)
530 else if (params % model .eq. 3)
then
531 call lpb_energy(constants, state, solvation_energy, ddx_error)
533 call update_error(ddx_error,
"Unknow model in energy.")
553 & state, electrostatics, force, ddx_error)
555 type(ddx_params_type),
intent(in) :: params
556 type(ddx_constants_type),
intent(in) :: constants
557 type(ddx_workspace_type),
intent(inout) :: workspace
558 type(ddx_state_type),
intent(inout) :: state
559 type(ddx_electrostatics_type),
intent(in) :: electrostatics
560 real(dp),
intent(out) :: force(3, params % nsph)
561 type(ddx_error_type),
intent(inout) :: ddx_error
563 if (.not.state % solved)
then
564 call update_error(ddx_error, &
565 &
"In solvation_force_terms, the solution is not available.")
568 if (.not.state % adjoint_solved)
then
569 call update_error(ddx_error, &
570 &
"In solvation_force_terms, the adjoint solution is not available.")
573 if (.not.state % rhs_done)
then
574 call update_error(ddx_error, &
575 &
"In solvation_force_terms, the RHS is not initialized")
578 if (.not.state % adjoint_rhs_done)
then
579 call update_error(ddx_error, &
580 &
"In solvation_force_terms, the adjoint RHS is not initialized")
584 if (params % model .eq. 1)
then
586 & state, electrostatics % e_cav, force, ddx_error)
587 else if (params % model .eq. 2)
then
589 & state, electrostatics % e_cav, force, ddx_error)
590 else if (params % model .eq. 3)
then
592 & state, electrostatics % g_cav, force, ddx_error)
594 call update_error(ddx_error,
"Unknow model in solvation_force_terms.")
subroutine setup(params, constants, workspace, state, electrostatics, psi, ddx_error)
Setup the state for the different models.
subroutine fill_guess_adjoint(params, constants, workspace, state, tol, ddx_error)
Do a guess for the adjoint linear system for the different models.
subroutine solve_adjoint(params, constants, workspace, state, tol, ddx_error)
Solve the adjoint linear system for the different models.
subroutine solvation_force_terms(params, constants, workspace, state, electrostatics, force, ddx_error)
Compute the solvation terms of the forces (solute aspecific) for the different models....
subroutine fill_guess(params, constants, workspace, state, tol, ddx_error)
Do a guess for the primal linear system for the different models.
subroutine energy(params, constants, workspace, state, solvation_energy, ddx_error)
Compute the energy for the different models.
subroutine ddinit(model, nsph, coords, radii, eps, ddx_data, ddx_error, force, kappa, eta, shift, lmax, ngrid, incore, maxiter, jacobi_ndiis, enable_fmm, pm, pl, nproc, logfile, adjoint, eps_int, switching)
Wrapper to the initialization routine which supports optional arguments. This will make future mainte...
subroutine ddrun(ddx_data, state, electrostatics, psi, tol, esolv, ddx_error, force, read_guess)
Main solver routine.
subroutine solve(params, constants, workspace, state, tol, ddx_error)
Solve the primal linear system for the different models.
subroutine cosmo_guess(params, constants, workspace, state, ddx_error)
Do a guess for the primal ddCOSMO linear system.
subroutine cosmo_solve(params, constants, workspace, state, tol, ddx_error)
Solve the primal ddCOSMO linear system.
subroutine cosmo_solve_adjoint(params, constants, workspace, state, tol, ddx_error)
Solve the adjoint ddCOSMO linear system.
subroutine cosmo_solvation_force_terms(params, constants, workspace, state, e_cav, force, ddx_error)
Compute the solvation term of the forces (solute aspecific). This must be summed to the solute specif...
subroutine cosmo_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.
subroutine cosmo_guess_adjoint(params, constants, workspace, state, ddx_error)
Do a guess for the adjoint ddCOSMO linear system.
subroutine cosmo_energy(constants, state, esolv, ddx_error)
Compute the ddCOSMO energy.
subroutine lpb_solve(params, constants, workspace, state, tol, ddx_error)
Solve the ddLPB primal linear system.
subroutine lpb_energy(constants, state, esolv, ddx_error)
Compute the ddLPB energy.
subroutine lpb_setup(params, constants, workspace, state, phi_cav, e_cav, psi, ddx_error)
Given the potential and the electric field at the cavity points, assemble the RHS for ddLPB.
subroutine lpb_solve_adjoint(params, constants, workspace, state, tol, ddx_error)
Solve the adjoint ddLPB linear system.
subroutine lpb_guess_adjoint(params, constants, workspace, state, tol, ddx_error)
Do a guess for the adjoint ddLPB linear system.
subroutine lpb_guess(params, constants, workspace, state, tol, ddx_error)
Do a guess for the primal ddLPB linear system.
subroutine lpb_solvation_force_terms(params, constants, workspace, state, hessianphi_cav, force, ddx_error)
Compute the solvation terms of the forces (solute aspecific). This must be summed to the solute speci...
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.
subroutine pcm_guess(params, constants, workspace, state, ddx_error)
Do a guess for the primal ddPCM linear system.
subroutine pcm_energy(constants, state, esolv, ddx_error)
Compute the ddPCM energy.
subroutine pcm_solvation_force_terms(params, constants, workspace, state, e_cav, force, ddx_error)
Compute the solvation contribution to the ddPCM forces.
subroutine pcm_solve(params, constants, workspace, state, tol, ddx_error)
Solve the ddPCM primal linear system.
subroutine pcm_solve_adjoint(params, constants, workspace, state, tol, ddx_error)
Solve the ddPCM adjpint linear system.
subroutine pcm_guess_adjoint(params, constants, workspace, state, ddx_error)
Do a guess for the adjoint ddPCM linear system.
High-level subroutines for ddcosmo.
Module defining default parameters, for consistency between the various initialization routines.
High-level subroutines for ddlpb.
High-level subroutines for ddpcm.
High-level module of the ddX software.