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