Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor geometry optimization (part 1) #947

Merged
merged 2 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 62 additions & 37 deletions src/geoopt_driver.f90
Original file line number Diff line number Diff line change
Expand Up @@ -18,66 +18,81 @@
module xtb_geoopt
contains

!> wrapper for relaxation engines
!> more info: https://xtb-docs.readthedocs.io/en/latest/optimization.html
subroutine geometry_optimization &
& (env,mol,wfn,calc,egap,et,maxiter,maxcycle_in,etot,g,sigma, &
& tight,pr,initial_sp,fail)

use xtb_mctc_accuracy, only : wp
use xtb_mctc_io, only : stdout

use xtb_type_molecule
use xtb_type_restart
use xtb_type_calculator
use xtb_type_data

use xtb_optimizer
use xtb_relaxation_engine
use xtb_single

use xtb_setparam

! Declaration section
implicit none

character(len=*), parameter :: source = 'xtb_geoopt'

!> Dummy-argument list
!> instace of polymorphic calculatior
class(TCalculator), intent(inout) :: calc
!! instance of calculatior

!> calculation environment
type(TEnvironment), intent(inout) :: env
!! calculation environment

!> molecular data information
type(TMolecule), intent(inout) :: mol
!! molecular information

!> wavefunction
type(TRestart),intent(inout) :: wfn
!! wavefunction

!> optimization level
integer, intent(in) :: tight
!! optimization level

!> max number of SCC cycles
integer, intent(in) :: maxiter
!! max number of SCC cycles

!> max number of optimization cycles
integer, intent(in) :: maxcycle_in
!! max number of optimization cycles

!> total energy
real(wp),intent(inout) :: etot
!! total energy

!> electronic temperature
real(wp),intent(in) :: et
!! electronic temprature

!> HOMO-LUMO gap
real(wp),intent(inout) :: egap
!! HOMO-LUMO gap

!> gradients
real(wp),intent(inout) :: g(3,mol%n)
!! gradients

!> strain derivatives
real(wp),intent(inout) :: sigma(3,3)
!! strain derivatives

!> internal printlevel
logical, intent(in) :: pr
!! printlevel

!> optimization convergence
logical, intent(out) :: fail
!! true-> optimization not converged

!> perform initial single point
logical, intent(in) :: initial_sp
!! true-> perform initial single point

!> Local variables
type(scc_results) :: res
logical :: final_sp, exitRun
integer :: printlevel
integer :: ilog

!----------------!
! Initialization !
!----------------!

final_sp = pr

if (pr) then
Expand All @@ -88,10 +103,9 @@ subroutine geometry_optimization &
printlevel = 0
endif

!> create optimization log file
! create/open optimization log !
if (.not.allocated(set%opt_logfile)) then
call open_file(ilog,'xtbopt.log','w')
!! default
else
if (set%opt_logfile == '-') then
ilog = stdout
Expand All @@ -102,36 +116,46 @@ subroutine geometry_optimization &
endif
endif

! create ONIOM optimization logs for low & high methods !
if (set%oniom_settings%logs) then
call open_file(set%oniom_settings%ilog1,"low.inner_region.log",'w')
call open_file(set%oniom_settings%ilog2,"high.inner_region.log",'w')
endif

call mol%update
!! update interatomic and minimum image(periodic) distances
call mol%update ! update interatomic and minimum image (periodic) distances

!-------------!
! Calculation !
!-------------!

if (initial_sp) call singlepoint &
&(env,mol,wfn,calc, &
& egap,et,maxiter,printlevel-1,.false.,.false.,1.0_wp,etot,g,sigma,res)

!> actual calculation
select case(set%opt_engine)
case(p_engine_rf)
case(p_engine_rf) ! ANCopt !
call ancopt &
&(env,ilog,mol,wfn,calc, &
& egap,et,maxiter,maxcycle_in,etot,g,sigma,tight,pr,fail)
final_sp = .true.
!! required since ANCopt might perform an untracked displacement
final_sp = .true. ! required since ANCopt might perform an untracked displacement

case(p_engine_lbfgs)
call l_ancopt &
call l_ancopt & ! L-ANCopt !
&(env,ilog,mol,wfn,calc, &
& tight,maxcycle_in,etot,egap,g,sigma,printlevel,fail)

