Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief methods to setup replicas of the same system differing only by atom
10 : !> positions and velocities (as used in path integral or nudged elastic
11 : !> band for example)
12 : !> \par History
13 : !> 09.2005 created [fawzi]
14 : !> \author fawzi
15 : ! **************************************************************************************************
16 : MODULE replica_methods
17 : USE cp_control_types, ONLY: dft_control_type
18 : USE cp_files, ONLY: close_file,&
19 : open_file
20 : USE cp_log_handling, ONLY: cp_get_default_logger,&
21 : cp_logger_get_default_io_unit,&
22 : cp_logger_type,&
23 : cp_to_string
24 : USE cp_output_handling, ONLY: cp_add_iter_level
25 : USE cp_result_types, ONLY: cp_result_create,&
26 : cp_result_retain
27 : USE cp_subsys_types, ONLY: cp_subsys_get,&
28 : cp_subsys_set,&
29 : cp_subsys_type
30 : USE f77_interface, ONLY: calc_force,&
31 : create_force_env,&
32 : f_env_add_defaults,&
33 : f_env_rm_defaults,&
34 : f_env_type,&
35 : get_nparticle,&
36 : get_pos,&
37 : set_vel
38 : USE force_env_types, ONLY: force_env_get,&
39 : use_qs_force
40 : USE input_section_types, ONLY: section_type,&
41 : section_vals_type,&
42 : section_vals_val_get,&
43 : section_vals_val_set,&
44 : section_vals_write
45 : USE kinds, ONLY: default_path_length,&
46 : dp
47 : USE message_passing, ONLY: mp_comm_null,&
48 : mp_para_cart_type,&
49 : mp_para_env_type
50 : USE qs_environment_types, ONLY: get_qs_env,&
51 : qs_environment_type,&
52 : set_qs_env
53 : USE qs_wf_history_methods, ONLY: wfi_create,&
54 : wfi_create_for_kp
55 : USE qs_wf_history_types, ONLY: wfi_retain
56 : USE replica_types, ONLY: rep_env_sync,&
57 : rep_env_sync_results,&
58 : rep_envs_add_rep_env,&
59 : rep_envs_get_rep_env,&
60 : replica_env_type
61 : #include "./base/base_uses.f90"
62 :
63 : IMPLICIT NONE
64 : PRIVATE
65 :
66 : LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .TRUE.
67 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'replica_methods'
68 : INTEGER, SAVE, PRIVATE :: last_rep_env_id = 0
69 :
70 : PUBLIC :: rep_env_create, rep_env_calc_e_f
71 :
72 : CONTAINS
73 :
74 : ! **************************************************************************************************
75 : !> \brief creates a replica environment together with its force environment
76 : !> \param rep_env the replica environment that will be created
77 : !> \param para_env the parallel environment that will contain the replicas
78 : !> \param input the input used to initialize the force environment
79 : !> \param input_declaration ...
80 : !> \param nrep the number of replicas to calculate
81 : !> \param prep the number of processors for each replica
82 : !> \param sync_v if the velocity should be synchronized (defaults to false)
83 : !> \param keep_wf_history if wf history should be kept on a per replica
84 : !> basis (defaults to true for QS jobs)
85 : !> \param row_force to use the new mapping to the cart with rows
86 : !> working on force instead of columns.
87 : !> \author fawzi
88 : ! **************************************************************************************************
89 148 : SUBROUTINE rep_env_create(rep_env, para_env, input, input_declaration, nrep, prep, &
90 : sync_v, keep_wf_history, row_force)
91 : TYPE(replica_env_type), POINTER :: rep_env
92 : TYPE(mp_para_env_type), POINTER :: para_env
93 : TYPE(section_vals_type), POINTER :: input
94 : TYPE(section_type), POINTER :: input_declaration
95 : INTEGER :: nrep, prep
96 : LOGICAL, INTENT(in), OPTIONAL :: sync_v, keep_wf_history, row_force
97 :
98 : CHARACTER(len=default_path_length) :: input_file_path, output_file_path
99 : INTEGER :: forcedim, i, i0, ierr, ip, ir, irep, lp, &
100 : my_prep, new_env_id, nparticle, &
101 : nrep_local, unit_nr
102 148 : INTEGER, ALLOCATABLE, DIMENSION(:, :) :: gridinfo
103 : INTEGER, DIMENSION(2) :: dims, pos
104 : TYPE(cp_logger_type), POINTER :: logger
105 : TYPE(mp_para_cart_type), POINTER :: cart
106 : TYPE(mp_para_env_type), POINTER :: para_env_f, para_env_full, &
107 : para_env_inter_rep
108 :
109 148 : CPASSERT(.NOT. ASSOCIATED(rep_env))
110 148 : CPASSERT(ASSOCIATED(input_declaration))
111 :
112 148 : NULLIFY (cart, para_env_f, para_env_inter_rep)
113 148 : logger => cp_get_default_logger()
114 148 : unit_nr = cp_logger_get_default_io_unit(logger)
115 148 : new_env_id = -1
116 148 : forcedim = 1
117 148 : IF (PRESENT(row_force)) THEN
118 148 : IF (row_force) forcedim = 2
119 : END IF
120 148 : my_prep = MIN(prep, para_env%num_pe)
121 148 : dims(3 - forcedim) = MIN(para_env%num_pe/my_prep, nrep)
122 148 : dims(forcedim) = my_prep
123 148 : IF ((dims(1)*dims(2) /= para_env%num_pe) .AND. (unit_nr > 0)) THEN
124 0 : WRITE (unit_nr, FMT="(T2,A)") "REPLICA| WARNING: number of processors is not divisible by the number of replicas"
125 0 : WRITE (unit_nr, FMT="(T2,A,I0,A)") "REPLICA| ", para_env%num_pe - dims(1)*dims(2), " MPI process(es) will be idle"
126 : END IF
127 148 : ALLOCATE (cart)
128 148 : CALL cart%create(comm_old=para_env, ndims=2, dims=dims)
129 148 : IF (cart /= mp_comm_null) THEN
130 444 : pos = cart%mepos_cart
131 148 : ALLOCATE (para_env_full)
132 148 : para_env_full = cart
133 148 : ALLOCATE (para_env_f)
134 148 : CALL para_env_f%from_split(cart, pos(3 - forcedim))
135 148 : ALLOCATE (para_env_inter_rep)
136 148 : CALL para_env_inter_rep%from_split(cart, pos(forcedim))
137 148 : ALLOCATE (rep_env)
138 : ELSE
139 0 : pos = -1
140 0 : DEALLOCATE (cart)
141 : END IF
142 444 : ALLOCATE (gridinfo(2, 0:para_env%num_pe - 1))
143 148 : gridinfo = 0
144 444 : gridinfo(:, para_env%mepos) = pos
145 148 : CALL para_env%sum(gridinfo)
146 148 : IF (unit_nr > 0) THEN
147 74 : WRITE (unit_nr, FMT="(T2,A,T71,I10)") "REPLICA| layout of the replica grid, number of groups ", para_env_inter_rep%num_pe
148 74 : WRITE (unit_nr, FMT="(T2,A,T71,I10)") "REPLICA| layout of the replica grid, size of each group", para_env_f%num_pe
149 74 : WRITE (unit_nr, FMT="(T2,A)", ADVANCE="NO") "REPLICA| MPI process to grid (group,rank) correspondence:"
150 222 : DO i = 0, para_env%num_pe - 1
151 148 : IF (MODULO(i, 4) == 0) WRITE (unit_nr, *)
152 : WRITE (unit_nr, FMT='(A3,I4,A3,I4,A1,I4,A1)', ADVANCE="NO") &
153 148 : " (", i, " : ", gridinfo(3 - forcedim, i), ",", &
154 370 : gridinfo(forcedim, i), ")"
155 : END DO
156 74 : WRITE (unit_nr, *)
157 : END IF
158 148 : DEALLOCATE (gridinfo)
159 148 : IF (ASSOCIATED(rep_env)) THEN
160 148 : last_rep_env_id = last_rep_env_id + 1
161 148 : rep_env%id_nr = last_rep_env_id
162 148 : rep_env%ref_count = 1
163 148 : rep_env%nrep = nrep
164 148 : rep_env%sync_v = .FALSE.
165 148 : IF (PRESENT(sync_v)) rep_env%sync_v = sync_v
166 148 : rep_env%keep_wf_history = .TRUE.
167 148 : IF (PRESENT(keep_wf_history)) rep_env%keep_wf_history = keep_wf_history
168 148 : NULLIFY (rep_env%wf_history)
169 148 : NULLIFY (rep_env%results)
170 :
171 148 : rep_env%force_dim = forcedim
172 148 : rep_env%my_rep_group = cart%mepos_cart(3 - forcedim)
173 : ALLOCATE (rep_env%inter_rep_rank(0:para_env_inter_rep%num_pe - 1), &
174 740 : rep_env%force_rank(0:para_env_f%num_pe - 1))
175 414 : rep_env%inter_rep_rank = 0
176 148 : rep_env%inter_rep_rank(rep_env%my_rep_group) = para_env_inter_rep%mepos
177 680 : CALL para_env_inter_rep%sum(rep_env%inter_rep_rank)
178 326 : rep_env%force_rank = 0
179 148 : rep_env%force_rank(cart%mepos_cart(forcedim)) = para_env_f%mepos
180 504 : CALL para_env_f%sum(rep_env%force_rank)
181 :
182 : CALL section_vals_val_get(input, "GLOBAL%PROJECT_NAME", &
183 148 : c_val=input_file_path)
184 148 : rep_env%original_project_name = input_file_path
185 : ! By default replica_env handles files for each replica
186 : ! with the structure PROJECT_NAME-r-N where N is the
187 : ! number of the local replica..
188 148 : lp = LEN_TRIM(input_file_path)
189 : input_file_path(lp + 1:LEN(input_file_path)) = "-r-"// &
190 148 : ADJUSTL(cp_to_string(rep_env%my_rep_group))
191 148 : lp = LEN_TRIM(input_file_path)
192 : ! Setup new project name
193 : CALL section_vals_val_set(input, "GLOBAL%PROJECT_NAME", &
194 148 : c_val=input_file_path)
195 : ! Redirect the output of each replica on a same local file
196 148 : output_file_path = input_file_path(1:lp)//".out"
197 : CALL section_vals_val_set(input, "GLOBAL%OUTPUT_FILE_NAME", &
198 148 : c_val=TRIM(output_file_path))
199 :
200 : ! Dump an input file to warm-up new force_eval structures and
201 : ! delete them immediately afterwards..
202 148 : input_file_path(lp + 1:LEN(input_file_path)) = ".inp"
203 148 : IF (para_env_f%is_source()) THEN
204 : CALL open_file(file_name=TRIM(input_file_path), file_status="UNKNOWN", &
205 : file_form="FORMATTED", file_action="WRITE", &
206 133 : unit_number=unit_nr)
207 133 : CALL section_vals_write(input, unit_nr, hide_root=.TRUE.)
208 133 : CALL close_file(unit_nr)
209 : END IF
210 : CALL create_force_env(new_env_id, input_declaration, input_file_path, &
211 148 : output_file_path, para_env_f, ierr=ierr)
212 148 : CPASSERT(ierr == 0)
213 :
214 : ! Delete input files..
215 148 : IF (para_env_f%is_source()) THEN
216 : CALL open_file(file_name=TRIM(input_file_path), file_status="OLD", &
217 133 : file_form="FORMATTED", file_action="READ", unit_number=unit_nr)
218 133 : CALL close_file(unit_number=unit_nr, file_status="DELETE")
219 : END IF
220 :
221 148 : rep_env%f_env_id = new_env_id
222 148 : CALL get_nparticle(new_env_id, nparticle, ierr)
223 148 : CPASSERT(ierr == 0)
224 148 : rep_env%nparticle = nparticle
225 148 : rep_env%ndim = 3*nparticle
226 444 : ALLOCATE (rep_env%replica_owner(nrep))
227 :
228 148 : i0 = nrep/para_env_inter_rep%num_pe
229 148 : ir = MODULO(nrep, para_env_inter_rep%num_pe)
230 414 : DO ip = 0, para_env_inter_rep%num_pe - 1
231 916 : DO i = i0*ip + MIN(ip, ir) + 1, i0*(ip + 1) + MIN(ip + 1, ir)
232 768 : rep_env%replica_owner(i) = ip
233 : END DO
234 : END DO
235 :
236 148 : nrep_local = i0
237 148 : IF (rep_env%my_rep_group < ir) nrep_local = nrep_local + 1
238 : ALLOCATE (rep_env%local_rep_indices(nrep_local), &
239 740 : rep_env%rep_is_local(nrep))
240 148 : nrep_local = 0
241 650 : rep_env%rep_is_local = .FALSE.
242 650 : DO irep = 1, nrep
243 650 : IF (rep_env%replica_owner(irep) == rep_env%my_rep_group) THEN
244 266 : nrep_local = nrep_local + 1
245 266 : rep_env%local_rep_indices(nrep_local) = irep
246 266 : rep_env%rep_is_local(irep) = .TRUE.
247 : END IF
248 : END DO
249 148 : CPASSERT(nrep_local == SIZE(rep_env%local_rep_indices))
250 :
251 148 : rep_env%cart => cart
252 148 : rep_env%para_env => para_env_full
253 148 : rep_env%para_env_f => para_env_f
254 148 : rep_env%para_env_inter_rep => para_env_inter_rep
255 :
256 : ALLOCATE (rep_env%r(rep_env%ndim, nrep), rep_env%v(rep_env%ndim, nrep), &
257 1480 : rep_env%f(rep_env%ndim + 1, nrep))
258 :
259 313418 : rep_env%r = 0._dp
260 313920 : rep_env%f = 0._dp
261 313418 : rep_env%v = 0._dp
262 148 : CALL set_vel(rep_env%f_env_id, rep_env%v(:, 1), rep_env%ndim, ierr)
263 148 : CPASSERT(ierr == 0)
264 798 : DO i = 1, nrep
265 650 : IF (rep_env%rep_is_local(i)) THEN
266 266 : CALL get_pos(rep_env%f_env_id, rep_env%r(:, i), rep_env%ndim, ierr)
267 266 : CPASSERT(ierr == 0)
268 : END IF
269 : END DO
270 : END IF
271 148 : IF (ASSOCIATED(rep_env)) THEN
272 148 : CALL rep_envs_add_rep_env(rep_env)
273 148 : CALL rep_env_init_low(rep_env%id_nr, ierr)
274 148 : CPASSERT(ierr == 0)
275 : END IF
276 148 : END SUBROUTINE rep_env_create
277 :
278 : ! **************************************************************************************************
279 : !> \brief finishes the low level initialization of the replica env
280 : !> \param rep_env_id id_nr of the replica environment that should be initialized
281 : !> \param ierr will be non zero if there is an initialization error
282 : !> \author fawzi
283 : ! **************************************************************************************************
284 148 : SUBROUTINE rep_env_init_low(rep_env_id, ierr)
285 : INTEGER, INTENT(in) :: rep_env_id
286 : INTEGER, INTENT(out) :: ierr
287 :
288 : INTEGER :: i, in_use, stat
289 : LOGICAL :: do_kpoints, has_unit_metric
290 : TYPE(cp_logger_type), POINTER :: logger
291 : TYPE(cp_subsys_type), POINTER :: subsys
292 : TYPE(dft_control_type), POINTER :: dft_control
293 : TYPE(f_env_type), POINTER :: f_env
294 : TYPE(qs_environment_type), POINTER :: qs_env
295 : TYPE(replica_env_type), POINTER :: rep_env
296 :
297 148 : rep_env => rep_envs_get_rep_env(rep_env_id, ierr=stat)
298 148 : IF (.NOT. ASSOCIATED(rep_env)) THEN
299 0 : CPABORT("could not find rep_env with id_nr"//cp_to_string(rep_env_id))
300 : END IF
301 148 : NULLIFY (qs_env, dft_control, subsys)
302 148 : CALL f_env_add_defaults(f_env_id=rep_env%f_env_id, f_env=f_env)
303 148 : logger => cp_get_default_logger()
304 148 : logger%iter_info%iteration(1) = rep_env%my_rep_group
305 : CALL cp_add_iter_level(iteration_info=logger%iter_info, &
306 148 : level_name="REPLICA_EVAL")
307 : !wf interp
308 148 : IF (rep_env%keep_wf_history) THEN
309 148 : CALL force_env_get(f_env%force_env, in_use=in_use)
310 148 : IF (in_use == use_qs_force) THEN
311 30 : CALL force_env_get(f_env%force_env, qs_env=qs_env)
312 30 : CALL get_qs_env(qs_env, dft_control=dft_control)
313 126 : ALLOCATE (rep_env%wf_history(SIZE(rep_env%local_rep_indices)))
314 66 : DO i = 1, SIZE(rep_env%wf_history)
315 36 : NULLIFY (rep_env%wf_history(i)%wf_history)
316 66 : IF (i == 1) THEN
317 : CALL get_qs_env(qs_env, &
318 30 : wf_history=rep_env%wf_history(i)%wf_history)
319 30 : CALL wfi_retain(rep_env%wf_history(i)%wf_history)
320 : ELSE
321 : CALL get_qs_env(qs_env, has_unit_metric=has_unit_metric, &
322 6 : do_kpoints=do_kpoints)
323 : CALL wfi_create(rep_env%wf_history(i)%wf_history, &
324 : interpolation_method_nr= &
325 : dft_control%qs_control%wf_interpolation_method_nr, &
326 : extrapolation_order=dft_control%qs_control%wf_extrapolation_order, &
327 6 : has_unit_metric=has_unit_metric)
328 6 : IF (do_kpoints) THEN
329 0 : CALL wfi_create_for_kp(rep_env%wf_history(i)%wf_history)
330 : END IF
331 : END IF
332 : END DO
333 : ELSE
334 118 : rep_env%keep_wf_history = .FALSE.
335 : END IF
336 : END IF
337 946 : ALLOCATE (rep_env%results(rep_env%nrep))
338 650 : DO i = 1, rep_env%nrep
339 502 : NULLIFY (rep_env%results(i)%results)
340 650 : IF (i == 1) THEN
341 148 : CALL force_env_get(f_env%force_env, subsys=subsys)
342 148 : CALL cp_subsys_get(subsys, results=rep_env%results(i)%results)
343 148 : CALL cp_result_retain(rep_env%results(i)%results)
344 : ELSE
345 354 : CALL cp_result_create(rep_env%results(i)%results)
346 : END IF
347 : END DO
348 148 : CALL rep_env_sync(rep_env, rep_env%r)
349 148 : CALL rep_env_sync(rep_env, rep_env%v)
350 148 : CALL rep_env_sync(rep_env, rep_env%f)
351 :
352 148 : CALL f_env_rm_defaults(f_env, ierr)
353 148 : CPASSERT(ierr == 0)
354 148 : END SUBROUTINE rep_env_init_low
355 :
356 : ! **************************************************************************************************
357 : !> \brief evaluates the forces
358 : !> \param rep_env the replica environment on which you want to evaluate the
359 : !> forces
360 : !> \param calc_f if true calculates also the forces, if false only the
361 : !> energy
362 : !> \author fawzi
363 : !> \note
364 : !> indirect through f77_int_low to work around fortran madness
365 : ! **************************************************************************************************
366 8272 : SUBROUTINE rep_env_calc_e_f(rep_env, calc_f)
367 : TYPE(replica_env_type), POINTER :: rep_env
368 : LOGICAL, OPTIONAL :: calc_f
369 :
370 : CHARACTER(len=*), PARAMETER :: routineN = 'rep_env_calc_e_f'
371 :
372 : INTEGER :: handle, ierr, my_calc_f
373 :
374 4136 : CALL timeset(routineN, handle)
375 4136 : CPASSERT(ASSOCIATED(rep_env))
376 4136 : CPASSERT(rep_env%ref_count > 0)
377 4136 : my_calc_f = 0
378 4136 : IF (PRESENT(calc_f)) THEN
379 4136 : IF (calc_f) my_calc_f = 1
380 : END IF
381 4136 : CALL rep_env_calc_e_f_low(rep_env%id_nr, my_calc_f, ierr)
382 4136 : CPASSERT(ierr == 0)
383 4136 : CALL timestop(handle)
384 4136 : END SUBROUTINE rep_env_calc_e_f
385 :
386 : ! **************************************************************************************************
387 : !> \brief calculates energy and force, internal private method
388 : !> \param rep_env_id the id if the replica environment in which energy and
389 : !> forces have to be evaluated
390 : !> \param calc_f if nonzero calculates also the forces along with the
391 : !> energy
392 : !> \param ierr if an error happens this will be nonzero
393 : !> \author fawzi
394 : !> \note
395 : !> low level wrapper to export this function in f77_int_low and work
396 : !> around the handling of circular dependencies in fortran
397 : ! **************************************************************************************************
398 4136 : RECURSIVE SUBROUTINE rep_env_calc_e_f_low(rep_env_id, calc_f, ierr)
399 : INTEGER, INTENT(in) :: rep_env_id, calc_f
400 : INTEGER, INTENT(out) :: ierr
401 :
402 : TYPE(f_env_type), POINTER :: f_env
403 : TYPE(replica_env_type), POINTER :: rep_env
404 :
405 4136 : rep_env => rep_envs_get_rep_env(rep_env_id, ierr)
406 4136 : IF (ASSOCIATED(rep_env)) THEN
407 4136 : CALL f_env_add_defaults(f_env_id=rep_env%f_env_id, f_env=f_env)
408 4136 : CALL rep_env_calc_e_f_int(rep_env, calc_f /= 0)
409 4136 : CALL f_env_rm_defaults(f_env, ierr)
410 : ELSE
411 0 : ierr = 111
412 : END IF
413 4136 : END SUBROUTINE rep_env_calc_e_f_low
414 :
415 : ! **************************************************************************************************
416 : !> \brief calculates energy and force, internal private method
417 : !> \param rep_env the replica env to update
418 : !> \param calc_f if the force should be calculated as well (defaults to true)
419 : !> \author fawzi
420 : !> \note
421 : !> this is the where the real work is done
422 : ! **************************************************************************************************
423 8272 : SUBROUTINE rep_env_calc_e_f_int(rep_env, calc_f)
424 : TYPE(replica_env_type), POINTER :: rep_env
425 : LOGICAL, OPTIONAL :: calc_f
426 :
427 : INTEGER :: i, ierr, irep, md_iter, my_calc_f, ndim
428 : TYPE(cp_logger_type), POINTER :: logger
429 : TYPE(cp_subsys_type), POINTER :: subsys
430 : TYPE(f_env_type), POINTER :: f_env
431 : TYPE(qs_environment_type), POINTER :: qs_env
432 :
433 4136 : NULLIFY (f_env, qs_env, subsys)
434 4136 : CPASSERT(ASSOCIATED(rep_env))
435 4136 : CPASSERT(rep_env%ref_count > 0)
436 4136 : my_calc_f = 3*rep_env%nparticle
437 4136 : IF (PRESENT(calc_f)) THEN
438 4136 : IF (.NOT. calc_f) my_calc_f = 0
439 : END IF
440 :
441 4136 : CALL f_env_add_defaults(f_env_id=rep_env%f_env_id, f_env=f_env)
442 4136 : logger => cp_get_default_logger()
443 : ! md_iter=logger%iter_info%iteration(2)+1
444 4136 : md_iter = logger%iter_info%iteration(2)
445 4136 : CALL f_env_rm_defaults(f_env, ierr)
446 4136 : CPASSERT(ierr == 0)
447 9780 : DO i = 1, SIZE(rep_env%local_rep_indices)
448 5644 : irep = rep_env%local_rep_indices(i)
449 5644 : ndim = 3*rep_env%nparticle
450 5644 : IF (rep_env%sync_v) THEN
451 0 : CALL set_vel(rep_env%f_env_id, rep_env%v(:, irep), ndim, ierr)
452 0 : CPASSERT(ierr == 0)
453 : END IF
454 :
455 5644 : logger%iter_info%iteration(1) = irep
456 5644 : logger%iter_info%iteration(2) = md_iter
457 :
458 5644 : IF (rep_env%keep_wf_history) THEN
459 372 : CALL f_env_add_defaults(f_env_id=rep_env%f_env_id, f_env=f_env)
460 372 : CALL force_env_get(f_env%force_env, qs_env=qs_env)
461 : CALL set_qs_env(qs_env, &
462 372 : wf_history=rep_env%wf_history(i)%wf_history)
463 372 : CALL f_env_rm_defaults(f_env, ierr)
464 372 : CPASSERT(ierr == 0)
465 : END IF
466 :
467 5644 : CALL f_env_add_defaults(f_env_id=rep_env%f_env_id, f_env=f_env)
468 5644 : CALL force_env_get(f_env%force_env, subsys=subsys)
469 5644 : CALL cp_subsys_set(subsys, results=rep_env%results(irep)%results)
470 5644 : CALL f_env_rm_defaults(f_env, ierr)
471 5644 : CPASSERT(ierr == 0)
472 : CALL calc_force(rep_env%f_env_id, rep_env%r(:, irep), ndim, &
473 : rep_env%f(ndim + 1, irep), rep_env%f(:ndim, irep), &
474 5644 : my_calc_f, ierr)
475 15424 : CPASSERT(ierr == 0)
476 : END DO
477 4136 : CALL rep_env_sync(rep_env, rep_env%f)
478 4136 : CALL rep_env_sync_results(rep_env, rep_env%results)
479 :
480 4136 : END SUBROUTINE rep_env_calc_e_f_int
481 :
482 : END MODULE replica_methods
|