(git:34ef472)
tmc_tree_search.F
Go to the documentation of this file.
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 nodes search etc.
10 !> \par History
11 !> 11.2012 created [Mandes Schoenherr]
12 !> \author Mandes
13 ! **************************************************************************************************
14 
16  USE cp_log_handling, ONLY: cp_to_string
17  USE kinds, ONLY: dp
21  USE tmc_tree_types, ONLY: &
22  elem_array_type, global_tree_type, status_accepted, status_accepted_result, &
27  USE tmc_types, ONLY: tmc_env_type
28 #include "../base/base_uses.f90"
29 
30  IMPLICIT NONE
31 
32  PRIVATE
33 
34  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'tmc_tree_search'
35 
36  PUBLIC :: most_prob_end
37  PUBLIC :: search_next_energy_calc
43 CONTAINS
44 
45  !============================================================================
46  ! search tree node
47  !============================================================================
48 ! **************************************************************************************************
49 !> \brief search most probable end in global tree to create a new tree node
50 !> using the acceptance probabilities for each move type
51 !> of each temperature
52 !> routine distinguishes the search for most probable node
53 !> for energy and most probable node with open end
54 !> for new configuration
55 !> In case of searching open end:
56 !> routine stops in branch with canceled NMC,
57 !> using this a one possibility
58 !> \param global_tree_elem starting point for search
59 !> \param prob return value, the probability of reaching the tree node
60 !> \param n_acc drection of branch the next tree node should extend
61 !> \param search_energy_node ...
62 !> \parma search_energy_node flag if configuration for calculating exact
63 !> energy should be searched
64 !> \author Mandes 12.2012
65 ! **************************************************************************************************
66  RECURSIVE SUBROUTINE most_prob_end(global_tree_elem, prob, n_acc, &
67  search_energy_node)
68  TYPE(global_tree_type), POINTER :: global_tree_elem
69  REAL(kind=dp), INTENT(OUT) :: prob
70  LOGICAL, INTENT(INOUT) :: n_acc
71  LOGICAL, OPTIONAL :: search_energy_node
72 
73  CHARACTER(LEN=*), PARAMETER :: routinen = 'most_prob_end'
74 
75  INTEGER :: handle
76  LOGICAL :: check_accepted, check_rejected, keep_on, &
77  tmp_acc, tmp_nacc
78  REAL(kind=dp) :: prob_n_acc, prob_n_nacc
79  TYPE(global_tree_type), POINTER :: ptr_acc, ptr_nacc
80  TYPE(tree_type), POINTER :: st_elem
81 
82  NULLIFY (st_elem, ptr_acc, ptr_nacc)
83 
84  prob_n_acc = -100000
85  prob_n_nacc = -100000
86  check_accepted = .false.
87  check_rejected = .false.
88  keep_on = .true.
89 
90  cpassert(ASSOCIATED(global_tree_elem))
91  st_elem => global_tree_elem%conf(global_tree_elem%mv_conf)%elem
92  cpassert(ASSOCIATED(st_elem))
93 
94  ! start the timing
95  CALL timeset(routinen, handle)
96 
97  !-- follow trajectory until end
98  !-- evaluate following elements using status, and probabilites
99  SELECT CASE (global_tree_elem%stat)
101  check_accepted = .true.
103  check_rejected = .true.
104  CASE DEFAULT
105  !-- set directions of searching
106  SELECT CASE (st_elem%stat)
108  ! just for searching next element to calculate energy for (found)
109  IF (PRESENT(search_energy_node)) THEN
110  prob = 0.0_dp ! = log(1)
111  n_acc = .false. ! not needed, but maybe for initialisation
112  keep_on = .false.
113  ELSE
114  check_accepted = .true.
115  check_rejected = .true.
116  END IF
117  CASE (status_canceled_nmc)
118  ! just for search new element to create (found)
119  ! canceled elements can be reactivated
120  ! the parent element is returned,
121  ! the create_new_pt_tree_node check for existing of this node
122  IF (.NOT. PRESENT(search_energy_node)) THEN
123  prob = 0.0_dp
124  n_acc = ASSOCIATED(global_tree_elem%parent%acc, global_tree_elem)
125  global_tree_elem => global_tree_elem%parent
126  keep_on = .false.
127  END IF
131  ! status accepted and rejection needed for swapped
132  ! configurations in parallel tempering
133  check_accepted = .true.
134  check_rejected = .true.
137  ! just for searching next element to create
138  IF (.NOT. PRESENT(search_energy_node)) THEN
139  check_rejected = .true.
140  END IF
142  CASE DEFAULT
143  CALL cp_abort(__location__, &
144  "unknown sub tree element status "// &
145  cp_to_string(st_elem%stat))
146  END SELECT
147  END SELECT
148 
149  IF (keep_on) THEN
150  !-- recursive search, remembering lowest element (tree end),
151  ! and multiply probabilities to go there
152  !-- search in ACCEPTED branch
153  IF (check_accepted) THEN
154  ! test if probable accepted child exist and is not rejected
155  IF (ASSOCIATED(global_tree_elem%acc)) THEN
156  ptr_acc => global_tree_elem%acc
157  IF (PRESENT(search_energy_node)) THEN
158  CALL most_prob_end(global_tree_elem=ptr_acc, prob=prob_n_acc, &
159  n_acc=tmp_acc, &
160  search_energy_node=search_energy_node)
161  ELSE
162  CALL most_prob_end(global_tree_elem=ptr_acc, prob=prob_n_acc, &
163  n_acc=tmp_acc)
164  END IF
165  !-- do probability multiplication
166  ! (in logscale because of really small probabilities)
167  prob_n_acc = prob_n_acc + log(global_tree_elem%prob_acc)
168  ELSE
169  ! prob of going in acc or rej direction is
170  ! calculated in parent element
171  prob_n_acc = log(global_tree_elem%prob_acc)
172  IF (PRESENT(search_energy_node)) prob_n_acc = -100000
173  ptr_acc => global_tree_elem
174  tmp_acc = .true.
175  END IF
176  END IF
177 
178  !-- search in REJECTED branch
179  IF (check_rejected) THEN
180  ! test if probabliy rejected child exist
181  IF (ASSOCIATED(global_tree_elem%nacc)) THEN
182  ptr_nacc => global_tree_elem%nacc
183  IF (PRESENT(search_energy_node)) THEN
184  CALL most_prob_end(global_tree_elem=ptr_nacc, prob=prob_n_nacc, &
185  n_acc=tmp_nacc, &
186  search_energy_node=search_energy_node)
187  ELSE
188  CALL most_prob_end(global_tree_elem=ptr_nacc, prob=prob_n_nacc, &
189  n_acc=tmp_nacc)
190  END IF
191  !-- do probability multiplication
192  ! (in logscale because of really small probabilities)
193  prob_n_nacc = prob_n_nacc + log(1 - global_tree_elem%prob_acc)
194  ELSE
195  ! prob of going in acc or rej direction is
196  ! calculated in parent element
197  prob_n_nacc = log(1 - global_tree_elem%prob_acc)
198  IF (PRESENT(search_energy_node)) prob_n_nacc = -100000
199  ptr_nacc => global_tree_elem
200  tmp_nacc = .false.
201  END IF
202  END IF
203  ! test which direction is more likely
204  ! and set result pointer and probability,
205  ! remembering the direction
206  IF (prob_n_acc .GE. prob_n_nacc) THEN
207  prob = prob_n_acc
208  global_tree_elem => ptr_acc
209  n_acc = tmp_acc
210  ELSE
211  prob = prob_n_nacc
212  global_tree_elem => ptr_nacc
213  n_acc = tmp_nacc
214  END IF
215  END IF
216  ! end the timing
217  CALL timestop(handle)
218  END SUBROUTINE most_prob_end
219 
220 ! **************************************************************************************************
221 !> \brief gt_head head of the global tree
222 !> \param gt_head ...
223 !> \param new_gt_elem return value the energy should be calculated for
224 !> \param stat routine status return value
225 !> \param react_count reactivation counter
226 !> \author Mandes 12.2012
227 ! **************************************************************************************************
228  SUBROUTINE search_next_energy_calc(gt_head, new_gt_elem, stat, react_count)
229  TYPE(global_tree_type), POINTER :: gt_head, new_gt_elem
230  INTEGER :: stat, react_count
231 
232  CHARACTER(LEN=*), PARAMETER :: routinen = 'search_next_energy_calc'
233 
234  INTEGER :: handle
235  LOGICAL :: flag
236  REAL(kind=dp) :: prob
237 
238  prob = 0.0_dp
239  flag = .false.
240  cpassert(ASSOCIATED(gt_head))
241 
242  ! start the timing
243  CALL timeset(routinen, handle)
244 
245  new_gt_elem => gt_head
246 
247  CALL most_prob_end(global_tree_elem=new_gt_elem, prob=prob, n_acc=flag, &
248  search_energy_node=.true.)
249 
250  stat = status_created
251  ! set status for master
252  ! (if TMC_STATUS_WAIT_FOR_NEW_TASK, no calculation necessary)
253  IF (.NOT. ASSOCIATED(new_gt_elem) .OR. (exp(prob) .LT. 1.0e-10)) THEN
255  ELSE
256  ! reactivate canceled elements
257  IF (new_gt_elem%conf(new_gt_elem%mv_conf)%elem%stat .EQ. &
259  CALL add_to_references(gt_elem=new_gt_elem)
260  react_count = react_count + 1
261  new_gt_elem%conf(new_gt_elem%mv_conf)%elem%stat = status_created
262  END IF
263  ! if elem status is not status_created
264  IF (new_gt_elem%conf(new_gt_elem%mv_conf)%elem%stat .NE. status_created) THEN
266  END IF
267  END IF
268  ! end the timing
269  CALL timestop(handle)
270  END SUBROUTINE search_next_energy_calc
271 
272 ! **************************************************************************************************
273 !> \brief searching the parent element (last accepted configuration before)
274 !> \param current actual tree element
275 !> \return parent tree element (last accepted one)
276 !> \author Mandes 12.2012
277 !> \note routine searches last (assumed) accepted element in subtree
278 ! **************************************************************************************************
279  RECURSIVE FUNCTION search_parent_element(current) RESULT(parent)
280  TYPE(tree_type), POINTER :: current, parent
281 
282  CHARACTER(LEN=*), PARAMETER :: routinen = 'search_parent_element'
283 
284  INTEGER :: handle
285 
286  cpassert(ASSOCIATED(current))
287 
288  ! start the timing
289  CALL timeset(routinen, handle)
290 
291  IF (ASSOCIATED(current%parent)) THEN
292  ! the result value if the child (we came from) is in acc direction
293  parent => current%parent
294  IF (ASSOCIATED(parent%nacc, current)) THEN
295  parent => search_parent_element(parent)
296  END IF
297  ELSE
298  ! if parent not exist, we are at the head of the tree
299  parent => current
300  END IF
301  ! end the timing
302  CALL timestop(handle)
303  cpassert(ASSOCIATED(parent))
304  END FUNCTION search_parent_element
305 
306 ! **************************************************************************************************
307 !> \brief search the next global element in the Markov Chain to check
308 !> \param ptr start point for search, should be on the known Markov Chain
309 !> \param found flag if routine was successful
310 !> \author Mandes 12.2012
311 ! **************************************************************************************************
312  RECURSIVE SUBROUTINE search_next_gt_element_to_check(ptr, found)
313  TYPE(global_tree_type), POINTER :: ptr
314  LOGICAL :: found
315 
316  CHARACTER(LEN=*), PARAMETER :: routinen = 'search_next_gt_element_to_check'
317 
318  INTEGER :: handle
319 
320  found = .false.
321 
322  cpassert(ASSOCIATED(ptr))
323 
324  ! start the timing
325  CALL timeset(routinen, handle)
326 
327  ! -- global tree status is not updated after receiving calculations
328  ! (not intrinsically), hence try to check elements with could be ready
329  SELECT CASE (ptr%stat)
331  IF (ASSOCIATED(ptr%acc)) THEN
332  ptr => ptr%acc
333  CALL search_next_gt_element_to_check(ptr, found)
334  END IF
336  IF (ASSOCIATED(ptr%nacc)) THEN
337  ptr => ptr%nacc
338  CALL search_next_gt_element_to_check(ptr, found)
339  END IF
343  found = .true.
346  ! nothing to do
347  CASE DEFAULT
348  CALL cp_abort(__location__, &
349  "unexpected status "//cp_to_string(ptr%stat)// &
350  "of global tree elem "//cp_to_string(ptr%nr))
351  END SELECT
352  ! end the timing
353  CALL timestop(handle)
354 
355  cpassert(ASSOCIATED(ptr))
356  END SUBROUTINE search_next_gt_element_to_check
357 
358 ! **************************************************************************************************
359 !> \brief get the changed element of the actual global tree element and its
360 !> related last accepted parent
361 !> \param gt_act_elem actual global tree element
362 !> \param elem1 two subtree elements which should be compared
363 !> \param elem2 two subtree elements which should be compared
364 !> \author Mandes 12.2012
365 ! **************************************************************************************************
366  SUBROUTINE get_subtree_elements_to_check(gt_act_elem, elem1, elem2)
367  TYPE(global_tree_type), POINTER :: gt_act_elem
368  TYPE(tree_type), INTENT(OUT), POINTER :: elem1, elem2
369 
370  CHARACTER(LEN=*), PARAMETER :: routinen = 'get_subtree_elements_to_check'
371 
372  INTEGER :: handle
373 
374  cpassert(ASSOCIATED(gt_act_elem))
375 
376  ! start the timing
377  CALL timeset(routinen, handle)
378 
379  IF (gt_act_elem%swaped) THEN
380  !------------------------------------------------------------
381  !-- take the last accepted configurations for check of both configurations, because
382  !-- in case of swapping, the last accepted elements have to be compared
383  IF (gt_act_elem%conf_n_acc(gt_act_elem%conf(gt_act_elem%mv_conf)%elem%sub_tree_nr)) THEN
384  elem1 => gt_act_elem%conf(gt_act_elem%mv_conf)%elem
385  ELSE
386  elem1 => search_parent_element(gt_act_elem%conf(gt_act_elem%mv_conf)%elem)
387  END IF
388  ! second element
389  IF (gt_act_elem%conf_n_acc(gt_act_elem%conf(gt_act_elem%mv_conf + 1)%elem%sub_tree_nr)) THEN
390  elem2 => gt_act_elem%conf(gt_act_elem%mv_conf + 1)%elem
391  ELSE
392  elem2 => search_parent_element(gt_act_elem%conf(gt_act_elem%mv_conf + 1)%elem)
393  END IF
394  ELSE
395  elem1 => gt_act_elem%conf(gt_act_elem%mv_conf)%elem
396  elem2 => search_parent_element(elem1)
397  END IF
398 
399  ! end the timing
400  CALL timestop(handle)
401 
402  cpassert(ASSOCIATED(gt_act_elem))
403  cpassert(ASSOCIATED(elem1))
404  cpassert(ASSOCIATED(elem2))
405  END SUBROUTINE get_subtree_elements_to_check
406 
407 ! **************************************************************************************************
408 !> \brief searches last element on trajectory,
409 !> until where the sides of the tree are deleted (of global tree)
410 !> also found the last accepted element before
411 !> \param last_acc returns last accepted element in cleaned tree part
412 !> \param tree_ptr end point of search
413 !> \author Mandes 12.2012
414 ! **************************************************************************************************
415  RECURSIVE SUBROUTINE search_end_of_clean_g_tree(last_acc, tree_ptr)
416  TYPE(global_tree_type), POINTER :: last_acc, tree_ptr
417 
418  CHARACTER(LEN=*), PARAMETER :: routinen = 'search_end_of_clean_g_tree'
419 
420  INTEGER :: handle
421 
422  cpassert(ASSOCIATED(last_acc))
423  cpassert(ASSOCIATED(tree_ptr))
424 
425  ! start the timing
426  CALL timeset(routinen, handle)
427 
428  SELECT CASE (tree_ptr%stat)
430  IF (ASSOCIATED(tree_ptr%acc) .AND. .NOT. ASSOCIATED(tree_ptr%nacc)) THEN
431  last_acc => tree_ptr
432  tree_ptr => tree_ptr%acc
433  CALL search_end_of_clean_g_tree(last_acc, tree_ptr)
434  END IF
436  IF (ASSOCIATED(tree_ptr%nacc) .AND. .NOT. ASSOCIATED(tree_ptr%acc)) THEN
437  tree_ptr => tree_ptr%nacc
438  CALL search_end_of_clean_g_tree(last_acc, tree_ptr)
439  END IF
444  ! nothing to do
445  CASE DEFAULT
446  CALL cp_abort(__location__, &
447  "the global tree element "//cp_to_string(tree_ptr%nr)// &
448  " stat "//cp_to_string(tree_ptr%stat)//" is UNknown")
449  END SELECT
450  ! end the timing
451  CALL timestop(handle)
452  cpassert(ASSOCIATED(last_acc))
453  cpassert(ASSOCIATED(tree_ptr))
454  END SUBROUTINE search_end_of_clean_g_tree
455 
456 ! **************************************************************************************************
457 !> \brief searches last element on trajectory,
458 !> until where the sides of the tree are deleted (in sub tree)
459 !> also found the last accepted element before.
460 !> searches the last element which at least have ONE (not calculated)
461 !> node in the tree branch
462 !> \param tree_ptr ...
463 !> \param last_acc ...
464 !> \author Mandes 12.2012
465 ! **************************************************************************************************
466  RECURSIVE SUBROUTINE search_end_of_clean_tree(tree_ptr, last_acc)
467  TYPE(tree_type), POINTER :: tree_ptr
468  TYPE(tree_type), INTENT(IN), POINTER :: last_acc
469 
470  CHARACTER(LEN=*), PARAMETER :: routinen = 'search_end_of_clean_tree'
471 
472  INTEGER :: handle
473 
474  cpassert(ASSOCIATED(tree_ptr))
475  cpassert(ASSOCIATED(last_acc))
476 
477  ! start the timing
478  CALL timeset(routinen, handle)
479 
480  IF (.NOT. ASSOCIATED(last_acc, tree_ptr)) THEN
481  IF (ASSOCIATED(tree_ptr%acc) .AND. .NOT. ASSOCIATED(tree_ptr%nacc)) THEN
482  tree_ptr => tree_ptr%acc
483  CALL search_end_of_clean_tree(tree_ptr, last_acc)
484  ELSE IF (ASSOCIATED(tree_ptr%nacc) .AND. .NOT. ASSOCIATED(tree_ptr%acc)) THEN
485  tree_ptr => tree_ptr%nacc
486  CALL search_end_of_clean_tree(tree_ptr, last_acc)
487  END IF
488  END IF
489  ! end the timing
490  CALL timestop(handle)
491  cpassert(ASSOCIATED(tree_ptr))
492  cpassert(ASSOCIATED(last_acc))
493  END SUBROUTINE search_end_of_clean_tree
494 
495 ! **************************************************************************************************
496 !> \brief searches in all branches down below the entered global tree element
497 !> for elements to cancel, if prob is present start searching at the
498 !> related tree child node
499 !> \param pt_elem_in start search point
500 !> \param prob the acceptance probability of the tree element to define
501 !> the direction to start with
502 !> \param tmc_env TMC environment
503 !> \author Mandes 12.2012
504 ! **************************************************************************************************
505  RECURSIVE SUBROUTINE search_canceling_elements(pt_elem_in, prob, tmc_env)
506  TYPE(global_tree_type), INTENT(IN), POINTER :: pt_elem_in
507  REAL(kind=dp), OPTIONAL :: prob
508  TYPE(tmc_env_type), POINTER :: tmc_env
509 
510  CHARACTER(LEN=*), PARAMETER :: routinen = 'search_canceling_elements'
511 
512  INTEGER :: handle
513  LOGICAL :: ready
514  TYPE(global_tree_type), POINTER :: act_pt_ptr, pt_elem
515 
516  NULLIFY (pt_elem, act_pt_ptr)
517  cpassert(ASSOCIATED(pt_elem_in))
518  cpassert(ASSOCIATED(tmc_env))
519 
520  ! start the timing
521  CALL timeset(routinen, handle)
522 
523  ready = .true.
524  ! if prob present select the related branch
525  IF (PRESENT(prob)) THEN
526  IF (prob .LT. 1.0e-10 .AND. ASSOCIATED(pt_elem_in%acc)) THEN
527  pt_elem => pt_elem_in%acc
528  ELSE IF (prob .GT. (1.0_dp - 1.0e-10) .AND. ASSOCIATED(pt_elem_in%nacc)) THEN
529  pt_elem => pt_elem_in%nacc
530  ELSE
531  ready = .false.
532  END IF
533  ELSE
534  pt_elem => pt_elem_in
535  END IF
536 
537  IF (ready) THEN
538  IF (ASSOCIATED(pt_elem%conf(pt_elem%mv_conf)%elem)) THEN
539  SELECT CASE (pt_elem%conf(pt_elem%mv_conf)%elem%stat)
544  status_calc_approx_ener) ! no canceling
547  CALL search_and_remove_reference_in_list(gt_ptr=pt_elem, &
548  elem=pt_elem%conf(pt_elem%mv_conf)%elem, tmc_env=tmc_env)
549 
550  CASE DEFAULT
551  CALL cp_abort(__location__, &
552  "unknown status of subtree element"// &
553  cp_to_string(pt_elem%conf(pt_elem%mv_conf)%elem%stat))
554  END SELECT
555  END IF
556  !-- go until the ends ot he tree, to search for elements to cancel
557  !-- check if child nodes exist
558  IF (ASSOCIATED(pt_elem%acc)) THEN
559  act_pt_ptr => pt_elem%acc
560  CALL search_canceling_elements(pt_elem_in=act_pt_ptr, tmc_env=tmc_env)
561  END IF
562  IF (ASSOCIATED(pt_elem%nacc)) THEN
563  act_pt_ptr => pt_elem%nacc
564  CALL search_canceling_elements(pt_elem_in=act_pt_ptr, tmc_env=tmc_env)
565  END IF
566  END IF
567  ! end the timing
568  CALL timestop(handle)
569  cpassert(ASSOCIATED(pt_elem_in))
570  END SUBROUTINE search_canceling_elements
571 
572 ! **************************************************************************************************
573 !> \brief searches for created configurations in all subtrees
574 !> \param global_tree_ptr pointer to one global tree element
575 !> \param counters array returning the counters for each subtree
576 !> \author Mandes 01.2013
577 ! **************************************************************************************************
578  SUBROUTINE count_prepared_nodes_in_trees(global_tree_ptr, counters)
579  TYPE(global_tree_type), INTENT(IN), POINTER :: global_tree_ptr
580  INTEGER, DIMENSION(:), POINTER :: counters
581 
582  CHARACTER(len=*), PARAMETER :: routinen = 'count_prepared_nodes_in_trees'
583 
584  INTEGER :: handle, i
585  TYPE(tree_type), POINTER :: begin_ptr
586 
587  NULLIFY (begin_ptr)
588 
589  cpassert(ASSOCIATED(global_tree_ptr))
590  cpassert(ASSOCIATED(counters))
591  cpassert(SIZE(counters(1:)) .EQ. SIZE(global_tree_ptr%conf(:)))
592 
593  ! start the timing
594  CALL timeset(routinen, handle)
595 
596  counters(:) = 0
597  DO i = 1, SIZE(global_tree_ptr%conf(:))
598  begin_ptr => global_tree_ptr%conf(i)%elem
599  CALL count_prepared_nodes_in_subtree(tree_ptr=begin_ptr, &
600  counter=counters(i))
601  END DO
602 
603  ! end the timing
604  CALL timestop(handle)
605  END SUBROUTINE count_prepared_nodes_in_trees
606 
607 ! **************************************************************************************************
608 !> \brief counts the prepared tree nodes in subtrees
609 !> \param tree_ptr pointer to one subtree element
610 !> \param counter returning the amount of prepared
611 !> (ready for energy calculation) elements ind certain sub tree
612 !> \author Mandes 01.2013
613 ! **************************************************************************************************
614  RECURSIVE SUBROUTINE count_prepared_nodes_in_subtree(tree_ptr, counter)
615  TYPE(tree_type), POINTER :: tree_ptr
616  INTEGER :: counter
617 
618  TYPE(tree_type), POINTER :: tmp_ptr
619 
620  NULLIFY (tmp_ptr)
621 
622  cpassert(ASSOCIATED(tree_ptr))
623 
624  SELECT CASE (tree_ptr%stat)
626  IF (ASSOCIATED(tree_ptr%acc)) THEN
627  tmp_ptr => tree_ptr%acc
628  CALL count_prepared_nodes_in_subtree(tmp_ptr, counter)
629  END IF
631  IF (ASSOCIATED(tree_ptr%nacc)) THEN
632  tmp_ptr => tree_ptr%nacc
633  CALL count_prepared_nodes_in_subtree(tmp_ptr, counter)
634  END IF
637  IF (tree_ptr%stat .EQ. status_created) counter = counter + 1
638  IF (ASSOCIATED(tree_ptr%acc)) THEN
639  tmp_ptr => tree_ptr%acc
640  CALL count_prepared_nodes_in_subtree(tmp_ptr, counter)
641  END IF
642  IF (ASSOCIATED(tree_ptr%nacc)) THEN
643  tmp_ptr => tree_ptr%nacc
644  CALL count_prepared_nodes_in_subtree(tmp_ptr, counter)
645  END IF
648  !TODO maybe also count caneled confs for debug output
649  CASE DEFAULT
650  CALL cp_abort(__location__, &
651  "stat "//cp_to_string(tree_ptr%stat)// &
652  "of elem "//cp_to_string(tree_ptr%nr)// &
653  "unknown.")
654  END SELECT
655  END SUBROUTINE count_prepared_nodes_in_subtree
656 
657 ! **************************************************************************************************
658 !> \brief counts the number of existing nodes in global and subtrees
659 !> \param global_tree_ptr pointer to one global tree element
660 !> \param end_of_clean_trees points to the last elements of the clean sub trees
661 !> \param counters array returning the counters for each subtree
662 !> \param head_elements_nr node number of the existing
663 !> global and sub tree heads
664 !> \author Mandes 01.2013
665 ! **************************************************************************************************
666  SUBROUTINE count_nodes_in_trees(global_tree_ptr, end_of_clean_trees, &
667  counters, head_elements_nr)
668  TYPE(global_tree_type), POINTER :: global_tree_ptr
669  TYPE(elem_array_type), DIMENSION(:), POINTER :: end_of_clean_trees
670  INTEGER, DIMENSION(:), POINTER :: counters, head_elements_nr
671 
672  CHARACTER(len=*), PARAMETER :: routinen = 'count_nodes_in_trees'
673 
674  INTEGER :: handle, i
675  TYPE(global_tree_type), POINTER :: begin_gt_ptr
676  TYPE(tree_type), POINTER :: begin_ptr
677 
678  NULLIFY (begin_gt_ptr, begin_ptr)
679 
680  cpassert(ASSOCIATED(global_tree_ptr))
681  cpassert(ASSOCIATED(end_of_clean_trees))
682  cpassert(ASSOCIATED(counters))
683  cpassert(SIZE(counters(1:)) .EQ. SIZE(global_tree_ptr%conf(:)))
684 
685  ! start the timing
686  CALL timeset(routinen, handle)
687 
688  begin_gt_ptr => global_tree_ptr
689  counters(:) = 0
690  DO
691  IF (.NOT. ASSOCIATED(begin_gt_ptr%parent)) EXIT
692  begin_gt_ptr => begin_gt_ptr%parent
693  END DO
694  head_elements_nr(0) = begin_gt_ptr%nr
695  CALL count_nodes_in_global_tree(begin_gt_ptr, counters(0))
696  DO i = 1, SIZE(end_of_clean_trees(:))
697  begin_ptr => end_of_clean_trees(i)%elem
698  DO
699  IF (.NOT. ASSOCIATED(begin_ptr%parent)) EXIT
700  begin_ptr => begin_ptr%parent
701  END DO
702  head_elements_nr(i) = begin_ptr%nr
703  CALL count_nodes_in_tree(begin_ptr, counters(i))
704  END DO
705 
706  ! end the timing
707  CALL timestop(handle)
708  END SUBROUTINE count_nodes_in_trees
709 
710 ! **************************************************************************************************
711 !> \brief counts existing nodes in global tree
712 !> \param ptr global tree head
713 !> \param counter return value with the amount of existing global tree elements
714 !> \author Mandes 01.2013
715 ! **************************************************************************************************
716  RECURSIVE SUBROUTINE count_nodes_in_global_tree(ptr, counter)
717  TYPE(global_tree_type), INTENT(IN), POINTER :: ptr
718  INTEGER, INTENT(INOUT) :: counter
719 
720  cpassert(ASSOCIATED(ptr))
721 
722  counter = counter + 1
723 
724  IF (ASSOCIATED(ptr%acc)) &
725  CALL count_nodes_in_global_tree(ptr%acc, counter)
726  IF (ASSOCIATED(ptr%nacc)) &
727  CALL count_nodes_in_global_tree(ptr%nacc, counter)
728  END SUBROUTINE count_nodes_in_global_tree
729 
730 ! **************************************************************************************************
731 !> \brief counts existing nodes in certain sub tree
732 !> \param ptr subtree tree head
733 !> \param counter return value with the amount of existing sub tree elements
734 !> \author Mandes 01.2013
735 ! **************************************************************************************************
736  RECURSIVE SUBROUTINE count_nodes_in_tree(ptr, counter)
737  TYPE(tree_type), POINTER :: ptr
738  INTEGER :: counter
739 
740  cpassert(ASSOCIATED(ptr))
741 
742  counter = counter + 1
743 
744  IF (ASSOCIATED(ptr%acc)) &
745  CALL count_nodes_in_tree(ptr%acc, counter)
746  IF (ASSOCIATED(ptr%nacc)) &
747  CALL count_nodes_in_tree(ptr%nacc, counter)
748  END SUBROUTINE count_nodes_in_tree
749 END MODULE tmc_tree_search
various routines to log and control the output. The idea is that decisions about where to log should ...
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public dp
Definition: kinds.F:34
tree nodes creation, searching, deallocation, references etc.
Definition: tmc_stati.F:15
integer, parameter, public tmc_status_wait_for_new_task
Definition: tmc_stati.F:52
global tree references
subroutine, public search_and_remove_reference_in_list(gt_ptr, elem, tmc_env)
removes the global tree references of this actual global tree element from all related sub tree eleme...
subroutine, public add_to_references(gt_elem)
adds global tree reference to the modified sub tree element(s)
tree nodes search etc.
subroutine, public search_next_energy_calc(gt_head, new_gt_elem, stat, react_count)
gt_head head of the global tree
recursive subroutine, public search_end_of_clean_g_tree(last_acc, tree_ptr)
searches last element on trajectory, until where the sides of the tree are deleted (of global tree) a...
recursive type(tree_type) function, pointer, public search_parent_element(current)
searching the parent element (last accepted configuration before)
recursive subroutine, public most_prob_end(global_tree_elem, prob, n_acc, search_energy_node)
search most probable end in global tree to create a new tree node using the acceptance probabilities ...
recursive subroutine, public search_end_of_clean_tree(tree_ptr, last_acc)
searches last element on trajectory, until where the sides of the tree are deleted (in sub tree) also...
recursive subroutine, public search_canceling_elements(pt_elem_in, prob, tmc_env)
searches in all branches down below the entered global tree element for elements to cancel,...
subroutine, public get_subtree_elements_to_check(gt_act_elem, elem1, elem2)
get the changed element of the actual global tree element and its related last accepted parent
subroutine, public count_nodes_in_trees(global_tree_ptr, end_of_clean_trees, counters, head_elements_nr)
counts the number of existing nodes in global and subtrees
subroutine, public count_prepared_nodes_in_trees(global_tree_ptr, counters)
searches for created configurations in all subtrees
recursive subroutine, public search_next_gt_element_to_check(ptr, found)
search the next global element in the Markov Chain to check
module handles definition of the tree nodes for the global and the subtrees binary tree parent elemen...
integer, parameter, public status_deleted
integer, parameter, public status_accepted
integer, parameter, public status_calculate_energy
integer, parameter, public status_calculate_md
integer, parameter, public status_canceled_ener
integer, parameter, public status_calculated
integer, parameter, public status_cancel_ener
integer, parameter, public status_cancel_nmc
integer, parameter, public status_canceled_nmc
integer, parameter, public status_calc_approx_ener
integer, parameter, public status_rejected
integer, parameter, public status_calculate_nmc_steps
integer, parameter, public status_accepted_result
integer, parameter, public status_deleted_result
integer, parameter, public status_created
integer, parameter, public status_rejected_result
module handles definition of the tree nodes for the global and the subtrees binary tree parent elemen...
Definition: tmc_types.F:32