1!! Copyright (C) 2019 N. Tancogne-Dejean 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 propagator_abst_oct_m 22 use clock_oct_m 23 use global_oct_m 24 use linked_list_oct_m 25 use messages_oct_m 26 use namespace_oct_m 27 use parser_oct_m 28 use profiling_oct_m 29 30 implicit none 31 32 private 33 public :: & 34 propagator_abst_t, & 35 propagator_step_debug_message 36 37 type, extends(linked_list_t) :: propagator_abst_t 38 private 39 40 type(list_iterator_t) :: iter 41 type(list_iterator_t) :: scf_start 42 integer :: current_ops 43 44 integer, public :: start_step 45 integer, public :: final_step 46 47 integer, public :: algo_steps 48 FLOAT, public :: dt 49 integer, public :: max_td_steps 50 51 !< Options related to predictor-corrector propagators 52 logical, public :: predictor_corrector = .false. 53 integer, public :: scf_count 54 integer, public :: max_scf_count 55 FLOAT, public :: scf_tol 56 57 logical :: step_done 58 logical, public :: inside_scf = .false. 59 60 type(clock_t), public :: clock 61 62 contains 63 ! Below are the list of operations that needs to be implemented 64 procedure :: get_td_operation => propagator_get_tdop 65 procedure :: step_is_done => propagator_step_is_done 66 procedure :: next => propagator_next 67 procedure :: rewind => propagator_rewind 68 procedure :: finished => propagator_finished 69 procedure :: save_scf_start => propagator_save_scf_start 70 procedure :: rewind_scf_loop => propagator_rewind_scf_loop 71 procedure :: parse_td_variables => propagator_parse_td_variables 72 end type propagator_abst_t 73 74 ! Known propagation operations 75 integer, public, parameter :: & 76 FINISHED = 0, & 77 VERLET_START = 1, & 78 VERLET_FINISH = 2, & 79 VERLET_UPDATE_POS = 3, & 80 VERLET_COMPUTE_ACC = 4, & 81 VERLET_COMPUTE_VEL = 5, & 82 SYNC = 6, & 83 UPDATE_INTERACTIONS = 7, & 84 START_SCF_LOOP = 8, & 85 END_SCF_LOOP = 9, & 86 STORE_CURRENT_STATUS = 10, & 87 BEEMAN_START = 11, & 88 BEEMAN_FINISH = 12, & 89 BEEMAN_PREDICT_POS = 13, & 90 BEEMAN_PREDICT_VEL = 14, & 91 BEEMAN_CORRECT_POS = 15, & 92 BEEMAN_CORRECT_VEL = 16, & 93 EXPMID_START = 17, & 94 EXPMID_FINISH = 18, & 95 EXPMID_PREDICT_DT_2 = 19, & 96 EXPMID_PREDICT_DT = 20, & 97 EXPMID_CORRECT_DT_2 = 21, & 98 UPDATE_HAMILTONIAN = 22 99 100 ! Known multisystem propagators 101 integer, public, parameter :: & 102 PROP_VERLET = 1, & 103 PROP_BEEMAN = 2, & 104 PROP_BEEMAN_SCF = 3, & 105 PROP_EXPMID = 4, & 106 PROP_EXPMID_SCF = 5 107 108 109contains 110 111 subroutine propagator_rewind(this) 112 class(propagator_abst_t), intent(inout) :: this 113 114 PUSH_SUB(propagator_rewind) 115 116 call this%iter%start(this) 117 call this%next() 118 this%step_done = .false. 119 120 POP_SUB(propagator_rewind) 121 end subroutine propagator_rewind 122 123 subroutine propagator_finished(this) 124 class(propagator_abst_t), intent(inout) :: this 125 126 PUSH_SUB(propagator_finished) 127 128 this%step_done = .true. 129 130 POP_SUB(propagator_finished) 131 end subroutine propagator_finished 132 133 subroutine propagator_next(this) 134 class(propagator_abst_t), intent(inout) :: this 135 136 PUSH_SUB(propagator_next) 137 138 select type(next_ops => this%iter%get_next()) 139 type is (integer) 140 this%current_ops = next_ops 141 class default 142 message(1) = "Corrupted list." 143 call messages_fatal(1) 144 end select 145 146 POP_SUB(propagator_next) 147 end subroutine propagator_next 148 149 integer function propagator_get_tdop(this) result(tdop) 150 class(propagator_abst_t), intent(in) :: this 151 152 PUSH_SUB(propagator_get_tdop) 153 154 tdop = this%current_ops 155 156 POP_SUB(propagator_get_tdop) 157 end function propagator_get_tdop 158 159 logical pure function propagator_step_is_done(this) result(step_is_done) 160 class(propagator_abst_t), intent(in) :: this 161 162 step_is_done = this%step_done 163 164 end function propagator_step_is_done 165 166 subroutine propagator_save_scf_start(this) 167 class(propagator_abst_t), intent(inout) :: this 168 169 PUSH_SUB(propagator_save_scf_start) 170 171 ! Save the current iteration state (START_SCF_LOOP) and move to next step 172 this%scf_start = this%iter 173 call this%next() 174 this%scf_count = 0 175 176 POP_SUB(propagator_save_scf_start) 177 178 end subroutine propagator_save_scf_start 179 180 subroutine propagator_rewind_scf_loop(this) 181 class(propagator_abst_t), intent(inout) :: this 182 183 PUSH_SUB(propagator_rewind_scf_loop) 184 185 ! Reset the iteration state to the beginning of the loop (START_SCF_LOOP) and move to next step 186 this%iter = this%scf_start 187 call this%next() 188 this%scf_count = this%scf_count + 1 189 190 POP_SUB(propagator_rewind_scf_loop) 191 192 end subroutine propagator_rewind_scf_loop 193 194 function propagator_step_debug_message(tdop) result(description) 195 integer, intent(in) :: tdop 196 character(len=100) :: description 197 198 PUSH_SUB(propagator_step_debug_message) 199 200 select case (tdop) 201 case (FINISHED) 202 description = "Propagation step finished for" 203 case (UPDATE_INTERACTIONS) 204 description = "Updating interactions for" 205 case (START_SCF_LOOP) 206 description = "Starting SCF loop for" 207 case (END_SCF_LOOP) 208 description = "End of SCF iteration for" 209 case (STORE_CURRENT_STATUS) 210 description = "Storing the current status for" 211 case (VERLET_UPDATE_POS) 212 description = "Propagation step - Updating positions for" 213 case (VERLET_COMPUTE_ACC) 214 description = "Propagation step - Computing acceleration for" 215 case (VERLET_COMPUTE_VEL) 216 description = "Propagation step - Computing velocity for" 217 case (BEEMAN_PREDICT_POS) 218 description = "Prediction step - Computing position for" 219 case (BEEMAN_PREDICT_VEL) 220 description = "Prediction step - Computing velocity for" 221 case (BEEMAN_CORRECT_POS) 222 description = "Correction step - Computing position for" 223 case (BEEMAN_CORRECT_VEL) 224 description = "Correction step - Computing velocity for" 225 case default 226 description = "Unknown step for " 227 end select 228 229 POP_SUB(propagator_step_debug_message) 230 end function propagator_step_debug_message 231 232 !-------------------------------------------------------- 233 subroutine propagator_parse_td_variables(this, namespace) 234 class(propagator_abst_t), intent(inout) :: this 235 type(namespace_t), intent(in) :: namespace 236 237 PUSH_SUB(propagator_parse_td_variables) 238 239 ! This variable is also defined (and properly documented) in td/td.F90. 240 ! This is temporary, until all the propagators are moved to the new framework. 241 call parse_variable(namespace, 'TDTimeStep', CNST(10.0), this%dt) 242 243 ! This variable is also defined (and properly documented) in td/td.F90. 244 ! This is temporary, until all the propagators are moved to the new framework. 245 call parse_variable(namespace, 'TDMaxSteps', 1000, this%max_td_steps) 246 247 POP_SUB(propagator_parse_td_variables) 248 end subroutine propagator_parse_td_variables 249 250end module propagator_abst_oct_m 251 252 253!!o, Local Variables: 254!! mode: f90 255!! coding: utf-8 256!! End: 257