Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief Tree Monte Carlo entry point, set up, CPU redistribution and
10 : !> input reading
11 : !> \par History
12 : !> 11.2012 created [Mandes Schoenherr]
13 : !> \author Mandes
14 : ! **************************************************************************************************
15 :
16 : MODULE tmc_setup
17 : USE bibliography, ONLY: cite_reference,&
18 : schonherr2014
19 : USE cp_files, ONLY: close_file,&
20 : open_file
21 : USE cp_log_handling, ONLY: &
22 : cp_add_default_logger, cp_get_default_logger, cp_logger_create, &
23 : cp_logger_get_default_io_unit, cp_logger_release, cp_logger_set, cp_logger_type, &
24 : cp_rm_default_logger, cp_to_string
25 : USE environment, ONLY: cp2k_get_walltime
26 : USE f77_interface, ONLY: create_force_env,&
27 : destroy_force_env
28 : USE global_types, ONLY: global_environment_type
29 : USE header, ONLY: tmc_ana_header,&
30 : tmc_header
31 : USE input_section_types, ONLY: section_type,&
32 : section_vals_get,&
33 : section_vals_get_subs_vals,&
34 : section_vals_type,&
35 : section_vals_val_get
36 : USE kinds, ONLY: default_path_length,&
37 : default_string_length,&
38 : dp
39 : USE machine, ONLY: default_output_unit,&
40 : m_flush
41 : USE message_passing, ONLY: mp_para_env_type
42 : USE parallel_rng_types, ONLY: UNIFORM,&
43 : rng_stream_type
44 : USE physcon, ONLY: au2a => angstrom,&
45 : au2bar => bar
46 : USE tmc_analysis, ONLY: analysis_init,&
47 : analysis_restart_print,&
48 : analysis_restart_read,&
49 : analyze_file_configurations,&
50 : finalize_tmc_analysis,&
51 : tmc_read_ana_input
52 : USE tmc_analysis_types, ONLY: tmc_ana_env_release,&
53 : tmc_ana_list_type
54 : USE tmc_file_io, ONLY: expand_file_name_int
55 : USE tmc_master, ONLY: do_tmc_master
56 : USE tmc_move_handle, ONLY: finalize_mv_types,&
57 : print_move_types,&
58 : read_init_move_types
59 : USE tmc_stati, ONLY: &
60 : task_type_MC, task_type_ideal_gas, tmc_NMC_worker_out_file_name, tmc_ana_out_file_name, &
61 : tmc_default_restart_in_file_name, tmc_default_restart_out_file_name, &
62 : tmc_default_unspecified_name, tmc_energy_worker_out_file_name, tmc_master_out_file_name
63 : USE tmc_tree_build, ONLY: allocate_new_sub_tree_node,&
64 : deallocate_sub_tree_node
65 : USE tmc_tree_types, ONLY: tree_type
66 : USE tmc_types, ONLY: tmc_comp_set_type,&
67 : tmc_env_create,&
68 : tmc_env_release,&
69 : tmc_env_type,&
70 : tmc_master_env_create,&
71 : tmc_master_env_release,&
72 : tmc_worker_env_create,&
73 : tmc_worker_env_release
74 : USE tmc_worker, ONLY: do_tmc_worker,&
75 : get_atom_kinds_and_cell,&
76 : get_initial_conf
77 : #include "../base/base_uses.f90"
78 :
79 : IMPLICIT NONE
80 :
81 : PRIVATE
82 :
83 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'tmc_setup'
84 :
85 : PUBLIC :: do_tmc, do_analyze_files
86 :
87 : CONTAINS
88 :
89 : ! **************************************************************************************************
90 : !> \brief tmc_entry point
91 : !> \param input_declaration ...
92 : !> \param root_section ...
93 : !> \param para_env ...
94 : !> \param globenv the global environment for the simulation
95 : !> \author Mandes 11.2012
96 : ! **************************************************************************************************
97 28 : SUBROUTINE do_tmc(input_declaration, root_section, para_env, globenv)
98 : TYPE(section_type), POINTER :: input_declaration
99 : TYPE(section_vals_type), POINTER :: root_section
100 : TYPE(mp_para_env_type), POINTER :: para_env
101 : TYPE(global_environment_type), POINTER :: globenv
102 :
103 : CHARACTER(LEN=*), PARAMETER :: routineN = 'do_tmc'
104 :
105 : INTEGER :: bcast_output_unit, handle, i, ierr, &
106 : output_unit
107 : LOGICAL :: init_rng, success
108 28 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: init_rng_seed
109 : TYPE(cp_logger_type), POINTER :: logger, logger_sub
110 : TYPE(section_vals_type), POINTER :: tmc_ana_section
111 28 : TYPE(tmc_ana_list_type), DIMENSION(:), POINTER :: tmc_ana_env_list
112 : TYPE(tmc_env_type), POINTER :: tmc_env
113 :
114 : ! start the timing
115 :
116 28 : CALL timeset(routineN, handle)
117 :
118 28 : CALL cite_reference(Schonherr2014)
119 :
120 28 : NULLIFY (logger, logger_sub, tmc_env, tmc_ana_env_list)
121 28 : logger => cp_get_default_logger()
122 28 : output_unit = cp_logger_get_default_io_unit(logger)
123 :
124 : ! write header, on the 'rank 0' of the global communicator
125 28 : IF (output_unit > 0) THEN
126 14 : CALL tmc_header(output_unit)
127 14 : CALL m_flush(output_unit)
128 : END IF
129 : ! ugly, we need to know the output unit on source, everywhere, in particular
130 : ! the tmc master
131 28 : IF (output_unit /= default_output_unit .AND. output_unit > 0) THEN
132 0 : WRITE (UNIT=output_unit, FMT="(/,T2,A)") REPEAT("-", 79)
133 0 : WRITE (UNIT=output_unit, FMT="(/,T2,A)") "The TMC output files are:"
134 : WRITE (UNIT=output_unit, FMT="(/,T2,A)") &
135 0 : TRIM(tmc_master_out_file_name)//" the TMC master"
136 : WRITE (UNIT=output_unit, FMT="(/,T2,A)") &
137 0 : TRIM(tmc_energy_worker_out_file_name)//" the worker outputs (energy calculations etc.)"
138 : WRITE (UNIT=output_unit, FMT="(/,T2,A)") &
139 0 : TRIM(tmc_ana_out_file_name)//" the analysis output"
140 0 : WRITE (UNIT=output_unit, FMT="(/,T2,A)") REPEAT("-", 79)
141 : END IF
142 28 : bcast_output_unit = output_unit
143 28 : CALL para_env%bcast(bcast_output_unit)
144 :
145 : ! create tmc_env
146 28 : CALL tmc_env_create(tmc_env)
147 28 : CALL tmc_preread_input(root_section, tmc_env)
148 : CALL tmc_redistributing_cores(tmc_env%tmc_comp_set, para_env, &
149 : ana_on_the_fly=tmc_env%tmc_comp_set%ana_on_the_fly, &
150 28 : success=success)
151 :
152 28 : IF (success) THEN
153 : ! initialize master and worker environment
154 28 : IF (tmc_env%tmc_comp_set%group_nr == 0) THEN
155 14 : CALL tmc_master_env_create(tmc_env) ! create master env
156 : ELSE IF (tmc_env%tmc_comp_set%group_nr /= 0) THEN
157 14 : CALL tmc_worker_env_create(tmc_env) ! create worker env
158 : END IF
159 :
160 28 : CALL tmc_read_input(root_section, tmc_env)
161 : !CALL init_move_types(tmc_params=tmc_env%params)
162 :
163 : ! init random number generator: use determistic random numbers
164 28 : init_rng = .TRUE.
165 28 : IF (tmc_env%tmc_comp_set%group_nr == 0) THEN
166 14 : IF (tmc_env%m_env%rnd_init > 0) THEN
167 14 : init_rng = .FALSE.
168 14 : ALLOCATE (init_rng_seed(3, 2))
169 : init_rng_seed(:, :) = &
170 : RESHAPE([tmc_env%m_env%rnd_init*42.0_dp, &
171 : tmc_env%m_env%rnd_init*54.0_dp, &
172 : tmc_env%m_env%rnd_init*63.0_dp, &
173 : tmc_env%m_env%rnd_init*98.0_dp, &
174 : tmc_env%m_env%rnd_init*10.0_dp, &
175 : tmc_env%m_env%rnd_init*2.0_dp], &
176 98 : [3, 2])
177 : tmc_env%rng_stream = rng_stream_type( &
178 : name="TMC_deterministic_rng_stream", &
179 : seed=init_rng_seed(:, :), &
180 14 : distribution_type=UNIFORM)
181 14 : DEALLOCATE (init_rng_seed)
182 : END IF
183 : END IF
184 : IF (init_rng) THEN
185 : tmc_env%rng_stream = rng_stream_type( &
186 : name="TMC_rng_stream", &
187 14 : distribution_type=UNIFORM)
188 : END IF
189 :
190 : ! start running master and worker routines
191 : ! the master
192 28 : IF (tmc_env%tmc_comp_set%group_nr == 0) THEN
193 : !TODO get the correct usage of creating and handling the logger...
194 : CALL cp_logger_create(logger_sub, para_env=tmc_env%tmc_comp_set%para_env_m_only, &
195 14 : default_global_unit_nr=default_output_unit, close_global_unit_on_dealloc=.FALSE.)
196 14 : CALL cp_logger_set(logger_sub, local_filename="tmc_main")
197 14 : CALL cp_add_default_logger(logger_sub)
198 :
199 : ! if we're doing output to the screen, keep it there, else this master
200 : ! opens a file (not that two different ranks are writing to the
201 : ! default_output_unit, we leave it up to mpirun or so to merge stuff
202 14 : IF (bcast_output_unit == default_output_unit) THEN
203 14 : tmc_env%m_env%io_unit = default_output_unit
204 : ELSE
205 : CALL open_file(file_name=tmc_master_out_file_name, file_status="UNKNOWN", &
206 : file_action="WRITE", file_position="APPEND", &
207 0 : unit_number=tmc_env%m_env%io_unit)
208 0 : CALL tmc_header(tmc_env%m_env%io_unit)
209 : END IF
210 : ! print the intresting parameters and starting values
211 14 : CALL tmc_print_params(tmc_env)
212 : CALL print_move_types(init=.TRUE., file_io=tmc_env%m_env%io_unit, &
213 14 : tmc_params=tmc_env%params)
214 14 : CALL do_tmc_master(tmc_env=tmc_env, globenv=globenv) ! start the master routine
215 :
216 14 : IF (bcast_output_unit /= tmc_env%m_env%io_unit) THEN
217 0 : CALL close_file(unit_number=tmc_env%m_env%io_unit)
218 : END IF
219 :
220 14 : CALL cp_rm_default_logger()
221 14 : CALL cp_logger_release(logger_sub)
222 :
223 : ! the worker groups
224 14 : ELSE IF (tmc_env%tmc_comp_set%group_nr > 0) THEN
225 14 : NULLIFY (logger_sub)
226 : ! create separate logger and error handler for each worker
227 : CALL cp_logger_create(logger_sub, para_env=tmc_env%tmc_comp_set%para_env_sub_group, &
228 14 : default_global_unit_nr=default_output_unit, close_global_unit_on_dealloc=.FALSE.)
229 14 : CALL cp_logger_set(logger_sub, local_filename="tmc_localLog")
230 14 : CALL cp_add_default_logger(logger_sub)
231 14 : tmc_env%w_env%io_unit = default_output_unit
232 :
233 : ! energy worker
234 14 : IF (tmc_env%tmc_comp_set%group_nr <= tmc_env%tmc_comp_set%group_ener_nr) THEN
235 : CALL create_force_env(new_env_id=tmc_env%w_env%env_id_ener, &
236 : input_declaration=input_declaration, &
237 : input_path=tmc_env%params%energy_inp_file, &
238 : mpi_comm=tmc_env%tmc_comp_set%para_env_sub_group, &
239 : output_path=TRIM(expand_file_name_int(file_name=tmc_energy_worker_out_file_name, &
240 : ivalue=tmc_env%tmc_comp_set%group_nr)), &
241 14 : ierr=ierr)
242 14 : IF (ierr /= 0) THEN
243 0 : CPABORT("creating force env result in error "//cp_to_string(ierr))
244 : END IF
245 : END IF
246 : ! worker for configurational change
247 14 : IF (tmc_env%params%NMC_inp_file /= "" .AND. &
248 : (tmc_env%tmc_comp_set%group_cc_nr == 0 .OR. &
249 : tmc_env%tmc_comp_set%group_nr > tmc_env%tmc_comp_set%group_ener_nr)) THEN
250 : CALL create_force_env(new_env_id=tmc_env%w_env%env_id_approx, &
251 : input_declaration=input_declaration, &
252 : input_path=tmc_env%params%NMC_inp_file, &
253 : mpi_comm=tmc_env%tmc_comp_set%para_env_sub_group, &
254 : output_path=TRIM(expand_file_name_int(file_name=tmc_NMC_worker_out_file_name, &
255 : ivalue=tmc_env%tmc_comp_set%group_nr)), &
256 5 : ierr=ierr)
257 5 : IF (ierr /= 0) THEN
258 0 : CPABORT("creating approx force env result in error "//cp_to_string(ierr))
259 : END IF
260 : END IF
261 14 : CALL do_tmc_worker(tmc_env=tmc_env) ! start the worker routine
262 :
263 14 : IF (tmc_env%w_env%env_id_ener > 0) THEN
264 14 : CALL destroy_force_env(tmc_env%w_env%env_id_ener, ierr)
265 : END IF
266 14 : IF (tmc_env%w_env%env_id_approx > 0) THEN
267 5 : CALL destroy_force_env(tmc_env%w_env%env_id_approx, ierr)
268 : END IF
269 :
270 14 : CALL cp_rm_default_logger()
271 14 : CALL cp_logger_release(logger_sub)
272 :
273 : ! the analysis group
274 0 : ELSE IF (ASSOCIATED(tmc_env%tmc_comp_set%para_env_m_ana)) THEN
275 : ! unused worker groups can do analysis
276 0 : NULLIFY (logger_sub)
277 : ! create separate logger and error handler for each worker
278 : CALL cp_logger_create(logger_sub, para_env=tmc_env%tmc_comp_set%para_env_m_ana, &
279 0 : default_global_unit_nr=default_output_unit, close_global_unit_on_dealloc=.FALSE.)
280 0 : tmc_env%w_env%io_unit = default_output_unit
281 0 : CALL cp_logger_set(logger_sub, local_filename="tmc_ana_localLog")
282 0 : CALL cp_add_default_logger(logger_sub)
283 : ! if we're doing output to the screen, keep it there, else this master
284 : ! opens a file (not that two different ranks are writing to the
285 : ! default_output_unit, we leave it up to mpirun or so to merge stuff
286 0 : IF (bcast_output_unit == default_output_unit) THEN
287 0 : output_unit = default_output_unit
288 : ELSE
289 : CALL open_file(file_name=tmc_ana_out_file_name, file_status="UNKNOWN", &
290 : file_action="WRITE", file_position="APPEND", &
291 0 : unit_number=output_unit)
292 0 : CALL tmc_ana_header(output_unit)
293 : END IF
294 :
295 0 : ALLOCATE (tmc_ana_env_list(tmc_env%params%nr_temp))
296 0 : tmc_ana_section => section_vals_get_subs_vals(root_section, "MOTION%TMC%TMC_ANALYSIS")
297 0 : DO i = 1, tmc_env%params%nr_temp
298 0 : CALL tmc_read_ana_input(tmc_ana_section, tmc_ana_env_list(i)%temp)
299 0 : tmc_ana_env_list(i)%temp%io_unit = output_unit
300 : END DO
301 0 : CALL do_tmc_worker(tmc_env=tmc_env, ana_list=tmc_ana_env_list) ! start the worker routine for analysis
302 0 : DO i = 1, tmc_env%params%nr_temp
303 0 : IF (ASSOCIATED(tmc_ana_env_list(i)%temp%last_elem)) THEN
304 0 : CALL deallocate_sub_tree_node(tree_elem=tmc_ana_env_list(i)%temp%last_elem)
305 : END IF
306 0 : CALL tmc_ana_env_release(tmc_ana_env_list(i)%temp)
307 : END DO
308 0 : DEALLOCATE (tmc_ana_env_list)
309 0 : IF (bcast_output_unit /= output_unit) THEN
310 0 : CALL close_file(unit_number=tmc_env%m_env%io_unit)
311 : END IF
312 0 : CALL cp_rm_default_logger()
313 0 : CALL cp_logger_release(logger_sub)
314 :
315 : END IF ! unused worker groups have nothing to do
316 :
317 : ! delete the random numbers
318 28 : DEALLOCATE (tmc_env%rng_stream)
319 :
320 : ! deallocate the move types
321 28 : CALL finalize_mv_types(tmc_env%params)
322 :
323 : ! finalize master and worker environment
324 28 : IF (tmc_env%tmc_comp_set%group_nr == 0) THEN
325 14 : CALL tmc_master_env_release(tmc_env) ! release master env
326 : ELSE IF (tmc_env%tmc_comp_set%group_nr /= 0) THEN
327 14 : CALL tmc_worker_env_release(tmc_env) ! release worker env
328 : END IF ! unused worker groups have nothing to do
329 :
330 : ELSE
331 0 : IF (tmc_env%params%print_test_output) THEN
332 0 : WRITE (output_unit, *) "TMC|NOTenoughProcessorsX= -999"
333 0 : WRITE (output_unit, *) "TMC|NOTcalculatedTotal energy: -999"
334 : END IF
335 : END IF
336 : ! finalize / deallocate everything
337 28 : CALL tmc_env_release(tmc_env)
338 :
339 : ! end the timing
340 28 : CALL timestop(handle)
341 :
342 28 : END SUBROUTINE do_tmc
343 :
344 : ! **************************************************************************************************
345 : !> \brief analyze TMC trajectory files
346 : !> \param input_declaration ...
347 : !> \param root_section ...
348 : !> \param para_env ...
349 : !> \param
350 : !> \author Mandes 03.2013
351 : ! **************************************************************************************************
352 12 : SUBROUTINE do_analyze_files(input_declaration, root_section, para_env)
353 : TYPE(section_type), POINTER :: input_declaration
354 : TYPE(section_vals_type), POINTER :: root_section
355 : TYPE(mp_para_env_type), POINTER :: para_env
356 :
357 : CHARACTER(LEN=*), PARAMETER :: routineN = 'do_analyze_files'
358 :
359 : INTEGER :: dir_ind, handle, nr_dim, output_unit, &
360 : temp
361 : TYPE(cp_logger_type), POINTER :: logger
362 12 : TYPE(tmc_ana_list_type), DIMENSION(:), POINTER :: ana_list
363 : TYPE(tmc_env_type), POINTER :: tmc_env
364 : TYPE(tree_type), POINTER :: elem
365 :
366 12 : NULLIFY (ana_list, tmc_env, elem, logger)
367 :
368 : ! start the timing
369 12 : CALL timeset(routineN, handle)
370 :
371 : ! create a TMC environment (also to have a params environment)
372 12 : CALL tmc_env_create(tmc_env)
373 : ! -- spiltting communicator
374 12 : ALLOCATE (tmc_env%tmc_comp_set%para_env_m_ana)
375 12 : CALL tmc_env%tmc_comp_set%para_env_m_ana%from_split(para_env, para_env%mepos, 0)
376 12 : IF (para_env%num_pe /= 1) THEN
377 12 : CPWARN("just one out of "//cp_to_string(para_env%num_pe)//"cores is used ")
378 : END IF
379 : ! distribute work to availuble cores
380 12 : IF (para_env%mepos == 0) THEN
381 : !TODO get the correct usage of creating and handling the logger...
382 6 : logger => cp_get_default_logger()
383 6 : output_unit = cp_logger_get_default_io_unit(logger)
384 6 : CPASSERT(output_unit > 0)
385 : ! write the header
386 6 : CALL tmc_ana_header(output_unit)
387 :
388 : ! read the input and create the ana environments for each temp
389 : CALL tmc_read_ana_files_input(input_declaration=input_declaration, &
390 : input=root_section, ana_list=ana_list, &
391 6 : elem=elem, tmc_env=tmc_env)
392 6 : nr_dim = SIZE(elem%pos)
393 : ! we need a new tree element with all neccessay arrays, (e.g. dipoles could not be allocated already)
394 6 : CALL deallocate_sub_tree_node(tree_elem=elem)
395 6 : CPASSERT(SIZE(ana_list) > 0)
396 :
397 : ! print initial test output (for single core tests, where no data is produced)
398 6 : IF (tmc_env%params%print_test_output) THEN
399 6 : WRITE (output_unit, *) "TMC|ANAtestOutputInitX= -999"
400 : END IF
401 :
402 : ! do the analysis
403 24 : DO temp = 1, SIZE(ana_list)
404 : ! initialize the structures
405 18 : ana_list(temp)%temp%io_unit = output_unit
406 18 : CALL analysis_init(ana_env=ana_list(temp)%temp, nr_dim=nr_dim)
407 : ! to allocate the dipole array in tree elements
408 18 : IF (ana_list(temp)%temp%costum_dip_file_name /= &
409 : tmc_default_unspecified_name) THEN
410 0 : tmc_env%params%print_dipole = .TRUE.
411 : END IF
412 :
413 18 : IF (.NOT. ASSOCIATED(elem)) THEN
414 : CALL allocate_new_sub_tree_node(tmc_params=tmc_env%params, &
415 18 : next_el=elem, nr_dim=nr_dim)
416 : END IF
417 : CALL analysis_restart_read(ana_env=ana_list(temp)%temp, &
418 18 : elem=elem)
419 18 : IF (.NOT. ASSOCIATED(elem) .AND. .NOT. ASSOCIATED(ana_list(temp)%temp%last_elem)) THEN
420 0 : CPABORT("uncorrect initialization of the initial configuration")
421 : END IF
422 : ! do for all directories
423 36 : DO dir_ind = 1, SIZE(ana_list(temp)%temp%dirs)
424 18 : WRITE (output_unit, FMT='(T2,A,"| ",A,T41,A40)') "TMC_ANA", &
425 36 : "read directory", TRIM(ana_list(temp)%temp%dirs(dir_ind))
426 : CALL analyze_file_configurations( &
427 : start_id=ana_list(temp)%temp%from_elem, &
428 : end_id=ana_list(temp)%temp%to_elem, &
429 : dir_ind=dir_ind, &
430 : ana_env=ana_list(temp)%temp, &
431 18 : tmc_params=tmc_env%params)
432 : ! remove the last saved element to start with a new file
433 : ! there is no weight for this element
434 18 : IF (dir_ind < SIZE(ana_list(temp)%temp%dirs) .AND. &
435 : ASSOCIATED(ana_list(temp)%temp%last_elem)) THEN
436 0 : CALL deallocate_sub_tree_node(tree_elem=ana_list(temp)%temp%last_elem)
437 : END IF
438 36 : IF (ASSOCIATED(ana_list(temp)%temp%last_elem)) THEN
439 : ana_list(temp)%temp%conf_offset = ana_list(temp)%temp%conf_offset &
440 18 : + ana_list(temp)%temp%last_elem%nr
441 : END IF
442 : END DO
443 18 : CALL finalize_tmc_analysis(ana_env=ana_list(temp)%temp)
444 : ! write analysis restart file
445 : ! if there is something to write
446 : ! shifts the last element to actual element
447 18 : IF (ASSOCIATED(ana_list(temp)%temp%last_elem)) THEN
448 18 : CALL analysis_restart_print(ana_env=ana_list(temp)%temp)
449 : END IF
450 18 : IF (ASSOCIATED(ana_list(temp)%temp%last_elem)) THEN
451 18 : CALL deallocate_sub_tree_node(tree_elem=ana_list(temp)%temp%last_elem)
452 : END IF
453 18 : IF (ASSOCIATED(elem)) THEN
454 15 : CALL deallocate_sub_tree_node(tree_elem=elem)
455 : END IF
456 :
457 18 : IF (ASSOCIATED(ana_list(temp)%temp%last_elem)) THEN
458 0 : CALL deallocate_sub_tree_node(tree_elem=ana_list(temp)%temp%last_elem)
459 : END IF
460 :
461 24 : CALL tmc_ana_env_release(ana_list(temp)%temp)
462 : END DO
463 :
464 6 : DEALLOCATE (ana_list)
465 : END IF
466 12 : CALL tmc_env_release(tmc_env)
467 :
468 : ! end the timing
469 12 : CALL timestop(handle)
470 12 : END SUBROUTINE do_analyze_files
471 :
472 : ! **************************************************************************************************
473 : !> \brief creates a new para environment for tmc analysis for each temperature
474 : !> \param input_declaration ...
475 : !> \param input global environment
476 : !> \param ana_list ...
477 : !> \param elem ...
478 : !> \param tmc_env TMC analysis environment
479 : !> \author Mandes 03.2013
480 : ! **************************************************************************************************
481 6 : SUBROUTINE tmc_read_ana_files_input(input_declaration, input, ana_list, elem, tmc_env)
482 : TYPE(section_type), POINTER :: input_declaration
483 : TYPE(section_vals_type), POINTER :: input
484 : TYPE(tmc_ana_list_type), DIMENSION(:), POINTER :: ana_list
485 : TYPE(tree_type), POINTER :: elem
486 : TYPE(tmc_env_type), POINTER :: tmc_env
487 :
488 : CHARACTER(len=default_string_length), &
489 6 : DIMENSION(:), POINTER :: directories
490 : INTEGER :: env_id, ierr, nr_temp, t_act
491 : LOGICAL :: flag
492 : REAL(KIND=dp) :: tmax, tmin
493 6 : REAL(KIND=dp), DIMENSION(:), POINTER :: inp_Temp, Temps
494 : TYPE(section_vals_type), POINTER :: tmc_section
495 :
496 6 : NULLIFY (tmc_section, inp_Temp, Temps)
497 0 : CPASSERT(ASSOCIATED(input))
498 6 : CPASSERT(.NOT. ASSOCIATED(ana_list))
499 6 : CPASSERT(.NOT. ASSOCIATED(elem))
500 6 : CPASSERT(ASSOCIATED(tmc_env))
501 :
502 : ! first global TMC stuff
503 6 : tmc_section => section_vals_get_subs_vals(input, "MOTION%TMC")
504 6 : CALL section_vals_val_get(tmc_section, "PRINT_TEST_OUTPUT", l_val=tmc_env%params%print_test_output)
505 : ! TMC analysis stuff
506 6 : tmc_section => section_vals_get_subs_vals(input, "MOTION%TMC%TMC_ANALYSIS_FILES")
507 6 : CALL section_vals_get(tmc_section, explicit=flag)
508 6 : CPASSERT(flag)
509 :
510 : CALL section_vals_val_get(tmc_section, "FORCE_ENV_FILE", &
511 6 : c_val=tmc_env%params%energy_inp_file)
512 :
513 6 : CALL section_vals_val_get(tmc_section, "NR_TEMPERATURE", i_val=nr_temp)
514 :
515 6 : CALL section_vals_val_get(tmc_section, "TEMPERATURE", r_vals=inp_Temp)
516 6 : IF ((nr_temp > 1) .AND. (SIZE(inp_Temp) /= 2)) THEN
517 0 : CPABORT("specify each temperature, skip keyword NR_TEMPERATURE")
518 : END IF
519 6 : IF (nr_temp == 1) THEN
520 0 : nr_temp = SIZE(inp_Temp)
521 0 : ALLOCATE (Temps(nr_temp))
522 0 : Temps(:) = inp_Temp(:)
523 : ELSE
524 6 : tmin = inp_Temp(1)
525 6 : tmax = inp_Temp(2)
526 18 : ALLOCATE (Temps(nr_temp))
527 6 : Temps(1) = tmin
528 18 : DO t_act = 2, SIZE(Temps)
529 18 : Temps(t_act) = Temps(t_act - 1) + (tmax - tmin)/(SIZE(Temps) - 1.0_dp)
530 : END DO
531 24 : IF (ANY(Temps < 0.0_dp)) THEN
532 : CALL cp_abort(__LOCATION__, "The temperatures are negative. Should be specified using "// &
533 0 : "TEMPERATURE {T_min} {T_max} and NR_TEMPERATURE {#temperatures}")
534 : END IF
535 : END IF
536 :
537 : ! get multiple directories
538 6 : CALL section_vals_val_get(tmc_section, "DIRECTORIES", c_vals=directories)
539 :
540 : ! get init configuration (for sizes)
541 : CALL create_force_env(new_env_id=env_id, &
542 : input_declaration=input_declaration, &
543 : input_path=tmc_env%params%energy_inp_file, &
544 : mpi_comm=tmc_env%tmc_comp_set%para_env_m_ana, &
545 6 : output_path="tmc_ana.out", ierr=ierr)
546 : CALL get_initial_conf(tmc_params=tmc_env%params, init_conf=elem, &
547 6 : env_id=env_id)
548 : CALL get_atom_kinds_and_cell(env_id=env_id, atoms=tmc_env%params%atoms, &
549 6 : cell=tmc_env%params%cell)
550 6 : CALL destroy_force_env(env_id, ierr)
551 :
552 36 : ALLOCATE (ana_list(SIZE(Temps)))
553 24 : DO t_act = 1, SIZE(Temps)
554 18 : ana_list(t_act)%temp => NULL()
555 18 : CALL tmc_read_ana_input(tmc_section, ana_list(t_act)%temp)
556 18 : ana_list(t_act)%temp%temperature = Temps(t_act)
557 54 : ALLOCATE (ana_list(t_act)%temp%dirs(SIZE(directories)))
558 72 : ana_list(t_act)%temp%dirs(:) = directories(:)
559 18 : ana_list(t_act)%temp%cell => tmc_env%params%cell
560 18 : ana_list(t_act)%temp%atoms => tmc_env%params%atoms
561 18 : ana_list(t_act)%temp%print_test_output = tmc_env%params%print_test_output
562 :
563 : CALL section_vals_val_get(tmc_section, "POSITION_FILE", &
564 18 : c_val=ana_list(t_act)%temp%costum_pos_file_name)
565 : CALL section_vals_val_get(tmc_section, "DIPOLE_FILE", &
566 18 : c_val=ana_list(t_act)%temp%costum_dip_file_name)
567 : CALL section_vals_val_get(tmc_section, "CELL_FILE", &
568 18 : c_val=ana_list(t_act)%temp%costum_cell_file_name)
569 18 : CALL section_vals_val_get(tmc_section, "START_ELEM", i_val=ana_list(t_act)%temp%from_elem)
570 24 : CALL section_vals_val_get(tmc_section, "END_ELEM", i_val=ana_list(t_act)%temp%to_elem)
571 : END DO
572 6 : DEALLOCATE (Temps)
573 24 : END SUBROUTINE tmc_read_ana_files_input
574 :
575 : ! **************************************************************************************************
576 : !> \brief read the variables for distributing cores
577 : !> \param input ...
578 : !> \param tmc_env structure for storing all the tmc parameters
579 : !> \author Mandes 11.2012
580 : ! **************************************************************************************************
581 140 : SUBROUTINE tmc_preread_input(input, tmc_env)
582 : TYPE(section_vals_type), POINTER :: input
583 : TYPE(tmc_env_type), POINTER :: tmc_env
584 :
585 : CHARACTER(LEN=default_path_length) :: c_tmp
586 : INTEGER :: itmp
587 : LOGICAL :: explicit_key, flag
588 : REAL(KIND=dp) :: tmax, tmin
589 28 : REAL(KIND=dp), DIMENSION(:), POINTER :: inp_Temp
590 : TYPE(section_vals_type), POINTER :: tmc_section
591 :
592 28 : NULLIFY (tmc_section, inp_Temp)
593 :
594 0 : CPASSERT(ASSOCIATED(input))
595 :
596 28 : tmc_env%tmc_comp_set%ana_on_the_fly = 0
597 28 : tmc_section => section_vals_get_subs_vals(input, "MOTION%TMC%TMC_ANALYSIS")
598 28 : CALL section_vals_get(tmc_section, explicit=flag)
599 28 : IF (flag) THEN
600 0 : tmc_env%tmc_comp_set%ana_on_the_fly = 1
601 : END IF
602 :
603 28 : tmc_section => section_vals_get_subs_vals(input, "MOTION%TMC")
604 28 : CALL section_vals_get(tmc_section, explicit=flag)
605 28 : CPASSERT(flag)
606 :
607 28 : CALL section_vals_val_get(tmc_section, "PRINT_TEST_OUTPUT", l_val=tmc_env%params%print_test_output)
608 :
609 28 : CPASSERT(ASSOCIATED(tmc_env%tmc_comp_set))
610 : ! read the parameters for the computational setup
611 28 : CALL section_vals_val_get(tmc_section, "GROUP_ENERGY_SIZE", i_val=tmc_env%tmc_comp_set%group_ener_size)
612 28 : CALL section_vals_val_get(tmc_section, "GROUP_ENERGY_NR", i_val=tmc_env%tmc_comp_set%group_ener_nr)
613 28 : CALL section_vals_val_get(tmc_section, "GROUP_CC_SIZE", i_val=tmc_env%tmc_comp_set%group_cc_size)
614 28 : CALL section_vals_val_get(tmc_section, "GROUP_ANALYSIS_NR", i_val=itmp)
615 28 : IF (tmc_env%tmc_comp_set%ana_on_the_fly > 0) THEN
616 0 : tmc_env%tmc_comp_set%ana_on_the_fly = itmp
617 : END IF
618 28 : IF (tmc_env%tmc_comp_set%ana_on_the_fly > 1) THEN
619 : CALL cp_abort(__LOCATION__, &
620 : "analysing on the fly is up to now not supported for multiple cores. "// &
621 : "Restart file witing for this case and temperature "// &
622 0 : "distribution has to be solved.!.")
623 : END IF
624 28 : CALL section_vals_val_get(tmc_section, "RESULT_LIST_IN_MEMORY", l_val=tmc_env%params%USE_REDUCED_TREE)
625 : ! swap the variable, because of oposit meaning
626 28 : tmc_env%params%USE_REDUCED_TREE = .NOT. tmc_env%params%USE_REDUCED_TREE
627 28 : CALL section_vals_val_get(tmc_section, "NR_TEMPERATURE", i_val=tmc_env%params%nr_temp)
628 :
629 : ! stuff everyone needs to know
630 28 : CALL section_vals_val_get(tmc_section, "NMC_MOVES%NMC_FILE_NAME", c_val=tmc_env%params%NMC_inp_file)
631 28 : IF (tmc_env%params%NMC_inp_file == tmc_default_unspecified_name) THEN
632 : ! file name keyword without file name
633 0 : CPABORT("no or a valid NMC input file has to be specified ")
634 28 : ELSE IF (tmc_env%params%NMC_inp_file == "") THEN
635 : ! no keyword
636 18 : IF (tmc_env%tmc_comp_set%group_cc_size > 0) THEN
637 : CALL cp_warn(__LOCATION__, &
638 : "The configurational groups are deactivated, "// &
639 0 : "because no approximated energy input is specified.")
640 : END IF
641 18 : tmc_env%tmc_comp_set%group_cc_size = 0
642 : ELSE
643 : ! check file existence
644 10 : INQUIRE (FILE=TRIM(tmc_env%params%NMC_inp_file), EXIST=flag, IOSTAT=itmp)
645 10 : IF (.NOT. flag .OR. itmp /= 0) THEN
646 0 : CPABORT("a valid NMC input file has to be specified")
647 : END IF
648 : END IF
649 :
650 28 : CALL section_vals_val_get(tmc_section, "TEMPERATURE", r_vals=inp_Temp)
651 28 : IF (tmc_env%params%nr_temp > 1 .AND. SIZE(inp_Temp) /= 2) THEN
652 0 : CPABORT("specify each temperature, skip keyword NR_TEMPERATURE")
653 : END IF
654 28 : IF (tmc_env%params%nr_temp == 1) THEN
655 16 : tmc_env%params%nr_temp = SIZE(inp_Temp)
656 48 : ALLOCATE (tmc_env%params%Temp(tmc_env%params%nr_temp))
657 48 : tmc_env%params%Temp(:) = inp_Temp(:)
658 : ELSE
659 12 : tmin = inp_Temp(1)
660 12 : tmax = inp_Temp(2)
661 36 : ALLOCATE (tmc_env%params%Temp(tmc_env%params%nr_temp))
662 12 : tmc_env%params%Temp(1) = tmin
663 36 : DO itmp = 2, SIZE(tmc_env%params%Temp)
664 36 : tmc_env%params%Temp(itmp) = tmc_env%params%Temp(itmp - 1) + (tmax - tmin)/(SIZE(tmc_env%params%Temp) - 1.0_dp)
665 : END DO
666 48 : IF (ANY(tmc_env%params%Temp < 0.0_dp)) THEN
667 : CALL cp_abort(__LOCATION__, "The temperatures are negative. Should be specified using "// &
668 0 : "TEMPERATURE {T_min} {T_max} and NR_TEMPERATURE {#temperatures}")
669 : END IF
670 : END IF
671 :
672 28 : CALL section_vals_val_get(tmc_section, "TASK_TYPE", explicit=explicit_key)
673 28 : IF (explicit_key) THEN
674 0 : CALL section_vals_val_get(tmc_section, "TASK_TYPE", c_val=c_tmp)
675 0 : SELECT CASE (TRIM(c_tmp))
676 : CASE (TRIM(tmc_default_unspecified_name))
677 0 : tmc_env%params%task_type = task_type_MC
678 : CASE ("IDEAL_GAS")
679 0 : tmc_env%params%task_type = task_type_ideal_gas
680 : CASE DEFAULT
681 : CALL cp_warn(__LOCATION__, &
682 : 'unknown TMC task type "'//TRIM(c_tmp)//'" specified. '// &
683 0 : " Set to default.")
684 0 : tmc_env%params%task_type = task_type_MC
685 : END SELECT
686 : END IF
687 :
688 28 : END SUBROUTINE tmc_preread_input
689 :
690 : ! **************************************************************************************************
691 : !> \brief read the tmc subsection from the input file
692 : !> \param input points to the tmc subsection in the input file
693 : !> \param tmc_env structure for storing all the tmc parameters
694 : !> \author Mandes 11.2012
695 : ! **************************************************************************************************
696 140 : SUBROUTINE tmc_read_input(input, tmc_env)
697 : TYPE(section_vals_type), POINTER :: input
698 : TYPE(tmc_env_type), POINTER :: tmc_env
699 :
700 : INTEGER :: itmp
701 : LOGICAL :: explicit, flag
702 : REAL(KIND=dp) :: r_tmp
703 28 : REAL(KIND=dp), DIMENSION(:), POINTER :: r_arr_tmp
704 : TYPE(section_vals_type), POINTER :: tmc_section
705 :
706 28 : NULLIFY (tmc_section)
707 :
708 0 : CPASSERT(ASSOCIATED(input))
709 :
710 28 : tmc_section => section_vals_get_subs_vals(input, "MOTION%TMC")
711 28 : CALL section_vals_get(tmc_section, explicit=flag)
712 28 : CPASSERT(flag)
713 :
714 : ! only for the master
715 28 : IF (tmc_env%tmc_comp_set%group_nr == 0) THEN
716 14 : CPASSERT(ASSOCIATED(tmc_env%m_env))
717 : ! the walltime input can be done as HH:MM:SS or just in seconds.
718 : CALL cp2k_get_walltime(section=input, keyword_name="GLOBAL%WALLTIME", &
719 14 : walltime=tmc_env%m_env%walltime)
720 :
721 14 : CALL section_vals_val_get(tmc_section, "NUM_MC_ELEM", i_val=tmc_env%m_env%num_MC_elem)
722 14 : CALL section_vals_val_get(tmc_section, "RND_DETERMINISTIC", i_val=tmc_env%m_env%rnd_init)
723 : ! restarting
724 14 : CALL section_vals_val_get(tmc_section, "RESTART_IN", c_val=tmc_env%m_env%restart_in_file_name)
725 14 : IF (tmc_env%m_env%restart_in_file_name == tmc_default_unspecified_name) THEN
726 3 : tmc_env%m_env%restart_in_file_name = tmc_default_restart_in_file_name
727 3 : INQUIRE (FILE=tmc_env%m_env%restart_in_file_name, EXIST=flag)
728 3 : IF (.NOT. flag) tmc_env%m_env%restart_in_file_name = ""
729 : END IF
730 14 : CALL section_vals_val_get(tmc_section, "RESTART_OUT", i_val=tmc_env%m_env%restart_out_step)
731 : ! restart just at the end (lone keyword)
732 14 : IF (tmc_env%m_env%restart_out_step == -9) THEN
733 3 : tmc_env%m_env%restart_out_file_name = tmc_default_restart_out_file_name
734 3 : tmc_env%m_env%restart_out_step = HUGE(tmc_env%m_env%restart_out_step)
735 : END IF
736 14 : IF (tmc_env%m_env%restart_out_step < 0) THEN
737 : CALL cp_abort(__LOCATION__, &
738 : "Please specify a valid value for the frequency "// &
739 : "to write restart files (RESTART_OUT #). "// &
740 : "# > 0 to define the amount of Markov chain elements in between, "// &
741 : "or 0 to deactivate the restart file writing. "// &
742 0 : "Lonely keyword writes restart file only at the end of the run.")
743 : END IF
744 :
745 14 : CALL section_vals_val_get(tmc_section, "INFO_OUT_STEP_SIZE", i_val=tmc_env%m_env%info_out_step_size)
746 14 : CALL section_vals_val_get(tmc_section, "DOT_TREE", c_val=tmc_env%params%dot_file_name)
747 14 : CALL section_vals_val_get(tmc_section, "ALL_CONF_FILE_NAME", c_val=tmc_env%params%all_conf_file_name)
748 14 : IF (tmc_env%params%dot_file_name /= "") tmc_env%params%DRAW_TREE = .TRUE.
749 :
750 : ! everything for the worker group
751 : ELSE IF (tmc_env%tmc_comp_set%group_nr /= 0) THEN
752 14 : CPASSERT(ASSOCIATED(tmc_env%w_env))
753 : END IF
754 :
755 : ! stuff everyone needs to know
756 :
757 : ! the NMC_FILE_NAME is already read in tmc_preread_input
758 28 : CALL section_vals_val_get(tmc_section, "ENERGY_FILE_NAME", c_val=tmc_env%params%energy_inp_file)
759 : ! file name keyword without file name
760 28 : IF (tmc_env%params%energy_inp_file == "") THEN
761 0 : CPABORT("a valid exact energy input file has to be specified ")
762 : END IF
763 : ! check file existence
764 28 : INQUIRE (FILE=TRIM(tmc_env%params%energy_inp_file), EXIST=flag, IOSTAT=itmp)
765 28 : IF (.NOT. flag .OR. itmp /= 0) THEN
766 : CALL cp_abort(__LOCATION__, "a valid exact energy input file has to be specified, "// &
767 0 : TRIM(tmc_env%params%energy_inp_file)//" does not exist.")
768 : END IF
769 :
770 28 : CALL section_vals_val_get(tmc_section, "NUM_MV_ELEM_IN_CELL", i_val=tmc_env%params%nr_elem_mv)
771 :
772 28 : CALL section_vals_val_get(tmc_section, "VOLUME_ISOTROPIC", l_val=tmc_env%params%v_isotropic)
773 28 : CALL section_vals_val_get(tmc_section, "PRESSURE", r_val=tmc_env%params%pressure)
774 28 : tmc_env%params%pressure = tmc_env%params%pressure/au2bar
775 28 : CALL section_vals_val_get(tmc_section, "MOVE_CENTER_OF_MASS", l_val=tmc_env%params%mv_cen_of_mass)
776 :
777 28 : CALL section_vals_val_get(tmc_section, "SUB_BOX", r_vals=r_arr_tmp)
778 28 : IF (SIZE(r_arr_tmp) > 1) THEN
779 0 : IF (SIZE(r_arr_tmp) /= tmc_env%params%dim_per_elem) THEN
780 0 : CPABORT("The entered sub box sizes does not fit in number of dimensions.")
781 : END IF
782 0 : IF (ANY(r_arr_tmp <= 0.0_dp)) THEN
783 0 : CPABORT("The entered sub box lengths should be greater than 0.")
784 : END IF
785 0 : DO itmp = 1, SIZE(tmc_env%params%sub_box_size)
786 0 : tmc_env%params%sub_box_size(itmp) = r_arr_tmp(itmp)/au2a
787 : END DO
788 28 : ELSE IF (r_arr_tmp(1) > 0.0_dp) THEN
789 2 : r_tmp = r_arr_tmp(1)/au2a
790 8 : tmc_env%params%sub_box_size(:) = r_tmp
791 : END IF
792 :
793 : ! read all the distinct moves
794 : CALL read_init_move_types(tmc_params=tmc_env%params, &
795 28 : tmc_section=tmc_section)
796 :
797 28 : CALL section_vals_val_get(tmc_section, "ESIMATE_ACC_PROB", l_val=tmc_env%params%esimate_acc_prob)
798 28 : CALL section_vals_val_get(tmc_section, "SPECULATIVE_CANCELING", l_val=tmc_env%params%SPECULATIVE_CANCELING)
799 28 : CALL section_vals_val_get(tmc_section, "USE_SCF_ENERGY_INFO", l_val=tmc_env%params%use_scf_energy_info)
800 : ! printing
801 28 : CALL section_vals_val_get(tmc_section, "PRINT_ONLY_ACC", l_val=tmc_env%params%print_only_diff_conf)
802 28 : CALL section_vals_val_get(tmc_section, "PRINT_COORDS", l_val=tmc_env%params%print_trajectory)
803 28 : CALL section_vals_val_get(tmc_section, "PRINT_DIPOLE", explicit=explicit)
804 28 : IF (explicit) THEN
805 0 : CALL section_vals_val_get(tmc_section, "PRINT_DIPOLE", l_val=tmc_env%params%print_dipole)
806 : END IF
807 28 : CALL section_vals_val_get(tmc_section, "PRINT_FORCES", explicit=explicit)
808 28 : IF (explicit) THEN
809 4 : CALL section_vals_val_get(tmc_section, "PRINT_FORCES", l_val=tmc_env%params%print_forces)
810 : END IF
811 28 : CALL section_vals_val_get(tmc_section, "PRINT_CELL", explicit=explicit)
812 28 : IF (explicit) THEN
813 4 : CALL section_vals_val_get(tmc_section, "PRINT_CELL", l_val=tmc_env%params%print_cell)
814 : END IF
815 28 : CALL section_vals_val_get(tmc_section, "PRINT_ENERGIES", l_val=tmc_env%params%print_energies)
816 :
817 28 : END SUBROUTINE tmc_read_input
818 :
819 : ! **************************************************************************************************
820 : !> \brief creates a new para environment for tmc
821 : !> \param tmc_comp_set structure with parameters for computational setup
822 : !> \param para_env the old parallel environment
823 : !> \param ana_on_the_fly ...
824 : !> \param success ...
825 : !> \author Mandes 11.2012
826 : ! **************************************************************************************************
827 28 : SUBROUTINE tmc_redistributing_cores(tmc_comp_set, para_env, ana_on_the_fly, &
828 : success)
829 : TYPE(tmc_comp_set_type), POINTER :: tmc_comp_set
830 : TYPE(mp_para_env_type), POINTER :: para_env
831 : INTEGER :: ana_on_the_fly
832 : LOGICAL :: success
833 :
834 : INTEGER :: cc_group, cc_group_rank, master_ana_group, master_ana_rank, &
835 : master_first_e_worker_g, master_first_e_worker_r, master_worker_group, &
836 : master_worker_rank, my_mpi_undefined, total_used
837 : LOGICAL :: flag, master
838 :
839 28 : CPASSERT(ASSOCIATED(tmc_comp_set))
840 28 : CPASSERT(ASSOCIATED(para_env))
841 :
842 : ! colors and positions for new communicators
843 : ! variables for printing
844 28 : tmc_comp_set%group_nr = -1
845 28 : my_mpi_undefined = para_env%num_pe + 10000 !HUGE(my_mpi_undefined)! mp_undefined
846 28 : master_worker_group = my_mpi_undefined
847 28 : master_worker_rank = -1
848 28 : cc_group = my_mpi_undefined
849 28 : cc_group_rank = -1
850 28 : master_first_e_worker_g = my_mpi_undefined
851 28 : master_first_e_worker_r = -1
852 28 : master_ana_group = my_mpi_undefined
853 28 : master_ana_rank = -1
854 :
855 28 : master = .FALSE.
856 28 : flag = .FALSE.
857 28 : success = .TRUE.
858 :
859 28 : IF (para_env%num_pe <= 1) THEN
860 0 : CPWARN("TMC need at least 2 cores (one for master, one for worker)")
861 0 : success = .FALSE.
862 : ELSE
863 : ! check if there are enougth cores available
864 28 : IF (tmc_comp_set%group_ener_size*tmc_comp_set%group_ener_nr > (para_env%num_pe - 1)) THEN
865 0 : CPWARN("The selected energy group size is too huge. ")
866 : END IF
867 : IF (flag) THEN
868 : tmc_comp_set%group_ener_nr = INT((para_env%num_pe - 1)/ &
869 : REAL(tmc_comp_set%group_ener_size, KIND=dp))
870 : IF (tmc_comp_set%group_ener_nr < 1) THEN
871 : CPWARN("The selected energy group size is too huge. ")
872 : END IF
873 : IF (flag) success = .FALSE.
874 : END IF
875 :
876 : ! set the amount of configurational change worker groups
877 28 : tmc_comp_set%group_cc_nr = 0
878 28 : IF (tmc_comp_set%group_cc_size > 0) THEN
879 : tmc_comp_set%group_cc_nr = INT((para_env%num_pe - 1 - tmc_comp_set%ana_on_the_fly &
880 : - tmc_comp_set%group_ener_size*tmc_comp_set%group_ener_nr)/ &
881 0 : REAL(tmc_comp_set%group_cc_size, KIND=dp))
882 :
883 0 : IF (tmc_comp_set%group_cc_nr < 1) THEN
884 : CALL cp_warn(__LOCATION__, &
885 0 : "There are not enougth cores left for creating groups for configurational change.")
886 : END IF
887 : IF (flag) success = .FALSE.
888 : END IF
889 :
890 : total_used = tmc_comp_set%group_ener_size*tmc_comp_set%group_ener_nr + &
891 : tmc_comp_set%group_cc_size*tmc_comp_set%group_cc_nr + &
892 28 : tmc_comp_set%ana_on_the_fly
893 28 : IF (para_env%num_pe - 1 > total_used) THEN
894 0 : CPWARN(" mpi ranks are unused, but can be used for analysis.")
895 : END IF
896 :
897 : ! determine the master node
898 28 : IF (para_env%mepos == para_env%num_pe - 1) THEN
899 14 : master = .TRUE.
900 14 : master_worker_group = para_env%num_pe + 3 ! belong to master_worker_comm
901 14 : master_worker_rank = 0 ! rank in m_w_comm
902 14 : master_first_e_worker_g = para_env%num_pe + 3 ! belong to master_first_energy_worker_comm
903 14 : master_first_e_worker_r = 0
904 14 : tmc_comp_set%group_nr = 0 !para_env%num_pe +3
905 14 : master_ana_group = para_env%num_pe + 4
906 14 : master_ana_rank = 0
907 : ELSE
908 : ! energy calculation groups
909 14 : IF (para_env%mepos < tmc_comp_set%group_ener_size*tmc_comp_set%group_ener_nr) THEN
910 14 : tmc_comp_set%group_nr = INT(para_env%mepos/tmc_comp_set%group_ener_size) + 1 ! assign to groups
911 : ! master of worker group
912 14 : IF (MODULO(para_env%mepos, tmc_comp_set%group_ener_size) == 0) THEN ! tmc_comp_set%group_nr masters
913 14 : master_worker_group = para_env%num_pe + 3 ! belong to master_worker_comm
914 14 : master_worker_rank = tmc_comp_set%group_nr ! rank in m_w_comm
915 14 : IF (master_worker_rank == 1) THEN
916 14 : master_first_e_worker_g = para_env%num_pe + 3 ! belong to master_first_energy_worker_comm
917 14 : master_first_e_worker_r = 1
918 : END IF
919 : END IF
920 14 : cc_group = tmc_comp_set%group_nr
921 : cc_group_rank = para_env%mepos - &
922 14 : (tmc_comp_set%group_nr - 1)*tmc_comp_set%group_ener_size ! rank in worker group
923 :
924 : ! configurational change groups
925 0 : ELSE IF (para_env%mepos < (tmc_comp_set%group_ener_size*tmc_comp_set%group_ener_nr + &
926 : tmc_comp_set%group_cc_size*tmc_comp_set%group_cc_nr)) THEN
927 0 : cc_group_rank = para_env%mepos - tmc_comp_set%group_ener_size*tmc_comp_set%group_ener_nr ! temporary
928 0 : tmc_comp_set%group_nr = tmc_comp_set%group_ener_nr + 1 + INT(cc_group_rank/tmc_comp_set%group_cc_size)
929 0 : cc_group = tmc_comp_set%group_nr
930 : ! master of worker group
931 0 : IF (MODULO(cc_group_rank, tmc_comp_set%group_cc_size) == 0) THEN ! tmc_comp_set%group_nr masters
932 0 : master_worker_group = para_env%num_pe + 3 ! belong to master_worker_comm
933 0 : master_worker_rank = tmc_comp_set%group_nr ! rank in m_w_comm
934 : END IF
935 : !cc_group_rank = cc_group_rank-(tmc_comp_set%group_nr-1)*tmc_comp_set%group_cc_size ! rank in worker group
936 0 : cc_group_rank = MODULO(cc_group_rank, tmc_comp_set%group_cc_size) ! rank in worker group
937 : ELSE
938 : ! not used cores
939 : ! up to now we use just one core for doing the analysis
940 0 : IF (para_env%mepos == para_env%num_pe - 2) THEN
941 0 : tmc_comp_set%group_nr = para_env%mepos - (para_env%num_pe - 1) ! negative
942 0 : CPASSERT(tmc_comp_set%group_nr < 0)
943 0 : IF (para_env%mepos >= para_env%num_pe - 1 - ana_on_the_fly) THEN
944 0 : master_ana_group = para_env%num_pe + 4
945 0 : master_ana_rank = -tmc_comp_set%group_nr
946 : END IF
947 : END IF
948 : END IF
949 : END IF
950 :
951 28 : IF (success) THEN
952 : ! -- splitting communicators
953 : ! worker intern communication
954 28 : ALLOCATE (tmc_comp_set%para_env_sub_group)
955 28 : CALL tmc_comp_set%para_env_sub_group%from_split(para_env, cc_group, cc_group_rank)
956 : ! not the unused cores
957 28 : IF (cc_group_rank < 0) THEN
958 14 : CALL tmc_comp_set%para_env_sub_group%free()
959 14 : DEALLOCATE (tmc_comp_set%para_env_sub_group)
960 : END IF
961 :
962 : ! worker master communication
963 28 : ALLOCATE (tmc_comp_set%para_env_m_w)
964 28 : CALL tmc_comp_set%para_env_m_w%from_split(para_env, master_worker_group, master_worker_rank)
965 : ! not the unused cores
966 28 : IF (master_worker_rank < 0) THEN
967 0 : CALL tmc_comp_set%para_env_m_w%free()
968 0 : DEALLOCATE (tmc_comp_set%para_env_m_w)
969 : END IF
970 :
971 : ! communicator only for first energy worker master and global master
972 28 : ALLOCATE (tmc_comp_set%para_env_m_first_w)
973 28 : CALL tmc_comp_set%para_env_m_first_w%from_split(para_env, master_first_e_worker_g, master_first_e_worker_r)
974 : ! not the unused cores
975 28 : IF (master_first_e_worker_r < 0) THEN
976 0 : CALL tmc_comp_set%para_env_m_first_w%free()
977 0 : DEALLOCATE (tmc_comp_set%para_env_m_first_w)
978 : END IF
979 :
980 : ! communicator only for analysis worker and global master
981 28 : ALLOCATE (tmc_comp_set%para_env_m_ana)
982 28 : CALL tmc_comp_set%para_env_m_ana%from_split(para_env, master_ana_group, master_ana_rank)
983 28 : IF (master_ana_rank < 0) THEN
984 14 : CALL tmc_comp_set%para_env_m_ana%free()
985 14 : DEALLOCATE (tmc_comp_set%para_env_m_ana)
986 : END IF
987 :
988 : ! communicator for master only to handle external control
989 28 : master_ana_group = my_mpi_undefined
990 28 : master_ana_rank = -1
991 28 : IF (master) THEN
992 14 : master_ana_group = 1
993 14 : master_ana_rank = 1
994 : END IF
995 28 : ALLOCATE (tmc_comp_set%para_env_m_only)
996 28 : CALL tmc_comp_set%para_env_m_only%from_split(para_env, master_ana_group, master_ana_rank)
997 28 : IF (master_ana_rank < 0) THEN
998 14 : CALL tmc_comp_set%para_env_m_only%free()
999 14 : DEALLOCATE (tmc_comp_set%para_env_m_only)
1000 : END IF
1001 : END IF
1002 : END IF
1003 28 : END SUBROUTINE tmc_redistributing_cores
1004 :
1005 : ! **************************************************************************************************
1006 : !> \brief prints the most important parameters used for TMC
1007 : !> \param tmc_env tructure with parameters for TMC
1008 : !> \author Mandes 11.2012
1009 : ! **************************************************************************************************
1010 14 : SUBROUTINE tmc_print_params(tmc_env)
1011 : TYPE(tmc_env_type), POINTER :: tmc_env
1012 :
1013 : CHARACTER(LEN=*), PARAMETER :: fmt_my = '(T2,A,"| ",A,T41,A40)', plabel = "TMC"
1014 :
1015 : CHARACTER(LEN=80) :: c_tmp, fmt_tmp
1016 : INTEGER :: file_nr
1017 :
1018 14 : CPASSERT(ASSOCIATED(tmc_env))
1019 14 : CPASSERT(ASSOCIATED(tmc_env%tmc_comp_set))
1020 : ! only the master prints out
1021 14 : IF (tmc_env%tmc_comp_set%group_nr == 0) THEN
1022 14 : file_nr = tmc_env%m_env%io_unit
1023 14 : CPASSERT(ASSOCIATED(tmc_env%tmc_comp_set%para_env_m_w))
1024 14 : CPASSERT(ASSOCIATED(tmc_env%m_env))
1025 :
1026 14 : CALL m_flush(file_nr)
1027 14 : WRITE (file_nr, *)
1028 :
1029 14 : WRITE (UNIT=file_nr, FMT="(/,T2,A)") REPEAT("-", 79)
1030 14 : WRITE (UNIT=file_nr, FMT="(T2,A,T80,A)") "-", "-"
1031 14 : WRITE (UNIT=file_nr, FMT="(T2,A,T35,A,T80,A)") "-", "TMC setting", "-"
1032 14 : WRITE (UNIT=file_nr, FMT="(T2,A,T80,A)") "-", "-"
1033 14 : WRITE (UNIT=file_nr, FMT="(T2,A)") REPEAT("-", 79)
1034 :
1035 14 : WRITE (UNIT=file_nr, FMT="(T2,A,T35,A,T80,A)") "-", "distribution of cores", "-"
1036 14 : WRITE (file_nr, FMT=fmt_my) plabel, "number of all working groups ", &
1037 28 : cp_to_string(tmc_env%tmc_comp_set%para_env_m_w%num_pe - 1)
1038 14 : WRITE (file_nr, FMT=fmt_my) plabel, "number of groups (ener|cc)", &
1039 : cp_to_string(tmc_env%tmc_comp_set%group_ener_nr)//" | "// &
1040 28 : cp_to_string(tmc_env%tmc_comp_set%group_cc_nr)
1041 14 : WRITE (file_nr, FMT=fmt_my) plabel, "cores per group (ener|cc) ", &
1042 : cp_to_string(tmc_env%tmc_comp_set%group_ener_size)//" | "// &
1043 28 : cp_to_string(tmc_env%tmc_comp_set%group_cc_size)
1044 14 : IF (ASSOCIATED(tmc_env%tmc_comp_set%para_env_m_ana)) THEN
1045 14 : WRITE (file_nr, FMT=fmt_my) plabel, "Analysis groups ", &
1046 28 : cp_to_string(tmc_env%tmc_comp_set%para_env_m_ana%num_pe - 1)
1047 : END IF
1048 14 : IF (SIZE(tmc_env%params%Temp(:)) <= 7) THEN
1049 14 : WRITE (fmt_tmp, *) '(T2,A,"| ",A,T25,A56)'
1050 14 : c_tmp = ""
1051 40 : WRITE (c_tmp, FMT="(1000F8.2)") tmc_env%params%Temp(:)
1052 14 : WRITE (file_nr, FMT=fmt_tmp) plabel, "Temperature(s) [K]", TRIM(c_tmp)
1053 : ELSE
1054 0 : WRITE (file_nr, FMT='(A,1000F8.2)') " "//plabel//"| Temperature(s) [K]", &
1055 0 : tmc_env%params%Temp(:)
1056 : END IF
1057 14 : WRITE (file_nr, FMT=fmt_my) plabel, "# of Monte Carlo Chain elements: ", &
1058 28 : cp_to_string(tmc_env%m_env%num_MC_elem)
1059 14 : WRITE (file_nr, FMT=fmt_my) plabel, "exact potential input file:", &
1060 28 : TRIM(tmc_env%params%energy_inp_file)
1061 14 : IF (tmc_env%params%NMC_inp_file /= "") THEN
1062 5 : WRITE (file_nr, FMT=fmt_my) plabel, "approximate potential input file:", &
1063 10 : TRIM(tmc_env%params%NMC_inp_file)
1064 : END IF
1065 53 : IF (ANY(tmc_env%params%sub_box_size > 0.0_dp)) THEN
1066 1 : WRITE (fmt_tmp, *) '(T2,A,"| ",A,T25,A56)'
1067 1 : c_tmp = ""
1068 4 : WRITE (c_tmp, FMT="(1000F8.2)") tmc_env%params%sub_box_size(:)*au2a
1069 1 : WRITE (file_nr, FMT=fmt_tmp) plabel, "Sub box size [A]", TRIM(c_tmp)
1070 : END IF
1071 14 : IF (tmc_env%params%pressure > 0.0_dp) THEN
1072 6 : WRITE (file_nr, FMT=fmt_my) plabel, "Pressure [bar]: ", &
1073 12 : cp_to_string(tmc_env%params%pressure*au2bar)
1074 : END IF
1075 14 : WRITE (file_nr, FMT=fmt_my) plabel, "Numbers of atoms/molecules moved "
1076 14 : WRITE (file_nr, FMT=fmt_my) plabel, " within one conf. change", &
1077 28 : cp_to_string(tmc_env%params%nr_elem_mv)
1078 14 : WRITE (UNIT=file_nr, FMT="(/,T2,A)") REPEAT("-", 79)
1079 : END IF
1080 :
1081 14 : END SUBROUTINE tmc_print_params
1082 :
1083 : END MODULE tmc_setup
|