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
27 use system_oct_m
28 use parser_oct_m
30
31 implicit none
32
33 private
34 public :: &
36
45 type, extends(multisystem_t) :: ensemble_t
46 integer :: nreplica
47 ! !!
48 ! !! This is the number of replicas in, planned for a calculation.
49 ! !! The actual number of replicas in one run is determined by
50 ! !! last-first+1.
51 ! !!
52 ! !! The total number of replicas can be different can differ if
53 ! !! further runs have been added to improve the convergence.
54 integer :: first
55 integer :: last
56 real(real64), allocatable :: weights(:)
57
58 contains
59 procedure :: create_interactions => ensemble_create_interactions
60 procedure :: add_partners_to_list => ensemble_add_partners_to_list
61 final :: ensemble_finalizer
62 end type ensemble_t
63
64 interface ensemble_t
65 procedure ensemble_constructor
66 end interface ensemble_t
67
68contains
69
70 ! ---------------------------------------------------------
76 !
77 recursive function ensemble_constructor(namespace, n_replicas, first, last, system_factory, names, types, calc_mode_id) &
78 result(sys)
79 type(namespace_t), intent(in) :: namespace
80 integer, intent(in) :: n_replicas
81 class(system_factory_abst_t), intent(in) :: system_factory
82 integer, intent(in) :: first
83 integer, intent(in) :: last
84 character(len=128), intent(in) :: names(:)
85 integer, intent(in) :: types(:)
86 integer, intent(in) :: calc_mode_id
87 class(ensemble_t), pointer :: sys
88
89 integer :: ireplica
90 class(system_t), pointer :: replica
91 character(len=128) :: replica_name
92
93 push_sub(ensemble_constructor)
94
95 allocate(sys)
96 sys%namespace = namespace
97 sys%nreplica = n_replicas
98 sys%first = max(1, first)
99 sys%last = min(n_replicas, last)
100
101
102 ! No interaction directly supported by this system (but classes that extend it can add their own)
103 allocate(sys%supported_interactions(0))
104 allocate(sys%supported_interactions_as_partner(0))
105
106 do ireplica = sys%first, sys%last
107 write(replica_name, '(I8.8)') ireplica
108
109 ! Be aware that we need to use `sys%namespace` here. Passing only `namespace` leads to an error,
110 ! as `namespace` seems to be deleted when the routine exits.
111 !
112 replica => multisystem_basic_t(namespace_t(replica_name, parent=sys%namespace), names, types, system_factory, calc_mode_id)
113
114 call sys%list%add(replica)
115
116 end do
117
118 ! Initialize weights to uniform distribution
119
120 safe_allocate(sys%weights(1:sys%nreplica))
121 sys%weights = 1.0_real64/sys%nreplica
122
123 pop_sub(ensemble_constructor)
124 end function ensemble_constructor
125
126 recursive subroutine ensemble_finalizer(this)
127 type(ensemble_t), intent(inout) :: this
128
129 push_sub(ensemble_finalizer)
130
131 call ensemble_end(this)
132
133 pop_sub(ensemble_finalizer)
134 end subroutine ensemble_finalizer
135
136 recursive subroutine ensemble_end(this)
137 type(ensemble_t), intent(inout) :: this
138
139 push_sub(ensemble_end)
141 safe_deallocate_a(this%weights)
142 call multisystem_end(this)
143
144 pop_sub(ensemble_end)
145 end subroutine ensemble_end
146
147 ! ---------------------------------------------------------
157 recursive subroutine ensemble_create_interactions(this, interaction_factory, available_partners)
158 class(ensemble_t), intent(inout) :: this
159 class(interactions_factory_abst_t), intent(in) :: interaction_factory
160 class(partner_list_t), target, intent(in) :: available_partners
161
162 type(system_iterator_t) :: iter
163 class(system_t), pointer :: subsystem
164 type(partner_list_t) :: partners
165
167
168 ! Create interactions of the ensemble container
169 call system_create_interactions(this, interaction_factory, available_partners)
170
171 ! Create the subsystems interactions
172 call iter%start(this%list)
173 do while (iter%has_next())
174 subsystem => iter%get_next()
175 ! partners = available_partners
176 ! the above line would provide inter-replica ghost interactions, which does not seem
177 ! to be necessary, as the replicas can propagate independent of each other.
178 ! If we need more synchronization, e.g. for averages, this should be provided by the
179 ! real interaction.
180 ! In order to restore the inter-replica ghost, uncomment the line above and remove
181 ! the line below (partners.empty()).
182 call partners%empty()
183 call partners%add(subsystem)
184 call subsystem%create_interactions(interaction_factory, partners)
185 end do
186
188 end subroutine ensemble_create_interactions
189
190
195 recursive subroutine ensemble_add_partners_to_list(this, list, interaction_type)
196 class(ensemble_t), intent(in) :: this
197 class(partner_list_t), intent(inout) :: list
198 integer, optional, intent(in) :: interaction_type
199
200 type(system_iterator_t) :: iter
201 class(system_t), pointer :: system
202
204
205 if (present(interaction_type)) then
206 if (any(this%supported_interactions_as_partner == interaction_type)) then
207 call list%add(this)
208 end if
209 else
210 call list%add(this)
211
212 call iter%start(this%list)
213 do while (iter%has_next())
214 system => iter%get_next()
215 call system%add_partners_to_list(list)
216 end do
217
218 end if
219
222
223end 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:253
recursive subroutine ensemble_finalizer(this)
Definition: ensemble.F90:222
recursive class(ensemble_t) function, pointer ensemble_constructor(namespace, n_replicas, first, last, system_factory, names, types, calc_mode_id)
Constructor for the ensemble_t class.
Definition: ensemble.F90:174
recursive subroutine ensemble_end(this)
Definition: ensemble.F90:232
recursive subroutine ensemble_add_partners_to_list(this, list, interaction_type)
add the container to the flat list.
Definition: ensemble.F90:291
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:140
Container class for lists of system_oct_m::system_t.
the abstract multisystem class
Abstract class for systems.
Definition: system.F90:174