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, calc_mode_id) 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 integer, intent(in) :: calc_mode_id
76 class(ensemble_t), pointer :: sys
77
78 integer :: ireplica
79 class(system_t), pointer :: replica
80 character(len=128) :: replica_name
81
82 push_sub(ensemble_constructor)
83
84 allocate(sys)
85 sys%namespace = namespace
86 sys%nreplica = n_replicas
87
88 ! No interaction directly supported by this system (but classes that extend it can add their own)
89 allocate(sys%supported_interactions(0))
90 allocate(sys%supported_interactions_as_partner(0))
91
92 do ireplica = 1, sys%nreplica
93 write(replica_name, '(I8.8)') ireplica
94
95 ! Be aware that we need to use `sys%namespace` here. Passing only `namespace` leads to an error,
96 ! as `namespace` seems to be deleted when the routine exits.
97 !
98 replica => multisystem_basic_t(namespace_t(replica_name, parent=sys%namespace), names, types, system_factory, calc_mode_id)
99
100 call sys%list%add(replica)
101
102 end do
103
104 ! Initialize weights to uniform distribution
105
106 safe_allocate(sys%weights(1:sys%nreplica))
107 sys%weights = 1.0_real64/sys%nreplica
108
110 end function ensemble_constructor
111
112 recursive subroutine ensemble_finalizer(this)
113 type(ensemble_t), intent(inout) :: this
114
115 push_sub(ensemble_finalizer)
116
117 call ensemble_end(this)
118
119 pop_sub(ensemble_finalizer)
120 end subroutine ensemble_finalizer
121
122 recursive subroutine ensemble_end(this)
123 type(ensemble_t), intent(inout) :: this
124
125 push_sub(ensemble_end)
126
127 safe_deallocate_a(this%weights)
128 call multisystem_end(this)
129
130 pop_sub(ensemble_end)
131 end subroutine ensemble_end
132
133 ! ---------------------------------------------------------
143 recursive subroutine ensemble_create_interactions(this, interaction_factory, available_partners)
144 class(ensemble_t), intent(inout) :: this
145 class(interactions_factory_abst_t), intent(in) :: interaction_factory
146 class(partner_list_t), target, intent(in) :: available_partners
148 type(system_iterator_t) :: iter
149 class(system_t), pointer :: subsystem
150 type(partner_list_t) :: partners
151
152
153 ! Create interactions of the ensemble container
154 call system_create_interactions(this, interaction_factory, available_partners)
155
156 ! Create the subsystems interactions
157 call iter%start(this%list)
158 do while (iter%has_next())
159 subsystem => iter%get_next()
160 ! partners = available_partners
161 ! the above line would provide inter-replica ghost interactions, which does not seem
162 ! to be necessary, as the replicas can propagate independent of each other.
163 ! If we need more synchronization, e.g. for averages, this should be provided by the
164 ! real interaction.
165 ! In order to restore the inter-replica ghost, uncomment the line above and remove
166 ! the line below (partners.empty()).
167 call partners%empty()
168 call partners%add(subsystem)
169 call subsystem%create_interactions(interaction_factory, partners)
170 end do
171
172 end subroutine ensemble_create_interactions
173
174
179 recursive subroutine ensemble_add_partners_to_list(this, list, interaction_type)
180 class(ensemble_t), intent(in) :: this
181 class(partner_list_t), intent(inout) :: list
182 integer, optional, intent(in) :: interaction_type
183
184 type(system_iterator_t) :: iter
185 class(system_t), pointer :: system
186
188
189 if (present(interaction_type)) then
190 if (any(this%supported_interactions_as_partner == interaction_type)) then
191 call list%add(this)
192 end if
193 else
194 call list%add(this)
195
196 call iter%start(this%list)
197 do while (iter%has_next())
198 system => iter%get_next()
199 call system%add_partners_to_list(list)
200 end do
201
202 end if
203
205 end subroutine ensemble_add_partners_to_list
206
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:239
recursive class(ensemble_t) function, pointer ensemble_constructor(namespace, n_replicas, system_factory, names, types, calc_mode_id)
Constructor for the ensemble_t class.
Definition: ensemble.F90:165
recursive subroutine ensemble_finalizer(this)
Definition: ensemble.F90:208
recursive subroutine ensemble_end(this)
Definition: ensemble.F90:218
recursive subroutine ensemble_add_partners_to_list(this, list, interaction_type)
add the container to the flat list.
Definition: ensemble.F90:275
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