25subroutine ddfromfile(fname, ddx_data, tol, charges, ddx_error)
27 character(len=*),
intent(in) :: fname
28 type(ddx_type),
intent(out) :: ddx_data
29 type(ddx_error_type),
intent(inout) :: ddx_error
30 real(dp),
intent(out) :: tol
31 real(dp),
allocatable,
intent(out) :: charges(:)
33 integer :: nproc, model, lmax, ngrid, force, fmm, pm, pl, &
34 & nsph, i, matvecmem, maxiter, jacobi_ndiis, &
36 real(dp) :: eps, se, eta, kappa
37 real(dp),
allocatable :: csph(:, :), radii(:)
38 character(len=255) :: output_filename
41 open(unit=100, file=fname, form=
'formatted', access=
'sequential')
43 read(100, *) output_filename
47 call update_error(ddx_error,
"Error on the 2nd line of a config " // &
48 &
"file " // trim(fname) //
": `nproc` must be a positive " // &
53 if((model .lt. 1) .or. (model .gt. 3))
then
54 call update_error(ddx_error,
"Error on the 3rd line of a config file " // &
55 & trim(fname) //
": `model` must be an integer of a value " // &
61 call update_error(ddx_error,
"Error on the 4th line of a config file " // &
62 & trim(fname) //
": `lmax` must be a non-negative integer value.")
67 call update_error(ddx_error,
"Error on the 5th line of a config file " // &
68 & trim(fname) //
": `ngrid` must be a non-negative integer value.")
72 if(eps .lt. zero)
then
73 call update_error(ddx_error,
"Error on the 6th line of a config file " // &
74 & trim(fname) //
": `eps` must be a non-negative floating " // &
79 if((se .lt. -one) .or. (se .gt. one))
then
80 call update_error(ddx_error,
"Error on the 7th line of a config file " // &
81 & trim(fname) //
": `se` must be a floating point value in a " // &
86 if((eta .lt. zero) .or. (eta .gt. one))
then
87 call update_error(ddx_error,
"Error on the 8th line of a config file " // &
88 & trim(fname) //
": `eta` must be a floating point value " // &
89 &
"in a range [0, 1].")
93 if(kappa .lt. zero)
then
94 call update_error(ddx_error,
"Error on the 9th line of a config file " // &
95 & trim(fname) //
": `kappa` must be a non-negative floating " // &
100 read(100, *) matvecmem
101 if((matvecmem.lt. 0) .or. (matvecmem .gt. 1))
then
102 call update_error(ddx_error,
"Error on the 10th line of a config " // &
103 &
"file " // trim(fname) //
": `matvecmem` must be an " // &
104 &
"integer value of a value 0 or 1.")
108 if((tol .lt. 1d-14) .or. (tol .gt. one))
then
109 call update_error(ddx_error,
"Error on the 12th line of a config " // &
110 &
"file " // trim(fname) //
": `tol` must be a floating " // &
111 &
"point value in a range [1d-14, 1].")
115 if((maxiter .le. 0))
then
116 call update_error(ddx_error,
"Error on the 13th line of a config " // &
117 &
"file " // trim(fname) //
": `maxiter` must be a positive " // &
121 read(100, *) jacobi_ndiis
122 if((jacobi_ndiis .lt. 0))
then
123 call update_error(ddx_error,
"Error on the 14th line of a config " // &
124 &
"file " // trim(fname) //
": `jacobi_ndiis` must be a " // &
125 &
"non-negative integer value.")
129 if((force .lt. 0) .or. (force .gt. 1))
then
130 call update_error(ddx_error,
"Error on the 17th line of a config " // &
131 &
"file " // trim(fname) //
": `force` must be an integer " // &
132 "value of a value 0 or 1.")
136 if((fmm .lt. 0) .or. (fmm .gt. 1))
then
137 call update_error(ddx_error,
"Error on the 18th line of a config " // &
138 &
"file " // trim(fname) //
": `fmm` must be an integer " // &
139 &
"value of a value 0 or 1.")
144 call update_error(ddx_error,
"Error on the 19th line of a config " // &
145 &
"file " // trim(fname) //
": `pm` must be a non-negative " // &
151 call update_error(ddx_error,
"Error on the 20th line of a config " // &
152 &
"file " // trim(fname) //
": `pl` must be a non-negative " // &
158 call update_error(ddx_error,
"Error on the 21th line of a config " // &
159 &
"file " // trim(fname) //
": `nsph` must be a positive " // &
164 if (ddx_error % flag .ne. 0)
return
167 allocate(charges(nsph), csph(3, nsph), radii(nsph), stat=istatus)
168 if(istatus .ne. 0)
then
169 call update_error(ddx_error,
"Could not allocate space for " // &
170 &
"coordinates, radii and charges of atoms.")
174 read(100, *) charges(i), csph(1, i), csph(2, i), csph(3, i), radii(i)
180 radii = radii * tobohr
181 kappa = kappa / tobohr
184 call closest_supported_lebedev_grid(ngrid)
187 call ddinit(model, nsph, csph, radii, eps, ddx_data, ddx_error, &
188 & force=force, kappa=kappa, eta=eta, shift=se, lmax=lmax, &
189 & ngrid=ngrid, incore=matvecmem, maxiter=maxiter, &
190 & jacobi_ndiis=jacobi_ndiis, enable_fmm=fmm, pm=pm, pl=pl, &
191 & nproc=nproc, logfile=output_filename)
193 if (ddx_error % flag .ne. 0)
then
194 call update_error(ddx_error,
"ddinit returned an error, exiting")
198 deallocate(radii, csph, stat=istatus)
199 if(istatus .ne. 0)
then
200 call update_error(ddx_error,
"Could not deallocate space for " // &
201 &
"coordinates, radii and charges of atoms")
243subroutine ddinit(model, nsph, coords, radii, eps, ddx_data, ddx_error, &
244 & force, kappa, eta, shift, lmax, ngrid, incore, maxiter, &
245 & jacobi_ndiis, enable_fmm, pm, pl, nproc, logfile, adjoint, eps_int)
248 integer,
intent(in) :: model, nsph
249 real(dp),
intent(in) :: coords(3, nsph), radii(nsph)
250 type(ddx_type),
target,
intent(out) :: ddx_data
251 type(ddx_error_type),
intent(inout) :: ddx_error
252 real(dp),
intent(in) :: eps
255 integer,
intent(in),
optional :: force, adjoint, lmax, ngrid, incore, &
256 & maxiter, jacobi_ndiis, enable_fmm, pm, pl, nproc
257 real(dp),
intent(in),
optional :: kappa, eta, shift, eps_int
258 character(len=255),
intent(in),
optional :: logfile
261 integer :: local_force = 0
262 integer :: local_adjoint = 0
263 integer :: local_lmax = 6
264 integer :: local_ngrid = 302
265 integer :: local_incore = 0
266 integer :: local_maxiter = 100
267 integer :: local_jacobi_ndiis = 20
268 integer :: local_enable_fmm = 1
269 integer :: local_pm = 8
270 integer :: local_pl = 8
271 integer :: local_nproc = 1
272 real(dp) :: local_kappa = 0.0d0
273 real(dp) :: local_eta = 0.1d0
274 real(dp) :: local_shift
275 real(dp) :: local_eps_int = 1.0d0
276 character(len=255) :: local_logfile =
""
279 real(dp),
allocatable :: x(:), y(:), z(:)
283 if (
present(force)) local_force = force
284 if (
present(lmax)) local_lmax = lmax
285 if (
present(ngrid)) local_ngrid = ngrid
286 if (
present(incore)) local_incore = incore
287 if (
present(maxiter)) local_maxiter = maxiter
288 if (
present(jacobi_ndiis)) local_jacobi_ndiis = jacobi_ndiis
289 if (
present(enable_fmm)) local_enable_fmm = enable_fmm
290 if (
present(pm)) local_pm = pm
291 if (
present(pl)) local_pl = pl
292 if (
present(nproc)) local_nproc = nproc
293 if (
present(kappa)) local_kappa = kappa
294 if (
present(eta)) local_eta = eta
295 if (
present(logfile)) local_logfile = logfile
299 if (
present(shift))
then
310 if (
present(adjoint))
then
311 local_adjoint = adjoint
312 call update_error(ddx_error, &
313 &
"ddinit: adjoint argument is not yet supported")
316 if (
present(eps_int))
then
317 local_eps_int = eps_int
318 call update_error(ddx_error, &
319 &
"ddinit: eps_int argument is not yet supported")
323 allocate(x(nsph), y(nsph), z(nsph), stat=info)
324 if (info .ne. 0)
then
325 call update_error(ddx_error,
"ddinit: allocation failed")
332 call allocate_model(nsph, x, y, z, radii, model, local_lmax, local_ngrid, &
333 & local_force, local_enable_fmm, local_pm, local_pl, local_shift, &
334 & local_eta, eps, local_kappa, local_incore, local_maxiter, &
335 & local_jacobi_ndiis, local_nproc, local_logfile, ddx_data, ddx_error)
337 deallocate(x, y, z, stat=info)
339 call update_error(ddx_error,
"ddinit: deallocation failed")
362subroutine ddrun(ddx_data, state, electrostatics, psi, tol, esolv, &
363 & ddx_error, force, read_guess)
364 type(ddx_type),
intent(inout) :: ddx_data
365 type(ddx_state_type),
intent(inout) :: state
366 type(ddx_electrostatics_type),
intent(in) :: electrostatics
367 real(dp),
intent(in) :: psi(ddx_data % constants % nbasis, &
368 & ddx_data % params % nsph)
369 real(dp),
intent(in) :: tol
370 real(dp),
intent(out) :: esolv
371 type(ddx_error_type),
intent(inout) :: ddx_error
372 real(dp),
intent(out),
optional :: force(3, ddx_data % params % nsph)
373 logical,
intent(in),
optional :: read_guess
378 if (
present(read_guess))
then
379 do_guess = .not.read_guess
386 if ((.not.
present(force)) .and. (ddx_data % params % force .eq. 1))
then
387 call update_error(ddx_error, &
388 &
"ddrun: forces are to be computed, but the optional force" // &
389 &
" array has not been passed.")
393 call setup(ddx_data % params, ddx_data % constants, &
394 & ddx_data % workspace, state, electrostatics, psi, ddx_error)
395 if (ddx_error % flag .ne. 0)
then
396 call update_error(ddx_error,
"ddrun: setup returned an error, exiting")
402 call fill_guess(ddx_data % params, ddx_data % constants, &
403 & ddx_data % workspace, state, tol, ddx_error)
404 if (ddx_error % flag .ne. 0)
then
405 call update_error(ddx_error, &
406 &
"ddrun: fill_guess returned an error, exiting")
410 call solve(ddx_data % params, ddx_data % constants, &
411 & ddx_data % workspace, state, tol, ddx_error)
412 if (ddx_error % flag .ne. 0)
then
413 call update_error(ddx_error,
"ddrun: solve returned an error, exiting")
418 call energy(ddx_data % params, ddx_data % constants, &
419 & ddx_data % workspace, state, esolv, ddx_error)
420 if (ddx_error % flag .ne. 0)
then
421 call update_error(ddx_error,
"ddrun: energy returned an error, exiting")
426 if (ddx_data % params % force .eq. 1)
then
429 & ddx_data % workspace, state, tol, ddx_error)
430 if (ddx_error % flag .ne. 0)
then
431 call update_error(ddx_error, &
432 &
"ddrun: fill_guess_adjoint returned an error, exiting")
436 call solve_adjoint(ddx_data % params, ddx_data % constants, &
437 & ddx_data % workspace, state, tol, ddx_error)
438 if (ddx_error % flag .ne. 0)
then
439 call update_error(ddx_error, &
440 &
"ddrun: solve_adjoint returned an error, exiting")
446 if (ddx_data % params % force .eq. 1)
then
449 & ddx_data % workspace, state, electrostatics, force, ddx_error)
450 if (ddx_error % flag .ne. 0)
then
451 call update_error(ddx_error, &
452 &
"ddrun: solvation_force_terms returned an error, exiting")
471subroutine setup(params, constants, workspace, state, electrostatics, &
474 type(ddx_params_type),
intent(in) :: params
475 type(ddx_constants_type),
intent(inout) :: constants
476 type(ddx_workspace_type),
intent(inout) :: workspace
477 type(ddx_state_type),
intent(inout) :: state
478 type(ddx_electrostatics_type),
intent(in) :: electrostatics
479 real(dp),
intent(in) :: psi(constants % nbasis, params % nsph)
480 type(ddx_error_type),
intent(inout) :: ddx_error
482 if (params % model .eq. 1)
then
483 call cosmo_setup(params, constants, workspace, state, &
484 & electrostatics % phi_cav, psi, ddx_error)
485 else if (params % model .eq. 2)
then
486 call pcm_setup(params, constants, workspace, state, &
487 & electrostatics % phi_cav, psi, ddx_error)
488 else if (params % model .eq. 3)
then
489 call lpb_setup(params, constants, workspace, state, &
490 & electrostatics % phi_cav, electrostatics % e_cav, &
493 call update_error(ddx_error,
"Unknow model in setup.")
509subroutine fill_guess(params, constants, workspace, state, tol, ddx_error)
511 type(ddx_params_type),
intent(in) :: params
512 type(ddx_constants_type),
intent(inout) :: constants
513 type(ddx_workspace_type),
intent(inout) :: workspace
514 type(ddx_state_type),
intent(inout) :: state
515 real(dp),
intent(in) :: tol
516 type(ddx_error_type),
intent(inout) :: ddx_error
518 if (params % model .eq. 1)
then
519 call cosmo_guess(params, constants, workspace, state, ddx_error)
520 else if (params % model .eq. 2)
then
521 call pcm_guess(params, constants, workspace, state, ddx_error)
522 else if (params % model .eq. 3)
then
523 call lpb_guess(params, constants, workspace, state, tol, ddx_error)
525 call update_error(ddx_error,
"Unknow model in fill_guess.")
543 type(ddx_params_type),
intent(in) :: params
544 type(ddx_constants_type),
intent(inout) :: constants
545 type(ddx_workspace_type),
intent(inout) :: workspace
546 type(ddx_state_type),
intent(inout) :: state
547 real(dp),
intent(in) :: tol
548 type(ddx_error_type),
intent(inout) :: ddx_error
550 if (params % model .eq. 1)
then
552 else if (params % model .eq. 2)
then
554 else if (params % model .eq. 3)
then
557 call update_error(ddx_error,
"Unknow model in fill_guess_adjoint.")
573subroutine solve(params, constants, workspace, state, tol, ddx_error)
575 type(ddx_params_type),
intent(in) :: params
576 type(ddx_constants_type),
intent(inout) :: constants
577 type(ddx_workspace_type),
intent(inout) :: workspace
578 type(ddx_state_type),
intent(inout) :: state
579 real(dp),
intent(in) :: tol
580 type(ddx_error_type),
intent(inout) :: ddx_error
582 if (params % model .eq. 1)
then
583 call cosmo_solve(params, constants, workspace, state, tol, ddx_error)
584 else if (params % model .eq. 2)
then
585 call pcm_solve(params, constants, workspace, state, tol, ddx_error)
586 else if (params % model .eq. 3)
then
587 call lpb_solve(params, constants, workspace, state, tol, ddx_error)
589 call update_error(ddx_error,
"Unknow model in solve.")
605subroutine solve_adjoint(params, constants, workspace, state, tol, ddx_error)
607 type(ddx_params_type),
intent(in) :: params
608 type(ddx_constants_type),
intent(inout) :: constants
609 type(ddx_workspace_type),
intent(inout) :: workspace
610 type(ddx_state_type),
intent(inout) :: state
611 real(dp),
intent(in) :: tol
612 type(ddx_error_type),
intent(inout) :: ddx_error
614 if (params % model .eq. 1)
then
616 else if (params % model .eq. 2)
then
618 else if (params % model .eq. 3)
then
621 call update_error(ddx_error,
"Unknow model in solve_adjoint.")
637subroutine energy(params, constants, workspace, state, solvation_energy, ddx_error)
639 type(ddx_params_type),
intent(in) :: params
640 type(ddx_constants_type),
intent(in) :: constants
641 type(ddx_workspace_type),
intent(in) :: workspace
642 type(ddx_state_type),
intent(in) :: state
643 type(ddx_error_type),
intent(inout) :: ddx_error
644 real(dp),
intent(out) :: solvation_energy
647 if (
allocated(workspace % tmp_pot))
continue
649 if (params % model .eq. 1)
then
650 call cosmo_energy(constants, state, solvation_energy, ddx_error)
651 else if (params % model .eq. 2)
then
652 call pcm_energy(constants, state, solvation_energy, ddx_error)
653 else if (params % model .eq. 3)
then
654 call lpb_energy(constants, state, solvation_energy, ddx_error)
656 call update_error(ddx_error,
"Unknow model in energy.")
676 & state, electrostatics, force, ddx_error)
678 type(ddx_params_type),
intent(in) :: params
679 type(ddx_constants_type),
intent(in) :: constants
680 type(ddx_workspace_type),
intent(inout) :: workspace
681 type(ddx_state_type),
intent(inout) :: state
682 type(ddx_electrostatics_type),
intent(in) :: electrostatics
683 real(dp),
intent(out) :: force(3, params % nsph)
684 type(ddx_error_type),
intent(inout) :: ddx_error
686 if (params % model .eq. 1)
then
688 & state, electrostatics % e_cav, force, ddx_error)
689 else if (params % model .eq. 2)
then
691 & state, electrostatics % e_cav, force, ddx_error)
692 else if (params % model .eq. 3)
then
694 & state, electrostatics % g_cav, force, ddx_error)
696 call update_error(ddx_error,
"Unknow model in solvation_force_terms.")
subroutine ddfromfile(fname, ddx_data, tol, charges, ddx_error)
Read the configuration from ddX input file and return a ddx_data structure.
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)
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.
High-level subroutines for ddlpb.
High-level subroutines for ddpcm.
High-level module of the ddX software.