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 real(real64), allocatable :: weights(:)
48 integer :: distribution_type
49
50 contains
51 procedure :: create_interactions => ensemble_create_interactions
52 procedure :: add_partners_to_list => ensemble_add_partners_to_list
53 final :: ensemble_finalizer
54 end type ensemble_t
55
56 interface ensemble_t
57 procedure ensemble_constructor
58 end interface ensemble_t
59
60contains
61
62 ! ---------------------------------------------------------
68 !
69 recursive function ensemble_constructor(namespace, n_replicas, system_factory, names, types) result(sys)
70 type(namespace_t), intent(in) :: namespace
71 integer, intent(in) :: n_replicas
72 class(system_factory_abst_t), intent(in) :: system_factory
73 character(len=128), intent(in) :: names(:)
74 integer, intent(in) :: types(:)
75 class(ensemble_t), pointer :: sys
76
77 integer :: ireplica
78 class(system_t), pointer :: replica
79 character(len=128) :: replica_name
80
81 push_sub(ensemble_constructor)
82
83 allocate(sys)
84 sys%namespace = namespace
85 sys%nreplica = n_replicas
86
87 ! No interaction directly supported by this system (but classes that extend it can add their own)
88 allocate(sys%supported_interactions(0))
89 allocate(sys%supported_interactions_as_partner(0))
90
91 do ireplica = 1, sys%nreplica
92 write(replica_name, '(I8.8)') ireplica
93
94 ! Be aware that we need to use `sys%namespace` here. Passing only `namespace` leads to an error,
95 ! as `namespace` seems to be deleted when the routine exits.
96 !
97 replica => multisystem_basic_t(namespace_t(replica_name, parent=sys%namespace), names, types, system_factory)
98
99 call sys%list%add(replica)
100
101 end do
102
103 ! Initialize weights to uniform distribution
104
105 safe_allocate(sys%weights(1:sys%nreplica))
106 sys%weights = 1.0_real64/sys%nreplica
108 pop_sub(ensemble_constructor)
109 end function ensemble_constructor
110
111 recursive subroutine ensemble_finalizer(this)
112 type(ensemble_t), intent(inout) :: this
113
114 push_sub(ensemble_finalizer)
115
116 call ensemble_end(this)
117
118 pop_sub(ensemble_finalizer)
119 end subroutine ensemble_finalizer
120
121 recursive subroutine ensemble_end(this)
122 type(ensemble_t), intent(inout) :: this
123
124 push_sub(ensemble_end)
125
126 safe_deallocate_a(this%weights)
127 call multisystem_end(this)
128
129 pop_sub(ensemble_end)
130 end subroutine ensemble_end
131
132 ! ---------------------------------------------------------
142 recursive subroutine ensemble_create_interactions(this, interaction_factory, available_partners)
143 class(ensemble_t), intent(inout) :: this
144 class(interactions_factory_abst_t), intent(in) :: interaction_factory
145 class(partner_list_t), target, intent(in) :: available_partners
147 type(system_iterator_t) :: iter
148 class(system_t), pointer :: subsystem
149 type(partner_list_t) :: partners
150
151
152 ! Create interactions of the ensemble container
153 call system_create_interactions(this, interaction_factory, available_partners)
154
155 ! Create the subsystems interactions
156 call iter%start(this%list)
157 do while (iter%has_next())
158 subsystem => iter%get_next()
159 ! partners = available_partners
160 ! the above line would provide inter-replica ghost interactions, which does not seem
161 ! to be necessary, as the replicas can propagate independent of each other.
162 ! If we need more synchronization, e.g. for averages, this should be provided by the
163 ! real interaction.
164 ! In order to restore the inter-replica ghost, uncomment the line above and remove
165 ! the line below (partners.empty()).
166 call partners%empty()
167 call partners%add(subsystem)
168 call subsystem%create_interactions(interaction_factory, partners)
169 end do
170
171 end subroutine ensemble_create_interactions
172
173
178 recursive subroutine ensemble_add_partners_to_list(this, list, interaction_type)
179 class(ensemble_t), intent(in) :: this
180 class(partner_list_t), intent(inout) :: list
181 integer, optional, intent(in) :: interaction_type
182
183 type(system_iterator_t) :: iter
184 class(system_t), pointer :: system
185
187
188 if (present(interaction_type)) then
189 if (any(this%supported_interactions_as_partner == interaction_type)) then
190 call list%add(this)
191 end if
192 else
193 call list%add(this)
194
195 call iter%start(this%list)
196 do while (iter%has_next())
197 system => iter%get_next()
198 call system%add_partners_to_list(list)
199 end do
200
201 end if
202
205
206end module ensemble_oct_m
This module implements the basic elements defining algorithms.
Definition: algorithm.F90:141
This module implements the ensemble class.
Definition: ensemble.F90:107
recursive subroutine ensemble_create_interactions(this, interaction_factory, available_partners)
create the interactions of the ensemble
Definition: ensemble.F90:236
recursive subroutine ensemble_finalizer(this)
Definition: ensemble.F90:205
recursive subroutine ensemble_end(this)
Definition: ensemble.F90:215
recursive subroutine ensemble_add_partners_to_list(this, list, interaction_type)
add the container to the flat list.
Definition: ensemble.F90:272
recursive class(ensemble_t) function, pointer ensemble_constructor(namespace, n_replicas, system_factory, names, types)
Constructor for the ensemble_t class.
Definition: ensemble.F90:163
This module defines classes and functions for interaction partners.
This module defines the abstract class for the interaction factory.
Definition: io.F90:114
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:118
recursive subroutine, public system_create_interactions(this, interaction_factory, available_partners)
create the interactions of the system
Definition: system.F90:502
the ensemble class
Definition: ensemble.F90:138
Container class for lists of system_oct_m::system_t.
the abstract multisystem class
Abstract class for systems.
Definition: system.F90:172