Octopus
ensemble.F90
Go to the documentation of this file.
1!! Copyright (C) 2024 S. de la Pena, M. Lueders
2!!
3!! This Source Code Form is subject to the terms of the Mozilla Public
4!! License, v. 2.0. If a copy of the MPL was not distributed with this
5!! file, You can obtain one at https://mozilla.org/MPL/2.0/.
6!!
7#include "global.h"
8
13!
14module ensemble_oct_m
15
17 use debug_oct_m
18 use global_oct_m
21 use io_oct_m
23 use mpi_oct_m
28 use system_oct_m
29 use parser_oct_m
31
32 implicit none
33
34 private
35 public :: &
37
46 type, extends(multisystem_t) :: ensemble_t
47 integer :: nreplica
48 ! !!
49 ! !! This is the number of replicas in, planned for a calculation.
50 ! !! The actual number of replicas in one run is determined by
51 ! !! last-first+1.
52 ! !!
53 ! !! The total number of replicas can be different can differ if
54 ! !! further runs have been added to improve the convergence.
55 integer :: first
56 integer :: last
57 real(real64), allocatable :: weights(:)
58
59 contains
60 procedure :: create_interactions => ensemble_create_interactions
61 procedure :: add_partners_to_list => ensemble_add_partners_to_list
62 final :: ensemble_finalizer
63 end type ensemble_t
64
65 interface ensemble_t
66 procedure ensemble_constructor
67 end interface ensemble_t
68
69contains
70
71 ! ---------------------------------------------------------
77 !
78 recursive function ensemble_constructor(namespace, n_replicas, first, last, system_factory, names, types, calc_mode_id, grp) &
79 result(sys)
80 type(namespace_t), intent(in) :: namespace
81 integer, intent(in) :: n_replicas
82 class(system_factory_abst_t), intent(in) :: system_factory
83 integer, intent(in) :: first
84 integer, intent(in) :: last
85 character(len=128), intent(in) :: names(:)
86 integer, intent(in) :: types(:)
87 integer, intent(in) :: calc_mode_id
88 type(mpi_grp_t), intent(in) :: grp
89 class(ensemble_t), pointer :: sys
90
91 integer :: ireplica
92 class(system_t), pointer :: replica
93 character(len=128) :: replica_name
94
95 push_sub(ensemble_constructor)
96
97 allocate(sys)
98 sys%namespace = namespace
99 sys%nreplica = n_replicas
100 sys%first = max(1, first)
101 sys%last = min(n_replicas, last)
102
103
104 ! No interaction directly supported by this system (but classes that extend it can add their own)
105 allocate(sys%supported_interactions(0))
106 allocate(sys%supported_interactions_as_partner(0))
107
108 do ireplica = sys%first, sys%last
109 write(replica_name, '(I8.8)') ireplica
110
111 ! Be aware that we need to use `sys%namespace` here. Passing only `namespace` leads to an error,
112 ! as `namespace` seems to be deleted when the routine exits.
113 !
114 replica => multisystem_basic_t(namespace_t(replica_name, parent=sys%namespace), names, types, &
115 system_factory, calc_mode_id, grp)
116
117 call sys%list%add(replica)
118
119 end do
120
121 ! Initialize weights to uniform distribution
122
123 safe_allocate(sys%weights(1:sys%nreplica))
124 sys%weights = 1.0_real64/sys%nreplica
125
126 pop_sub(ensemble_constructor)
127 end function ensemble_constructor
128
129 recursive subroutine ensemble_finalizer(this)
130 type(ensemble_t), intent(inout) :: this
131
132 push_sub(ensemble_finalizer)
133
134 call ensemble_end(this)
135
136 pop_sub(ensemble_finalizer)
137 end subroutine ensemble_finalizer
138
139 recursive subroutine ensemble_end(this)
140 type(ensemble_t), intent(inout) :: this
142 push_sub(ensemble_end)
143
144 safe_deallocate_a(this%weights)
145 call multisystem_end(this)
146
147 pop_sub(ensemble_end)
148 end subroutine ensemble_end
149
150 ! ---------------------------------------------------------
159 !
160 recursive subroutine ensemble_create_interactions(this, interaction_factory, available_partners)
161 class(ensemble_t), intent(inout) :: this
162 class(interactions_factory_abst_t), intent(in) :: interaction_factory
163 class(partner_list_t), target, intent(in) :: available_partners
164
165 type(system_iterator_t) :: iter
166 class(system_t), pointer :: subsystem
167 type(partner_list_t) :: partners
168
170
171 ! Create interactions of the ensemble container
172 call system_create_interactions(this, interaction_factory, available_partners)
174 ! Create the subsystems interactions
175 call iter%start(this%list)
176 do while (iter%has_next())
177 subsystem => iter%get_next()
178 ! partners = available_partners
179 ! the above line would provide inter-replica ghost interactions, which does not seem
180 ! to be necessary, as the replicas can propagate independent of each other.
181 ! If we need more synchronization, e.g. for averages, this should be provided by the
182 ! real interaction.
183 ! In order to restore the inter-replica ghost, uncomment the line above and remove
184 ! the line below (partners.empty()).
185 call partners%empty()
186 call partners%add(subsystem)
187 call subsystem%create_interactions(interaction_factory, partners)
188 end do
189
191 end subroutine ensemble_create_interactions
192
193
198 recursive subroutine ensemble_add_partners_to_list(this, list, interaction_type)
199 class(ensemble_t), intent(in) :: this
200 class(partner_list_t), intent(inout) :: list
201 integer, optional, intent(in) :: interaction_type
202
203 type(system_iterator_t) :: iter
204 class(system_t), pointer :: system
205
207
208 if (present(interaction_type)) then
209 if (any(this%supported_interactions_as_partner == interaction_type)) then
210 call list%add(this)
211 end if
212 else
213 call list%add(this)
214
215 call iter%start(this%list)
216 do while (iter%has_next())
217 system => iter%get_next()
218 call system%add_partners_to_list(list)
219 end do
220
221 end if
222
225
226end module ensemble_oct_m
This module implements the basic elements defining algorithms.
Definition: algorithm.F90:143
This module implements the ensemble class.
Definition: ensemble.F90:109
recursive subroutine ensemble_create_interactions(this, interaction_factory, available_partners)
create the interactions of the ensemble
Definition: ensemble.F90:256
recursive subroutine ensemble_finalizer(this)
Definition: ensemble.F90:225
recursive subroutine ensemble_end(this)
Definition: ensemble.F90:235
recursive subroutine ensemble_add_partners_to_list(this, list, interaction_type)
add the container to the flat list.
Definition: ensemble.F90:294
recursive class(ensemble_t) function, pointer ensemble_constructor(namespace, n_replicas, first, last, system_factory, names, types, calc_mode_id, grp)
Constructor for the ensemble_t class.
Definition: ensemble.F90:175
This module defines classes and functions for interaction partners.
This module defines the abstract class for the interaction factory.
Definition: io.F90:116
This module implements the basic mulsisystem class, a container system for other systems.
This module implements the abstract multisystem class.
recursive subroutine, public multisystem_end(this)
This module defines the abstract class for the system factory.
This module implements the abstract system type.
Definition: system.F90:120
recursive subroutine, public system_create_interactions(this, interaction_factory, available_partners)
create the interactions of the system
Definition: system.F90:518
the ensemble class
Definition: ensemble.F90:141
Container class for lists of system_oct_m::system_t.
the abstract multisystem class
Abstract class for systems.
Definition: system.F90:174