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