Skip to content

Commit e45956f

Browse files
authored
Resolve out-of-bounds access in ONIOM (#661)
1 parent 45ea0ab commit e45956f

File tree

3 files changed

+90
-55
lines changed

3 files changed

+90
-55
lines changed

src/extern/turbomole.f90

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ subroutine singlepoint(self, env, mol, chk, printlevel, restart, &
117117
efix = 0.0_wp
118118
dipole(:) = 0.0_wp
119119

120-
call external_turbomole(mol%n,mol%at,mol%xyz,chk%wfn%nel,chk%wfn%nopen, &
120+
call external_turbomole(env,mol%n,mol%at,mol%xyz,chk%wfn%nel,chk%wfn%nopen, &
121121
& self%extcode,self%extmode,.true.,energy,gradient,results%dipole,self%lSolv)
122122

123123
call env%check(exitRun)
@@ -163,10 +163,12 @@ subroutine singlepoint(self, env, mol, chk, printlevel, restart, &
163163
endif
164164
end subroutine singlepoint
165165

166-
subroutine external_turbomole(n,at,xyz,nel,nopen,extcode,extmode,grd,eel,g,dip,lsolv)
166+
subroutine external_turbomole(env,n,at,xyz,nel,nopen,extcode,extmode,grd,eel,g,dip,lsolv)
167167
use xtb_mctc_accuracy, only : wp
168168
use xtb_setparam
169169
implicit none
170+
!> Computational environment
171+
type(TEnvironment), intent(inout) :: env
170172
integer n, at(n), nel, nopen
171173
logical grd,lsolv
172174
integer, intent(in) :: extcode, extmode
@@ -176,11 +178,26 @@ subroutine external_turbomole(n,at,xyz,nel,nopen,extcode,extmode,grd,eel,g,dip,l
176178
real(wp) eel
177179
real(wp) dip(3)
178180
character(len=255) atmp
181+
character(len=:), allocatable :: syspath, cefine
179182
logical :: cache, exist
180183

181184
cache = .false.
182185
dip=0
183186

187+
inquire(file="control", exist=exist)
188+
if (.not.exist) then
189+
call rdvar("PATH", syspath)
190+
call rdpath(syspath, "cefine", cefine, exist)
191+
if (exist) then
192+
call wrtm(n,at,xyz)
193+
call execute_command_line("exec "//cefine//" --func tpss --def2/SVP --cosmo 2.38 --d4 -sym c1 --noopt")
194+
end if
195+
end if
196+
197+
if (.not.exist) then
198+
call env%error("No 'control' file in current directory")
199+
return
200+
end if
184201

185202
! TM (RI)
186203
if(extcode.eq.1)then
@@ -194,7 +211,7 @@ subroutine external_turbomole(n,at,xyz,nel,nopen,extcode,extmode,grd,eel,g,dip,l
194211
call wrtm(n,at,xyz)
195212
if(extmode.eq.1)then
196213
call execute_command_line('exec ridft > job.last 2>> /dev/null')
197-
if(grd)call execute_command_line('exec rdgrad >> job.last 2>> /dev/null')
214+
if(grd)call execute_command_line('exec rdgrad >> job.last 2>> /dev/null ')
198215
endif
199216
call extcodeok(extcode)
200217
call rdtm(n,grd,eel,g,xyz_cached)
@@ -385,18 +402,13 @@ subroutine hessian(self, env, mol0, chk0, list, step, hess, dipgrad)
385402
real(wp), intent(inout) :: dipgrad(:, :)
386403

387404
integer :: idipd, stat
388-
type(TMolecule), allocatable :: mol
389-
type(TRestart), allocatable :: chk
390-
real(wp) :: er, el, dr(3), dl(3), sr(3, 3), sl(3, 3), egap, step2
391-
real(wp) :: t0, t1, w0, w1
392-
real(wp), allocatable :: gr(:, :), gl(:, :)
393-
type(scc_results) :: rr, rl
394405
type(TReader) :: reader
395406

396-
call wrtm(mol%n,mol%at,mol%xyz) !Overwrite coord with RAM-xyz file
407+
call wrtm(mol0%n,mol0%at,mol0%xyz) !Overwrite coord with RAM-xyz file
408+
397409
call execute_command_line('exec aoforce > job.last2>> /dev/null')
398410
call reader%open('hessian')
399-
call readHessian(env, mol, hess, reader, fileType%tmol)
411+
call readHessian(env, mol0, hess, reader, fileType%tmol)
400412
call reader%close
401413

402414
call open_file(idipd,'dipgrad','r')
@@ -405,7 +417,7 @@ subroutine hessian(self, env, mol0, chk0, list, step, hess, dipgrad)
405417
return
406418
end if
407419

408-
call read_dipgrad(idipd, mol%n, dipgrad, stat)
420+
call read_dipgrad(idipd, mol0%n, dipgrad, stat)
409421

410422
if(stat /=0 ) then
411423
call env%error('An error occurred while reading the dipolegradient', source)

src/oniom.f90

Lines changed: 57 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -208,20 +208,23 @@ subroutine singlepoint(self, env, mol, chk, printlevel, restart, energy, gradien
208208
end if
209209

210210
! Check whether the low-level calculator needs a wavefunction
211-
if (chk%wfn%nel == 0) then
211+
if (.not.allocated(chk%wfn%qsh)) then
212+
! print *, 'overwritten' - for restart
212213
select type(xtb => self%real_low)
213214
type is(TxTBCalculator)
214215
call newWavefunction(env, mol, xtb, chk)
215216
end select
216217
end if
217218

219+
218220
! Perform calculation on outer region
219221
call self%real_low%singlepoint(env, mol, chk, printlevel, restart, &
220222
& energy, gradient, sigma, hlgap, results)
221223

222224
!> check for charges
223225
call calculateCharge(self, env, mol, chk)
224226

227+
225228
!> Creating Linked atoms
226229
call self%cutbond(env, mol, chk, self%topo, inner_mol)
227230
call env%check(exitRun)
@@ -373,6 +376,8 @@ subroutine hessian(self, env, mol0, chk0, list, step, hess, dipgrad)
373376
call self%real_low%hessian(env, mol0, chk0, list, step, &
374377
& hess, dipgrad)
375378

379+
!call chk0%wfn%allocate(mol0%n,chk0%basis%nshell,chk0%real_low%basis%nao)
380+
print*,"cutbond"
376381
! Creating Linked atoms
377382
call self%cutbond(env, mol0, chk0, self%topo, mol_model)
378383
mol_model%chrg = float(self%chrg_model)
@@ -383,6 +388,7 @@ subroutine hessian(self, env, mol0, chk0, list, step, hess, dipgrad)
383388

384389
hess_model(:, :) = 0.0_wp
385390
dipgrad_model(:, :) = 0.0_wp
391+
386392
call self%model_low%hessian(env, mol_model, self%chk_low, list_model, step, &
387393
& hess_model, dipgrad_model)
388394

@@ -429,27 +435,39 @@ end subroutine writeInfo
429435

430436
subroutine cutbond(self, env, mol, chk, topo, inner_mol)
431437

438+
!> to initialize mol object
432439
use xtb_type_molecule, only: init
433440

441+
!> To get topology info from wfn
434442
use xtb_topology, only: makeBondTopology, topologyToNeighbourList
435443

444+
!> actual calculator
436445
class(TOniomCalculator), intent(in) :: self
437446

447+
!> Environment
438448
type(TEnvironment), intent(inout) :: env
439449

450+
!> Wavefunction
440451
type(TRestart), intent(in) :: chk
441452

453+
!> Molecular data storage
442454
type(TMolecule), intent(in) :: mol
443455

456+
!> Inner region geometry
444457
type(TMolecule), intent(inout) :: inner_mol
445458

459+
!> Some buffer geometry
446460
type(TMolecule) :: cash
447461

462+
!> topology info
448463
type(TTopology), allocatable, intent(inout) :: topo
449464

465+
!> neighbour lists
450466
type(TNeighbourList) :: neighList
451467

452468
integer :: i, j, n, k, pre_last,iterator
469+
470+
!> Arrays for inner region atoms and their atomic numbers
453471
integer, allocatable :: at(:), at2(:)
454472
real(wp), allocatable :: xyz(:, :), xyz2(:, :)
455473
logical :: inside
@@ -461,7 +479,6 @@ subroutine cutbond(self, env, mol, chk, topo, inner_mol)
461479
allocate (xyz2(3, size(self%idx)))
462480
allocate (at(n))
463481
allocate (xyz(3, n))
464-
allocate (bonded(2, mol%n))
465482

466483
!> Assignment of initial inner region
467484
do i = 1, size(self%idx)
@@ -471,9 +488,10 @@ subroutine cutbond(self, env, mol, chk, topo, inner_mol)
471488
xyz2(:, i) = mol%xyz(:, self%idx(i))
472489
end do
473490

491+
!> To identify bonded atoms and save them into an array + iterator
474492
select type (calc => self%real_low)
475493
type is (TGFFCalculator)
476-
bonded = calc%topo%blist
494+
bonded = calc%topo%blist !> automatic allocation
477495
iterator = size(bonded,2)
478496

479497
type is (TxTBCalculator)
@@ -483,12 +501,12 @@ subroutine cutbond(self, env, mol, chk, topo, inner_mol)
483501

484502
call topologyToNeighbourList(topo, neighList, mol) !> return neighList
485503
end if
504+
allocate (bonded(2, len(topo)))
486505
do i = 1, len(topo)
487506
bonded(:, i) = topo%list(1:2, i)
488507
end do
489-
iterator = len(topo)
508+
iterator = size(bonded,2)
490509
end select
491-
492510
!> Actual bond cutting and creating linked atom
493511
do i = 1, size(self%idx)
494512
do j = 1, iterator
@@ -509,7 +527,7 @@ subroutine cutbond(self, env, mol, chk, topo, inner_mol)
509527
call resize(at)
510528
at(pre_last + 1) = 1
511529
call resize(xyz)
512-
call coord(mol, xyz, pre_last, at(self%idx(i)), self%idx(i), bonded(2, j))
530+
call coord(mol, xyz, at(pre_last), self%idx(i), bonded(2, j))
513531
end if
514532
inside = .FALSE.
515533
else if (bonded(2, j) == self%idx(i)) then
@@ -529,61 +547,59 @@ subroutine cutbond(self, env, mol, chk, topo, inner_mol)
529547
call resize(at)
530548
at(pre_last + 1) = 1
531549
call resize(xyz)
532-
call coord(mol, xyz, pre_last, at(self%idx(i)), self%idx(i), bonded(1, j))
550+
call coord(mol, xyz, at(pre_last), self%idx(i), bonded(1, j))
533551
end if
534552
inside = .FALSE.
535553
end if
536554
end do
537555
end do
538-
539-
! call init(cash,at2,xyz2)
556+
!call init(cash,at2,xyz2)
540557
call init(inner_mol, at, xyz)
541-
! block
542-
! use xtb_io_writer
543-
! use xtb_mctc_filetypes, only : fileType
544-
! integer :: io
545-
! call open_file(io, "inner-region_without_h.xyz", "w")
546-
! call writeMolecule(cash, io, filetype%xyz)
547-
! call close_file(io)
548-
! stop
549-
! end block
558+
!block
559+
!use xtb_io_writer
560+
!use xtb_mctc_filetypes, only : fileType
561+
!integer :: io
562+
!call open_file(io, "inner-region_with_h.xyz", "w")
563+
!call writeMolecule(inner_mol, io, filetype%xyz)
564+
!call close_file(io)
565+
!stop
566+
!end block
550567

551568
end subroutine cutbond
552569

553570
subroutine new_atom(at)
554571

555572
integer, allocatable, intent(inout) :: at(:)
556-
integer, allocatable :: tmp(:)
557-
allocate (tmp(size(at) + 1))
558-
tmp(:size(at)) = at(:size(at))
573+
integer, allocatable :: tmp2(:)
574+
allocate (tmp2(size(at) + 1))
575+
tmp2(:size(at)) = at(:size(at))
559576
deallocate (at)
560-
call move_alloc(tmp, at)
577+
call move_alloc(tmp2, at)
561578

562579
end subroutine new_atom
563580

564581
subroutine new_coordinates(xyz)
565582

566-
real, allocatable, intent(inout) :: xyz(:, :)
567-
real, allocatable :: tmp(:, :)
583+
real, allocatable :: xyz(:, :)
584+
real, allocatable :: tmp1(:, :)
568585
integer :: atom_num
569586

570-
!coord_num = size(xyz,1)
571587
atom_num = size(xyz, 2)
572-
allocate (tmp(3, atom_num + 1))
573-
tmp(:, :atom_num) = xyz(:, :atom_num)
588+
allocate (tmp1(size(xyz,1), atom_num + 1))
589+
tmp1(:, :size(xyz,2)) = xyz(:, :size(xyz,2))
574590
deallocate (xyz)
575-
call move_alloc(tmp, xyz)
591+
call move_alloc(tmp1, xyz)
576592

577593
end subroutine new_coordinates
578594

579-
!call coord(neighList, xyz, pre_last, at(idx(i)), idx(i), topo%list(1,j))
580-
subroutine newcoord(mol, xyz, pre_last, at, idx1, idx2)
595+
!call coord(mol, xyz, pre_last, at(self%idx(i)), self%idx(i), bonded(1, j))
596+
subroutine newcoord(mol, xyz, at, idx1, idx2)
581597

582598
type(TMolecule), intent(in) :: mol
583599

584600
real(wp), intent(inout) :: xyz(:, :)
585601

586-
integer, intent(in) :: pre_last
602+
!integer, intent(in) :: pre_last
587603

588604
integer, intent(in) :: at, idx1, idx2
589605

@@ -614,7 +630,8 @@ subroutine newcoord(mol, xyz, pre_last, at, idx1, idx2)
614630
xyz2 = mol%xyz(:, idx2)
615631
prefactor = dist/sqrt(sum((xyz1 - xyz2)**2))
616632

617-
xyz(:, size(xyz, 2)) = xyz1 + (xyz2 - xyz1)*prefactor
633+
!> new H coordinates
634+
xyz(:, size(xyz, 2)) = xyz1 + (xyz2 - xyz1) * prefactor
618635

619636
end subroutine newcoord
620637

@@ -705,19 +722,17 @@ subroutine calculateCharge(self, env, mol, chk)
705722
charge = charge + calc%topo%qa(self%idx(i))
706723

707724
end do
708-
709-
type is (TxTBCalculator)
710-
do i = 1, size(self%idx)
725+
type is (TxTBCalculator)
726+
do i = 1, size(self%idx)
711727
charge = charge + chk%wfn%q(self%idx(i))
728+
end do
712729

713-
end do
714-
715-
class default
716-
call env%error("Not possible to calculate with external methods for real region", source)
717-
return
718-
end select
730+
class default
731+
call env%error("Not possible to calculate with external methods for real region", source)
732+
return
733+
end select
719734

720-
self%chrg_model = nint(charge)
735+
self%chrg_model = nint(charge)
721736

722737
end subroutine calculateCharge
723738

src/prog/main.F90

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ module xtb_prog_main
8585
use xtb_gfnff_convert, only : struc_convert
8686
use xtb_scan
8787
use xtb_kopt
88-
use xtb_oniom, only : oniom_input
88+
use xtb_oniom, only : oniom_input, TOniomCalculator
8989
implicit none
9090
private
9191

@@ -564,6 +564,14 @@ subroutine xtbMain(env, argParser)
564564
calc%etemp = set%etemp
565565
calc%maxiter = set%maxscciter
566566
ipeashift = calc%xtbData%ipeashift
567+
type is(TOniomCalculator)
568+
select type(xtb => calc%real_low)
569+
type is(TxTBCalculator)
570+
call chk%wfn%allocate(mol%n,xtb%basis%nshell,xtb%basis%nao)
571+
if (restart) then ! only in first run
572+
call readRestart(env,chk%wfn,'xtbrestart',mol%n,mol%at,set%gfn_method,exist,.true.)
573+
endif
574+
end select
567575
end select
568576

569577
! ========================================================================

0 commit comments

Comments
 (0)