31 integer,
parameter,
public :: &
32 COUPLINGS_UNDEFINED = 0, &
44 type(namespace_t),
public :: namespace
46 integer,
allocatable,
public :: supported_interactions_as_partner(:)
49 type(quantity_list_t),
public :: quantities
60 procedure(interaction_partner_init_interaction_as_partner),
deferred :: init_interaction_as_partner
62 procedure(interaction_partner_copy_quantities_to_interaction),
deferred :: copy_quantities_to_interaction
71 class(interaction_partner_t),
intent(in) :: partner
72 class(interaction_surrogate_t),
intent(inout) :: interaction
79 class(interaction_partner_t),
intent(inout) :: partner
80 class(interaction_surrogate_t),
intent(inout) :: interaction
111 class(interaction_partner_t),
intent(in) :: this
112 class(partner_list_t),
intent(inout) :: list
113 integer,
optional,
intent(in) :: interaction_type
115 if (
present(interaction_type))
then
116 if (any(this%supported_interactions_as_partner == interaction_type))
then
135 character(len=*),
intent(in) :: label
139 write(
message(1),
'(a,a,a,a,a)')
'Interation partner "', trim(this%namespace%get()), &
140 '"does not know how to update quantity"', trim(label),
'".'
160 do i = 1,
size(quantity%parents)
161 parent => this%quantities%get(quantity%parents(i))
164 if (parent%iteration >= requested_iteration .or. .not. parent%updated_on_demand) cycle
166 call this%update_on_demand_quantity(parent, requested_iteration)
171 if (all(this%quantities%iteration_equal(quantity%parents, requested_iteration) .or. &
172 this%quantities%always_available(quantity%parents)))
then
174 quantity%iteration = requested_iteration
176 quantity%iteration,
"set"))
177 call this%update_quantity(quantity%label)
192 class(interaction_partner_t),
target,
intent(inout) :: this
193 character(len=*),
intent(in) :: labels(:)
195 logical,
intent(in) :: retardation_allowed
200 do iq = 1,
size(labels)
202 quantity => this%quantities%get(labels(iq))
205 if (quantity%iteration >= requested_iteration .or. .not. quantity%updated_on_demand) cycle
207 if (quantity%always_available)
then
210 call this%update_on_demand_quantity(quantity, requested_iteration)
212 else if (quantity%iteration + 1 <= requested_iteration .or. &
213 (retardation_allowed .and. quantity%iteration + 1 > requested_iteration))
then
216 call this%update_on_demand_quantity(quantity, quantity%iteration + 1)
233 character(len=*),
intent(in) :: couplings(:)
237 integer :: i, ahead, on_time, relevant_couplings
238 character(len=200) :: marker_info
239 character(len=20) :: status_string
247 requested_iteration = requested_iteration)
253 relevant_couplings = 0
254 do i = 1,
size(couplings)
255 coupling => this%quantities%get(couplings(i))
258 if (coupling%always_available) cycle
260 relevant_couplings = relevant_couplings + 1
261 if (coupling%iteration == requested_iteration) on_time = on_time + 1
262 if (coupling%iteration > requested_iteration) ahead = ahead + 1
266 if (on_time > 0 .and. ahead > 0)
then
267 status = couplings_undefined
268 status_string =
"UNDEFINED"
269 else if (on_time + ahead < relevant_couplings)
then
271 status_string =
"BEHIND"
272 else if (on_time == relevant_couplings)
then
274 status_string =
"ON_TIME"
275 else if (ahead == relevant_couplings)
then
277 status_string =
"AHEAD"
280 write(marker_info,
'(A20," check_couplings_status: ahead = ",I5,", on_time = ",I5,", relevant = ",I5, ", status = ",A9)') &
281 trim(this%namespace%get()), ahead, on_time, relevant_couplings, trim(status_string)
296 call this%add_ptr(partner)
310 select type (ptr => this%get_next_ptr())
This module defines classes and functions for interaction partners.
integer, parameter, public couplings_on_time
recursive subroutine interaction_partner_add_partners_to_list(this, list, interaction_type)
add interaction partner to a list
integer function interaction_partner_check_couplings_status(this, couplings, requested_iteration)
Check the status of some couplings.
class(interaction_partner_t) function, pointer partner_iterator_get_next(this)
get next partner from the list
recursive subroutine interaction_partner_update_on_demand_quantity(this, quantity, requested_iteration)
subroutine partner_list_add_node(this, partner)
add a partner to the list
integer, parameter, public couplings_behind_in_time
subroutine interaction_partner_update_on_demand_quantities(this, labels, requested_iteration, retardation_allowed)
Given a list of quantities, update the ones that can be update on demand.
subroutine interaction_partner_update_quantity(this, label)
Method to be overriden by interaction partners that have quantities that can be updated on demand.
integer, parameter, public couplings_ahead_in_time
This module implements fully polymorphic linked lists, and some specializations thereof.
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
This module implements the multisystem debug functionality.
subroutine, public multisystem_debug_write_marker(system_namespace, event)
type(event_handle_t) function, public multisystem_debug_write_event_in(system_namespace, event, extra, system_iteration, algo_iteration, interaction_iteration, partner_iteration, requested_iteration)
subroutine, public multisystem_debug_write_event_out(handle, extra, update, system_iteration, algo_iteration, interaction_iteration, partner_iteration, requested_iteration)
This module defines the quantity_t class and the IDs for quantities, which can be exposed by a system...
abstract class for general interaction partners
iterator for the list of partners
surrogate interaction class to avoid circular dependencies between modules.
This class implements the iteration counter used by the multisystem algorithms. As any iteration coun...
This class implements an iterator for the polymorphic linked list.
This class implements a linked list of unlimited polymorphic values.
events marking a function call
handle to keep track of in- out- events
events marking an iteration update
Systems (system_t) can expose quantities that can be used to calculate interactions with other system...