Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief Main force create for embedding
10 : !> \author Vladimir Rybkin 02.2018
11 : ! **************************************************************************************************
12 : MODULE embed_main
13 : USE cp_files, ONLY: open_file
14 : USE cp_log_handling, ONLY: cp_get_default_logger,&
15 : cp_logger_create,&
16 : cp_logger_set,&
17 : cp_logger_type,&
18 : cp_to_string
19 : USE cp_output_handling, ONLY: cp_print_key_unit_nr
20 : USE embed_environment, ONLY: embed_init
21 : USE embed_types, ONLY: embed_env_create,&
22 : embed_env_type
23 : USE input_section_types, ONLY: section_vals_type,&
24 : section_vals_val_get
25 : USE kinds, ONLY: default_path_length,&
26 : default_string_length
27 : USE message_passing, ONLY: mp_para_env_type
28 : #include "./base/base_uses.f90"
29 :
30 : IMPLICIT NONE
31 :
32 : PRIVATE
33 :
34 : ! Global parameters
35 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'embed_main'
36 :
37 : PUBLIC :: embed_create_force_env
38 :
39 : CONTAINS
40 : ! **************************************************************************************************
41 : !> \brief Controls program flow for embedded calculations
42 : !> \param embed_env ...
43 : !> \param root_section ...
44 : !> \param para_env ...
45 : !> \param force_env_section ...
46 : !> \param n_subforce_eval ...
47 : !> \param use_motion_section ...
48 : !> \author Vladimir Rybkin
49 : ! **************************************************************************************************
50 24 : SUBROUTINE embed_create_force_env(embed_env, root_section, para_env, &
51 : force_env_section, n_subforce_eval, use_motion_section)
52 :
53 : TYPE(embed_env_type), INTENT(OUT) :: embed_env
54 : TYPE(section_vals_type), POINTER :: root_section
55 : TYPE(mp_para_env_type), POINTER :: para_env
56 : TYPE(section_vals_type), POINTER :: force_env_section
57 : INTEGER, INTENT(IN) :: n_subforce_eval
58 : LOGICAL, INTENT(IN) :: use_motion_section
59 :
60 : CHARACTER(LEN=*), PARAMETER :: routineN = 'embed_create_force_env'
61 :
62 : CHARACTER(len=default_path_length) :: c_val, input_file_path, output_file_path
63 : INTEGER :: group_size_wish, handle, i, lp, &
64 : n_rep_val, ngroup_wish, output_unit, &
65 : unit_nr
66 24 : INTEGER, DIMENSION(:), POINTER :: group_partition, i_vals
67 : TYPE(cp_logger_type), POINTER :: logger
68 : TYPE(mp_para_env_type), POINTER :: sub_para_env
69 :
70 24 : CALL timeset(routineN, handle)
71 24 : logger => cp_get_default_logger()
72 : output_unit = cp_print_key_unit_nr(logger, force_env_section, "EMBED%PRINT%PROGRAM_RUN_INFO", &
73 24 : extension=".log")
74 :
75 24 : CALL embed_env_create(embed_env, para_env=para_env)
76 : ! Setup the new parallel env
77 24 : NULLIFY (group_partition)
78 24 : CALL section_vals_val_get(force_env_section, "EMBED%GROUP_PARTITION", n_rep_val=n_rep_val)
79 :
80 : ! Split the current communicator
81 72 : ALLOCATE (embed_env%group_distribution(0:para_env%num_pe - 1))
82 24 : ALLOCATE (sub_para_env)
83 24 : IF (n_rep_val > 0) THEN
84 0 : CALL section_vals_val_get(force_env_section, "EMBED%GROUP_PARTITION", i_vals=i_vals)
85 0 : ALLOCATE (group_partition(0:SIZE(i_vals) - 1))
86 0 : group_partition(:) = i_vals
87 0 : ngroup_wish = SIZE(i_vals)
88 :
89 : CALL sub_para_env%from_split(para_env, embed_env%ngroups, embed_env%group_distribution, &
90 : n_subgroups=ngroup_wish, &
91 0 : group_partition=group_partition)
92 : ELSE
93 24 : CALL section_vals_val_get(force_env_section, "EMBED%NGROUPS", n_rep_val=n_rep_val)
94 24 : IF (n_rep_val > 0) THEN
95 24 : CALL section_vals_val_get(force_env_section, "EMBED%NGROUPS", i_val=ngroup_wish)
96 24 : IF (ngroup_wish /= 1) CPABORT("Embedding runs with NGROUP=1 and no group partitioning")
97 : ELSE
98 0 : ngroup_wish = n_subforce_eval
99 : END IF
100 24 : group_size_wish = MAX(1, para_env%num_pe/ngroup_wish)
101 :
102 : CALL sub_para_env%from_split(para_env, embed_env%ngroups, embed_env%group_distribution, &
103 24 : subgroup_min_size=group_size_wish)
104 : END IF
105 :
106 24 : IF (output_unit > 0) THEN
107 12 : WRITE (output_unit, FMT="(T2,A,T71,I10)") "EMBED_ENV| Number of created MPI groups:", embed_env%ngroups
108 12 : WRITE (output_unit, FMT="(T2,A)", ADVANCE="NO") "EMBED_ENV| Task to group correspondence:"
109 36 : DO i = 0, para_env%num_pe - 1
110 24 : IF (MODULO(i, 4) == 0) WRITE (output_unit, *)
111 : WRITE (output_unit, FMT='(A3,I4,A3,I4,A1)', ADVANCE="NO") &
112 36 : " (", i, " : ", embed_env%group_distribution(i), ")"
113 : END DO
114 12 : WRITE (output_unit, *)
115 : END IF
116 24 : IF (ASSOCIATED(group_partition)) THEN
117 0 : DEALLOCATE (group_partition)
118 : END IF
119 : ! Allocate para_env and handle the several loggers
120 96 : ALLOCATE (embed_env%sub_para_env(embed_env%ngroups))
121 96 : ALLOCATE (embed_env%sub_logger(embed_env%ngroups))
122 72 : ALLOCATE (embed_env%energies(n_subforce_eval))
123 : !
124 24 : NULLIFY (logger)
125 24 : i = embed_env%group_distribution(para_env%mepos) + 1
126 : ! Create sub_para_env
127 24 : embed_env%sub_para_env(i)%para_env => sub_para_env
128 : ! Create sub_logger
129 24 : IF (embed_env%sub_para_env(i)%para_env%is_source()) THEN
130 : ! Redirecting output of subforce_eval to file..
131 : CALL section_vals_val_get(root_section, "GLOBAL%PROJECT_NAME", &
132 12 : c_val=input_file_path)
133 12 : lp = LEN_TRIM(input_file_path)
134 : input_file_path(lp + 1:LEN(input_file_path)) = "-r-"// &
135 12 : ADJUSTL(cp_to_string(i))
136 12 : lp = LEN_TRIM(input_file_path)
137 12 : output_file_path = input_file_path(1:lp)//".out"
138 : CALL open_file(file_name=output_file_path, file_status="UNKNOWN", &
139 : file_action="WRITE", file_position="APPEND", &
140 12 : unit_number=unit_nr)
141 : ELSE
142 12 : unit_nr = -1
143 : END IF
144 : CALL cp_logger_create(embed_env%sub_logger(i)%p, &
145 : para_env=embed_env%sub_para_env(i)%para_env, &
146 : default_global_unit_nr=unit_nr, &
147 24 : close_global_unit_on_dealloc=.FALSE.)
148 : ! Try to use better names for the local log if it is not too late
149 : CALL section_vals_val_get(root_section, "GLOBAL%OUTPUT_FILE_NAME", &
150 24 : c_val=c_val)
151 24 : IF (c_val /= "") THEN
152 : CALL cp_logger_set(embed_env%sub_logger(i)%p, &
153 0 : local_filename=TRIM(c_val)//"_localLog")
154 : END IF
155 24 : CALL section_vals_val_get(root_section, "GLOBAL%PROJECT", c_val=c_val)
156 24 : IF (c_val /= "") THEN
157 : CALL cp_logger_set(embed_env%sub_logger(i)%p, &
158 24 : local_filename=TRIM(c_val)//"_localLog")
159 : END IF
160 24 : IF (LEN_TRIM(c_val) > default_string_length) THEN
161 0 : CPWARN("The project name will be truncated.")
162 : END IF
163 24 : embed_env%sub_logger(i)%p%iter_info%project_name = TRIM(c_val)
164 : CALL section_vals_val_get(root_section, "GLOBAL%PRINT_LEVEL", &
165 24 : i_val=embed_env%sub_logger(i)%p%iter_info%print_level)
166 :
167 : ! *** initializations for the setup of the EMBED environment ***
168 : CALL embed_init(embed_env, root_section, para_env, force_env_section, &
169 24 : use_motion_section)
170 24 : CALL timestop(handle)
171 :
172 48 : END SUBROUTINE embed_create_force_env
173 :
174 : END MODULE embed_main
|