case(p_engine_inertial)
call fire &
call fire & ! FIRE !
&(env,ilog,mol,wfn,calc, &
& tight,maxcycle_in,etot,egap,g,sigma,printlevel,fail)

end select


!-----------------!
! Post-processing !
!-----------------!

! check convergence !
if (pr) then
if (fail) then
call touch_file('NOT_CONVERGED')
Expand All @@ -141,14 +165,14 @@ subroutine geometry_optimization &
endif
end if

call env%check(exitRun)
!! check if any errors occur
call env%check(exitRun) ! error check

if (exitRun) then
call env%rescue("Trying to recover from failed geometry optimization", source)
fail = .true.
end if

! print fine details of optimized geometry !
if (pr.and.set%pr_finalstruct) then
write(env%unit,'(''================'')')
write(env%unit,*) 'final structure:'
Expand All @@ -157,17 +181,18 @@ subroutine geometry_optimization &
endif
if (pr.and.set%pr_geosum) call geosum(mol%n,mol%at,mol%xyz)

!> usually final SP is performed for all three engines
! final SP (usually for all engines) !
if (final_sp) then
if (pr) call generic_header(env%unit,'Final Singlepoint',49,10)
call singlepoint &
&(env,mol,wfn,calc, &
& egap,et,maxiter,printlevel,.false.,.false.,1.0_wp,etot,g,sigma,res)
endif

if (ilog .ne.stdout) call close_file(ilog)
!! close log file if it is not printed out on stdout
! close log file !
if (ilog.ne.stdout) call close_file(ilog)

! close ONIOM optlogs !
if (set%oniom_settings%logs) then
call close_file(set%oniom_settings%ilog1)
call close_file(set%oniom_settings%ilog2)
Expand Down
4 changes: 3 additions & 1 deletion src/optimizer.f90
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,9 @@ subroutine ancopt(env,ilog,mol,chk,calc, &
character(len=*),parameter :: chrfmt = &
'(10x,":",3x,a,a18, 10x,":")'


! Print ANCopt header !
call ancopt_header(env%unit,set%veryverbose)

if(mol%n.eq.1) return
!! do not optimize for 1 molecule
if (profile) call timer%new(8,.false.)
Expand Down
27 changes: 12 additions & 15 deletions src/prog/main.F90
Original file line number Diff line number Diff line change
Expand Up @@ -690,33 +690,29 @@ subroutine xtbMain(env, argParser)
endif


! ------------------------------------------------------------------------
!> Geometry optimization(ANCopt,L_ANCopt,FIRE)
! ------------------------------------------------------------------------
if ((set%runtyp.eq.p_run_opt).or.(set%runtyp.eq.p_run_ohess).or. &
& (set%runtyp.eq.p_run_omd).or.(set%runtyp.eq.p_run_screen).or. &
& (set%runtyp.eq.p_run_metaopt)) then
!---------------------------------------------!
! Geometry optimization(ANCopt,L_ANCopt,FIRE) !
!---------------------------------------------!
if (anyopt) then

if (set%opt_engine.eq.p_engine_rf) &
call ancopt_header(env%unit,set%veryverbose)
!! Print ANCopt header

! start optimization timer !
call start_timing(3)
!! the system_clock and cpu_time calls for the optimization start

! calculation !
call geometry_optimization &
& (env, mol,chk,calc, &
& egap,set%etemp,set%maxscciter,set%optset%maxoptcycle,etot,g,sigma,set%optset%optlev,.true.,.false.,murks)
!! Optimization

!> write results
! save results !
res%e_total = etot
res%gnorm = norm2(g)

! constrained optimization !
if (nscan.gt.0) then
call relaxed_scan(env,mol,chk,calc)
endif

!> if geo opt fails -> xtblast file
! in case of failure cretae xtblast geometry !
if (murks) then
call generateFileName(tmpname, 'xtblast', extension, mol%ftype)
write(env%unit,'(/,a,1x,a,/)') &
Expand All @@ -727,8 +723,9 @@ subroutine xtbMain(env, argParser)
call env%terminate("Geometry optimization failed")
end if

! stop optimization timer !
call stop_timing(3)
!! the system_clock and cpu_time calls for the optimization end

endif


Expand Down
Loading