22 integer,
parameter ::
group_type_whole=0, & !< Execute the callbacks in this group once per timestep
35 procedure(),
nopass,
pointer :: ptr
40 character(len=STRING_LENGTH) :: name
41 character(len=STRING_LENGTH),
dimension(30) :: group_members
42 integer ::
type, & !< Type (execute once per timestep or per column)
43 id, & !< Id number of the group which is also the order executed
104 class(*),
pointer :: description_data
105 character(len=STRING_LENGTH) :: group_name
106 logical :: component_enabled
108 allocate(registry_descriptor, source=descriptor)
110 if (
options_has_key(options_database, trim(descriptor%name)//
"_enabled"))
then 113 component_enabled=.false.
114 call log_master_log(
log_warn,
"No enabled configuration for component "//trim(descriptor%name)//
" therefore disabling this")
117 if (component_enabled)
then 127 description_data => registry_descriptor
135 character(len=*),
intent(in) :: name
145 character(len=*),
intent(in) :: name
148 class(*),
pointer :: data
154 call data%ptr(current_state, name, get_component_field_value)
166 character(len=*),
intent(in) :: name
169 class(*),
pointer :: data
175 call data%ptr(current_state, name, get_component_field_information)
196 class(*),
pointer :: field_generic_description
198 class(*),
pointer :: genericwrapper
200 if (
associated(descriptor%published_fields) .and.
associated(descriptor%field_value_retrieval) .and. &
201 associated(descriptor%field_information_retrieval))
then 202 do i=1,
size(descriptor%published_fields)
203 field_generic_description=>descriptor%published_fields(i)
206 wrapper%ptr => descriptor%field_value_retrieval
207 genericwrapper=>wrapper
210 wrapper%ptr => descriptor%field_information_retrieval
211 genericwrapper=>wrapper
215 else if (
associated(descriptor%published_fields) .or.
associated(descriptor%field_value_retrieval) .or. &
216 associated(descriptor%field_information_retrieval))
then 218 " has provided incomplete configuration for published fields, therefore ignoring these")
226 character(len=*),
intent(in) :: name
227 class(*),
pointer :: description_data
230 select type(description_data)
234 deallocate(description_data)
241 character(len=*),
intent(in) :: name
243 class(*),
pointer :: description_data
245 get_component_info => null()
247 if (
associated(description_data))
then 248 select type(description_data)
250 get_component_info => description_data
257 type(
map_type) function get_all_registered_components()
258 integer :: i, number_of_components
259 class(*),
pointer :: description_data
265 select type(description_data)
267 call c_put_real(get_all_registered_components, description_data%name, description_data%version)
275 type(model_state_type),
intent(inout) :: current_state
283 type(model_state_type),
intent(inout) :: current_state
294 type(model_state_type),
intent(inout) :: current_state
306 type(map_type) :: specific_ts
312 call c_free(specific_ts)
317 type(map_type) function order_grouped_timstep_callbacks(group_id)
318 integer,
intent(in) :: group_id
320 integer :: group_size, i
325 group_size=descriptor%number_of_members
327 call c_put_integer(order_grouped_timstep_callbacks, trim(descriptor%group_members(i)), i)
334 type(hashmap_type),
intent(inout) :: options_database
335 character(len=*),
intent(in) :: component_name
338 if (options_has_key(options_database, trim(component_name)//
"_enabled"))
then 381 character(len=*),
intent(in) :: group_name
393 character(len=*),
intent(in) :: group_name
395 class(*),
pointer :: generic
398 if (
associated(generic))
then 401 get_group_descriptor_from_name=generic
404 call log_master_log(log_error,
"No configuration specified for group "//group_name)
412 integer,
intent(in) :: group_id
414 type(iterator_type) :: iterator
415 class(*),
pointer :: generic
418 do while (c_has_next(iterator))
419 generic=>c_get_generic(c_next_mapentry(iterator))
420 if (
associated(generic))
then 423 if (generic%id == group_id)
then 424 get_group_descriptor_from_id=generic
436 type(map_type),
intent(inout) :: stage_callbacks
437 character(len=*),
intent(in) :: stagetitle
439 integer :: i, entries
441 entries = c_size(stage_callbacks)
443 call log_master_log(log_info,
"Stage: "//stagetitle//
" at: "//trim(conv_to_string(i))//
" "//c_key_at(stage_callbacks, i))
448 type(hashmap_type),
intent(inout) :: options_database
455 type(hashmap_type),
intent(inout) :: options_database
456 type(map_type),
intent(inout) :: data_structure
457 character(len=*) :: key
459 integer :: number_of_elements, i
460 character(len=STRING_LENGTH) :: component_name
462 number_of_elements=options_get_array_size(options_database, key)
463 do i=1, number_of_elements
464 component_name=options_get_string(options_database, key, i)
465 call c_put_integer(data_structure, trim(component_name), i)
470 type(hashmap_type),
intent(inout) :: options_database
472 integer :: group_elements, i, j
473 class(*),
pointer :: generic_to_add
475 character(len=STRING_LENGTH) :: group_type
477 group_elements=options_get_array_size(options_database,
"group_names")
478 if (group_elements .lt. 1)
call log_master_log(log_error,
"You must provide some group definitions")
479 do i=1, group_elements
480 group_description%name=trim(options_get_string(options_database,
"group_names", i))
481 if (options_has_key(options_database, trim(group_description%name)//
"_group_type"))
then 482 group_type=trim(options_get_string(options_database, trim(group_description%name)//
"_group_type"))
483 if (trim(group_type) .eq.
"entire")
then 484 group_description%type=0
485 else if (trim(group_type) .eq.
"column")
then 486 group_description%type=1
487 else if (trim(group_type) .eq.
"slice")
then 488 group_description%type=2
490 call log_master_log(log_error,
"Group type "//trim(group_type)//
" for group "&
491 //trim(group_description%name)//
" not understood")
494 call log_master_log(log_error,
"No group type for group "//trim(group_description%name))
496 group_description%id=i
497 if (.not. options_has_key(options_database, trim(group_description%name)//
"_group_contents"))
then 498 call log_master_log(log_error,
"No component contents specified for group "//trim(group_description%name))
500 group_description%number_of_members=options_get_array_size(options_database, &
501 trim(group_description%name)//
"_group_contents")
502 if (group_description%number_of_members == 0 .or. .not. options_has_key(options_database, &
503 trim(group_description%name)//
"_group_contentsa_size"))
then 504 if (options_has_key(options_database, trim(group_description%name)//
"_group_contents"))
then 505 group_description%number_of_members=1
506 group_description%group_members(1)=trim(options_get_string(options_database, &
507 trim(group_description%name)//
"_group_contents"))
508 call c_put_string(
component_groups, trim(group_description%group_members(1)), group_description%name)
510 call log_master_log(log_error,
"No contents specified for group "//trim(group_description%name))
513 do j=1, group_description%number_of_members
514 group_description%group_members(j)=trim(options_get_string(options_database, &
515 trim(group_description%name)//
"_group_contents", j))
516 call c_put_string(
component_groups, trim(group_description%group_members(j)), group_description%name)
519 allocate(generic_to_add, source=group_description)
520 call c_put_generic(
group_descriptors, group_description%name, generic_to_add, .false.)
528 type(component_descriptor_type),
intent(inout) :: descriptor
530 character(len=STRING_LENGTH) :: group_name
544 type(component_descriptor_type),
intent(in) :: descriptor
545 character(len=*),
intent(in),
optional :: group_name
547 if (
associated(descriptor%initialisation))
call c_remove(
init_callbacks, descriptor%name)
548 if (
associated(descriptor%timestep) .and.
present(group_name)) &
556 type(component_descriptor_type),
intent(in) :: descriptor
557 character(len=*),
intent(in),
optional :: group_name
560 if (
associated(descriptor%timestep))
then 561 if (
present(group_name))
then 564 call log_master_log(log_error,
"In the configuration you must provide a group for component "&
565 //trim(descriptor%name)//
" which has a timestep callback")
572 type(map_type),
intent(inout) :: callbacks, priorities
573 character(len=*),
intent(in) :: stage_name
575 type(map_type) :: ordered_callbacks
576 integer :: i, entries_in_list, current_item
577 class(*),
pointer :: generic
579 entries_in_list=c_size(callbacks)
580 do i=1, entries_in_list
582 if (current_item .ge. 1)
then 583 generic=>c_generic_at(callbacks, current_item)
584 call c_put_generic(ordered_callbacks, c_key_at(callbacks, current_item), generic, .false.)
585 call c_remove(callbacks, c_key_at(callbacks, current_item))
589 entries_in_list=c_size(callbacks)
590 do i=1, entries_in_list
591 generic=>c_generic_at(callbacks, i)
592 call c_put_generic(ordered_callbacks, c_key_at(callbacks, i), generic, .false.)
593 call log_master_log(log_warn,
"Run order callback for component "//trim(c_key_at(callbacks, i))//&
594 " at stage "//stage_name//
" not specified")
596 callbacks=ordered_callbacks
600 type(map_type),
intent(inout) :: callbacks, priorities
602 integer :: i, entries_in_list, min_priority, min_location, priority
603 character(len=STRING_LENGTH) :: key
608 entries_in_list=c_size(callbacks)
609 do i=1, entries_in_list
610 key=c_key_at(callbacks, i)
611 if (c_contains(priorities, key))
then 612 priority=c_get_integer(priorities, key)
613 if (priority .lt. min_priority)
then 614 min_priority=priority
626 type(map_type),
intent(inout) :: callback_map
627 type(model_state_type),
intent(inout) :: current_state
629 class(*),
pointer :: data
630 type(iterator_type) :: iterator
632 iterator=c_get_iterator(callback_map)
633 do while (c_has_next(iterator))
634 data=>c_get_generic(c_next_mapentry(iterator))
637 call data%ptr(current_state)
646 subroutine add_callback(callback_map, name, procedure_pointer)
647 type(map_type),
intent(inout) :: callback_map
648 procedure(),
pointer :: procedure_pointer
649 character(len=*),
intent(in) :: name
652 class(*),
pointer :: genericwrapper
655 wrapper%ptr => procedure_pointer
656 genericwrapper=>wrapper
657 call c_put_generic(callback_map, name, genericwrapper, .false.)
subroutine display_callbacks_in_order(stage_callbacks, stagetitle)
Displays the registered callbacks of a specific stage in the order that they will be called...
type(map_type), save finalisation_callbacks
Callback hooks for the finalisation stage.
integer, dimension(:), allocatable group_types
Group types.
integer function, public options_get_array_size(options_database, key)
Gets the size of the array held in the options database corresponding to a specific key...
Retrieves the key currently being held at a specific index in the map or "" if the index > map elemen...
Gets a specific generic element out of the list, stack, queue or map with the corresponding key...
type(component_descriptor_type) function, pointer, public get_component_info(name)
Retrieves detailed information about a specific component.
Wrapper type for the value returned for a published field from a component.
Returns whether a collection is empty.
Puts an integer key-value pair into the map.
type(group_descriptor_type) function get_group_descriptor_from_id(group_id)
Given the id of a group this will return the corresponding descriptor.
subroutine load_callback_hooks(descriptor, group_name)
Will install the callback hooks for each state.
type(map_type), save group_descriptors
Group descriptors for each group, name->descriptor.
subroutine, public display_callbacks_in_order_at_each_stage()
Displays the registered callbacks of each stage in the order that they will be called.
subroutine, public free_registry()
Will deregister all components and free up the registry data structures. This can either be called at...
subroutine unload_callback_hooks(descriptor, group_name)
Will unload the callback hooks that have been installed for each state.
integer, parameter, public log_error
Only log ERROR messages.
subroutine load_published_fields(descriptor)
Loads the published fields information for an entire component into the registry's definition list...
character(len=string_length) function, public options_get_string(options_database, key, index)
Retrieves a string value from the database that matches the provided key.
type(map_type) function, public get_all_registered_components()
Returns a brief summary of all registered components.
Private helper type which wraps a procedure pointer. This is needed for storage in our collections_mo...
subroutine rebalance_callbacks(callbacks, priorities, stage_name)
logical function, public is_component_field_available(name)
Determines whether a specific published field is available or not.
character(len=string_length), dimension(:), allocatable group_locations
Provides an id to each group.
subroutine, public execute_timestep_callbacks(current_state, group_id)
Calls all timestep callbacks with the specified state.
subroutine, public get_ordered_groups(ordered_groups)
Orders all the groups (in the order that they will be called in) and returns an array with these in o...
Contains common definitions for the data and datatypes used by MONC.
type(map_type), dimension(:), allocatable timestep_callbacks
Callback hooks for the timestep stage.
The ModelState which represents the current state of a run.
logical function, public is_component_enabled(options_database, component_name)
Determines whether or not a specific component is registered and enabled.
subroutine, public log_master_log(level, message)
Will log just from the master process.
A hashmap structure, the same as a map but uses hashing for greatly improved performance when storing...
Gets a specific integer element out of the list, stack, queue or map with the corresponding key...
Conversion between common inbuilt FORTRAN data types.
Converts data types to strings.
Description of a component.
Puts a string key-value pair into the map.
subroutine read_initialisation_and_finalisation_orders(options_database)
integer function get_group_id(group_name)
Given a group name this returns the id (i.e. order) of that group.
type(map_type), save finalisation_orderings
type(component_field_value_type) function, public get_component_field_value(current_state, name)
Retrieves the value wrapper of a components published field.
type(hashmap_type), save field_procedure_retrievals
Map data structure that holds string (length 20 maximum) key value pairs.
subroutine, public order_all_callbacks()
Orders all callbacks in the prospective stages based upon the priorities of each descriptor.
Returns the number of elements in the collection.
type(component_field_information_type) function, public get_component_field_information(current_state, name)
Retrieves information about a components published field which includes its type and size...
Interfaces and types that MONC components must specify.
subroutine remove_descriptor(descriptor)
Will remove a specific descriptor from the registry table and uninstall the corresponding callback ho...
integer, parameter, public timestep_priority_index
type(map_type), save component_groups
Collection data structures.
integer, parameter, public group_type_whole
Execute the callbacks in this group once per timestep.
integer, parameter, public log_warn
Log WARNING and ERROR messages.
type(map_type), save init_callbacks
Callback hooks for the initialisation stage.
integer, parameter, public string_length
Default length of strings.
integer, parameter, public finalisation_priority_index
subroutine add_callback(callback_map, name, procedure_pointer)
Will install a specific callback hook into the specified map_type of existing hooks.
integer function get_highest_callback_priority(callbacks, priorities)
integer, parameter, public init_priority_index
Index of each priority value in the descriptor.
List data structure which implements a doubly linked list. This list will preserve its order...
subroutine read_group_configurations(options_database)
type(group_descriptor_type) function get_group_descriptor_from_name(group_name)
Given a group name this returns the group descriptor corresponding to that or an error if none is fou...
Adds a generic element to the end of the list.
subroutine read_specific_orders(options_database, key, data_structure)
type(list_type) function, public get_all_component_published_fields()
Retrieves all of the published field information.
integer, parameter, public group_type_column
Execute the callbacks in this group for each column per timestep.
type(hashmap_type), save field_procedure_sizings
Manages the options database. Contains administration functions and deduce runtime options from the c...
integer, parameter, public log_info
Log INFO, WARNING and ERROR messages.
logical function, public options_get_logical(options_database, key, index)
Retrieves a logical value from the database that matches the provided key.
subroutine, public execute_initialisation_callbacks(current_state)
Calls all initialisation callbacks with the specified state.
Frees up all the allocatable, heap, memory associated with a list, stack, queue or map...
Puts a generic key-value pair into the map.
Retrieves the generic value held at the specific map index or null if index > map elements...
character(len=string_length), dimension(:), allocatable enabled_component_input_keys
Temporary read array of component enable names.
subroutine, public deregister_component(name)
Will deregister a component, remove all callback hooks and free registry specific memory allocated to...
subroutine, public register_component(options_database, descriptor)
Will register a component and install the nescesary callback hooks.
subroutine execute_callbacks(callback_map, current_state)
Will execute the appropriate callbacks in a specific map_type given the current state.
type(map_type) function order_grouped_timstep_callbacks(group_id)
Determines whether or not a map contains a specific key.
Adds a string to the end of the list.
logical function, public options_has_key(options_database, key)
Determines whether a specific key is in the database.
type(map_type), save init_orderings
The model state which represents the current state of a run.
subroutine, public init_registry(options_database)
Initialises the registry with the provided configuration file.
subroutine, public execute_finalisation_callbacks(current_state)
Calls all finalisation callbacks with the specified state.
Gets a specific string element out of the list, stack, queue or map with the corresponding key...
type(map_type), save component_descriptions
Copies of component descriptors.
type(list_type), save field_information
Puts a double precision real key-value pair into the map.
Removes a specific element from the list or map.