Octopus
run.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
2!! Copyright (C) 2020 M. Oliveira
3!!
4!! This program is free software; you can redistribute it and/or modify
5!! it under the terms of the GNU General Public License as published by
6!! the Free Software Foundation; either version 2, or (at your option)
7!! any later version.
8!!
9!! This program is distributed in the hope that it will be useful,
10!! but WITHOUT ANY WARRANTY; without even the implied warranty of
11!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!! GNU General Public License for more details.
13!!
14!! You should have received a copy of the GNU General Public License
15!! along with this program; if not, write to the Free Software
16!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17!! 02110-1301, USA.
18!!
19
20#include "global.h"
21
24module run_oct_m
25 use accel_oct_m
27 use casida_oct_m
28 use debug_oct_m
33 use fft_oct_m
35 use global_oct_m
40 use io_oct_m
41 use lasers_oct_m
44 use mpi_oct_m
51 use parser_oct_m
57 use kdotp_oct_m
59 use pulpo_oct_m
63 use system_oct_m
64 use td_oct_m
65#ifdef HAVE_APP_TESTS
66 use test_oct_m
67#endif
70 use unocc_oct_m
72 use vdw_oct_m
73
74 implicit none
75
76 private
77 public :: &
78 run
79
80 integer, parameter :: LR = 1, fd = 2
81
82contains
83
84 ! ---------------------------------------------------------
86 integer function get_resp_method(namespace)
87 type(namespace_t), intent(in) :: namespace
88
89 push_sub(get_resp_method)
90
91 !%Variable ResponseMethod
92 !%Type integer
93 !%Default sternheimer
94 !%Section Linear Response
95 !%Description
96 !% Some response properties can be calculated either via
97 !% Sternheimer linear response or by using finite
98 !% differences. You can use this variable to select how you want
99 !% them to be calculated, it applies to <tt>em_resp</tt> and <tt>vib_modes</tt>
100 !% calculation modes. By default, the Sternheimer linear-response
101 !% technique is used.
102 !%Option sternheimer 1
103 !% The linear response is obtained by solving a self-consistent
104 !% Sternheimer equation for the variation of the orbitals. This
105 !% is the recommended method.
106 !%Option finite_differences 2
107 !% Properties are calculated as a finite-differences derivative of
108 !% the energy obtained by several ground-state calculations. This
109 !% method, slow and limited only to static response, is kept
110 !% mainly because it is simple and useful for testing purposes.
111 !%End
112
113 call parse_variable(namespace, 'ResponseMethod', lr, get_resp_method)
114
115 if (.not. varinfo_valid_option('ResponseMethod', get_resp_method)) then
116 call messages_input_error(namespace, 'ResponseMethod')
117 end if
118
120 end function get_resp_method
121
122 ! ---------------------------------------------------------
126 subroutine run(namespace, calc_mode_id)
127 type(namespace_t), intent(in) :: namespace
128 integer, intent(in) :: calc_mode_id
129
130 type(partner_list_t) :: partners
131 class(system_t), pointer :: systems
132 type(system_factory_t) :: system_factory
133 type(interactions_factory_t) :: interactions_factory
134 logical :: from_scratch
135 integer :: iunit_out
136 type(partner_iterator_t) :: iter
137 type(system_list_t) :: flat_list
138 class(interaction_partner_t), pointer :: partner
139 real(real64) :: largest_dt, largest_allowed_time
140
141 push_sub(run)
142
143 call messages_print_with_emphasis(msg="Calculation Mode", namespace=namespace)
144 call messages_print_var_option("CalculationMode", calc_mode_id, namespace=namespace)
145 call messages_print_with_emphasis(namespace=namespace)
146
147 call calc_mode_parallel_strategy_init(calc_mode_id)
148
149 if (calc_mode_id == option__calculationmode__recipe) then
150 call pulpo_print()
151 pop_sub(run)
152 return
153 end if
154
155 call unit_system_init(namespace)
156
157 call accel_init(mpi_world, namespace)
158
159 ! initialize FFTs
160 call fft_all_init(namespace)
161
162 if (calc_mode_id == option__calculationmode__test) then
163#ifdef HAVE_APP_TESTS
164 call test_run(namespace, mpi_world)
165 call fft_all_end()
167 pop_sub(run)
168 return
169#else
170 call messages_not_implemented("CalculationMode = test (build with OCTOPUS_APP_TESTS=ON)", namespace=namespace)
171#endif
172 end if
173
174 ! Create systems
175 if (parse_is_defined(namespace, "Systems")) then
176 ! We are running in multi-system mode
177 systems => system_factory%create(namespace, system_multisystem, calc_mode_id, mpi_world)
178 else
179 ! Fall back to old behaviour
180 systems => electrons_t(namespace, mpi_world, calc_mode_id)
181 end if
182
183 ! Create list of partners
184 select type (systems)
185 class is (multisystem_basic_t)
186 ! Systems are also partners
187 partners = systems%list
188 ! Add external potentials to partners list
189 call load_external_potentials(partners, namespace)
190
191 call load_external_waves(partners, namespace)
192
193 ! Add lasers to the partner list
194 call load_lasers(partners, namespace)
195
196 type is (electrons_t)
197 call partners%add(systems)
198 end select
199
200 ! Initialize algorithms (currently only propagators are supported)
201 select type (systems)
202 class is (multisystem_basic_t)
203 select case (calc_mode_id)
204 case (option__calculationmode__gs)
205 call systems%new_algorithm(minimizer_factory_t(systems%namespace))
206 case (option__calculationmode__td)
207 call systems%new_algorithm(propagator_factory_t(systems%namespace))
208 end select
209 end select
210
211
212 ! Check whether the final propagation time would lead to an infinite loop, and stop the code if necessary.
213 ! See issue: https://gitlab.com/octopus-code/octopus/-/issues/1226
214 !
215 ! The deadlock currently appears when systems have different timesteps, and one system could do a
216 !
217 ! 2 4 6 8 10 propagation time=11
218 ! system1 (dt=2): * * * * * |
219 ! system2 (dt=4): * * |
220 !
221 ! As system2 is not allowed to do to timestep 12, it is stuck at 8. System1 will try to get to 10, but is stuck at a barrier, as
222 ! system2 is behind, and keeps waiting for system2.
223 !
224 ! We can only allow propagations up to the largest time, the fastest system (largest dt)
225 ! can reach within the given propagation time. If one of the slower systems could perform
226 ! an extra step within the propagation time, we need to stop the calculation, before the
227 ! propagation, to prevent wasting CPU time in the deadlock.
228 !
229 ! TODO: Fix the framework, so that this infinite loop can be avoided in the first place.
230
231 if(calc_mode_id == option__calculationmode__td) then
232
233 select type (sys => systems)
234 type is (multisystem_basic_t)
235
236 largest_dt = m_zero
237 largest_allowed_time = m_zero
238
239 call sys%get_flat_list(flat_list)
240
241 call iter%start(flat_list)
242 do while (iter%has_next())
243 select type (subsystem => iter%get_next())
244 class is (system_t)
245 select type (subalgorithm => subsystem%algo)
246 class is (propagator_t)
247 largest_dt = max(largest_dt, subalgorithm%dt)
248 end select
249 end select
250 end do
251
252 select type(prop => systems%algo)
253 class is (propagator_t)
254 largest_allowed_time = floor(prop%final_time / largest_dt)* largest_dt
255 class default
256 assert(.false.)
257 end select
258
259 call iter%start(flat_list)
260 do while (iter%has_next())
261 select type(subsystem => iter%get_next())
262 class is (system_t)
263 select type (subalgorithm => subsystem%algo)
264 class is (propagator_t)
265 if( floor(subalgorithm%final_time/subalgorithm%dt) * subalgorithm%dt > largest_allowed_time ) then
266 write(message(1), *) "Incommensurate propagation time: The calculation would run into a deadlock, as a system with"
267 write(message(2), *) "a smaller timestep would attempt a timestep beyond the last step" &
268 // " of a system with a larger time step."
269 write(message(3), *) "Please, adjust the TDPropagationTime and/or the TDTimeStep variables of the systems."
270 write(message(4), *) ""
271 write(message(5), *) "With the current timesteps, the TDPropagationTime should be ", largest_allowed_time
272 call messages_fatal(5, namespace=namespace)
273 end if
274 end select
275 end select
276 end do
277
278 end select
279
280 end if
281
282 ![create_interactions] !doxygen marker. Dont delete
283 ! Create and initialize interactions
284 !
285 ! This function is called recursively for all subsystems of systems.
286 ! If systems is a multisystem_basic_t container, the partners list contains all subsystems.
287 call systems%create_interactions(interactions_factory, partners)
288 ![create_interactions]
289
290 select type (systems)
291 class is (multisystem_basic_t)
292 ! Write the interaction graph as a DOT graph for debug
293 if ((debug%interaction_graph .or. debug%interaction_graph_full) .and. mpi_world%is_root()) then
294 iunit_out = io_open('debug/interaction_graph.dot', systems%namespace, action='write')
295 write(iunit_out, '(a)') 'digraph {'
296 call systems%write_interaction_graph(iunit_out, debug%interaction_graph_full)
297 write(iunit_out, '(a)') '}'
298 call io_close(iunit_out)
299 end if
300 end select
301
302 if (.not. systems%process_is_slave()) then
303 call messages_write('Info: Octopus initialization completed.', new_line = .true.)
304 call messages_write('Info: Starting calculation mode.')
305 call messages_info(namespace=namespace)
306
307 !%Variable FromScratch
308 !%Type logical
309 !%Default false
310 !%Section Execution
311 !%Description
312 !% When this variable is set to true, <tt>Octopus</tt> will perform a
313 !% calculation from the beginning, without looking for restart
314 !% information.
315 !% NOTE: If available, mesh partitioning information will be used for
316 !% initializing the calculation regardless of the set value for this variable.
317 !%End
318 call parse_variable(namespace, 'FromScratch', .false., from_scratch)
319
320 call profiling_in("CALC_MODE")
321
322 select case (calc_mode_id)
323 case (option__calculationmode__gs)
324 select type (systems)
325 class is (multisystem_basic_t)
326 call multisystem_run(systems, from_scratch)
327 type is (electrons_t)
328 call systems%ground_state_run(from_scratch)
329 end select
330 case (option__calculationmode__unocc)
331 call unocc_run(systems, from_scratch)
332 case (option__calculationmode__td)
333 select type (systems)
334 class is (multisystem_basic_t)
335 call multisystem_run(systems, from_scratch)
336 type is (electrons_t)
337 call time_dependent_run(systems, from_scratch)
338 end select
339 case (option__calculationmode__go)
340 call geom_opt_run(systems, from_scratch)
341 case (option__calculationmode__opt_control)
342 call opt_control_run(systems)
343 case (option__calculationmode__em_resp)
344 select case (get_resp_method(namespace))
345 case (fd)
346 call static_pol_run(systems, from_scratch)
347 case (lr)
348 call em_resp_run(systems, from_scratch)
349 end select
350 case (option__calculationmode__casida)
351 call casida_run(systems, from_scratch)
352 case (option__calculationmode__vdw)
353 call vdw_run(systems, from_scratch)
354 case (option__calculationmode__vib_modes)
355 select case (get_resp_method(namespace))
356 case (fd)
357 call phonons_run(systems)
358 case (lr)
359 call phonons_lr_run(systems, from_scratch)
360 end select
361 case (option__calculationmode__one_shot)
362 message(1) = "CalculationMode = one_shot is obsolete. Please use gs with MaximumIter = 0."
363 call messages_fatal(1, namespace=namespace)
364 case (option__calculationmode__kdotp)
365 call kdotp_lr_run(systems, from_scratch)
366 case (option__calculationmode__dummy)
367 case (option__calculationmode__invert_ks)
368 call invert_ks_run(systems)
369 case (option__calculationmode__recipe)
370 assert(.false.) !this is handled before, if we get here, it is an error
371 end select
372
373 call profiling_out("CALC_MODE")
374 end if
375
376 select type (systems)
377 class is (multisystem_basic_t)
378 !Deallocate the external potentials
379 call iter%start(partners)
380 do while (iter%has_next())
381 select type(ptr => iter%get_next())
382 class is(external_potential_t)
383 partner => ptr
384 safe_deallocate_p(partner)
385 class is(external_waves_t)
386 partner => ptr
387 safe_deallocate_p(partner)
388 class is(lasers_t)
389 partner => ptr
390 safe_deallocate_p(partner)
391 end select
392 end do
393 end select
394
395 ! Finalize systems
396 safe_deallocate_p(systems)
397
398 call fft_all_end()
399
401
403
404 pop_sub(run)
405
406 end subroutine run
407
409 subroutine calc_mode_parallel_strategy_init(calc_mode_id)
410 integer, intent(in) :: calc_mode_id
411
413
414 select case (calc_mode_id)
415 case (option__calculationmode__gs, option__calculationmode__go, option__calculationmode__unocc)
416 call calc_mode_par%set_parallelization(p_strategy_states, default = .false.)
417#ifdef HAVE_SCALAPACK
418 call calc_mode_par%set_scalapack_compat()
419#endif
420
421 case (option__calculationmode__td)
422 call calc_mode_par%set_parallelization(p_strategy_states, default = .true.)
423
424 case (option__calculationmode__casida)
425 ! Pure 'other' parallelization is a bad idea. Trying to solve the Poisson equation separately on each node
426 ! consumes excessive memory and time (easily more than is available). In principle, the line below would setup
427 ! joint domain/other parallelization, but 'other' parallelization takes precedence, especially since
428 ! multicomm_init does not know the actual problem size and uses a fictitious value of 10000, making it
429 ! impossible to choose joint parallelization wisely, and generally resulting in a choice of only one domain
430 ! group. FIXME! --DAS
431
432 ! With the recent improvements, the 'other' parallelization over electron-hole
433 ! pairs works quite well now. For smaller matrices, a combination
434 ! seems to give the fastest run times. For larger matrices (more than a few
435 ! thousand entries per dimension), CasidaDistributedMatrix is needed for
436 ! the Casida matrix to fit into memory; this takes the cores from the
437 ! 'other' strategy. For very large matrices (more than 100000), it is
438 ! advisable to use only the 'other' strategy because the diagonalization
439 ! uses most of the computation time.
440 ! Thus you may want to enable this or a combination of other and domain to get
441 ! better performance - STO
442 call calc_mode_par%set_parallelization(p_strategy_other, default = .false.) ! enabled, but not default
443 call calc_mode_par%unset_parallelization(p_strategy_kpoints) ! disabled. FIXME: could be implemented.
444
445 end select
446
448
450
451end module run_oct_m
452
453!! Local Variables:
454!! mode: f90
455!! coding: utf-8
456!! End:
double floor(double __x) __attribute__((__nothrow__
subroutine, public accel_init(base_grp, namespace)
Definition: accel.F90:423
subroutine, public accel_end(namespace)
Definition: accel.F90:708
This module handles the calculation mode.
integer, parameter, public p_strategy_kpoints
parallelization in k-points
integer, parameter, public p_strategy_other
something else like e-h pairs
type(calc_mode_par_t), public calc_mode_par
Singleton instance of parallel calculation mode.
integer, parameter, public p_strategy_states
parallelization in states
This module implements the Casida equations for excited states.
Definition: casida.F90:120
subroutine, public casida_run(system, from_scratch)
Definition: casida.F90:294
type(debug_t), save, public debug
Definition: debug.F90:156
subroutine, public em_resp_run(system, from_scratch)
Definition: em_resp.F90:234
subroutine, public load_external_potentials(external_potentials, namespace)
subroutine, public load_external_waves(partners, namespace)
Fast Fourier Transform module. This module provides a single interface that works with different FFT ...
Definition: fft.F90:120
subroutine, public fft_all_init(namespace)
initialize the table
Definition: fft.F90:283
subroutine, public fft_all_end()
delete all plans
Definition: fft.F90:398
subroutine, public geom_opt_run(system, from_scratch)
Definition: geom_opt.F90:213
real(real64), parameter, public m_zero
Definition: global.F90:200
This module defines classes and functions for interaction partners.
subroutine, public invert_ks_run(system)
Definition: invert_ks.F90:149
Definition: io.F90:116
subroutine, public io_close(iunit, grp)
Definition: io.F90:467
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
Definition: io.F90:402
subroutine, public kdotp_lr_run(system, from_scratch)
Definition: kdotp.F90:187
subroutine, public load_lasers(partners, namespace)
Definition: lasers.F90:1235
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:898
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1068
character(len=512), private msg
Definition: messages.F90:167
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
This module implements the factory for ground state algorithm.
subroutine, public mpi_debug_statistics()
Definition: mpi_debug.F90:221
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:272
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
This module implements the basic mulsisystem class, a container system for other systems.
This module implements the multisystem debug functionality.
subroutine, public multisystem_run(systems, from_scratch)
type(namespace_t), public global_namespace
Definition: namespace.F90:135
This module contains the main procedure ("opt_control_run") that is used when optimal control runs ar...
subroutine, public opt_control_run(system)
logical function, public parse_is_defined(namespace, name)
Definition: parser.F90:463
subroutine, public phonons_run(system)
Definition: phonons_fd.F90:154
subroutine, public phonons_lr_run(system, from_scratch)
Definition: phonons_lr.F90:172
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 factory for propagators.
This module implements the basic propagator framework.
Definition: propagator.F90:119
subroutine, public pulpo_print()
Definition: pulpo.F90:132
top level module for all calculation modes
Definition: run.F90:119
integer function get_resp_method(namespace)
query input file for the response mode.
Definition: run.F90:182
integer, parameter fd
Definition: run.F90:175
subroutine calc_mode_parallel_strategy_init(calc_mode_id)
Calculation mode initialization (parallelization strategy)
Definition: run.F90:505
subroutine, public run(namespace, calc_mode_id)
main routine to run all calculations: This routine parses the input file, sets up the systems and int...
Definition: run.F90:222
subroutine, public static_pol_run(system, from_scratch)
Definition: static_pol.F90:160
integer, parameter, public system_multisystem
container system. (multisystem_basic_oct_m::multisystem_basic_t)
This module implements the abstract system type.
Definition: system.F90:120
Definition: td.F90:116
subroutine, public time_dependent_run(electrons, from_scratch)
This module defines the unit system, used for input and output.
subroutine, public unit_system_init(namespace)
subroutine, public unocc_run(system, from_scratch)
Definition: unocc.F90:162
subroutine, public vdw_run(system, from_scratch)
Definition: vdw.F90:154
Class describing the electron system.
Definition: electrons.F90:222
This class defines the factory for minimizers.
Container class for lists of system_oct_m::system_t.
This class defines the factory for propagators.
Abstract class implementing propagators.
Definition: propagator.F90:144
Abstract class for systems.
Definition: system.F90:175
int true(void)