Octopus
dftb.F90
Go to the documentation of this file.
1!! Copyright (C) 2020 F. Bonafé, H. Appel
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
21module dftb_oct_m
23 use debug_oct_m
24#ifdef HAVE_DFTBPLUS
25 use dftbplus
26#endif
27 use global_oct_m
31 use io_oct_m
33 use ions_oct_m
34 use, intrinsic :: iso_fortran_env
35 use lasers_oct_m
37 use mpi_oct_m
40 use parser_oct_m
46 use system_oct_m
48 use unit_oct_m
51
52 implicit none
53
54 private
55 public :: &
56 dftb_t, &
58
59 integer, parameter :: &
60 OUTPUT_COORDINATES = 1, &
62
65 type, extends(system_t) :: dftb_t
66 private
67 integer :: n_atom
68 real(real64), allocatable :: coords(:,:), gradients(:,:)
69 real(real64), allocatable :: acc(:,:)
70 real(real64), allocatable :: tot_force(:,:)
71 real(real64), allocatable :: vel(:,:)
72 real(real64), allocatable :: prev_tot_force(:,:)
73 integer, allocatable :: species(:)
74 integer :: dynamics
75 real(real64), allocatable :: mass(:)
76 real(real64), allocatable :: atom_charges(:,:)
77 character(len=LABEL_LEN), allocatable :: labels(:)
78 real(real64), allocatable :: prev_acc(:,:,:)
79 real(real64) :: scc_tolerance
80 class(ions_t), pointer :: ions => null()
81 type(c_ptr) :: output_handle(2)
82 type(ion_dynamics_t) :: ions_dyn
83 class(lasers_t), pointer :: lasers => null()
84 logical :: laser_field
85 real(real64) :: field(3)
86 real(real64) :: energy
87#ifdef HAVE_DFTBPLUS
88 type(TDftbPlus) :: dftbp
89#endif
90 contains
91 procedure :: init_interaction => dftb_init_interaction
92 procedure :: initialize => dftb_initialize
93 procedure :: do_algorithmic_operation => dftb_do_algorithmic_operation
94 procedure :: output_start => dftb_output_start
95 procedure :: output_write => dftb_output_write
96 procedure :: output_finish => dftb_output_finish
97 procedure :: is_tolerance_reached => dftb_is_tolerance_reached
98 procedure :: copy_quantities_to_interaction => dftb_copy_quantities_to_interaction
99 procedure :: init_interaction_as_partner => dftb_init_interaction_as_partner
100 procedure :: update_interactions_start => dftb_update_interactions_start
101 procedure :: restart_write_data => dftb_restart_write_data
102 procedure :: restart_read_data => dftb_restart_read_data
103 procedure :: update_kinetic_energy => dftb_update_kinetic_energy
104 final :: dftb_finalize
105 end type dftb_t
106
107 interface dftb_t
108 procedure dftb_constructor
109 end interface dftb_t
110
112 integer, parameter :: &
113 EHRENFEST = 1, &
114 bo = 2
115
116contains
117
118 ! ---------------------------------------------------------
123 function dftb_constructor(namespace, grp) result(sys)
124 class(dftb_t), pointer :: sys
125 type(namespace_t), intent(in) :: namespace
126 type(mpi_grp_t), intent(in) :: grp
127
128 push_sub(dftb_constructor)
129
130#ifndef HAVE_DFTBPLUS
131 message(1) = "DFTB+ system not available. This feature requires compiling Octopus with the DFTB+ library"
132 call messages_fatal(1, namespace=namespace)
133#endif
134
135 allocate(sys)
136
137 call dftb_init(sys, namespace, grp)
138
139 pop_sub(dftb_constructor)
140 end function dftb_constructor
141
142 ! ---------------------------------------------------------
147 ! ---------------------------------------------------------
148 subroutine dftb_init(this, namespace, grp)
149 class(dftb_t), target, intent(inout) :: this
150 type(namespace_t), intent(in) :: namespace
151 type(mpi_grp_t), intent(in) :: grp
152
153 integer :: ii, jj, ispec
154 character(len=MAX_PATH_LEN) :: slako_dir
155 character(len=1), allocatable :: max_ang_mom(:)
156 character(len=LABEL_LEN) :: this_max_ang_mom, this_label
157 integer :: n_maxang_block
158 type(block_t) :: blk
159 real(real64) :: initial_temp
161#ifdef HAVE_DFTBPLUS
162 type(tdftbplusinput) :: input
163 type(fnode), pointer :: proot, pgeo, pham, pdftb, pmaxang, pslakos, ptype2files, panalysis
164 type(fnode), pointer :: pparseropts
165 type(fnode), pointer :: pelecdyn, pperturb, plaser
166#endif
168 push_sub(dftb_init)
170 this%namespace = namespace
172 ! Currently this system does not support any interaction
173 allocate(this%supported_interactions(0))
174 allocate(this%supported_interactions_as_partner(0))
176 ! Quantities updated by the algorithm
177 call this%quantities%add(quantity_t("position", updated_on_demand = .false.))
178 call this%quantities%add(quantity_t("velocity", updated_on_demand = .false.))
180 call messages_print_with_emphasis(msg="DFTB+ System", namespace=namespace)
182 this%ions => ions_t(namespace, grp)
183 this%n_atom = this%ions%natoms
184 safe_allocate(this%coords(1:3, 1:this%n_atom))
185 safe_allocate(this%acc(1:3, 1:this%n_atom))
186 safe_allocate(this%vel(1:3, 1:this%n_atom))
187 safe_allocate(this%tot_force(1:3, 1:this%n_atom))
188 safe_allocate(this%prev_tot_force(1:3, 1:this%n_atom))
189 safe_allocate(this%gradients(1:3, 1:this%n_atom))
190 safe_allocate(this%species(1:this%n_atom))
191 safe_allocate(this%mass(1:this%n_atom))
192 safe_allocate(this%atom_charges(1:this%n_atom, 1))
193 safe_allocate(this%labels(1:this%ions%nspecies))
194 safe_allocate(max_ang_mom(1:this%ions%nspecies))
195 max_ang_mom = "s"
197 ispec = 1
198 this%species(1) = 1
199 this%labels(1) = trim(this%ions%atom(1)%label)
200
201 this%coords = this%ions%pos
202 ! mass is read from the default pseudopotential files
203 this%mass = this%ions%mass
204 do ii = 1, this%n_atom
205 if ((ii > 1) .and. .not. (any(this%labels(1:ispec) == this%ions%atom(ii)%label))) then
206 ispec = ispec + 1
207 this%labels(ispec) = trim(this%ions%atom(ii)%label)
208 end if
209 do jj = 1, ispec
210 if (trim(this%ions%atom(ii)%label) == trim(this%labels(jj))) then
211 this%species(ii) = jj
212 end if
213 end do
214 end do
215 this%vel = m_zero
216 this%tot_force = m_zero
217
218 !%Variable MaxAngularMomentum
219 !%Type block
220 !%Section DFTBPlusInterface
221 !%Description
222 !% Specifies the highest angular momentum for each atom type. All orbitals up
223 !% to that angular momentum will be included in the calculation.
224 !% Possible values for the angular momenta are s, p, d, f.
225 !% These are examples:
226 !%
227 !% <tt>%MaxAngularMomentum
228 !% <br>&nbsp;&nbsp;'O' | 'p'
229 !% <br>&nbsp;&nbsp;'H' | 's'
230 !% <br>%</tt>
231 !%End
232 n_maxang_block = 0
233 if (parse_block(namespace, 'MaxAngularMomentum', blk) == 0) then
234 n_maxang_block = parse_block_n(blk)
235 if (n_maxang_block /= this%ions%nspecies) then
236 call messages_input_error(namespace, "MaxAngularMomentum", "Wrong number of species.")
237 end if
238
239 do ii = 1, n_maxang_block
240 call parse_block_string(blk, ii-1, 0, this_label)
241 call parse_block_string(blk, ii-1, 1, this_max_ang_mom)
242 if (.not. any(["s","p","d","f"] == trim(adjustl(this_max_ang_mom)))) then
243 call messages_input_error(namespace, "MaxAngularMomentum", "Wrong maximum angular momentum for element"//trim(this_label))
244 end if
245 do jj = 1, this%ions%nspecies
246 if (trim(adjustl(this_label)) == trim(adjustl(this%labels(jj)))) then
247 max_ang_mom(jj) = trim(adjustl(this_max_ang_mom))
248 end if
249 end do
250 end do
251 end if
252 call parse_block_end(blk)
253
254 !%Variable SlakoDir
255 !%Type string
256 !%Default "./"
257 !%Section Execution::IO
258 !%Description
259 !% Folder containing the Slako files
260 !%End
261 call parse_variable(namespace, 'SlakoDir', './', slako_dir)
262
263
264 ! Dynamics variables
265
266 call ion_dynamics_init(this%ions_dyn, namespace, this%ions, .false.)
267
268 call parse_variable(namespace, 'TDDynamics', bo, this%dynamics)
269 call messages_print_var_option('TDDynamics', this%dynamics, namespace=namespace)
270 if (this%dynamics == bo) then
271 call ion_dynamics_unfreeze(this%ions_dyn)
272 end if
273
274 !%Variable InitialIonicTemperature
275 !%Type float
276 !%Default 0.0
277 !%Section DFTBPlusInterface
278 !%Description
279 !% If this variable is present, the ions will have initial velocities
280 !% velocities to the atoms following a Boltzmann distribution with
281 !% this temperature (in Kelvin). Used only if <tt>TDDynamics = Ehrenfest</tt>
282 !% and <tt>MoveIons = yes</tt>.
283 !%End
284 call parse_variable(namespace, 'InitialIonicTemperature', m_zero, initial_temp, unit = unit_kelvin)
285
286 this%lasers => lasers_t(namespace)
287 call lasers_parse_external_fields(this%lasers)
288 if (this%lasers%no_lasers > 0) then
289 this%laser_field = .true.
290 else
291 this%laser_field = .false.
292 end if
293
294#ifdef HAVE_DFTBPLUS
295 call tdftbplus_init(this%dftbp)
296
297 call this%dftbp%getEmptyInput(input)
298 call input%getRootNode(proot)
299 call setchild(proot, "Geometry", pgeo)
300 call setchildvalue(pgeo, "Periodic", .false.)
301 call setchildvalue(pgeo, "TypeNames", this%labels(1:this%ions%nspecies))
302 call setchildvalue(pgeo, "TypesAndCoordinates", reshape(this%species, [1, size(this%species)]), this%coords)
303 call setchild(proot, "Hamiltonian", pham)
304 call setchild(pham, "Dftb", pdftb)
305 call setchildvalue(pdftb, "Scc", .true.)
306
307 !%Variable SccTolerance
308 !%Type float
309 !%Section DFTBPlusInterface
310 !%Description
311 !% Self-consistent-charges convergence tolerance. Once this
312 !% tolerance has been achieved the SCC cycle will stop.
313 !%End
314 call parse_variable(namespace, 'SccTolerance', 1e-9_real64, this%scc_tolerance)
315 call messages_print_var_value('SccTolerance', this%scc_tolerance, namespace=namespace)
316 call setchildvalue(pdftb, "SccTolerance", this%scc_tolerance)
317
318 ! sub-block inside hamiltonian for the maximum angular momenta
319 call setchild(pdftb, "MaxAngularMomentum", pmaxang)
320 ! explicitly set the maximum angular momenta for the species
321 do ii = 1, this%ions%nspecies
322 call setchildvalue(pmaxang, this%labels(ii), max_ang_mom(ii))
323 end do
324
325 ! get the SK data
326 ! You should provide the skfiles as found in the external/slakos/origin/mio-1-1/ folder. These can
327 ! be downloaded with the utils/get_opt_externals script
328 call setchild(pdftb, "SlaterKosterFiles", pslakos)
329 call setchild(pslakos, "Type2FileNames", ptype2files)
330 call setchildvalue(ptype2files, "Prefix", slako_dir)
331 call setchildvalue(ptype2files, "Separator", "-")
332 call setchildvalue(ptype2files, "Suffix", ".skf")
333
334 ! set up analysis options
335 call setchild(proot, "Analysis", panalysis)
336 call setchildvalue(panalysis, "CalculateForces", .true.)
337
338 call setchild(proot, "ParserOptions", pparseropts)
339 call setchildvalue(pparseropts, "ParserVersion", 5)
340
341 if (this%dynamics == ehrenfest) then
342 call setchild(proot, "ElectronDynamics", pelecdyn)
343 call setchildvalue(pelecdyn, "IonDynamics", this%ions_dyn%is_active())
344 if (this%ions_dyn%is_active()) then
345 call setchildvalue(pelecdyn, "InitialTemperature", initial_temp)
346 end if
347
348 ! initialize with wrong arguments for the moment, will be overriden later
349 call setchildvalue(pelecdyn, "Steps", 1)
350 call setchildvalue(pelecdyn, "TimeStep", m_one)
351 call setchild(pelecdyn, "Perturbation", pperturb)
352 if (this%laser_field) then
353 call setchild(pperturb, "Laser", plaser)
354 call setchildvalue(plaser, "PolarizationDirection", [ m_one , m_zero , m_zero ])
355 call setchildvalue(plaser, "LaserEnergy", m_one)
356 call setchildvalue(pelecdyn, "FieldStrength", m_one)
357 else
358 call setchild(pperturb, "None", plaser)
359 end if
360 end if
361
362 message(1) = 'Input tree in HSD format:'
363 call messages_info(1, namespace=namespace)
364 call dumphsd(input%hsdTree, stdout)
365
366 ! initialise the DFTB+ calculator
367 call this%dftbp%setupCalculator(input)
368 call this%dftbp%setGeometry(this%coords)
369#endif
370
371 pop_sub(dftb_init)
372 end subroutine dftb_init
373
374 ! ---------------------------------------------------------
375 subroutine dftb_init_interaction(this, interaction)
376 class(dftb_t), target, intent(inout) :: this
377 class(interaction_t), intent(inout) :: interaction
378
379 push_sub(dftb_init_interaction)
380
381 select type (interaction)
382 class default
383 message(1) = "Trying to initialize an unsupported interaction by DFTB+."
384 call messages_fatal(1, namespace=this%namespace)
385 end select
387 pop_sub(dftb_init_interaction)
388 end subroutine dftb_init_interaction
389
390 ! ---------------------------------------------------------
391 subroutine dftb_initialize(this)
392 class(dftb_t), intent(inout) :: this
393
394 push_sub(dftb_initialize)
395
396#ifdef HAVE_DFTBPLUS
397 select type (algo => this%algo)
398 class is (propagator_t)
399 select case (this%dynamics)
400 case (bo)
401 call this%dftbp%getGradients(this%gradients)
402 this%tot_force = -this%gradients
403 case (ehrenfest)
404 call this%dftbp%getEnergy(this%energy)
405 call this%dftbp%initializeTimeProp(algo%dt, this%laser_field, .false.)
406 end select
407 end select
408#endif
409
410 pop_sub(dftb_initialize)
411 end subroutine dftb_initialize
412
413 ! ---------------------------------------------------------
414 logical function dftb_do_algorithmic_operation(this, operation, updated_quantities) result(done)
415 class(dftb_t), intent(inout) :: this
416 class(algorithmic_operation_t), intent(in) :: operation
417 character(len=:), allocatable, intent(out) :: updated_quantities(:)
418
419 integer :: ii, jj, il
420 type(tdf_t) :: ff, phi
421 complex(real64) :: amp, pol(3)
422 real(real64) :: time, omega
423
425 call profiling_in(trim(this%namespace%get())//":"//trim(operation%id))
426
427 select type (algo => this%algo)
428 class is (propagator_t)
429
430 done = .true.
431 select case (this%dynamics)
432 case (bo)
433 ! Born-Oppenheimer dynamics
434 select case (operation%id)
436 ! Do nothing
437
438 case (verlet_start)
439 safe_allocate(this%prev_acc(1:3, 1:this%n_atom, 1))
440 do jj = 1, this%n_atom
441 this%acc(1:3, jj) = this%tot_force(1:3, jj) / this%mass(jj)
442 end do
443
444 case (verlet_finish)
445 safe_deallocate_a(this%prev_acc)
446
447 case (verlet_update_pos)
448 do jj = 1, this%n_atom
449 this%coords(1:3, jj) = this%coords(1:3, jj) + algo%dt * this%vel(1:3, jj) &
450 + m_half * algo%dt**2 * this%acc(1:3, jj)
451 end do
452 updated_quantities = ["position"]
453
454 case (verlet_compute_acc)
455 do ii = size(this%prev_acc, dim=3) - 1, 1, -1
456 this%prev_acc(1:3, 1:this%n_atom, ii + 1) = this%prev_acc(1:3, 1:this%n_atom, ii)
457 end do
458 this%prev_acc(1:3, 1:this%n_atom, 1) = this%acc(1:3, 1:this%n_atom)
459#ifdef HAVE_DFTBPLUS
460 call this%dftbp%setGeometry(this%coords)
461 call this%dftbp%getGradients(this%gradients)
462 this%tot_force = -this%gradients
463#endif
464 do jj = 1, this%n_atom
465 this%acc(1:3, jj) = this%tot_force(1:3, jj) / this%mass(jj)
466 end do
467
468 case (verlet_compute_vel)
469 this%vel(1:3, 1:this%n_atom) = this%vel(1:3, 1:this%n_atom) &
470 + m_half * algo%dt * (this%prev_acc(1:3, 1:this%n_atom, 1) + &
471 this%acc(1:3, 1:this%n_atom))
472 updated_quantities = ["velocity"]
473
474 case default
475 done = .false.
476 end select
477
478 case (ehrenfest)
479 ! Ehrenfest dynamics
480 select case (operation%id)
482 ! Do nothing
483 case (verlet_start)
484 !Do nothing
485 case (verlet_finish)
486 !Do nothing
487 case (verlet_update_pos)
488 this%field = m_zero
489 time = this%iteration%value()
490 do il = 1, this%lasers%no_lasers
491 ! get properties of laser
492 call laser_get_f(this%lasers%lasers(il), ff)
493 call laser_get_phi(this%lasers%lasers(il), phi)
494 omega = laser_carrier_frequency(this%lasers%lasers(il))
495 pol = laser_polarization(this%lasers%lasers(il))
496 ! calculate electric field from laser
497 amp = tdf(ff, time) * exp(m_zi * (omega*time + tdf(phi, time)))
498 this%field(1:3) = this%field(1:3) + real(amp*pol(1:3), real64)
499 end do
500#ifdef HAVE_DFTBPLUS
501 call this%dftbp%setTdElectricField(this%field)
502 call this%dftbp%doOneTdStep(this%iteration%counter(), atomnetcharges=this%atom_charges, coord=this%coords,&
503 force=this%tot_force, energy=this%energy)
504#endif
505 case (verlet_compute_acc)
506 !Do nothing
507 case (verlet_compute_vel)
508 !Do nothing
509 case default
510 done = .false.
511 end select
512
513 end select
514
515 end select
516
517 call profiling_out(trim(this%namespace%get())//":"//trim(operation%id))
520
521 ! ---------------------------------------------------------
522 logical function dftb_is_tolerance_reached(this, tol) result(converged)
523 class(dftb_t), intent(in) :: this
524 real(real64), intent(in) :: tol
525
527
528 ! this routine is never called at present, no reason to be here
529 assert(.false.)
530 converged = .false.
531
534
535 ! ---------------------------------------------------------
536 subroutine dftb_output_start(this)
537 class(dftb_t), intent(inout) :: this
538
539 push_sub(dftb_output_start)
540
541 select type (algo => this%algo)
542 class is (propagator_t)
543 ! Create output handle
544 call io_mkdir('td.general', this%namespace)
545 if (mpi_world%is_root()) then
546 call write_iter_init(this%output_handle(output_coordinates), 0, algo%dt, &
547 trim(io_workpath("td.general/coordinates", this%namespace)))
548 call write_iter_init(this%output_handle(output_forces), 0, algo%dt, &
549 trim(io_workpath("td.general/forces", this%namespace)))
550 end if
551
552 ! Output info for first iteration
553 call this%output_write()
554 end select
555
556 pop_sub(dftb_output_start)
557 end subroutine dftb_output_start
558
559 ! ---------------------------------------------------------
560 subroutine dftb_output_finish(this)
561 class(dftb_t), intent(inout) :: this
562
563 push_sub(dftb_output_finish)
564
565 select type (algo => this%algo)
566 class is (propagator_t)
567 if (mpi_world%is_root()) then
568 call write_iter_end(this%output_handle(output_coordinates))
569 call write_iter_end(this%output_handle(output_forces))
570 end if
571 end select
572
573 pop_sub(dftb_output_finish)
574 end subroutine dftb_output_finish
575
576 ! ---------------------------------------------------------
577 subroutine dftb_output_write(this)
578 class(dftb_t), intent(inout) :: this
579
580 integer :: idir, iat, iout
581 character(len=50) :: aux
582 character(1) :: out_label(2)
583 real(real64) :: tmp(3)
584
585 if (.not. mpi_world%is_root()) return ! only first node outputs
586
587 push_sub(dftb_output_write)
588 call profiling_in(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
589
590 select type (algo => this%algo)
591 class is (propagator_t)
592 out_label(1) = "x"
593 out_label(2) = "f"
594
595 if (this%iteration%counter() == 0) then
596 ! header
597 do iout = 1, 2
598 call write_iter_clear(this%output_handle(iout))
599 call write_iter_string(this%output_handle(iout),'#####################################################################')
600 call write_iter_nl(this%output_handle(iout))
601 call write_iter_string(this%output_handle(iout),'# HEADER')
602 call write_iter_nl(this%output_handle(iout))
603
604 ! first line: column names
605 call write_iter_header_start(this%output_handle(iout))
606
607 do iat = 1, this%n_atom
608 do idir = 1, 3
609 write(aux, '(a1,a1,i3,a1,i3,a1)') out_label(iout),'(', iat, ',', idir, ')'
610 call write_iter_header(this%output_handle(iout), aux)
611 end do
612 end do
613 call write_iter_nl(this%output_handle(iout))
614
615 ! second line: units
616 call write_iter_string(this%output_handle(iout), '#[Iter n.]')
617 call write_iter_header(this%output_handle(iout), '[' // trim(units_abbrev(units_out%time)) // ']')
618 end do
619
620 do iat = 1, this%n_atom
621 do idir = 1, 3
622 call write_iter_header(this%output_handle(output_coordinates), '[' // trim(units_abbrev(units_out%length)) // ']')
623 call write_iter_header(this%output_handle(output_forces), '[' // trim(units_abbrev(units_out%force)) // ']')
624 end do
625 end do
626
627 do iout = 1, 2
628 call write_iter_nl(this%output_handle(iout))
629 call write_iter_string(this%output_handle(iout),'#######################################################################')
630 call write_iter_nl(this%output_handle(iout))
631 end do
632 end if
633
634 call write_iter_start(this%output_handle(output_coordinates))
635 call write_iter_start(this%output_handle(output_forces))
636
637 do iat = 1, this%n_atom
638 ! Position
639 tmp(1:3) = units_from_atomic(units_out%length, this%coords(1:3, iat))
640 call write_iter_double(this%output_handle(output_coordinates), tmp, 3)
641 ! Force
642 tmp(1:3) = units_from_atomic(units_out%force, this%tot_force(1:3, iat))
643 call write_iter_double(this%output_handle(output_forces), tmp, 3)
644 end do
645
646 call write_iter_nl(this%output_handle(output_coordinates))
647 call write_iter_nl(this%output_handle(output_forces))
648
649 end select
650
651 call profiling_out(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
652 pop_sub(dftb_output_write)
653 end subroutine dftb_output_write
654
655 ! ---------------------------------------------------------
656 subroutine dftb_init_interaction_as_partner(partner, interaction)
657 class(dftb_t), intent(in) :: partner
658 class(interaction_surrogate_t), intent(inout) :: interaction
659
661
662 select type (interaction)
663 class default
664 message(1) = "Unsupported interaction."
665 call messages_fatal(1, namespace=partner%namespace)
666 end select
667
670
671 ! ---------------------------------------------------------
672 subroutine dftb_copy_quantities_to_interaction(partner, interaction)
673 class(dftb_t), intent(inout) :: partner
674 class(interaction_surrogate_t), intent(inout) :: interaction
675
677
678 select type (interaction)
679 class default
680 message(1) = "Unsupported interaction."
681 call messages_fatal(1, namespace=partner%namespace)
682 end select
683
686
687 ! ---------------------------------------------------------
688 subroutine dftb_update_interactions_start(this)
689 class(dftb_t), intent(inout) :: this
690
692
693 ! Store previous force, as it is used as SCF criterium
694 this%prev_tot_force(1:3, 1:this%n_atom) = this%tot_force(1:3, 1:this%n_atom)
695
698
699 ! ---------------------------------------------------------
700 subroutine dftb_update_kinetic_energy(this)
701 class(dftb_t), intent(inout) :: this
702
704
705 this%kinetic_energy = m_zero
706
709
710 ! ---------------------------------------------------------
711 subroutine dftb_restart_write_data(this)
712 class(dftb_t), intent(inout) :: this
713
715
716 message(1) = "DFTB system "//trim(this%namespace%get())//" cannot write restart data."
717 call messages_warning(1, namespace=this%namespace)
718
720 end subroutine dftb_restart_write_data
722 ! ---------------------------------------------------------
723 ! this function returns true if restart data could be read
724 logical function dftb_restart_read_data(this)
725 class(dftb_t), intent(inout) :: this
726
727 push_sub(dftb_restart_read_data)
728
729 ! restarting not yet supported
730 dftb_restart_read_data = .false.
731
734
735 ! ---------------------------------------------------------
736 subroutine dftb_finalize(this)
737 type(dftb_t), intent(inout) :: this
738
739 push_sub(dftb_finalize)
740
741 safe_deallocate_a(this%coords)
742 safe_deallocate_a(this%acc)
743 safe_deallocate_a(this%vel)
744 safe_deallocate_a(this%tot_force)
745 safe_deallocate_a(this%prev_tot_force)
746 safe_deallocate_a(this%gradients)
747 safe_deallocate_a(this%species)
748 safe_deallocate_a(this%mass)
749 call ion_dynamics_end(this%ions_dyn)
750
751 deallocate(this%ions)
752
753 ! No call to safe_deallocate macro here, as it gives an ICE with gfortran
754 if (associated(this%lasers)) then
755 deallocate(this%lasers)
756 end if
757
758#ifdef HAVE_DFTBPLUS
759 call tdftbplus_destruct(this%dftbp)
760#endif
761
762 call system_end(this)
763
764 pop_sub(dftb_finalize)
765 end subroutine dftb_finalize
766
767end module dftb_oct_m
768
769!! Local Variables:
770!! mode: f90
771!! coding: utf-8
772!! End:
Prints out to iunit a message in the form: ["InputVariable" = value] where "InputVariable" is given b...
Definition: messages.F90:182
Writes to the corresponding file and adds one to the iteration. Must be called after write_iter_init(...
Definition: write_iter.F90:163
double exp(double __x) __attribute__((__nothrow__
This module implements the basic elements defining algorithms.
Definition: algorithm.F90:143
subroutine dftb_output_write(this)
Definition: dftb.F90:575
subroutine dftb_update_interactions_start(this)
Definition: dftb.F90:686
subroutine dftb_init_interaction_as_partner(partner, interaction)
Definition: dftb.F90:654
subroutine dftb_output_finish(this)
Definition: dftb.F90:558
subroutine dftb_restart_write_data(this)
Definition: dftb.F90:709
subroutine dftb_init_interaction(this, interaction)
Definition: dftb.F90:387
logical function dftb_restart_read_data(this)
Definition: dftb.F90:722
logical function dftb_do_algorithmic_operation(this, operation, updated_quantities)
Definition: dftb.F90:412
subroutine dftb_update_kinetic_energy(this)
Definition: dftb.F90:698
subroutine dftb_initialize(this)
Definition: dftb.F90:403
integer, parameter output_forces
Definition: dftb.F90:154
class(dftb_t) function, pointer dftb_constructor(namespace, grp)
The factory routine (or constructor) allocates a pointer of the corresponding type and then calls the...
Definition: dftb.F90:219
subroutine dftb_finalize(this)
Definition: dftb.F90:734
logical function dftb_is_tolerance_reached(this, tol)
Definition: dftb.F90:520
subroutine dftb_output_start(this)
Definition: dftb.F90:534
integer, parameter bo
Definition: dftb.F90:207
subroutine, public dftb_init(this, namespace, grp)
The init routine is a module level procedure This has the advantage that different classes can have d...
Definition: dftb.F90:244
subroutine dftb_copy_quantities_to_interaction(partner, interaction)
Definition: dftb.F90:670
real(real64), parameter, public m_zero
Definition: global.F90:200
complex(real64), parameter, public m_zi
Definition: global.F90:214
real(real64), parameter, public m_half
Definition: global.F90:206
real(real64), parameter, public m_one
Definition: global.F90:201
This module defines the abstract interaction_t class, and some auxiliary classes for interactions.
Definition: io.F90:116
character(len=max_path_len) function, public io_workpath(path, namespace)
construct path name from given name and namespace
Definition: io.F90:318
subroutine, public io_mkdir(fname, namespace, parents)
Definition: io.F90:361
subroutine, public ion_dynamics_unfreeze(this)
Unfreezes the ionic movement.
subroutine, public ion_dynamics_init(this, namespace, ions, symmetrize, symm)
subroutine, public ion_dynamics_end(this)
complex(real64) function, dimension(3), public laser_polarization(laser)
Definition: lasers.F90:730
subroutine, public lasers_parse_external_fields(this)
Definition: lasers.F90:246
subroutine, public laser_get_f(laser, ff)
Definition: lasers.F90:773
real(real64) function, public laser_carrier_frequency(laser)
Definition: lasers.F90:623
subroutine, public laser_get_phi(laser, phi)
Definition: lasers.F90:801
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:898
character(len=512), private msg
Definition: messages.F90:167
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:525
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:691
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:272
This module implements the multisystem debug functionality.
subroutine, public parse_block_string(blk, l, c, res, convert_to_c)
Definition: parser.F90:818
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:623
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:631
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:554
This module implements the basic propagator framework.
Definition: propagator.F90:119
character(len=algo_label_len), parameter, public store_current_status
Definition: propagator.F90:176
character(len=30), parameter, public verlet_start
character(len=30), parameter, public verlet_compute_acc
character(len=30), parameter, public verlet_update_pos
character(len=30), parameter, public verlet_finish
character(len=30), parameter, public verlet_compute_vel
This module defines the quantity_t class and the IDs for quantities, which can be exposed by a system...
Definition: quantity.F90:140
This module implements the abstract system type.
Definition: system.F90:120
subroutine, public system_end(this)
Definition: system.F90:1152
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:134
character(len=20) pure function, public units_abbrev(this)
Definition: unit.F90:225
This module defines the unit system, used for input and output.
type(unit_system_t), public units_out
type(unit_t), public unit_kelvin
For converting energies into temperatures.
Explicit interfaces to C functions, defined in write_iter_low.cc.
Definition: write_iter.F90:116
subroutine, public write_iter_header(out, string)
Definition: write_iter.F90:249
subroutine, public write_iter_string(out, string)
Definition: write_iter.F90:265
subroutine, public write_iter_init(out, iter, factor, file)
Definition: write_iter.F90:229
Descriptor of one algorithmic operation.
Definition: algorithm.F90:165
class for a tight binding
Definition: dftb.F90:160
abstract interaction class
surrogate interaction class to avoid circular dependencies between modules.
Abstract class implementing propagators.
Definition: propagator.F90:144
Systems (system_t) can expose quantities that can be used to calculate interactions with other system...
Definition: quantity.F90:173
Abstract class for systems.
Definition: system.F90:175
int true(void)
subroutine input()
Definition: vdw.F90:257